displaymanager - maybe, just maybe, successfully get rid of the need for 0xFF000000 in the VideoProvider buffers. Should enable some little speedups and cleanups of other code that had to add the 0xFF000000 alpha channel

This commit is contained in:
zeromus 2014-12-13 23:04:22 +00:00
parent 557309eb6f
commit 979fa2c0f7
13 changed files with 109 additions and 21 deletions

View File

@ -495,6 +495,7 @@ TESTEROO:
{
//wrap the videoprovider data in a BitmapBuffer (no point to refactoring that many IVideoProviders)
bb = new BitmapBuffer(bufferWidth, bufferHeight, videoBuffer);
bb.DiscardAlpha();
//now, acquire the data sent from the videoProvider into a texture
videoTexture = VideoTextureFrugalizer.Get(bb);

View File

@ -260,7 +260,7 @@ namespace BizHawk.Client.EmuHawk.Filters
GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit);
GuiRenderer.Begin(OutputSize.Width, OutputSize.Height);
GuiRenderer.SetBlendState(GL.BlendNone);
GuiRenderer.SetBlendState(GL.BlendNoneCopy);
if(FilterOption != eFilterOption.None)
InputTexture.SetFilterLinear();

View File

@ -64,7 +64,7 @@ namespace BizHawk.Client.EmuHawk.Filters
{
var renderer = FilterProgram.GuiRenderer;
renderer.Begin(FindOutput().SurfaceFormat.Size);
renderer.SetBlendState(FilterProgram.GL.BlendNone);
renderer.SetBlendState(FilterProgram.GL.BlendNoneCopy);
renderer.Draw(InputTexture);
renderer.End();
}

View File

@ -51,6 +51,9 @@ namespace BizHawk.Client.EmuHawk
//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)
{

View File

@ -73,9 +73,15 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
return;
using (var g = CreateGraphics())
{
//not sure we had proof we needed this but it cant hurt
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
RenderTargetWrapper.MyBufferedGraphics.Render(g);
}
//not too sure about this.. i think we have to re-allocate it so we can support a changed window size. did we do this at the right time anyway?
//maybe I should try caching harder, I hate to reallocate these constantly
RenderTargetWrapper.CreateGraphics();
}
}

View File

@ -89,9 +89,10 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
sd.Color CurrentModulateColor = sd.Color.White;
IBlendState CurrentBlendState;
public void SetBlendState(IBlendState rsBlend)
{
CurrentBlendState = rsBlend;
}
MatrixStack _Projection, _Modelview;
@ -121,6 +122,8 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
{
Begin();
CurrentBlendState = Gdi.BlendNormal;
Projection = Owner.CreateGuiProjectionMatrix(width, height);
Modelview = Owner.CreateGuiViewMatrix(width, height);
}
@ -172,6 +175,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
new sd.PointF(x+w,y),
new sd.PointF(x,y+h),
};
g.DrawImage(tw.SDBitmap, destPoints, new sd.RectangleF(x0, y0, x1 - x0, y1 - y0), sd.GraphicsUnit.Pixel, CurrentImageAttributes);
//g.DrawImage(tw.SDBitmap, 0, 0); //test
}
@ -199,18 +203,50 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;
if (tw.MagFilter == TextureMagFilter.Nearest)
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
//---------
if (CurrentBlendState == Gdi.BlendNormal)
{
g.CompositingMode = sd.Drawing2D.CompositingMode.SourceOver;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.Default; //?
//CurrentImageAttributes.ClearColorMatrix(ColorAdjustType.Bitmap);
}
else
//if(CurrentBlendState == Gdi.BlendNoneCopy)
//if(CurrentBlendState == Gdi.BlendNoneOpaque)
{
g.CompositingMode = sd.Drawing2D.CompositingMode.SourceCopy;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
//WARNING : DO NOT USE COLOR MATRIX TO WIPE THE ALPHA
//ITS SOOOOOOOOOOOOOOOOOOOOOOOOOOOO SLOW
//instead, we added kind of hacky support for 24bpp images
}
}
unsafe void DrawInternal(Texture2d tex, float x, float y, float w, float h)
{
var tw = Gdi.TextureWrapperForTexture(tex);
var g = Gdi.GetCurrentGraphics();
PrepDraw(g,tw);
PrepDraw(g, tw);
//a little bit of a fastpath.. I think it's safe
if (w == tex.Width && h == tex.Height && x == (int)x && y == (int)y)
g.DrawImageUnscaled(tw.SDBitmap, (int)x, (int)y);
else
g.DrawImage(tw.SDBitmap, x, y, w, h);
//if (w == tex.Width && h == tex.Height && x == (int)x && y == (int)y)
// g.DrawImageUnscaled(tw.SDBitmap, (int)x, (int)y);
//else
{
sd.PointF[] destPoints = new sd.PointF[] {
new sd.PointF(x,y),
new sd.PointF(x+w,y),
new sd.PointF(x,y+h),
};
//g.DrawImage(tw.SDBitmap, x, y, w, h); //original
g.DrawImage(tw.SDBitmap, destPoints, new sd.RectangleF(0, 0, tex.Width, tex.Height), sd.GraphicsUnit.Pixel, CurrentImageAttributes);
}
}
unsafe void DrawInternal(Art art, float x, float y, float w, float h, bool fx, bool fy)

View File

@ -130,9 +130,10 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
}
class MyBlendState : IBlendState { }
static MyBlendState _rsBlendNone = new MyBlendState(), _rsBlendNormal = new MyBlendState();
static MyBlendState _rsBlendNoneVerbatim = new MyBlendState(), _rsBlendNoneOpaque = new MyBlendState(), _rsBlendNormal = new MyBlendState();
public IBlendState BlendNone { get { return _rsBlendNone; } }
public IBlendState BlendNoneCopy { get { return _rsBlendNoneVerbatim; } }
public IBlendState BlendNoneOpaque { get { return _rsBlendNoneOpaque; } }
public IBlendState BlendNormal { get { return _rsBlendNormal; } }
public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required)

