[Mesa-dev] [PATCH 3/3] egl: Add MESA_image_sRGB extension.

John Kåre Alsaker john.kare.alsaker at gmail.com
Sat Feb 23 07:53:24 PST 2013


This gives applications access to use DRIimage.duplicateImage to create sRGB and linear views from EGL images.
---
 docs/MESA_image_sRGB.spec               | 132 ++++++++++++++++++++++++++++++++
 include/EGL/eglmesaext.h                |   7 ++
 src/egl/drivers/dri2/egl_dri2.c         | 115 +++++++++++++++++++---------
 src/egl/drivers/dri2/egl_dri2.h         |   2 +-
 src/egl/drivers/dri2/platform_android.c |  19 ++++-
 src/egl/drivers/dri2/platform_drm.c     |  18 ++++-
 src/egl/drivers/dri2/platform_x11.c     |  18 ++++-
 src/egl/main/eglcurrent.c               |   5 ++
 src/egl/main/egldisplay.h               |   1 +
 src/egl/main/eglimage.c                 |   6 ++
 src/egl/main/eglimage.h                 |   3 +
 src/egl/main/eglmisc.c                  |   1 +
 12 files changed, 281 insertions(+), 46 deletions(-)
 create mode 100644 docs/MESA_image_sRGB.spec

diff --git a/docs/MESA_image_sRGB.spec b/docs/MESA_image_sRGB.spec
new file mode 100644
index 0000000..f8a0bea
--- /dev/null
+++ b/docs/MESA_image_sRGB.spec
@@ -0,0 +1,132 @@
+Name
+
+    MESA_image_sRGB
+
+Name Strings
+
+    EGL_MESA_image_sRGB
+
+Contact
+
+    John Kåre Alsaker <john.kare.alsaker at gmail.com>
+
+Status
+
+    Complete
+
+Version
+
+    Version 2, February 23, 2013
+
+Number
+
+    EGL Extension #not assigned
+
+Dependencies
+
+    EGL 1.2 or later is required.
+
+    EGL_KHR_image_base is required.
+
+    This extension is written against the wording of the EGL 1.2
+    specification.
+
+Overview
+
+    This extension provides a way for applications to allocate sRGB
+    or linear gamma views for EGLImage sources. This means that
+    sampling from the resulting EGLImage should convert from sRGB's
+    gamma into linear gamma.
+
+IP Status
+
+    Open-source; freely implementable.
+
+New Tokens
+
+    Accepted in the <attrib_list> parameter of eglCreateImageKHR:
+
+        EGL_GAMMA_MESA				0x3290
+
+    Accepted as values for the EGL_GAMMA_MESA attribute:
+
+        EGL_DEFAULT_MESA			0x3291
+
+    Error states:
+
+        EGL_BAD_VIEW_MESA			0x3292
+
+Additions to the EGL 1.2 Specification:
+
+    Add to section 2.5.1 "EGLImage Specification" (as defined by the
+    EGL_KHR_image_base specification), in the description of
+    eglCreateImageKHR:
+
+   "Attributes names accepted in <attrib_list> are shown in Table bbb
+
+      +----------------+-------------------------+------------------+
+      | Attribute      | Description             | Default Value    |
+      +----------------+-------------------------+------------------+
+      | EGL_GAMMA_MESA | Specifies the gamma     | EGL_DEFAULT_MESA |
+      |                | view of the             |                  |
+      |                | EGLImage created.       |                  |
+      +----------------+-------------------------+------------------+
+       Table bbb.  Legal attributes for eglCreateImageKHR
+       <attrib_list> parameter
+
+    ...
+
+    If the value of attribute EGL_GAMMA_MESA is EGL_DEFAULT_MESA (the
+    default), then the gamma view of the resulting EGLImage will be
+    the same as the EGLImage source.
+
+    If the value of attribute EGL_GAMMA_MESA is EGL_COLORSPACE_LINEAR,
+    then the gamma view of the resulting EGLImage will be linear
+    and no gamma conversions will be done when sampling the image
+    in client APIs.
+
+    If the value of attribute EGL_GAMMA_MESA is EGL_COLORSPACE_sRGB,
+    then the gamma view of the resulting EGLImage will be an sRGB
+    view and the red, green and blue color components will be
+    converted from sRGB gamma to linear gamma when sampling the image
+    in client APIs. This conversion should ideally take place before
+    any filtering, but that is not required. The conversion from an
+    sRGB gamma component, cs, to a linear gamma component, cl, is as
+    follows.
+
+            {  cs / 12.92,                 cs <= 0.04045
+       cl = {
+            {  ((cs + 0.055)/1.055)^2.4,   cs >  0.04045
+
+    Assume cs is the sRGB gamma component in the range [0,1]."
+
+    Add to the list of error conditions for eglCreateImageKHR:
+
+      "* If the value specified in <attrib_list> for EGL_GAMMA_MESA
+         is not EGL_DEFAULT_MESA, and the implementation does not
+         support creating the specified gamma view, the error
+         EGL_BAD_VIEW_MESA is generated.
+
+       * If the value specified in <attrib_list> for EGL_GAMMA_MESA
+         is EGL_COLORSPACE_sRGB, and the EGLImage source does not have
+         red, green and blue color components, the error
+         EGL_BAD_VIEW_MESA is generated."
+
+Issues
+
+    1)  Should creating multiple EGLImages from the same source
+        with a different gamma view be allowed?
+
+        RESOLVED: Yes.
+
+        This is so applications can easily switch between using
+        an sRGB and a linear gamma view for a single EGLImage
+        source.
+
+Revision History
+
+    Version 2, February 23, 2013
+        Changed used tokens (John Kåre Alsaker)
+
+    Version 1, October 9, 2012
+        Initial draft (John Kåre Alsaker)
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index d476d18..59f903a 100644
--- a/include/EGL/eglmesaext.h
+++ b/include/EGL/eglmesaext.h
@@ -109,6 +109,13 @@ typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDRMDISPLAYMESA) (int fd);
 #endif
 #endif
 
+#ifndef EGL_MESA_image_sRGB
+#define EGL_MESA_image_sRGB 1
+#define EGL_GAMMA_MESA 0x3290 /* eglCreateImageKHR attribute */
+#define EGL_DEFAULT_MESA 0x3291
+#define EGL_BAD_VIEW_MESA 0x3292
+#endif
+
 #ifndef EGL_WL_bind_wayland_display
 #define EGL_WL_bind_wayland_display 1
 
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index ae842d7..f2fcd28 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -491,6 +491,8 @@ dri2_setup_screen(_EGLDisplay *disp)
          disp->Extensions.EXT_create_context_robustness = EGL_TRUE;
    }
 
