diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index a155fd863b..669da8d03c 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -31,6 +31,7 @@ namespace Avalonia.Skia
private bool _disposed;
private GRContext _grContext;
public GRContext GrContext => _grContext;
+ private ISkiaGpu _gpu;
private readonly SKPaint _strokePaint = new SKPaint();
private readonly SKPaint _fillPaint = new SKPaint();
private readonly SKPaint _boxShadowPaint = new SKPaint();
@@ -65,6 +66,11 @@ namespace Avalonia.Skia
/// GPU-accelerated context (optional)
///
public GRContext GrContext;
+
+ ///
+ /// Skia GPU provider context (optional)
+ ///
+ public ISkiaGpu Gpu;
}
///
@@ -79,6 +85,7 @@ namespace Avalonia.Skia
_disposables = disposables;
_canTextUseLcdRendering = !createInfo.DisableTextLcdRendering;
_grContext = createInfo.GrContext;
+ _gpu = createInfo.Gpu;
if (_grContext != null)
Monitor.Enter(_grContext);
Surface = createInfo.Surface;
@@ -417,7 +424,7 @@ namespace Avalonia.Skia
///
public IRenderTargetBitmapImpl CreateLayer(Size size)
{
- return CreateRenderTarget(size);
+ return CreateRenderTarget( size);
}
///
@@ -925,7 +932,8 @@ namespace Avalonia.Skia
Dpi = _dpi,
Format = format,
DisableTextLcdRendering = !_canTextUseLcdRendering,
- GrContext = _grContext
+ GrContext = _grContext,
+ Gpu = _gpu
};
return new SurfaceRenderTarget(createInfo);
diff --git a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs
index 1a7a9b75cf..ebb0cb3a1b 100644
--- a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs
+++ b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using Avalonia.OpenGL.Imaging;
using SkiaSharp;
@@ -15,6 +16,19 @@ namespace Avalonia.Skia
/// Surfaces.
/// Created render target or if it fails.
ISkiaGpuRenderTarget TryCreateRenderTarget(IEnumerable
internal class SkiaGpuRenderTarget : IRenderTargetWithCorruptionInfo
{
+ private readonly ISkiaGpu _skiaGpu;
private readonly ISkiaGpuRenderTarget _renderTarget;
- public SkiaGpuRenderTarget(ISkiaGpuRenderTarget renderTarget)
+ public SkiaGpuRenderTarget(ISkiaGpu skiaGpu, ISkiaGpuRenderTarget renderTarget)
{
+ _skiaGpu = skiaGpu;
_renderTarget = renderTarget;
}
@@ -30,7 +32,8 @@ namespace Avalonia.Skia
Surface = session.SkSurface,
Dpi = SkiaPlatform.DefaultDpi * session.ScaleFactor,
VisualBrushRenderer = visualBrushRenderer,
- DisableTextLcdRendering = true
+ DisableTextLcdRendering = true,
+ Gpu = _skiaGpu
};
return new DrawingContextImpl(nfo, session);
diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
index b9c1cbc673..d6f76a2c20 100644
--- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
+++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
@@ -138,7 +138,7 @@ namespace Avalonia.Skia
var gpuRenderTarget = _skiaGpu?.TryCreateRenderTarget(surfaces);
if (gpuRenderTarget != null)
{
- return new SkiaGpuRenderTarget(gpuRenderTarget);
+ return new SkiaGpuRenderTarget(_skiaGpu, gpuRenderTarget);
}
foreach (var surface in surfaces)
diff --git a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
index 428087ac56..d6ea229089 100644
--- a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
+++ b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
@@ -13,10 +13,29 @@ namespace Avalonia.Skia
///
internal class SurfaceRenderTarget : IRenderTargetBitmapImpl, IDrawableBitmapImpl
{
- private readonly SKSurface _surface;
+ private readonly ISkiaSurface _surface;
private readonly SKCanvas _canvas;
private readonly bool _disableLcdRendering;
private readonly GRContext _grContext;
+ private readonly ISkiaGpu _gpu;
+
+ class SkiaSurfaceWrapper : ISkiaSurface
+ {
+ public SKSurface WriteSurface { get; private set; }
+ public SKSurface ReadSurface { get; private set; }
+
+ public SkiaSurfaceWrapper(SKSurface surface)
+ {
+ WriteSurface = ReadSurface = surface;
+ }
+
+ public void Dispose()
+ {
+ WriteSurface?.Dispose();
+ WriteSurface = null;
+ ReadSurface = null;
+ }
+ }
///
/// Create new surface render target.
@@ -29,9 +48,14 @@ namespace Avalonia.Skia
_disableLcdRendering = createInfo.DisableTextLcdRendering;
_grContext = createInfo.GrContext;
- _surface = CreateSurface(createInfo.GrContext, PixelSize.Width, PixelSize.Height, createInfo.Format);
+ _gpu = createInfo.Gpu;
- _canvas = _surface?.Canvas;
+ _surface = _gpu?.TryCreateSurface(PixelSize);
+ if (_surface == null)
+ _surface = new SkiaSurfaceWrapper(CreateSurface(createInfo.GrContext, PixelSize.Width, PixelSize.Height,
+ createInfo.Format));
+
+ _canvas = _surface?.WriteSurface.Canvas;
if (_surface == null || _canvas == null)
{
@@ -70,11 +94,12 @@ namespace Avalonia.Skia
var createInfo = new DrawingContextImpl.CreateInfo
{
- Surface = _surface,
+ Surface = _surface.WriteSurface,
Dpi = Dpi,
VisualBrushRenderer = visualBrushRenderer,
DisableTextLcdRendering = _disableLcdRendering,
- GrContext = _grContext
+ GrContext = _grContext,
+ Gpu = _gpu
};
return new DrawingContextImpl(createInfo, Disposable.Create(() => Version++));
@@ -111,8 +136,8 @@ namespace Avalonia.Skia
{
if (sourceRect.Left == 0 && sourceRect.Top == 0 && sourceRect.Size == destRect.Size)
{
- _surface.Canvas.Flush();
- _surface.Draw(context.Canvas, destRect.Left, destRect.Top, paint);
+ _surface.ReadSurface.Canvas.Flush();
+ _surface.ReadSurface.Draw(context.Canvas, destRect.Left, destRect.Top, paint);
}
else
using (var image = SnapshotImage())
@@ -127,7 +152,7 @@ namespace Avalonia.Skia
/// Image snapshot.
public SKImage SnapshotImage()
{
- return _surface.Snapshot();
+ return _surface.ReadSurface.Snapshot();
}
///
@@ -178,6 +203,8 @@ namespace Avalonia.Skia
/// GPU-accelerated context (optional)
///
public GRContext GrContext;
+
+ public ISkiaGpu Gpu;
}
}
}