Browse Source

Initial

pull/1861/head
Benedikt Schroeder 8 years ago
parent
commit
66bebd0c1b
  1. 91
      src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
  2. 22
      src/Windows/Avalonia.Direct2D1/ExternalRenderTarget.cs
  3. 27
      src/Windows/Avalonia.Direct2D1/FramebufferShimRenderTarget.cs
  4. 10
      src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs
  5. 13
      src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs
  6. 10
      src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
  7. 4
      src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs
  8. 3
      src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs
  9. 7
      src/Windows/Avalonia.Direct2D1/Media/Imaging/BitmapImpl.cs
  10. 28
      src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs
  11. 39
      src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs
  12. 33
      src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs
  13. 22
      src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs
  14. 8
      src/Windows/Avalonia.Direct2D1/Media/Imaging/WriteableWicBitmapImpl.cs
  15. 6
      src/Windows/Avalonia.Direct2D1/Media/StreamGeometryImpl.cs
  16. 19
      src/Windows/Avalonia.Direct2D1/RenderTarget.cs
  17. 55
      src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs

91
src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs

@ -4,14 +4,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Avalonia.Direct2D1.Media;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Controls;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media.Imaging;
using Avalonia.Rendering;
using Avalonia.Media;
using Avalonia.Platform;
namespace Avalonia
{
@ -31,15 +29,16 @@ namespace Avalonia.Direct2D1
{
private static readonly Direct2D1Platform s_instance = new Direct2D1Platform();
private static SharpDX.Direct2D1.Factory s_d2D1Factory;
public static SharpDX.Direct2D1.Factory1 Direct2D1Factory { get; private set; }
private static SharpDX.DirectWrite.Factory s_dwfactory;
public static SharpDX.Direct2D1.Device1 Direct2D1Device { get; private set; }
private static SharpDX.WIC.ImagingFactory s_imagingFactory;
public static SharpDX.DirectWrite.Factory1 DirectWriteFactory { get; private set; }
private static SharpDX.DXGI.Device s_dxgiDevice;
public static SharpDX.WIC.ImagingFactory ImagingFactory { get; private set; }
public static SharpDX.DXGI.Device1 DxgiDevice { get; private set; }
private static SharpDX.Direct2D1.Device s_d2D1Device;
private static readonly object s_initLock = new object();
private static bool s_initialized = false;
@ -49,13 +48,14 @@ namespace Avalonia.Direct2D1
lock (s_initLock)
{
if (s_initialized)
{
return;
}
#if DEBUG
try
{
s_d2D1Factory =
new SharpDX.Direct2D1.Factory1(SharpDX.Direct2D1.FactoryType.MultiThreaded,
Direct2D1Factory = new SharpDX.Direct2D1.Factory1(
SharpDX.Direct2D1.FactoryType.MultiThreaded,
SharpDX.Direct2D1.DebugLevel.Error);
}
catch
@ -63,12 +63,19 @@ namespace Avalonia.Direct2D1
//
}
#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,
if (Direct2D1Factory == null)
{
Direct2D1Factory = new SharpDX.Direct2D1.Factory1(
SharpDX.Direct2D1.FactoryType.MultiThreaded,
SharpDX.Direct2D1.DebugLevel.None);
}
using (var factory = new SharpDX.DirectWrite.Factory())
{
DirectWriteFactory = factory.QueryInterface<SharpDX.DirectWrite.Factory1>();
}
ImagingFactory = new SharpDX.WIC.ImagingFactory();
var featureLevels = new[]
{
@ -83,17 +90,18 @@ 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<SharpDX.DXGI.Device>();
DxgiDevice = d3dDevice.QueryInterface<SharpDX.DXGI.Device1>();
}
using (var factory1 = s_d2D1Factory.QueryInterface<SharpDX.Direct2D1.Factory1>())
using (var device = new SharpDX.Direct2D1.Device(Direct2D1Factory, DxgiDevice))
{
s_d2D1Device = new SharpDX.Direct2D1.Device(factory1, s_dxgiDevice);
Direct2D1Device = device.QueryInterface<SharpDX.Direct2D1.Device1>();
}
s_initialized = true;
}
}
@ -101,19 +109,13 @@ namespace Avalonia.Direct2D1
public static void Initialize()
{
InitializeDirect2D();
AvaloniaLocator.CurrentMutable
.Bind<IPlatformRenderInterface>().ToConstant(s_instance)
.BindToSelf(s_d2D1Factory)
.BindToSelf(s_dwfactory)
.BindToSelf(s_imagingFactory)
.BindToSelf(s_dxgiDevice)
.BindToSelf(s_d2D1Device);
AvaloniaLocator.CurrentMutable.Bind<IPlatformRenderInterface>().ToConstant(s_instance);
SharpDX.Configuration.EnableReleaseOnFinalizer = true;
}
public IBitmapImpl CreateBitmap(int width, int height)
{
return new WicBitmapImpl(s_imagingFactory, width, height);
return new WicBitmapImpl(width, height);
}
public IFormattedTextImpl CreateFormattedText(
@ -140,14 +142,22 @@ namespace Avalonia.Direct2D1
if (s is IPlatformHandle nativeWindow)
{
if (nativeWindow.HandleDescriptor != "HWND")
{
throw new NotSupportedException("Don't know how to create a Direct2D1 renderer from " +
nativeWindow.HandleDescriptor);
}
return new HwndRenderTarget(nativeWindow);
}
if (s is IExternalDirect2DRenderTargetSurface external)
return new ExternalRenderTarget(external, s_dwfactory, s_imagingFactory);
{
return new ExternalRenderTarget(external);
}
if (s is IFramebufferPlatformSurface fb)
return new FramebufferShimRenderTarget(fb, s_imagingFactory, s_d2D1Factory, s_dwfactory);
{
return new FramebufferShimRenderTarget(fb);
}
}
throw new NotSupportedException("Don't know how to create a Direct2D1 renderer from any of provided surfaces");
}
@ -158,19 +168,12 @@ namespace Avalonia.Direct2D1
double dpiX,
double dpiY)
{
return new WicRenderTargetBitmapImpl(
s_imagingFactory,
s_d2D1Factory,
s_dwfactory,
width,
height,
dpiX,
dpiY);
return new WicRenderTargetBitmapImpl(width, height, dpiX, dpiY);
}
public IWriteableBitmapImpl CreateWriteableBitmap(int width, int height, PixelFormat? format = null)
{
return new WriteableWicBitmapImpl(s_imagingFactory, width, height, format);
return new WriteableWicBitmapImpl(width, height, format);
}
public IStreamGeometryImpl CreateStreamGeometry()
@ -180,17 +183,17 @@ namespace Avalonia.Direct2D1
public IBitmapImpl LoadBitmap(string fileName)
{
return new WicBitmapImpl(s_imagingFactory, fileName);
return new WicBitmapImpl(fileName);
}
public IBitmapImpl LoadBitmap(Stream stream)
{
return new WicBitmapImpl(s_imagingFactory, stream);
return new WicBitmapImpl(stream);
}
public IBitmapImpl LoadBitmap(PixelFormat format, IntPtr data, int width, int height, int stride)
{
return new WicBitmapImpl(s_imagingFactory, format, data, width, height, stride);
return new WicBitmapImpl(format, data, width, height, stride);
}
}
}
}

