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