Browse Source

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.
pull/1306/head
Steven Kirk 8 years ago
parent
commit
9609d93f3b
  1. 11
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  2. 1
      tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs
  3. 51
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs

11
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
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(),
}
}
};

51
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(),
}
}
};

Loading…
Cancel
Save