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

Ian Romanick idr at freedesktop.org
Mon Feb 25 11:55:50 PST 2013


On 02/23/2013 07:53 AM, John Kåre Alsaker wrote:
> This gives applications access to use DRIimage.duplicateImage to create sRGB and linear views from EGL images.

The spec and the implementation really should be separate commits.

Also... are there piglit tests coming?

> ---
>   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 @@

More recent versions of the spec template include a section for 
describing conformance tests.  This would be a good place to document 
piglit tests.  It also helps app developers know how things should work.

> +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.

Interactions with GL_ARB_texture_view?  Really, texture views seem like 
the right way to do this.

> +
> +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;
> +

What if the underlying driver doesn't support sRGB?  Since this 
extension depends on KHR_image_base, the enable needs to at least depend 
on dri2_dpy->image.

>      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)

Shouldn't attrs sill be const?

>   {
>      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)

Ditto for const.

>   {
>      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)

Again.

>   {
>      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;
> +   }
> +

Why can't I create an sRGB view of a pixmap?  It's just a 
reinterpretation of the bits.  The spec doesn't give much guidance about 
why the implementation may not "support creating the specified gamma 
view".  At least mentioning something in the issues section would be 
helpful.

>      (void) ctx;

Usually all the (void) casting to work-around unused-varaible warnings 
comes before the real code in the function.

>
>      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

I know the ifdef stuff is used other places, but since this comes from 
our own header file, I don't think it's necessary.

> +      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);
>
>



More information about the mesa-dev mailing list