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

John Kåre Alsaker john.kare.alsaker at gmail.com
Sat Sep 29 09:21:09 PDT 2012


---
 include/EGL/eglmesaext.h                |  7 +++++++
 src/egl/drivers/dri2/egl_dri2.c         | 32 +++++++++++++++++++++++++++++++-
 src/egl/drivers/dri2/platform_android.c | 16 ++++++++++++++--
 src/egl/drivers/dri2/platform_drm.c     | 11 +++++++++++
 src/egl/drivers/dri2/platform_wayland.c | 11 +++++++++++
 src/egl/drivers/dri2/platform_x11.c     | 11 +++++++++++
 src/egl/main/egldisplay.h               |  1 +
 src/egl/main/eglimage.c                 |  6 ++++++
 src/egl/main/eglimage.h                 |  3 +++
 src/egl/main/eglmisc.c                  |  1 +
 10 files changed, 96 insertions(+), 3 deletions(-)

diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index d476d18..7fc4b65 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 0x4534001 /* eglCreateImageKHR attribute */
+#define EGL_LINEAR_MESA 0x4534002
+#define EGL_SRGB_MESA 0x4534003
+#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 4b58c35..e3263ba 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -492,6 +492,7 @@ dri2_setup_screen(_EGLDisplay *disp)
       disp->Extensions.MESA_drm_image = EGL_TRUE;
       disp->Extensions.KHR_image_base = EGL_TRUE;
       disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
+      disp->Extensions.MESA_image_sRGB = EGL_TRUE;
    }
 }
 
@@ -1026,6 +1027,17 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
    struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
    GLuint renderbuffer = (GLuint) (uintptr_t) buffer;
    __DRIimage *dri_image;
+   EGLint err;
+   _EGLImageAttribs attrs;
+
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS)
+      return NULL;
+
+   if (attrs.GammaMESA != EGL_LINEAR_MESA) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
 
    if (renderbuffer == 0) {
       _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
@@ -1054,6 +1066,11 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
    if (err != EGL_SUCCESS)
       return NULL;
 
+   if (attrs.GammaMESA != EGL_LINEAR_MESA) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
+
    if (attrs.Width <= 0 || attrs.Height <= 0 ||
        attrs.DRMBufferStrideMESA <= 0) {
       _eglError(EGL_BAD_PARAMETER,
@@ -1134,7 +1151,20 @@ 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_SRGB_MESA) {
+      if(dri2_dpy->image->base.version < 6) {
+         _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer");
+         return NULL;
+      }
+
+      if(f->components != EGL_TEXTURE_RGB && f->components != EGL_TEXTURE_RGBA) {
+         _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer");
+         return NULL;
+      }
+
+      dri_image = dri2_dpy->image->duplicateImage(dri2_dpy->dri_screen, buffer->driver_buffer, __DRI_IMAGE_FLAG_SRGB_VIEW, NULL);
+   } 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");
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index 15bf054..87d6d40 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -280,12 +280,24 @@ 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,
+                                        const EGLint *attr_list)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    struct dri2_egl_image *dri2_img;
    int name;
    EGLint format;
+   EGLint err;
+   _EGLImageAttribs attrs;
+
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS)
+      return NULL;
+
+   if (attrs.GammaMESA != EGL_LINEAR_MESA) {
+      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+      return NULL;
+   }
 
    if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC ||
        buf->common.version != sizeof(*buf)) {
@@ -359,7 +371,7 @@ droid_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
    switch (target) {
    case EGL_NATIVE_BUFFER_ANDROID:
       return dri2_create_image_android_native_buffer(disp,
-            (struct ANativeWindowBuffer *) buffer);
+            (struct ANativeWindowBuffer *) buffer, attr_list);
    default:
       return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
    }
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 3e04a6c..73a34b3 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -345,6 +345,17 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
    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;
+   EGLint err;
+   _EGLImageAttribs attrs;
+
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS)
+      return NULL;
+
+   if (attrs.GammaMESA != EGL_LINEAR_MESA) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr_pixmap");
+      return NULL;
+   }
 
    dri2_img = malloc(sizeof *dri2_img);
    if (!dri2_img) {
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index d9b45f1..d880e2b 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -636,6 +636,8 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    struct wl_egl_pixmap *wl_egl_pixmap = (struct wl_egl_pixmap *) buffer;
    struct dri2_egl_buffer *dri2_buf;
+   EGLint err;
+   _EGLImageAttribs attrs;
    EGLint wl_attr_list[] = {
 		EGL_WIDTH,		0,
 		EGL_HEIGHT,		0,
@@ -644,6 +646,15 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
 		EGL_NONE
    };
 
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS)
+      return NULL;
+
+   if (attrs.GammaMESA != EGL_LINEAR_MESA) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return NULL;
+   }
+
    dri2_buf = malloc(sizeof *dri2_buf);
    if (!dri2_buf)
            return NULL;
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index 2533774..a4af36f 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -872,6 +872,17 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
    xcb_get_geometry_reply_t *geometry_reply;
    xcb_generic_error_t *error;
    int stride, format;
+   EGLint err;
+   _EGLImageAttribs attrs;
+
+   err = _eglParseImageAttribList(&attrs, disp, attr_list);
+   if (err != EGL_SUCCESS)
+      return NULL;
+
+   if (attrs.GammaMESA != EGL_LINEAR_MESA) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return NULL;
+   }
 
    (void) ctx;
 
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index ccb1fbc..f31c330 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..b51bfa6 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_LINEAR_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 b7599d0..e0bd6ca 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.7.12.1



More information about the mesa-dev mailing list