暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RenderGraphObjectPool.cs 4.9KB

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