diff --git a/src/Uno.UI.Composition/Composition/CompositionEffectBrush.skia.cs b/src/Uno.UI.Composition/Composition/CompositionEffectBrush.skia.cs index 36ae415e23f4..dadca0805c59 100644 --- a/src/Uno.UI.Composition/Composition/CompositionEffectBrush.skia.cs +++ b/src/Uno.UI.Composition/Composition/CompositionEffectBrush.skia.cs @@ -11,6 +11,13 @@ namespace Windows.UI.Composition { public partial class CompositionEffectBrush : CompositionBrush { + private bool _isCurrentInputBackdrop; + + private SKRect _currentBounds; + private SKImageFilter? _filter; + + internal bool HasBackdropBrushInput { get; private set; } + private SKImageFilter? GenerateEffectFilter(object effect, SKRect bounds) { // TODO: https://user-images.githubusercontent.com/34550324/264485558-d7ee5062-b0e0-4f6e-a8c7-0620ec561d3d.png @@ -23,6 +30,15 @@ public partial class CompositionEffectBrush : CompositionBrush CompositionBrush? brush = GetSourceParameter(effectSourceParameter.Name); if (brush is not null) { + if (brush is CompositionBackdropBrush) + { + _isCurrentInputBackdrop = true; + HasBackdropBrushInput = true; + return null; + } + + _isCurrentInputBackdrop = false; + SKPaint paint = new SKPaint() { IsAntialias = true, IsAutohinted = true, FilterQuality = SKFilterQuality.High }; brush.UpdatePaint(paint, bounds); @@ -40,11 +56,13 @@ public partial class CompositionEffectBrush : CompositionBrush if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() == 3 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("BlurAmount", out uint sigmaProp, out _); effectInterop.GetNamedPropertyMapping("Optimization", out uint optProp, out _); effectInterop.GetNamedPropertyMapping("BorderMode", out uint borderProp, out _); @@ -63,11 +81,13 @@ public partial class CompositionEffectBrush : CompositionBrush if (effectInterop.GetSourceCount() == 1 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + return SKImageFilter.CreateColorFilter( SKColorFilter.CreateColorMatrix( new float[] // Grayscale Matrix @@ -87,11 +107,13 @@ public partial class CompositionEffectBrush : CompositionBrush if (effectInterop.GetSourceCount() == 1 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + return SKImageFilter.CreateColorFilter( SKColorFilter.CreateColorMatrix( new float[] // Invert Matrix @@ -111,11 +133,13 @@ public partial class CompositionEffectBrush : CompositionBrush if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() == 1 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Angle", out uint angleProp, out GraphicsEffectPropertyMapping angleMapping); float angle = (float)effectInterop.GetProperty(angleProp); @@ -143,11 +167,13 @@ public partial class CompositionEffectBrush : CompositionBrush if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 1 /* only the Color property is required */ && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + // Note: ColorHdr isn't supported by Composition (as of 10.0.25941.1000) effectInterop.GetNamedPropertyMapping("Color", out uint colorProp, out _); effectInterop.GetNamedPropertyMapping("ClampOutput", out uint clampProp, out _); @@ -223,17 +249,19 @@ half4 main() if (effectInterop.GetSourceCount() == 2 && effectInterop.GetPropertyCount() == 1 && effectInterop.GetSource(0) is IGraphicsEffectSource bg && effectInterop.GetSource(1) is IGraphicsEffectSource fg) { SKImageFilter? bgFilter = GenerateEffectFilter(bg, bounds); - if (bgFilter is null) + if (bgFilter is null && !_isCurrentInputBackdrop) { return null; } SKImageFilter? fgFilter = GenerateEffectFilter(fg, bounds); - if (fgFilter is null) + if (fgFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Mode", out uint modeProp, out _); D2D1BlendEffectMode mode = (D2D1BlendEffectMode)effectInterop.GetProperty(modeProp); SKBlendMode skMode = mode.ToSkia(); @@ -253,11 +281,13 @@ half4 main() if (effectInterop.GetSourceCount() > 1 && effectInterop.GetPropertyCount() == 1) { SKImageFilter? currentFilter = GenerateEffectFilter(effectInterop.GetSource(0), bounds); - if (currentFilter is null) + if (currentFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Mode", out uint modeProp, out _); D2D1CompositeMode mode = (D2D1CompositeMode)effectInterop.GetProperty(modeProp); SKBlendMode skMode = mode.ToSkia(); @@ -272,10 +302,12 @@ half4 main() { SKImageFilter? nextFilter = GenerateEffectFilter(effectInterop.GetSource(idx), bounds); - if (nextFilter is not null) + if (nextFilter is not null && !_isCurrentInputBackdrop) { currentFilter = SKImageFilter.CreateBlendMode(skMode, currentFilter, nextFilter, new(bounds)); } + + _isCurrentInputBackdrop = false; } return currentFilter; @@ -301,11 +333,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() == 1 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Opacity", out uint opacityProp, out _); float opacity = (float)effectInterop.GetProperty(opacityProp); @@ -329,11 +363,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 1 /* only the Contrast property is required */ && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Contrast", out uint contrastProp, out _); effectInterop.GetNamedPropertyMapping("ClampSource", out uint clampProp, out _); @@ -452,17 +488,19 @@ half4 main() if (effectInterop.GetSourceCount() == 2 && effectInterop.GetPropertyCount() >= 4 && effectInterop.GetSource(0) is IGraphicsEffectSource bg && effectInterop.GetSource(1) is IGraphicsEffectSource fg) { SKImageFilter? bgFilter = GenerateEffectFilter(bg, bounds); - if (bgFilter is null) + if (bgFilter is null && !_isCurrentInputBackdrop) { return null; } SKImageFilter? fgFilter = GenerateEffectFilter(fg, bounds); - if (fgFilter is null) + if (fgFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + float? multiplyAmount = effectInterop.GetProperty(0) as float?; float? source1Amount = effectInterop.GetProperty(1) as float?; float? source2Amount = effectInterop.GetProperty(2) as float?; @@ -508,11 +546,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() == 1 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Exposure", out uint exposureProp, out _); float exposure = (float)effectInterop.GetProperty(exposureProp); @@ -570,17 +610,19 @@ half4 main() if (effectInterop.GetSourceCount() == 2 && effectInterop.GetPropertyCount() == 1 && effectInterop.GetSource(0) is IGraphicsEffectSource sourceA && effectInterop.GetSource(1) is IGraphicsEffectSource sourceB) { SKImageFilter? sourceFilter1 = GenerateEffectFilter(sourceB, bounds); - if (sourceFilter1 is null) + if (sourceFilter1 is null && !_isCurrentInputBackdrop) { return null; } SKImageFilter? sourceFilter2 = GenerateEffectFilter(sourceA, bounds); - if (sourceFilter2 is null) + if (sourceFilter2 is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("CrossFade", out uint crossfadeProp, out _); float crossfade = (float)effectInterop.GetProperty(crossfadeProp); @@ -643,11 +685,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + return SKImageFilter.CreateColorFilter(SKColorFilter.CreateLumaColor(), sourceFilter, new(bounds)); } @@ -658,11 +702,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() == 13 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("RedOffset", out uint redOffsetProp, out _); effectInterop.GetNamedPropertyMapping("RedSlope", out uint redSlopeProp, out _); effectInterop.GetNamedPropertyMapping("RedDisable", out uint redDisableProp, out _); @@ -855,11 +901,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() == 17 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("RedAmplitude", out uint redAmplitudeProp, out _); effectInterop.GetNamedPropertyMapping("RedExponent", out uint redExponentProp, out _); effectInterop.GetNamedPropertyMapping("RedOffset", out uint redOffsetProp, out _); @@ -1073,11 +1121,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 4 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("TransformMatrix", out uint matrixProp, out _); Matrix3x2? matrix = effectInterop.GetProperty(matrixProp) as Matrix3x2?; @@ -1105,11 +1155,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() == 2 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("ExtendX", out uint modeXProp, out _); effectInterop.GetNamedPropertyMapping("ExtendY", out uint modeYProp, out _); D2D1BorderEdgeMode xmode = (D2D1BorderEdgeMode)effectInterop.GetProperty(modeXProp); @@ -1151,11 +1203,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 1 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Intensity", out uint intensityProp, out _); float intensity = (float)effectInterop.GetProperty(intensityProp); @@ -1179,11 +1233,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() == 2 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Temperature", out uint tempProp, out _); effectInterop.GetNamedPropertyMapping("Tint", out uint tintProp, out _); @@ -1211,11 +1267,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 1 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("ColorMatrix", out uint matrixProp, out _); float[] matrix = (float[])effectInterop.GetProperty(matrixProp); @@ -1238,11 +1296,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 4 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Azimuth", out uint azimuthProp, out GraphicsEffectPropertyMapping azimuthMapping); effectInterop.GetNamedPropertyMapping("Elevation", out uint elevationProp, out GraphicsEffectPropertyMapping elevationMapping); effectInterop.GetNamedPropertyMapping("DiffuseAmount", out uint amountProp, out _); @@ -1275,11 +1335,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 5 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Azimuth", out uint azimuthProp, out GraphicsEffectPropertyMapping azimuthMapping); effectInterop.GetNamedPropertyMapping("Elevation", out uint elevationProp, out GraphicsEffectPropertyMapping elevationMapping); effectInterop.GetNamedPropertyMapping("SpecularExponent", out uint exponentProp, out _); @@ -1315,11 +1377,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 6 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("LightPosition", out uint positionProp, out _); effectInterop.GetNamedPropertyMapping("LightTarget", out uint targetProp, out _); effectInterop.GetNamedPropertyMapping("Focus", out uint focusProp, out _); @@ -1352,11 +1416,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 7 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("LightPosition", out uint positionProp, out _); effectInterop.GetNamedPropertyMapping("LightTarget", out uint targetProp, out _); effectInterop.GetNamedPropertyMapping("Focus", out uint focusProp, out _); @@ -1391,11 +1457,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 3 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("LightPosition", out uint positionProp, out _); effectInterop.GetNamedPropertyMapping("DiffuseAmount", out uint amountProp, out _); effectInterop.GetNamedPropertyMapping("LightColor", out uint colorProp, out _); @@ -1414,11 +1482,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() >= 4 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("LightPosition", out uint positionProp, out _); effectInterop.GetNamedPropertyMapping("SpecularExponent", out uint exponentProp, out _); effectInterop.GetNamedPropertyMapping("SpecularAmount", out uint amountProp, out _); @@ -1439,17 +1509,19 @@ half4 main() if (effectInterop.GetSourceCount() == 2 && effectInterop.GetSource(0) is IGraphicsEffectSource source && effectInterop.GetSource(1) is IGraphicsEffectSource mask) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } SKImageFilter? maskFilter = GenerateEffectFilter(mask, bounds); - if (maskFilter is null) + if (maskFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + return SKImageFilter.CreateBlendMode(SKBlendMode.SrcIn, maskFilter, sourceFilter, new(bounds)); } @@ -1460,11 +1532,13 @@ half4 main() if (effectInterop.GetSourceCount() == 1 && effectInterop.GetPropertyCount() == 1 && effectInterop.GetSource(0) is IGraphicsEffectSource source) { SKImageFilter? sourceFilter = GenerateEffectFilter(source, bounds); - if (sourceFilter is null) + if (sourceFilter is null && !_isCurrentInputBackdrop) { return null; } + _isCurrentInputBackdrop = false; + effectInterop.GetNamedPropertyMapping("Saturation", out uint saturationProp, out _); float saturation = MathF.Min((float)effectInterop.GetProperty(saturationProp), 2); @@ -1550,9 +1624,14 @@ half4 main(float2 coords) internal override void UpdatePaint(SKPaint paint, SKRect bounds) { - SKImageFilter filter = GenerateEffectFilter(_effect, bounds) ?? throw new NotSupportedException($"Unsupported effect description.\r\nEffect name: {_effect.Name}"); + if (_currentBounds != bounds || _filter is null) + { + _filter = GenerateEffectFilter(_effect, bounds) ?? throw new NotSupportedException($"Unsupported effect description.\r\nEffect name: {_effect.Name}"); + _currentBounds = bounds; + } + paint.Shader = null; - paint.ImageFilter = filter; + paint.ImageFilter = _filter; paint.FilterQuality = SKFilterQuality.High; } } diff --git a/src/Uno.UI.Composition/Composition/CompositionSpriteShape.skia.cs b/src/Uno.UI.Composition/Composition/CompositionSpriteShape.skia.cs index f64800757d91..3660e7383eff 100644 --- a/src/Uno.UI.Composition/Composition/CompositionSpriteShape.skia.cs +++ b/src/Uno.UI.Composition/Composition/CompositionSpriteShape.skia.cs @@ -33,7 +33,18 @@ internal override void Draw(in DrawingSession session) fill.UpdatePaint(fillPaint, geometry.Bounds); - session.Surface.Canvas.DrawPath(geometryWithTransformations, fillPaint); + if (FillBrush is CompositionEffectBrush { HasBackdropBrushInput: true }) + { + // workaround until SkiaSharp adds support for SaveLayerRec + session.Surface.Canvas.SaveLayer(fillPaint); + session.Surface.Canvas.Scale(1.0f / session.Surface.Canvas.TotalMatrix.ScaleX); + session.Surface.Canvas.DrawSurface(session.Surface, new(-session.Surface.Canvas.TotalMatrix.TransX, -session.Surface.Canvas.DeviceClipBounds.Top + session.Surface.Canvas.LocalClipBounds.Top)); + session.Surface.Canvas.Restore(); + } + else + { + session.Surface.Canvas.DrawPath(geometryWithTransformations, fillPaint); + } } if (StrokeBrush is { } stroke && StrokeThickness > 0) diff --git a/src/Uno.UI.Composition/Composition/Compositor.cs b/src/Uno.UI.Composition/Composition/Compositor.cs index d2ca1d107d09..bb442b4b4971 100644 --- a/src/Uno.UI.Composition/Composition/Compositor.cs +++ b/src/Uno.UI.Composition/Composition/Compositor.cs @@ -164,6 +164,9 @@ public ExpressionAnimation CreateExpressionAnimation(string expression) => new ExpressionAnimation(this) { Expression = expression }; internal void InvalidateRender(Visual visual) => InvalidateRenderPartial(visual); + public CompositionBackdropBrush CreateBackdropBrush() + => new CompositionBackdropBrush(); + public CompositionEffectFactory CreateEffectFactory(IGraphicsEffect graphicsEffect) => new CompositionEffectFactory(graphicsEffect); diff --git a/src/Uno.UI.Composition/Composition/SpriteVisual.skia.cs b/src/Uno.UI.Composition/Composition/SpriteVisual.skia.cs index 85f5aac07255..987d85f98e99 100644 --- a/src/Uno.UI.Composition/Composition/SpriteVisual.skia.cs +++ b/src/Uno.UI.Composition/Composition/SpriteVisual.skia.cs @@ -51,10 +51,21 @@ internal override void Draw(in DrawingSession session) _paint.ColorFilter = session.Filters.OpacityColorFilter; - session.Surface.Canvas.DrawRect( - new SKRect(left: 0, top: 0, right: Size.X, bottom: Size.Y), - _paint - ); + if (Brush is CompositionEffectBrush { HasBackdropBrushInput: true }) + { + // workaround until SkiaSharp adds support for SaveLayerRec + session.Surface.Canvas.SaveLayer(_paint); + session.Surface.Canvas.Scale(1.0f / session.Surface.Canvas.TotalMatrix.ScaleX); + session.Surface.Canvas.DrawSurface(session.Surface, new(-session.Surface.Canvas.TotalMatrix.TransX, -session.Surface.Canvas.DeviceClipBounds.Top + session.Surface.Canvas.LocalClipBounds.Top)); + session.Surface.Canvas.Restore(); + } + else + { + session.Surface.Canvas.DrawRect( + new SKRect(left: 0, top: 0, right: Size.X, bottom: Size.Y), + _paint + ); + } } } } diff --git a/src/Uno.UWP/Generated/3.0.0.0/Windows.UI.Composition/CompositionBackdropBrush.cs b/src/Uno.UWP/Generated/3.0.0.0/Windows.UI.Composition/CompositionBackdropBrush.cs index 77db7f2d726d..b61f16c4a054 100644 --- a/src/Uno.UWP/Generated/3.0.0.0/Windows.UI.Composition/CompositionBackdropBrush.cs +++ b/src/Uno.UWP/Generated/3.0.0.0/Windows.UI.Composition/CompositionBackdropBrush.cs @@ -3,7 +3,7 @@ #pragma warning disable 114 // new keyword hiding namespace Windows.UI.Composition { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ +#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || false || __NETSTD_REFERENCE__ || __MACOS__ [global::Uno.NotImplemented] #endif public partial class CompositionBackdropBrush : global::Windows.UI.Composition.CompositionBrush