mono / SkiaSharp

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.
MIT License
4.17k stars 522 forks source link

[BUG] Using SKPaint.Clone() leads to Access Violation in DisposeNative when upgrading to SkiaSharp 3.0 #2755

Open Rippletank opened 3 months ago

Rippletank commented 3 months ago

Description

I'm in the processes of upgrading an existing app to SkiaSharp version 3 to try out the exciting new GPU acceleration integration with Maui on windows. After the upgrade and before enabling acceleration, I found I was getting Access Violations in DisposeNative of SKPaint. The call Stack only starts at ~SKNativeObject, so I guessed it was something to do with the GC. I was eventually was able to stop the error appearing by replace any calls to Clone() on SKPaint objects, most of which were due to earlier bad design choices on my part.

I haven't done a repo on this as its part of a large project, but wanted to flag it.

Am I right in thinking that the SKPaint class has developed much deeper links with the native code than in version 3.0? Is there any discussions/bug report/notes that could help understand the changes to this class and what that means? For example, is a performance benefit to keep an SKPaint object long term to avoid creating a fresh one for each draw call? Similarly with the SKFont, the separation from the SKPaint object makes a lot of sense, I removed all of the obsolete calls, but is it ok to keep the SKFont objects around long term?

Code

paint = oldPaint.Clone();

Expected Behavior

No response

Actual Behavior

No response

Version of SkiaSharp

2.88.3 (Current)

Last Known Good Version of SkiaSharp

2.88.2 (Previous)

IDE / Editor

Visual Studio (Windows)

Platform / Operating System

Windows

Platform / Operating System Version

Maui Windows11

Devices

No response

Relevant Screenshots

No response

Relevant Log Output

Stack trace: 

    [Managed to Native Transition]  
>   SkiaSharp.dll!SkiaSharp.SKPaint.DisposeNative() Line 428    C#
    SkiaSharp.dll!SkiaSharp.SKNativeObject.Dispose(bool disposing) Line 61  C#
    SkiaSharp.dll!SkiaSharp.SKObject.Dispose(bool disposing) Line 90    C#
    SkiaSharp.dll!SkiaSharp.SKPaint.Dispose(bool disposing) Line 424    C#
    SkiaSharp.dll!SkiaSharp.SKNativeObject.~SKNativeObject() Line 34    C#

Code of Conduct