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 { /// /// 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 /// 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(); CurrentTextures.Add(null); CurrentTextures.Add(null); } IGL GL; List 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; } } }