Skip to content

Commit

Permalink
Function pointers and LibraryImport (#2917)
Browse files Browse the repository at this point in the history
* Update generator to emit function pointers

* Regenerate interop files

* Enable USE_LIBRARY_IMPORT in HarfBuzzSharp

* Enable USE_LIBRARY_IMPORT on SkiaSharp

* Set DisableRuntimeMarshalling on HarfBuzzSharp

* Replace remaining DllImports with LibraryImport on SkiaSharp

* Set DisableRuntimeMarshalling on SkiaSharp as well

* Fix missed proxy definition

* Regenerate skia api with a correct submodule version

* Collections literals are not supported on the CI .NET SDK

* An attempt to fix Tizen build

* Forgot about partial

* Set UnmanagedType.LPStr on evas_gl_proc_address_get instead

* Set USE_LIBRARY_IMPORT on remaining projects too

* Update generator tool to generate DelegateProxy as well

* Regenerate HarfBuzz and SkiaSharp with new DelegateProxy source gen

* Regenerate other projects as well

* Add `protected internal` to test classes too, since this project has InternalsVisibleTo configured

* Disable DelegateTypesAreValid and DelegateTypesHaveAttributes tests on .NET 7+ build, see comments

* Reduce warnings noise

* Update binding/SkiaSharp/GRGlInterface.cs

Co-authored-by: Filip Navara <filip.navara@gmail.com>

* Add missing USE_LIBRARY_IMPORT defines

* Update binding/SkiaSharp/GRGlInterface.cs

* Also needs USE_LIBRARY_IMPORT

---------

Co-authored-by: Matthew Leibowitz <mattleibow@live.com>
Co-authored-by: Filip Navara <filip.navara@gmail.com>
  • Loading branch information
3 people authored Aug 21, 2024
1 parent 6058ab0 commit 9cbf9c8
Show file tree
Hide file tree
Showing 62 changed files with 7,937 additions and 536 deletions.
14 changes: 0 additions & 14 deletions binding/Binding.Shared/DelegateProxies.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,6 @@ internal static partial class DelegateProxies
{
// normal delegates

[MethodImpl (MethodImplOptions.AggressiveInlining)]
public static T Create<T> (object managedDel, T nativeDel, out GCHandle gch, out IntPtr contextPtr)
{
if (managedDel == null) {
gch = default (GCHandle);
contextPtr = IntPtr.Zero;
return default (T);
}

gch = GCHandle.Alloc (managedDel);
contextPtr = GCHandle.ToIntPtr (gch);
return nativeDel;
}

[MethodImpl (MethodImplOptions.AggressiveInlining)]
public static void Create (object managedDel, out GCHandle gch, out IntPtr contextPtr)
{
Expand Down
4 changes: 2 additions & 2 deletions binding/HarfBuzzSharp/Blob.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#nullable disable

using System;
using System.ComponentModel;
using System.IO;

namespace HarfBuzzSharp
Expand Down Expand Up @@ -84,7 +83,8 @@ public static unsafe Blob FromStream (Stream stream)

private static IntPtr Create (IntPtr data, int length, MemoryMode mode, ReleaseDelegate releaseProc)
{
var proxy = DelegateProxies.Create (releaseProc, DelegateProxies.ReleaseDelegateProxy, out _, out var ctx);
DelegateProxies.Create (releaseProc, out _, out var ctx);
var proxy = releaseProc != null ? DelegateProxies.DestroyProxy : null;
return HarfBuzzApi.hb_blob_create ((void*)data, (uint)length, mode, (void*)ctx, proxy);
}

Expand Down
32 changes: 12 additions & 20 deletions binding/HarfBuzzSharp/DelegateProxies.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#nullable disable

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// ReSharper disable PartialMethodParameterNameMismatch

namespace HarfBuzzSharp
{
Expand All @@ -11,15 +13,7 @@ namespace HarfBuzzSharp

internal static unsafe partial class DelegateProxies
{
// references to the proxy implementations
public static readonly DestroyProxyDelegate ReleaseDelegateProxy = ReleaseDelegateProxyImplementation;
public static readonly DestroyProxyDelegate ReleaseDelegateProxyForMulti = ReleaseDelegateProxyImplementationForMulti;
public static readonly ReferenceTableProxyDelegate GetTableDelegateProxy = GetTableDelegateProxyImplementation;

// internal proxy implementations

[MonoPInvokeCallback (typeof (DestroyProxyDelegate))]
private static void ReleaseDelegateProxyImplementation (void* context)
private static partial void DestroyProxyImplementation (void* context)
{
var del = Get<ReleaseDelegate> ((IntPtr)context, out var gch);
try {
Expand All @@ -29,16 +23,7 @@ private static void ReleaseDelegateProxyImplementation (void* context)
}
}

[MonoPInvokeCallback (typeof (ReferenceTableProxyDelegate))]
private static IntPtr GetTableDelegateProxyImplementation (IntPtr face, uint tag, void* context)
{
GetMultiUserData<GetTableDelegate, Face> ((IntPtr)context, out var getTable, out var userData, out _);
var blob = getTable.Invoke (userData, tag);
return blob?.Handle ?? IntPtr.Zero;
}

[MonoPInvokeCallback (typeof (DestroyProxyDelegate))]
private static void ReleaseDelegateProxyImplementationForMulti (void* context)
private static partial void DestroyProxyImplementationForMulti (void* context)
{
var del = GetMulti<ReleaseDelegate> ((IntPtr)context, out var gch);
try {
Expand All @@ -47,5 +32,12 @@ private static void ReleaseDelegateProxyImplementationForMulti (void* context)
gch.Free ();
}
}

private static partial IntPtr ReferenceTableProxyImplementation (IntPtr face, uint tag, void* context)
{
GetMultiUserData<GetTableDelegate, Face> ((IntPtr)context, out var getTable, out var userData, out _);
var blob = getTable.Invoke (userData, tag);
return blob?.Handle ?? IntPtr.Zero;
}
}
}
51 changes: 13 additions & 38 deletions binding/HarfBuzzSharp/DelegateProxies.font.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#nullable disable
// ReSharper disable PartialMethodParameterNameMismatch

using System;

Expand Down Expand Up @@ -30,24 +31,9 @@ namespace HarfBuzzSharp

internal static unsafe partial class DelegateProxies
{
// references to the proxy implementations
public static readonly FontGetFontExtentsProxyDelegate FontExtentsProxy = FontExtentsProxyImplementation;
public static readonly FontGetNominalGlyphProxyDelegate NominalGlyphProxy = NominalGlyphProxyImplementation;
public static readonly FontGetVariationGlyphProxyDelegate VariationGlyphProxy = VariationGlyphProxyImplementation;
public static readonly FontGetNominalGlyphsProxyDelegate NominalGlyphsProxy = NominalGlyphsProxyImplementation;
public static readonly FontGetGlyphAdvanceProxyDelegate GlyphAdvanceProxy = GlyphAdvanceProxyImplementation;
public static readonly FontGetGlyphAdvancesProxyDelegate GlyphAdvancesProxy = GlyphAdvancesProxyImplementation;
public static readonly FontGetGlyphOriginProxyDelegate GlyphOriginProxy = GlyphOriginProxyImplementation;
public static readonly FontGetGlyphKerningProxyDelegate GlyphKerningProxy = GlyphKerningProxyImplementation;
public static readonly FontGetGlyphExtentsProxyDelegate GlyphExtentsProxy = GlyphExtentsProxyImplementation;
public static readonly FontGetGlyphContourPointProxyDelegate GlyphContourPointProxy = GlyphContourPointProxyImplementation;
public static readonly FontGetGlyphNameProxyDelegate GlyphNameProxy = GlyphNameProxyImplementation;
public static readonly FontGetGlyphFromNameProxyDelegate GlyphFromNameProxy = GlyphFromNameProxyImplementation;

// internal proxy implementations

[MonoPInvokeCallback (typeof (FontGetFontExtentsProxyDelegate))]
private static bool FontExtentsProxyImplementation (IntPtr font, void* fontData, FontExtents* extents, void* context)
private static partial bool FontGetFontExtentsProxyImplementation (IntPtr font, void* fontData, FontExtents* extents, void* context)
{
var del = GetMulti<FontExtentsDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
Expand All @@ -57,8 +43,7 @@ private static bool FontExtentsProxyImplementation (IntPtr font, void* fontData,
return result;
}

[MonoPInvokeCallback (typeof (FontGetNominalGlyphProxyDelegate))]
private static bool NominalGlyphProxyImplementation (IntPtr font, void* fontData, uint unicode, uint* glyph, void* context)
private static partial bool FontGetNominalGlyphProxyImplementation (IntPtr font, void* fontData, uint unicode, uint* glyph, void* context)
{
var del = GetMulti<NominalGlyphDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
Expand All @@ -68,8 +53,7 @@ private static bool NominalGlyphProxyImplementation (IntPtr font, void* fontData
return result;
}

[MonoPInvokeCallback (typeof (FontGetNominalGlyphsProxyDelegate))]
private static uint NominalGlyphsProxyImplementation (IntPtr font, void* fontData, uint count, uint* firstUnicode, uint unicodeStride, uint* firstGlyph, uint glyphStride, void* context)
private static partial uint FontGetNominalGlyphsProxyImplementation (IntPtr font, void* fontData, uint count, uint* firstUnicode, uint unicodeStride, uint* firstGlyph, uint glyphStride, void* context)
{
var del = GetMulti<NominalGlyphsDelegate> ((IntPtr)context, out _);
var unicodes = new ReadOnlySpan<uint> (firstUnicode, (int)count);
Expand All @@ -78,8 +62,7 @@ private static uint NominalGlyphsProxyImplementation (IntPtr font, void* fontDat
return del.Invoke (userData.Font, userData.FontData, count, unicodes, glyphs);
}

[MonoPInvokeCallback (typeof (FontGetVariationGlyphProxyDelegate))]
private static bool VariationGlyphProxyImplementation (IntPtr font, void* fontData, uint unicode, uint variationSelector, uint* glyph, void* context)
private static partial bool FontGetVariationGlyphProxyImplementation (IntPtr font, void* fontData, uint unicode, uint variationSelector, uint* glyph, void* context)
{
var del = GetMulti<VariationGlyphDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
Expand All @@ -89,16 +72,14 @@ private static bool VariationGlyphProxyImplementation (IntPtr font, void* fontDa
return result;
}

[MonoPInvokeCallback (typeof (FontGetGlyphAdvanceProxyDelegate))]
private static int GlyphAdvanceProxyImplementation (IntPtr font, void* fontData, uint glyph, void* context)
private static partial int FontGetGlyphAdvanceProxyImplementation (IntPtr font, void* fontData, uint glyph, void* context)
{
var del = GetMulti<GlyphAdvanceDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
return del.Invoke (userData.Font, userData.FontData, glyph);
}

[MonoPInvokeCallback (typeof (FontGetGlyphAdvancesProxyDelegate))]
private static void GlyphAdvancesProxyImplementation (IntPtr font, void* fontData, uint count, uint* firstGlyph, uint glyphStride, int* firstAdvance, uint advanceStride, void* context)
private static partial void FontGetGlyphAdvancesProxyImplementation (IntPtr font, void* fontData, uint count, uint* firstGlyph, uint glyphStride, int* firstAdvance, uint advanceStride, void* context)
{
var del = GetMulti<GlyphAdvancesDelegate> ((IntPtr)context, out _);
var glyphs = new ReadOnlySpan<uint> (firstGlyph, (int)count);
Expand All @@ -107,8 +88,7 @@ private static void GlyphAdvancesProxyImplementation (IntPtr font, void* fontDat
del.Invoke (userData.Font, userData.FontData, count, glyphs, advances);
}

[MonoPInvokeCallback (typeof (FontGetGlyphOriginProxyDelegate))]
private static bool GlyphOriginProxyImplementation (IntPtr font, void* fontData, uint glyph, int* x, int* y, void* context)
private static partial bool FontGetGlyphOriginProxyImplementation (IntPtr font, void* fontData, uint glyph, int* x, int* y, void* context)
{
var del = GetMulti<GlyphOriginDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
Expand All @@ -120,16 +100,14 @@ private static bool GlyphOriginProxyImplementation (IntPtr font, void* fontData,
return result;
}

[MonoPInvokeCallback (typeof (FontGetGlyphKerningProxyDelegate))]
private static int GlyphKerningProxyImplementation (IntPtr font, void* fontData, uint firstGlyph, uint secondGlyph, void* context)
private static partial int FontGetGlyphKerningProxyImplementation (IntPtr font, void* fontData, uint firstGlyph, uint secondGlyph, void* context)
{
var del = GetMulti<GlyphKerningDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
return del.Invoke (userData.Font, userData.FontData, firstGlyph, secondGlyph);
}

[MonoPInvokeCallback (typeof (FontGetGlyphExtentsProxyDelegate))]
private static bool GlyphExtentsProxyImplementation (IntPtr font, void* fontData, uint glyph, GlyphExtents* extents, void* context)
private static partial bool FontGetGlyphExtentsProxyImplementation (IntPtr font, void* fontData, uint glyph, GlyphExtents* extents, void* context)
{
var del = GetMulti<GlyphExtentsDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
Expand All @@ -139,8 +117,7 @@ private static bool GlyphExtentsProxyImplementation (IntPtr font, void* fontData
return result;
}

[MonoPInvokeCallback (typeof (FontGetGlyphContourPointProxyDelegate))]
private static bool GlyphContourPointProxyImplementation (IntPtr font, void* fontData, uint glyph, uint pointIndex, int* x, int* y, void* context)
private static partial bool FontGetGlyphContourPointProxyImplementation (IntPtr font, void* fontData, uint glyph, uint pointIndex, int* x, int* y, void* context)
{
var del = GetMulti<GlyphContourPointDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
Expand All @@ -152,8 +129,7 @@ private static bool GlyphContourPointProxyImplementation (IntPtr font, void* fon
return result;
}

[MonoPInvokeCallback (typeof (FontGetGlyphNameProxyDelegate))]
private static bool GlyphNameProxyImplementation (IntPtr font, void* fontData, uint glyph, void* nameBuffer, uint size, void* context)
private static partial bool FontGetGlyphNameProxyImplementation (IntPtr font, void* fontData, uint glyph, void* nameBuffer, uint size, void* context)
{
var del = GetMulti<GlyphNameDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
Expand All @@ -166,8 +142,7 @@ private static bool GlyphNameProxyImplementation (IntPtr font, void* fontData, u
return result;
}

[MonoPInvokeCallback (typeof (FontGetGlyphFromNameProxyDelegate))]
private static bool GlyphFromNameProxyImplementation (IntPtr font, void* fontData, void* name, int len, uint* glyph, void* context)
private static partial bool FontGetGlyphFromNameProxyImplementation (IntPtr font, void* fontData, void* name, int len, uint* glyph, void* context)
{
var del = GetMulti<GlyphFromNameDelegate> ((IntPtr)context, out _);
var userData = GetMultiUserData<FontUserData> ((IntPtr)fontData, out _);
Expand Down
28 changes: 9 additions & 19 deletions binding/HarfBuzzSharp/DelegateProxies.unicode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#nullable disable
// ReSharper disable PartialMethodParameterNameMismatch

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace HarfBuzzSharp
{
Expand All @@ -18,43 +21,31 @@ namespace HarfBuzzSharp

internal static unsafe partial class DelegateProxies
{
public static readonly UnicodeCombiningClassProxyDelegate CombiningClassProxy = CombiningClassProxyImplementation;
public static readonly UnicodeGeneralCategoryProxyDelegate GeneralCategoryProxy = GeneralCategoryProxyImplementation;
public static readonly UnicodeMirroringProxyDelegate MirroringProxy = MirroringProxyImplementation;
public static readonly UnicodeScriptProxyDelegate ScriptProxy = ScriptProxyImplementation;
public static readonly UnicodeComposeProxyDelegate ComposeProxy = ComposeProxyImplementation;
public static readonly UnicodeDecomposeProxyDelegate DecomposeProxy = DecomposeProxyImplementation;

[MonoPInvokeCallback (typeof (UnicodeCombiningClassProxyDelegate))]
private static int CombiningClassProxyImplementation (IntPtr ufuncs, uint unicode, void* context)
private static partial int UnicodeCombiningClassProxyImplementation (IntPtr ufuncs, uint unicode, void* context)
{
GetMultiUserData<CombiningClassDelegate, UnicodeFunctions> ((IntPtr)context, out var del, out var functions, out _);
return (int)del.Invoke (functions, unicode);
}

[MonoPInvokeCallback (typeof (UnicodeGeneralCategoryProxyDelegate))]
private static int GeneralCategoryProxyImplementation (IntPtr ufuncs, uint unicode, void* context)
private static partial int UnicodeGeneralCategoryProxyImplementation (IntPtr ufuncs, uint unicode, void* context)
{
GetMultiUserData<GeneralCategoryDelegate, UnicodeFunctions> ((IntPtr)context, out var del, out var functions, out _);
return (int)del.Invoke (functions, unicode);
}

[MonoPInvokeCallback (typeof (UnicodeMirroringProxyDelegate))]
private static uint MirroringProxyImplementation (IntPtr ufuncs, uint unicode, void* context)
private static partial uint UnicodeMirroringProxyImplementation (IntPtr ufuncs, uint unicode, void* context)
{
GetMultiUserData<MirroringDelegate, UnicodeFunctions> ((IntPtr)context, out var del, out var functions, out _);
return del.Invoke (functions, unicode);
}

[MonoPInvokeCallback (typeof (UnicodeScriptProxyDelegate))]
private static uint ScriptProxyImplementation (IntPtr ufuncs, uint unicode, void* context)
private static partial uint UnicodeScriptProxyImplementation (IntPtr ufuncs, uint unicode, void* context)
{
GetMultiUserData<ScriptDelegate, UnicodeFunctions> ((IntPtr)context, out var del, out var functions, out _);
return del.Invoke (functions, unicode);
}

[MonoPInvokeCallback (typeof (UnicodeComposeProxyDelegate))]
private static bool ComposeProxyImplementation (IntPtr ufuncs, uint a, uint b, uint* ab, void* context)
private static partial bool UnicodeComposeProxyImplementation (IntPtr ufuncs, uint a, uint b, uint* ab, void* context)
{
GetMultiUserData<ComposeDelegate, UnicodeFunctions> ((IntPtr)context, out var del, out var functions, out _);
var result = del.Invoke (functions, a, b, out var abManaged);
Expand All @@ -63,8 +54,7 @@ private static bool ComposeProxyImplementation (IntPtr ufuncs, uint a, uint b, u
return result;
}

[MonoPInvokeCallback (typeof (UnicodeDecomposeProxyDelegate))]
private static bool DecomposeProxyImplementation (IntPtr ufuncs, uint ab, uint* a, uint* b, void* context)
private static partial bool UnicodeDecomposeProxyImplementation (IntPtr ufuncs, uint ab, uint* a, uint* b, void* context)
{
GetMultiUserData<DecomposeDelegate, UnicodeFunctions> ((IntPtr)context, out var del, out var functions, out _);
var result = del.Invoke (functions, ab, out var aManaged, out var bManaged);
Expand Down
4 changes: 2 additions & 2 deletions binding/HarfBuzzSharp/Face.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ public Face (GetTableDelegate getTable, ReleaseDelegate destroy)
throw new ArgumentNullException (nameof (getTable));

Handle = HarfBuzzApi.hb_face_create_for_tables (
DelegateProxies.GetTableDelegateProxy,
DelegateProxies.ReferenceTableProxy,
(void*)DelegateProxies.CreateMultiUserData (getTable, destroy, this),
DelegateProxies.ReleaseDelegateProxyForMulti);
DelegateProxies.DestroyProxyForMulti);
}

internal Face (IntPtr handle)
Expand Down
2 changes: 1 addition & 1 deletion binding/HarfBuzzSharp/Font.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void SetFontFunctions (FontFunctions fontFunctions, object fontData, Rele

var container = new FontUserData (this, fontData);
var ctx = DelegateProxies.CreateMultiUserData (destroy, container);
HarfBuzzApi.hb_font_set_funcs (Handle, fontFunctions.Handle, (void*)ctx, DelegateProxies.ReleaseDelegateProxyForMulti);
HarfBuzzApi.hb_font_set_funcs (Handle, fontFunctions.Handle, (void*)ctx, DelegateProxies.DestroyProxyForMulti);
}

public void GetScale (out int xScale, out int yScale)
Expand Down
Loading

0 comments on commit 9cbf9c8

Please sign in to comment.