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

perf: Update X11 bindings to LibraryImport #16556

Merged
merged 1 commit into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/Uno.UI.Runtime.Skia.X11/X11ApplicationHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
using Uno.UI.Xaml.Controls;
using Uno.UI.Runtime.Skia;
using System.Threading.Tasks;
using System.Runtime.InteropServices.Marshalling;

namespace Uno.WinUI.Runtime.Skia.X11;

public class X11ApplicationHost : SkiaHost, ISkiaApplicationHost, IDisposable
public partial class X11ApplicationHost : SkiaHost, ISkiaApplicationHost, IDisposable
{
[ThreadStatic] private static bool _isDispatcherThread;
private readonly EventLoop _eventLoop;
Expand All @@ -31,9 +32,6 @@ static X11ApplicationHost()
// We therefore wrap every x11 call with XLockDisplay and XUnlockDisplay
var _ = X11Helper.XInitThreads();

[DllImport("libc")]
static extern void setlocale(int type, string s);

// keyboard input fails without this, not sure why this works but Avalonia and xev make similar calls, cf. https://stackoverflow.com/a/18288346
// This disables IME, cf. https://tedyin.com/posts/a-brief-intro-to-linux-input-method-framework/
setlocale(/* LC_ALL */ 6, "");
Expand Down Expand Up @@ -77,6 +75,9 @@ public X11ApplicationHost(Func<Application> appBuilder)
CoreDispatcher.HasThreadAccessOverride = () => _isDispatcherThread;
}

[LibraryImport("libc", StringMarshallingCustomType = typeof(AnsiStringMarshaller))]
private static partial void setlocale(int type, string s);

