Browse Source

Use the correct flag to determine if extra dirty rect needs to be combined with existing one

# Conflicts:
#	src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisual.ComputedProperties.cs
xpf/composition-rework-branch
Nikita Tsukanov 1 week ago
parent
commit
dd44ec447f
  1. 6
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisual.ComputedProperties.cs
  2. 2
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisual.DirtyInputs.cs
  3. 6
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisual.Update.cs
  4. 25
      tests/Avalonia.Base.UnitTests/Rendering/CompositorInvalidationTests.cs

6
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisual.ComputedProperties.cs

@ -50,7 +50,7 @@ partial class ServerCompositionVisual
private LtrbRect? _ownClipRect; private LtrbRect? _ownClipRect;
private bool _hasExtraDirtyRect; private bool _needsToAddExtraDirtyRectToDirtyRegion;
private LtrbRect _extraDirtyRect; private LtrbRect _extraDirtyRect;
public virtual LtrbRect? ComputeOwnContentBounds() => null; public virtual LtrbRect? ComputeOwnContentBounds() => null;
@ -107,7 +107,7 @@ partial class ServerCompositionVisual
_isDirtyForRender |= fDirtyForRender; _isDirtyForRender |= fDirtyForRender;
// If node itself is dirty for render, we don't need to keep track of extra dirty rects // If node itself is dirty for render, we don't need to keep track of extra dirty rects
_hasExtraDirtyRect = !fDirtyForRender && (_hasExtraDirtyRect || fAdditionalDirtyRegion); _needsToAddExtraDirtyRectToDirtyRegion = !fDirtyForRender && (_needsToAddExtraDirtyRectToDirtyRegion || fAdditionalDirtyRegion);
} }
public void RecomputeOwnProperties() public void RecomputeOwnProperties()
@ -161,4 +161,4 @@ partial class ServerCompositionVisual
_ownBoundsDirty = _clipSizeDirty = _combinedTransformDirty = _compositionFieldsDirty = false; _ownBoundsDirty = _clipSizeDirty = _combinedTransformDirty = _compositionFieldsDirty = false;
PropagateFlags(setDirtyBounds, setDirtyForRender, setHasExtraDirtyRect); PropagateFlags(setDirtyBounds, setDirtyForRender, setHasExtraDirtyRect);
} }
} }

2
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisual.DirtyInputs.cs

@ -163,7 +163,7 @@ partial class ServerCompositionVisual
protected void AddExtraDirtyRect(LtrbRect rect) protected void AddExtraDirtyRect(LtrbRect rect)
{ {
_extraDirtyRect = _hasExtraDirtyRect ? _extraDirtyRect.Union(rect) : rect; _extraDirtyRect = _delayPropagateHasExtraDirtyRects ? _extraDirtyRect.Union(rect) : rect;
_delayPropagateHasExtraDirtyRects = true; _delayPropagateHasExtraDirtyRects = true;
EnqueueOwnPropertiesRecompute(); EnqueueOwnPropertiesRecompute();
} }

6
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisual.Update.cs

@ -56,7 +56,7 @@ internal partial class ServerCompositionVisual
private bool NeedToPushBoundsAffectingProperties(ServerCompositionVisual node) private bool NeedToPushBoundsAffectingProperties(ServerCompositionVisual node)
{ {
return (node._isDirtyForRenderInSubgraph || node._hasExtraDirtyRect || node._contentChanged); return (node._isDirtyForRenderInSubgraph || node._needsToAddExtraDirtyRectToDirtyRegion || node._contentChanged);
} }
public void PreSubgraph(ServerCompositionVisual node, out bool visitChildren) public void PreSubgraph(ServerCompositionVisual node, out bool visitChildren)
@ -141,7 +141,7 @@ internal partial class ServerCompositionVisual
// specified before the tranform, i.e. in inner space, hence we have to pick them // specified before the tranform, i.e. in inner space, hence we have to pick them
// up before we pop the transform from the transform stack. // up before we pop the transform from the transform stack.
// //
if (node._hasExtraDirtyRect) if (node._needsToAddExtraDirtyRectToDirtyRegion)
{ {
AddToDirtyRegion(node._extraDirtyRect); AddToDirtyRegion(node._extraDirtyRect);
} }
@ -167,7 +167,7 @@ internal partial class ServerCompositionVisual
node._isDirtyForRender = false; node._isDirtyForRender = false;
node._isDirtyForRenderInSubgraph = false; node._isDirtyForRenderInSubgraph = false;
node._needsBoundingBoxUpdate = false; node._needsBoundingBoxUpdate = false;
node._hasExtraDirtyRect = false; node._needsToAddExtraDirtyRectToDirtyRegion = false;
node._contentChanged = false; node._contentChanged = false;
} }

25
tests/Avalonia.Base.UnitTests/Rendering/CompositorInvalidationTests.cs

@ -38,6 +38,31 @@ public class CompositorInvalidationTests : CompositorTestsBase
s.AssertRects(new Rect(30, 50, 20, 10)); s.AssertRects(new Rect(30, 50, 20, 10));
} }
} }
[Fact]
public void Sibling_Controls_Should_Invalidate_Union_Rect_When_Removed()
{
using (var s = new CompositorCanvas())
{
var control = new Border()
{
Background = Brushes.Red, Width = 20, Height = 10,
[Canvas.LeftProperty] = 30, [Canvas.TopProperty] = 10
};
var control2 = new Border()
{
Background = Brushes.Blue, Width = 20, Height = 10,
[Canvas.LeftProperty] = 30, [Canvas.TopProperty] = 50
};
s.Canvas.Children.Add(control);
s.Canvas.Children.Add(control2);
s.RunJobs();
s.Events.Rects.Clear();
s.Canvas.Children.Remove(control);
s.Canvas.Children.Remove(control2);
s.AssertRects(new Rect(30, 10, 20, 50));
}
}
[Fact] [Fact]
public void Control_Should_Invalidate_Both_Own_Rects_When_Moved() public void Control_Should_Invalidate_Both_Own_Rects_When_Moved()

Loading…
Cancel
Save