2 using System
.Collections
.Generic
;
3 using UnityEngine
.Assertions
;
4 using UnityEngine
.Rendering
;
6 namespace UnityEngine
.Experimental
.Rendering
9 /// Implement a multiple buffering for RenderTextures.
21 /// var camera = GetCamera();
22 /// var buffers = GetFrameHistoryBuffersFor(camera);
24 /// // Set reference size in case the rendering size changed this frame
25 /// buffers.SetReferenceSize(
26 /// GetCameraWidth(camera), GetCameraHeight(camera),
27 /// GetCameraUseMSAA(camera), GetCameraMSAASamples(camera)
31 /// var currentColor = buffer.GetFrameRT((int)BufferType.Color, 0);
32 /// if (currentColor == null) // Buffer was not allocated
34 /// buffer.AllocBuffer(
35 /// (int)BufferType.Color, // Color buffer id
36 /// ColorBufferAllocator, // Custom functor to implement allocation
37 /// 2 // Use 2 RT for this buffer for double buffering
39 /// currentColor = buffer.GetFrameRT((int)BufferType.Color, 0);
42 /// var previousColor = buffers.GetFrameRT((int)BufferType.Color, 1);
44 /// // Use previousColor and write into currentColor
48 public class BufferedRTHandleSystem
: IDisposable
50 Dictionary
<int, RTHandleSystem
.RTHandle
[]> m_RTHandles
= new Dictionary
<int, RTHandleSystem
.RTHandle
[]>();
52 RTHandleSystem m_RTHandleSystem
= new RTHandleSystem();
53 bool m_DisposedValue
= false;
56 /// Return the frame RT or null.
58 /// <param name="bufferId">Defines the buffer to use.</param>
59 /// <param name="frameIndex"></param>
60 /// <returns>The frame RT or null when the <paramref name="bufferId"/> was not previously allocated (<see cref="BufferedRTHandleSystem.AllocBuffer(int, Func{RTHandleSystem, int, RTHandleSystem.RTHandle}, int)" />).</returns>
61 public RTHandleSystem
.RTHandle
GetFrameRT(int bufferId
, int frameIndex
)
63 if (!m_RTHandles
.ContainsKey(bufferId
))
66 Assert
.IsTrue(frameIndex
>= 0 && frameIndex
< m_RTHandles
[bufferId
].Length
);
68 return m_RTHandles
[bufferId
][frameIndex
];
72 /// Allocate RT handles for a buffer.
74 /// <param name="bufferId">The buffer to allocate.</param>
75 /// <param name="allocator">The functor to use for allocation.</param>
76 /// <param name="bufferCount">The number of RT handles for this buffer.</param>
77 public void AllocBuffer(
79 Func
<RTHandleSystem
, int, RTHandleSystem
.RTHandle
> allocator
,
83 var buffer
= new RTHandleSystem
.RTHandle
[bufferCount
];
84 m_RTHandles
.Add(bufferId
, buffer
);
86 // First is autoresized
87 buffer
[0] = allocator(m_RTHandleSystem
, 0);
89 // Other are resized on demand
90 for (int i
= 1, c
= buffer
.Length
; i
< c
; ++i
)
92 buffer
[i
] = allocator(m_RTHandleSystem
, i
);
93 m_RTHandleSystem
.SwitchResizeMode(buffer
[i
], RTHandleSystem
.ResizeMode
.OnDemand
);
98 /// Set the reference size for this RT Handle System (<see cref="RTHandleSystem.SetReferenceSize(int, int, bool, MSAASamples)"/>)
100 /// <param name="width">The width of the RTs of this buffer.</param>
101 /// <param name="height">The height of the RTs of this buffer.</param>
102 /// <param name="msaaSamples">Number of MSAA samples for this buffer.</param>
103 public void SetReferenceSize(int width
, int height
, MSAASamples msaaSamples
)
105 m_RTHandleSystem
.SetReferenceSize(width
, height
, msaaSamples
);
109 /// Swap the buffers.
111 /// Take care that if the new current frame needs resizing, it will occurs during the this call.
115 foreach (var item
in m_RTHandles
)
117 // Do not index out of bounds...
118 if (item
.Value
.Length
> 1)
120 var nextFirst
= item
.Value
[item
.Value
.Length
- 1];
121 for (int i
= 0, c
= item
.Value
.Length
- 1; i
< c
; ++i
)
122 item
.Value
[i
+ 1] = item
.Value
[i
];
123 item
.Value
[0] = nextFirst
;
125 // First is autoresize, other are on demand
126 m_RTHandleSystem
.SwitchResizeMode(item
.Value
[0], RTHandleSystem
.ResizeMode
.Auto
);
127 m_RTHandleSystem
.SwitchResizeMode(item
.Value
[1], RTHandleSystem
.ResizeMode
.OnDemand
);
131 m_RTHandleSystem
.SwitchResizeMode(item
.Value
[0], RTHandleSystem
.ResizeMode
.Auto
);
136 void Dispose(bool disposing
)
138 if (!m_DisposedValue
)
142 m_RTHandleSystem
.Dispose();
143 m_RTHandleSystem
= null;
146 m_DisposedValue
= true;
150 public void Dispose()
156 /// Deallocate and clear all buffers.
158 public void ReleaseAll()
160 foreach (var item
in m_RTHandles
)
162 for (int i
= 0, c
= item
.Value
.Length
; i
< c
; ++i
)
164 m_RTHandleSystem
.Release(item
.Value
[i
]);