From bc79b388b57703a20b09f7c8de38b2d19b6aaab0 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sat, 29 Apr 2023 22:06:45 -0400 Subject: [PATCH 1/2] 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(); From cc0e2302e7a58dd5453dfa2e315179b506abbf37 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sat, 29 Apr 2023 22:07:12 -0400 Subject: [PATCH 2/2] Remove ICustomDrawOperation from the IDrawingContextImpl as it seems useless there now --- src/Avalonia.Base/Media/ImmediateDrawingContext.cs | 1 - src/Avalonia.Base/Platform/IDrawingContextImpl.cs | 7 ------- .../Rendering/Composition/Server/DrawingContextProxy.cs | 5 ----- .../Avalonia.Headless/HeadlessPlatformRenderInterface.cs | 7 +------ src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 9 --------- .../Avalonia.Direct2D1/Media/DrawingContextImpl.cs | 5 +---- 6 files changed, 2 insertions(+), 32 deletions(-) diff --git a/src/Avalonia.Base/Media/ImmediateDrawingContext.cs b/src/Avalonia.Base/Media/ImmediateDrawingContext.cs index 58b153482d..17c4560523 100644 --- a/src/Avalonia.Base/Media/ImmediateDrawingContext.cs +++ b/src/Avalonia.Base/Media/ImmediateDrawingContext.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using Avalonia.Platform; -using Avalonia.Rendering.SceneGraph; using Avalonia.Threading; using Avalonia.Utilities; using Avalonia.Media.Imaging; diff --git a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs index 1359ad6603..ef53024508 100644 --- a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs +++ b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs @@ -1,6 +1,5 @@ using System; using Avalonia.Media; -using Avalonia.Rendering.SceneGraph; using Avalonia.Utilities; using Avalonia.Media.Imaging; using Avalonia.Metadata; @@ -168,12 +167,6 @@ namespace Avalonia.Platform /// void PopBitmapBlendMode(); - /// - /// Adds a custom draw operation - /// - /// Custom draw operation - void Custom(ICustomDrawOperation custom); - /// /// Attempts to get an optional feature from the drawing context implementation /// diff --git a/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs b/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs index 1ec1362a4c..901bdaae0d 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs @@ -143,11 +143,6 @@ internal class CompositorDrawingContextProxy : IDrawingContextImpl, _impl.PopBitmapBlendMode(); } - public void Custom(ICustomDrawOperation custom) - { - _impl.Custom(custom); - } - public object? GetFeature(Type t) => _impl.GetFeature(t); diff --git a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs index b23697fd2a..38375045cb 100644 --- a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs +++ b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs @@ -433,12 +433,7 @@ namespace Avalonia.Headless { } - - public void Custom(ICustomDrawOperation custom) - { - - } - + public object? GetFeature(Type t) { return null; diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index f48d45f961..cea55f4d29 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -5,12 +5,9 @@ using System.Linq; using System.Threading; using Avalonia.Media; using Avalonia.Platform; -using Avalonia.Rendering; -using Avalonia.Rendering.SceneGraph; using Avalonia.Rendering.Utilities; using Avalonia.Utilities; using Avalonia.Media.Imaging; -using Avalonia.Skia.Helpers; using SkiaSharp; using ISceneBrush = Avalonia.Media.ISceneBrush; @@ -667,12 +664,6 @@ namespace Avalonia.Skia _currentBlendingMode = _blendingModeStack.Pop(); } - public void Custom(ICustomDrawOperation custom) - { - CheckLease(); - custom.Render(this); - } - /// public void PushOpacityMask(IBrush mask, Rect bounds) { diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs index 318b0fe9ae..be5cef35b5 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.Numerics; using Avalonia.Media; using Avalonia.Platform; -using Avalonia.Rendering; -using Avalonia.Rendering.SceneGraph; using Avalonia.Utilities; using Avalonia.Media.Imaging; using SharpDX; @@ -608,8 +606,7 @@ namespace Avalonia.Direct2D1.Media { PopLayer(); } - - public void Custom(ICustomDrawOperation custom) => custom.Render(this); + public object GetFeature(Type t) => null; } }