소스 검색

Don't create render layers for non-parent controls.

Only create a new render layer when a control has both an animating opacity _and_ children.
Steven Kirk 8 년 전
부모
커밋
9609d93f3b

+ 9 - 2
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@@ -167,7 +167,6 @@ namespace Avalonia.Rendering.SceneGraph
                 using (context.PushPostTransform(m))
                 using (context.PushTransformContainer())
                 {
-                    var startLayer = (visual as IAvaloniaObject)?.IsAnimating(Visual.OpacityProperty) ?? false;
                     var clipBounds = bounds.TransformToAABB(contextImpl.Transform).Intersect(clip);
 
                     forceRecurse = forceRecurse ||
@@ -181,7 +180,7 @@ namespace Avalonia.Rendering.SceneGraph
                     node.Opacity = opacity;
                     node.OpacityMask = visual.OpacityMask;
 
-                    if (startLayer)
+                    if (ShouldStartLayer(visual))
                     {
                         if (node.LayerRoot != visual)
                         {
@@ -366,6 +365,14 @@ namespace Avalonia.Rendering.SceneGraph
             }
         }
 
+        private static bool ShouldStartLayer(IVisual visual)
+        {
+            var o = visual as IAvaloniaObject;
+            return visual.VisualChildren.Count > 0 &&
+                o != null &&
+                o.IsAnimating(Visual.OpacityProperty);
+        }
+
         private static IGeometryImpl CreateLayerGeometryClip(VisualNode node)
         {
             IGeometryImpl result = null;

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

@@ -261,6 +261,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
                     Child = border = new Border
                     {
                         Background = Brushes.Green,
+                        Child = new Canvas(),
                     }
                 }
             };

+ 47 - 4
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs

@@ -15,7 +15,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
     public partial class SceneBuilderTests
     {
         [Fact]
-        public void Control_With_Animated_Opacity_Should_Start_New_Layer()
+        public void Control_With_Animated_Opacity_And_Children_Should_Start_New_Layer()
         {
             using (TestApplication())
             {
@@ -34,7 +34,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
                         {
                             Background = Brushes.Red,
                             Padding = new Thickness(12),
-                            Child = canvas = new Canvas(),
+                            Child = canvas = new Canvas()
                         }
                     }
                 };
@@ -82,6 +82,42 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
             }
         }
 
+        [Fact]
+        public void Control_With_Animated_Opacity_And_No_Children_Should_Not_Start_New_Layer()
+        {
+            using (TestApplication())
+            {
+                Decorator decorator;
+                Border border;
+                var tree = new TestRoot
+                {
+                    Padding = new Thickness(10),
+                    Width = 100,
+                    Height = 120,
+                    Child = decorator = new Decorator
+                    {
+                        Padding = new Thickness(11),
+                        Child = border = new Border
+                        {
+                            Background = Brushes.Red,
+                        }
+                    }
+                };
+
+                var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
+                layout.ExecuteInitialLayoutPass(tree);
+
+                var animation = new BehaviorSubject<double>(0.5);
+                border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
+
+                var scene = new Scene(tree);
+                var sceneBuilder = new SceneBuilder();
+                sceneBuilder.UpdateAll(scene);
+
+                Assert.Single(scene.Layers);
+            }
+        }
+
         [Fact]
         public void Removing_Control_With_Animated_Opacity_Should_Remove_Layers()
         {
@@ -102,7 +138,10 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
                         {
                             Background = Brushes.Red,
                             Padding = new Thickness(12),
-                            Child = canvas = new Canvas()
+                            Child = canvas = new Canvas
+                            {
+                                Children = { new TextBlock() },
+                            }
                         }
                     }
                 };
@@ -149,7 +188,10 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
                         {
                             Background = Brushes.Red,
                             Padding = new Thickness(12),
-                            Child = canvas = new Canvas(),
+                            Child = canvas = new Canvas
+                            {
+                                Children = { new TextBlock() },
+                            }
                         }
                     }
                 };
@@ -193,6 +235,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
                         Child = border = new Border
                         {
                             Opacity = 0.5,
+                            Child = new Canvas(),
                         }
                     }
                 };