Direct2D1Platform.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using Avalonia.Direct2D1.Media;
  8. using Avalonia.Media;
  9. using Avalonia.Platform;
  10. using Avalonia.Controls;
  11. using Avalonia.Controls.Platform.Surfaces;
  12. using Avalonia.Direct2D1.Media.Imaging;
  13. using Avalonia.Rendering;
  14. namespace Avalonia
  15. {
  16. public static class Direct2DApplicationExtensions
  17. {
  18. public static T UseDirect2D1<T>(this T builder) where T : AppBuilderBase<T>, new()
  19. {
  20. builder.UseRenderingSubsystem(Direct2D1.Direct2D1Platform.Initialize, "Direct2D1");
  21. return builder;
  22. }
  23. }
  24. }
  25. namespace Avalonia.Direct2D1
  26. {
  27. public class Direct2D1Platform : IPlatformRenderInterface
  28. {
  29. private static readonly Direct2D1Platform s_instance = new Direct2D1Platform();
  30. private static SharpDX.Direct2D1.Factory s_d2D1Factory;
  31. private static SharpDX.DirectWrite.Factory s_dwfactory;
  32. private static SharpDX.WIC.ImagingFactory s_imagingFactory;
  33. private static SharpDX.DXGI.Device s_dxgiDevice;
  34. private static SharpDX.Direct2D1.Device s_d2D1Device;
  35. private static readonly object s_initLock = new object();
  36. private static bool s_initialized = false;
  37. internal static void InitializeDirect2D()
  38. {
  39. lock (s_initLock)
  40. {
  41. if (s_initialized)
  42. return;
  43. #if DEBUG
  44. try
  45. {
  46. s_d2D1Factory =
  47. new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded,
  48. SharpDX.Direct2D1.DebugLevel.Error);
  49. }
  50. catch
  51. {
  52. //
  53. }
  54. #endif
  55. s_dwfactory = new SharpDX.DirectWrite.Factory();
  56. s_imagingFactory = new SharpDX.WIC.ImagingFactory();
  57. if (s_d2D1Factory == null)
  58. s_d2D1Factory = new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded,
  59. SharpDX.Direct2D1.DebugLevel.None);
  60. var featureLevels = new[]
  61. {
  62. SharpDX.Direct3D.FeatureLevel.Level_11_1,
  63. SharpDX.Direct3D.FeatureLevel.Level_11_0,
  64. SharpDX.Direct3D.FeatureLevel.Level_10_1,
  65. SharpDX.Direct3D.FeatureLevel.Level_10_0,
  66. SharpDX.Direct3D.FeatureLevel.Level_9_3,
  67. SharpDX.Direct3D.FeatureLevel.Level_9_2,
  68. SharpDX.Direct3D.FeatureLevel.Level_9_1,
  69. };
  70. using (var d3dDevice = new SharpDX.Direct3D11.Device(
  71. SharpDX.Direct3D.DriverType.Hardware,
  72. SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport |
  73. SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport,
  74. featureLevels))
  75. {
  76. s_dxgiDevice = d3dDevice.QueryInterface<SharpDX.DXGI.Device>();
  77. }
  78. using (var factory1 = s_d2D1Factory.QueryInterface<SharpDX.Direct2D1.Factory1>())
  79. {
  80. s_d2D1Device = new SharpDX.Direct2D1.Device(factory1, s_dxgiDevice);
  81. }
  82. s_initialized = true;
  83. }
  84. }
  85. public static void Initialize()
  86. {
  87. InitializeDirect2D();
  88. AvaloniaLocator.CurrentMutable
  89. .Bind<IPlatformRenderInterface>().ToConstant(s_instance)
  90. .BindToSelf(s_d2D1Factory)
  91. .BindToSelf(s_dwfactory)
  92. .BindToSelf(s_imagingFactory)
  93. .BindToSelf(s_dxgiDevice)
  94. .BindToSelf(s_d2D1Device);
  95. SharpDX.Configuration.EnableReleaseOnFinalizer = true;
  96. }
  97. public IBitmapImpl CreateBitmap(int width, int height)
  98. {
  99. return new WicBitmapImpl(s_imagingFactory, width, height);
  100. }
  101. public IFormattedTextImpl CreateFormattedText(
  102. string text,
  103. Typeface typeface,
  104. TextAlignment textAlignment,
  105. TextWrapping wrapping,
  106. Size constraint,
  107. IReadOnlyList<FormattedTextStyleSpan> spans)
  108. {
  109. return new FormattedTextImpl(
  110. text,
  111. typeface,
  112. textAlignment,
  113. wrapping,
  114. constraint,
  115. spans);
  116. }
  117. public IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces)
  118. {
  119. var nativeWindow = surfaces?.OfType<IPlatformHandle>().FirstOrDefault();
  120. if (nativeWindow != null)
  121. {
  122. if (nativeWindow.HandleDescriptor != "HWND")
  123. throw new NotSupportedException("Don't know how to create a Direct2D1 renderer from " + nativeWindow.HandleDescriptor);
  124. return new HwndRenderTarget(nativeWindow);
  125. }
  126. throw new NotSupportedException("Don't know how to create a Direct2D1 renderer from any of provided surfaces");
  127. }
  128. public IRenderTargetBitmapImpl CreateRenderTargetBitmap(
  129. int width,
  130. int height,
  131. double dpiX,
  132. double dpiY)
  133. {
  134. return new RenderTargetBitmapImpl(
  135. s_imagingFactory,
  136. s_d2D1Factory,
  137. s_dwfactory,
  138. width,
  139. height,
  140. dpiX,
  141. dpiY);
  142. }
  143. public IWritableBitmapImpl CreateWritableBitmap(int width, int height, PixelFormat? format = null)
  144. {
  145. return new WritableWicBitmapImpl(s_imagingFactory, width, height, format);
  146. }
  147. public IStreamGeometryImpl CreateStreamGeometry()
  148. {
  149. return new StreamGeometryImpl();
  150. }
  151. public IBitmapImpl LoadBitmap(string fileName)
  152. {
  153. return new WicBitmapImpl(s_imagingFactory, fileName);
  154. }
  155. public IBitmapImpl LoadBitmap(Stream stream)
  156. {
  157. return new WicBitmapImpl(s_imagingFactory, stream);
  158. }
  159. public IBitmapImpl LoadBitmap(PixelFormat format, IntPtr data, int width, int height, int stride)
  160. {
  161. return new WicBitmapImpl(s_imagingFactory, format, data, width, height, stride);
  162. }
  163. }
  164. }