summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2015-02-16 17:10:28 +0100
committerJonny Lamb <jonny.lamb@collabora.co.uk>2015-07-20 09:48:27 +0200
commit05655d4b096cca89e99e41c0afb19b5e48d11248 (patch)
treeb645082b792ed6f44817e4168e5c62a2baae6854
parenta68cf17ce970b1e36dc9e426fcdb68b0e9b2af98 (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.h5
-rw-r--r--src/egl/drivers/dri2/platform_wayland.c21
-rw-r--r--src/egl/drivers/dri2/platform_x11.c23
-rw-r--r--src/egl/main/eglapi.c10
-rw-r--r--src/egl/main/eglconfig.c12
-rw-r--r--src/egl/main/egldisplay.h1
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;