display manager speedup-dont use any gdi+ unless absolutely necessary (d3d renderer less sensitive to window size)
This commit is contained in:
parent
7d23581764
commit
2b5fd9e8d9
|
@ -109,47 +109,92 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DisplaySurface : IDisposable
|
public unsafe class DisplaySurface : IDisposable
|
||||||
{
|
{
|
||||||
|
Bitmap bmp;
|
||||||
|
BitmapData bmpdata;
|
||||||
|
int[] pixels;
|
||||||
|
|
||||||
|
public unsafe void Clear()
|
||||||
|
{
|
||||||
|
FromBitmap(false);
|
||||||
|
Util.memset(PixelPtr, 0, Stride * Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap PeekBitmap()
|
||||||
|
{
|
||||||
|
ToBitmap();
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// returns a Graphics object used to render to this surface. be sure to dispose it!
|
/// returns a Graphics object used to render to this surface. be sure to dispose it!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Graphics GetGraphics()
|
public Graphics GetGraphics()
|
||||||
{
|
{
|
||||||
Unlock();
|
ToBitmap();
|
||||||
return Graphics.FromImage(bmp);
|
return Graphics.FromImage(bmp);
|
||||||
}
|
}
|
||||||
Bitmap bmp;
|
|
||||||
BitmapData bmpdata;
|
|
||||||
|
|
||||||
//TODO - lock and cache these
|
public unsafe void ToBitmap(bool copy=true)
|
||||||
public unsafe int* PixelPtr { get { return (int*)bmpdata.Scan0.ToPointer(); } }
|
|
||||||
public IntPtr PixelIntPtr { get { return bmpdata.Scan0; } }
|
|
||||||
public int Stride { get { return bmpdata.Stride; } }
|
|
||||||
public int OffsetOf(int x, int y) { return y * Stride + x*4; }
|
|
||||||
|
|
||||||
public unsafe void Clear()
|
|
||||||
{
|
{
|
||||||
Lock();
|
if (isBitmap) return;
|
||||||
Util.memset32(PixelPtr, 0, Stride * Height);
|
isBitmap = true;
|
||||||
|
|
||||||
|
if (bmp == null)
|
||||||
|
{
|
||||||
|
bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy)
|
||||||
|
{
|
||||||
|
bmpdata = bmp.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||||
|
|
||||||
|
int w = Width;
|
||||||
|
int h = Height;
|
||||||
|
int stride = bmpdata.Stride / 4;
|
||||||
|
int* bmpbuf = (int*)bmpdata.Scan0.ToPointer();
|
||||||
|
for (int y = 0, i = 0; y < h; y++)
|
||||||
|
for (int x = 0; x < w; x++)
|
||||||
|
bmpbuf[y * stride + x] = pixels[i++];
|
||||||
|
|
||||||
|
bmp.UnlockBits(bmpdata);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public bool IsBitmap { get { return isBitmap; } }
|
||||||
/// returns a bitmap which you can use but not hold onto.
|
bool isBitmap = false;
|
||||||
/// we may remove this later, as managing a Bitmap just for this may be a drag. (probably not though)
|
|
||||||
/// </summary>
|
public unsafe void FromBitmap(bool copy=true)
|
||||||
public Bitmap PeekBitmap()
|
|
||||||
{
|
{
|
||||||
Unlock();
|
if (!isBitmap) return;
|
||||||
return bmp;
|
isBitmap = false;
|
||||||
|
|
||||||
|
if (copy)
|
||||||
|
{
|
||||||
|
bmpdata = bmp.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||||
|
|
||||||
|
int w = Width;
|
||||||
|
int h = Height;
|
||||||
|
int stride = bmpdata.Stride / 4;
|
||||||
|
int* bmpbuf = (int*)bmpdata.Scan0.ToPointer();
|
||||||
|
for (int y = 0, i = 0; y < h; y++)
|
||||||
|
for (int x = 0; x < w; x++)
|
||||||
|
pixels[i++] = bmpbuf[y * stride + x];
|
||||||
|
|
||||||
|
bmp.UnlockBits(bmpdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static DisplaySurface DisplaySurfaceWrappingBitmap(Bitmap bmp)
|
public static DisplaySurface DisplaySurfaceWrappingBitmap(Bitmap bmp)
|
||||||
{
|
{
|
||||||
DisplaySurface ret = new DisplaySurface();
|
DisplaySurface ret = new DisplaySurface();
|
||||||
ret.Width = bmp.Width;
|
ret.Width = bmp.Width;
|
||||||
ret.Height = bmp.Height;
|
ret.Height = bmp.Height;
|
||||||
ret.bmp = bmp;
|
ret.bmp = bmp;
|
||||||
|
ret.isBitmap = true;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +211,27 @@ namespace BizHawk.MultiClient
|
||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
|
|
||||||
bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
pixels = new int[width * height];
|
||||||
Lock();
|
LockPixels();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int* PixelPtr { get { return (int*)ptr; } }
|
||||||
|
public IntPtr PixelIntPtr { get { return new IntPtr(ptr); } }
|
||||||
|
public int Stride { get { return Width*4; } }
|
||||||
|
public int OffsetOf(int x, int y) { return y * Stride + x*4; }
|
||||||
|
|
||||||
|
void* ptr;
|
||||||
|
GCHandle handle;
|
||||||
|
void LockPixels()
|
||||||
|
{
|
||||||
|
UnlockPixels();
|
||||||
|
handle = GCHandle.Alloc(pixels, GCHandleType.Pinned);
|
||||||
|
ptr = handle.AddrOfPinnedObject().ToPointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnlockPixels()
|
||||||
|
{
|
||||||
|
if(handle.IsAllocated) handle.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -176,23 +240,27 @@ namespace BizHawk.MultiClient
|
||||||
/// <param name="xpad"></param>
|
/// <param name="xpad"></param>
|
||||||
/// <param name="ypad"></param>
|
/// <param name="ypad"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public unsafe DisplaySurface ToPaddedSurface(int xpad0, int ypad0, int xpad1, int ypad1)
|
public DisplaySurface ToPaddedSurface(int xpad0, int ypad0, int xpad1, int ypad1)
|
||||||
{
|
{
|
||||||
Lock();
|
//Lock();
|
||||||
int new_width = Width + xpad0 + xpad1;
|
//int new_width = Width + xpad0 + xpad1;
|
||||||
int new_height = Height + ypad0 + ypad1;
|
//int new_height = Height + ypad0 + ypad1;
|
||||||
DisplaySurface ret = new DisplaySurface(new_width, new_height);
|
//DisplaySurface ret = new DisplaySurface(new_width, new_height);
|
||||||
ret.Lock();
|
//ret.Lock();
|
||||||
int* dptr = ret.PixelPtr;
|
//int* dptr = ret.PixelPtr;
|
||||||
int* sptr = PixelPtr;
|
//int* sptr = PixelPtr;
|
||||||
int dstride = ret.Stride/4;
|
//int dstride = ret.Stride/4;
|
||||||
int sstride = Stride/4;
|
//int sstride = Stride/4;
|
||||||
for (int y = 0; y < Height; y++)
|
//for (int y = 0; y < Height; y++)
|
||||||
for (int x = 0; x < Width; x++)
|
// for (int x = 0; x < Width; x++)
|
||||||
{
|
// {
|
||||||
dptr[(y + ypad0) * dstride + x + xpad0] = sptr[y * sstride + x];
|
// dptr[(y + ypad0) * dstride + x + xpad0] = sptr[y * sstride + x];
|
||||||
}
|
// }
|
||||||
return ret;
|
//return ret;
|
||||||
|
|
||||||
|
//need to reimplement this
|
||||||
|
throw new NotSupportedException();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Width { get; private set; }
|
public int Width { get; private set; }
|
||||||
|
@ -203,77 +271,17 @@ namespace BizHawk.MultiClient
|
||||||
if (bmp != null)
|
if (bmp != null)
|
||||||
bmp.Dispose();
|
bmp.Dispose();
|
||||||
bmp = null;
|
bmp = null;
|
||||||
|
UnlockPixels();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
//public unsafe int[] ToIntArray() { }
|
||||||
/// copies out the buffer as an int array (hopefully you can do this with a pointer instead and save some time!)
|
|
||||||
/// </summary>
|
public void AcceptIntArray(int[] newpixels)
|
||||||
public unsafe int[] ToIntArray()
|
|
||||||
{
|
{
|
||||||
Lock();
|
FromBitmap(false);
|
||||||
|
UnlockPixels();
|
||||||
int w = bmp.Width;
|
pixels = newpixels;
|
||||||
int h = bmp.Height;
|
LockPixels();
|
||||||
var ret = new int[bmp.Width * bmp.Height];
|
|
||||||
int* pData = (int*)bmpdata.Scan0.ToPointer();
|
|
||||||
int stride = bmpdata.Stride / 4;
|
|
||||||
for (int y = 0, i = 0; y < h; y++)
|
|
||||||
for (int x = 0; x < w; x++)
|
|
||||||
ret[i++] = pData[y * stride + x];
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe void SetFromIntArray(int[] pixels)
|
|
||||||
{
|
|
||||||
Lock();
|
|
||||||
|
|
||||||
if (Stride == Width * 4)
|
|
||||||
{
|
|
||||||
Marshal.Copy(pixels, 0, PixelIntPtr, Width * Height);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int w = Width;
|
|
||||||
int h = Height;
|
|
||||||
int* pData = PixelPtr;
|
|
||||||
int stride = Stride / 4;
|
|
||||||
for (int y = 0, i = 0; y < h; y++)
|
|
||||||
for (int x = 0; x < w; x++)
|
|
||||||
pData[y * stride + x] = pixels[i++];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// locks this surface so that it can be accessed by raw pointer
|
|
||||||
/// </summary>
|
|
||||||
public void Lock()
|
|
||||||
{
|
|
||||||
if (bmpdata != null) return;
|
|
||||||
var imageLockMode = ImageLockMode.ReadWrite;
|
|
||||||
bmpdata = bmp.LockBits(new Rectangle(0, 0, Width, Height), imageLockMode, PixelFormat.Format32bppArgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsLocked { get { return bmpdata != null; } }
|
|
||||||
|
|
||||||
public void Unlock()
|
|
||||||
{
|
|
||||||
if (bmpdata != null)
|
|
||||||
bmp.UnlockBits(bmpdata);
|
|
||||||
bmpdata = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe DisplaySurface FromVideoProvider(IVideoProvider provider)
|
|
||||||
{
|
|
||||||
int w = provider.BufferWidth;
|
|
||||||
int h = provider.BufferHeight;
|
|
||||||
int[] buffer = provider.GetVideoBuffer();
|
|
||||||
var ret = new DisplaySurface(w,h);
|
|
||||||
int* pData = ret.PixelPtr;
|
|
||||||
int stride = ret.Stride / 4;
|
|
||||||
for (int y = 0, i=0; y < h; y++)
|
|
||||||
for (int x = 0; x < w; x++)
|
|
||||||
pData[y * stride + x] = buffer[i++];
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,8 +596,9 @@ namespace BizHawk.MultiClient
|
||||||
SwappableDisplaySurfaceSet sourceSurfaceSet = new SwappableDisplaySurfaceSet();
|
SwappableDisplaySurfaceSet sourceSurfaceSet = new SwappableDisplaySurfaceSet();
|
||||||
public void UpdateSource(IVideoProvider videoProvider)
|
public void UpdateSource(IVideoProvider videoProvider)
|
||||||
{
|
{
|
||||||
|
//needsclear = false because we're about to clobber the data with AcceptIntArray
|
||||||
var newPendingSurface = sourceSurfaceSet.AllocateSurface(videoProvider.BufferWidth, videoProvider.BufferHeight, false);
|
var newPendingSurface = sourceSurfaceSet.AllocateSurface(videoProvider.BufferWidth, videoProvider.BufferHeight, false);
|
||||||
newPendingSurface.SetFromIntArray(videoProvider.GetVideoBuffer());
|
newPendingSurface.AcceptIntArray(videoProvider.GetVideoBuffer());
|
||||||
sourceSurfaceSet.SetPending(newPendingSurface);
|
sourceSurfaceSet.SetPending(newPendingSurface);
|
||||||
wakeupEvent.Set();
|
wakeupEvent.Set();
|
||||||
}
|
}
|
||||||
|
@ -731,6 +740,7 @@ namespace BizHawk.MultiClient
|
||||||
Global.OSD.DrawScreenInfo(g);
|
Global.OSD.DrawScreenInfo(g);
|
||||||
Global.OSD.DrawMessages(g);
|
Global.OSD.DrawMessages(g);
|
||||||
}
|
}
|
||||||
|
nativeBmp.FromBitmap();
|
||||||
Global.RenderPanel.RenderOverlay(nativeBmp);
|
Global.RenderPanel.RenderOverlay(nativeBmp);
|
||||||
//release the native resolution image
|
//release the native resolution image
|
||||||
nativeDisplaySurfaceSet.ReleaseSurface(nativeBmp);
|
nativeDisplaySurfaceSet.ReleaseSurface(nativeBmp);
|
||||||
|
|
|
@ -78,7 +78,6 @@ namespace BizHawk.MultiClient
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the image data to the texture.
|
// Copy the image data to the texture.
|
||||||
surface.Lock();
|
|
||||||
using (var Data = Texture.LockRectangle(0, new Rectangle(0, 0, imageWidth, imageHeight), LockFlags.None).Data)
|
using (var Data = Texture.LockRectangle(0, new Rectangle(0, 0, imageWidth, imageHeight), LockFlags.None).Data)
|
||||||
{
|
{
|
||||||
if (imageWidth == textureWidth)
|
if (imageWidth == textureWidth)
|
||||||
|
@ -295,7 +294,7 @@ namespace BizHawk.MultiClient
|
||||||
|
|
||||||
Resized = false;
|
Resized = false;
|
||||||
Device.Clear(ClearFlags.Target, BackgroundColor, 1.0f, 0);
|
Device.Clear(ClearFlags.Target, BackgroundColor, 1.0f, 0);
|
||||||
Device.Present(SlimDX.Direct3D9.Present.DoNotWait);
|
Present();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FastRenderAndPresent(DisplaySurface surface)
|
public void FastRenderAndPresent(DisplaySurface surface)
|
||||||
|
@ -378,7 +377,8 @@ namespace BizHawk.MultiClient
|
||||||
|
|
||||||
public void Present()
|
public void Present()
|
||||||
{
|
{
|
||||||
Device.Present(SlimDX.Direct3D9.Present.DoNotWait);
|
//Device.Present(SlimDX.Direct3D9.Present.DoNotWait);
|
||||||
|
Device.Present(SlimDX.Direct3D9.Present.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue