Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[.NET/CoreGraphics] Use [UnmanagedCallersOnly] instead of [MonoPInvokeCallback] Partial Fix for #10470 #15906

Merged
merged 5 commits into from
Sep 12, 2022

Conversation

stephen-hawley
Copy link
Contributor

Completed the work for CoreGraphics.
One exception is PDFArray.cs which uses SetupBlockUnsafe (noted in the issue)

@stephen-hawley stephen-hawley added skip-device-tests Skip device tests not-notes-worthy Ignore for release notes labels Sep 8, 2022
@vs-mobiletools-engineering-service2

This comment has been minimized.

Comment on lines 111 to 126

#if NET
[StructLayout (LayoutKind.Sequential)]
unsafe struct CGFunctionCallbacks {
public /* unsigned int */ uint version;
public delegate* unmanaged<IntPtr, nfloat*, nfloat*, void> evaluate;
public delegate* unmanaged<IntPtr, void> release;
}
#else
[StructLayout (LayoutKind.Sequential)]
struct CGFunctionCallbacks {
public /* unsigned int */ uint version;
public CGFunctionEvaluateCallback? evaluate;
public CGFunctionReleaseCallback? release;
}
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the struct is the same and we might add more data in it, why not doing:

Suggested change
#if NET
[StructLayout (LayoutKind.Sequential)]
unsafe struct CGFunctionCallbacks {
public /* unsigned int */ uint version;
public delegate* unmanaged<IntPtr, nfloat*, nfloat*, void> evaluate;
public delegate* unmanaged<IntPtr, void> release;
}
#else
[StructLayout (LayoutKind.Sequential)]
struct CGFunctionCallbacks {
public /* unsigned int */ uint version;
public CGFunctionEvaluateCallback? evaluate;
public CGFunctionReleaseCallback? release;
}
#endif
[StructLayout (LayoutKind.Sequential)]
struct CGFunctionCallbacks {
public /* unsigned int */ uint version;
#if NET
public delegate* unmanaged<IntPtr, nfloat*, nfloat*, void> evaluate;
public delegate* unmanaged<IntPtr, void> release;
#else
public CGFunctionEvaluateCallback? evaluate;
public CGFunctionReleaseCallback? release;
#endif
}

That way if we need to add more stuff, we won't have to write it twice.

Copy link
Contributor Author

@stephen-hawley stephen-hawley Sep 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered that, but since the struct needs to be marked unsafe, this would start to get into the ridiculous range:

    [StructLayout (LayoutKind.Sequential)]
#if NET
    unsafe struct CGFunctionCallbacks {
#else
    struct CGFunctionCallbacks {
#endif
        public /* unsigned int */ uint version;
#if NET
        public delegate* unmanaged<IntPtr, nfloat*, nfloat*, void> evaluate;
        public delegate* unmanaged<IntPtr, void> release;
#else
        public CGFunctionEvaluateCallback? evaluate;
        public CGFunctionReleaseCallback? release;
#endif
    }

At this point every element is different except for the attribute and the uint.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't work if you mark just the fields as unsafe?

    public unsafe delegate* unmanaged<IntPtr, nfloat*, nfloat*, void> evaluate;
    public unsafe delegate* unmanaged<IntPtr, void> release;

@@ -136,17 +150,24 @@ public unsafe CGFunction (nfloat []? domain, nfloat []? range, CGFunctionEvaluat
var handle = CGFunctionCreate (GCHandle.ToIntPtr (gch), domain is not null ? domain.Length / 2 : 0, domain, range is not null ? range.Length / 2 : 0, range, ref cbacks);
InitializeHandle (handle);
}

#if NET
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The [MonoPInvokeCallback (typeof (CGFunctionReleaseCallback))] was just being added in those platforms that are not macOS, now with the #If NET the UnmanagedCallersOnly is added in all platforms including macOS, is this intended?

Copy link
Contributor Author

@stephen-hawley stephen-hawley Sep 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It's intentional. My understanding is that macOS doesn't need the [MonoPInvoke] attribute, but other platforms do. For .NET 7, everybody gets [UnmanagedCallersOnly]

#endif
static void ReleaseCallback (IntPtr info)
{
GCHandle.FromIntPtr (info).Free ();
}

#if NET
[UnmanagedCallersOnly]
#else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question as the previous one.


#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same.

Comment on lines 56 to 70
#if NET
[StructLayout (LayoutKind.Sequential)]
unsafe struct CGPatternCallbacks {
internal /* unsigned int */ uint version;
internal delegate* unmanaged<IntPtr, IntPtr, void> draw;
internal delegate* unmanaged<IntPtr, void> release;
}
#else
[StructLayout (LayoutKind.Sequential)]
struct CGPatternCallbacks {
internal /* unsigned int */ uint version;
internal DrawPatternCallback draw;
internal ReleaseInfoCallback release;
}
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about the struct.

Suggested change
#if NET
[StructLayout (LayoutKind.Sequential)]
unsafe struct CGPatternCallbacks {
internal /* unsigned int */ uint version;
internal delegate* unmanaged<IntPtr, IntPtr, void> draw;
internal delegate* unmanaged<IntPtr, void> release;
}
#else
[StructLayout (LayoutKind.Sequential)]
struct CGPatternCallbacks {
internal /* unsigned int */ uint version;
internal DrawPatternCallback draw;
internal ReleaseInfoCallback release;
}
#endif
[StructLayout (LayoutKind.Sequential)]
struct CGPatternCallbacks {
internal /* unsigned int */ uint version;
#if NET
internal delegate* unmanaged<IntPtr, IntPtr, void> draw;
internal delegate* unmanaged<IntPtr, void> release;
#else
internal DrawPatternCallback draw;
internal ReleaseInfoCallback release;
}
#endif

@@ -111,8 +134,12 @@ public CGPattern (CGRect bounds, CGAffineTransform matrix, nfloat xStep, nfloat
Handle = CGPatternCreate (GCHandle.ToIntPtr (gch), bounds, matrix, xStep, yStep, tiling, isColored, ref callbacks);
}

#if NET
[UnmanagedCallersOnly]
#else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, it adds macOS when it did not in the past.

@@ -123,8 +150,12 @@ static void DrawCallback (IntPtr voidptr, IntPtr cgcontextptr)
}
}

#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

[DllImport (Constants.CoreGraphicsLibrary)]
extern static IntPtr CGDataProviderCreateWithData (/* void* */ IntPtr info, /* const void* */ IntPtr data, /* size_t */ nint size, /* CGDataProviderReleaseDataCallback */ CGDataProviderReleaseDataCallback releaseData);
#endif

delegate void CGDataProviderReleaseDataCallback (IntPtr info, IntPtr data, nint size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this delegate still needed in NET?

Comment on lines 111 to 126

#if NET
[StructLayout (LayoutKind.Sequential)]
unsafe struct CGFunctionCallbacks {
public /* unsigned int */ uint version;
public delegate* unmanaged<IntPtr, nfloat*, nfloat*, void> evaluate;
public delegate* unmanaged<IntPtr, void> release;
}
#else
[StructLayout (LayoutKind.Sequential)]
struct CGFunctionCallbacks {
public /* unsigned int */ uint version;
public CGFunctionEvaluateCallback? evaluate;
public CGFunctionReleaseCallback? release;
}
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't work if you mark just the fields as unsafe?

    public unsafe delegate* unmanaged<IntPtr, nfloat*, nfloat*, void> evaluate;
    public unsafe delegate* unmanaged<IntPtr, void> release;

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [PR Build] Tests on macOS Mac Catalina (10.15) passed 💻

All tests on macOS Mac Catalina (10.15) passed.

Pipeline on Agent
Hash: 587e14a3e3e26aa4cdea375a7821bd7b33e55256 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

📚 [PR Build] Artifacts 📚

Packages generated

View packages

Pipeline on Agent XAMBOT-1103.Monterey'
Hash: 587e14a3e3e26aa4cdea375a7821bd7b33e55256 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [PR Build] Tests on macOS M1 - Mac Big Sur (11.5) passed 💻

All tests on macOS M1 - Mac Big Sur (11.5) passed.

Pipeline on Agent
Hash: 587e14a3e3e26aa4cdea375a7821bd7b33e55256 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ API diff for current PR / commit

Legacy Xamarin (No breaking changes)
  • iOS (no change detected)
  • tvOS (no change detected)
  • watchOS (no change detected)
  • macOS (no change detected)
NET (empty diffs)
  • iOS: (empty diff detected)
  • tvOS: (empty diff detected)
  • MacCatalyst: (empty diff detected)
  • macOS: (empty diff detected)

✅ API diff vs stable

Legacy Xamarin (No breaking changes)
.NET (No breaking changes)
Legacy Xamarin (stable) vs .NET

✅ Generator diff

Generator diff is empty

Pipeline on Agent
Hash: 587e14a3e3e26aa4cdea375a7821bd7b33e55256 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

🔥 [CI Build] Test results 🔥

Test results

❌ Tests failed on VSTS: simulator tests

0 tests crashed, 2 tests failed, 151 tests passed.

Failures

❌ monotouch tests

2 tests failed, 21 tests passed.
  • monotouch-test/Mac [dotnet]/Debug [dotnet]: BuildFailure
  • monotouch-test/tvOS - simulator/Debug (static registrar) [dotnet]: TimedOut

Html Report (VSDrops) Download

Successes

✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests: All 1 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 7 tests passed. Html Report (VSDrops) Download
✅ framework: All 8 tests passed. Html Report (VSDrops) Download
✅ generator: All 2 tests passed. Html Report (VSDrops) Download
✅ interdependent_binding_projects: All 7 tests passed. Html Report (VSDrops) Download
✅ install_source: All 1 tests passed. Html Report (VSDrops) Download
✅ introspection: All 8 tests passed. Html Report (VSDrops) Download
✅ linker: All 65 tests passed. Html Report (VSDrops) Download
✅ mmp: All 2 tests passed. Html Report (VSDrops) Download
✅ mononative: All 12 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ mtouch: All 1 tests passed. Html Report (VSDrops) Download
✅ xammac: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 8 tests passed. Html Report (VSDrops) Download
✅ xtro: All 2 tests passed. Html Report (VSDrops) Download

Pipeline on Agent
Hash: [PR build]

@stephen-hawley stephen-hawley merged commit 2a37989 into xamarin:main Sep 12, 2022
@stephen-hawley stephen-hawley deleted the pinvoke-coregraphics branch September 12, 2022 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
not-notes-worthy Ignore for release notes skip-device-tests Skip device tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants