Skip to content

Commit 2299d96

Browse files
kekekeksGillibald
andauthored
Enable VisualBrush to be used as Visual's OpacityMask (#17072)
* Enable VisualBrush to be used as Visual's OpacityMask * Add missing test file --------- Co-authored-by: Benedikt Stebner <[email protected]>
1 parent 85fff4a commit 2299d96

File tree

8 files changed

+81
-6
lines changed

8 files changed

+81
-6
lines changed

src/Avalonia.Base/Rendering/Composition/Visual.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Numerics;
33
using Avalonia.Media;
4+
using Avalonia.Rendering.Composition.Drawing;
45
using Avalonia.VisualTree;
56

67
namespace Avalonia.Rendering.Composition
@@ -25,9 +26,25 @@ public IBrush? OpacityMask
2526
get => _opacityMask;
2627
set
2728
{
28-
if (_opacityMask == value)
29+
if (ReferenceEquals(_opacityMask, value))
2930
return;
30-
OpacityMaskBrush = (_opacityMask = value)?.ToImmutable();
31+
32+
// Release the previous compositor-resource based brush
33+
if (_opacityMask is ICompositionRenderResource<IBrush> oldCompositorBrush)
34+
{
35+
oldCompositorBrush.ReleaseOnCompositor(Compositor);
36+
_opacityMask = null;
37+
OpacityMaskBrushTransportField = null;
38+
}
39+
40+
if (value is ICompositionRenderResource<IBrush> newCompositorBrush)
41+
{
42+
newCompositorBrush.AddRefOnCompositor(Compositor);
43+
OpacityMaskBrushTransportField = newCompositorBrush.GetForCompositor(Compositor);
44+
_opacityMask = value;
45+
}
46+
else
47+
OpacityMaskBrushTransportField = (_opacityMask = value)?.ToImmutable();
3148
}
3249
}
3350

src/Avalonia.Base/Visual.Composition.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ internal virtual void DetachFromCompositor()
3535
CompositionVisual.Children.Remove(ChildCompositionVisual);
3636

3737
CompositionVisual.DrawList = null;
38+
CompositionVisual.OpacityMask = null;
3839
CompositionVisual = null;
3940
}
4041
}
@@ -141,7 +142,7 @@ internal virtual void SynchronizeCompositionProperties()
141142
comp.Clip = Clip?.PlatformImpl;
142143

143144
if (!Equals(comp.OpacityMask, OpacityMask))
144-
comp.OpacityMask = OpacityMask?.ToImmutable();
145+
comp.OpacityMask = OpacityMask;
145146

146147
if (!comp.Effect.EffectEquals(Effect))
147148
comp.Effect = Effect?.ToImmutable();

src/Avalonia.Base/composition-schema.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<Property Name="TransformMatrix" Type="Avalonia.Matrix" DefaultValue="Avalonia.Matrix.Identity" Animated="true" Internal="true"/>
3232
<Property Name="AdornedVisual" Type="CompositionVisual?" Internal="true" />
3333
<Property Name="AdornerIsClipped" Type="bool" Internal="true" />
34-
<Property Name="OpacityMaskBrush" Type="Avalonia.Media.IImmutableBrush?" Internal="true" />
34+
<Property Name="OpacityMaskBrush" ClientName="OpacityMaskBrushTransportField" Type="Avalonia.Media.IBrush?" Private="true" />
3535
<Property Name="Effect" Type="Avalonia.Media.IImmutableEffect?" Internal="true" />
3636
<Property Name="RenderOptions" Type="Avalonia.Media.RenderOptions" />
3737
</Object>

src/tools/DevGenerators/CompositionGenerator/Config.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ public class GProperty
107107
[XmlAttribute]
108108
public string Name { get; set; }
109109
[XmlAttribute]
110+
public string ClientName { get; set; }
111+
[XmlAttribute]
110112
public string Type { get; set; }
111113
[XmlAttribute]
112114
public string DefaultValue { get; set; }
@@ -116,6 +118,8 @@ public class GProperty
116118
public bool InternalSet { get; set; }
117119
[XmlAttribute]
118120
public bool Internal { get; set; }
121+
[XmlAttribute]
122+
public bool Private { get; set; }
119123
}
120124

121125
public class GAnimationType

src/tools/DevGenerators/CompositionGenerator/Generator.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,9 @@ private static ClassDeclarationSyntax GenerateClientProperty(ClassDeclarationSyn
310310
var fieldName = PropertyBackingFieldName(prop);
311311
return client
312312
.AddMembers(DeclareField(prop.Type, fieldName))
313-
.AddMembers(PropertyDeclaration(propType, prop.Name)
314-
.AddModifiers(prop.Internal ? SyntaxKind.InternalKeyword : SyntaxKind.PublicKeyword)
313+
.AddMembers(PropertyDeclaration(propType, prop.ClientName ?? prop.Name)
314+
.AddModifiers(
315+
prop.Private ? SyntaxKind.PrivateKeyword : prop.Internal ? SyntaxKind.InternalKeyword : SyntaxKind.PublicKeyword)
315316
.AddAccessorListAccessors(
316317
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration,
317318
Block(ReturnStatement(IdentifierName(fieldName)))),

tests/Avalonia.RenderTests/Media/VisualBrushTests.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,5 +710,57 @@ public async Task VisualBrush_Is_Properly_Mapped(bool relative)
710710
await RenderToFile(new RelativePointTestPrimitivesHelper(brush), testName);
711711
CompareImages(testName);
712712
}
713+
714+
715+
[Fact]
716+
public async Task VisualBrush_Should_Be_Usable_As_Opacity_Mask()
717+
{
718+
var target = new Border()
719+
{
720+
Padding = new Thickness(8),
721+
Width = 920,
722+
Height = 920,
723+
Background = Brushes.Magenta,
724+
OpacityMask = new VisualBrush
725+
{
726+
Stretch = Stretch.Fill,
727+
TileMode = TileMode.None,
728+
729+
Visual = new Border()
730+
{
731+
Width = 200,
732+
Height = 200,
733+
Padding = new Thickness(20),
734+
Child = new Grid()
735+
{
736+
737+
ColumnDefinitions = ColumnDefinitions.Parse("*,*,*"),
738+
RowDefinitions = RowDefinitions.Parse("*,*,*"),
739+
Children =
740+
{
741+
new Border()
742+
{
743+
Background = Brushes.Aqua,
744+
},
745+
new Border()
746+
{
747+
[Grid.ColumnProperty] = 1,
748+
[Grid.RowProperty] = 2,
749+
Background = Brushes.Aqua,
750+
},
751+
new Border()
752+
{
753+
[Grid.ColumnProperty] = 3,
754+
Background = Brushes.Aqua,
755+
},
756+
}
757+
},
758+
}
759+
}
760+
};
761+
762+
await RenderToFile(target);
763+
CompareImages();
764+
}
713765
}
714766
}

0 commit comments

Comments
 (0)