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

NullReferenceException in System.Delegate.Combine on macOS in 1.68.0 #727

Closed nor0x closed 5 years ago

nor0x commented 5 years ago

Description

After updating from 1.60.3 to 1.68.0. I'm getting a NullReferenceException when I try to subscribe to the PaintSurface event of a SKGLView.

Code

NullReferenceException"  at System.Delegate.Combine (System.Delegate a, System.Delegate b) [0x0001d] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.2.1.12/src/Xamarin.Mac/mcs/class/corlib/System/Delegate.cs:548 
  at SkiaSharp.Views.Mac.SKGLView.add_PaintSurface (System.EventHandler1[TEventArgs] value) [0x00009] in <f196d3fbe68d4774a19d9220fd09cf57>:0 
  at MyViewController+<ViewDidLoad>d__59.MoveNext () [0x00277] in -mypath-MyViewController.cs:599 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.2.1.12/src/Xamarin.Mac/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1023 
  at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00002] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.2.1.12/src/Xamarin.Mac/Foundation/NSAction.cs:178 
  at (wrapper managed-to-native) AppKit.NSApplication.NSApplicationMain(int,string[])
  at AppKit.NSApplication.Main (System.String[] args) [0x00040] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.2.1.12/src/Xamarin.Mac/AppKit/NSApplication.cs:100 
  at MainClass.Main (System.String[] args) [0x00007] in main.cs:10

Expected Behavior

The NullReferenceException above is thrown once I subscribe to the PaintSurface event of SKGLView in a NSViewController.

CanvasView.PaintSurface += CanvasView_PaintSurface;

I haven't changed any code, just updated the NuGet package for SkiaSharp and SkiaSharp.Views from 1.60.3 to 1.68.0.

Basic Information

VS bug #754181

mattleibow commented 5 years ago

I haven't seen this before, did you update in all the related projects? Also, try clean/rebuild, maybe the app is not using the new dlls...

I have attached a small sample that works for me.

SkiaSharpMacTest.zip

nor0x commented 5 years ago

thanks for the reply - unfortunately I had no luck with cleaning and rebuilding the solution / restarting Visual Studio and the machine.

I still get the same exception. screenshot

With the following Stacktrace at System.Delegate.Combine (System.Delegate a, System.Delegate b) [0x0001d] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.2.1.12/src/Xamarin.Mac/mcs/class/corlib/System/Delegate.cs:548 at SkiaSharp.Views.Mac.SKGLView.add_PaintSurface (System.EventHandler1[TEventArgs] value) [0x00009] in <f196d3fbe68d4774a19d9220fd09cf57>:0 at MYPROJECT.Controller.MainVC+<Init>d__45.MoveNext () [0x002d2] in MYPATH/MYPROJECT/Controller/MainVC:163 --- End of stack trace from previous location where exception was thrown --- at MYPROJECT.Controller.RootViewController+<<OpenAsync>b__22_0>d.MoveNext () [0x000de] in MYPATH/MYPROJECT/Controller/RootViewController.cs:277 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.2.1.12/src/Xamarin.Mac/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1023 at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00002] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.2.1.12/src/Xamarin.Mac/Foundation/NSAction.cs:178 at (wrapper managed-to-native) AppKit.NSApplication.NSApplicationMain(int,string[]) at AppKit.NSApplication.Main (System.String[] args) [0x00040] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.2.1.12/src/Xamarin.Mac/AppKit/NSApplication.cs:100 at MYPROJECT.MainClass.Main (System.String[] args) [0x00007] in MYPATH/MYPROJECT/Main.cs:10 Maybe this information is helpful - it's difficult for me to build a repro, because the project is kinda complex

mattleibow commented 5 years ago

There appears to be talk of async in that stack trace. Is it possible to give some pseudo code with how you are attaching the event handler? Maybe there is some threading issue.

What you can try is to wrap the attach in a run-on-main-thread code... Could it be possible that multiple event handles are attaching at the same time?

