Explorar o código

Merge pull request #4049 from microhobby/libdrm-fix-toradex-vivante

LinuxFramebuffer: DrmOutput: Use the drmModeAddFB2 as main call and drmModeAddFB as fallback
Nikita Tsukanov %!s(int64=5) %!d(string=hai) anos
pai
achega
52701a0341

+ 10 - 2
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
         {

+ 20 - 3
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);