Browse Source

Enable stencil buffers by default + add configurable option (#21586)

pull/21590/head
Julien Lebosquain 4 months ago
committed by GitHub
parent
commit
9808817e31
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs
  2. 5
      src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs
  3. 6
      src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs
  4. 10
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  5. 6
      src/Skia/Avalonia.Skia/SkiaOptions.cs
  6. 2
      src/Skia/Avalonia.Skia/SkiaPlatform.cs

5
src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs

@ -15,11 +15,12 @@ internal class SkiaMetalGpu : ISkiaGpu
internal GRContext GrContext => _context ?? throw new ObjectDisposedException(nameof(SkiaMetalGpu)); internal GRContext GrContext => _context ?? throw new ObjectDisposedException(nameof(SkiaMetalGpu));
public SkiaMetalGpu(IMetalDevice device, long? maxResourceBytes) public SkiaMetalGpu(IMetalDevice device, long? maxResourceBytes, bool? useStencilBuffers = null)
{ {
var avoidStencilBuffers = useStencilBuffers == false;
_context = GRContext.CreateMetal( _context = GRContext.CreateMetal(
new GRMtlBackendContext { DeviceHandle = device.Device, QueueHandle = device.CommandQueue, }, new GRMtlBackendContext { DeviceHandle = device.Device, QueueHandle = device.CommandQueue, },
new GRContextOptions { AvoidStencilBuffers = true }) new GRContextOptions { AvoidStencilBuffers = avoidStencilBuffers })
?? throw new InvalidOperationException("Unable to create GRContext from Metal device."); ?? throw new InvalidOperationException("Unable to create GRContext from Metal device.");
_device = device; _device = device;
if (device.TryGetFeature<IMetalExternalObjectsFeature>() is { } externalObjects) if (device.TryGetFeature<IMetalExternalObjectsFeature>() is { } externalObjects)

5
src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs

@ -21,7 +21,7 @@ namespace Avalonia.Skia
private bool? _canCreateSurfaces; private bool? _canCreateSurfaces;
private readonly IExternalObjectsRenderInterfaceContextFeature? _externalObjectsFeature; private readonly IExternalObjectsRenderInterfaceContextFeature? _externalObjectsFeature;
public GlSkiaGpu(IGlContext context, long? maxResourceBytes) public GlSkiaGpu(IGlContext context, long? maxResourceBytes, bool? useStencilBuffers)
{ {
_glContext = context; _glContext = context;
using (_glContext.EnsureCurrent()) using (_glContext.EnsureCurrent())
@ -40,7 +40,8 @@ namespace Avalonia.Skia
using(iface) using(iface)
{ {
_grContext = GRContext.CreateGl(iface, new GRContextOptions { AvoidStencilBuffers = true }); var avoidStencilBuffers = useStencilBuffers == false;
_grContext = GRContext.CreateGl(iface, new GRContextOptions { AvoidStencilBuffers = avoidStencilBuffers });
if (maxResourceBytes.HasValue) if (maxResourceBytes.HasValue)
{ {
_grContext.SetResourceCacheLimit(maxResourceBytes.Value); _grContext.SetResourceCacheLimit(maxResourceBytes.Value);

6
src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs

@ -13,7 +13,7 @@ internal class VulkanSkiaGpu : ISkiaGpu
public IVulkanPlatformGraphicsContext Vulkan { get; private set; } public IVulkanPlatformGraphicsContext Vulkan { get; private set; }
public GRContext GrContext { get; private set; } public GRContext GrContext { get; private set; }
public VulkanSkiaGpu(IVulkanPlatformGraphicsContext vulkan, long? maxResourceBytes) public VulkanSkiaGpu(IVulkanPlatformGraphicsContext vulkan, long? maxResourceBytes, bool? useStencilBuffers)
{ {
Vulkan = vulkan; Vulkan = vulkan;
var device = vulkan.Device; var device = vulkan.Device;
@ -48,7 +48,9 @@ internal class VulkanSkiaGpu : ISkiaGpu
GetProcedureAddress = GetProcAddressWrapper GetProcedureAddress = GetProcAddressWrapper
}; };
GrContext = GRContext.CreateVulkan(ctx) ?? var avoidStencilBuffers = useStencilBuffers == false;
GrContext = GRContext.CreateVulkan(ctx, new GRContextOptions { AvoidStencilBuffers = avoidStencilBuffers }) ??
throw new VulkanException("Unable to create GrContext from IVulkanDevice"); throw new VulkanException("Unable to create GrContext from IVulkanDevice");
if (maxResourceBytes.HasValue) if (maxResourceBytes.HasValue)

10
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -20,10 +20,12 @@ namespace Avalonia.Skia
internal class PlatformRenderInterface : IPlatformRenderInterface internal class PlatformRenderInterface : IPlatformRenderInterface
{ {
private readonly long? _maxResourceBytes; private readonly long? _maxResourceBytes;
private readonly bool? _useStencilBuffers;
public PlatformRenderInterface(long? maxResourceBytes = null) public PlatformRenderInterface(long? maxResourceBytes = null, bool? useStencilBuffers = null)
{ {
_maxResourceBytes = maxResourceBytes; _maxResourceBytes = maxResourceBytes;
_useStencilBuffers = useStencilBuffers;
DefaultPixelFormat = SKImageInfo.PlatformColorType.ToPixelFormat(); DefaultPixelFormat = SKImageInfo.PlatformColorType.ToPixelFormat();
} }
@ -35,11 +37,11 @@ namespace Avalonia.Skia
if (graphicsContext is ISkiaGpu skiaGpu) if (graphicsContext is ISkiaGpu skiaGpu)
return new SkiaContext(skiaGpu); return new SkiaContext(skiaGpu);
if (graphicsContext is IGlContext gl) if (graphicsContext is IGlContext gl)
return new SkiaContext(new GlSkiaGpu(gl, _maxResourceBytes)); return new SkiaContext(new GlSkiaGpu(gl, _maxResourceBytes, _useStencilBuffers));
if (graphicsContext is IMetalDevice metal) if (graphicsContext is IMetalDevice metal)
return new SkiaContext(new SkiaMetalGpu(metal, _maxResourceBytes)); return new SkiaContext(new SkiaMetalGpu(metal, _maxResourceBytes, _useStencilBuffers));
if (graphicsContext is IVulkanPlatformGraphicsContext vulkanContext) if (graphicsContext is IVulkanPlatformGraphicsContext vulkanContext)
return new SkiaContext(new VulkanSkiaGpu(vulkanContext, _maxResourceBytes)); return new SkiaContext(new VulkanSkiaGpu(vulkanContext, _maxResourceBytes, _useStencilBuffers));
throw new ArgumentException("Graphics context of type is not supported"); throw new ArgumentException("Graphics context of type is not supported");
} }

6
src/Skia/Avalonia.Skia/SkiaOptions.cs

@ -24,5 +24,11 @@ namespace Avalonia
/// Enabling this might have performance implications. /// Enabling this might have performance implications.
/// </remarks> /// </remarks>
public bool UseOpacitySaveLayer { get; set; } = false; public bool UseOpacitySaveLayer { get; set; } = false;
/// <summary>
/// Gets whether stencil buffers can be used for various draw operations, improving performance.
/// If null (the default), Avalonia chooses whether to enable stencil buffers depending on the platform.
/// </summary>
public bool? UseStencilBuffers { get; set; }
} }
} }

2
src/Skia/Avalonia.Skia/SkiaPlatform.cs

@ -17,7 +17,7 @@ namespace Avalonia.Skia
public static void Initialize(SkiaOptions options) public static void Initialize(SkiaOptions options)
{ {
var renderInterface = new PlatformRenderInterface(options.MaxGpuResourceSizeBytes); var renderInterface = new PlatformRenderInterface(options.MaxGpuResourceSizeBytes, options.UseStencilBuffers);
AvaloniaLocator.CurrentMutable AvaloniaLocator.CurrentMutable
.Bind<IPlatformRenderInterface>().ToConstant(renderInterface) .Bind<IPlatformRenderInterface>().ToConstant(renderInterface)

Loading…
Cancel
Save