Files
Bachelor-Arbeit-Adrian-Haefner/Library/PackageCache/com.unity.xr.arfoundation@ef86c118adc4/Runtime/ARFoundation/Textures/FixedLengthSwapchainStrategy.cs
adriadri6972 d3d9c5f833 upload project
2025-07-31 15:21:08 +02:00

109 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using Unity.Collections;
using Unity.XR.CoreUtils.Collections;
using UnityEngine.XR.ARSubsystems;
namespace UnityEngine.XR.ARFoundation
{
/// <summary>
/// Swapchain strategy for providers that expose a fixed-length swapchain of fixed-size textures.
/// </summary>
/// <remarks>
/// This strategy is especially useful for providers that represent textures using `RenderTexture`, as it
/// allows you to create all the RenderTextures when the swapchain is initialized and re-use them for the duration
/// of the app's lifecycle.
/// </remarks>
class FixedLengthSwapchainStrategy : ISwapchainStrategy
{
/// <summary>
/// A 2-dimensional array of texture info objects.
/// Each row represents a frame. Each column represents a texture that is used that frame.
/// </summary>
IUpdatableTexture[][] m_UpdatableTextures;
/// <summary>
/// Enables a constant-time lookup operation. Given the native pointer of any texture in the swapchain,
/// look up the index of the frame where that texture is used.
/// </summary>
readonly Dictionary<IntPtr, int> m_FrameIndicesByTexturePtr = new();
readonly int m_NumTexturesPerFrame;
internal FixedLengthSwapchainStrategy(NativeArray<NativeArray<XRTextureDescriptor>> swapchainDescriptors)
{
if (swapchainDescriptors.Length == 0
|| swapchainDescriptors[0].Length == 0)
throw new ArgumentException("Swapchain must contain at least one texture", nameof(swapchainDescriptors));
int numFramesInSwapchain = swapchainDescriptors.Length;
m_NumTexturesPerFrame = swapchainDescriptors[0].Length;
m_UpdatableTextures = new IUpdatableTexture[numFramesInSwapchain][];
for (var i = 0; i < numFramesInSwapchain; ++i)
{
if (swapchainDescriptors[i].Length != m_NumTexturesPerFrame)
throw new ArgumentException(
"Swapchain must use the same number of textures per frame", nameof(swapchainDescriptors));
m_UpdatableTextures[i] = new IUpdatableTexture[m_NumTexturesPerFrame];
for (var j = 0; j < m_NumTexturesPerFrame; ++j)
{
if (swapchainDescriptors[i][j].nativeTexture == IntPtr.Zero)
throw new ArgumentException("Swapchain textures must have non-null native texture pointer.", nameof(swapchainDescriptors));
if (m_FrameIndicesByTexturePtr.ContainsKey(swapchainDescriptors[i][j].nativeTexture))
throw new ArgumentException("Swapchain native texture pointers must be unique.", nameof(swapchainDescriptors));
m_UpdatableTextures[i][j] = UpdatableTextureFactory.Create(swapchainDescriptors[i][j]);
m_FrameIndicesByTexturePtr.Add(swapchainDescriptors[i][j].nativeTexture, i);
}
}
}
bool ISwapchainStrategy.TryUpdateTexturesForFrame(
NativeArray<XRTextureDescriptor> descriptors, out ReadOnlyListSpan<IUpdatableTexture> textureInfos)
{
if (descriptors.Length == 0)
{
textureInfos = ReadOnlyListSpan<IUpdatableTexture>.Empty();
return true;
}
if (!m_FrameIndicesByTexturePtr.TryGetValue(descriptors[0].nativeTexture, out var frameIndex))
throw new InvalidOperationException(
"Fixed-length swapchain strategy was given a texture that is not in the swapchain.");
if (descriptors.Length != m_NumTexturesPerFrame)
throw new InvalidOperationException(
$"Fixed-length swapchain uses {m_NumTexturesPerFrame} textures per frame, but was given {descriptors.Length} textures this frame.");
bool allRequiredTexturesDoExist = true;
for (var j = 0; j < m_NumTexturesPerFrame; j++)
{
if (!m_UpdatableTextures[frameIndex][j].TryUpdateFromDescriptor(descriptors[j]))
allRequiredTexturesDoExist = false;
}
textureInfos = new ReadOnlyListSpan<IUpdatableTexture>(m_UpdatableTextures[frameIndex]);
return allRequiredTexturesDoExist;
}
public void DestroyTextures()
{
foreach (var frame in m_UpdatableTextures)
{
foreach (var textureInfo in frame)
{
textureInfo.DestroyTexture();
}
}
}
void IDisposable.Dispose()
{
DestroyTextures();
}
}
}