Browse Source

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
Nikita Tsukanov 1 year ago
parent
commit
cffb4b8d62

+ 0 - 6
src/Avalonia.Base/Media/PlatformDrawingContext.cs

@@ -26,12 +26,6 @@ internal sealed class PlatformDrawingContext : DrawingContext
         _ownsImpl = ownsImpl;
         _ownsImpl = ownsImpl;
     }
     }
 
 
-    public RenderOptions RenderOptions
-    {
-        get => _impl.RenderOptions;
-        set => _impl.RenderOptions = value;
-    }
-
     protected override void DrawLineCore(IPen pen, Point p1, Point p2) =>
     protected override void DrawLineCore(IPen pen, Point p1, Point p2) =>
         _impl.DrawLine(pen, p1, p2);
         _impl.DrawLine(pen, p1, p2);
 
 

+ 0 - 5
src/Avalonia.Base/Platform/IDrawingContextImpl.cs

@@ -13,11 +13,6 @@ namespace Avalonia.Platform
     [Unstable]
     [Unstable]
     public interface IDrawingContextImpl : IDisposable
     public interface IDrawingContextImpl : IDisposable
     {
     {
-        /// <summary>
-        /// Gets or sets the current render options used to control the rendering behavior of drawing operations.
-        /// </summary>
-        RenderOptions RenderOptions { get; set; }
-
         /// <summary>
         /// <summary>
         /// Gets or sets the current transform of the drawing context.
         /// Gets or sets the current transform of the drawing context.
         /// </summary>
         /// </summary>

+ 0 - 6
src/Avalonia.Base/Rendering/Composition/Server/DrawingContextProxy.cs

@@ -41,12 +41,6 @@ internal class CompositorDrawingContextProxy : IDrawingContextImpl,
         set => _impl.Transform = (_transform = value) * PostTransform;
         set => _impl.Transform = (_transform = value) * PostTransform;
     }
     }
 
 
-    public RenderOptions RenderOptions
-    {
-        get => _impl.RenderOptions;
-        set => _impl.RenderOptions = value;
-    }
-
     public void Clear(Color color)
     public void Clear(Color color)
     {
     {
         _impl.Clear(color);
         _impl.Clear(color);

+ 2 - 1
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.DirtyProperties.cs

@@ -14,7 +14,8 @@ partial class ServerCompositionVisual
           | CompositionVisualChangedFields.ClipToBounds
           | CompositionVisualChangedFields.ClipToBounds
           | CompositionVisualChangedFields.ClipToBoundsAnimated
           | CompositionVisualChangedFields.ClipToBoundsAnimated
           | CompositionVisualChangedFields.Size
           | CompositionVisualChangedFields.Size
-          | CompositionVisualChangedFields.SizeAnimated;
+          | CompositionVisualChangedFields.SizeAnimated
+          | CompositionVisualChangedFields.RenderOptions;
 
 
     private const CompositionVisualChangedFields CombinedTransformFieldsMask =
     private const CompositionVisualChangedFields CombinedTransformFieldsMask =
         CompositionVisualChangedFields.Size
         CompositionVisualChangedFields.Size

+ 6 - 7
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs

@@ -58,6 +58,10 @@ namespace Avalonia.Rendering.Composition.Server
             canvas.PostTransform = transform;
             canvas.PostTransform = transform;
             canvas.Transform = Matrix.Identity;
             canvas.Transform = Matrix.Identity;
 
 
+            var applyRenderOptions = RenderOptions != default;
+
+            if (applyRenderOptions)
+                canvas.PushRenderOptions(RenderOptions);
             if (Effect != null)
             if (Effect != null)
                 canvas.PushEffect(Effect);
                 canvas.PushEffect(Effect);
             
             
@@ -70,8 +74,6 @@ namespace Avalonia.Rendering.Composition.Server
             if (OpacityMaskBrush != null)
             if (OpacityMaskBrush != null)
                 canvas.PushOpacityMask(OpacityMaskBrush, boundsRect);
                 canvas.PushOpacityMask(OpacityMaskBrush, boundsRect);
 
 
-            canvas.RenderOptions = RenderOptions;
-
             RenderCore(canvas, currentTransformedClip, dirtyRects);
             RenderCore(canvas, currentTransformedClip, dirtyRects);
             
             
             // Hack to force invalidation of SKMatrix
             // Hack to force invalidation of SKMatrix
@@ -91,6 +93,8 @@ namespace Avalonia.Rendering.Composition.Server
             
             
             if (Effect != null)
             if (Effect != null)
                 canvas.PopEffect();
                 canvas.PopEffect();
+            if(applyRenderOptions)
+                canvas.PopRenderOptions();
         }
         }
 
 
         protected virtual bool HandlesClipToBounds => false;
         protected virtual bool HandlesClipToBounds => false;
