SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
Skia objects, like SkiaSharp.SKPaint, have disposable Skia properties that are retrieved based on their underlying C++ objects. The C# owner class does not have any reference to the C# equivalent of this property. This could result in too early garbage collection of dependent objects. This dispose action will call the C# destructor and free all allocated memory while the property is still in use.
See for example the following scenario:
A new SkiaSharp.SKPaint instance is created
A Shader is set onto the SKPaint object
Garbage collection is triggered
The C# Shader class is garbage collected since it is not referenced anymore. All C++ shader resources are freed
A fatal crash will occur since the SKPaint is making use of the freed memory
An alternative fault situation:
A new SkiaSharp.SKPaint instance is created
A Shader is set onto the SKPaint object
The SKPaint instance is used
Garbage collection is triggered
The C# Shader class is garbage collected since it is not referenced anymore. All C++ shader resources are freed
The SKPaint object is disposed
A fatal crash occurs when the SKPaint instance tried to destruct the shader.
The SKPaint.Shader property:
public SKShader Shader
{
get => SKShader.GetObject(SkiaApi.sk_paint_get_shader(this.Handle));
set => SkiaApi.sk_paint_set_shader(this.Handle, value == null ? IntPtr.Zero : value.Handle);
}
The SkiaSharp.SKPaint class should hold a reference to the C# Shader to prevent garbage collection.
An example of the alternative situation, this results in the following fatal crash:
Skia objects, like SkiaSharp.SKPaint, have disposable Skia properties that are retrieved based on their underlying C++ objects. The C# owner class does not have any reference to the C# equivalent of this property. This could result in too early garbage collection of dependent objects. This dispose action will call the C# destructor and free all allocated memory while the property is still in use.
See for example the following scenario:
An alternative fault situation:
The SKPaint.Shader property:
The SkiaSharp.SKPaint class should hold a reference to the C# Shader to prevent garbage collection.
An example of the alternative situation, this results in the following fatal crash:
Version information: