[gtk/import-dmabuf: 2/2] Add a more complete implementation




commit 1868d71163c32e531e0e2d453a291e487176821b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun May 9 10:28:16 2021 -0400

    Add a more complete implementation
    
    Support multiple planes, and modifiers.
    
    And make this a backend API.

 gdk/wayland/gdkglcontext-wayland.c | 156 ++++++++++++++++++++++++++++++-------
 gdk/wayland/gdkwaylandglcontext.h  |  13 +++-
 2 files changed, 142 insertions(+), 27 deletions(-)
---
diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c
index fa410c41e8..e922e725ef 100644
--- a/gdk/wayland/gdkglcontext-wayland.c
+++ b/gdk/wayland/gdkglcontext-wayland.c
@@ -313,36 +313,110 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
   gdk_wayland_surface_notify_committed (surface);
 }
 
-static GdkTexture *
-gdk_wayland_gl_context_import_dmabuf (GdkGLContext *context,
-                                      int           fd,
-                                      int           fourcc,
-                                      int           width,
-                                      int           height,
-                                      int           offset,
-                                      int           stride)
+int
+gdk_wayland_gl_context_import_dmabuf (GdkGLContext   *context,
+                                      uint32_t        format,
+                                      unsigned int    width,
+                                      unsigned int    height,
+                                      uint32_t        n_planes,
+                                      const int      *fds,
+                                      const uint32_t *strides,
+                                      const uint32_t *offsets,
+                                      const uint64_t *modifiers)
 {
   GdkDisplay *display = gdk_gl_context_get_display (context);
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
   guint texture;
-  const EGLAttrib attribute_list[] = {
-    EGL_WIDTH, width,
-    EGL_HEIGHT, height,
-    EGL_LINUX_DRM_FOURCC_EXT, fourcc,
-    EGL_DMA_BUF_PLANE0_FD_EXT, fd,
-    EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
-    EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
-    EGL_NONE
-  };
+  EGLint attribs[2 * (3 + 4 * 5) + 1];
+  int i;
   EGLImage image;
 
-  gdk_gl_context_make_current (context);
+  g_return_val_if_fail (GDK_IS_WAYLAND_GL_CONTEXT (context), 0);
+  g_return_val_if_fail (0 < n_planes && n_planes <= 4, 0);
+
+  i = 0;
+  attribs[i++] = EGL_WIDTH;
+  attribs[i++] = width;
+  attribs[i++] = EGL_HEIGHT;
+  attribs[i++] = height;
+  attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
+  attribs[i++] = format;
+
+  if (n_planes > 0)
+    {
+      attribs[i++] = EGL_DMA_BUF_PLANE0_FD_EXT;
+      attribs[i++] = fds[0];
+      attribs[i++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
+      attribs[i++] = offsets[0];
+      attribs[i++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
+      attribs[i++] = strides[0];
+      if (modifiers)
+        {
+          attribs[i++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
+          attribs[i++] = modifiers[0] & 0xFFFFFFFF;
+          attribs[i++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
+          attribs[i++] = modifiers[0] >> 32;
+        }
+    }
+
+  if (n_planes > 1)
+    {
+      attribs[i++] = EGL_DMA_BUF_PLANE1_FD_EXT;
+      attribs[i++] = fds[1];
+      attribs[i++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
+      attribs[i++] = offsets[1];
+      attribs[i++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
+      attribs[i++] = strides[1];
+      if (modifiers)
+        {
+          attribs[i++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
+          attribs[i++] = modifiers[1] & 0xFFFFFFFF;
+          attribs[i++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
+          attribs[i++] = modifiers[1] >> 32;
+        }
+    }
+
+  if (n_planes > 2)
+    {
+      attribs[i++] = EGL_DMA_BUF_PLANE2_FD_EXT;
+      attribs[i++] = fds[2];
+      attribs[i++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
+      attribs[i++] = offsets[2];
+      attribs[i++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
+      attribs[i++] = strides[2];
+      if (modifiers)
+        {
+          attribs[i++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
+          attribs[i++] = modifiers[2] & 0xFFFFFFFF;
+          attribs[i++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
+          attribs[i++] = modifiers[2] >> 32;
+        }
+    }
+
+  if (n_planes > 3)
+    {
+      attribs[i++] = EGL_DMA_BUF_PLANE3_FD_EXT;
+      attribs[i++] = fds[3];
+      attribs[i++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
+      attribs[i++] = offsets[3];
+      attribs[i++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
+      attribs[i++] = strides[3];
+      if (modifiers)
+        {
+          attribs[i++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
+          attribs[i++] = modifiers[3] & 0xFFFFFFFF;
+          attribs[i++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
+          attribs[i++] = modifiers[3] >> 32;
+        }
+    }
+
+  attribs[i++] = EGL_NONE;
 
-  image = eglCreateImage (display_wayland->egl_display,
-                          EGL_NO_CONTEXT,
-                          EGL_LINUX_DMA_BUF_EXT,
-                          (EGLClientBuffer)NULL,
-                          attribute_list);
+  image = eglCreateImageKHR (display_wayland->egl_display,
+                             EGL_NO_CONTEXT,
+                             EGL_LINUX_DMA_BUF_EXT,
+                             (EGLClientBuffer)NULL,
+                             attribs);
   if (image == EGL_NO_IMAGE)
     {
       switch (eglGetError ())
@@ -370,9 +444,12 @@ gdk_wayland_gl_context_import_dmabuf (GdkGLContext *context,
           g_print ("error: %d\n", eglGetError ());
           break;
         }
-      return NULL;
+
+      return 0;
     }
 
+  gdk_gl_context_make_current (context);
+
   glGenTextures (1, &texture);
   glBindTexture (GL_TEXTURE_2D, texture);
   glEGLImageTargetTexture2DOES (GL_TEXTURE_2D, image);
@@ -381,7 +458,34 @@ gdk_wayland_gl_context_import_dmabuf (GdkGLContext *context,
 
   eglDestroyImage (display_wayland->egl_display, image);
 
-  return gdk_gl_texture_new (context, texture, width, height, NULL, NULL);
+  return texture;
+}
+
+static GdkTexture *
+import_dmabuf (GdkGLContext *context,
+               int           fd,
+               int           fourcc,
+               int           width,
+               int           height,
+               int           offset,
+               int           stride)
+{
+  int texture;
+
+  texture = gdk_wayland_gl_context_import_dmabuf (context,
+                                                  fourcc,
+                                                  width,
+                                                  height,
+                                                  1,
+                                                  (const int *)&fd,
+                                                  (const uint32_t *)&stride,
+                                                  (const uint32_t *)&offset,
+                                                  NULL);
+
+  return gdk_gl_texture_new (context,
+                             texture,
+                             width, height,
+                             NULL, NULL);
 }
 
 static void
@@ -398,7 +502,7 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
   context_class->realize = gdk_wayland_gl_context_realize;
   context_class->get_damage = gdk_wayland_gl_context_get_damage;
 
-  context_class->import_dmabuf = gdk_wayland_gl_context_import_dmabuf;
+  context_class->import_dmabuf = import_dmabuf;
 }
 
 static void
diff --git a/gdk/wayland/gdkwaylandglcontext.h b/gdk/wayland/gdkwaylandglcontext.h
index 34a1e4c2a4..7f83af9976 100644
--- a/gdk/wayland/gdkwaylandglcontext.h
+++ b/gdk/wayland/gdkwaylandglcontext.h
@@ -32,7 +32,7 @@ G_BEGIN_DECLS
 
 #define GDK_TYPE_WAYLAND_GL_CONTEXT            (gdk_wayland_gl_context_get_type ())
 #define GDK_WAYLAND_GL_CONTEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GDK_TYPE_WAYLAND_GL_CONTEXT, GdkWaylandGLContext))
-#define GDK_WAYLAND_IS_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WAYLAND_GL_CONTEXT))
+#define GDK_IS_WAYLAND_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WAYLAND_GL_CONTEXT))
 
 typedef struct _GdkWaylandGLContext            GdkWaylandGLContext;
 typedef struct _GdkWaylandGLContextClass       GdkWaylandGLContextClass;
@@ -40,6 +40,17 @@ typedef struct _GdkWaylandGLContextClass     GdkWaylandGLContextClass;
 GDK_AVAILABLE_IN_ALL
 GType gdk_wayland_gl_context_get_type (void) G_GNUC_CONST;
 
+GDK_AVAILABLE_IN_4_4
+int   gdk_wayland_gl_context_import_dmabuf (GdkGLContext   *context,
+                                            uint32_t        fourcc,
+                                            unsigned int    width,
+                                            unsigned int    height,
+                                            uint32_t        n_planes,
+                                            const int      *fd,
+                                            const uint32_t *stride,
+                                            const uint32_t *offset,
+                                            const uint64_t *modifiers);
+
 G_END_DECLS
 
 #endif /* __GDK_WAYLAND_GL_CONTEXT_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]