22
src/Windows/Avalonia.Direct2D1/ExternalRenderTarget.cs

@ -1,27 +1,19 @@
using System;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Rendering;
using SharpDX;
using DirectWriteFactory = SharpDX.DirectWrite.Factory;
namespace Avalonia.Direct2D1
{
class ExternalRenderTarget : IRenderTarget, ILayerFactory
{
private readonly IExternalDirect2DRenderTargetSurface _externalRenderTargetProvider;
private readonly DirectWriteFactory _dwFactory;
private readonly SharpDX.WIC.ImagingFactory _wicFactory;
public ExternalRenderTarget(
IExternalDirect2DRenderTargetSurface externalRenderTargetProvider,
DirectWriteFactory dwFactory,
SharpDX.WIC.ImagingFactory wicFactory)
IExternalDirect2DRenderTargetSurface externalRenderTargetProvider)
{
_externalRenderTargetProvider = externalRenderTargetProvider;
_dwFactory = dwFactory;
_wicFactory = wicFactory;
}
public void Dispose()
@ -33,7 +25,7 @@ namespace Avalonia.Direct2D1
{
var target = _externalRenderTargetProvider.GetOrCreateRenderTarget();
_externalRenderTargetProvider.BeforeDrawing();
return new DrawingContextImpl(visualBrushRenderer, null, target, _dwFactory, _wicFactory, null, () =>
return new DrawingContextImpl(visualBrushRenderer, null, target, null, () =>
{
try
{
@ -48,12 +40,8 @@ namespace Avalonia.Direct2D1
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
var target = _externalRenderTargetProvider.GetOrCreateRenderTarget();
return D2DRenderTargetBitmapImpl.CreateCompatible(
_wicFactory,
_dwFactory,
target,
size);
var renderTarget = _externalRenderTargetProvider.GetOrCreateRenderTarget();
return D2DRenderTargetBitmapImpl.CreateCompatible(renderTarget, size);
}
}
}

27
src/Windows/Avalonia.Direct2D1/FramebufferShimRenderTarget.cs

@ -1,14 +1,9 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Win32.Interop;
using SharpDX.Direct2D1;
using SharpDX.WIC;
using PixelFormat = Avalonia.Platform.PixelFormat;
@ -17,22 +12,14 @@ namespace Avalonia.Direct2D1
class FramebufferShimRenderTarget : IRenderTarget
{
private readonly IFramebufferPlatformSurface _surface;
private readonly ImagingFactory _imagingFactory;
private readonly Factory _d2DFactory;
private readonly SharpDX.DirectWrite.Factory _dwriteFactory;
public FramebufferShimRenderTarget(IFramebufferPlatformSurface surface,
ImagingFactory imagingFactory, Factory d2dFactory, SharpDX.DirectWrite.Factory dwriteFactory)
public FramebufferShimRenderTarget(IFramebufferPlatformSurface surface)
{
_surface = surface;
_imagingFactory = imagingFactory;
_d2DFactory = d2dFactory;
_dwriteFactory = dwriteFactory;
}
public void Dispose()
{
{
}
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
@ -44,7 +31,7 @@ namespace Avalonia.Direct2D1
throw new ArgumentException("Unsupported pixel format: " + locked.Format);
}
return new FramebufferShim(locked, _imagingFactory, _d2DFactory, _dwriteFactory)
return new FramebufferShim(locked)
.CreateDrawingContext(visualBrushRenderer);
}
@ -52,10 +39,8 @@ namespace Avalonia.Direct2D1
{
private readonly ILockedFramebuffer _target;
public FramebufferShim(ILockedFramebuffer target,
ImagingFactory imagingFactory, Factory d2dFactory, SharpDX.DirectWrite.Factory dwriteFactory
) : base(imagingFactory, d2dFactory, dwriteFactory,
target.Width, target.Height, target.Dpi.X, target.Dpi.Y, target.Format)
public FramebufferShim(ILockedFramebuffer target) :
base(target.Width, target.Height, target.Dpi.X, target.Dpi.Y, target.Format)
{
_target = target;
}
@ -76,10 +61,8 @@ namespace Avalonia.Direct2D1
}
Dispose();
_target.Dispose();
});
}
}
}
}

