From 34d779df45c4a7c03497b015cde51a255c9017aa Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 11 Jan 2017 09:49:12 -0600 Subject: [PATCH 1/9] Updated gitignore to remove vs2017 specific files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a510c4e49f..d16287cfb4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ *.suo *.user *.sln.docstates +.vs/ # Build results From f44468a3ab6f2abb0d1cb5250ebe835b952dcaa2 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 11 Jan 2017 10:47:48 -0600 Subject: [PATCH 2/9] Added swap chain backed render target. --- Avalonia.sln.DotSettings | 19 +++ .../Avalonia.Direct2D1.csproj | 20 +-- .../Avalonia.Direct2D1/Direct2D1Platform.cs | 36 ++++- .../Avalonia.Direct2D1/HwndRenderTarget.cs | 56 ++++++++ .../Media/DrawingContext.cs | 8 +- .../SwapChainRenderTarget.cs | 134 ++++++++++++++++++ src/Windows/Avalonia.Direct2D1/app.config | 4 +- .../Avalonia.Direct2D1/packages.config | 7 +- 8 files changed, 265 insertions(+), 19 deletions(-) create mode 100644 src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs create mode 100644 src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs diff --git a/Avalonia.sln.DotSettings b/Avalonia.sln.DotSettings index bf98899847..16c9218a7e 100644 --- a/Avalonia.sln.DotSettings +++ b/Avalonia.sln.DotSettings @@ -2,6 +2,24 @@ ExplicitlyExcluded ExplicitlyExcluded HINT + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="set_" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="_" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="False" Prefix="I" Suffix="" Style="AaBb" /> @@ -10,6 +28,7 @@ <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="s_" Suffix="" Style="aaBb" /></Policy> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> diff --git a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj index 9f9558ff76..95ccc98692 100644 --- a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj +++ b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj @@ -37,17 +37,17 @@ true - - ..\..\..\packages\SharpDX.3.1.0\lib\net45\SharpDX.dll - True + + ..\..\..\packages\SharpDX.3.1.1\lib\net45\SharpDX.dll - - ..\..\..\packages\SharpDX.Direct2D1.3.1.0\lib\net45\SharpDX.Direct2D1.dll - True + + ..\..\..\packages\SharpDX.Direct2D1.3.1.1\lib\net45\SharpDX.Direct2D1.dll - - ..\..\..\packages\SharpDX.DXGI.3.1.0\lib\net45\SharpDX.DXGI.dll - True + + ..\..\..\packages\SharpDX.Direct3D11.3.1.1\lib\net45\SharpDX.Direct3D11.dll + + + ..\..\..\packages\SharpDX.DXGI.3.1.1\lib\net45\SharpDX.DXGI.dll @@ -62,6 +62,7 @@ + @@ -79,6 +80,7 @@ + diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index b43eef2fa9..f86fa0b93a 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -8,6 +8,7 @@ using Avalonia.Media; using Avalonia.Platform; using Avalonia.Controls; using Avalonia.Rendering; +using SharpDX.Direct3D11; namespace Avalonia { @@ -29,20 +30,47 @@ namespace Avalonia.Direct2D1 private static readonly SharpDX.Direct2D1.Factory s_d2D1Factory = #if DEBUG - new SharpDX.Direct2D1.Factory(SharpDX.Direct2D1.FactoryType.SingleThreaded, SharpDX.Direct2D1.DebugLevel.Error); + new SharpDX.Direct2D1.Factory(SharpDX.Direct2D1.FactoryType.MultiThreaded, SharpDX.Direct2D1.DebugLevel.Error); #else - new SharpDX.Direct2D1.Factory(SharpDX.Direct2D1.FactoryType.SingleThreaded, SharpDX.Direct2D1.DebugLevel.None); + new SharpDX.Direct2D1.Factory(SharpDX.Direct2D1.FactoryType.MultiThreaded, SharpDX.Direct2D1.DebugLevel.None); #endif private static readonly SharpDX.DirectWrite.Factory s_dwfactory = new SharpDX.DirectWrite.Factory(); private static readonly SharpDX.WIC.ImagingFactory s_imagingFactory = new SharpDX.WIC.ImagingFactory(); + private static readonly SharpDX.DXGI.Device s_device; + + static Direct2D1Platform() + { + var featureLevels = new[] + { + SharpDX.Direct3D.FeatureLevel.Level_12_1, + SharpDX.Direct3D.FeatureLevel.Level_12_0, + SharpDX.Direct3D.FeatureLevel.Level_11_1, + SharpDX.Direct3D.FeatureLevel.Level_11_0, + SharpDX.Direct3D.FeatureLevel.Level_10_1, + SharpDX.Direct3D.FeatureLevel.Level_10_0, + SharpDX.Direct3D.FeatureLevel.Level_9_3, + SharpDX.Direct3D.FeatureLevel.Level_9_2, + SharpDX.Direct3D.FeatureLevel.Level_9_1, + }; + + using (var d3dDevice = new SharpDX.Direct3D11.Device( + SharpDX.Direct3D.DriverType.Hardware, + SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport, + featureLevels)) + { + s_device = d3dDevice.QueryInterface(); + } + } + public static void Initialize() => AvaloniaLocator.CurrentMutable .Bind().ToConstant(s_instance) .Bind().ToConstant(s_instance) .BindToSelf(s_d2D1Factory) .BindToSelf(s_dwfactory) - .BindToSelf(s_imagingFactory); + .BindToSelf(s_imagingFactory) + .BindToSelf(s_device); public IBitmapImpl CreateBitmap(int width, int height) { @@ -70,7 +98,7 @@ namespace Avalonia.Direct2D1 { if (handle.HandleDescriptor == "HWND") { - return new RenderTarget(handle.Handle); + return new HwndRenderTarget(handle.Handle); } else { diff --git a/src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs b/src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs new file mode 100644 index 0000000000..5c0c460dcb --- /dev/null +++ b/src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Avalonia.Win32.Interop; +using SharpDX; +using SharpDX.DXGI; + +namespace Avalonia.Direct2D1 +{ + class HwndRenderTarget : SwapChainRenderTarget + { + private readonly IntPtr _hwnd; + + public HwndRenderTarget(IntPtr hwnd) + { + _hwnd = hwnd; + } + + protected override SwapChain1 CreateSwapChain(Factory2 dxgiFactory, SwapChainDescription1 swapChainDesc) + { + return new SwapChain1(dxgiFactory, Device, _hwnd, ref swapChainDesc); + } + + protected override Size2F GetWindowDpi() + { + if (UnmanagedMethods.ShCoreAvailable) + { + uint dpix, dpiy; + + var monitor = UnmanagedMethods.MonitorFromWindow( + _hwnd, + UnmanagedMethods.MONITOR.MONITOR_DEFAULTTONEAREST); + + if (UnmanagedMethods.GetDpiForMonitor( + monitor, + UnmanagedMethods.MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, + out dpix, + out dpiy) == 0) + { + return new Size2F(dpix, dpiy); + } + } + + return new Size2F(96, 96); + } + + protected override Size2 GetWindowSize() + { + UnmanagedMethods.RECT rc; + UnmanagedMethods.GetClientRect(_hwnd, out rc); + return new Size2(rc.right - rc.left, rc.bottom - rc.top); + } + } +} diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs index 75a0f43d9f..decf3c6fc6 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs @@ -27,6 +27,8 @@ namespace Avalonia.Direct2D1.Media /// private SharpDX.DirectWrite.Factory _directWriteFactory; + private SharpDX.DXGI.SwapChain1 _swapChain; + /// /// Initializes a new instance of the class. /// @@ -34,10 +36,12 @@ namespace Avalonia.Direct2D1.Media /// The DirectWrite factory. public DrawingContext( SharpDX.Direct2D1.RenderTarget renderTarget, - SharpDX.DirectWrite.Factory directWriteFactory) + SharpDX.DirectWrite.Factory directWriteFactory, + SharpDX.DXGI.SwapChain1 swapChain = null) { _renderTarget = renderTarget; _directWriteFactory = directWriteFactory; + _swapChain = swapChain; _renderTarget.BeginDraw(); } @@ -60,6 +64,8 @@ namespace Avalonia.Direct2D1.Media try { _renderTarget.EndDraw(); + + _swapChain?.Present(1, SharpDX.DXGI.PresentFlags.None); } catch (SharpDXException ex) when((uint)ex.HResult == 0x8899000C) // D2DERR_RECREATE_TARGET { diff --git a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs new file mode 100644 index 0000000000..a7b2f532c2 --- /dev/null +++ b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Avalonia.Media; +using Avalonia.Platform; +using Avalonia.Win32.Interop; +using SharpDX; +using SharpDX.Direct2D1; +using SharpDX.DXGI; +using AlphaMode = SharpDX.Direct2D1.AlphaMode; +using Device = SharpDX.Direct2D1.Device; +using Factory = SharpDX.Direct2D1.Factory; +using Factory2 = SharpDX.DXGI.Factory2; + +namespace Avalonia.Direct2D1 +{ + public abstract class SwapChainRenderTarget : IRenderTarget + { + private Size2 _savedSize; + private Size2F _savedDpi; + private DeviceContext _deviceContext; + private SwapChain1 _swapChain; + + protected SwapChainRenderTarget() + { + Device = AvaloniaLocator.Current.GetService(); + Direct2DFactory = AvaloniaLocator.Current.GetService(); + DirectWriteFactory = AvaloniaLocator.Current.GetService(); + } + + + /// + /// Gets the Direct2D factory. + /// + public Factory Direct2DFactory + { + get; + } + + /// + /// Gets the DirectWrite factory. + /// + public SharpDX.DirectWrite.Factory DirectWriteFactory + { + get; + } + + protected SharpDX.DXGI.Device Device { get; } + + /// + /// Creates a drawing context for a rendering session. + /// + /// An . + public DrawingContext CreateDrawingContext() + { + var size = GetWindowSize(); + var dpi = GetWindowDpi(); + + if (size != _savedSize || dpi != _savedDpi) + { + _savedSize = size; + _savedDpi = dpi; + CreateSwapChain(); + } + + return new DrawingContext(new Media.DrawingContext(_deviceContext, DirectWriteFactory, _swapChain)); + } + + public void Dispose() + { + _deviceContext.Dispose(); + _swapChain.Dispose(); + } + + private void CreateSwapChain() + { + using (var d2dDevice = new Device(Device)) + using (var dxgiAdaptor = Device.Adapter) + using (var dxgiFactory = dxgiAdaptor.GetParent()) + { + _deviceContext?.Dispose(); + _deviceContext = new DeviceContext(d2dDevice, DeviceContextOptions.None); + + var swapChainDesc = new SwapChainDescription1 + { + Width = _savedSize.Width, + Height = _savedSize.Height, + Format = Format.B8G8R8A8_UNorm, + Stereo = false, + SampleDescription = new SampleDescription + { + Count = 1, + Quality = 0, + }, + Usage = Usage.RenderTargetOutput, + BufferCount = 2, + Scaling = Scaling.None, + SwapEffect = SwapEffect.FlipSequential, + Flags = 0, + }; + + var dpi = Direct2DFactory.DesktopDpi; + + _swapChain?.Dispose(); + _swapChain = CreateSwapChain(dxgiFactory, swapChainDesc); + + using (var dxgiBackBuffer = _swapChain.GetBackBuffer(0)) + using (var d2dBackBuffer = new Bitmap1( + _deviceContext, + dxgiBackBuffer, + new BitmapProperties1( + new PixelFormat + { + AlphaMode = AlphaMode.Ignore, + Format = Format.B8G8R8A8_UNorm + }, + _savedDpi.Width, + _savedDpi.Height, + BitmapOptions.Target | BitmapOptions.CannotDraw))) + { + _deviceContext.Target = d2dBackBuffer; + } + } + } + + protected abstract SwapChain1 CreateSwapChain(Factory2 dxgiFactory, SwapChainDescription1 swapChainDesc); + + protected abstract Size2F GetWindowDpi(); + + protected abstract Size2 GetWindowSize(); + } +} diff --git a/src/Windows/Avalonia.Direct2D1/app.config b/src/Windows/Avalonia.Direct2D1/app.config index 743de168f3..60a1012655 100644 --- a/src/Windows/Avalonia.Direct2D1/app.config +++ b/src/Windows/Avalonia.Direct2D1/app.config @@ -8,11 +8,11 @@ - + - + diff --git a/src/Windows/Avalonia.Direct2D1/packages.config b/src/Windows/Avalonia.Direct2D1/packages.config index 57031c2b9d..780e6014e5 100644 --- a/src/Windows/Avalonia.Direct2D1/packages.config +++ b/src/Windows/Avalonia.Direct2D1/packages.config @@ -1,6 +1,7 @@  - - - + + + + \ No newline at end of file From cc4c3d02d0fcb61b74843b8391597ac2f2058d20 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 11 Jan 2017 11:08:12 -0600 Subject: [PATCH 3/9] Fixed DPI issues. --- src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs | 1 + src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs index decf3c6fc6..486116c27b 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs @@ -34,6 +34,7 @@ namespace Avalonia.Direct2D1.Media /// /// The render target to draw to. /// The DirectWrite factory. + /// An optional swap chain associated with this drawing context. public DrawingContext( SharpDX.Direct2D1.RenderTarget renderTarget, SharpDX.DirectWrite.Factory directWriteFactory, diff --git a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs index a7b2f532c2..2fbf65ed15 100644 --- a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs +++ b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs @@ -81,7 +81,8 @@ namespace Avalonia.Direct2D1 using (var dxgiFactory = dxgiAdaptor.GetParent()) { _deviceContext?.Dispose(); - _deviceContext = new DeviceContext(d2dDevice, DeviceContextOptions.None); + _deviceContext = new DeviceContext(d2dDevice, DeviceContextOptions.None) {DotsPerInch = _savedDpi}; + var swapChainDesc = new SwapChainDescription1 { @@ -101,8 +102,6 @@ namespace Avalonia.Direct2D1 Flags = 0, }; - var dpi = Direct2DFactory.DesktopDpi; - _swapChain?.Dispose(); _swapChain = CreateSwapChain(dxgiFactory, swapChainDesc); From bde461f4005458cb69d266ddaa63cd4371fff1e6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 11 Jan 2017 11:30:36 -0600 Subject: [PATCH 4/9] Use the factory associated with the Direct2D1 device. --- .../Avalonia.Direct2D1/Direct2D1Platform.cs | 21 +++++++++---------- .../Avalonia.Direct2D1/HwndRenderTarget.cs | 2 +- .../SwapChainRenderTarget.cs | 12 ++++++----- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index f86fa0b93a..c1ce7ce6f8 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -28,17 +28,13 @@ namespace Avalonia.Direct2D1 { private static readonly Direct2D1Platform s_instance = new Direct2D1Platform(); - private static readonly SharpDX.Direct2D1.Factory s_d2D1Factory = -#if DEBUG - new SharpDX.Direct2D1.Factory(SharpDX.Direct2D1.FactoryType.MultiThreaded, SharpDX.Direct2D1.DebugLevel.Error); -#else - new SharpDX.Direct2D1.Factory(SharpDX.Direct2D1.FactoryType.MultiThreaded, SharpDX.Direct2D1.DebugLevel.None); -#endif private static readonly SharpDX.DirectWrite.Factory s_dwfactory = new SharpDX.DirectWrite.Factory(); private static readonly SharpDX.WIC.ImagingFactory s_imagingFactory = new SharpDX.WIC.ImagingFactory(); - private static readonly SharpDX.DXGI.Device s_device; + private static readonly SharpDX.DXGI.Device s_dxgiDevice; + + private static readonly SharpDX.Direct2D1.Device s_d2d1Device; static Direct2D1Platform() { @@ -60,17 +56,20 @@ namespace Avalonia.Direct2D1 SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport, featureLevels)) { - s_device = d3dDevice.QueryInterface(); + s_dxgiDevice = d3dDevice.QueryInterface(); } + + s_d2d1Device = new SharpDX.Direct2D1.Device(s_dxgiDevice); } public static void Initialize() => AvaloniaLocator.CurrentMutable .Bind().ToConstant(s_instance) .Bind().ToConstant(s_instance) - .BindToSelf(s_d2D1Factory) + .BindToSelf(s_d2d1Device.Factory) .BindToSelf(s_dwfactory) .BindToSelf(s_imagingFactory) - .BindToSelf(s_device); + .BindToSelf(s_dxgiDevice) + .BindToSelf(s_d2d1Device); public IBitmapImpl CreateBitmap(int width, int height) { @@ -110,7 +109,7 @@ namespace Avalonia.Direct2D1 public IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height) { - return new RenderTargetBitmapImpl(s_imagingFactory, s_d2D1Factory, width, height); + return new RenderTargetBitmapImpl(s_imagingFactory, s_d2d1Device.Factory, width, height); } public IStreamGeometryImpl CreateStreamGeometry() diff --git a/src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs b/src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs index 5c0c460dcb..49d4c91c52 100644 --- a/src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs +++ b/src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs @@ -20,7 +20,7 @@ namespace Avalonia.Direct2D1 protected override SwapChain1 CreateSwapChain(Factory2 dxgiFactory, SwapChainDescription1 swapChainDesc) { - return new SwapChain1(dxgiFactory, Device, _hwnd, ref swapChainDesc); + return new SwapChain1(dxgiFactory, DxgiDevice, _hwnd, ref swapChainDesc); } protected override Size2F GetWindowDpi() diff --git a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs index 2fbf65ed15..0d3799f1b1 100644 --- a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs +++ b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs @@ -25,7 +25,8 @@ namespace Avalonia.Direct2D1 protected SwapChainRenderTarget() { - Device = AvaloniaLocator.Current.GetService(); + DxgiDevice = AvaloniaLocator.Current.GetService(); + D2DDevice = AvaloniaLocator.Current.GetService(); Direct2DFactory = AvaloniaLocator.Current.GetService(); DirectWriteFactory = AvaloniaLocator.Current.GetService(); } @@ -47,7 +48,9 @@ namespace Avalonia.Direct2D1 get; } - protected SharpDX.DXGI.Device Device { get; } + protected SharpDX.DXGI.Device DxgiDevice { get; } + + public Device D2DDevice { get; } /// /// Creates a drawing context for a rendering session. @@ -76,12 +79,11 @@ namespace Avalonia.Direct2D1 private void CreateSwapChain() { - using (var d2dDevice = new Device(Device)) - using (var dxgiAdaptor = Device.Adapter) + using (var dxgiAdaptor = DxgiDevice.Adapter) using (var dxgiFactory = dxgiAdaptor.GetParent()) { _deviceContext?.Dispose(); - _deviceContext = new DeviceContext(d2dDevice, DeviceContextOptions.None) {DotsPerInch = _savedDpi}; + _deviceContext = new DeviceContext(D2DDevice, DeviceContextOptions.None) {DotsPerInch = _savedDpi}; var swapChainDesc = new SwapChainDescription1 From 4575c1abc9841f7ebf3bf5e3eb69d90f2b30b619 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 11 Jan 2017 11:38:20 -0600 Subject: [PATCH 5/9] Updated Resharper naming rules to match our conventions. --- Avalonia.sln.DotSettings | 2 +- src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Avalonia.sln.DotSettings b/Avalonia.sln.DotSettings index 16c9218a7e..ab21d6e50b 100644 --- a/Avalonia.sln.DotSettings +++ b/Avalonia.sln.DotSettings @@ -30,7 +30,7 @@ <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="s_" Suffix="" Style="aaBb" /></Policy> + <Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /> <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index c1ce7ce6f8..6d6e1a1149 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -34,7 +34,7 @@ namespace Avalonia.Direct2D1 private static readonly SharpDX.DXGI.Device s_dxgiDevice; - private static readonly SharpDX.Direct2D1.Device s_d2d1Device; + private static readonly SharpDX.Direct2D1.Device s_d2D1Device; static Direct2D1Platform() { @@ -59,17 +59,17 @@ namespace Avalonia.Direct2D1 s_dxgiDevice = d3dDevice.QueryInterface(); } - s_d2d1Device = new SharpDX.Direct2D1.Device(s_dxgiDevice); + s_d2D1Device = new SharpDX.Direct2D1.Device(s_dxgiDevice); } public static void Initialize() => AvaloniaLocator.CurrentMutable .Bind().ToConstant(s_instance) .Bind().ToConstant(s_instance) - .BindToSelf(s_d2d1Device.Factory) + .BindToSelf(s_d2D1Device.Factory) .BindToSelf(s_dwfactory) .BindToSelf(s_imagingFactory) .BindToSelf(s_dxgiDevice) - .BindToSelf(s_d2d1Device); + .BindToSelf(s_d2D1Device); public IBitmapImpl CreateBitmap(int width, int height) { @@ -109,7 +109,7 @@ namespace Avalonia.Direct2D1 public IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height) { - return new RenderTargetBitmapImpl(s_imagingFactory, s_d2d1Device.Factory, width, height); + return new RenderTargetBitmapImpl(s_imagingFactory, s_d2D1Device.Factory, width, height); } public IStreamGeometryImpl CreateStreamGeometry() From d02b7cbe9285e3056c3a94852ebc832e8c76a447 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 11 Jan 2017 11:56:20 -0600 Subject: [PATCH 6/9] Create D2D1 device with a factory. --- .../Avalonia.Direct2D1/Direct2D1Platform.cs | 14 +++- .../Avalonia.Direct2D1/RenderTarget.cs | 79 ------------------- .../SwapChainRenderTarget.cs | 4 +- 3 files changed, 13 insertions(+), 84 deletions(-) diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 6d6e1a1149..f4515a3814 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -8,7 +8,6 @@ using Avalonia.Media; using Avalonia.Platform; using Avalonia.Controls; using Avalonia.Rendering; -using SharpDX.Direct3D11; namespace Avalonia { @@ -28,6 +27,12 @@ namespace Avalonia.Direct2D1 { private static readonly Direct2D1Platform s_instance = new Direct2D1Platform(); + private static readonly SharpDX.Direct2D1.Factory s_d2D1Factory = +#if DEBUG + new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded, SharpDX.Direct2D1.DebugLevel.Error); +#else + new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded, SharpDX.Direct2D1.DebugLevel.None); +#endif private static readonly SharpDX.DirectWrite.Factory s_dwfactory = new SharpDX.DirectWrite.Factory(); private static readonly SharpDX.WIC.ImagingFactory s_imagingFactory = new SharpDX.WIC.ImagingFactory(); @@ -59,13 +64,16 @@ namespace Avalonia.Direct2D1 s_dxgiDevice = d3dDevice.QueryInterface(); } - s_d2D1Device = new SharpDX.Direct2D1.Device(s_dxgiDevice); + using (var factory1 = s_d2D1Factory.QueryInterface()) + { + s_d2D1Device = new SharpDX.Direct2D1.Device(factory1, s_dxgiDevice); + } } public static void Initialize() => AvaloniaLocator.CurrentMutable .Bind().ToConstant(s_instance) .Bind().ToConstant(s_instance) - .BindToSelf(s_d2D1Device.Factory) + .BindToSelf(s_d2D1Factory) .BindToSelf(s_dwfactory) .BindToSelf(s_imagingFactory) .BindToSelf(s_dxgiDevice) diff --git a/src/Windows/Avalonia.Direct2D1/RenderTarget.cs b/src/Windows/Avalonia.Direct2D1/RenderTarget.cs index 180e1a7472..52146d77c1 100644 --- a/src/Windows/Avalonia.Direct2D1/RenderTarget.cs +++ b/src/Windows/Avalonia.Direct2D1/RenderTarget.cs @@ -13,42 +13,11 @@ namespace Avalonia.Direct2D1 { public class RenderTarget : IRenderTarget { - private readonly IntPtr _hwnd; - private Size2 _savedSize; - private Size2F _savedDpi; - /// /// The render target. /// private readonly SharpDX.Direct2D1.RenderTarget _renderTarget; - /// - /// Initializes a new instance of the class. - /// - /// The window handle. - public RenderTarget(IntPtr hwnd) - { - _hwnd = hwnd; - Direct2DFactory = AvaloniaLocator.Current.GetService(); - DirectWriteFactory = AvaloniaLocator.Current.GetService(); - - RenderTargetProperties renderTargetProperties = new RenderTargetProperties - { - }; - - HwndRenderTargetProperties hwndProperties = new HwndRenderTargetProperties - { - Hwnd = hwnd, - PixelSize = _savedSize = GetWindowSize(), - PresentOptions = PresentOptions.Immediately, - }; - - _renderTarget = new WindowRenderTarget( - Direct2DFactory, - renderTargetProperties, - hwndProperties); - } - /// /// Initializes a new instance of the class. /// @@ -82,24 +51,6 @@ namespace Avalonia.Direct2D1 /// An . public DrawingContext CreateDrawingContext() { - var window = _renderTarget as WindowRenderTarget; - - if (window != null) - { - var size = GetWindowSize(); - var dpi = GetWindowDpi(); - - if (size != _savedSize) - { - window.Resize(_savedSize = size); - } - - if (dpi != _savedDpi) - { - window.DotsPerInch = _savedDpi = dpi; - } - } - return new DrawingContext(new Media.DrawingContext(_renderTarget, DirectWriteFactory)); } @@ -107,35 +58,5 @@ namespace Avalonia.Direct2D1 { _renderTarget.Dispose(); } - - private Size2F GetWindowDpi() - { - if (UnmanagedMethods.ShCoreAvailable) - { - uint dpix, dpiy; - - var monitor = UnmanagedMethods.MonitorFromWindow( - _hwnd, - UnmanagedMethods.MONITOR.MONITOR_DEFAULTTONEAREST); - - if (UnmanagedMethods.GetDpiForMonitor( - monitor, - UnmanagedMethods.MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, - out dpix, - out dpiy) == 0) - { - return new Size2F(dpix, dpiy); - } - } - - return new Size2F(96, 96); - } - - private Size2 GetWindowSize() - { - UnmanagedMethods.RECT rc; - UnmanagedMethods.GetClientRect(_hwnd, out rc); - return new Size2(rc.right - rc.left, rc.bottom - rc.top); - } } } diff --git a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs index 0d3799f1b1..8362305b9f 100644 --- a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs +++ b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs @@ -73,8 +73,8 @@ namespace Avalonia.Direct2D1 public void Dispose() { - _deviceContext.Dispose(); - _swapChain.Dispose(); + _deviceContext?.Dispose(); + _swapChain?.Dispose(); } private void CreateSwapChain() From e2ba8fb5bb0b25e61d8774d5461e3b124969b54b Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 11 Jan 2017 13:15:13 -0600 Subject: [PATCH 7/9] Make video support creation flag only be set when running on Windows 8 or newer (Direct3D11.1 or newer). --- src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index f4515a3814..69e0811b5e 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -55,10 +55,16 @@ namespace Avalonia.Direct2D1 SharpDX.Direct3D.FeatureLevel.Level_9_2, SharpDX.Direct3D.FeatureLevel.Level_9_1, }; + var creationFlags = SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport; + var osVersion = Environment.OSVersion.Version; + if (osVersion.Major > 6 || (osVersion.Major == 6 && osVersion.Minor >= 2)) // If Windows 8 or newer + { + creationFlags |= SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport; + } using (var d3dDevice = new SharpDX.Direct3D11.Device( SharpDX.Direct3D.DriverType.Hardware, - SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport, + creationFlags, featureLevels)) { s_dxgiDevice = d3dDevice.QueryInterface(); From 9d73868da75d1ad53844814066ec15dab4cbca7c Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 11 Jan 2017 13:29:54 -0600 Subject: [PATCH 8/9] Remove the VideoSupport flag because AppVeyor machines do not support it. --- src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 69e0811b5e..49a5130282 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -55,16 +55,10 @@ namespace Avalonia.Direct2D1 SharpDX.Direct3D.FeatureLevel.Level_9_2, SharpDX.Direct3D.FeatureLevel.Level_9_1, }; - var creationFlags = SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport; - var osVersion = Environment.OSVersion.Version; - if (osVersion.Major > 6 || (osVersion.Major == 6 && osVersion.Minor >= 2)) // If Windows 8 or newer - { - creationFlags |= SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport; - } using (var d3dDevice = new SharpDX.Direct3D11.Device( SharpDX.Direct3D.DriverType.Hardware, - creationFlags, + SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport, featureLevels)) { s_dxgiDevice = d3dDevice.QueryInterface(); From 619e64ef1d7c4f4a3c08c43ddda910861addd44b Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 11 Jan 2017 15:28:17 -0600 Subject: [PATCH 9/9] Remove DirectX 12 feature level choices. Device will be created with feature levels up to DirectX 11.1 (Windows 8), which is all we use. --- src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 49a5130282..a073407a6c 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -45,8 +45,6 @@ namespace Avalonia.Direct2D1 { var featureLevels = new[] { - SharpDX.Direct3D.FeatureLevel.Level_12_1, - SharpDX.Direct3D.FeatureLevel.Level_12_0, SharpDX.Direct3D.FeatureLevel.Level_11_1, SharpDX.Direct3D.FeatureLevel.Level_11_0, SharpDX.Direct3D.FeatureLevel.Level_10_1, @@ -58,7 +56,7 @@ namespace Avalonia.Direct2D1 using (var d3dDevice = new SharpDX.Direct3D11.Device( SharpDX.Direct3D.DriverType.Hardware, - SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport, + SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport, featureLevels)) { s_dxgiDevice = d3dDevice.QueryInterface();