[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