diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2015-02-16 17:10:28 +0100 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2015-07-20 09:48:27 +0200 |
commit | 05655d4b096cca89e99e41c0afb19b5e48d11248 (patch) | |
tree | b645082b792ed6f44817e4168e5c62a2baae6854 | |
parent | a68cf17ce970b1e36dc9e426fcdb68b0e9b2af98 (diff) |
egl: implement EGL_MESA_transparent_alpha for x11 and waylandegl-transparency
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67676
-rw-r--r-- | include/EGL/eglmesaext.h | 5 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_wayland.c | 21 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_x11.c | 23 | ||||
-rw-r--r-- | src/egl/main/eglapi.c | 10 | ||||
-rw-r--r-- | src/egl/main/eglconfig.c | 12 | ||||
-rw-r--r-- | src/egl/main/egldisplay.h | 1 |
6 files changed, 55 insertions, 17 deletions
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h index 917a2043c7..866be76688 100644 --- a/include/EGL/eglmesaext.h +++ b/include/EGL/eglmesaext.h @@ -95,6 +95,11 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG #define EGL_NO_CONFIG_MESA ((EGLConfig)0) #endif +#ifndef EGL_MESA_transparent_alpha +#define EGL_MESA_transparent_alpha 1 +#define EGL_TRANSPARENT_ALPHA_MESA 0x31D9 +#endif + #ifdef __cplusplus } #endif diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 1e127607cd..64fd51cb12 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -144,7 +144,7 @@ dri2_wl_create_surface(_EGLDriver *drv, _EGLDisplay *disp, if (conf->RedSize == 5) dri2_surf->format = WL_DRM_FORMAT_RGB565; - else if (conf->AlphaSize == 0) + else if (conf->AlphaSize == 0 || conf->TransparentType == EGL_NONE) dri2_surf->format = WL_DRM_FORMAT_XRGB8888; else dri2_surf->format = WL_DRM_FORMAT_ARGB8888; @@ -1054,11 +1054,15 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp) struct dri2_egl_display *dri2_dpy; const __DRIconfig *config; uint32_t types; - int i; + int i, j; static const unsigned int argb_masks[4] = { 0xff0000, 0xff00, 0xff, 0xff000000 }; static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 }; static const unsigned int rgb565_masks[4] = { 0xf800, 0x07e0, 0x001f, 0 }; + static const EGLint argb_attrs[] = { + EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_ALPHA_MESA, + EGL_NONE + }; loader_set_logger(_eglLog); @@ -1175,14 +1179,16 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp) } types = EGL_WINDOW_BIT; - for (i = 0; dri2_dpy->driver_configs[i]; i++) { + for (i = 0, j = 1; dri2_dpy->driver_configs[i]; i++) { config = dri2_dpy->driver_configs[i]; if (dri2_dpy->formats & HAS_XRGB8888) - dri2_add_config(disp, config, i + 1, types, NULL, rgb_masks); - if (dri2_dpy->formats & HAS_ARGB8888) - dri2_add_config(disp, config, i + 1, types, NULL, argb_masks); + dri2_add_config(disp, config, j++, types, NULL, rgb_masks); + if (dri2_dpy->formats & HAS_ARGB8888) { + dri2_add_config(disp, config, j++, types, argb_attrs, argb_masks); + dri2_add_config(disp, config, j++, types, NULL, argb_masks); + } if (dri2_dpy->formats & HAS_RGB565) - dri2_add_config(disp, config, i + 1, types, NULL, rgb565_masks); + dri2_add_config(disp, config, j++, types, NULL, rgb565_masks); } disp->Extensions.WL_bind_wayland_display = EGL_TRUE; @@ -1197,6 +1203,7 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp) dri2_fallback_create_wayland_buffer_from_image; } disp->Extensions.EXT_buffer_age = EGL_TRUE; + disp->Extensions.MESA_transparent_alpha = EGL_TRUE; disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE; diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index ad40bd57aa..e7f332849e 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -698,18 +698,22 @@ dri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy, dri2_add_config(disp, dri2_dpy->driver_configs[j], id++, surface_type, config_attrs, rgba_masks); - /* Allow a 24-bit RGB visual to match a 32-bit RGBA EGLConfig. - * Otherwise it will only match a 32-bit RGBA visual. On a - * composited window manager on X11, this will make all of the - * EGLConfigs with destination alpha get blended by the - * compositor. This is probably not what the application - * wants... especially on drivers that only have 32-bit RGBA - * EGLConfigs! */ + rgba_masks[3] = + ~(rgba_masks[0] | rgba_masks[1] | rgba_masks[2]); + if (d.data->depth == 24) { - rgba_masks[3] = - ~(rgba_masks[0] | rgba_masks[1] | rgba_masks[2]); dri2_add_config(disp, dri2_dpy->driver_configs[j], id++, surface_type, config_attrs, rgba_masks); + } else if (d.data->depth == 32) { + EGLint rgba_attrs[] = { + EGL_NATIVE_VISUAL_ID, config_attrs[1], + EGL_NATIVE_VISUAL_TYPE, config_attrs[3], + EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_ALPHA_MESA, + EGL_NONE + }; + + dri2_add_config(disp, dri2_dpy->driver_configs[j], id++, + surface_type, rgba_attrs, rgba_masks); } } } @@ -1280,6 +1284,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE; disp->Extensions.NV_post_sub_buffer = EGL_TRUE; disp->Extensions.CHROMIUM_sync_control = EGL_TRUE; + disp->Extensions.MESA_transparent_alpha = EGL_TRUE; #ifdef HAVE_WAYLAND_PLATFORM disp->Extensions.WL_bind_wayland_display = EGL_TRUE; diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 824e51ea55..896f69e3dd 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -809,6 +809,10 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config, EGLSurface ret; _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); + + if (conf->TransparentType == EGL_TRANSPARENT_ALPHA_MESA) + RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE); + surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap, attrib_list); ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; @@ -882,6 +886,9 @@ eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); + if (conf->TransparentType == EGL_TRANSPARENT_ALPHA_MESA) + RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE); + surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list); ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; @@ -1275,6 +1282,9 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); + if (conf->TransparentType == EGL_TRANSPARENT_ALPHA_MESA) + RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE); + surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer, conf, attrib_list); ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index cf65c69b7b..c7830fb743 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -301,7 +301,8 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) valid = EGL_FALSE; break; case EGL_TRANSPARENT_TYPE: - if (val != EGL_NONE && val != EGL_TRANSPARENT_RGB) + if (val != EGL_NONE && val != EGL_TRANSPARENT_RGB && + val != EGL_TRANSPARENT_ALPHA_MESA) valid = EGL_FALSE; break; case EGL_COLOR_BUFFER_TYPE: @@ -367,6 +368,15 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) } } + /* an initial check for conflicting attribute values, required when + * for_matching is true */ + + if (conf->TransparentType == EGL_TRANSPARENT_ALPHA_MESA && + conf->AlphaSize == 0) { + _eglLog(_EGL_DEBUG, "conflicting transparent type and alpha size values"); + return EGL_FALSE; + } + /* any invalid attribute value should have been catched */ if (!valid || for_matching) return valid; diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 8d3393564b..5ddf3fb5f6 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -121,6 +121,7 @@ struct _egl_extensions EGLBoolean MESA_drm_display; EGLBoolean MESA_drm_image; EGLBoolean MESA_image_dma_buf_export; + EGLBoolean MESA_transparent_alpha; EGLBoolean NOK_swap_region; EGLBoolean NOK_texture_from_pixmap; |