If you roll back to v1.60.3, does this issue go away?

This is weird since that code is not mine, but in system.

nor0x commented 5 years ago

Same exception if I try attaching the event handler wrapped in BeginInvokeOnMainThread BeginInvokeOnMainThread(() => { CanvasView.PaintSurface += CanvasView_PaintSurface; });

I'm attaching the event handler in an async Init method. I also tried attaching in ViewDidLoad - which gives me the exact same exception.

No issues with 1.60.3

mattleibow commented 5 years ago

Just want to check... You are not using Xamarin.Forms, are you?

One last thing to try is to create a dummy object in the constructor:

var testing = new SKGLView();
testing.PaintSurface += CanvasView_PaintSurface;

If this is in the constructor, and still fails, then there is something really wrong somewhere. If it works, could you share some code/pseudo code of that init method. Or, you can just email me that one file so I can have a look if it is confidential: maleib<AT>microsoft<.>com

nor0x commented 5 years ago

I'm using Xamarin.Mac not Xamarin.Forms.

attaching CanvasView_PaintSurface to a dummy SKGLView object works fine. I will look into my initialization method tomorrow and check what I can share. I'm happy to send you some source files via email. Thank you

nor0x commented 5 years ago

Here is some pseudo code from the initialization logic I'm using in my application. Maybe this snippet helps identify the problem.

//this is called on a button click in FirstViewController
var secondViewController = this.Storyboard.InstantiateControllerWithIdentifier("secondVC") as SecondViewController;
var window = NSApplication.SharedApplication.Windows.First();
secondViewController.View.Frame = new CGRect(0, 0, window.ContentView.Frame.Width, window.ContentView.Frame.Height);
window.ContentViewController = secondViewController;
await secondViewController.Init();

//Init method of SecondViewController
public async Task Init()
{
    //...
    //some async init stuff
    CanvasView.AcceptsTouchEvents = true;
    CanvasView.BecomeFirstResponder();

    var pan = new NSPanGestureRecognizer(PanEvent);
    var zoom = new NSMagnificationGestureRecognizer(ZoomEvent);
    var tap = new NSClickGestureRecognizer(ClickEvent);
    CanvasView.AddGestureRecognizer(pan);
    CanvasView.AddGestureRecognizer(zoom);
    CanvasView.AddGestureRecognizer(tap);
    CanvasView.AddGestureRecognizer(doubleTap);
    CanvasView.PaintSurface += CanvasView_PaintSurface;

}
nor0x commented 5 years ago

One more detail - if I'm using SKCanvasView instead of SKGLView attaching the event handler works fine

mattleibow commented 5 years ago

It all looks good 🙁 and, the fact that one view works and another does not is even more scary. What really gets me is that the event code is nothing to do with skia at all, it is just the basic .NET event.

note: I can't seem to see where you attach the event, but that could should work if it was anywhere

I think it may be time to have a look at the code.

nor0x commented 5 years ago

I'm still working on a repro. I tried running your example which also fails on my machine. So I have built my own mini-repro and this also fails, it's a super basic example though. Maybe the error is somewhere on my system. Could you check if this code runs fine on your machine?

I'm getting this error with the following stacktrace

image

at SkiaSharp.Views.Mac.SKGLView.DrawRect (CoreGraphics.CGRect dirtyRect) [0x000d0] in <f196d3fbe68d4774a19d9220fd09cf57>:0 \n at (wrapper managed-to-native) AppKit.NSApplication.NSApplicationMain(int,string[])\n at AppKit.NSApplication.Main (System.String[] args) [0x00040] in /Library/Frameworks/Xamarin.Mac.framework/Versions/5.2.1.12/src/Xamarin.Mac/AppKit/NSApplication.cs:100 \n at SkiaSharpMacTest.MainClass.Main (System.String[] args) [0x00007] in /Users/profile/Downloads/SkiaSharpMacTest-fixed-3/SkiaSharpMacTest/Main.cs:10

