[Mesa-dev] [PATCH 7/9] egl: implement EGL_KHR_gl_colorspace
Marek Olšák
maraeo at gmail.com
Wed Jun 10 09:27:18 PDT 2015
From: Marek Olšák <marek.olsak at amd.com>
---
src/egl/drivers/dri2/egl_dri2.c | 40 ++++++++++++++++++++++++++-------
src/egl/drivers/dri2/egl_dri2.h | 6 +++++
src/egl/drivers/dri2/platform_android.c | 4 ++++
src/egl/drivers/dri2/platform_drm.c | 9 +++++---
src/egl/drivers/dri2/platform_wayland.c | 9 +++++---
src/egl/drivers/dri2/platform_x11.c | 12 +++++-----
src/egl/main/eglconfig.c | 3 ++-
src/egl/main/eglsurface.c | 24 ++++++++++++++++++++
src/egl/main/eglsurface.h | 1 +
9 files changed, 87 insertions(+), 21 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index eacb36c..84f0afb 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -28,6 +28,7 @@
#define WL_HIDE_DEPRECATED
#include <stdint.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -109,6 +110,18 @@ EGLint dri2_to_egl_attribute_map[] = {
0, /* __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE */
};
+const __DRIconfig *
+dri2_get_dri_config(struct dri2_egl_config *conf, EGLint surface_type,
+ EGLenum colorspace)
+{
+ if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR)
+ return surface_type == EGL_WINDOW_BIT ? conf->dri_srgb_double_config :
+ conf->dri_srgb_single_config;
+ else
+ return surface_type == EGL_WINDOW_BIT ? conf->dri_double_config :
+ conf->dri_single_config;
+}
+
static EGLBoolean
dri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria)
{
@@ -130,6 +143,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
struct dri2_egl_display *dri2_dpy;
_EGLConfig base;
unsigned int attrib, value, double_buffer;
+ bool srgb = false;
EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
unsigned int dri_masks[4] = { 0, 0, 0, 0 };
_EGLConfig *matching_config;
@@ -202,6 +216,9 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
/* Don't expose visuals with the accumulation buffer. */
if (value > 0)
return NULL;
+
+ case __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE:
+ srgb = value != 0;
break;
default:
@@ -249,28 +266,35 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
if (num_configs == 1) {
conf = (struct dri2_egl_config *) matching_config;
- if (double_buffer && !conf->dri_double_config)
+ if (double_buffer && srgb && !conf->dri_srgb_double_config)
+ conf->dri_srgb_double_config = dri_config;
+ else if (double_buffer && !srgb && !conf->dri_double_config)
conf->dri_double_config = dri_config;
- else if (!double_buffer && !conf->dri_single_config)
+ else if (!double_buffer && srgb && !conf->dri_srgb_single_config)
+ conf->dri_srgb_single_config = dri_config;
+ else if (!double_buffer && !srgb && !conf->dri_single_config)
conf->dri_single_config = dri_config;
else
/* a similar config type is already added (unlikely) => discard */
return NULL;
}
else if (num_configs == 0) {
- conf = malloc(sizeof *conf);
+ conf = calloc(1, sizeof *conf);
if (conf == NULL)
return NULL;
memcpy(&conf->base, &base, sizeof base);
if (double_buffer) {
- conf->dri_double_config = dri_config;
- conf->dri_single_config = NULL;
+ if (srgb)
+ conf->dri_srgb_double_config = dri_config;
+ else
+ conf->dri_double_config = dri_config;
} else {
- conf->dri_single_config = dri_config;
- conf->dri_double_config = NULL;
+ if (srgb)
+ conf->dri_srgb_single_config = dri_config;
+ else
+ conf->dri_single_config = dri_config;
}
- conf->base.SurfaceType = 0;
conf->base.ConfigID = config_id;
_eglLinkConfig(&conf->base);
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index adade3d..6b9a48e 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -285,6 +285,8 @@ struct dri2_egl_config
_EGLConfig base;
const __DRIconfig *dri_single_config;
const __DRIconfig *dri_double_config;
+ const __DRIconfig *dri_srgb_single_config;
+ const __DRIconfig *dri_srgb_double_config;
};
struct dri2_egl_image
@@ -354,4 +356,8 @@ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp);
void
dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw);
+const __DRIconfig *
+dri2_get_dri_config(struct dri2_egl_config *conf, EGLint surface_type,
+ EGLenum colorspace);
+
#endif /* EGL_DRI2_INCLUDED */
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index fed3073..3cb2459 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -199,6 +199,7 @@ droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
struct dri2_egl_surface *dri2_surf;
struct ANativeWindow *window = native_window;
+ const __DRIconfig *config;
dri2_surf = calloc(1, sizeof *dri2_surf);
if (!dri2_surf) {
@@ -230,6 +231,9 @@ droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
window->query(window, NATIVE_WINDOW_HEIGHT, &dri2_surf->base.Height);
}
+ config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ dri2_surf->base.GLColorspace);
+
dri2_surf->dri_drawable =
(*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen,
dri2_conf->dri_double_config,
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 3391afc..4cda266 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -128,10 +128,13 @@ dri2_drm_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
}
if (dri2_dpy->dri2) {
+ const __DRIconfig *config =
+ dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ dri2_surf->base.GLColorspace);
+
dri2_surf->dri_drawable =
- (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
- dri2_conf->dri_double_config,
- dri2_surf->gbm_surf);
+ (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config,
+ dri2_surf->gbm_surf);
} else {
assert(dri2_dpy->swrast != NULL);
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index ea2f9f2..429d2cb 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -130,6 +130,7 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp,
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
struct wl_egl_window *window = native_window;
struct dri2_egl_surface *dri2_surf;
+ const __DRIconfig *config;
(void) drv;
@@ -157,10 +158,12 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp,
dri2_surf->base.Width = -1;
dri2_surf->base.Height = -1;
+ config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ dri2_surf->base.GLColorspace);
+
dri2_surf->dri_drawable =
- (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
- dri2_conf->dri_double_config,
- dri2_surf);
+ (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config,
+ dri2_surf);
if (dri2_surf->dri_drawable == NULL) {
_eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
goto cleanup_dri_drawable;
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index e0d0fdc..66717cd 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -238,12 +238,12 @@ dri2_x11_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
}
if (dri2_dpy->dri2) {
- dri2_surf->dri_drawable =
- (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
- type == EGL_WINDOW_BIT ?
- dri2_conf->dri_double_config :
- dri2_conf->dri_single_config,
- dri2_surf);
+ const __DRIconfig *config =
+ dri2_get_dri_config(dri2_conf, type, dri2_surf->base.GLColorspace);
+
+ dri2_surf->dri_drawable =
+ (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config,
+ dri2_surf);
} else {
assert(dri2_dpy->swrast);
dri2_surf->dri_drawable =
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index cf65c69..c445d9b 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -83,7 +83,8 @@ _eglLinkConfig(_EGLConfig *conf)
_EGLDisplay *dpy = conf->Display;
/* sanity check */
- assert(dpy && conf->ConfigID > 0);
+ assert(dpy);
+ assert(conf->ConfigID > 0);
if (!dpy->Configs) {
dpy->Configs = _eglCreateArray("Config", 16);
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 76c60e9..541353f 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -84,6 +84,22 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
switch (attr) {
/* common attributes */
+ case EGL_GL_COLORSPACE_KHR:
+ if (!dpy->Extensions.KHR_gl_colorspace) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ switch (val) {
+ case EGL_GL_COLORSPACE_SRGB_KHR:
+ case EGL_GL_COLORSPACE_LINEAR_KHR:
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ }
+ if (err != EGL_SUCCESS)
+ break;
+ surf->GLColorspace = val;
+ break;
case EGL_VG_COLORSPACE:
switch (val) {
case EGL_VG_COLORSPACE_sRGB:
@@ -272,6 +288,7 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
surf->RenderBuffer = renderBuffer;
surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
+ surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR;
surf->MipmapLevel = 0;
surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
@@ -352,6 +369,13 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
case EGL_VG_COLORSPACE:
*value = surface->VGColorspace;
break;
+ case EGL_GL_COLORSPACE_KHR:
+ if (!dpy->Extensions.KHR_gl_colorspace) {
+ _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
+ return EGL_FALSE;
+ }
+ *value = surface->GLColorspace;
+ break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
*value = surface->PostSubBufferSupportedNV;
break;
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 74c429a..fc799ee 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -65,6 +65,7 @@ struct _egl_surface
EGLenum RenderBuffer;
EGLenum VGAlphaFormat;
EGLenum VGColorspace;
+ EGLenum GLColorspace;
/* attributes set by eglSurfaceAttrib */
EGLint MipmapLevel;
--
2.1.0
More information about the mesa-dev
mailing list