#define WL_HIDE_DEPRECATED
#include <stdint.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
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)
{
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;
return NULL;
break;
+ case __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE:
+ srgb = value != 0;
+ break;
+
default:
key = dri2_to_egl_attribute_map[attrib];
if (key != 0)
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);
_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
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 */
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) {
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,
+ (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config,
dri2_surf);
if (dri2_surf->dri_drawable == NULL) {
_eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
}
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);
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;
dri2_surf->base.Width = -1;
dri2_surf->base.Height = -1;
- dri2_surf->dri_drawable =
- (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
- dri2_conf->dri_double_config,
- dri2_surf);
+ 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, config,
+ dri2_surf);
if (dri2_surf->dri_drawable == NULL) {
_eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
goto cleanup_surf;
}
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 =
_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);
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:
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;
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;
EGLenum RenderBuffer;
EGLenum VGAlphaFormat;
EGLenum VGColorspace;
+ EGLenum GLColorspace;
/* attributes set by eglSurfaceAttrib */
EGLint MipmapLevel;