@@ -128,11 +132,6 @@ namespace Avalonia.Rendering.Composition.Server
 
 
             var wasVisible = IsVisibleInFrame;
             var wasVisible = IsVisibleInFrame;
 
 
-            if(Parent != null)
-            {
-                RenderOptions = RenderOptions.MergeWith(Parent.RenderOptions);
-            }
-
             // Calculate new parent-relative transform
             // Calculate new parent-relative transform
             if (_combinedTransformDirty)
             if (_combinedTransformDirty)
             {
             {

+ 1 - 18
src/Avalonia.Base/Rendering/ImmediateRenderer.cs

@@ -44,18 +44,8 @@ namespace Avalonia.Rendering
 
 
         public static void Render(DrawingContext context, Visual visual, Rect clipRect)
         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 opacity = visual.Opacity;
                 var clipToBounds = visual.ClipToBounds;
                 var clipToBounds = visual.ClipToBounds;
                 var bounds = new Rect(visual.Bounds.Size);
                 var bounds = new Rect(visual.Bounds.Size);
@@ -130,13 +120,6 @@ namespace Avalonia.Rendering
                     }
                     }
                 }
                 }
             }
             }
-            finally
-            {
-                if (platformContext != null)
-                {
-                    platformContext.RenderOptions = currentRenderOptions;
-                }
-            }       
         }
         }
     }
     }
 }
 }

+ 8 - 4
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@@ -1050,15 +1050,17 @@ namespace Avalonia.Skia
 
 
                 context.Clear(Colors.Transparent);
                 context.Clear(Colors.Transparent);
                 context.PushClip(calc.IntermediateClip);
                 context.PushClip(calc.IntermediateClip);
+                context.PushRenderOptions(RenderOptions);
+                
                 context.Transform = calc.IntermediateTransform;
                 context.Transform = calc.IntermediateTransform;
-                context.RenderOptions = RenderOptions;
-
+                
                 context.DrawBitmap(
                 context.DrawBitmap(
                     tileBrushImage,
                     tileBrushImage,
                     1,
                     1,
                     sourceRect,
                     sourceRect,
                     targetRect);
                     targetRect);
 
 
+                context.PopRenderOptions();
                 context.PopClip();
                 context.PopClip();
             }
             }
 
 
@@ -1133,9 +1135,10 @@ namespace Avalonia.Skia
 
 
                 using (var ctx = intermediate.CreateDrawingContext(true))
                 using (var ctx = intermediate.CreateDrawingContext(true))
                 {
                 {
-                    ctx.RenderOptions = RenderOptions;
+                    ctx.PushRenderOptions(RenderOptions);
                     ctx.Clear(Colors.Transparent);
                     ctx.Clear(Colors.Transparent);
                     content.Render(ctx, rect.TopLeft == default ? null : Matrix.CreateTranslation(-rect.X, -rect.Y));
                     content.Render(ctx, rect.TopLeft == default ? null : Matrix.CreateTranslation(-rect.X, -rect.Y));
+                    ctx.PopRenderOptions();
                 }
                 }
 
 
                 ConfigureTileBrush(ref paintWrapper, targetRect, content.Brush, intermediate);
                 ConfigureTileBrush(ref paintWrapper, targetRect, content.Brush, intermediate);
@@ -1170,9 +1173,10 @@ namespace Avalonia.Skia
             using var pictureTarget = new PictureRenderTarget(_gpu, _grContext, _intermediateSurfaceDpi);
             using var pictureTarget = new PictureRenderTarget(_gpu, _grContext, _intermediateSurfaceDpi);
             using (var ctx = pictureTarget.CreateDrawingContext(calc.IntermediateSize))
             using (var ctx = pictureTarget.CreateDrawingContext(calc.IntermediateSize))
             {
             {
-                ctx.RenderOptions = RenderOptions;
                 ctx.PushClip(calc.IntermediateClip);
                 ctx.PushClip(calc.IntermediateClip);
+                ctx.PushRenderOptions(RenderOptions);
                 content.Render(ctx, transform);
                 content.Render(ctx, transform);
+                ctx.PopRenderOptions();
                 ctx.PopClip();
                 ctx.PopClip();
             }
             }