+   disp->Extensions.MESA_image_sRGB = EGL_TRUE;
+
    if (dri2_dpy->image) {
       disp->Extensions.MESA_drm_image = EGL_TRUE;
       disp->Extensions.KHR_image_base = EGL_TRUE;
@@ -1099,13 +1101,18 @@ dri2_create_image(_EGLDisplay *disp, __DRIimage *dri_image)
 static _EGLImage *
 dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
 				   EGLClientBuffer buffer,
-				   const EGLint *attr_list)
+				   _EGLImageAttribs *attrs)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
    GLuint renderbuffer = (GLuint) (uintptr_t) buffer;
    __DRIimage *dri_image;
 
+   if (attrs->GammaMESA != EGL_DEFAULT_MESA) {
+      _eglError(EGL_BAD_VIEW_MESA, "dri2_create_image_khr_renderbuffer");
+      return EGL_NO_IMAGE_KHR;
+   }
+
    if (renderbuffer == 0) {
       _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
       return EGL_NO_IMAGE_KHR;
@@ -1120,30 +1127,30 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
 
 static _EGLImage *
 dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
-				  EGLClientBuffer buffer, const EGLint *attr_list)
+				  EGLClientBuffer buffer, _EGLImageAttribs *attrs)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
-   EGLint format, name, pitch, err;
-   _EGLImageAttribs attrs;
+   EGLint format, name, pitch;
    __DRIimage *dri_image;
 
    name = (EGLint) (uintptr_t) buffer;
 
-   err = _eglParseImageAttribList(&attrs, disp, attr_list);
-   if (err != EGL_SUCCESS)
+   if (attrs->GammaMESA != EGL_DEFAULT_MESA) {
+      _eglError(EGL_BAD_VIEW_MESA, "dri2_create_image_mesa_drm_buffer");
       return NULL;
+   }
 
