diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionContainerVisual.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionContainerVisual.cs index 4f300503b2..396009841b 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionContainerVisual.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionContainerVisual.cs @@ -65,6 +65,8 @@ namespace Avalonia.Rendering.Composition.Server return new(_transformedContentBounds, oldInvalidated, newInvalidated); } + protected override LtrbRect GetEffectBounds() => _transformedContentBounds ?? default; + void AddEffectPaddedDirtyRect(IImmutableEffect effect, LtrbRect transformedBounds) { var padding = effect.GetEffectOutputPadding(); diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs index 112a817541..306693ba34 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs @@ -62,8 +62,7 @@ namespace Avalonia.Rendering.Composition.Server if (applyRenderOptions) canvas.PushRenderOptions(RenderOptions); - if (Effect != null) - canvas.PushEffect(Effect); + var needPopEffect = PushEffect(canvas); if (Opacity != 1) canvas.PushOpacity(Opacity, ClipToBounds ? boundsRect : null); @@ -87,12 +86,28 @@ namespace Avalonia.Rendering.Composition.Server if (Opacity != 1) canvas.PopOpacity(); - if (Effect != null) + if (needPopEffect) canvas.PopEffect(); if(applyRenderOptions) canvas.PopRenderOptions(); } + protected virtual LtrbRect GetEffectBounds() => TransformedOwnContentBounds; + + private bool PushEffect(CompositorDrawingContextProxy canvas) + { + if (Effect == null) + return false; + var clip = GetEffectBounds(); + if (clip.IsZeroSize) + return false; + var oldMatrix = canvas.Transform; + canvas.Transform = Matrix.Identity; + canvas.PushEffect(GetEffectBounds().ToRect(), Effect!); + canvas.Transform = oldMatrix; + return true; + } + protected virtual bool HandlesClipToBounds => false; private ReadbackData _readback0, _readback1, _readback2;