Browse Source

Merge pull request #2364 from MarchingCube/feature/skia-renderinterface

Allow for modifying Skia PlatformRenderInterface behavior.
pull/2449/head
Nikita Tsukanov 7 years ago
committed by GitHub
parent
commit
55efd41bdb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 42
      src/Skia/Avalonia.Skia/CustomRenderTarget.cs
  2. 26
      src/Skia/Avalonia.Skia/ICustomSkiaGpu.cs
  3. 29
      src/Skia/Avalonia.Skia/ICustomSkiaRenderSession.cs
  4. 19
      src/Skia/Avalonia.Skia/ICustomSkiaRenderTarget.cs
  5. 30
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  6. 5
      src/Skia/Avalonia.Skia/SkiaApplicationExtensions.cs
  7. 19
      src/Skia/Avalonia.Skia/SkiaOptions.cs
  8. 10
      src/Skia/Avalonia.Skia/SkiaPlatform.cs

42
src/Skia/Avalonia.Skia/CustomRenderTarget.cs

@ -0,0 +1,42 @@
// 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 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);
}
}
}

26
src/Skia/Avalonia.Skia/ICustomSkiaGpu.cs

@ -0,0 +1,26 @@
// 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.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);
}
}

29
src/Skia/Avalonia.Skia/ICustomSkiaRenderSession.cs

@ -0,0 +1,29 @@
// 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 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; }
}
}

19
src/Skia/Avalonia.Skia/ICustomSkiaRenderTarget.cs

@ -0,0 +1,19 @@
// 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;
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();
}
}

30
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -17,12 +17,23 @@ namespace Avalonia.Skia
/// </summary>
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)

5
src/Skia/Avalonia.Skia/SkiaApplicationExtensions.cs

@ -20,8 +20,9 @@ namespace Avalonia
/// <returns>Configure builder.</returns>
public static T UseSkia<T>(this T builder) where T : AppBuilderBase<T>, new()
{
builder.UseRenderingSubsystem(() => SkiaPlatform.Initialize(), "Skia");
return builder;
return builder.UseRenderingSubsystem(() => SkiaPlatform.Initialize(
AvaloniaLocator.Current.GetService<SkiaOptions>() ?? new SkiaOptions()),
"Skia");
}
}
}

19
src/Skia/Avalonia.Skia/SkiaOptions.cs

@ -0,0 +1,19 @@
// 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.Skia;
namespace Avalonia
{
/// <summary>
/// Options for Skia rendering subsystem.
/// </summary>
public class SkiaOptions
{
/// <summary>
/// Custom gpu factory to use. Can be used to customize behavior of Skia renderer.
/// </summary>
public Func<ICustomSkiaGpu> CustomGpuFactory { get; set; }
}
}

10
src/Skia/Avalonia.Skia/SkiaPlatform.cs

@ -15,8 +15,14 @@ namespace Avalonia.Skia
/// </summary>
public static void Initialize()
{
var renderInterface = new PlatformRenderInterface();
Initialize(new SkiaOptions());
}
public static void Initialize(SkiaOptions options)
{
var customGpu = options.CustomGpuFactory?.Invoke();
var renderInterface = new PlatformRenderInterface(customGpu);
AvaloniaLocator.CurrentMutable
.Bind<IPlatformRenderInterface>().ToConstant(renderInterface);
}

Loading…
Cancel
Save