|
|
|
|
/******************************************************************************/
|
|
|
|
|
/*
|
|
|
|
|
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<Janitor>
|
|
|
|
|
{
|
|
|
|
|
private class DisposalRecord
|
|
|
|
|
{
|
|
|
|
|
public int Frame = -1;
|
|
|
|
|
public List<ComputeBuffer> Buffers = new List<ComputeBuffer>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Queue<DisposalRecord> m_queue = new Queue<DisposalRecord>();
|
|
|
|
|
|
|
|
|
|
#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}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|