SkiaSharp_macOS.zip

mattleibow commented 5 years ago

Totally works on my machine:

screen shot 2018-12-18 at 06 05 12
mattleibow commented 5 years ago

Both your and my sample works just fine. Maybe you have bad NuGets - due to a preview version?

You can try clearing your nuget cache:

nuget locals all -clear

or maybe not so harsh, just delete:

~/.nuget/packages/skiasharp ~/.nuget/packages/skiasharp.views

Also, maybe attach your machine info from VS > About > Show Details > Copy Information

You might have a bad mono or mac install... or something. I can check.

nor0x commented 5 years ago

clearing the nuget cache or deleting the skiasharp packages manually didn't solve the problem. I will run the code on a second mac tomorrow. Here are the details from VS > About

=== Visual Studio Professional 2017 for Mac ===

Version 7.7.2 (build 21)
Installation UUID: 606b8730-5344-4f22-8895-9af524c45723
    GTK+ 2.24.23 (Raleigh theme)
    Xamarin.Mac 4.4.1.178 (master / eeaeb7e6)

    Package version: 516000221

=== Mono Framework MDK ===

Runtime:
    Mono 5.16.0.221 (2018-06/b63e5378e38) (64-bit)
    Package version: 516000221

=== NuGet ===

Version: 4.8.0.5385

=== .NET Core ===

Runtime: /usr/local/share/dotnet/dotnet
Runtime Versions:
    2.2.0
    2.1.5
    2.1.2
SDK: /usr/local/share/dotnet/sdk/2.2.100/Sdks
SDK Versions:
    2.2.100
    2.1.403
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.16.0/lib/mono/msbuild/15.0/bin/Sdks

=== Xamarin.Profiler ===

Version: 1.6.4
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Apple Developer Tools ===

Xcode 10.1 (14460.46)
Build 10B61

=== Xamarin.Mac ===

Version: 5.2.1.12 (Visual Studio Professional)
Hash: 65ec520f
Branch: 
Build date: 2018-12-05 12:06:09-0500

=== Xamarin.iOS ===

Version: 12.2.1.12 (Visual Studio Professional)
Hash: 65ec520f
Branch: d15-9
Build date: 2018-12-05 12:06:09-0500

=== Xamarin.Android ===

Version: 9.1.4.2 (Visual Studio Professional)
Android SDK: /Users/johnny/Library/Developer/Xamarin/android-sdk-macosx
    Supported Android versions:
        7.0 (API level 24)
        7.1 (API level 25)
        8.1 (API level 27)

SDK Tools Version: 26.1.1
SDK Platform Tools Version: 28.0.1
SDK Build Tools Version: 27.0.3

