BizHawk/BizHawk.Client.EmuHawk/DisplayManager/TextureFrugalizer.cs

82 lines
2.1 KiB
C#

using System;
using System.Collections.Generic;
using BizHawk.Common;
using BizHawk.Emulation.Common;
using BizHawk.Client.Common;
using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// Recycles a pair of temporary textures (in case double-buffering helps any) to contain a BitmapBuffer's or DisplaySurface's contents, as long as the dimensions match.
/// When the dimensions dont match, a new one will be allocated
/// </summary>
public class TextureFrugalizer : IDisposable
{
public TextureFrugalizer(IGL gl)
{
GL = gl;
ResetList();
}
public void Dispose()
{
foreach (var ct in CurrentTextures)
if(ct != null)
ct.Dispose();
ResetList();
}
void ResetList()
{
CurrentTextures = new List<Texture2d>();
CurrentTextures.Add(null);
CurrentTextures.Add(null);
}
IGL GL;
List<Texture2d> CurrentTextures;
public Texture2d Get(DisplaySurface ds)
{
using (var bb = new BitmapBuffer(ds.PeekBitmap(), new BitmapLoadOptions()))
{
return Get(bb);
}
}
public Texture2d Get(BitmapBuffer bb)
{
//get the current entry
Texture2d CurrentTexture = CurrentTextures[0];
//TODO - its a bit cruddy here that we dont respect the current texture HasAlpha condition (in fact, theres no such concept)
//we might need to deal with that in the future to fix some bugs.
//check if its rotten and needs recreating
if (CurrentTexture == null || CurrentTexture.IntWidth != bb.Width || CurrentTexture.IntHeight != bb.Height)
{
//needs recreating. be sure to kill the old one...
if (CurrentTexture != null)
CurrentTexture.Dispose();
//and make a new one
CurrentTexture = GL.LoadTexture(bb);
}
else
{
//its good! just load in the data
GL.LoadTextureData(CurrentTexture, bb);
}
//now shuffle the buffers
CurrentTextures[0] = CurrentTextures[1];
CurrentTextures[1] = CurrentTexture;
//deterministic state, i guess
CurrentTexture.SetFilterNearest();
return CurrentTexture;
}
}
}