Browse Source

Introduce RenderOptions.RequiresFullOpacityHandling

pull/12572/head
Benedikt Stebner 3 years ago
parent
commit
4b5c680a26
  1. 45
      src/Avalonia.Base/Media/RenderOptions.cs
  2. 28
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs

45
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; }
/// <summary>
/// Gets the value of the BitmapInterpolationMode attached property for a visual.
/// </summary>
/// <param name="visual">The control.</param>
/// <returns>The control's left coordinate.</returns>
/// <returns>The value.</returns>
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.
/// </summary>
/// <param name="visual">The control.</param>
/// <param name="value">The left value.</param>
/// <param name="value">The value.</param>
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.
/// </summary>
/// <param name="visual">The control.</param>
/// <returns>The control's left coordinate.</returns>
/// <returns>The value.</returns>
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.
/// </summary>
/// <param name="visual">The control.</param>
/// <returns>The control's left coordinate.</returns>
/// <returns>The value.</returns>
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.
/// </summary>
/// <param name="visual">The control.</param>
/// <param name="value">The left value.</param>
/// <param name="value">The value.</param>
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.
/// </summary>
/// <param name="visual">The control.</param>
/// <returns>The control's left coordinate.</returns>
/// <returns>The value.</returns>
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.
/// </summary>
/// <param name="visual">The control.</param>
/// <param name="value">The left value.</param>
/// <param name="value">The value.</param>
public static void SetTextRenderingMode(Visual visual, TextRenderingMode value)
{
visual.RenderOptions = visual.RenderOptions with { TextRenderingMode = value };
}
/// <summary>
/// Gets the value of the RequiresFullOpacityHandling attached property for a visual.
/// </summary>
/// <param name="visual">The control.</param>
/// <returns>The value.</returns>
public static bool? GetRequiresFullOpacityHandling(Visual visual)
{
return visual.RenderOptions.RequiresFullOpacityHandling;
}
/// <summary>
/// Sets the value of the RequiresFullOpacityHandling attached property for a visual.
/// </summary>
/// <param name="visual">The control.</param>
/// <param name="value">The value.</param>
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
};
}
}

28
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();
}
/// <inheritdoc />

Loading…
Cancel
Save