Java SDK: /Users/johnny/Library/Developer/Xamarin/jdk/microsoft_dist_openjdk_1.8.0.9
openjdk version "1.8.0-9"
OpenJDK Runtime Environment (build 1.8.0-9-microsoft-b00)
OpenJDK 64-Bit Server VM (build 25.71-b00, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Android Device Manager ===

Version: 7.7.1.0
Hash: 06ceaea1

=== Xamarin Inspector ===

Version: 1.4.3
Hash: db27525
Branch: 1.4-release
Build date: Mon, 09 Jul 2018 21:20:18 GMT
Client compatibility: 1

=== Build Information ===

Release ID: 707020021
Git revision: f1fea53df9eb0bb5890a9563c0d7ea7b03922144
Build date: 2018-12-14 18:37:35+00
Build branch: release-7.7
Xamarin extensions: 9c5cea335e6a9ce4ccfde31c4aa06c25a3576085

=== Operating System ===

Mac OS X 10.14.2
Darwin 18.2.0 Darwin Kernel Version 18.2.0
    Mon Nov 12 20:24:46 PST 2018
    root:xnu-4903.231.4~2/RELEASE_X86_64 x86_64

=== Enabled user installed extensions ===

Prism Template Studio and Developer Toolkit 2.2.0.434
mattleibow commented 5 years ago

The only thing that I can see as a difference is the OS:

ME Mac OS X 10.13.6 Darwin 17.7.0 Darwin Kernel Version 17.7.0 Fri Nov 2 20:43:16 PDT 2018 root:xnu-4570.71.17~1/RELEASE_X86_64 x86_64

YOU Mac OS X 10.14.2 Darwin 18.2.0 Darwin Kernel Version 18.2.0 Mon Nov 12 20:24:46 PST 2018 root:xnu-4903.231.4~2/RELEASE_X86_64 x86_64

It appears my mac did not actually let me know there was a major update :sob: I'll update and see what happens.

mattleibow commented 5 years ago

So, while I get my second mac up and running, I got some suggestions from our team here. You can share your .app file and I can test to see if it is your tools or your environment that is having issues. I have attached mine so you can test that. Let me know if it crashes for you.

Source: SkiaSharp_macOS.zip (this is just your source relinked to avoid scrolling) My .app: SkiaSharpMacTest.app.zip

My machine: specs Your machine: specs

nor0x commented 5 years ago

Thank you for the .app file. I tried running it on my machine and it crashed immediately. Here is the output of the process inspected in Console.

I guess there must be something wrong with my system?

screenshot at dec 18 18-47-49
mattleibow commented 5 years ago

One last thing to check is to send me your .app file and I can run it here to confirm that it is your system - it might be just the tooling used to build the package is bad and affecting the running. I have also contacted our resident mac experts to get some real advice.

nor0x commented 5 years ago

Sure thing. Here is the .app file built on my system SkiaSharpMacTest.zip

mattleibow commented 5 years ago

Good news! (which is really bad news) and a "It's not you, it's me" time. I have managed to reproduce the issue on my other, older macbook.

I get the same error in the drawing code (probably just manifests for you in the attach), this means that I am probably trying to create a GPU surface that the GPU does not support - maybe the wrong color type, color space or alpha type.

What is your actual hardware there? Mine works with:

screen shot 2018-12-18 at 21 07 33

(I'll edit when my old macbook restarts)

nor0x commented 5 years ago

This is the hardware of my 13 inch Macbook Pro

screenshot at dec 18 20-18-51

The other machine I used to test the code is a Macbook Pro 2018 15 inch with an i7 6x 2.6 GHz.

mattleibow commented 5 years ago

All right, I have found the issue. It appears that on my old MacBook, I can only have a surface with 1 sample. And, on my new MacBook, I can have 8. In both cases, I requested 4, but appears that I only got 1 on one machine and 8 on another.

I need to investigate this some more, but I can implement a fix for the time being - I can just query SkiaSharp for the number of samples that it is allowed.

In the meantime, you can see what your machine outputs but running this modified app:

Source: Modified.zip App: SkiaSharpMacTest.app.zip

Let me know what you get on your side before I make any changes...

mattleibow commented 5 years ago

I think it also may have to do with the graphics drivers... I started my Android emulator and it asked my to update some driver or something - didn't actually read that message, just checked the box to never show again lol

nor0x commented 5 years ago

I ran the Modified SkiaSharpMacText and got the message "SAMPLES = 1"

mattleibow commented 5 years ago

OK, I think I know what to do now. I can query the context for the supported sample count. In the meantime, you can use SKCanvasView or the custom view.

I am going to improve the views a bit since they haven't really been touched since the beginning. I need to add colorspace support as well, see #732

nor0x commented 5 years ago

Thank you so much 🙌 I think I will use 1.60.3 for now, it works perfectly for me. Should I close the issue now or leave it open until you are done?

mattleibow commented 5 years ago

Leave it open. I tag the commit with this issue so we have links

mattleibow commented 5 years ago

I believe I fixed the issue by not assuming what my samples are, but rather asking the system. I updated the way surface are created in ALL the views as well, just to prevent any future issue on other platforms. https://github.com/mono/SkiaSharp/pull/741