From: Pekka Paalanen <pekka.paala...@collabora.co.uk>

Squashed with:
 gl-renderer: error if dmabuf exposed unsupported
 gl_renderer: always use GL_TEXTURE_EXTERNAL_OES with dmabuf
---
 src/gl-renderer.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 103 insertions(+)

diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index bb46acd..bb4e409 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -35,6 +35,8 @@
 
 #include "gl-renderer.h"
 #include "vertex-clipping.h"
+#include "linux-dmabuf.h"
+#include "linux-dmabuf-server-protocol.h"
 
 #include <EGL/eglext.h>
 #include "weston-egl-ext.h"
@@ -149,6 +151,8 @@ struct gl_renderer {
 
        int has_configless_context;
 
+       int has_dmabuf_import;
+
        struct gl_shader texture_shader_rgba;
        struct gl_shader texture_shader_rgbx;
        struct gl_shader texture_shader_egl_external;
@@ -1305,12 +1309,104 @@ gl_renderer_attach_egl(struct weston_surface *es, 
struct weston_buffer *buffer,
 }
 
 static void
+gl_renderer_attach_dmabuf(struct weston_surface *surface,
+                         struct weston_buffer *buffer,
+                         struct linux_dmabuf_buffer *dmabuf)
+{
+#ifdef EGL_EXT_image_dma_buf_import
+       struct gl_renderer *gr = get_renderer(surface->compositor);
+       struct gl_surface_state *gs = get_surface_state(surface);
+       EGLint attribs[30];
+       int atti = 0;
+       int i;
+
+       assert(gr->has_dmabuf_import);
+
+       buffer->width = dmabuf->width;
+       buffer->height = dmabuf->height;
+       buffer->y_inverted = 1; /* XXX: readlly? */
+
+       attribs[atti++] = EGL_WIDTH;
+       attribs[atti++] = dmabuf->width;
+       attribs[atti++] = EGL_HEIGHT;
+       attribs[atti++] = dmabuf->height;
+       attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
+       attribs[atti++] = dmabuf->format;
+
+       if (dmabuf->n_planes > 0) {
+               attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
+               attribs[atti++] = dmabuf->dmabuf_fd[0];
+               attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
+               attribs[atti++] = dmabuf->offset[0];
+               attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
+               attribs[atti++] = dmabuf->stride[0];
+       }
+
+       if (dmabuf->n_planes > 1) {
+               attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
+               attribs[atti++] = dmabuf->dmabuf_fd[1];
+               attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
+               attribs[atti++] = dmabuf->offset[1];
+               attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
+               attribs[atti++] = dmabuf->stride[1];
+       }
+
+       if (dmabuf->n_planes > 2) {
+               attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT;
+               attribs[atti++] = dmabuf->dmabuf_fd[2];
+               attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
+               attribs[atti++] = dmabuf->offset[2];
+               attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
+               attribs[atti++] = dmabuf->stride[2];
+       }
+
+       attribs[atti++] = EGL_NONE;
+
+       for (i = 0; i < gs->num_images; i++)
+               gr->destroy_image(gr->egl_display, gs->images[i]);
+       gs->num_images = 0;
+       gs->target = GL_TEXTURE_EXTERNAL_OES;
+       gs->shader = &gr->texture_shader_egl_external;
+
+       ensure_textures(gs, 1);
+
+       gs->images[0] = gr->create_image(gr->egl_display, EGL_NO_CONTEXT,
+                                        EGL_LINUX_DMA_BUF_EXT, NULL,
+                                        attribs);
+       if (!gs->images[0]) {
+               /* XXX: wrong resource for error code */
+               wl_resource_post_error(dmabuf->resource,
+                                      ZLINUX_DMABUF_ERROR_INVALID_DMABUF,
+                                      "dmabuf import to EGL failed");
+               return;
+       }
+       gs->num_images = 1;
+
+       glActiveTexture(GL_TEXTURE0);
+       glBindTexture(gs->target, gs->textures[0]);
+       gr->image_target_texture_2d(gs->target, gs->images[0]);
+
+       gs->pitch = buffer->width;
+       gs->height = buffer->height;
+       gs->buffer_type = BUFFER_TYPE_EGL;
+       gs->y_inverted = buffer->y_inverted;
+
+#else
+       /* XXX: wrong resource for error code */
+       wl_resource_post_error(dmabuf->resource,
+                              ZLINUX_DMABUF_ERROR_INVALID_DMABUF,
+                              "implementation error: EGL dmabuf import");
+#endif /* EGL_EXT_image_dma_buf_import */
+}
+
+static void
 gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
 {
        struct weston_compositor *ec = es->compositor;
        struct gl_renderer *gr = get_renderer(ec);
        struct gl_surface_state *gs = get_surface_state(es);
        struct wl_shm_buffer *shm_buffer;
+       struct linux_dmabuf_buffer *dmabuf;
        EGLint format;
        int i;
 
@@ -1336,6 +1432,8 @@ gl_renderer_attach(struct weston_surface *es, struct 
weston_buffer *buffer)
        else if (gr->query_buffer(gr->egl_display, (void *) buffer->resource,
                                  EGL_TEXTURE_FORMAT, &format))
                gl_renderer_attach_egl(es, buffer, format);
+       else if ((dmabuf = linux_dmabuf_buffer_get(buffer->resource)))
+               gl_renderer_attach_dmabuf(es, buffer, dmabuf);
        else {
                weston_log("unhandled buffer type!\n");
                weston_buffer_reference(&gs->buffer_ref, NULL);
@@ -1948,6 +2046,11 @@ gl_renderer_setup_egl_extensions(struct 
weston_compositor *ec)
                gr->has_configless_context = 1;
 #endif
 
+#ifdef EGL_EXT_image_dma_buf_import
+       if (strstr(extensions, "EGL_EXT_image_dma_buf_import"))
+               gr->has_dmabuf_import = 1;
+#endif
+
        return 0;
 }
 
-- 
2.1.0

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to