Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SKIA] Don't re-create SKImage on every WriteableBitmap draw call #18164

Merged
merged 1 commit into from
Feb 11, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading