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

144 lines
3.0 KiB
C#

/******************************************************************************/
/*
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}");
}
}
}