diff --git a/src/BizHawk.Bizware.Graphics.Controls/Controls/D3D9Control.cs b/src/BizHawk.Bizware.Graphics.Controls/Controls/D3D9Control.cs index 597b46a47e..73e66e89b7 100644 --- a/src/BizHawk.Bizware.Graphics.Controls/Controls/D3D9Control.cs +++ b/src/BizHawk.Bizware.Graphics.Controls/Controls/D3D9Control.cs @@ -1,16 +1,17 @@ using System; -using System.Drawing; using System.Windows.Forms; namespace BizHawk.Bizware.Graphics.Controls { internal sealed class D3D9Control : GraphicsControl { - private readonly Func _createSwapChain; + private readonly Func _createSwapChain; private D3D9SwapChain _swapChain; private bool Vsync; - public D3D9Control(Func createSwapChain) + private D3D9SwapChain.ControlParameters ControlParameters => new(Handle, Width, Height, Vsync); + + public D3D9Control(Func createSwapChain) { _createSwapChain = createSwapChain; @@ -21,12 +22,10 @@ namespace BizHawk.Bizware.Graphics.Controls DoubleBuffered = false; } - protected override Size DefaultSize => new(1, 1); - protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); - _swapChain = _createSwapChain(Handle); + _swapChain = _createSwapChain(ControlParameters); } protected override void OnHandleDestroyed(EventArgs e) @@ -39,7 +38,7 @@ namespace BizHawk.Bizware.Graphics.Controls protected override void OnResize(EventArgs e) { base.OnResize(e); - _swapChain.Refresh(Vsync); + _swapChain.Refresh(ControlParameters); } public override void SetVsync(bool state) @@ -47,7 +46,7 @@ namespace BizHawk.Bizware.Graphics.Controls if (Vsync != state) { Vsync = state; - _swapChain.Refresh(Vsync); + _swapChain.Refresh(ControlParameters); } } @@ -58,6 +57,6 @@ namespace BizHawk.Bizware.Graphics.Controls => _swapChain.SetBackBuffer(); public override void SwapBuffers() - => _swapChain.PresentBuffer(); + => _swapChain.PresentBuffer(ControlParameters); } } \ No newline at end of file diff --git a/src/BizHawk.Bizware.Graphics/D3D9/D3D9SwapChain.cs b/src/BizHawk.Bizware.Graphics/D3D9/D3D9SwapChain.cs index 938fef167a..77e494317f 100644 --- a/src/BizHawk.Bizware.Graphics/D3D9/D3D9SwapChain.cs +++ b/src/BizHawk.Bizware.Graphics/D3D9/D3D9SwapChain.cs @@ -7,16 +7,32 @@ namespace BizHawk.Bizware.Graphics { public sealed class D3D9SwapChain : IDisposable { + public readonly struct ControlParameters + { + public readonly IntPtr Handle; + public readonly int Width; + public readonly int Height; + public readonly bool Vsync; + + public ControlParameters(IntPtr handle, int width, int height, bool vsync) + { + Handle = handle; + Width = Math.Max(width, 1); + Height = Math.Max(height, 1); + Vsync = vsync; + } + } + private const int D3DERR_DEVICELOST = unchecked((int)0x88760868); private readonly Device _device; - private readonly Func _resetDeviceCallback; - private readonly Func _resetSwapChainCallback; + private readonly Func _resetDeviceCallback; + private readonly Func _resetSwapChainCallback; private SwapChain _swapChain; internal D3D9SwapChain(Device device, SwapChain swapChain, - Func resetDeviceCallback, Func resetSwapChainCallback) + Func resetDeviceCallback, Func resetSwapChainCallback) { _device = device; _swapChain = swapChain; @@ -37,7 +53,7 @@ namespace BizHawk.Bizware.Graphics _device.DepthStencilSurface = null; } - public void PresentBuffer() + public void PresentBuffer(ControlParameters cp) { SetBackBuffer(); @@ -49,19 +65,12 @@ namespace BizHawk.Bizware.Graphics { if (ex.ResultCode.Code == D3DERR_DEVICELOST) { - var pp = _swapChain.PresentParameters; - pp.BackBufferWidth = pp.BackBufferHeight = 0; - _swapChain = _resetDeviceCallback(pp); + _swapChain = _resetDeviceCallback(cp); } } } - public void Refresh(bool vsync) - { - var pp = _swapChain.PresentParameters; - pp.BackBufferWidth = pp.BackBufferHeight = 0; - pp.PresentationInterval = vsync ? PresentInterval.One : PresentInterval.Immediate; - _swapChain = _resetSwapChainCallback(pp); - } + public void Refresh(ControlParameters cp) + => _swapChain = _resetSwapChainCallback(cp); } } diff --git a/src/BizHawk.Bizware.Graphics/D3D9/IGL_D3D9.cs b/src/BizHawk.Bizware.Graphics/D3D9/IGL_D3D9.cs index cdc2743a51..4cbe12bc6b 100644 --- a/src/BizHawk.Bizware.Graphics/D3D9/IGL_D3D9.cs +++ b/src/BizHawk.Bizware.Graphics/D3D9/IGL_D3D9.cs @@ -29,6 +29,7 @@ namespace BizHawk.Bizware.Graphics private const int D3DERR_DEVICENOTRESET = unchecked((int)0x88760869); private Device _device; + private Size _maxWindowSize; private SwapChain _controlSwapchain; private IntPtr _offscreenSdl2Window; @@ -105,6 +106,11 @@ namespace BizHawk.Bizware.Graphics flags |= CreateFlags.FpuPreserve; _device = new(d3d9, 0, DeviceType.Hardware, pp.DeviceWindowHandle, flags, pp); + + // save the maximum size a window backbuffer can be + // this allows us to avoid resetting the swapchain on resizing the window + var displayMode = d3d9.Adapters[0].CurrentDisplayMode; + _maxWindowSize = new(displayMode.Width, displayMode.Height); } private PresentParameters MakePresentParameters() @@ -119,7 +125,22 @@ namespace BizHawk.Bizware.Graphics }; } - private SwapChain ResetDevice(PresentParameters swapChainPresentParameters) + private static PresentParameters MakePresentParameters(D3D9SwapChain.ControlParameters cp) + { + return new() + { + BackBufferWidth = cp.Width, + BackBufferHeight = cp.Height, + BackBufferFormat = Format.X8R8G8B8, + BackBufferCount = 2, + SwapEffect = SwapEffect.Discard, + DeviceWindowHandle = cp.Handle, + Windowed = true, + PresentationInterval = cp.Vsync ? PresentInterval.One : PresentInterval.Immediate + }; + } + + private SwapChain ResetDevice(D3D9SwapChain.ControlParameters cp) { SuspendRenderTargets(); _controlSwapchain.Dispose(); @@ -151,35 +172,29 @@ namespace BizHawk.Bizware.Graphics } ResumeRenderTargets(); - _controlSwapchain = new(_device, swapChainPresentParameters); - return _controlSwapchain; - } - - private SwapChain ResetSwapChain(PresentParameters pp) - { - _controlSwapchain.Dispose(); + pp = MakePresentParameters(cp); _controlSwapchain = new(_device, pp); return _controlSwapchain; } - public D3D9SwapChain CreateSwapChain(IntPtr handle) + private SwapChain ResetSwapChain(D3D9SwapChain.ControlParameters cp) + { + _controlSwapchain.Dispose(); + + var pp = MakePresentParameters(cp); + _controlSwapchain = new(_device, pp); + return _controlSwapchain; + } + + public D3D9SwapChain CreateSwapChain(D3D9SwapChain.ControlParameters cp) { if (_controlSwapchain != null) { throw new InvalidOperationException($"{nameof(IGL_D3D9)} can only have 1 control swap chain"); } - var pp = new PresentParameters - { - BackBufferCount = 1, - BackBufferFormat = Format.X8R8G8B8, - SwapEffect = SwapEffect.Discard, - DeviceWindowHandle = handle, - Windowed = true, - PresentationInterval = PresentInterval.Immediate - }; - + var pp = MakePresentParameters(cp); _controlSwapchain = new(_device, pp); return new(_device, _controlSwapchain, ResetDevice, ResetSwapChain); }