10
src/Windows/Avalonia.Direct2D1/HwndRenderTarget.cs

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Platform;
using Avalonia.Platform;
using Avalonia.Win32.Interop;
using SharpDX;
using SharpDX.DXGI;
@ -22,7 +16,7 @@ namespace Avalonia.Direct2D1
protected override SwapChain1 CreateSwapChain(Factory2 dxgiFactory, SwapChainDescription1 swapChainDesc)
{
return new SwapChain1(dxgiFactory, DxgiDevice, _window.Handle, ref swapChainDesc);
return new SwapChain1(dxgiFactory, Direct2D1Platform.DxgiDevice, _window.Handle, ref swapChainDesc);
}
protected override Size2F GetWindowDpi()

13
src/Windows/Avalonia.Direct2D1/Media/Direct2D1FontCollectionCache.cs

@ -7,16 +7,13 @@ namespace Avalonia.Direct2D1.Media
internal static class Direct2D1FontCollectionCache
{
private static readonly ConcurrentDictionary<FontFamilyKey, SharpDX.DirectWrite.FontCollection> s_cachedCollections;
private static readonly SharpDX.DirectWrite.Factory s_factory;
private static readonly SharpDX.DirectWrite.FontCollection s_installedFontCollection;
static Direct2D1FontCollectionCache()
{
s_cachedCollections = new ConcurrentDictionary<FontFamilyKey, SharpDX.DirectWrite.FontCollection>();
s_factory = AvaloniaLocator.Current.GetService<SharpDX.DirectWrite.Factory>();
s_installedFontCollection = s_factory.GetSystemFontCollection(false);
s_installedFontCollection = Direct2D1Platform.DirectWriteFactory.GetSystemFontCollection(false);
}
public static SharpDX.DirectWrite.TextFormat GetTextFormat(Typeface typeface)
@ -39,7 +36,7 @@ namespace Avalonia.Direct2D1.Media
}
return new SharpDX.DirectWrite.TextFormat(
s_factory,
Direct2D1Platform.DirectWriteFactory,
fontFamilyName,
fontCollection,
(SharpDX.DirectWrite.FontWeight)typeface.Weight,
@ -57,9 +54,9 @@ namespace Avalonia.Direct2D1.Media
{
var assets = FontFamilyLoader.LoadFontAssets(key);
var fontLoader = new DWriteResourceFontLoader(s_factory, assets);
var fontLoader = new DWriteResourceFontLoader(Direct2D1Platform.DirectWriteFactory, assets);
return new SharpDX.DirectWrite.FontCollection(s_factory, fontLoader, fontLoader.Key);
return new SharpDX.DirectWrite.FontCollection(Direct2D1Platform.DirectWriteFactory, fontLoader, fontLoader.Key);
}
}
}
}

