Browse Source

Fix opacity mask rendering.

We're potentially creating a new immutable version of the opacity mask each time the `VisualNode` is updated. Need to implement comparison between mutable and immutable brushes.
pull/1306/head
Steven Kirk 8 years ago
parent
commit
2a87dbd6ca
  1. 4
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  2. 10
      src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
  3. 26
      tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs

4
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@ -178,7 +178,9 @@ namespace Avalonia.Rendering.SceneGraph
node.ClipToBounds = clipToBounds; node.ClipToBounds = clipToBounds;
node.GeometryClip = visual.Clip?.PlatformImpl; node.GeometryClip = visual.Clip?.PlatformImpl;
node.Opacity = opacity; node.Opacity = opacity;
node.OpacityMask = visual.OpacityMask;
// TODO: Check equality between node.OpacityMask and visual.OpacityMask before assigning.
node.OpacityMask = visual.OpacityMask?.ToImmutable();
if (ShouldStartLayer(visual)) if (ShouldStartLayer(visual))
{ {

10
src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs

@ -231,6 +231,11 @@ namespace Avalonia.Rendering.SceneGraph
context.PushOpacity(Opacity); context.PushOpacity(Opacity);
} }
if (OpacityMask != null)
{
context.PushOpacityMask(OpacityMask, ClipBounds);
}
context.Transform = Transform; context.Transform = Transform;
if (GeometryClip != null) if (GeometryClip != null)
@ -247,6 +252,11 @@ namespace Avalonia.Rendering.SceneGraph
context.PopGeometryClip(); context.PopGeometryClip();
} }
if (OpacityMask != null)
{
context.PopOpacityMask();
}
if (Opacity != 1 && !skipOpacity) if (Opacity != 1 && !skipOpacity)
{ {
context.PopOpacity(); context.PopOpacity();

26
tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs

@ -165,6 +165,32 @@ namespace Avalonia.Visuals.UnitTests.Rendering
context.Verify(x => x.PopOpacity(), Times.Never); context.Verify(x => x.PopOpacity(), Times.Never);
} }
[Fact]
public void Should_Push_Opacity_Mask()
{
var root = new TestRoot
{
Width = 100,
Height = 100,
Child = new Border
{
Background = Brushes.Red,
OpacityMask = Brushes.Green,
}
};
root.Measure(Size.Infinity);
root.Arrange(new Rect(root.DesiredSize));
var target = CreateTargetAndRunFrame(root);
var context = GetLayerContext(target, root);
var animation = new BehaviorSubject<double>(0.5);
context.Verify(x => x.PushOpacityMask(Brushes.Green, new Rect(0, 0, 100, 100)), Times.Once);
context.Verify(x => x.FillRectangle(Brushes.Red, new Rect(0, 0, 100, 100), 0), Times.Once);
context.Verify(x => x.PopOpacityMask(), Times.Once);
}
[Fact] [Fact]
public void Should_Create_Layer_For_Root() public void Should_Create_Layer_For_Root()
{ {

Loading…
Cancel
Save