View File

@ -145,9 +145,15 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
GL.BlendFuncSeparate(mybs.colorSource, mybs.colorDest, mybs.alphaSource, mybs.alphaDest);
}
else GL.Disable(EnableCap.Blend);
if (rsBlend == _rsBlendNoneOpaque)
{
//make sure constant color is set correctly
GL.BlendColor(new Color4(255, 255, 255, 255));
}
}
public IBlendState BlendNone { get { return _rsBlendNone; } }
public IBlendState BlendNoneCopy { get { return _rsBlendNoneVerbatim; } }
public IBlendState BlendNoneOpaque { get { return _rsBlendNoneOpaque; } }
public IBlendState BlendNormal { get { return _rsBlendNormal; } }
public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required)
@ -641,13 +647,23 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
void CreateRenderStates()
{
_rsBlendNone = new MyBlendState(false, BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero, BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
_rsBlendNormal = new MyBlendState(true,
_rsBlendNoneVerbatim = new MyBlendState(
false,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
_rsBlendNoneOpaque = new MyBlendState(
false,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero,
BlendingFactorSrc.ConstantAlpha, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
_rsBlendNormal = new MyBlendState(
true,
BlendingFactorSrc.SrcAlpha, BlendEquationMode.FuncAdd, BlendingFactorDest.OneMinusSrcAlpha,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
}
MyBlendState _rsBlendNone, _rsBlendNormal;
MyBlendState _rsBlendNoneVerbatim, _rsBlendNoneOpaque, _rsBlendNormal;
//state caches
int sActiveTexture;

View File

@ -82,7 +82,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //junk
pData[i++] = 1; pData[i++] = v1; //texcoord
Owner.SetBlendState(Owner.BlendNone);
Owner.SetBlendState(Owner.BlendNoneCopy);
Owner.BindArrayData(pData);
Owner.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
}

View File

@ -153,9 +153,10 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
}
class MyBlendState : IBlendState { }
static MyBlendState _rsBlendNone = new MyBlendState(), _rsBlendNormal = new MyBlendState();
static MyBlendState _rsBlendNoneOpaque = new MyBlendState(), _rsBlendNoneVerbatim = new MyBlendState(), _rsBlendNormal = new MyBlendState();
public IBlendState BlendNone { get { return _rsBlendNone; } }
public IBlendState BlendNoneCopy { get { return _rsBlendNoneVerbatim; } }
public IBlendState BlendNoneOpaque { get { return _rsBlendNoneOpaque; } }
public IBlendState BlendNormal { get { return _rsBlendNormal; } }
public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required)

View File

@ -29,6 +29,11 @@ namespace BizHawk.Bizware.BizwareGL
public int Width, Height;
public int[] Pixels;
/// <summary>
/// Whether this instance should be considered as having alpha (ARGB) or not (XRBG)
/// </summary>
public bool HasAlpha = true;
public Size Size { get { return new Size(Width, Height); } }
sd.Bitmap WrappedBitmap;
@ -241,6 +246,14 @@ namespace BizHawk.Bizware.BizwareGL
this.Height = height;
}
/// <summary>
/// Suggests that this BitmapBuffer is now XRGB instead of ARGB but doesn't actually change any of the pixels data.
/// Should affect how things get exported from here, though, I think
/// </summary>
public void DiscardAlpha()
{
HasAlpha = false;
}
void LoadInternal(Stream stream, sd.Bitmap bitmap, BitmapLoadOptions options)
{
@ -464,16 +477,21 @@ namespace BizHawk.Bizware.BizwareGL
/// </summary>
public unsafe Bitmap ToSysdrawingBitmap()
{
Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
var pf = PixelFormat.Format32bppArgb;
if (!HasAlpha)
pf = PixelFormat.Format24bppRgb;
Bitmap bmp = new Bitmap(Width, Height, pf);
ToSysdrawingBitmap(bmp);
return bmp;
}
/// <summary>
/// Dumps this BitmapBuffer to an existing System.Drawing.Bitmap
/// Dumps this BitmapBuffer to an existing System.Drawing.Bitmap.
/// Some features of this may not be super fast (in particular, 32bpp to 24bpp conversion; we might fix that later with a customized loop)
/// </summary>
public unsafe void ToSysdrawingBitmap(Bitmap bmp)
{
//note: we lock it as 32bpp even if the bitmap is 24bpp so we can write to it more conveniently.
var bmpdata = bmp.LockBits(new sd.Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
if (bmp.Width != 0 && bmp.Height != 0)

View File

@ -155,7 +155,13 @@ namespace BizHawk.Bizware.BizwareGL
/// retrieves a blend state for opaque rendering
/// Alpha values are copied from the source fragment.
/// </summary>
IBlendState BlendNone { get; }
IBlendState BlendNoneCopy { get; }
/// <summary>
/// retrieves a blend state for opaque rendering
/// Alpha values are written as opaque
/// </summary>
IBlendState BlendNoneOpaque { get; }
/// <summary>
/// retrieves a blend state for normal (non-premultiplied) alpha blending.

View File

@ -73,7 +73,7 @@ namespace BizHawk.Bizware.BizwareGL
{
if (rt == null) return;
GuiRenderer.Begin(Width, Height, true);
GuiRenderer.SetBlendState(GL.BlendNone);
GuiRenderer.SetBlendState(GL.BlendNoneCopy);
GuiRenderer.Draw(rt.Texture2d);
GuiRenderer.End();
base.SwapBuffers();