BizHawk/BizHawk.Client.EmuHawk/DisplayManager/SwappableBitmapBufferSet.cs

76 lines
2.0 KiB
C#

using System;
using System.Collections.Generic;
using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// encapsulates thread-safe concept of pending/current BitmapBuffer, reusing buffers where matching
/// sizes are available and keeping them cleaned up when they dont seem like theyll need to be used anymore
/// This isnt in the csproj right now, but I'm keeping it, in case its handy.
/// </summary>
class SwappableBitmapBufferSet
{
BitmapBuffer Pending, Current;
Queue<BitmapBuffer> ReleasedSurfaces = new Queue<BitmapBuffer>();
/// <summary>
/// retrieves a surface with the specified size, reusing an old buffer if available and clearing if requested
/// </summary>
public BitmapBuffer AllocateSurface(int width, int height, bool needsClear = true)
{
for (; ; )
{
BitmapBuffer trial;
lock (this)
{
if (ReleasedSurfaces.Count == 0) break;
trial = ReleasedSurfaces.Dequeue();
}
if (trial.Width == width && trial.Height == height)
{
if (needsClear) trial.ClearWithoutAlloc();
return trial;
}
trial.Dispose();
}
return new BitmapBuffer(width, height);
}
/// <summary>
/// sets the provided buffer as pending. takes control of the supplied buffer
/// </summary>
public void SetPending(BitmapBuffer newPending)
{
lock (this)
{
if (Pending != null) ReleasedSurfaces.Enqueue(Pending);
Pending = newPending;
}
}
public void ReleaseSurface(BitmapBuffer surface)
{
lock (this) ReleasedSurfaces.Enqueue(surface);
}
/// <summary>
/// returns the current buffer, making the most recent pending buffer (if there is such) as the new current first.
/// </summary>
public BitmapBuffer GetCurrent()
{
lock (this)
{
if (Pending != null)
{
if (Current != null) ReleasedSurfaces.Enqueue(Current);
Current = Pending;
Pending = null;
}
}
return Current;
}
}
}