diff --git a/src/Avalonia.Base/Media/RenderOptions.cs b/src/Avalonia.Base/Media/RenderOptions.cs
index 639498543b..1ac2520919 100644
--- a/src/Avalonia.Base/Media/RenderOptions.cs
+++ b/src/Avalonia.Base/Media/RenderOptions.cs
@@ -8,12 +8,13 @@ namespace Avalonia.Media
public EdgeMode EdgeMode { get; init; }
public TextRenderingMode TextRenderingMode { get; init; }
public BitmapBlendingMode BitmapBlendingMode { get; init; }
+ public bool? RequiresFullOpacityHandling { get; init; }
///
/// Gets the value of the BitmapInterpolationMode attached property for a visual.
///
/// The control.
- /// The control's left coordinate.
+ /// The value.
public static BitmapInterpolationMode GetBitmapInterpolationMode(Visual visual)
{
return visual.RenderOptions.BitmapInterpolationMode;
@@ -23,7 +24,7 @@ namespace Avalonia.Media
/// Sets the value of the BitmapInterpolationMode attached property for a visual.
///
/// The control.
- /// The left value.
+ /// The value.
public static void SetBitmapInterpolationMode(Visual visual, BitmapInterpolationMode value)
{
visual.RenderOptions = visual.RenderOptions with { BitmapInterpolationMode = value };
@@ -33,7 +34,7 @@ namespace Avalonia.Media
/// Gets the value of the BitmapBlendingMode attached property for a visual.
///
/// The control.
- /// The control's left coordinate.
+ /// The value.
public static BitmapBlendingMode GetBitmapBlendingMode(Visual visual)
{
return visual.RenderOptions.BitmapBlendingMode;
@@ -53,7 +54,7 @@ namespace Avalonia.Media
/// Gets the value of the EdgeMode attached property for a visual.
///
/// The control.
- /// The control's left coordinate.
+ /// The value.
public static EdgeMode GetEdgeMode(Visual visual)
{
return visual.RenderOptions.EdgeMode;
@@ -63,7 +64,7 @@ namespace Avalonia.Media
/// Sets the value of the EdgeMode attached property for a visual.
///
/// The control.
- /// The left value.
+ /// The value.
public static void SetEdgeMode(Visual visual, EdgeMode value)
{
visual.RenderOptions = visual.RenderOptions with { EdgeMode = value };
@@ -73,7 +74,7 @@ namespace Avalonia.Media
/// Gets the value of the TextRenderingMode attached property for a visual.
///
/// The control.
- /// The control's left coordinate.
+ /// The value.
public static TextRenderingMode GetTextRenderingMode(Visual visual)
{
return visual.RenderOptions.TextRenderingMode;
@@ -83,12 +84,32 @@ namespace Avalonia.Media
/// Sets the value of the TextRenderingMode attached property for a visual.
///
/// The control.
- /// The left value.
+ /// The value.
public static void SetTextRenderingMode(Visual visual, TextRenderingMode value)
{
visual.RenderOptions = visual.RenderOptions with { TextRenderingMode = value };
}
+ ///
+ /// Gets the value of the RequiresFullOpacityHandling attached property for a visual.
+ ///
+ /// The control.
+ /// The value.
+ public static bool? GetRequiresFullOpacityHandling(Visual visual)
+ {
+ return visual.RenderOptions.RequiresFullOpacityHandling;
+ }
+
+ ///
+ /// Sets the value of the RequiresFullOpacityHandling attached property for a visual.
+ ///
+ /// The control.
+ /// The value.
+ public static void SetRequiresFullOpacityHandling(Visual visual, bool? value)
+ {
+ visual.RenderOptions = visual.RenderOptions with { RequiresFullOpacityHandling = value };
+ }
+
public RenderOptions MergeWith(RenderOptions other)
{
var bitmapInterpolationMode = BitmapInterpolationMode;
@@ -119,12 +140,20 @@ namespace Avalonia.Media
bitmapBlendingMode = other.BitmapBlendingMode;
}
+ var requiresFullOpacityHandling = RequiresFullOpacityHandling;
+
+ if (requiresFullOpacityHandling == null)
+ {
+ requiresFullOpacityHandling = other.RequiresFullOpacityHandling;
+ }
+
return new RenderOptions
{
BitmapInterpolationMode = bitmapInterpolationMode,
EdgeMode = edgeMode,
TextRenderingMode = textRenderingMode,
- BitmapBlendingMode = bitmapBlendingMode
+ BitmapBlendingMode = bitmapBlendingMode,
+ RequiresFullOpacityHandling = requiresFullOpacityHandling
};
}
}
diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index fbff4ab4e7..b1b1de0ffe 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -189,7 +189,8 @@ namespace Avalonia.Skia
var d = destRect.ToSKRect();
var paint = SKPaintCache.Shared.Get();
- paint.Color = new SKColor(255, 255, 255, (byte)(255 * opacity * (_useOpacitySaveLayer ? 1 : _currentOpacity)));
+
+ paint.Color = new SKColor(255, 255, 255, (byte)(255 * opacity * _currentOpacity));
paint.FilterQuality = RenderOptions.BitmapInterpolationMode.ToSKFilterQuality();
paint.BlendMode = RenderOptions.BitmapBlendingMode.ToSKBlendMode();
@@ -375,7 +376,7 @@ namespace Avalonia.Skia
{
if (boxShadow != default && !boxShadow.IsInset)
{
- using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _useOpacitySaveLayer ? 1 : _currentOpacity))
+ using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _currentOpacity))
{
var spread = (float)boxShadow.Spread;
if (boxShadow.IsInset)
@@ -432,7 +433,7 @@ namespace Avalonia.Skia
{
if (boxShadow != default && boxShadow.IsInset)
{
- using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _useOpacitySaveLayer ? 1 : _currentOpacity))
+ using (var shadow = BoxShadowFilter.Create(_boxShadowPaint, boxShadow, _currentOpacity))
{
var spread = (float)boxShadow.Spread;
var offsetX = (float)boxShadow.OffsetX;
@@ -592,8 +593,16 @@ namespace Avalonia.Skia
{
CheckLease();
- if(_useOpacitySaveLayer)
+ _opacityStack.Push(_currentOpacity);
+
+ var useOpacitySaveLayer = _useOpacitySaveLayer || RenderOptions.RequiresFullOpacityHandling == true;
+
+ if (useOpacitySaveLayer)
{
+ opacity = _currentOpacity * opacity; //Take current multiplied opacity
+
+ _currentOpacity = 1; //Opacity is applied via layering
+
if (bounds.HasValue)
{
var rect = bounds.Value.ToSKRect();
@@ -606,7 +615,6 @@ namespace Avalonia.Skia
}
else
{
- _opacityStack.Push(_currentOpacity);
_currentOpacity *= opacity;
}
}
@@ -616,14 +624,14 @@ namespace Avalonia.Skia
{
CheckLease();
- if(_useOpacitySaveLayer)
+ var useOpacitySaveLayer = _useOpacitySaveLayer || RenderOptions.RequiresFullOpacityHandling == true;
+
+ if (useOpacitySaveLayer)
{
Canvas.Restore();
}
- else
- {
- _currentOpacity = _opacityStack.Pop();
- }
+
+ _currentOpacity = _opacityStack.Pop();
}
///