10
src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs

@ -24,8 +24,6 @@ namespace Avalonia.Direct2D1.Media
private readonly SharpDX.Direct2D1.RenderTarget _renderTarget;
private readonly SharpDX.DXGI.SwapChain1 _swapChain;
private readonly Action _finishedCallback;
private readonly SharpDX.WIC.ImagingFactory _imagingFactory;
private SharpDX.DirectWrite.Factory _directWriteFactory;
/// <summary>
/// Initializes a new instance of the <see cref="DrawingContextImpl"/> class.
@ -36,16 +34,12 @@ namespace Avalonia.Direct2D1.Media
/// An object to use to create layers. May be null, in which case a
/// <see cref="WicRenderTargetBitmapImpl"/> will created when a new layer is requested.
/// </param>
/// <param name="directWriteFactory">The DirectWrite factory.</param>
/// <param name="imagingFactory">The WIC imaging factory.</param>
/// <param name="swapChain">An optional swap chain associated with this drawing context.</param>
/// <param name="finishedCallback">An optional delegate to be called when context is disposed.</param>
public DrawingContextImpl(
IVisualBrushRenderer visualBrushRenderer,
ILayerFactory layerFactory,
SharpDX.Direct2D1.RenderTarget renderTarget,
SharpDX.DirectWrite.Factory directWriteFactory,
SharpDX.WIC.ImagingFactory imagingFactory,
SharpDX.DXGI.SwapChain1 swapChain = null,
Action finishedCallback = null)
{
@ -54,8 +48,6 @@ namespace Avalonia.Direct2D1.Media
_renderTarget = renderTarget;
_swapChain = swapChain;
_finishedCallback = finishedCallback;
_directWriteFactory = directWriteFactory;
_imagingFactory = imagingFactory;
_renderTarget.BeginDraw();
}
@ -443,7 +435,7 @@ namespace Avalonia.Direct2D1.Media
return new ImageBrushImpl(
visualBrush,
_renderTarget,
new D2DBitmapImpl(_imagingFactory, intermediate.Bitmap),
new D2DBitmapImpl(intermediate.Bitmap),
destinationSize);
}
}

4
src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs

