From 06aa7780fbc0cee0eb231c9f0610fdc946cc4a0f Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Mon, 1 May 2017 15:16:21 +0300 Subject: [PATCH] Moved Direct2D initialization away from static constructor --- .../Avalonia.Direct2D1.csproj | 2 +- .../Avalonia.Direct2D1/Direct2D1Platform.cs | 91 ++++++++++++------- .../Avalonia.Direct2D1/Direct2DChecker.cs | 29 ++++++ .../Properties/AssemblyInfo.cs | 2 +- .../WindowsVersionChecker.cs | 15 --- 5 files changed, 90 insertions(+), 49 deletions(-) create mode 100644 src/Windows/Avalonia.Direct2D1/Direct2DChecker.cs delete mode 100644 src/Windows/Avalonia.Direct2D1/WindowsVersionChecker.cs diff --git a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj index e71201b949..ab62f5ac75 100644 --- a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj +++ b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj @@ -73,7 +73,7 @@ - + diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 7ac527bb1e..469c29d626 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -31,49 +31,76 @@ 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 SharpDX.Direct2D1.Factory s_d2D1Factory; - private static readonly SharpDX.WIC.ImagingFactory s_imagingFactory = new SharpDX.WIC.ImagingFactory(); + private static SharpDX.DirectWrite.Factory s_dwfactory; - private static readonly SharpDX.DXGI.Device s_dxgiDevice; + private static SharpDX.WIC.ImagingFactory s_imagingFactory; - private static readonly SharpDX.Direct2D1.Device s_d2D1Device; + private static SharpDX.DXGI.Device s_dxgiDevice; - static Direct2D1Platform() - { - var featureLevels = new[] - { - 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_dxgiDevice = d3dDevice.QueryInterface(); - } + private static SharpDX.Direct2D1.Device s_d2D1Device; + + private static readonly object s_initLock = new object(); + private static bool s_initialized = false; - using (var factory1 = s_d2D1Factory.QueryInterface()) + internal static void InitializeDirect2D() + { + lock (s_initLock) { - s_d2D1Device = new SharpDX.Direct2D1.Device(factory1, s_dxgiDevice); + if (s_initialized) + return; +#if DEBUG + try + { + s_d2D1Factory = + + new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded, + SharpDX.Direct2D1.DebugLevel.Error); + } + catch + { + // + } +#endif + s_dwfactory = new SharpDX.DirectWrite.Factory(); + s_imagingFactory = new SharpDX.WIC.ImagingFactory(); + if (s_d2D1Factory == null) + s_d2D1Factory = new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded, + SharpDX.Direct2D1.DebugLevel.None); + + + var featureLevels = new[] + { + 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_dxgiDevice = d3dDevice.QueryInterface(); + } + + using (var factory1 = s_d2D1Factory.QueryInterface()) + { + s_d2D1Device = new SharpDX.Direct2D1.Device(factory1, s_dxgiDevice); + } + s_initialized = true; } } public static void Initialize() { + InitializeDirect2D(); AvaloniaLocator.CurrentMutable .Bind().ToConstant(s_instance) .BindToSelf(s_d2D1Factory) diff --git a/src/Windows/Avalonia.Direct2D1/Direct2DChecker.cs b/src/Windows/Avalonia.Direct2D1/Direct2DChecker.cs new file mode 100644 index 0000000000..e7e27493e5 --- /dev/null +++ b/src/Windows/Avalonia.Direct2D1/Direct2DChecker.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Avalonia.Platform; + +namespace Avalonia.Direct2D1 +{ + class Direct2DChecker : IModuleEnvironmentChecker + { + //Direct2D backend doesn't work on some machines anymore + public bool IsCompatible + { + get + { + try + { + Direct2D1Platform.InitializeDirect2D(); + return true; + } + catch + { + return false; + } + } + } + } +} diff --git a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs index 63d9c5bfe3..c1c5b24048 100644 --- a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs +++ b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs @@ -7,5 +7,5 @@ using Avalonia.Direct2D1; [assembly: AssemblyTitle("Avalonia.Direct2D1")] [assembly: ExportRenderingSubsystem(OperatingSystemType.WinNT, 1, "Direct2D1", typeof(Direct2D1Platform), nameof(Direct2D1Platform.Initialize), - typeof(WindowsVersionChecker))] + typeof(Direct2DChecker))] diff --git a/src/Windows/Avalonia.Direct2D1/WindowsVersionChecker.cs b/src/Windows/Avalonia.Direct2D1/WindowsVersionChecker.cs deleted file mode 100644 index 875167b71a..0000000000 --- a/src/Windows/Avalonia.Direct2D1/WindowsVersionChecker.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Avalonia.Platform; - -namespace Avalonia.Direct2D1 -{ - class WindowsVersionChecker : IModuleEnvironmentChecker - { - //Direct2D backend doesn't work with Win7 anymore - public bool IsCompatible => Environment.OSVersion.Version >= new Version(6, 2); - } -}