Browse Source

Added IDrawingContextImpl.CreateLayer

pull/1184/head
Steven Kirk 9 years ago
parent
commit
5607404e6c
  1. 2
      samples/interop/Direct3DInteropSample/MainWindow.cs
  2. 14
      src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs
  3. 5
      src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs
  4. 6
      src/Gtk/Avalonia.Cairo/Media/DrawingContext.cs
  5. 6
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  6. 15
      src/Windows/Avalonia.Direct2D1/ExternalRenderTarget.cs
  7. 10
      src/Windows/Avalonia.Direct2D1/ICreateLayer.cs
  8. 10
      src/Windows/Avalonia.Direct2D1/ILayerFactory.cs
  9. 26
      src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
  10. 12
      src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs
  11. 7
      src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs
  12. 14
      src/Windows/Avalonia.Direct2D1/RenderTarget.cs
  13. 8
      src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs

2
samples/interop/Direct3DInteropSample/MainWindow.cs

@ -253,7 +253,7 @@ namespace Direct3DInteropSample
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
{
return new DrawingContextImpl(visualBrushRenderer, _window._d2dRenderTarget,
return new DrawingContextImpl(visualBrushRenderer, null, _window._d2dRenderTarget,
AvaloniaLocator.Current.GetService<SharpDX.DirectWrite.Factory>(),
AvaloniaLocator.Current.GetService<ImagingFactory>());
}

14
src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs

@ -80,6 +80,20 @@ namespace Avalonia.Platform
/// <param name="cornerRadius">The corner radius.</param>
void FillRectangle(IBrush brush, Rect rect, float cornerRadius = 0.0f);
/// <summary>
/// Creates a new <see cref="IRenderTargetBitmapImpl"/> that can be used as a render layer
/// for the current render target.
/// </summary>
/// <param name="size">The size of the layer in DIPs.</param>
/// <returns>An <see cref="IRenderTargetBitmapImpl"/></returns>
/// <remarks>
/// Depending on the rendering backend used, a layer created via this method may be more
/// performant than a standard render target bitmap. In particular the Direct2D backend
/// has to do a format conversion each time a standard render target bitmap is rendered,
/// but a layer created via this method has no such overhead.
/// </remarks>
IRenderTargetBitmapImpl CreateLayer(Size size);
/// <summary>
/// Pushes a clip rectange.
/// </summary>

5
src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs

@ -194,6 +194,11 @@ namespace Avalonia.Rendering.SceneGraph
}
}
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
throw new NotImplementedException();
}
/// <inheritdoc/>
public void PopClip()
{

6
src/Gtk/Avalonia.Cairo/Media/DrawingContext.cs

@ -227,6 +227,12 @@ namespace Avalonia.Cairo.Media
}
}
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
var surface = new Cairo.ImageSurface(Cairo.Format.Argb32, (int)size.Width, (int)size.Height);
return new RenderTargetBitmapImpl(surface);
}
/// <summary>
/// Pushes a clip rectange.
/// </summary>

6
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -349,6 +349,12 @@ namespace Avalonia.Skia
}
}
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
var pixelSize = size * (_dpi / 96);
return new BitmapImpl((int)pixelSize.Width, (int)pixelSize.Height, _dpi);
}
public void PushClip(Rect clip)
{
Canvas.Save();

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

@ -1,5 +1,6 @@
using System;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Rendering;
using SharpDX;
@ -7,7 +8,7 @@ using DirectWriteFactory = SharpDX.DirectWrite.Factory;
namespace Avalonia.Direct2D1
{
class ExternalRenderTarget : IRenderTarget
class ExternalRenderTarget : IRenderTarget, ILayerFactory
{
private readonly IExternalDirect2DRenderTargetSurface _externalRenderTargetProvider;
private readonly DirectWriteFactory _dwFactory;
@ -32,7 +33,7 @@ namespace Avalonia.Direct2D1
{
var target = _externalRenderTargetProvider.GetOrCreateRenderTarget();
_externalRenderTargetProvider.BeforeDrawing();
return new DrawingContextImpl(visualBrushRenderer, target, _dwFactory, _wicFactory, null, () =>
return new DrawingContextImpl(visualBrushRenderer, null, target, _dwFactory, _wicFactory, null, () =>
{
try
{
@ -44,5 +45,15 @@ namespace Avalonia.Direct2D1
}
});
}
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
var target = _externalRenderTargetProvider.GetOrCreateRenderTarget();
return D2DRenderTargetBitmapImpl.CreateCompatible(
_wicFactory,
_dwFactory,
target,
size);
}
}
}

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

@ -1,10 +0,0 @@
using System;
using Avalonia.Platform;
namespace Avalonia.Direct2D1
{
internal interface ICreateLayer
{
IRenderTargetBitmapImpl CreateLayer(int pixelWidth, int pixelHeight);
}
}

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

@ -0,0 +1,10 @@
using System;
using Avalonia.Platform;
namespace Avalonia.Direct2D1
{
public interface ILayerFactory
{
IRenderTargetBitmapImpl CreateLayer(Size size);
}
}

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

@ -18,6 +18,7 @@ namespace Avalonia.Direct2D1.Media
public class DrawingContextImpl : IDrawingContextImpl, IDisposable
{
private readonly IVisualBrushRenderer _visualBrushRenderer;
private readonly ILayerFactory _layerFactory;
private readonly SharpDX.Direct2D1.RenderTarget _renderTarget;
private readonly SharpDX.DXGI.SwapChain1 _swapChain;
private readonly Action _finishedCallback;
@ -29,12 +30,17 @@ namespace Avalonia.Direct2D1.Media
/// </summary>
/// <param name="visualBrushRenderer">The visual brush renderer.</param>
/// <param name="renderTarget">The render target to draw to.</param>
/// <param name="layerFactory">
/// 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,
@ -42,6 +48,7 @@ namespace Avalonia.Direct2D1.Media
Action finishedCallback = null)
{
_visualBrushRenderer = visualBrushRenderer;
_layerFactory = layerFactory;
_renderTarget = renderTarget;
_swapChain = swapChain;
_finishedCallback = finishedCallback;
@ -285,6 +292,25 @@ namespace Avalonia.Direct2D1.Media
}
}
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
if (_layerFactory != null)
{
return _layerFactory.CreateLayer(size);
}
else
{
var platform = AvaloniaLocator.Current.GetService<IPlatformRenderInterface>();
var dpi = new Vector(_renderTarget.DotsPerInch.Width, _renderTarget.DotsPerInch.Height);
var pixelSize = size * (dpi / 96);
return platform.CreateRenderTargetBitmap(
(int)pixelSize.Width,
(int)pixelSize.Height,
dpi.X,
dpi.Y);
}
}
/// <summary>
/// Pushes a clip rectange.
/// </summary>

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

