Skip to content

Commit 5045923

Browse files
committed
Add graphics safety checks to prevent accessViolationExceptions
1 parent de94816 commit 5045923

File tree

6 files changed

+38
-9
lines changed

6 files changed

+38
-9
lines changed

src/SimulationFramework.SkiaSharp/SkiaCanvas.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace SimulationFramework.SkiaSharp;
88

9-
internal sealed class SkiaCanvas : ICanvas
9+
internal sealed class SkiaCanvas : SkiaGraphicsObject, ICanvas
1010
{
1111
public ITexture Target { get; }
1212

@@ -25,8 +25,6 @@ internal sealed class SkiaCanvas : ICanvas
2525

2626
private SkiaTexture SkiaTextureTarget => Target as SkiaTexture;
2727

28-
public bool IsDisposed { get; private set; }
29-
3028
public SkiaCanvas(SkiaGraphicsProvider provider, ITexture target, SKCanvas canvas, bool owner)
3129
{
3230
this.Target = target;
@@ -258,8 +256,11 @@ public void ResetState()
258256
currentState = new SkiaCanvasState(this.GetSKCanvas(), null);
259257
}
260258

261-
public void Dispose()
259+
public override void Dispose()
262260
{
261+
if (IsDisposed)
262+
return;
263+
263264
if (owner)
264265
canvas.Dispose();
265266

@@ -269,7 +270,5 @@ public void Dispose()
269270
{
270271
stateStack.Pop().Dispose();
271272
}
272-
273-
this.IsDisposed = true;
274273
}
275274
}

src/SimulationFramework.SkiaSharp/SkiaCanvasState.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ protected override void UpdateStrokeWidth(float strokeWidth)
113113

114114
protected override void UpdateFillTexture(ITexture texture, Matrix3x2 transform, TileMode tileModeX, TileMode tileModeY)
115115
{
116-
if (texture is not null)
116+
if (texture is SkiaTexture skTexture)
117117
{
118118
bool changed = false;
119119
changed |= this.FillTexture != texture;
@@ -124,7 +124,7 @@ protected override void UpdateFillTexture(ITexture texture, Matrix3x2 transform,
124124
if (changed)
125125
{
126126
this.fillTextureShader?.Dispose();
127-
this.fillTextureShader = SKShader.CreateImage(SkiaInterop.GetImage(texture), tileModeX.AsSKShaderTileMode(), tileModeY.AsSKShaderTileMode(), transform.AsSKMatrix());
127+
this.fillTextureShader = SKShader.CreateImage(skTexture.GetImage(), tileModeX.AsSKShaderTileMode(), tileModeY.AsSKShaderTileMode(), transform.AsSKMatrix());
128128
}
129129
}
130130

src/SimulationFramework.SkiaSharp/SkiaFileFont.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public override SKTypeface GetTypeface(FontStyle style)
2828

2929
public override void Dispose()
3030
{
31+
if (IsDisposed)
32+
return;
3133
typeface.Dispose();
3234
base.Dispose();
3335
}

src/SimulationFramework.SkiaSharp/SkiaGraphicsProvider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ public bool TryCreateTexture(int width, int height, ReadOnlySpan<Color> pixels,
7272

7373
return true;
7474
}
75-
catch
75+
catch (Exception ex)
7676
{
77+
Log.Error($"Error creating texture: " + ex);
7778
texture = null;
7879
return false;
7980
}

src/SimulationFramework.SkiaSharp/SkiaSystemFont.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ public override SKTypeface GetTypeface(FontStyle style)
6262

6363
public override void Dispose()
6464
{
65+
if (IsDisposed)
66+
return;
67+
6568
regular.Dispose();
6669
bold?.Dispose();
6770
italic?.Dispose();

src/SimulationFramework.SkiaSharp/SkiaTexture.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ public void InvalidatePixels()
7272

7373
public override void Dispose()
7474
{
75+
if (IsDisposed)
76+
return;
77+
7578
this.canvas.Dispose();
7679
this.surface.Dispose();
7780
this.image.Dispose();
@@ -106,6 +109,9 @@ private unsafe void UpdateLocalPixels()
106109

107110
public unsafe void Update(ReadOnlySpan<Color> pixels)
108111
{
112+
if (IsDisposed)
113+
throw new InvalidOperationException("Cannot use disposed texture!");
114+
109115
Color* buffer = null;
110116
try
111117
{
@@ -144,6 +150,9 @@ private void TextureFlip(ReadOnlySpan<Color> src, Span<Color> dest)
144150

145151
public ICanvas GetCanvas()
146152
{
153+
if (IsDisposed)
154+
throw new InvalidOperationException("Cannot use disposed texture!");
155+
147156
if (Options.HasFlag(TextureOptions.NonRenderTarget))
148157
{
149158
throw new InvalidOperationException("Cannot render to a texture with the TextureOptions.NonRenderTarget flag.");
@@ -164,21 +173,36 @@ public void ApplyChanges()
164173

165174
public SKSurface GetSurface()
166175
{
176+
if (IsDisposed)
177+
throw new InvalidOperationException("Cannot use disposed texture!");
178+
167179
return surface;
168180
}
169181

170182
public SKImage GetImage()
171183
{
184+
if (IsDisposed)
185+
186+
if (IsDisposed)
187+
throw new InvalidOperationException("Cannot use disposed texture!");
188+
throw new InvalidOperationException("Cannot use disposed texture!");
189+
172190
return image;
173191
}
174192

175193
public uint GetGLTexture()
176194
{
195+
if (IsDisposed)
196+
throw new InvalidOperationException("Cannot use disposed texture!");
197+
177198
return glTexture;
178199
}
179200

180201
public void Encode(Stream destination, TextureEncoding encoding)
181202
{
203+
if (IsDisposed)
204+
throw new InvalidOperationException("Cannot use disposed texture!");
205+
182206
var data = image.Encode(encoding switch
183207
{
184208
TextureEncoding.PNG => SKEncodedImageFormat.Png,

0 commit comments

Comments
 (0)