[Mesa-dev] [PATCH 7/8] egl: Add EGL_WAYLAND_PLANE_WL attribute

Kristian Høgsberg krh at bitplanet.net
Thu Jul 5 14:50:07 PDT 2012


This lets us specify the plane to create the image for for multiplanar
wl_buffers.

Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
---
 docs/WL_bind_wayland_display.spec |   16 +++++--
 include/EGL/eglmesaext.h          |    1 +
 src/egl/drivers/dri2/egl_dri2.c   |   86 ++++++++++++++++++++++++++++++++++---
 src/egl/main/eglimage.c           |    5 +++
 src/egl/main/eglimage.h           |    3 ++
 5 files changed, 103 insertions(+), 8 deletions(-)

diff --git a/docs/WL_bind_wayland_display.spec b/docs/WL_bind_wayland_display.spec
index e2fde3c..2e2db59 100644
--- a/docs/WL_bind_wayland_display.spec
+++ b/docs/WL_bind_wayland_display.spec
@@ -62,6 +62,10 @@ New Tokens
 
         EGL_WAYLAND_BUFFER_WL                   0x31D5
 
+    Accepted in the <attrib_list> parameter of eglCreateImageKHR:
+
+        EGL_WAYLAND_PLANE_WL                    0x31D6
+
 Additions to the EGL 1.4 Specification:
 
     To bind a server side wl_display to an EGLDisplay, call
@@ -80,9 +84,12 @@ Additions to the EGL 1.4 Specification:
     eglUnbindWaylandDisplayWL returns EGL_FALSE when there is no
     wl_display bound to the EGLDisplay currently otherwise EGL_TRUE.
 
-    Import a wl_buffer by calling eglCreateImageKHR with
-    wl_buffer as EGLClientBuffer, EGL_WAYLAND_BUFFER_WL as the target,
-    NULL context and an empty attribute_list.
+    Import a wl_buffer by calling eglCreateImageKHR with wl_buffer as
+    EGLClientBuffer, EGL_WAYLAND_BUFFER_WL as the target, NULL context
+    and an empty attribute_list.  For multi-planar buffers such as
+    many YUV buffers, specify the plane to create the EGLImage for by
+    using the EGL_WAYLAND_PLANE_WL attribute.  The value of the
+    attribute is the index of the plane, as defined by the buffer format.
 
 Issues
 
@@ -90,3 +97,6 @@ Revision History
 
     Version 1, March 1, 2011
         Initial draft (Benjamin Franzke)
+    Version 2, July 5, 2012
+        Add EGL_WAYLAND_PLANE_WL attribute to allow creating an EGLImage
+        for different planes of planar buffer. (Kristian Høgsberg)
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index 52dd5b1..d291608 100644
--- a/include/EGL/eglmesaext.h
+++ b/include/EGL/eglmesaext.h
@@ -113,6 +113,7 @@ typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDRMDISPLAYMESA) (int fd);
 #define EGL_WL_bind_wayland_display 1
 
 #define EGL_WAYLAND_BUFFER_WL			0x31D5 /* eglCreateImageKHR target */
+#define EGL_WAYLAND_PLANE_WL			0x31D6 /* eglCreateImageKHR target */
 struct wl_display;
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index a666711..ec2106a 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1057,15 +1057,91 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
 				    EGLClientBuffer _buffer,
 				    const EGLint *attr_list)
 {
-   struct wl_buffer *buffer = (struct wl_buffer *) _buffer;
+   struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer;
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
-   __DRIimage *dri_image, *source;
+   __DRIimage *dri_image;
+   _EGLImageAttribs attrs;
+   EGLint err;
+   uint32_t format;
+   int32_t offset, stride, plane, width, height;
+   int cpp;
 
-   if (!wayland_buffer_is_drm(buffer))
+   if (!wayland_buffer_is_drm(&buffer->buffer))
        return NULL;
 
-   source = wayland_drm_buffer_get_buffer(buffer);
-   dri_image = dri2_dpy->image->dupImage(source, NULL);
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   plane = attrs.PlaneWL;
+   if (err != EGL_SUCCESS || plane < 0) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer");
+      return NULL;
+   }
+
+   switch (buffer->driver_format) {
+   case __DRI_IMAGE_FORMAT_ARGB8888:
+   case __DRI_IMAGE_FORMAT_XRGB8888:
+      if (plane > 0) {
+         _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer");
+         return NULL;
+      }
+      width = buffer->buffer.width;
+      height = buffer->buffer.height;
+      format = buffer->driver_format;
+      offset = buffer->offset[0];
+      stride = buffer->stride[0];
+      cpp = 4;
+      break;
+
+   case __DRI_IMAGE_FORMAT_YUV420:
+      if (plane > 2) {
+         _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer");
+         return NULL;
+      }
+
+      if (plane == 0) {
+         width = buffer->buffer.width;
+         height = buffer->buffer.height;
+      } else {
+         width = buffer->buffer.width / 2;
+         height = buffer->buffer.height / 2;
+      }
+
+      format = __DRI_IMAGE_FORMAT_R8;
+      offset = buffer->offset[plane];
+      stride = buffer->stride[plane];
+      cpp = 1;
+      break;
+
+   case __DRI_IMAGE_FORMAT_NV12:
+      if (plane > 1) {
+         _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+         return NULL;
+      }
+
+      if (plane == 0) {
+         width = buffer->buffer.width;
+         height = buffer->buffer.height;
+         format = __DRI_IMAGE_FORMAT_R8;
+         cpp = 1;
+      } else {
+         width = buffer->buffer.width / 2;
+         height = buffer->buffer.height / 2;
+         format = __DRI_IMAGE_FORMAT_RG88;
+         cpp = 2;
+      }
+
+      offset = buffer->offset[plane];
+      stride = buffer->stride[plane];
+
+      break;
+
+   default:
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return NULL;
+   }
+
+   dri_image = dri2_dpy->image->createSubImage(buffer->driver_buffer,
+                                               width, height, format,
+                                               offset, stride / cpp, NULL);
 
    return dri2_create_image(disp, dri_image);
 }
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index 1174d0a..bfae709 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -88,6 +88,11 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
          attrs->DRMBufferStrideMESA = val;
          break;
 
+      /* EGL_WL_bind_wayland_display */
+      case EGL_WAYLAND_PLANE_WL:
+         attrs->PlaneWL = val;
+         break;
+
       default:
          /* unknown attrs are ignored */
          break;
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index acb36aa..9cc86d5 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -50,6 +50,9 @@ struct _egl_image_attribs
    EGLint DRMBufferFormatMESA;
    EGLint DRMBufferUseMESA;
    EGLint DRMBufferStrideMESA;
+
+   /* EGL_WL_bind_wayland_display */
+   EGLint PlaneWL;
 };
 
 /**
-- 
1.7.10.2



More information about the mesa-dev mailing list