@ -21,15 +21,13 @@ namespace Avalonia.Direct2D1.Media
{
Text = text;
var factory = AvaloniaLocator.Current.GetService<DWrite.Factory>();
var textFormat = Direct2D1FontCollectionCache.GetTextFormat(typeface);
textFormat.WordWrapping =
wrapping == TextWrapping.Wrap ? DWrite.WordWrapping.Wrap : DWrite.WordWrapping.NoWrap;
TextLayout = new DWrite.TextLayout(
factory,
Direct2D1Platform.DirectWriteFactory,
Text ?? string.Empty,
textFormat,
(float)constraint.Width,

3
src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs

@ -53,10 +53,9 @@ namespace Avalonia.Direct2D1.Media
public ITransformedGeometryImpl WithTransform(Matrix transform)
{
var factory = AvaloniaLocator.Current.GetService<Factory>();
return new TransformedGeometryImpl(
new TransformedGeometry(
factory,
Direct2D1Platform.Direct2D1Factory,
GetSourceGeometry(),
transform.ToDirect2D()),
this);

7
src/Windows/Avalonia.Direct2D1/Media/Imaging/BitmapImpl.cs

@ -1,19 +1,12 @@
using System;
using System.IO;
using Avalonia.Platform;
using SharpDX.WIC;
using D2DBitmap = SharpDX.Direct2D1.Bitmap;
namespace Avalonia.Direct2D1.Media
{
public abstract class BitmapImpl : IBitmapImpl, IDisposable
{
public BitmapImpl(ImagingFactory imagingFactory)
{
WicImagingFactory = imagingFactory;
}
public ImagingFactory WicImagingFactory { get; }
public abstract int PixelWidth { get; }
public abstract int PixelHeight { get; }

28
src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs

@ -1,7 +1,6 @@
using System;
using System.IO;
using SharpDX.Direct2D1;
using WICFactory = SharpDX.WIC.ImagingFactory;
using ImagingFactory2 = SharpDX.WIC.ImagingFactory2;
using ImageParameters = SharpDX.WIC.ImageParameters;
using PngBitmapEncoder = SharpDX.WIC.PngBitmapEncoder;
@ -13,52 +12,51 @@ namespace Avalonia.Direct2D1.Media
/// </summary>
public class D2DBitmapImpl : BitmapImpl
{
private Bitmap _direct2D;
private Bitmap _direct2DBitmap;
/// <summary>
/// Initialize a new instance of the <see cref="BitmapImpl"/> class
/// with a bitmap backed by GPU memory.
/// </summary>
/// <param name="imagingFactory">The image factory to use when saving out this bitmap.</param>
/// <param name="d2DBitmap">The GPU bitmap.</param>
/// <remarks>
/// This bitmap must be either from the same render target,
/// or if the render target is a <see cref="SharpDX.Direct2D1.DeviceContext"/>,
/// the device associated with this context, to be renderable.
/// </remarks>
public D2DBitmapImpl(WICFactory imagingFactory, Bitmap d2DBitmap)
: base(imagingFactory)
public D2DBitmapImpl(Bitmap d2DBitmap)
{
_direct2D = d2DBitmap ?? throw new ArgumentNullException(nameof(d2DBitmap));
_direct2DBitmap = d2DBitmap ?? throw new ArgumentNullException(nameof(d2DBitmap));
}
public override int PixelWidth => _direct2D.PixelSize.Width;
public override int PixelHeight => _direct2D.PixelSize.Height;
public override int PixelWidth => _direct2DBitmap.PixelSize.Width;
public override int PixelHeight => _direct2DBitmap.PixelSize.Height;
public override void Dispose()
{
base.Dispose();
_direct2D.Dispose();
_direct2DBitmap.Dispose();
}
public override OptionalDispose<Bitmap> GetDirect2DBitmap(SharpDX.Direct2D1.RenderTarget target)
{
return new OptionalDispose<Bitmap>(_direct2D, false);
return new OptionalDispose<Bitmap>(_direct2DBitmap, false);
}
public override void Save(Stream stream)
{
using (var encoder = new PngBitmapEncoder(WicImagingFactory, stream))
using (var encoder = new PngBitmapEncoder(Direct2D1Platform.ImagingFactory, stream))
using (var frameEncode = new SharpDX.WIC.BitmapFrameEncode(encoder))
using (var imageEncoder = new SharpDX.WIC.ImageEncoder((ImagingFactory2)WicImagingFactory, null))
//ToDo: Not supported under Windows 7!
using (var imageEncoder = new SharpDX.WIC.ImageEncoder((ImagingFactory2)Direct2D1Platform.ImagingFactory, null))
{
var parameters = new ImageParameters(
new PixelFormat(SharpDX.DXGI.Format.R8G8B8A8_UNorm, AlphaMode.Premultiplied),
_direct2D.DotsPerInch.Width,
_direct2D.DotsPerInch.Height,
_direct2DBitmap.DotsPerInch.Width,
_direct2DBitmap.DotsPerInch.Height,
0, 0, PixelWidth, PixelHeight);
imageEncoder.WriteFrame(_direct2D, frameEncode, parameters);
imageEncoder.WriteFrame(_direct2DBitmap, frameEncode, parameters);
frameEncode.Commit();
encoder.Commit();
}

39
src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs

@ -1,35 +1,25 @@
using System;
using Avalonia.Platform;
using Avalonia.Platform;
using Avalonia.Rendering;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.WIC;
using D2DBitmap = SharpDX.Direct2D1.Bitmap;
using DirectWriteFactory = SharpDX.DirectWrite.Factory;
namespace Avalonia.Direct2D1.Media.Imaging
{
public class D2DRenderTargetBitmapImpl : D2DBitmapImpl, IRenderTargetBitmapImpl, ILayerFactory
{
private readonly DirectWriteFactory _dwriteFactory;
private readonly BitmapRenderTarget _target;
private readonly BitmapRenderTarget _renderTarget;
public D2DRenderTargetBitmapImpl(
ImagingFactory imagingFactory,
DirectWriteFactory dwriteFactory,
BitmapRenderTarget target)
: base(imagingFactory, target.Bitmap)
public D2DRenderTargetBitmapImpl(BitmapRenderTarget renderTarget)
: base(renderTarget.Bitmap)
{
_dwriteFactory = dwriteFactory;
_target = target;
_renderTarget = renderTarget;
}
public override int PixelWidth => _target.PixelSize.Width;
public override int PixelHeight => _target.PixelSize.Height;
public override int PixelWidth => _renderTarget.PixelSize.Width;
public override int PixelHeight => _renderTarget.PixelSize.Height;
public static D2DRenderTargetBitmapImpl CreateCompatible(
ImagingFactory imagingFactory,
DirectWriteFactory dwriteFactory,
SharpDX.Direct2D1.RenderTarget renderTarget,
Size size)
{
@ -37,32 +27,27 @@ namespace Avalonia.Direct2D1.Media.Imaging
renderTarget,
CompatibleRenderTargetOptions.None,
new Size2F((float)size.Width, (float)size.Height));
return new D2DRenderTargetBitmapImpl(imagingFactory, dwriteFactory, bitmapRenderTarget);
return new D2DRenderTargetBitmapImpl(bitmapRenderTarget);
}
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
{
return new DrawingContextImpl(
visualBrushRenderer,
this,
_target,
_dwriteFactory,
WicImagingFactory);
return new DrawingContextImpl(visualBrushRenderer, this, _renderTarget);
}
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
return CreateCompatible(WicImagingFactory, _dwriteFactory, _target, size);
return CreateCompatible(_renderTarget, size);
}
public override void Dispose()
{
_target.Dispose();
_renderTarget.Dispose();
}
public override OptionalDispose<D2DBitmap> GetDirect2DBitmap(SharpDX.Direct2D1.RenderTarget target)
{
return new OptionalDispose<D2DBitmap>(_target.Bitmap, false);
return new OptionalDispose<D2DBitmap>(_renderTarget.Bitmap, false);
}
}
}

33
src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs

@ -19,57 +19,52 @@ namespace Avalonia.Direct2D1.Media
/// <summary>
/// Initializes a new instance of the <see cref="WicBitmapImpl"/> class.
/// </summary>
/// <param name="factory">The WIC imaging factory to use.</param>
/// <param name="fileName">The filename of the bitmap to load.</param>
public WicBitmapImpl(ImagingFactory factory, string fileName)
: base(factory)
public WicBitmapImpl(string fileName)
{
using (BitmapDecoder decoder = new BitmapDecoder(factory, fileName, DecodeOptions.CacheOnDemand))
using (BitmapDecoder decoder = new BitmapDecoder(Direct2D1Platform.ImagingFactory, fileName, DecodeOptions.CacheOnDemand))
{
WicImpl = new Bitmap(factory, decoder.GetFrame(0), BitmapCreateCacheOption.CacheOnDemand);
WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, decoder.GetFrame(0), BitmapCreateCacheOption.CacheOnDemand);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="WicBitmapImpl"/> class.
/// </summary>
/// <param name="factory">The WIC imaging factory to use.</param>
/// <param name="stream">The stream to read the bitmap from.</param>
public WicBitmapImpl(ImagingFactory factory, Stream stream)
: base(factory)
public WicBitmapImpl(Stream stream)
{
using (BitmapDecoder decoder = new BitmapDecoder(factory, stream, DecodeOptions.CacheOnLoad))
using (BitmapDecoder decoder = new BitmapDecoder(Direct2D1Platform.ImagingFactory, stream, DecodeOptions.CacheOnLoad))
{
WicImpl = new Bitmap(factory, decoder.GetFrame(0), BitmapCreateCacheOption.CacheOnLoad);
WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, decoder.GetFrame(0), BitmapCreateCacheOption.CacheOnLoad);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="WicBitmapImpl"/> class.
/// </summary>
/// <param name="factory">The WIC imaging factory to use.</param>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
/// <param name="pixelFormat">Pixel format</param>
public WicBitmapImpl(ImagingFactory factory, int width, int height, APixelFormat? pixelFormat = null)
: base(factory)
public WicBitmapImpl(int width, int height, APixelFormat? pixelFormat = null)
{
if (!pixelFormat.HasValue)
{
pixelFormat = APixelFormat.Bgra8888;
}
PixelFormat = pixelFormat;
WicImpl = new Bitmap(
factory,
Direct2D1Platform.ImagingFactory,
width,
height,
pixelFormat.Value.ToWic(),
BitmapCreateCacheOption.CacheOnLoad);
}
public WicBitmapImpl(ImagingFactory factory, APixelFormat format, IntPtr data, int width, int height, int stride)
: base(factory)
public WicBitmapImpl(APixelFormat format, IntPtr data, int width, int height, int stride)
{
WicImpl = new Bitmap(factory, width, height, format.ToWic(), BitmapCreateCacheOption.CacheOnDemand);
WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, width, height, format.ToWic(), BitmapCreateCacheOption.CacheOnDemand);
PixelFormat = format;
using (var l = WicImpl.Lock(BitmapLockFlags.Write))
{
@ -112,14 +107,14 @@ namespace Avalonia.Direct2D1.Media
/// <returns>The Direct2D bitmap.</returns>
public override OptionalDispose<D2DBitmap> GetDirect2DBitmap(SharpDX.Direct2D1.RenderTarget renderTarget)
{
FormatConverter converter = new FormatConverter(WicImagingFactory);
FormatConverter converter = new FormatConverter(Direct2D1Platform.ImagingFactory);
converter.Initialize(WicImpl, SharpDX.WIC.PixelFormat.Format32bppPBGRA);
return new OptionalDispose<D2DBitmap>(D2DBitmap.FromWicBitmap(renderTarget, converter), true);
}
public override void Save(Stream stream)
{
using (var encoder = new PngBitmapEncoder(WicImagingFactory, stream))
using (var encoder = new PngBitmapEncoder(Direct2D1Platform.ImagingFactory, stream))
using (var frame = new BitmapFrameEncode(encoder))
{
frame.Initialize();

22
src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs

@ -5,26 +5,20 @@ using System;
using Avalonia.Platform;
using Avalonia.Rendering;
using SharpDX.Direct2D1;
using SharpDX.WIC;
using DirectWriteFactory = SharpDX.DirectWrite.Factory;
namespace Avalonia.Direct2D1.Media
{
public class WicRenderTargetBitmapImpl : WicBitmapImpl, IRenderTargetBitmapImpl
{
private readonly DirectWriteFactory _dwriteFactory;
private readonly WicRenderTarget _target;
private readonly WicRenderTarget _renderTarget;
public WicRenderTargetBitmapImpl(
ImagingFactory imagingFactory,
Factory d2dFactory,
DirectWriteFactory dwriteFactory,
int width,
int height,
double dpiX,
double dpiY,
Platform.PixelFormat? pixelFormat = null)
: base(imagingFactory, width, height, pixelFormat)
: base(width, height, pixelFormat)
{
var props = new RenderTargetProperties
{
@ -32,17 +26,16 @@ namespace Avalonia.Direct2D1.Media
DpiY = (float)dpiY,
};
_target = new WicRenderTarget(
d2dFactory,
_renderTarget = new WicRenderTarget(
Direct2D1Platform.Direct2D1Factory,
WicImpl,
props);
_dwriteFactory = dwriteFactory;
}
public override void Dispose()
{
_target.Dispose();
_renderTarget.Dispose();
base.Dispose();
}
@ -51,8 +44,7 @@ namespace Avalonia.Direct2D1.Media
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer, Action finishedCallback)
{
return new DrawingContextImpl(visualBrushRenderer, null, _target, _dwriteFactory, WicImagingFactory,
finishedCallback: finishedCallback);
return new DrawingContextImpl(visualBrushRenderer, null, _renderTarget, finishedCallback: finishedCallback);
}
}
}

8
src/Windows/Avalonia.Direct2D1/Media/Imaging/WriteableWicBitmapImpl.cs

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Platform;
using SharpDX.WIC;
using PixelFormat = Avalonia.Platform.PixelFormat;
@ -11,8 +7,8 @@ namespace Avalonia.Direct2D1.Media.Imaging
{
class WriteableWicBitmapImpl : WicBitmapImpl, IWriteableBitmapImpl
{
public WriteableWicBitmapImpl(ImagingFactory factory, int width, int height, PixelFormat? pixelFormat)
: base(factory, width, height, pixelFormat)
public WriteableWicBitmapImpl(int width, int height, PixelFormat? pixelFormat)
: base(width, height, pixelFormat)
{
}

6
src/Windows/Avalonia.Direct2D1/Media/StreamGeometryImpl.cs

@ -31,8 +31,7 @@ namespace Avalonia.Direct2D1.Media
/// <inheritdoc/>
public IStreamGeometryImpl Clone()
{
Factory factory = AvaloniaLocator.Current.GetService<Factory>();
var result = new PathGeometry(factory);
var result = new PathGeometry(Direct2D1Platform.Direct2D1Factory);
var sink = result.Open();
((PathGeometry)Geometry).Stream(sink);
sink.Close();
@ -47,8 +46,7 @@ namespace Avalonia.Direct2D1.Media
private static Geometry CreateGeometry()
{
Factory factory = AvaloniaLocator.Current.GetService<Factory>();
return new PathGeometry(factory);
return new PathGeometry(Direct2D1Platform.Direct2D1Factory);
}
}
}

19
src/Windows/Avalonia.Direct2D1/RenderTarget.cs

@ -1,14 +1,10 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Rendering;
using SharpDX.Direct2D1;
using DwFactory = SharpDX.DirectWrite.Factory;
using WicFactory = SharpDX.WIC.ImagingFactory;
namespace Avalonia.Direct2D1
{
@ -25,32 +21,21 @@ namespace Avalonia.Direct2D1
/// <param name="renderTarget">The render target.</param>
public RenderTarget(SharpDX.Direct2D1.RenderTarget renderTarget)
{
Direct2DFactory = AvaloniaLocator.Current.GetService<Factory>();
DirectWriteFactory = AvaloniaLocator.Current.GetService<DwFactory>();
WicFactory = AvaloniaLocator.Current.GetService<WicFactory>();
_renderTarget = renderTarget;
}
public Factory Direct2DFactory { get; }
public DwFactory DirectWriteFactory { get; }
public WicFactory WicFactory { get; }
/// <summary>
/// Creates a drawing context for a rendering session.
/// </summary>
/// <returns>An <see cref="Avalonia.Platform.IDrawingContextImpl"/>.</returns>
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
{
return new DrawingContextImpl(visualBrushRenderer, this, _renderTarget, DirectWriteFactory, WicFactory);
return new DrawingContextImpl(visualBrushRenderer, this, _renderTarget);
}
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
return D2DRenderTargetBitmapImpl.CreateCompatible(
WicFactory,
DirectWriteFactory,
_renderTarget,
size);
return D2DRenderTargetBitmapImpl.CreateCompatible(_renderTarget, size);
}
public void Dispose()

55
src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs

@ -1,16 +1,14 @@
using System;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Rendering;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.DXGI;
using PixelFormat = SharpDX.Direct2D1.PixelFormat;
using AlphaMode = SharpDX.Direct2D1.AlphaMode;
using Device = SharpDX.Direct2D1.Device;
using Factory = SharpDX.Direct2D1.Factory;
using Factory2 = SharpDX.DXGI.Factory2;
using Avalonia.Rendering;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media.Imaging;
using PixelFormat = SharpDX.Direct2D1.PixelFormat;
namespace Avalonia.Direct2D1
{
@ -21,23 +19,6 @@ namespace Avalonia.Direct2D1
private DeviceContext _deviceContext;
private SwapChain1 _swapChain;
protected SwapChainRenderTarget()
{
DxgiDevice = AvaloniaLocator.Current.GetService<SharpDX.DXGI.Device>();
D2DDevice = AvaloniaLocator.Current.GetService<Device>();
Direct2DFactory = AvaloniaLocator.Current.GetService<Factory>();
DirectWriteFactory = AvaloniaLocator.Current.GetService<SharpDX.DirectWrite.Factory>();
WicImagingFactory = AvaloniaLocator.Current.GetService<SharpDX.WIC.ImagingFactory>();
}
public Factory Direct2DFactory { get; }
public SharpDX.DirectWrite.Factory DirectWriteFactory { get; }
public SharpDX.WIC.ImagingFactory WicImagingFactory { get; }
protected SharpDX.DXGI.Device DxgiDevice { get; }
public Device D2DDevice { get; }
/// <summary>
/// Creates a drawing context for a rendering session.
/// </summary>
@ -54,13 +35,7 @@ namespace Avalonia.Direct2D1
CreateSwapChain();
}
return new DrawingContextImpl(
visualBrushRenderer,
this,
_deviceContext,
DirectWriteFactory,
WicImagingFactory,
_swapChain);
return new DrawingContextImpl(visualBrushRenderer, this, _deviceContext, _swapChain);
}
public IRenderTargetBitmapImpl CreateLayer(Size size)
@ -70,11 +45,7 @@ namespace Avalonia.Direct2D1
CreateSwapChain();
}
return D2DRenderTargetBitmapImpl.CreateCompatible(
WicImagingFactory,
DirectWriteFactory,
_deviceContext,
size);
return D2DRenderTargetBitmapImpl.CreateCompatible(_deviceContext, size);
}
public void Dispose()
@ -85,11 +56,11 @@ namespace Avalonia.Direct2D1
private void CreateSwapChain()
{
using (var dxgiAdaptor = DxgiDevice.Adapter)
using (var dxgiFactory = dxgiAdaptor.GetParent<Factory2>())
using (var dxgiAdaptor = Direct2D1Platform.DxgiDevice.Adapter)
using (var dxgiFactory = dxgiAdaptor.GetParent<SharpDX.DXGI.Factory2>())
{
_deviceContext?.Dispose();
_deviceContext = new DeviceContext(D2DDevice, DeviceContextOptions.None) {DotsPerInch = _savedDpi};
_deviceContext = new DeviceContext(Direct2D1Platform.Direct2D1Device, DeviceContextOptions.None) { DotsPerInch = _savedDpi };
var swapChainDesc = new SwapChainDescription1
{
@ -119,7 +90,7 @@ namespace Avalonia.Direct2D1
new BitmapProperties1(
new PixelFormat
{
AlphaMode = AlphaMode.Ignore,
AlphaMode = AlphaMode.Premultiplied,
Format = Format.B8G8R8A8_UNorm
},
_savedDpi.Width,
@ -131,7 +102,7 @@ namespace Avalonia.Direct2D1
}
}
protected abstract SwapChain1 CreateSwapChain(Factory2 dxgiFactory, SwapChainDescription1 swapChainDesc);
protected abstract SwapChain1 CreateSwapChain(SharpDX.DXGI.Factory2 dxgiFactory, SwapChainDescription1 swapChainDesc);
protected abstract Size2F GetWindowDpi();

Loading…
Cancel
Save