From bc79b388b57703a20b09f7c8de38b2d19b6aaab0 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sat, 29 Apr 2023 22:06:45 -0400 Subject: [PATCH] Use ImmediateDrawingContext in the ICustomDrawOperation interface --- samples/RenderDemo/Pages/CustomSkiaPage.cs | 4 ++-- .../Media/PlatformDrawingContext.cs | 16 ++++++++++++++-- .../Rendering/SceneGraph/CustomDrawOperation.cs | 14 ++++++++++++-- .../Avalonia.Browser/WebEmbeddableControlRoot.cs | 2 +- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/samples/RenderDemo/Pages/CustomSkiaPage.cs b/samples/RenderDemo/Pages/CustomSkiaPage.cs index 4a3e20ff5b..2d64ba8f7b 100644 --- a/samples/RenderDemo/Pages/CustomSkiaPage.cs +++ b/samples/RenderDemo/Pages/CustomSkiaPage.cs @@ -44,9 +44,9 @@ namespace RenderDemo.Pages public bool HitTest(Point p) => false; public bool Equals(ICustomDrawOperation other) => false; static Stopwatch St = Stopwatch.StartNew(); - public void Render(IDrawingContextImpl context) + public void Render(ImmediateDrawingContext context) { - var leaseFeature = context.GetFeature(); + var leaseFeature = context.TryGetFeature(); if (leaseFeature == null) context.DrawGlyphRun(Brushes.Black, _noSkia.PlatformImpl); else diff --git a/src/Avalonia.Base/Media/PlatformDrawingContext.cs b/src/Avalonia.Base/Media/PlatformDrawingContext.cs index eb8a93722c..4b683c6acb 100644 --- a/src/Avalonia.Base/Media/PlatformDrawingContext.cs +++ b/src/Avalonia.Base/Media/PlatformDrawingContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Avalonia.Logging; using Avalonia.Media.Imaging; using Avalonia.Media.Immutable; using Avalonia.Platform; @@ -41,8 +42,19 @@ internal sealed class PlatformDrawingContext : DrawingContext, IDrawingContextWi BitmapInterpolationMode bitmapInterpolationMode = BitmapInterpolationMode.Default) => _impl.DrawBitmap(source, opacity, sourceRect, destRect, bitmapInterpolationMode); - public override void Custom(ICustomDrawOperation custom) => - custom.Render(_impl); + public override void Custom(ICustomDrawOperation custom) + { + using var immediateDrawingContext = new ImmediateDrawingContext(_impl, false); + try + { + custom.Render(immediateDrawingContext); + } + catch (Exception e) + { + Logger.TryGet(LogEventLevel.Error, LogArea.Visual) + ?.Log(custom, $"Exception in {custom.GetType().Name}.{nameof(ICustomDrawOperation.Render)} {{0}}", e); + } + } public override void DrawGlyphRun(IBrush? foreground, GlyphRun glyphRun) { diff --git a/src/Avalonia.Base/Rendering/SceneGraph/CustomDrawOperation.cs b/src/Avalonia.Base/Rendering/SceneGraph/CustomDrawOperation.cs index 8f5ccb4e51..7ce9e6a8af 100644 --- a/src/Avalonia.Base/Rendering/SceneGraph/CustomDrawOperation.cs +++ b/src/Avalonia.Base/Rendering/SceneGraph/CustomDrawOperation.cs @@ -1,4 +1,5 @@ using System; +using Avalonia.Logging; using Avalonia.Media; using Avalonia.Platform; @@ -17,7 +18,16 @@ namespace Avalonia.Rendering.SceneGraph public override void Render(IDrawingContextImpl context) { - Custom.Render(context); + using var immediateDrawingContext = new ImmediateDrawingContext(context, false); + try + { + Custom.Render(immediateDrawingContext); + } + catch (Exception e) + { + Logger.TryGet(LogEventLevel.Error, LogArea.Visual) + ?.Log(Custom, $"Exception in {Custom.GetType().Name}.{nameof(ICustomDrawOperation.Render)} {{0}}", e); + } } public override void Dispose() => Custom.Dispose(); @@ -48,6 +58,6 @@ namespace Avalonia.Rendering.SceneGraph /// Renders the node to a drawing context. /// /// The drawing context. - void Render(IDrawingContextImpl context); + void Render(ImmediateDrawingContext context); } } diff --git a/src/Browser/Avalonia.Browser/WebEmbeddableControlRoot.cs b/src/Browser/Avalonia.Browser/WebEmbeddableControlRoot.cs index df1a24fa0f..993414f17f 100644 --- a/src/Browser/Avalonia.Browser/WebEmbeddableControlRoot.cs +++ b/src/Browser/Avalonia.Browser/WebEmbeddableControlRoot.cs @@ -37,7 +37,7 @@ namespace Avalonia.Browser return false; } - public void Render(IDrawingContextImpl context) + public void Render(ImmediateDrawingContext context) { _hasRendered = true; _onFirstRender();