diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs index e266c5ee54..787a2e4cb8 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/Drm.cs @@ -176,7 +176,13 @@ namespace Avalonia.LinuxFramebuffer.Output [DllImport(libdrm, SetLastError = true)] public static extern int drmModeAddFB(int fd, uint width, uint height, byte depth, byte bpp, uint pitch, uint bo_handle, - out uint buf_id); + out uint buf_id); + + [DllImport(libdrm, SetLastError = true)] + public static extern int drmModeAddFB2(int fd, uint width, uint height, + uint pixel_format, uint[] bo_handles, uint[] pitches, + uint[] offsets, out uint buf_id, uint flags); + [DllImport(libdrm, SetLastError = true)] public static extern int drmModeSetCrtc(int fd, uint crtcId, uint bufferId, uint x, uint y, uint *connectors, int count, @@ -261,6 +267,8 @@ namespace Avalonia.LinuxFramebuffer.Output [DllImport(libgbm, SetLastError = true)] public static extern uint gbm_bo_get_stride(IntPtr bo); + [DllImport(libgbm, SetLastError = true)] + public static extern uint gbm_bo_get_format(IntPtr bo); [StructLayout(LayoutKind.Explicit)] public struct GbmBoHandle @@ -278,7 +286,7 @@ namespace Avalonia.LinuxFramebuffer.Output } [DllImport(libgbm, SetLastError = true)] - public static extern ulong gbm_bo_get_handle(IntPtr bo); + public static extern GbmBoHandle gbm_bo_get_handle(IntPtr bo); public static class GbmColorFormats { diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs index 0f5b66befb..7a5d20fc83 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs @@ -7,6 +7,8 @@ using Avalonia.OpenGL; using Avalonia.Platform.Interop; using static Avalonia.LinuxFramebuffer.NativeUnsafeMethods; using static Avalonia.LinuxFramebuffer.Output.LibDrm; +using static Avalonia.LinuxFramebuffer.Output.LibDrm.GbmColorFormats; + namespace Avalonia.LinuxFramebuffer.Output { public unsafe class DrmOutput : IOutputBackend, IGlPlatformSurface, IWindowingPlatformGlFeature @@ -71,11 +73,26 @@ namespace Avalonia.LinuxFramebuffer.Output var w = gbm_bo_get_width(bo); var h = gbm_bo_get_height(bo); var stride = gbm_bo_get_stride(bo); - var handle = gbm_bo_get_handle(bo); + var handle = gbm_bo_get_handle(bo).u32; + var format = gbm_bo_get_format(bo); + + // prepare for the new ioctl call + var handles = new uint[] {handle, 0, 0, 0}; + var pitches = new uint[] {stride, 0, 0, 0}; + var offsets = new uint[] {}; + + var ret = drmModeAddFB2(_card.Fd, w, h, format, handles, pitches, + offsets, out var fbHandle, 0); - var ret = drmModeAddFB(_card.Fd, w, h, 24, 32, stride, (uint)handle, out var fbHandle); if (ret != 0) - throw new Win32Exception(ret, "drmModeAddFb failed"); + { + // legacy fallback + ret = drmModeAddFB(_card.Fd, w, h, 24, 32, stride, (uint)handle, + out fbHandle); + + if (ret != 0) + throw new Win32Exception(ret, $"drmModeAddFb failed {ret}"); + } gbm_bo_set_user_data(bo, new IntPtr((int)fbHandle), FbDestroyDelegate);