From 07ad0acdbefb6aef0e1c91a6bac8479306653fe5 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 10 Jun 2012 20:48:04 +0000 Subject: [PATCH] displaymanager experiments for superior vsync --- .../DisplayManager/DisplayManager.cs | 45 +++++++++++++++++-- BizHawk.MultiClient/RenderPanel.cs | 19 ++++++-- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/BizHawk.MultiClient/DisplayManager/DisplayManager.cs b/BizHawk.MultiClient/DisplayManager/DisplayManager.cs index 6cfeb02ae0..0d007c1dac 100644 --- a/BizHawk.MultiClient/DisplayManager/DisplayManager.cs +++ b/BizHawk.MultiClient/DisplayManager/DisplayManager.cs @@ -593,14 +593,36 @@ namespace BizHawk.MultiClient displayThread.Start(); } + volatile bool VsyncToggle = false; + volatile bool VsyncRequested = false; SwappableDisplaySurfaceSet sourceSurfaceSet = new SwappableDisplaySurfaceSet(); public void UpdateSource(IVideoProvider videoProvider) { + VsyncRequested = Global.Config.DisplayVSync; + //needsclear = false because we're about to clobber the data with AcceptIntArray var newPendingSurface = sourceSurfaceSet.AllocateSurface(videoProvider.BufferWidth, videoProvider.BufferHeight, false); newPendingSurface.AcceptIntArray(videoProvider.GetVideoBuffer()); sourceSurfaceSet.SetPending(newPendingSurface); wakeupEvent.Set(); + + if (VsyncRequested) + { + VsyncToggle = true; + + for (; ; ) + { + //if (Direct3DRenderPanel.vsyncEvent.WaitOne(1)) break; + if (!VsyncToggle) break; + Application.DoEvents(); + } + } + + //for(;;) + //{ + // if (Direct3DRenderPanel.vsyncEvent.WaitOne(1)) break; + // Application.DoEvents(); + //} } public bool Disposed { get; private set; } @@ -609,6 +631,7 @@ namespace BizHawk.MultiClient { if (Disposed) return; shutdownFlag = true; + VsyncToggle = true; while (shutdownFlag) Thread.Sleep(1); wakeupEvent.Dispose(); Disposed = true; @@ -649,7 +672,7 @@ namespace BizHawk.MultiClient Display(); //wait until we receive something interesting, or just a little while anyway - wakeupEvent.WaitOne(10); + wakeupEvent.WaitOne(1); if (suspendFlag) { @@ -729,7 +752,7 @@ namespace BizHawk.MultiClient { if (Global.Config.SuppressGui) { - Global.RenderPanel.FastRenderAndPresent(currentSourceSurface); + Global.RenderPanel.Render(currentSourceSurface); } else { @@ -739,12 +762,13 @@ namespace BizHawk.MultiClient { Global.OSD.DrawScreenInfo(g); Global.OSD.DrawMessages(g); + //Thread.Sleep(1); } nativeBmp.FromBitmap(); Global.RenderPanel.RenderOverlay(nativeBmp); //release the native resolution image nativeDisplaySurfaceSet.ReleaseSurface(nativeBmp); - Global.RenderPanel.Present(); + //Global.RenderPanel.Present(); } } else @@ -781,12 +805,25 @@ namespace BizHawk.MultiClient //send the native resolution image to the render panel Global.RenderPanel.Render(nativeBmp); - Global.RenderPanel.Present(); + //Global.RenderPanel.Present(); //release the native resolution image nativeDisplaySurfaceSet.ReleaseSurface(nativeBmp); } + Global.RenderPanel.Present(); + + if (VsyncRequested) + { + for (; ; ) + { + //if (Direct3DRenderPanel.vsyncEvent.WaitOne(1)) break; + if (VsyncToggle) break; + } + VsyncToggle = false; + } + + } Thread displayThread; diff --git a/BizHawk.MultiClient/RenderPanel.cs b/BizHawk.MultiClient/RenderPanel.cs index f14aa145a7..4bffa580d7 100644 --- a/BizHawk.MultiClient/RenderPanel.cs +++ b/BizHawk.MultiClient/RenderPanel.cs @@ -46,6 +46,10 @@ namespace BizHawk.MultiClient if (width == 0 || height == 0) return; bool needsRecreating = false; + + //experiment: + //needsRecreating = true; + if (Texture == null) { needsRecreating = true; @@ -58,6 +62,8 @@ namespace BizHawk.MultiClient needsRecreating = true; } } + + // If we need to recreate the texture, do so. if (needsRecreating) { @@ -78,7 +84,7 @@ namespace BizHawk.MultiClient } // Copy the image data to the texture. - using (var Data = Texture.LockRectangle(0, new Rectangle(0, 0, imageWidth, imageHeight), LockFlags.None).Data) + using (var Data = Texture.LockRectangle(0, LockFlags.Discard | LockFlags.NoDirtyUpdate).Data) { if (imageWidth == textureWidth) { @@ -348,13 +354,18 @@ namespace BizHawk.MultiClient backingControl.Invoke(() => CreateDevice()); Resized = false; + + //TODO //BackgroundColor = Color.FromArgb(video.BackgroundColor); + if (overlay) + { + //return; + } Texture.SetImage(surface, surface.Width, surface.Height); if(!overlay) Device.Clear(ClearFlags.Target, BackgroundColor, 0.0f, 0); - // figure out scaling factor float widthScale = (float)backingControl.Size.Width / surface.Width; float heightScale = (float)backingControl.Size.Height / surface.Height; @@ -369,7 +380,7 @@ namespace BizHawk.MultiClient Device.SetSamplerState(0, SamplerState.MinFilter, TextureFilter.Point); Sprite.Transform = Matrix.Scaling(finalScale, finalScale, 0f); Sprite.Draw(Texture.Texture, new Rectangle(0, 0, surface.Width, surface.Height), new Vector3(surface.Width / 2f, surface.Height / 2f, 0), new Vector3(backingControl.Size.Width / 2f / finalScale, backingControl.Size.Height / 2f / finalScale, 0), Color.White); - if (overlay) Device.SetRenderState(RenderState.AlphaBlendEnable, false); + //if (overlay) Device.SetRenderState(RenderState.AlphaBlendEnable, false); Sprite.End(); Device.EndScene(); @@ -379,8 +390,10 @@ namespace BizHawk.MultiClient { //Device.Present(SlimDX.Direct3D9.Present.DoNotWait); Device.Present(SlimDX.Direct3D9.Present.None); + vsyncEvent.Set(); } + public static EventWaitHandle vsyncEvent = new EventWaitHandle(false, EventResetMode.AutoReset); private bool disposed;