diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index 99ab60d1ac..e3957747bd 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -35,9 +35,9 @@ namespace Avalonia.Skia
private GRContext _grContext;
public GRContext GrContext => _grContext;
private ISkiaGpu _gpu;
- private readonly SKPaint _strokePaint = new SKPaint();
- private readonly SKPaint _fillPaint = new SKPaint();
- private readonly SKPaint _boxShadowPaint = new SKPaint();
+ private readonly SKPaint _strokePaint = SKPaintCache.Get();
+ private readonly SKPaint _fillPaint = SKPaintCache.Get();
+ private readonly SKPaint _boxShadowPaint = SKPaintCache.Get();
private static SKShader s_acrylicNoiseShader;
private readonly ISkiaGpuRenderSession _session;
private bool _leased = false;
@@ -187,17 +187,13 @@ namespace Avalonia.Skia
var s = sourceRect.ToSKRect();
var d = destRect.ToSKRect();
- using (var paint =
- new SKPaint
- {
- Color = new SKColor(255, 255, 255, (byte)(255 * opacity * _currentOpacity))
- })
- {
- paint.FilterQuality = bitmapInterpolationMode.ToSKFilterQuality();
- paint.BlendMode = _currentBlendingMode.ToSKBlendMode();
+ var paint = SKPaintCache.Get();
+ paint.Color = new SKColor(255, 255, 255, (byte)(255 * opacity * _currentOpacity));
+ paint.FilterQuality = bitmapInterpolationMode.ToSKFilterQuality();
+ paint.BlendMode = _currentBlendingMode.ToSKBlendMode();
- drawableImage.Draw(this, s, d, paint);
- }
+ drawableImage.Draw(this, s, d, paint);
+ SKPaintCache.Return(paint);
}
///
@@ -561,6 +557,11 @@ namespace Avalonia.Skia
CheckLease();
try
{
+ // Return leased paints.
+ SKPaintCache.Return(_strokePaint);
+ SKPaintCache.Return(_fillPaint);
+ SKPaintCache.Return(_boxShadowPaint);
+
if (_grContext != null)
{
Monitor.Exit(_grContext);
@@ -631,15 +632,17 @@ namespace Avalonia.Skia
public void PopOpacityMask()
{
CheckLease();
- using (var paint = new SKPaint { BlendMode = SKBlendMode.DstIn })
+
+ var paint = SKPaintCache.Get();
+ paint.BlendMode = SKBlendMode.DstIn;
+
+ Canvas.SaveLayer(paint);
+ SKPaintCache.Return(paint);
+ using (var paintWrapper = _maskStack.Pop())
{
- Canvas.SaveLayer(paint);
- using (var paintWrapper = _maskStack.Pop())
- {
- Canvas.DrawPaint(paintWrapper.Paint);
- }
- Canvas.Restore();
+ Canvas.DrawPaint(paintWrapper.Paint);
}
+ Canvas.Restore();
Canvas.Restore();
}
diff --git a/src/Skia/Avalonia.Skia/GeometryImpl.cs b/src/Skia/Avalonia.Skia/GeometryImpl.cs
index 19dbcf9713..0e95b5d139 100644
--- a/src/Skia/Avalonia.Skia/GeometryImpl.cs
+++ b/src/Skia/Avalonia.Skia/GeometryImpl.cs
@@ -81,15 +81,14 @@ namespace Avalonia.Skia
}
else
{
- using (var paint = new SKPaint())
- {
- paint.IsStroke = true;
- paint.StrokeWidth = strokeWidth;
+ var paint = SKPaintCache.Get();
+ paint.IsStroke = true;
+ paint.StrokeWidth = strokeWidth;
+ paint.GetFillPath(EffectivePath, strokePath);
- paint.GetFillPath(EffectivePath, strokePath);
+ SKPaintCache.Return(paint);
- _pathCache.Cache(strokePath, strokeWidth, strokePath.TightBounds.ToAvaloniaRect());
- }
+ _pathCache.Cache(strokePath, strokeWidth, strokePath.TightBounds.ToAvaloniaRect());
}
}
diff --git a/src/Skia/Avalonia.Skia/SKPaintCache.cs b/src/Skia/Avalonia.Skia/SKPaintCache.cs
new file mode 100644
index 0000000000..79f9575591
--- /dev/null
+++ b/src/Skia/Avalonia.Skia/SKPaintCache.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SkiaSharp;
+
+namespace Avalonia.Skia
+{
+ internal static class SKPaintCache
+ {
+ private static ConcurrentBag s_cachedPaints;
+
+ static SKPaintCache()
+ {
+ s_cachedPaints = new ConcurrentBag();
+ }
+
+ public static SKPaint Get()
+ {
+ if (!s_cachedPaints.TryTake(out var paint))
+ {
+ paint = new SKPaint();
+ }
+
+ return paint;
+ }
+
+ public static void Return(SKPaint paint)
+ {
+ paint.Reset();
+ s_cachedPaints.Add(paint);
+ }
+
+ public static void Clear()
+ {
+ while (s_cachedPaints.TryTake(out var paint))
+ {
+ paint.Dispose();
+ }
+ }
+
+ }
+}