[Mesa-dev] [PATCH v3 5/5] egl: Add MESA_image_sRGB extension.
John Kåre Alsaker
john.kare.alsaker at gmail.com
Sat Apr 26 07:25:55 PDT 2014
This gives applications access to use DRIimage.duplicateImage to create
sRGB and linear views from EGL images.
---
include/EGL/eglmesaext.h | 7 ++
src/egl/drivers/dri2/egl_dri2.c | 201 +++++++++++++++++++-------------
src/egl/drivers/dri2/egl_dri2.h | 11 +-
src/egl/drivers/dri2/platform_android.c | 36 +++---
src/egl/drivers/dri2/platform_drm.c | 36 +++---
src/egl/drivers/dri2/platform_wayland.c | 2 +-
src/egl/drivers/dri2/platform_x11.c | 37 +++---
src/egl/main/eglcurrent.c | 3 +
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, 192 insertions(+), 152 deletions(-)
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index 5fcc527..740f676 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 a132964..5b421ac 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -529,6 +529,10 @@ dri2_setup_screen(_EGLDisplay *disp)
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE;
}
+ if (dri2_dpy->image->base.version >= 9 &&
+ dri2_dpy->image->duplicateImage) {
+ disp->Extensions.MESA_image_sRGB = EGL_TRUE;
+ }
#ifdef HAVE_DRM_PLATFORM
if (dri2_dpy->image->base.version >= 8 &&
dri2_dpy->image->createImageFromDmaBufs) {
@@ -1218,6 +1222,47 @@ dri2_release_tex_image(_EGLDriver *drv,
return EGL_TRUE;
}
+static EGLBoolean
+dri2_process_dri_image(_EGLDisplay *disp, __DRIimage **dri_image,
+ const _EGLImageAttribs *attrs)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ __DRIimage *result;
+
+ if (attrs->GammaMESA == EGL_DEFAULT_MESA) {
+ return EGL_TRUE;
+ }
+
+ if (!disp->Extensions.MESA_image_sRGB) {
+ goto bad_view;
+ }
+
+ if (attrs->GammaMESA != EGL_COLORSPACE_sRGB &&
+ attrs->GammaMESA != EGL_COLORSPACE_LINEAR) {
+ goto bad_view;
+ }
+
+ result = dri2_dpy->image->duplicateImage(dri2_dpy->dri_screen,
+ *dri_image,
+ attrs->GammaMESA == EGL_COLORSPACE_sRGB ?
+ __DRI_IMAGE_FLAG_SRGB_VIEW :
+ __DRI_IMAGE_FLAG_LINEAR_VIEW, NULL);
+
+ if (result == NULL) {
+ goto bad_view;
+ }
+
+ dri2_dpy->image->destroyImage(*dri_image);
+
+ *dri_image = result;
+
+ return EGL_TRUE;
+
+bad_view:
+ _eglError(EGL_BAD_VIEW_MESA, "dri2_create_image");
+ return EGL_FALSE;
+}
+
static _EGLImage*
dri2_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer,
@@ -1228,9 +1273,11 @@ dri2_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
attr_list);
}
-static _EGLImage *
-dri2_create_image_from_dri(_EGLDisplay *disp, __DRIimage *dri_image)
+_EGLImage *
+dri2_create_image_from_dri(_EGLDisplay *disp, __DRIimage *dri_image,
+ const _EGLImageAttribs *attrs)
{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_image *dri2_img;
if (dri_image == NULL) {
@@ -1238,26 +1285,35 @@ dri2_create_image_from_dri(_EGLDisplay *disp, __DRIimage *dri_image)
return NULL;
}
+ if (!dri2_process_dri_image(disp, &dri_image, attrs)) {
+ goto error;
+ }
+
dri2_img = malloc(sizeof *dri2_img);
if (!dri2_img) {
_eglError(EGL_BAD_ALLOC, "dri2_create_image");
- return NULL;
+ goto error;
}
if (!_eglInitImage(&dri2_img->base, disp)) {
+ _eglError(EGL_BAD_ALLOC, "dri2_create_image");
free(dri2_img);
- return NULL;
+ goto error;
}
dri2_img->dri_image = dri_image;
return &dri2_img->base;
+
+error:
+ dri2_dpy->image->destroyImage(dri_image);
+ return NULL;
}
static _EGLImage *
dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
EGLClientBuffer buffer,
- const EGLint *attr_list)
+ const _EGLImageAttribs *attrs)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
@@ -1273,36 +1329,32 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
dri2_dpy->image->createImageFromRenderbuffer(dri2_ctx->dri_context,
renderbuffer, NULL);
- return dri2_create_image_from_dri(disp, dri_image);
+ return dri2_create_image_from_dri(disp, dri_image, attrs);
}
#ifdef HAVE_DRM_PLATFORM
static _EGLImage *
dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
- EGLClientBuffer buffer, const EGLint *attr_list)
+ EGLClientBuffer buffer,
+ const _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)
- 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,
@@ -1312,14 +1364,14 @@ 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,
NULL);
- return dri2_create_image_from_dri(disp, dri_image);
+ return dri2_create_image_from_dri(disp, dri_image, attrs);
}
#endif
@@ -1346,14 +1398,12 @@ 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)
+ const _EGLImageAttribs *attrs)
{
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;
buffer = wayland_drm_buffer_get(dri2_dpy->wl_server_drm,
@@ -1361,13 +1411,7 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
if (!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,
@@ -1382,7 +1426,7 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
- return dri2_create_image_from_dri(disp, dri_image);
+ return dri2_create_image_from_dri(disp, dri_image, attrs);
}
#endif
@@ -1424,13 +1468,12 @@ static _EGLImage *
dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
EGLenum target,
EGLClientBuffer buffer,
- const EGLint *attr_list)
+ const _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;
+ __DRIimage *dri_image;
GLuint texture = (GLuint) (uintptr_t) buffer;
- _EGLImageAttribs attrs;
GLuint depth;
GLenum gl_target;
unsigned error;
@@ -1440,16 +1483,13 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
return EGL_NO_IMAGE_KHR;
}
- if (_eglParseImageAttribList(&attrs, disp, attr_list) != EGL_SUCCESS)
- return EGL_NO_IMAGE_KHR;
-
switch (target) {
case EGL_GL_TEXTURE_2D_KHR:
depth = 0;
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:
@@ -1466,33 +1506,17 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
return EGL_NO_IMAGE_KHR;
}
- dri2_img = malloc(sizeof *dri2_img);
- if (!dri2_img) {
- _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
- return EGL_NO_IMAGE_KHR;
- }
-
- if (!_eglInitImage(&dri2_img->base, disp)) {
- _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
- free(dri2_img);
- return EGL_NO_IMAGE_KHR;
- }
-
- dri2_img->dri_image =
+ dri_image =
dri2_dpy->image->createImageFromTexture(dri2_ctx->dri_context,
gl_target,
texture,
depth,
- attrs.GLTextureLevel,
+ attrs->GLTextureLevel,
&error,
- dri2_img);
+ NULL);
dri2_create_image_khr_texture_error(error);
- if (!dri2_img->dri_image) {
- free(dri2_img);
- return EGL_NO_IMAGE_KHR;
- }
- return &dri2_img->base;
+ return dri2_create_image_from_dri(disp, dri_image, attrs);
}
static struct wl_buffer*
@@ -1693,12 +1717,11 @@ dri2_take_dma_buf_ownership(const int *fds, unsigned num_fds)
static _EGLImage *
dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
- EGLClientBuffer buffer, const EGLint *attr_list)
+ EGLClientBuffer buffer,
+ const _EGLImageAttribs *attrs)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
_EGLImage *res;
- EGLint err;
- _EGLImageAttribs attrs;
__DRIimage *dri_image;
unsigned num_fds;
unsigned i;
@@ -1718,33 +1741,27 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
- err = _eglParseImageAttribList(&attrs, disp, attr_list);
- if (err != EGL_SUCCESS) {
- _eglError(err, "bad attribute");
+ if (!dri2_check_dma_buf_attribs(attrs))
return NULL;
- }
- if (!dri2_check_dma_buf_attribs(&attrs))
- return NULL;
-
- num_fds = dri2_check_dma_buf_format(&attrs);
+ num_fds = dri2_check_dma_buf_format(attrs);
if (!num_fds)
return NULL;
for (i = 0; i < num_fds; ++i) {
- fds[i] = attrs.DMABufPlaneFds[i].Value;
- pitches[i] = attrs.DMABufPlanePitches[i].Value;
- offsets[i] = attrs.DMABufPlaneOffsets[i].Value;
+ fds[i] = attrs->DMABufPlaneFds[i].Value;
+ pitches[i] = attrs->DMABufPlanePitches[i].Value;
+ offsets[i] = attrs->DMABufPlaneOffsets[i].Value;
}
dri_image =
dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
- attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
+ attrs->Width, attrs->Height, attrs->DMABufFourCC.Value,
fds, num_fds, pitches, offsets,
- attrs.DMABufYuvColorSpaceHint.Value,
- attrs.DMABufSampleRangeHint.Value,
- attrs.DMABufChromaHorizontalSiting.Value,
- attrs.DMABufChromaVerticalSiting.Value,
+ attrs->DMABufYuvColorSpaceHint.Value,
+ attrs->DMABufSampleRangeHint.Value,
+ attrs->DMABufChromaHorizontalSiting.Value,
+ attrs->DMABufChromaVerticalSiting.Value,
&error,
NULL);
dri2_create_image_khr_texture_error(error);
@@ -1752,7 +1769,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
if (!dri_image)
return EGL_NO_IMAGE_KHR;
- res = dri2_create_image_from_dri(disp, dri_image);
+ res = dri2_create_image_from_dri(disp, dri_image, attrs);
if (res)
dri2_take_dma_buf_ownership(fds, num_fds);
@@ -1763,7 +1780,7 @@ dri2_create_image_dma_buf(_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, const _EGLImageAttribs *attrs)
{
(void) drv;
@@ -1775,20 +1792,20 @@ 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);
#ifdef HAVE_DRM_PLATFORM
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);
#endif
#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
#ifdef HAVE_DRM_PLATFORM
case EGL_LINUX_DMA_BUF_EXT:
- return dri2_create_image_dma_buf(disp, ctx, buffer, attr_list);
+ return dri2_create_image_dma_buf(disp, ctx, buffer, attrs);
#endif
default:
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
@@ -1796,6 +1813,22 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
}
}
+_EGLImage *
+dri2_create_image_khr_default(_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)
{
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index e62e265..84c400f 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -311,9 +311,18 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
const unsigned int *rgba_masks);
_EGLImage *
+dri2_create_image_from_dri(_EGLDisplay *disp, __DRIimage *dri_image,
+ const _EGLImageAttribs *attrs);
+
+_EGLImage *
dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
_EGLContext *ctx, EGLenum target,
- EGLClientBuffer buffer, const EGLint *attr_list);
+ EGLClientBuffer buffer, const _EGLImageAttribs *attrs);
+
+_EGLImage *
+dri2_create_image_khr_default(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLContext *ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list);
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 7b1db76..3f40eab 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -325,10 +325,11 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
static _EGLImage *
dri2_create_image_android_native_buffer(_EGLDisplay *disp, _EGLContext *ctx,
- struct ANativeWindowBuffer *buf)
+ struct ANativeWindowBuffer *buf,
+ const _EGLImageAttribs *attrs)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_image *dri2_img;
+ __DRIimage *dri_image;
int name;
EGLint format;
@@ -380,18 +381,7 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp, _EGLContext *ctx,
break;
}
- dri2_img = calloc(1, sizeof(*dri2_img));
- if (!dri2_img) {
- _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
- return NULL;
- }
-
- if (!_eglInitImage(&dri2_img->base, disp)) {
- free(dri2_img);
- return NULL;
- }
-
- dri2_img->dri_image =
+ dri_image =
dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
buf->width,
buf->height,
@@ -399,13 +389,8 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp, _EGLContext *ctx,
name,
buf->stride,
dri2_img);
- if (!dri2_img->dri_image) {
- free(dri2_img);
- _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
- return NULL;
- }
- return &dri2_img->base;
+ return dri2_create_image_from_dri(disp, dri_image, attrs);
}
static _EGLImage *
@@ -413,12 +398,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, ctx,
- (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 9a7633a..80eafea 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -407,31 +407,16 @@ dri2_drm_query_buffer_age(_EGLDriver *drv,
static _EGLImage *
dri2_drm_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
- EGLClientBuffer buffer, const EGLint *attr_list)
+ EGLClientBuffer buffer,
+ const _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;
+ __DRIimage *dri_image;
- dri2_img = malloc(sizeof *dri2_img);
- if (!dri2_img) {
- _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
- return NULL;
- }
-
- if (!_eglInitImage(&dri2_img->base, disp)) {
- free(dri2_img);
- return NULL;
- }
+ dri_image = dri2_dpy->image->dupImage(dri_bo->image, NULL);
- dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img);
- if (dri2_img->dri_image == NULL) {
- free(dri2_img);
- _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
- return NULL;
- }
-
- return &dri2_img->base;
+ return dri2_create_image_from_dri(disp, dri_image, attrs);
}
static _EGLImage *
@@ -439,13 +424,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_drm_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
+ return dri2_drm_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_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 37dcf19..113c62a 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -955,7 +955,7 @@ static struct dri2_egl_display_vtbl dri2_wl_display_vtbl = {
.create_pixmap_surface = dri2_wl_create_pixmap_surface,
.create_pbuffer_surface = dri2_fallback_create_pbuffer_surface,
.destroy_surface = dri2_wl_destroy_surface,
- .create_image = dri2_create_image_khr,
+ .create_image = dri2_create_image_khr_default,
.swap_interval = dri2_wl_swap_interval,
.swap_buffers = dri2_wl_swap_buffers,
.swap_buffers_with_damage = dri2_wl_swap_buffers_with_damage,
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index 7b585a2..995869c 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -896,10 +896,11 @@ dri2_x11_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,
+ const _EGLImageAttribs *attrs)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_image *dri2_img;
+ __DRIimage *dri_image;
unsigned int attachments[1];
xcb_drawable_t drawable;
xcb_dri2_get_buffers_cookie_t buffers_cookie;
@@ -953,35 +954,20 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
- dri2_img = malloc(sizeof *dri2_img);
- if (!dri2_img) {
- free(buffers_reply);
- free(geometry_reply);
- _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
- return EGL_NO_IMAGE_KHR;
- }
-
- if (!_eglInitImage(&dri2_img->base, disp)) {
- free(buffers_reply);
- free(geometry_reply);
- free(dri2_img);
- return EGL_NO_IMAGE_KHR;
- }
-
stride = buffers[0].pitch / buffers[0].cpp;
- dri2_img->dri_image =
+ dri_image =
dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
buffers_reply->width,
buffers_reply->height,
format,
buffers[0].name,
stride,
- dri2_img);
+ NULL);
free(buffers_reply);
free(geometry_reply);
- return &dri2_img->base;
+ return dri2_create_image_from_dri(disp, dri_image, attrs);
}
static _EGLImage *
@@ -989,13 +975,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 fcb732d..03ca063 100644
--- a/src/egl/main/eglcurrent.c
+++ b/src/egl/main/eglcurrent.c
@@ -325,6 +325,9 @@ _eglError(EGLint errCode, const char *msg)
s = "EGL_BAD_MODE_MESA";
break;
#endif
+ case EGL_BAD_VIEW_MESA:
+ s = "EGL_BAD_VIEW_MESA";
+ break;
default:
s = "other EGL error";
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 970c21a..5b9cee3 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 MESA_configless_context;
EGLBoolean WL_bind_wayland_display;
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index 818b597..80a8e4d 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 1b4d6cd..996de7b 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -56,6 +56,9 @@ struct _egl_image_attribs
EGLint DRMBufferUseMESA;
EGLint DRMBufferStrideMESA;
+ /* EGL_MESA_image_sRGB */
+ EGLint GammaMESA;
+
/* EGL_WL_bind_wayland_display */
EGLint PlaneWL;
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 65669d8..e5ccd81 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(MESA_configless_context);
_EGL_CHECK_EXTENSION(WL_bind_wayland_display);
--
1.9.2
More information about the mesa-dev
mailing list