@ -9,7 +9,7 @@ using DirectWriteFactory = SharpDX.DirectWrite.Factory;
namespace Avalonia.Direct2D1.Media.Imaging
{
public class D2DRenderTargetBitmapImpl : D2DBitmapImpl, IRenderTargetBitmapImpl, ICreateLayer
public class D2DRenderTargetBitmapImpl : D2DBitmapImpl, IRenderTargetBitmapImpl, ILayerFactory
{
private readonly DirectWriteFactory _dwriteFactory;
private readonly BitmapRenderTarget _target;
@ -31,13 +31,12 @@ namespace Avalonia.Direct2D1.Media.Imaging
ImagingFactory imagingFactory,
DirectWriteFactory dwriteFactory,
SharpDX.Direct2D1.RenderTarget renderTarget,
int pixelWidth,
int pixelHeight)
Size size)
{
var bitmapRenderTarget = new BitmapRenderTarget(
renderTarget,
CompatibleRenderTargetOptions.None,
new Size2F(pixelWidth, pixelHeight));
new Size2F((float)size.Width, (float)size.Height));
return new D2DRenderTargetBitmapImpl(imagingFactory, dwriteFactory, bitmapRenderTarget);
}
@ -45,14 +44,15 @@ namespace Avalonia.Direct2D1.Media.Imaging
{
return new DrawingContextImpl(
visualBrushRenderer,
this,
_target,
_dwriteFactory,
WicImagingFactory);
}
public IRenderTargetBitmapImpl CreateLayer(int pixelWidth, int pixelHeight)
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
return CreateCompatible(WicImagingFactory, _dwriteFactory, _target, pixelWidth, pixelHeight);
return CreateCompatible(WicImagingFactory, _dwriteFactory, _target, size);
}
public override void Dispose()

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

@ -47,7 +47,12 @@ namespace Avalonia.Direct2D1.Media
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
{
return new DrawingContextImpl(visualBrushRenderer, _target, _dwriteFactory, WicImagingFactory);
return new DrawingContextImpl(
visualBrushRenderer,
null,
_target,
_dwriteFactory,
WicImagingFactory);
}
}
}

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

@ -3,6 +3,7 @@
using System;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Rendering;
using SharpDX.Direct2D1;
@ -11,7 +12,7 @@ using WicFactory = SharpDX.WIC.ImagingFactory;
namespace Avalonia.Direct2D1
{
public class RenderTarget : IRenderTarget
public class RenderTarget : IRenderTarget, ILayerFactory
{
/// <summary>
/// The render target.
@ -40,7 +41,16 @@ namespace Avalonia.Direct2D1
/// <returns>An <see cref="Avalonia.Platform.IDrawingContextImpl"/>.</returns>
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
{
return new DrawingContextImpl(visualBrushRenderer, _renderTarget, DirectWriteFactory, WicFactory);
return new DrawingContextImpl(visualBrushRenderer, this, _renderTarget, DirectWriteFactory, WicFactory);
}
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
return D2DRenderTargetBitmapImpl.CreateCompatible(
WicFactory,
DirectWriteFactory,
_renderTarget,
size);
}
public void Dispose()

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

@ -14,7 +14,7 @@ using Avalonia.Direct2D1.Media.Imaging;
namespace Avalonia.Direct2D1
{
public abstract class SwapChainRenderTarget : IRenderTarget, ICreateLayer
public abstract class SwapChainRenderTarget : IRenderTarget, ILayerFactory
{
private Size2 _savedSize;
private Size2F _savedDpi;
@ -56,13 +56,14 @@ namespace Avalonia.Direct2D1
return new DrawingContextImpl(
visualBrushRenderer,
this,
_deviceContext,
DirectWriteFactory,
WicImagingFactory,
_swapChain);
}
public IRenderTargetBitmapImpl CreateLayer(int pixelWidth, int pixelHeight)
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
if (_deviceContext == null)
{
@ -73,8 +74,7 @@ namespace Avalonia.Direct2D1
WicImagingFactory,
DirectWriteFactory,
_deviceContext,
pixelWidth,
pixelHeight);
size);
}
public void Dispose()

Loading…
Cancel
Save