-   if (attrs.Width <= 0 || attrs.Height <= 0 ||
-       attrs.DRMBufferStrideMESA <= 0) {
+   if (attrs->Width <= 0 || attrs->Height <= 0 ||
+       attrs->DRMBufferStrideMESA <= 0) {
       _eglError(EGL_BAD_PARAMETER,
 		"bad width, height or stride");
       return NULL;
    }
 
-   switch (attrs.DRMBufferFormatMESA) {
+   switch (attrs->DRMBufferFormatMESA) {
    case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
       format = __DRI_IMAGE_FORMAT_ARGB8888;
-      pitch = attrs.DRMBufferStrideMESA;
+      pitch = attrs->DRMBufferStrideMESA;
       break;
    default:
       _eglError(EGL_BAD_PARAMETER,
@@ -1153,8 +1160,8 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
 
    dri_image =
       dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
-					   attrs.Width,
-					   attrs.Height,
+					   attrs->Width,
+					   attrs->Height,
 					   format,
 					   name,
 					   pitch,
@@ -1186,26 +1193,18 @@ static const struct wl_drm_components_descriptor {
 static _EGLImage *
 dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
 				    EGLClientBuffer _buffer,
-				    const EGLint *attr_list)
+				    _EGLImageAttribs *attrs)
 {
    struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer;
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    const struct wl_drm_components_descriptor *f;
    __DRIimage *dri_image;
-   _EGLImageAttribs attrs;
-   EGLint err;
    int32_t plane;
 
    if (!wayland_buffer_is_drm(&buffer->buffer))
        return NULL;
 
-   err = _eglParseImageAttribList(&attrs, disp, attr_list);
-   plane = attrs.PlaneWL;
-   if (err != EGL_SUCCESS) {
-      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer");
-      return NULL;
-   }
-
+   plane = attrs->PlaneWL;
    f = buffer->driver_format;
    if (plane < 0 || plane >= f->nplanes) {
       _eglError(EGL_BAD_PARAMETER,
@@ -1213,7 +1212,30 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
       return NULL;
    }
 
-   dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane, NULL);
+   if (attrs->GammaMESA != EGL_DEFAULT_MESA) {
+      if (attrs->GammaMESA != EGL_COLORSPACE_sRGB &&
+          attrs->GammaMESA != EGL_COLORSPACE_LINEAR) {
+         goto bad_view;
+      }
+
+      if(dri2_dpy->image->base.version < 7) {
+         goto bad_view;
+      }
+
+      if(f->components != EGL_TEXTURE_RGB && f->components != EGL_TEXTURE_RGBA) {
+         goto bad_view;
+      }
+
+      dri_image = dri2_dpy->image->duplicateImage(dri2_dpy->dri_screen,
+                     buffer->driver_buffer,
+                     attrs->GammaMESA == EGL_COLORSPACE_sRGB ? __DRI_IMAGE_FLAG_SRGB_VIEW :
+                     __DRI_IMAGE_FLAG_LINEAR_VIEW, NULL);
+
+      if (dri_image == NULL) {
+         goto bad_view;
+      }
+   } else
+      dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane, NULL);
 
    if (dri_image == NULL) {
       _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer");
@@ -1221,6 +1243,10 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
    }
 
    return dri2_create_image(disp, dri_image);
+
+bad_view:
+   _eglError(EGL_BAD_VIEW_MESA, "dri2_create_image_wayland_wl_buffer");
+   return NULL;
 }
 #endif
 
@@ -1262,24 +1288,25 @@ static _EGLImage *
 dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
 				   EGLenum target,
 				   EGLClientBuffer buffer,
-				   const EGLint *attr_list)
+				   _EGLImageAttribs *attrs)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
    struct dri2_egl_image *dri2_img;
    GLuint texture = (GLuint) (uintptr_t) buffer;
-   _EGLImageAttribs attrs;
    GLuint depth;
    GLenum gl_target;
    unsigned error;
 
-   if (texture == 0) {
-      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+   if (attrs->GammaMESA != EGL_DEFAULT_MESA) {
+      _eglError(EGL_BAD_VIEW_MESA, "dri2_create_image_khr_texture");
       return EGL_NO_IMAGE_KHR;
    }
 
-   if (_eglParseImageAttribList(&attrs, disp, attr_list) != EGL_SUCCESS)
+   if (texture == 0) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
       return EGL_NO_IMAGE_KHR;
+   }
 
    switch (target) {
    case EGL_GL_TEXTURE_2D_KHR:
@@ -1287,7 +1314,7 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
       gl_target = GL_TEXTURE_2D;
       break;
    case EGL_GL_TEXTURE_3D_KHR:
-      depth = attrs.GLTextureZOffset;
+      depth = attrs->GLTextureZOffset;
       gl_target = GL_TEXTURE_3D;
       break;
    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
@@ -1321,7 +1348,7 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
                                               gl_target,
                                               texture,
                                               depth,
-                                              attrs.GLTextureLevel,
+                                              attrs->GLTextureLevel,
                                               &error,
                                               dri2_img);
    dri2_create_image_khr_texture_error(error);
@@ -1336,7 +1363,7 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
 _EGLImage *
 dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
 		      _EGLContext *ctx, EGLenum target,
-		      EGLClientBuffer buffer, const EGLint *attr_list)
+		      EGLClientBuffer buffer, _EGLImageAttribs *attrs)
 {
    (void) drv;
 
@@ -1348,14 +1375,14 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
-      return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list);
+      return dri2_create_image_khr_texture(disp, ctx, target, buffer, attrs);
    case EGL_GL_RENDERBUFFER_KHR:
-      return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
+      return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attrs);
    case EGL_DRM_BUFFER_MESA:
-      return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list);
+      return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attrs);
 #ifdef HAVE_WAYLAND_PLATFORM
    case EGL_WAYLAND_BUFFER_WL:
-      return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
+      return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attrs);
 #endif
    default:
       _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
@@ -1363,6 +1390,22 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
    }
 }
 
+static _EGLImage *
+dri2_create_image_khr_fallback(_EGLDriver *drv, _EGLDisplay *disp,
+                          _EGLContext *ctx, EGLenum target,
+                          EGLClientBuffer buffer, const EGLint *attr_list)
+{
+   EGLint err;
+   _EGLImageAttribs attrs;
+
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS) {
+      return NULL;
+   }
+
+   return dri2_create_image_khr(drv, disp, ctx, target, buffer, &attrs);
+}
+
 static EGLBoolean
 dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image)
 {
@@ -1693,7 +1736,7 @@ _eglBuiltInDriverDRI2(const char *args)
    dri2_drv->base.API.WaitNative = dri2_wait_native;
    dri2_drv->base.API.BindTexImage = dri2_bind_tex_image;
    dri2_drv->base.API.ReleaseTexImage = dri2_release_tex_image;
-   dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr;
+   dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr_fallback;
    dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
    dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa;
    dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa;
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 84ea2a6..4650e19 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -251,7 +251,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
 _EGLImage *
 dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
 		      _EGLContext *ctx, EGLenum target,
-		      EGLClientBuffer buffer, const EGLint *attr_list);
+		      EGLClientBuffer buffer, _EGLImageAttribs *attrs);
 
 EGLBoolean
 dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp);
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index 3432f18..084866f 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -335,13 +335,19 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
 
 static _EGLImage *
 dri2_create_image_android_native_buffer(_EGLDisplay *disp,
-                                        struct ANativeWindowBuffer *buf)
+                                        struct ANativeWindowBuffer *buf,
+                                        _EGLImageAttribs *attrs)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    struct dri2_egl_image *dri2_img;
    int name;
    EGLint format;
 
+   if (attrs->GammaMESA != EGL_DEFAULT_MESA) {
+      _eglError(EGL_BAD_VIEW_MESA, "eglCreateEGLImageKHR");
+      return NULL;
+   }
+
    if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC ||
        buf->common.version != sizeof(*buf)) {
       _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
@@ -411,12 +417,19 @@ droid_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
 		       _EGLContext *ctx, EGLenum target,
 		       EGLClientBuffer buffer, const EGLint *attr_list)
 {
+   EGLint err;
+   _EGLImageAttribs attrs;
+
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS)
+      return NULL;
+
    switch (target) {
    case EGL_NATIVE_BUFFER_ANDROID:
       return dri2_create_image_android_native_buffer(disp,
-            (struct ANativeWindowBuffer *) buffer);
+            (struct ANativeWindowBuffer *) buffer, &attrs);
    default:
-      return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
+      return dri2_create_image_khr(drv, disp, ctx, target, buffer, &attrs);
    }
 }
 
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 615648b..5799b7b 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -360,12 +360,17 @@ dri2_query_buffer_age(_EGLDriver *drv,
 
 static _EGLImage *
 dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
-			     EGLClientBuffer buffer, const EGLint *attr_list)
+			     EGLClientBuffer buffer, _EGLImageAttribs *attrs)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer);
    struct dri2_egl_image *dri2_img;
 
+   if (attrs->GammaMESA != EGL_DEFAULT_MESA) {
+      _eglError(EGL_BAD_VIEW_MESA, "dri2_create_image_khr_pixmap");
+      return NULL;
+   }
+
    dri2_img = malloc(sizeof *dri2_img);
    if (!dri2_img) {
       _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
@@ -392,13 +397,20 @@ dri2_drm_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
                           _EGLContext *ctx, EGLenum target,
                           EGLClientBuffer buffer, const EGLint *attr_list)
 {
+   EGLint err;
+   _EGLImageAttribs attrs;
+
    (void) drv;
 
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS)
+      return NULL;
+
    switch (target) {
    case EGL_NATIVE_PIXMAP_KHR:
-      return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
+      return dri2_create_image_khr_pixmap(disp, ctx, buffer, &attrs);
    default:
-      return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
+      return dri2_create_image_khr(drv, disp, ctx, target, buffer, &attrs);
    }
 }
 
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index da61cfc..e2e82c3 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -851,7 +851,7 @@ dri2_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
 
 static _EGLImage *
 dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
-			     EGLClientBuffer buffer, const EGLint *attr_list)
+			     EGLClientBuffer buffer, _EGLImageAttribs *attrs)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    struct dri2_egl_image *dri2_img;
@@ -865,6 +865,11 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
    xcb_generic_error_t *error;
    int stride, format;
 
+   if (attrs->GammaMESA != EGL_DEFAULT_MESA) {
+      _eglError(EGL_BAD_VIEW_MESA, "dri2_create_image_khr_pixmap");
+      return NULL;
+   }
+
    (void) ctx;
 
    drawable = (xcb_drawable_t) (uintptr_t) buffer;
@@ -944,13 +949,20 @@ dri2_x11_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
 			  _EGLContext *ctx, EGLenum target,
 			  EGLClientBuffer buffer, const EGLint *attr_list)
 {
+   EGLint err;
+   _EGLImageAttribs attrs;
+
    (void) drv;
 
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS)
+      return NULL;
+
    switch (target) {
    case EGL_NATIVE_PIXMAP_KHR:
-      return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
+      return dri2_create_image_khr_pixmap(disp, ctx, buffer, &attrs);
    default:
-      return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
+      return dri2_create_image_khr(drv, disp, ctx, target, buffer, &attrs);
    }
 }
 
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
index 5b09a48..d48369b 100644
--- a/src/egl/main/eglcurrent.c
+++ b/src/egl/main/eglcurrent.c
@@ -325,6 +325,11 @@ _eglError(EGLint errCode, const char *msg)
          s = "EGL_BAD_MODE_MESA";
          break;
 #endif
+#ifdef EGL_MESA_image_sRGB
+      case EGL_BAD_VIEW_MESA:
+         s = "EGL_BAD_VIEW_MESA";
+         break;
+#endif
       default:
          s = "other EGL error";
       }
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 4b33470..8ecd5d8 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -89,6 +89,7 @@ struct _egl_extensions
    EGLBoolean MESA_copy_context;
    EGLBoolean MESA_drm_display;
    EGLBoolean MESA_drm_image;
+   EGLBoolean MESA_image_sRGB;
 
    EGLBoolean WL_bind_wayland_display;
 
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index bfae709..1119947 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -49,6 +49,7 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
    attrs->ImagePreserved = EGL_FALSE;
    attrs->GLTextureLevel = 0;
    attrs->GLTextureZOffset = 0;
+   attrs->GammaMESA = EGL_DEFAULT_MESA;
 
    if (!attrib_list)
       return err;
@@ -88,6 +89,11 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
          attrs->DRMBufferStrideMESA = val;
          break;
 
+      /* EGL_MESA_image_sRGB */
+      case EGL_GAMMA_MESA:
+         attrs->GammaMESA = val;
+         break;
+
       /* EGL_WL_bind_wayland_display */
       case EGL_WAYLAND_PLANE_WL:
          attrs->PlaneWL = val;
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index 9cc86d5..4c500d0 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -53,6 +53,9 @@ struct _egl_image_attribs
 
    /* EGL_WL_bind_wayland_display */
    EGLint PlaneWL;
+
+   /* EGL_MESA_image_sRGB */
+   EGLint GammaMESA;
 };
 
 /**
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 92b0eae..f2cc2e3 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -90,6 +90,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
    _EGL_CHECK_EXTENSION(MESA_copy_context);
    _EGL_CHECK_EXTENSION(MESA_drm_display);
    _EGL_CHECK_EXTENSION(MESA_drm_image);
+   _EGL_CHECK_EXTENSION(MESA_image_sRGB);
 
    _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
 
-- 
1.8.1.3



More information about the mesa-dev mailing list