diff --git a/src/Avalonia.Base/Layout/Layoutable.cs b/src/Avalonia.Base/Layout/Layoutable.cs index 47f2217816..b2d47ad112 100644 --- a/src/Avalonia.Base/Layout/Layoutable.cs +++ b/src/Avalonia.Base/Layout/Layoutable.cs @@ -948,5 +948,17 @@ namespace Avalonia.Layout { return new Size(Math.Max(size.Width, 0), Math.Max(size.Height, 0)); } + + internal override void SynchronizeCompositionProperties() + { + base.SynchronizeCompositionProperties(); + + if (CompositionVisual is { } visual) + { + // If the visual isn't using layout rounding, it's possible that antialiasing renders to pixels + // outside the current bounds. Extend the dirty rect by 1px in all directions in this case. + visual.ShouldExtendDirtyRect = !UseLayoutRounding; + } + } } } diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs index 54848d885d..112a817541 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual.cs @@ -254,6 +254,12 @@ namespace Avalonia.Rendering.Composition.Server { if (rc == default) return; + + // If the visual isn't using layout rounding, it's possible that antialiasing renders to pixels + // outside the current bounds. Extend the dirty rect by 1px in all directions in this case. + if (ShouldExtendDirtyRect && RenderOptions.EdgeMode != EdgeMode.Aliased) + rc = rc.Inflate(new Thickness(1)); + Root?.AddDirtyRect(rc); } diff --git a/src/Avalonia.Base/composition-schema.xml b/src/Avalonia.Base/composition-schema.xml index 6c48c71b51..ce989296b1 100644 --- a/src/Avalonia.Base/composition-schema.xml +++ b/src/Avalonia.Base/composition-schema.xml @@ -34,6 +34,7 @@ +