From: Marek Olšák Date: Wed, 10 Jun 2015 00:49:29 +0000 (+0200) Subject: egl: implement EGL_KHR_gl_colorspace (v2) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c2c2e9ab604793c6e01f85497f3f5bf645f962fa;p=mesa.git egl: implement EGL_KHR_gl_colorspace (v2) v2: add missing "break" Reviewed-by: Emil Velikov --- diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 5600e8212d0..bec894c50dd 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 +#include #include #include #include @@ -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; @@ -204,6 +218,10 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, return NULL; break; + case __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE: + srgb = value != 0; + break; + default: key = dri2_to_egl_attribute_map[attrib]; if (key != 0) @@ -249,28 +267,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 f0cc6da1867..0dfbc752656 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 @@ -357,4 +359,8 @@ dri2_initialize_surfaceless(_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 fed3073088a..4abe82f63a0 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,9 +231,11 @@ 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, + (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config, dri2_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index 0d1f4c6e0a7..a439a3be6b6 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -131,10 +131,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 1e127607cdd..f4cb1857a37 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; @@ -162,10 +163,12 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, 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; diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index ad40bd57aa6..fecd36b3e7e 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -243,12 +243,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 cf65c69b7b4..c445d9b0c92 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 76c60e940dc..541353f9e0a 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 74c429a9628..fc799ee43dc 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;