summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-05-09 10:28:16 -0400
committerMatthias Clasen <mclasen@redhat.com>2021-05-09 10:30:16 -0400
commit1868d71163c32e531e0e2d453a291e487176821b (patch)
tree5b0818b705634cbdc79d87f94f8f09d26a8915a4
parentff35efeb41ffae4d3e897915fbfa8702be5b2698 (diff)
downloadgtk+-import-dmabuf.tar.gz
Add a more complete implementationimport-dmabuf
Support multiple planes, and modifiers. And make this a backend API.
-rw-r--r--gdk/wayland/gdkglcontext-wayland.c156
-rw-r--r--gdk/wayland/gdkwaylandglcontext.h13
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__ */