windows-runtimemauiwinui-3skiasharpmaui-windows

.NET MAUI Windows 9.0 Preview 5 on Windows/WinUI 3 crashes when using SwapChainPanel via SkiaSharp after a while


The Problem

We are using .NET MAUI 9.0 Preview 5, .NET SDK 9.0 Preview 5, and SkiaSharp 3.0 Preview 3.1 in our game, GnollHack. SKGLView of SkiaSharp uses SwapChainPanel to render GPU accelerated graphics on Windows/WinUI3. Things work fine for a while, but then the game crashes with the following exception (found in the Output→Debug window):

Exception thrown at 0x00007FFB236EF39C (KernelBase.dll) in GnollHackM.exe: WinRT originate error - 0x80004005 : 'Reentrancy was detected in this XAML application. Use a debugger to locate the reentrant code and, if necessary, move that code to an asynchronous event handler. Press OK to exit the application.'.

Microsoft.ui.xaml.dll!00007FFA8F1137D8: CallContext:[\ImageDecodeActivity] 8000FFFF - E_UNEXPECTED

Unhandled exception at 0x00007FFA8F4A52F5 (Microsoft.ui.xaml.dll) in GnollHackM.exe: 0xC000027B: An application-internal exception has occurred (parameters: 0x0000022A8ED086C0, 0x0000000000000003).

This is in the Debug mode, but it happens also in the Release mode.

Steps to reproduce the bug

  1. Compile .NET MAUI Windows port using these instructions: https://github.com/hyvanmielenpelit/GnollHack/wiki/Development-Information
    • It's a relatively big task, I warn you.
  2. Start the game and enable GPU acceleration in the settings. Play the game for a while until it crashes. 10 minutes is usually enough.

Screenshot

The debugger always crashes at a lock statement.

Debugger Screenshot

Stack Trace

 GnollHackM.dll!GnollHackM.GamePage.PaintMainGamePage(object sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e) Line 7517    C#
 GnollHackM.dll!GnollHackM.GamePage.canvasView_PaintSurface(object sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e) Line 3860    C#
 GnollHackM.dll!GnollHackM.SwitchableCanvasView.internalGLView_PaintSurface(object sender, SkiaSharp.Views.Maui.SKPaintGLSurfaceEventArgs e) Line 213    C#
 [External Code]    
 GnollHackM.dll!GnollHackM.SwitchableCanvasView.InvalidateSurface() Line 75    C#
 GnollHackM.dll!GnollHackM.GamePage.UpdateMainCanvas() Line 1325    C#
 GnollHackM.dll!GnollHackM.SwitchableCanvasView.OnPropertyChanged(string propertyName) Line 352    C#
 [External Code]    
 GnollHackM.dll!GnollHackM.SwitchableCanvasView.GeneralAnimationCounter.set(long value) Line 331    C#
 GnollHackM.dll!GnollHackM.GamePage.StartMainCanvasAnimation.AnonymousMethod__415_0(double v) Line 1611    C#
 [External Code] 

Used Software

Used Hardware


Solution

  • We had to add DispatcherQueue.TryEnqueue to queue our InvalidateSurface method. We had to use the window's DispatcherQueue and not the one attached to the thread (it was slow).