A game about forced loneliness, made by TACStudios
at master 136 lines 5.0 kB view raw
1using System; 2using System.Collections.Generic; 3 4namespace UnityEngine.Rendering.RenderGraphModule 5{ 6 /// <summary> 7 /// Helper class provided in the RenderGraphContext to all Render Passes. 8 /// It allows you to do temporary allocations of various objects during a Render Pass. 9 /// </summary> 10 public sealed class RenderGraphObjectPool 11 { 12 // Only used to clear all existing pools at once from here when needed 13 static DynamicArray<SharedObjectPoolBase> s_AllocatedPools = new DynamicArray<SharedObjectPoolBase>(); 14 15 // Non abstract class instead of an interface to store it in a DynamicArray 16 class SharedObjectPoolBase 17 { 18 public SharedObjectPoolBase() {} 19 public virtual void Clear() {} 20 } 21 22 class SharedObjectPool<T> : SharedObjectPoolBase where T : class, new() 23 { 24 private static readonly Pool.ObjectPool<T> s_Pool = AllocatePool(); 25 26 private static Pool.ObjectPool<T> AllocatePool() 27 { 28 var newPool = new Pool.ObjectPool<T>(() => new T(), null, null); 29 // Storing instance to clear the static pool of the same type if needed 30 s_AllocatedPools.Add(new SharedObjectPool<T>()); 31 return newPool; 32 } 33 34 /// <summary> 35 /// Clear the pool using SharedObjectPool instance. 36 /// </summary> 37 /// <returns></returns> 38 public override void Clear() 39 { 40 s_Pool.Clear(); 41 } 42 43 /// <summary> 44 /// Get a new instance from the pool. 45 /// </summary> 46 /// <returns></returns> 47 public static T Get() => s_Pool.Get(); 48 49 /// <summary> 50 /// Release an object to the pool. 51 /// </summary> 52 /// <param name="toRelease">instance to release.</param> 53 public static void Release(T toRelease) => s_Pool.Release(toRelease); 54 } 55 56 57 Dictionary<(Type, int), Stack<object>> m_ArrayPool = new Dictionary<(Type, int), Stack<object>>(); 58 List<(object, (Type, int))> m_AllocatedArrays = new List<(object, (Type, int))>(); 59 List<MaterialPropertyBlock> m_AllocatedMaterialPropertyBlocks = new List<MaterialPropertyBlock>(); 60 61 internal RenderGraphObjectPool() { } 62 63 /// <summary> 64 /// Allocate a temporary typed array of a specific size. 65 /// Unity releases the array at the end of the Render Pass. 66 /// </summary> 67 /// <typeparam name="T">Type of the array to be allocated.</typeparam> 68 /// <param name="size">Number of element in the array.</param> 69 /// <returns>A new array of type T with size number of elements.</returns> 70 public T[] GetTempArray<T>(int size) 71 { 72 if (!m_ArrayPool.TryGetValue((typeof(T), size), out var stack)) 73 { 74 stack = new Stack<object>(); 75 m_ArrayPool.Add((typeof(T), size), stack); 76 } 77 78 var result = stack.Count > 0 ? (T[])stack.Pop() : new T[size]; 79 m_AllocatedArrays.Add((result, (typeof(T), size))); 80 return result; 81 } 82 83 /// <summary> 84 /// Allocate a temporary MaterialPropertyBlock for the Render Pass. 85 /// </summary> 86 /// <returns>A new clean MaterialPropertyBlock.</returns> 87 public MaterialPropertyBlock GetTempMaterialPropertyBlock() 88 { 89 var result = SharedObjectPool<MaterialPropertyBlock>.Get(); 90 result.Clear(); 91 m_AllocatedMaterialPropertyBlocks.Add(result); 92 return result; 93 } 94 95 internal void ReleaseAllTempAlloc() 96 { 97 foreach (var arrayDesc in m_AllocatedArrays) 98 { 99 bool result = m_ArrayPool.TryGetValue(arrayDesc.Item2, out var stack); 100 Debug.Assert(result, "Correct stack type should always be allocated."); 101 stack.Push(arrayDesc.Item1); 102 } 103 104 m_AllocatedArrays.Clear(); 105 106 foreach (var mpb in m_AllocatedMaterialPropertyBlocks) 107 { 108 SharedObjectPool<MaterialPropertyBlock>.Release(mpb); 109 } 110 111 m_AllocatedMaterialPropertyBlocks.Clear(); 112 } 113 114 // Regular pooling API. Only internal use for now 115 internal T Get<T>() where T : class, new() 116 { 117 return SharedObjectPool<T>.Get(); 118 } 119 120 internal void Release<T>(T value) where T : class, new() 121 { 122 SharedObjectPool<T>.Release(value); 123 } 124 125 internal void Cleanup() 126 { 127 m_AllocatedArrays.Clear(); 128 m_AllocatedMaterialPropertyBlocks.Clear(); 129 m_ArrayPool.Clear(); 130 131 // Removing all objects in the pools 132 foreach (var pool in s_AllocatedPools) 133 pool.Clear(); 134 } 135 } 136}