From cffb4b8d6230dc8d80e85680899a0fe69b95dd23 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Thu, 28 Mar 2024 15:54:24 +0500 Subject: [PATCH] Don't merge RenderOptions during update and only push them to drawing context if actually needed (#15111) * Don't merge RenderOptions during update and only push them to drawing context if actually needed * Removed RenderOptions property from IDrawingContextImpl --- .../Media/PlatformDrawingContext.cs | 6 ------ .../Platform/IDrawingContextImpl.cs | 5 ----- .../Composition/Server/DrawingContextProxy.cs | 6 ------ ...ServerCompositionVisual.DirtyProperties.cs | 3 ++- .../Server/ServerCompositionVisual.cs | 13 ++++++------- .../Rendering/ImmediateRenderer.cs | 19 +------------------ src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 12 ++++++++---- 7 files changed, 17 insertions(+), 47 deletions(-) diff --git a/src/Avalonia.Base/Media/PlatformDrawingContext.cs b/src/Avalonia.Base/Media/PlatformDrawingContext.cs index 410d996db2..312cae2c52 100644 --- a/src/Avalonia.Base/Media/PlatformDrawingContext.cs +++ b/src/Avalonia.Base/Media/PlatformDrawingContext.cs @@ -26,12 +26,6 @@ internal sealed class PlatformDrawingContext : DrawingContext _ownsImpl = ownsImpl; } - public RenderOptions RenderOptions - { - get => _impl.RenderOptions; - set => _impl.RenderOptions = value; - } - protected override void DrawLineCore(IPen pen, Point p1, Point p2) => _impl.DrawLine(pen, p1, p2); diff --git a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs index f367ed89ca..9621037cc1 100644 --- a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs +++ b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs @@ -13,11 +13,6 @@ namespace Avalonia.Platform [Unstable] public interface IDrawingContextImpl : IDisposable { - /// - /// Gets or sets the current render options used to control the rendering behavior of drawing operations. - /// - RenderOptions RenderOptions { get; set; } - /// /// Gets or sets the current transform of the drawing context. /// diff --git a/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs b/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs index 980c1413c6..0533278056 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs @@ -41,12 +41,6 @@ internal class CompositorDrawingContextProxy : IDrawingContextImpl, set => _impl.Transform = (_transform = value) * PostTransform; } - public RenderOptions RenderOptions - { - get => _impl.RenderOptions; - set => _impl.RenderOptions = value; - } - public void Clear(Color color) { _impl.Clear(color); diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.DirtyProperties.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.DirtyProperties.cs index 51414c2250..9d17756f2b 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.DirtyProperties.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.DirtyProperties.cs @@ -14,7 +14,8 @@ partial class ServerCompositionVisual | CompositionVisualChangedFields.ClipToBounds | CompositionVisualChangedFields.ClipToBoundsAnimated | CompositionVisualChangedFields.Size - | CompositionVisualChangedFields.SizeAnimated; + | CompositionVisualChangedFields.SizeAnimated + | CompositionVisualChangedFields.RenderOptions; private const CompositionVisualChangedFields CombinedTransformFieldsMask = CompositionVisualChangedFields.Size diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs index 1e19ee0051..65f6df6d9b 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs @@ -58,6 +58,10 @@ namespace Avalonia.Rendering.Composition.Server canvas.PostTransform = transform; canvas.Transform = Matrix.Identity; + var applyRenderOptions = RenderOptions != default; + + if (applyRenderOptions) + canvas.PushRenderOptions(RenderOptions); if (Effect != null) canvas.PushEffect(Effect); @@ -70,8 +74,6 @@ namespace Avalonia.Rendering.Composition.Server if (OpacityMaskBrush != null) canvas.PushOpacityMask(OpacityMaskBrush, boundsRect); - canvas.RenderOptions = RenderOptions; - RenderCore(canvas, currentTransformedClip, dirtyRects); // Hack to force invalidation of SKMatrix @@ -91,6 +93,8 @@ namespace Avalonia.Rendering.Composition.Server if (Effect != null) canvas.PopEffect(); + if(applyRenderOptions) + canvas.PopRenderOptions(); } protected virtual bool HandlesClipToBounds => false; @@ -128,11 +132,6 @@ namespace Avalonia.Rendering.Composition.Server var wasVisible = IsVisibleInFrame; - if(Parent != null) - { - RenderOptions = RenderOptions.MergeWith(Parent.RenderOptions); - } - // Calculate new parent-relative transform if (_combinedTransformDirty) { diff --git a/src/Avalonia.Base/Rendering/ImmediateRenderer.cs b/src/Avalonia.Base/Rendering/ImmediateRenderer.cs index 37c5e0a2c6..1d2244dfbb 100644 --- a/src/Avalonia.Base/Rendering/ImmediateRenderer.cs +++ b/src/Avalonia.Base/Rendering/ImmediateRenderer.cs @@ -44,18 +44,8 @@ namespace Avalonia.Rendering public static void Render(DrawingContext context, Visual visual, Rect clipRect) { - var currentRenderOptions = default(RenderOptions); - var platformContext = context as PlatformDrawingContext; - - try + using(visual.RenderOptions != default ? context.PushRenderOptions(visual.RenderOptions) : (DrawingContext.PushedState?)null) { - if (platformContext != null) - { - currentRenderOptions = platformContext.RenderOptions; - - platformContext.RenderOptions = visual.RenderOptions.MergeWith(platformContext.RenderOptions); - } - var opacity = visual.Opacity; var clipToBounds = visual.ClipToBounds; var bounds = new Rect(visual.Bounds.Size); @@ -130,13 +120,6 @@ namespace Avalonia.Rendering } } } - finally - { - if (platformContext != null) - { - platformContext.RenderOptions = currentRenderOptions; - } - } } } } diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 562faa6c94..39a11ede14 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -1050,15 +1050,17 @@ namespace Avalonia.Skia context.Clear(Colors.Transparent); context.PushClip(calc.IntermediateClip); + context.PushRenderOptions(RenderOptions); + context.Transform = calc.IntermediateTransform; - context.RenderOptions = RenderOptions; - + context.DrawBitmap( tileBrushImage, 1, sourceRect, targetRect); + context.PopRenderOptions(); context.PopClip(); } @@ -1133,9 +1135,10 @@ namespace Avalonia.Skia using (var ctx = intermediate.CreateDrawingContext(true)) { - ctx.RenderOptions = RenderOptions; + ctx.PushRenderOptions(RenderOptions); ctx.Clear(Colors.Transparent); content.Render(ctx, rect.TopLeft == default ? null : Matrix.CreateTranslation(-rect.X, -rect.Y)); + ctx.PopRenderOptions(); } ConfigureTileBrush(ref paintWrapper, targetRect, content.Brush, intermediate); @@ -1170,9 +1173,10 @@ namespace Avalonia.Skia using var pictureTarget = new PictureRenderTarget(_gpu, _grContext, _intermediateSurfaceDpi); using (var ctx = pictureTarget.CreateDrawingContext(calc.IntermediateSize)) { - ctx.RenderOptions = RenderOptions; ctx.PushClip(calc.IntermediateClip); + ctx.PushRenderOptions(RenderOptions); content.Render(ctx, transform); + ctx.PopRenderOptions(); ctx.PopClip(); }