/******************************************************************************/ /* Project - MudBun Publisher - Long Bunny Labs http://LongBunnyLabs.com Author - Ming-Lun "Allen" Chou http://AllenChou.net */ /******************************************************************************/ using System.Collections.Generic; #if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; namespace MudBun { public class Janitor : Singleton { private class DisposalRecord { public int Frame = -1; public List Buffers = new List(); } private Queue m_queue = new Queue(); #if MUDBUN_DEV private int m_lastQueuedFrame = -1; #endif public static void Dispose(ComputeBuffer buffer) { var instance = Instance; if (instance != null) { instance.Queue(buffer); } else { buffer.Release(); //Debug.Log($"Disposed immediately: {buffer}"); } } protected override void OnDisable() { base.OnDisable(); FlushAll(); } protected override void OnDestroy() { base.OnDestroy(); FlushAll(); } protected override void OnApplicationQuit() { base.OnApplicationQuit(); FlushAll(); } private void Update() { TryFlush(); //Debug.Log($"Update frame {Time.renderedFrameCount}"); #if UNITY_EDITOR if (!Application.isPlaying && m_queue.Count > 0) { EditorApplication.QueuePlayerLoopUpdate(); } #endif } private void Queue(params ComputeBuffer[] buffers) { DisposalRecord record; if (m_queue.Count > 0 && m_queue.Peek().Frame == Time.renderedFrameCount) { record = m_queue.Peek(); } else { record = new DisposalRecord() { Frame = Time.renderedFrameCount }; m_queue.Enqueue(record); } foreach (var buffer in buffers) record.Buffers.Add(buffer); #if MUDBUN_DEV if (m_lastQueuedFrame != Time.renderedFrameCount) { //Debug.Log($"Queued at frame {Time.renderedFrameCount}"); } m_lastQueuedFrame = Time.renderedFrameCount; #endif #if UNITY_EDITOR if (!Application.isPlaying) EditorApplication.QueuePlayerLoopUpdate(); #endif } private void TryFlush() { while (m_queue.Count > 0 && Time.renderedFrameCount > m_queue.Peek().Frame + 1) { var record = m_queue.Dequeue(); foreach (var buffer in record.Buffers) buffer.Release(); //Debug.Log($"Flushed record for frame {record.Frame} at frame {Time.renderedFrameCount}"); } } private void FlushAll() { foreach (var record in m_queue) foreach (var buffer in record.Buffers) buffer.Release(); m_queue.Clear(); //Debug.Log($"Flushed all at frame {Time.renderedFrameCount}"); } } }