Browse Source

Added two GetAndSetRadii methods.

Added documentaiton.
pull/10303/head
DJGosnell 3 years ago
parent
commit
416ef6b601
  1. 16
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  2. 76
      src/Skia/Avalonia.Skia/SKRoundRectCache.cs

16
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -365,15 +365,7 @@ namespace Avalonia.Skia
SKRoundRect skRoundRect = null; SKRoundRect skRoundRect = null;
if (needRoundRect) if (needRoundRect)
{ {
skRoundRect = SKRoundRectCache.Shared.Get(); skRoundRect = SKRoundRectCache.Shared.GetAndSetRadii(rc, rect);
skRoundRect.SetRectRadii(rc,
new[]
{
rect.RadiiTopLeft.ToSKPoint(),
rect.RadiiTopRight.ToSKPoint(),
rect.RadiiBottomRight.ToSKPoint(),
rect.RadiiBottomLeft.ToSKPoint(),
});
} }
foreach (var boxShadow in boxShadows) foreach (var boxShadow in boxShadows)
@ -389,8 +381,7 @@ namespace Avalonia.Skia
Canvas.Save(); Canvas.Save();
if (isRounded) if (isRounded)
{ {
var shadowRect = SKRoundRectCache.Shared.Get(); var shadowRect = SKRoundRectCache.Shared.GetAndSetRadii(skRoundRect!.Rect, skRoundRect.Radii);
shadowRect.SetRectRadii(skRoundRect!.Rect, skRoundRect.Radii);
if (spread != 0) if (spread != 0)
shadowRect.Inflate(spread, spread); shadowRect.Inflate(spread, spread);
Canvas.ClipRoundRect(skRoundRect, Canvas.ClipRoundRect(skRoundRect,
@ -446,8 +437,7 @@ namespace Avalonia.Skia
var outerRect = AreaCastingShadowInHole(rc, (float)boxShadow.Blur, spread, offsetX, offsetY); var outerRect = AreaCastingShadowInHole(rc, (float)boxShadow.Blur, spread, offsetX, offsetY);
Canvas.Save(); Canvas.Save();
var shadowRect = SKRoundRectCache.Shared.Get(); var shadowRect = SKRoundRectCache.Shared.GetAndSetRadii(skRoundRect!.Rect, skRoundRect.Radii);
shadowRect.SetRectRadii(skRoundRect!.Rect, skRoundRect.Radii);
if (spread != 0) if (spread != 0)
shadowRect.Deflate(spread, spread); shadowRect.Deflate(spread, spread);
Canvas.ClipRoundRect(skRoundRect, Canvas.ClipRoundRect(skRoundRect,

76
src/Skia/Avalonia.Skia/SKRoundRectCache.cs

@ -1,13 +1,73 @@
using System.Collections.Concurrent; using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using SkiaSharp; using SkiaSharp;
namespace Avalonia.Skia namespace Avalonia.Skia
{ {
/// <summary> /// <summary>
/// Cache for SKPaints. /// Cache for SKRoundRectCache.
/// </summary> /// </summary>
internal class SKRoundRectCache : SKCacheBase<SKRoundRect, SKRoundRectCache> internal class SKRoundRectCache : SKCacheBase<SKRoundRect, SKRoundRectCache>
{ {
/// <summary>
/// Cache for points to use for setting the radii.
/// </summary>
private readonly ConcurrentBag<SKPoint[]> _radiiCache = new();
/// <summary>
/// Gets a cached SKRoundRect and sets it with the passed rectangle and Radii.
/// </summary>
/// <param name="rectangle">Rectangle size to set the cached rectangle to.</param>
/// <param name="roundedRect">Rounded rectangle to copy the radii from.</param>
/// <returns>Configured rounded rectangle</returns>
public SKRoundRect GetAndSetRadii(in SKRect rectangle, in RoundedRect roundedRect)
{
if (!Cache.TryTake(out var item))
{
item = new SKRoundRect();
}
// Try and acquire a cached point array.
if (!_radiiCache.TryTake(out var skArray))
{
skArray = new SKPoint[4];
}
skArray[0].X = (float)roundedRect.RadiiTopLeft.X;
skArray[0].Y = (float)roundedRect.RadiiTopLeft.Y;
skArray[1].X = (float)roundedRect.RadiiTopRight.X;
skArray[1].Y = (float)roundedRect.RadiiTopRight.Y;
skArray[2].X = (float)roundedRect.RadiiBottomRight.X;
skArray[2].Y = (float)roundedRect.RadiiBottomRight.Y;
skArray[3].X = (float)roundedRect.RadiiBottomLeft.X;
skArray[3].Y = (float)roundedRect.RadiiBottomLeft.Y;
item.SetRectRadii(rectangle, skArray);
// Add the array back to the cache.
_radiiCache.Add(skArray);
return item;
}
/// <summary>
/// Gets a cached SKRoundRect and sets it with the passed rectangle and Radii.
/// </summary>
/// <param name="rectangle">Rectangle size to set the cached rectangle to.</param>
/// <param name="radii">point array of radii.</param>
/// <returns>Configured rounded rectangle</returns>
public SKRoundRect GetAndSetRadii(in SKRect rectangle, in SKPoint[] radii)
{
if (!Cache.TryTake(out var item))
{
item = new SKRoundRect();
}
item.SetRectRadii(rectangle, radii);
return item;
}
/// <summary> /// <summary>
/// Returns a SKPaint and resets it for reuse later. /// Returns a SKPaint and resets it for reuse later.
/// </summary> /// </summary>
@ -22,5 +82,17 @@ namespace Avalonia.Skia
rect.SetEmpty(); rect.SetEmpty();
Cache.Add(rect); Cache.Add(rect);
} }
/// <summary>
/// Clears and disposes all cached items.
/// </summary>
public new void Clear()
{
base.Clear();
// Clear out the cache of SKPoint arrays.
_radiiCache.Clear();
}
} }
} }

Loading…
Cancel
Save