@@ -15,7 +15,9 @@ namespace Avalonia.Skia
15
15
internal class WriteableBitmapImpl : IWriteableBitmapImpl , IDrawableBitmapImpl
16
16
{
17
17
private static readonly SKBitmapReleaseDelegate s_releaseDelegate = ReleaseProc ;
18
- private readonly SKBitmap _bitmap ;
18
+ private SKBitmap _bitmap ;
19
+ private SKImage ? _image ;
20
+ private bool _imageValid ;
19
21
private readonly object _lock = new ( ) ;
20
22
21
23
/// <summary>
@@ -119,13 +121,31 @@ public WriteableBitmapImpl(PixelSize size, Vector dpi, PixelFormat format, Alpha
119
121
public void Draw ( DrawingContextImpl context , SKRect sourceRect , SKRect destRect , SKPaint paint )
120
122
{
121
123
lock ( _lock )
122
- context . Canvas . DrawBitmap ( _bitmap , sourceRect , destRect , paint ) ;
124
+ {
125
+ if ( _image == null || ! _imageValid )
126
+ {
127
+ _image ? . Dispose ( ) ;
128
+ _image = null ;
129
+ // NOTE: this does a snapshot of the bitmap. If SKCanvas is not GPU-backed we might want to avoid
130
+ // that by force-sharing the pixel data with SKBitmap, but that would require manual pixel
131
+ // buffer management
132
+ _image = GetSnapshot ( ) ;
133
+ _imageValid = true ;
134
+ }
135
+ context . Canvas . DrawImage ( _image , sourceRect , destRect , paint ) ;
136
+ }
123
137
}
124
138
125
139
/// <inheritdoc />
126
140
public virtual void Dispose ( )
127
141
{
128
- _bitmap . Dispose ( ) ;
142
+ lock ( _lock )
143
+ {
144
+ _image ? . Dispose ( ) ;
145
+ _image = null ;
146
+ _bitmap . Dispose ( ) ;
147
+ _bitmap = null ! ;
148
+ }
129
149
}
130
150
131
151
/// <inheritdoc />
@@ -198,6 +218,7 @@ public void Dispose()
198
218
{
199
219
_bitmap . NotifyPixelsChanged ( ) ;
200
220
_parent . Version ++ ;
221
+ _parent . _imageValid = false ;
201
222
Monitor . Exit ( _parent . _lock ) ;
202
223
_bitmap = null ! ;
203
224
_parent = null ! ;
0 commit comments