From 3ce24794899f509a19e7cf79368cf564d4d4a711 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 27 May 2017 11:35:30 +0200 Subject: [PATCH] Implemented deferred opacity drawing. --- .../SceneGraph/DeferredDrawingContextImpl.cs | 22 +++++- .../Rendering/SceneGraph/OpacityNode.cs | 64 ++++++++++++++++++ .../CustomRender/Opacity.expected.png | Bin 0 -> 612 bytes .../CustomRender/Opacity.expected.png | Bin 0 -> 942 bytes 4 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 src/Avalonia.Visuals/Rendering/SceneGraph/OpacityNode.cs create mode 100644 tests/TestFiles/Cairo/Controls/CustomRender/Opacity.expected.png create mode 100644 tests/TestFiles/Skia/Controls/CustomRender/Opacity.expected.png diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs index 48bba84da7..5659bda1d9 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs @@ -208,7 +208,16 @@ namespace Avalonia.Rendering.SceneGraph /// public void PopOpacity() { - // TODO: Implement + var next = NextDrawAs(); + + if (next == null || !next.Equals(null)) + { + Add(new OpacityNode()); + } + else + { + ++_drawOperationindex; + } } /// @@ -232,7 +241,16 @@ namespace Avalonia.Rendering.SceneGraph /// public void PushOpacity(double opacity) { - // TODO: Implement + var next = NextDrawAs(); + + if (next == null || !next.Equals(opacity)) + { + Add(new OpacityNode(opacity)); + } + else + { + ++_drawOperationindex; + } } /// diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/OpacityNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/OpacityNode.cs new file mode 100644 index 0000000000..097bf15828 --- /dev/null +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/OpacityNode.cs @@ -0,0 +1,64 @@ +using System; +using Avalonia.Platform; + +namespace Avalonia.Rendering.SceneGraph +{ + /// + /// A node in the scene graph which represents an opacity push or pop. + /// + internal class OpacityNode : IDrawOperation + { + /// + /// Initializes a new instance of the class that represents an + /// opacity push. + /// + /// The opacity to push. + public OpacityNode(double opacity) + { + Opacity = opacity; + } + + /// + /// Initializes a new instance of the class that represents an + /// opacity pop. + /// + public OpacityNode() + { + } + + /// + public Rect Bounds => Rect.Empty; + + /// + /// Gets the opacity to be pushed or null if the operation represents a pop. + /// + public double? Opacity { get; } + + /// + public bool HitTest(Point p) => false; + + /// + /// Determines if this draw operation equals another. + /// + /// The opacity of the other draw operation. + /// True if the draw operations are the same, otherwise false. + /// + /// The properties of the other draw operation are passed in as arguments to prevent + /// allocation of a not-yet-constructed draw operation object. + /// + public bool Equals(double? opacity) => Opacity == opacity; + + /// + public void Render(IDrawingContextImpl context) + { + if (Opacity.HasValue) + { + context.PushOpacity(Opacity.Value); + } + else + { + context.PopOpacity(); + } + } + } +} diff --git a/tests/TestFiles/Cairo/Controls/CustomRender/Opacity.expected.png b/tests/TestFiles/Cairo/Controls/CustomRender/Opacity.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..159f428344f7ab12fc9ff8ce7993444e11041493 GIT binary patch literal 612 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu_bxCyDG8DLj6i)b@W6B1V&-dStR4&OSbTjy ze}lC!2TP-a04h-tzcpk2-&LU>uC9N7k)O#?L4akH7-V6PXl<2nc8xJ#qxGj|^!Niu a=MRR>%h+>29Lu%<#l5GipUXO@geCx_PiVye literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Skia/Controls/CustomRender/Opacity.expected.png b/tests/TestFiles/Skia/Controls/CustomRender/Opacity.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..399d502a5664efbe39e34a0a532c89a9bacbe80d GIT binary patch literal 942 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(GggIl|M$F{C2y?M=fhS$BqphlO0iE&^&xc-)rwKh$PfZ2W{{r_;F!+&|a~ zCkjgl$L#Q*XvUIw<)%bplcDCKGhMl#?I)`5fByZ4-94kt(K)8}#!ilKlEV6nSgcAX4RF5H~z7S z|Ma(t+dbLs(-%Fa%G~b{By^9jUCTUEf2O^K-{$uzOf3)b%e%<(u5StKoj*n^Azs}h_m$k@D@0#SB>xVyP&CT7m+2P#r&4u-U_TD>Kr<46* z_s7>&+i&hI{d0d^e%d9l@FiTXd>a+zUUe!gp&0m=%Vu6{1-oD!M< DAN5a? literal 0 HcmV?d00001