diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-05-09 10:28:16 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-05-09 10:30:16 -0400 |
commit | 1868d71163c32e531e0e2d453a291e487176821b (patch) | |
tree | 5b0818b705634cbdc79d87f94f8f09d26a8915a4 | |
parent | ff35efeb41ffae4d3e897915fbfa8702be5b2698 (diff) | |
download | gtk+-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.c | 156 | ||||
-rw-r--r-- | 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__ */ |