Created
October 19, 2020 18:11
-
-
Save samloeschen/d8ad54e8764cd8fbdc273badfcc82e96 to your computer and use it in GitHub Desktop.
RenderTexturePool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sometimes, RenderTexture.GetTemporary() and RenderTexture.ReleaseTemporary() leak textures. | |
// For those times, there is RenderTexturePool. | |
using System.Collections.Generic; | |
using Unity.Collections; | |
using UnityEngine; | |
public class RenderTexturePool { | |
readonly Dictionary<RenderTextureDescriptor, List<RenderTextureCounter>> _pool; | |
readonly int _initialListCapacity; | |
readonly int _expireAfterFrames; | |
public int PooledCount => _pooledCount; | |
int _pooledCount; | |
public RenderTexturePool(int initialDictCapacity, int initialListCapacity, int expireAfterFrames = 5) { | |
_initialListCapacity = initialListCapacity; | |
_pool = new Dictionary<RenderTextureDescriptor, List<RenderTextureCounter>>(initialDictCapacity); | |
_expireAfterFrames = expireAfterFrames; | |
} | |
public RenderTexture GetTemporary(RenderTextureDescriptor desc) { | |
RenderTexture rt; | |
if (_pool.TryGetValue(desc, out var list)) { | |
if (list.Count > 0) { | |
rt = list[0].rt; | |
list.RemoveAtSwapBack(0); | |
_pooledCount--; | |
} | |
} | |
rt = new RenderTexture(desc); | |
return rt; | |
} | |
public void ReleaseTemporary(RenderTexture renderTexture) { | |
var rtCounter = new RenderTextureCounter { rt = renderTexture }; | |
if (_pool.TryGetValue(renderTexture.descriptor, out var list)) { | |
list.Add(rtCounter); | |
return; | |
} | |
list = new List<RenderTextureCounter>(_initialListCapacity) { rtCounter }; | |
_pool.Add(renderTexture.descriptor, list); | |
_pooledCount++; | |
} | |
public void UpdateFrameCounts() { | |
foreach (var list in _pool.Values) { | |
for (int i = 0; i < list.Count; i++) { | |
var rtCounter = list[i]; | |
if (rtCounter.unusedFrameCount > _expireAfterFrames) { | |
rtCounter.rt.Release(); | |
list.RemoveAtSwapBack(i); | |
i--; | |
continue; | |
} | |
rtCounter.unusedFrameCount++; | |
list[i] = rtCounter; | |
} | |
} | |
} | |
struct RenderTextureCounter { | |
public RenderTexture rt; | |
public int unusedFrameCount; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment