Skip to content

Commit

Permalink
[SKIA] Don't re-create SKImage on every WriteableBitmap draw call (#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
kekekeks authored Feb 10, 2025
1 parent 920122c commit ead6ac8
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/Skia/Avalonia.Skia/WriteableBitmapImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ namespace Avalonia.Skia
internal class WriteableBitmapImpl : IWriteableBitmapImpl, IDrawableBitmapImpl
{
private static readonly SKBitmapReleaseDelegate s_releaseDelegate = ReleaseProc;
private readonly SKBitmap _bitmap;
private SKBitmap _bitmap;
private SKImage? _image;
private bool _imageValid;
private readonly object _lock = new();

/// <summary>
Expand Down Expand Up @@ -119,13 +121,31 @@ public WriteableBitmapImpl(PixelSize size, Vector dpi, PixelFormat format, Alpha
public void Draw(DrawingContextImpl context, SKRect sourceRect, SKRect destRect, SKPaint paint)
{
lock (_lock)
context.Canvas.DrawBitmap(_bitmap, sourceRect, destRect, paint);
{
if (_image == null || !_imageValid)
{
_image?.Dispose();
_image = null;
// NOTE: this does a snapshot of the bitmap. If SKCanvas is not GPU-backed we might want to avoid
// that by force-sharing the pixel data with SKBitmap, but that would require manual pixel
// buffer management
_image = GetSnapshot();
_imageValid = true;
}
context.Canvas.DrawImage(_image, sourceRect, destRect, paint);
}
}

/// <inheritdoc />
public virtual void Dispose()
{
_bitmap.Dispose();
lock (_lock)
{
_image?.Dispose();
_image = null;
_bitmap.Dispose();
_bitmap = null!;
}
}

/// <inheritdoc />
Expand Down Expand Up @@ -198,6 +218,7 @@ public void Dispose()
{
_bitmap.NotifyPixelsChanged();
_parent.Version++;
_parent._imageValid = false;
Monitor.Exit(_parent._lock);
_bitmap = null!;
_parent = null!;
Expand Down

0 comments on commit ead6ac8

Please sign in to comment.