Browse Source

Merge pull request #2524 from AvaloniaUI/fixes/2518-invalidate-in-sceneinvalidated

Clear dirty rects before calling SceneInvalidated.
Steven Kirk 6 years ago
parent
commit
ba9499f546

+ 3 - 2
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@@ -528,6 +528,8 @@ namespace Avalonia.Rendering
                     oldScene?.Dispose();
                 }
 
+                _dirty.Clear();
+
                 if (SceneInvalidated != null)
                 {
                     var rect = new Rect();
@@ -540,10 +542,9 @@ namespace Avalonia.Rendering
                         }
                     }
 
+                    System.Diagnostics.Debug.WriteLine("Invalidated " + rect);
                     SceneInvalidated(this, new SceneInvalidatedEventArgs((IRenderRoot)_root, rect));
                 }
-
-                _dirty.Clear();
             }
             else
             {

+ 46 - 0
tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs

@@ -325,6 +325,52 @@ namespace Avalonia.Visuals.UnitTests.Rendering
             context.Verify(x => x.DrawImage(borderLayer, 0.5, It.IsAny<Rect>(), It.IsAny<Rect>(), BitmapInterpolationMode.Default));
         }
 
+        [Fact]
+        public void Can_Dirty_Control_In_SceneInvalidated()
+        {
+            Border border1;
+            Border border2;
+            var root = new TestRoot
+            {
+                Width = 100,
+                Height = 100,
+                Child = new StackPanel
+                {
+                    Children =
+                    {
+                        (border1 = new Border
+                        {
+                            Background = Brushes.Red,
+                            Child = new Canvas(),
+                        }),
+                        (border2 = new Border
+                        {
+                            Background = Brushes.Red,
+                            Child = new Canvas(),
+                        }),
+                    }
+                }
+            };
+
+            root.Measure(Size.Infinity);
+            root.Arrange(new Rect(root.DesiredSize));
+
+            var target = CreateTargetAndRunFrame(root);
+            var invalidated = false;
+
+            target.SceneInvalidated += (s, e) =>
+            {
+                invalidated = true;
+                target.AddDirty(border2);
+            };
+
+            target.AddDirty(border1);
+            target.Paint(new Rect(root.DesiredSize));
+
+            Assert.True(invalidated);
+            Assert.True(((IRenderLoopTask)target).NeedsUpdate);
+        }
+
         private DeferredRenderer CreateTargetAndRunFrame(
             TestRoot root,
             Mock<IRenderTimer> timer = null,