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.
The debugger always crashes at a lock
statement.
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]
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).