Browse Source

Port Direct2D code from master.

Steven Kirk 8 years ago
parent
commit
3d76a5040c

+ 69 - 41
src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs

@@ -9,7 +9,9 @@ using Avalonia.Direct2D1.Media;
 using Avalonia.Media;
 using Avalonia.Platform;
 using Avalonia.Controls;
+using Avalonia.Controls.Platform.Surfaces;
 using Avalonia.Direct2D1.Media.Imaging;
+using Avalonia.Rendering;
 
 namespace Avalonia
 {
@@ -29,57 +31,83 @@ namespace Avalonia.Direct2D1
     {
         private static readonly Direct2D1Platform s_instance = new Direct2D1Platform();
 
-        private static readonly SharpDX.Direct2D1.Factory1 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<SharpDX.DXGI.Device>();
-            }
+        private static SharpDX.Direct2D1.Device s_d2D1Device;
 
-            using (var factory1 = s_d2D1Factory.QueryInterface<SharpDX.Direct2D1.Factory1>())
+        private static readonly object s_initLock = new object();
+        private static bool s_initialized = false;
+
+        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<SharpDX.DXGI.Device>();
+                }
+
+                using (var factory1 = s_d2D1Factory.QueryInterface<SharpDX.Direct2D1.Factory1>())
+                {
+                    s_d2D1Device = new SharpDX.Direct2D1.Device(factory1, s_dxgiDevice);
+                }
+                s_initialized = true;
             }
         }
 
         public static void Initialize()
         {
+            InitializeDirect2D();
             AvaloniaLocator.CurrentMutable
-                .Bind<IPlatformRenderInterface>().ToConstant(s_instance)
-                .Bind<SharpDX.Direct2D1.Factory>().ToConstant(s_d2D1Factory)
-                .Bind<SharpDX.Direct2D1.Factory1>().ToConstant(s_d2D1Factory)
-                .BindToSelf(s_dwfactory)
-                .BindToSelf(s_imagingFactory)
-                .BindToSelf(s_dxgiDevice)
-                .BindToSelf(s_d2D1Device);
+                        .Bind<IPlatformRenderInterface>().ToConstant(s_instance)
+                        .BindToSelf(s_d2D1Factory)
+                        .BindToSelf(s_dwfactory)
+                        .BindToSelf(s_imagingFactory)
+                        .BindToSelf(s_dxgiDevice)
+                        .BindToSelf(s_d2D1Device);
             SharpDX.Configuration.EnableReleaseOnFinalizer = true;
         }
 
@@ -110,7 +138,7 @@ namespace Avalonia.Direct2D1
             var nativeWindow = surfaces?.OfType<IPlatformHandle>().FirstOrDefault();
             if (nativeWindow != null)
             {
-                if(nativeWindow.HandleDescriptor != "HWND")
+                if (nativeWindow.HandleDescriptor != "HWND")
                     throw new NotSupportedException("Don't know how to create a Direct2D1 renderer from " + nativeWindow.HandleDescriptor);
                 return new HwndRenderTarget(nativeWindow);
             }
@@ -158,4 +186,4 @@ namespace Avalonia.Direct2D1
             return new WicBitmapImpl(s_imagingFactory, format, data, width, height, stride);
         }
     }
-}
+}

+ 15 - 1
src/Windows/Avalonia.Direct2D1/Direct2DChecker.cs

@@ -10,6 +10,20 @@ namespace Avalonia.Direct2D1
     class Direct2DChecker : IModuleEnvironmentChecker
     {
         //Direct2D backend doesn't work on some machines anymore
-        public bool IsCompatible => true;
+        public bool IsCompatible
+        {
+            get
+            {
+                try
+                {
+                    Direct2D1Platform.InitializeDirect2D();
+                    return true;
+                }
+                catch
+                {
+                    return false;
+                }
+            }
+        }
     }
 }