protected override Task RunLoop()
{
Thread.CurrentThread.Name = "Main Thread (keep-alive)";
Expand Down
70 changes: 35 additions & 35 deletions src/Uno.UI.Runtime.Skia.X11/X11_Bindings/X11Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace Uno.WinUI.Runtime.Skia.X11;
/// <summary>
/// This class includes missing bindings, atoms and other helper methods for X11.
/// </summary>
internal static class X11Helper
internal static partial class X11Helper
{
private const string libX11 = "libX11.so.6";
private const string libX11Randr = "libXrandr.so.2";
Expand Down Expand Up @@ -302,58 +302,58 @@ private unsafe static void SetMotifWMHints(X11Window x11Window, bool on, IntPtr?
private static Func<IntPtr, string, bool, IntPtr> _getAtom = Funcs.CreateMemoized<IntPtr, string, bool, IntPtr>(XLib.XInternAtom);
public static IntPtr GetAtom(IntPtr display, string name, bool only_if_exists = false) => _getAtom(display, name, only_if_exists);

[DllImport("libc")]
public unsafe static extern int poll(Pollfd* __fds, IntPtr __nfds, int __timeout);
[LibraryImport("libc")]
public unsafe static partial int poll(Pollfd* __fds, IntPtr __nfds, int __timeout);

[DllImport(libX11)]
public static extern int XPutImage(IntPtr display, IntPtr drawable, IntPtr gc, IntPtr image,
[LibraryImport(libX11)]
public static partial int XPutImage(IntPtr display, IntPtr drawable, IntPtr gc, IntPtr image,
int srcx, int srcy, int destx, int desty, uint width, uint height);

[DllImport(libX11)]
public static extern IntPtr XCreateImage(IntPtr display, IntPtr visual, uint depth, int format, int offset,
[LibraryImport(libX11)]
public static partial IntPtr XCreateImage(IntPtr display, IntPtr visual, uint depth, int format, int offset,
IntPtr data, uint width, uint height, int bitmap_pad, int bytes_per_line);

[DllImport(libX11)]
public static extern int XPending(IntPtr display);
[LibraryImport(libX11)]
public static partial int XPending(IntPtr display);

[DllImport(libX11)]
public static extern IntPtr XDefaultGC(IntPtr display, int screen_number);
[LibraryImport(libX11)]
public static partial IntPtr XDefaultGC(IntPtr display, int screen_number);

[DllImport(libX11)]
public static extern int XInitThreads();
[LibraryImport(libX11)]
public static partial int XInitThreads();

[DllImport(libX11)]
public static extern int XWidthMMOfScreen(IntPtr screen);
[LibraryImport(libX11)]
public static partial int XWidthMMOfScreen(IntPtr screen);

[DllImport(libX11)]
public static extern int XWidthOfScreen(IntPtr screen);
[LibraryImport(libX11)]
public static partial int XWidthOfScreen(IntPtr screen);

[DllImport(libX11)]
public static extern int XHeightMMOfScreen(IntPtr screen);
[LibraryImport(libX11)]
public static partial int XHeightMMOfScreen(IntPtr screen);

[DllImport(libX11)]
public static extern int XHeightOfScreen(IntPtr screen);
[LibraryImport(libX11)]
public static partial int XHeightOfScreen(IntPtr screen);

[DllImport(libX11Randr)]
public unsafe static extern XRRScreenResources* XRRGetScreenResourcesCurrent(IntPtr dpy, IntPtr window);
[LibraryImport(libX11Randr)]
public unsafe static partial XRRScreenResources* XRRGetScreenResourcesCurrent(IntPtr dpy, IntPtr window);

[DllImport(libX11Randr)]
public unsafe static extern void XRRFreeScreenResources(XRRScreenResources* resources);
[LibraryImport(libX11Randr)]
public unsafe static partial void XRRFreeScreenResources(XRRScreenResources* resources);

[DllImport(libX11Randr)]
public unsafe static extern XRROutputInfo* XRRGetOutputInfo(IntPtr dpy, IntPtr resources, IntPtr output);
[LibraryImport(libX11Randr)]
public unsafe static partial XRROutputInfo* XRRGetOutputInfo(IntPtr dpy, IntPtr resources, IntPtr output);

[DllImport(libX11Randr)]
public unsafe static extern void XRRFreeOutputInfo(XRROutputInfo* outputInfo);
[LibraryImport(libX11Randr)]
public unsafe static partial void XRRFreeOutputInfo(XRROutputInfo* outputInfo);

[DllImport(libX11Randr)]
public unsafe static extern XRRCrtcInfo* XRRGetCrtcInfo(IntPtr dpy, IntPtr resources, IntPtr crtc);
[LibraryImport(libX11Randr)]
public unsafe static partial XRRCrtcInfo* XRRGetCrtcInfo(IntPtr dpy, IntPtr resources, IntPtr crtc);

[DllImport(libX11Randr)]
public unsafe static extern void XRRFreeCrtcInfo(XRRCrtcInfo* crtcInfo);
[LibraryImport(libX11Randr)]
public unsafe static partial void XRRFreeCrtcInfo(XRRCrtcInfo* crtcInfo);

[DllImport(libX11Randr)]
public unsafe static extern int XRRGetCrtcTransform(IntPtr dpy, IntPtr crtc, ref XRRCrtcTransformAttributes* attributes);
[LibraryImport(libX11Randr)]
public unsafe static partial int XRRGetCrtcTransform(IntPtr dpy, IntPtr crtc, ref XRRCrtcTransformAttributes* attributes);

[StructLayout(LayoutKind.Sequential)]
#pragma warning disable CA1815 // Override equals and operator equals on value types
Expand Down
105 changes: 55 additions & 50 deletions src/Uno.UI.Runtime.Skia.X11/X11_Bindings/x11bindings_Glx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,95 +27,100 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;

// ReSharper disable UnassignedGetOnlyAutoProperty

namespace Uno.WinUI.Runtime.Skia.X11
{
unsafe internal class GlxInterface
internal unsafe partial class GlxInterface
{
private const string libGL = "libGL.so.1";
private static readonly char[] _separators = { ',', ' ' };
private static readonly int[] _null = { 0 };

[DllImport(libGL)]
public static extern bool glXQueryVersion(IntPtr dpy, out int maj, out int min);
[LibraryImport(libGL)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool glXQueryVersion(IntPtr dpy, out int maj, out int min);

[DllImport(libGL)]
public static extern bool glXQueryExtension(IntPtr dpy, out int errorBase, out int eventBase);
[LibraryImport(libGL)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool glXQueryExtension(IntPtr dpy, out int errorBase, out int eventBase);

[DllImport(libGL)]
public static extern bool glXMakeContextCurrent(IntPtr display, IntPtr draw, IntPtr read, IntPtr context);
[LibraryImport(libGL)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool glXMakeContextCurrent(IntPtr display, IntPtr draw, IntPtr read, IntPtr context);

[DllImport(libGL)]
public static extern bool glXMakeCurrent(IntPtr display, IntPtr drawable, IntPtr context);
[LibraryImport(libGL)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool glXMakeCurrent(IntPtr display, IntPtr drawable, IntPtr context);

[DllImport(libGL)]
public static extern IntPtr glXGetCurrentContext();
[LibraryImport(libGL)]
public static partial IntPtr glXGetCurrentContext();

[DllImport(libGL)]
public static extern IntPtr glXGetCurrentDisplay();
[LibraryImport(libGL)]
public static partial IntPtr glXGetCurrentDisplay();

[DllImport(libGL)]
public static extern IntPtr glXGetCurrentDrawable();
[LibraryImport(libGL)]
public static partial IntPtr glXGetCurrentDrawable();

[DllImport(libGL)]
public static extern IntPtr glXGetCurrentReadDrawable();
[LibraryImport(libGL)]
public static partial IntPtr glXGetCurrentReadDrawable();

[DllImport(libGL)]
public static extern IntPtr glXCreatePbuffer(IntPtr dpy, IntPtr fbc, int[] attrib_list);
[LibraryImport(libGL)]
public static partial IntPtr glXCreatePbuffer(IntPtr dpy, IntPtr fbc, int[] attrib_list);

[DllImport(libGL)]
public static extern IntPtr glXDestroyPbuffer(IntPtr dpy, IntPtr fb);
[LibraryImport(libGL)]
public static partial IntPtr glXDestroyPbuffer(IntPtr dpy, IntPtr fb);

[DllImport(libGL)]
public static extern XVisualInfo* glXChooseVisual(IntPtr dpy, int screen, int[] attribList);
[LibraryImport(libGL)]
public static partial XVisualInfo* glXChooseVisual(IntPtr dpy, int screen, int[] attribList);

[DllImport(libGL)]
public static extern IntPtr glXCreateContext(IntPtr dpy, XVisualInfo* vis, IntPtr shareList, bool direct);
[LibraryImport(libGL)]
public static partial IntPtr glXCreateContext(IntPtr dpy, XVisualInfo* vis, IntPtr shareList, [MarshalAs(UnmanagedType.Bool)] bool direct);

[DllImport(libGL)]
public static extern IntPtr glXCreateNewContext(IntPtr dpy, IntPtr config, int renderType, IntPtr shareList, int direct);
[LibraryImport(libGL)]
public static partial IntPtr glXCreateNewContext(IntPtr dpy, IntPtr config, int renderType, IntPtr shareList, int direct);

[DllImport(libGL)]
public static extern IntPtr glXCreateContextAttribsARB(IntPtr dpy, IntPtr fbconfig, IntPtr shareList,
bool direct, int[] attribs);
[LibraryImport(libGL)]
public static partial IntPtr glXCreateContextAttribsARB(IntPtr dpy, IntPtr fbconfig, IntPtr shareList,
[MarshalAs(UnmanagedType.Bool)] bool direct, int[] attribs);

[DllImport(libGL)]
public static extern IntPtr glXGetProcAddress(string buffer);
[LibraryImport(libGL, StringMarshallingCustomType = typeof(AnsiStringMarshaller))]
public static partial IntPtr glXGetProcAddress(string buffer);

[DllImport(libGL)]
public static extern void glXDestroyContext(IntPtr dpy, IntPtr ctx);
[LibraryImport(libGL)]
public static partial void glXDestroyContext(IntPtr dpy, IntPtr ctx);

[DllImport(libGL)]
public static extern IntPtr* glXChooseFBConfig(IntPtr dpy, int screen, int[] attrib_list, out int nelements);
[LibraryImport(libGL)]
public static partial IntPtr* glXChooseFBConfig(IntPtr dpy, int screen, int[] attrib_list, out int nelements);

public IntPtr* glXChooseFBConfig(IntPtr dpy, int screen, IEnumerable<int> attribs, out int nelements)
{
var arr = attribs.Concat(_null).ToArray();
return glXChooseFBConfig(dpy, screen, arr, out nelements);
}

[DllImport(libGL)]
public static extern XVisualInfo* glXGetVisualFromFBConfig(IntPtr dpy, IntPtr config);
[LibraryImport(libGL)]
public static partial XVisualInfo* glXGetVisualFromFBConfig(IntPtr dpy, IntPtr config);

[DllImport(libGL)]
public static extern int glXGetFBConfigAttrib(IntPtr dpy, IntPtr config, int attribute, out int value);
[LibraryImport(libGL)]
public static partial int glXGetFBConfigAttrib(IntPtr dpy, IntPtr config, int attribute, out int value);

[DllImport(libGL)]
public static extern void glXSwapBuffers(IntPtr dpy, IntPtr drawable);
[LibraryImport(libGL)]
public static partial void glXSwapBuffers(IntPtr dpy, IntPtr drawable);

[DllImport(libGL)]
public static extern void glXWaitX();
[LibraryImport(libGL)]
public static partial void glXWaitX();

[DllImport(libGL)]
public static extern void glXWaitGL();
[LibraryImport(libGL)]
public static partial void glXWaitGL();

[DllImport(libGL)]
public static extern int glGetError();
[LibraryImport(libGL)]
public static partial int glGetError();

[DllImport(libGL)]
public static extern IntPtr glXQueryExtensionsString(IntPtr display, int screen);
[LibraryImport(libGL)]
public static partial IntPtr glXQueryExtensionsString(IntPtr display, int screen);

// Ignores egl functions.
// On some Linux systems, glXGetProcAddress will return valid pointers for even EGL functions.
Expand Down