diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c index 8faba34cf..cf6d97932 100644 --- a/src/wayland/meta-wayland-dma-buf.c +++ b/src/wayland/meta-wayland-dma-buf.c @@ -75,11 +75,11 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer, CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); MetaWaylandDmaBufBuffer *dma_buf = buffer->dma_buf.dma_buf; + uint32_t n_planes; + uint64_t modifiers[META_WAYLAND_DMA_BUF_MAX_FDS]; CoglPixelFormat cogl_format; EGLImageKHR egl_image; CoglTexture2D *texture; - EGLint attribs[64]; - int attr_idx = 0; if (buffer->dma_buf.texture) return TRUE; @@ -112,75 +112,25 @@ meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer, return FALSE; } - attribs[attr_idx++] = EGL_WIDTH; - attribs[attr_idx++] = dma_buf->width; - attribs[attr_idx++] = EGL_HEIGHT; - attribs[attr_idx++] = dma_buf->height; - attribs[attr_idx++] = EGL_LINUX_DRM_FOURCC_EXT; - attribs[attr_idx++] = dma_buf->drm_format; - - attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_FD_EXT; - attribs[attr_idx++] = dma_buf->fds[0]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; - attribs[attr_idx++] = dma_buf->offsets[0]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; - attribs[attr_idx++] = dma_buf->strides[0]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; - attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; - attribs[attr_idx++] = dma_buf->drm_modifier >> 32; - - if (dma_buf->fds[1] >= 0) + for (n_planes = 0; n_planes < META_WAYLAND_DMA_BUF_MAX_FDS; n_planes++) { - attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_FD_EXT; - attribs[attr_idx++] = dma_buf->fds[1]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT; - attribs[attr_idx++] = dma_buf->offsets[1]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_PITCH_EXT; - attribs[attr_idx++] = dma_buf->strides[1]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT; - attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT; - attribs[attr_idx++] = dma_buf->drm_modifier >> 32; + if (dma_buf->fds[n_planes] < 0) + break; + + modifiers[n_planes] = dma_buf->drm_modifier; } - if (dma_buf->fds[2] >= 0) - { - attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_FD_EXT; - attribs[attr_idx++] = dma_buf->fds[2]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT; - attribs[attr_idx++] = dma_buf->offsets[2]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_PITCH_EXT; - attribs[attr_idx++] = dma_buf->strides[2]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT; - attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT; - attribs[attr_idx++] = dma_buf->drm_modifier >> 32; - } - - if (dma_buf->fds[3] >= 0) - { - attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_FD_EXT; - attribs[attr_idx++] = dma_buf->fds[3]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT; - attribs[attr_idx++] = dma_buf->offsets[3]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_PITCH_EXT; - attribs[attr_idx++] = dma_buf->strides[3]; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT; - attribs[attr_idx++] = dma_buf->drm_modifier & 0xffffffff; - attribs[attr_idx++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT; - attribs[attr_idx++] = dma_buf->drm_modifier >> 32; - } - - attribs[attr_idx++] = EGL_NONE; - attribs[attr_idx++] = EGL_NONE; - - /* The EXT_image_dma_buf_import spec states that EGL_NO_CONTEXT is to be used - * in conjunction with the EGL_LINUX_DMA_BUF_EXT target. Similarly, the - * native buffer is named in the attribs. */ - egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, NULL, attribs, - error); + egl_image = meta_egl_create_dmabuf_image (egl, + egl_display, + dma_buf->width, + dma_buf->height, + dma_buf->drm_format, + n_planes, + dma_buf->fds, + dma_buf->strides, + dma_buf->offsets, + modifiers, + error); if (egl_image == EGL_NO_IMAGE_KHR) return FALSE;