Browse Source

Custom skia gpu support.

pull/2364/head
Dariusz Komosinski 8 years ago
parent
commit
1db8031b02
  1. 39
      src/Skia/Avalonia.Skia/CustomRenderTarget.cs
  2. 23
      src/Skia/Avalonia.Skia/ICustomSkiaGpu.cs
  3. 26
      src/Skia/Avalonia.Skia/ICustomSkiaRenderSession.cs
  4. 16
      src/Skia/Avalonia.Skia/ICustomSkiaRenderTarget.cs
  5. 32
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  6. 7
      src/Skia/Avalonia.Skia/SkiaApplicationExtensions.cs
  7. 6
      src/Skia/Avalonia.Skia/SkiaPlatform.cs

39
src/Skia/Avalonia.Skia/CustomRenderTarget.cs

@ -0,0 +1,39 @@
using Avalonia.Platform;
using Avalonia.Rendering;
namespace Avalonia.Skia
{
/// <summary>
/// Adapts <see cref="ICustomSkiaRenderTarget"/> to be used within Skia rendering pipeline.
/// </summary>
internal class CustomRenderTarget : IRenderTarget
{
private readonly ICustomSkiaRenderTarget _renderTarget;
public CustomRenderTarget(ICustomSkiaRenderTarget renderTarget)
{
_renderTarget = renderTarget;
}
public void Dispose()
{
_renderTarget.Dispose();
}
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
{
ICustomSkiaRenderSession session = _renderTarget.BeginRendering();
var nfo = new DrawingContextImpl.CreateInfo
{
GrContext = session.GrContext,
Canvas = session.Canvas,
Dpi = SkiaPlatform.DefaultDpi * session.ScaleFactor,
VisualBrushRenderer = visualBrushRenderer,
DisableTextLcdRendering = true
};
return new DrawingContextImpl(nfo, session);
}
}
}

23
src/Skia/Avalonia.Skia/ICustomSkiaGpu.cs

@ -0,0 +1,23 @@
using System.Collections.Generic;
using SkiaSharp;
namespace Avalonia.Skia
{
/// <summary>
/// Custom Skia gpu instance.
/// </summary>
public interface ICustomSkiaGpu
{
/// <summary>
/// Skia GrContext used.
/// </summary>
GRContext GrContext { get; }
/// <summary>
/// Attempts to create custom render target from given surfaces.
/// </summary>
/// <param name="surfaces">Surfaces.</param>
/// <returns>Created render target or <see langword="null"/> if it fails.</returns>
ICustomSkiaRenderTarget TryCreateRenderTarget(IEnumerable<object> surfaces);
}
}

26
src/Skia/Avalonia.Skia/ICustomSkiaRenderSession.cs

@ -0,0 +1,26 @@
using System;
using SkiaSharp;
namespace Avalonia.Skia
{
/// <summary>
/// Custom render session for Skia render target.
/// </summary>
public interface ICustomSkiaRenderSession : IDisposable
{
/// <summary>
/// GrContext used by this session.
/// </summary>
GRContext GrContext { get; }
/// <summary>
/// Canvas that will be used to render.
/// </summary>
SKCanvas Canvas { get; }
/// <summary>
/// Scaling factor.
/// </summary>
double ScaleFactor { get; }
}
}

16
src/Skia/Avalonia.Skia/ICustomSkiaRenderTarget.cs

@ -0,0 +1,16 @@
using System;
namespace Avalonia.Skia
{
/// <summary>
/// Custom Skia render target.
/// </summary>
public interface ICustomSkiaRenderTarget : IDisposable
{
/// <summary>
/// Start rendering to this render target.
/// </summary>
/// <returns></returns>
ICustomSkiaRenderSession BeginRendering();
}
}

32
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -15,14 +15,25 @@ namespace Avalonia.Skia
/// <summary>
/// Skia platform render interface.
/// </summary>
public class PlatformRenderInterface : IPlatformRenderInterface
internal class PlatformRenderInterface : IPlatformRenderInterface
{
private readonly ICustomSkiaGpu _customSkiaGpu;
private GRContext GrContext { get; }
public IEnumerable<string> InstalledFontNames => SKFontManager.Default.FontFamilies;
public PlatformRenderInterface()
public PlatformRenderInterface(ICustomSkiaGpu customSkiaGpu)
{
if (customSkiaGpu != null)
{
_customSkiaGpu = customSkiaGpu;
GrContext = _customSkiaGpu.GrContext;
return;
}
var gl = AvaloniaLocator.Current.GetService<IWindowingPlatformGlFeature>();
if (gl != null)
{
@ -32,12 +43,11 @@ namespace Avalonia.Skia
? GRGlInterface.AssembleGlInterface((_, proc) => display.GlInterface.GetProcAddress(proc))
: GRGlInterface.AssembleGlesInterface((_, proc) => display.GlInterface.GetProcAddress(proc)))
{
GrContext = GRContext.Create(GRBackend.OpenGL, iface);
}
}
}
/// <inheritdoc />
public IFormattedTextImpl CreateFormattedText(
string text,
@ -98,13 +108,23 @@ namespace Avalonia.Skia
DisableTextLcdRendering = false,
GrContext = GrContext
};
return new SurfaceRenderTarget(createInfo);
}
/// <inheritdoc />
public virtual IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces)
public IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces)
{
if (_customSkiaGpu != null)
{
ICustomSkiaRenderTarget customRenderTarget = _customSkiaGpu.TryCreateRenderTarget(surfaces);
if (customRenderTarget != null)
{
return new CustomRenderTarget(customRenderTarget);
}
}
foreach (var surface in surfaces)
{
if (surface is IGlPlatformSurface glSurface && GrContext != null)

7
src/Skia/Avalonia.Skia/SkiaApplicationExtensions.cs

@ -1,6 +1,7 @@
// 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.Controls;
using Avalonia.Skia;
@ -18,9 +19,11 @@ namespace Avalonia
/// <typeparam name="T">Builder type.</typeparam>
/// <param name="builder">Builder.</param>
/// <returns>Configure builder.</returns>
public static T UseSkia<T>(this T builder) where T : AppBuilderBase<T>, new()
public static T UseSkia<T>(this T builder, Func<ICustomSkiaGpu> gpuFactory = null) where T : AppBuilderBase<T>, new()
{
builder.UseRenderingSubsystem(() => SkiaPlatform.Initialize(), "Skia");
var customGpu = gpuFactory?.Invoke();
builder.UseRenderingSubsystem(() => SkiaPlatform.Initialize(customGpu), "Skia");
return builder;
}
}

6
src/Skia/Avalonia.Skia/SkiaPlatform.cs

@ -13,10 +13,10 @@ namespace Avalonia.Skia
/// <summary>
/// Initialize Skia platform.
/// </summary>
public static void Initialize()
public static void Initialize(ICustomSkiaGpu customGpu)
{
var renderInterface = new PlatformRenderInterface();
var renderInterface = new PlatformRenderInterface(customGpu);
AvaloniaLocator.CurrentMutable
.Bind<IPlatformRenderInterface>().ToConstant(renderInterface);
}

Loading…
Cancel
Save