st/egl: overload NATIVE_PARAM_PREMULTIPLIED_ALPHA
authorChia-I Wu <olv@lunarg.com>
Wed, 7 Sep 2011 18:39:01 +0000 (02:39 +0800)
committerChia-I Wu <olv@lunarg.com>
Thu, 8 Sep 2011 03:16:12 +0000 (11:16 +0800)
EGL does not export this capability of a display server.  But wayland
makes use of EGL_VG_ALPHA_FORMAT to achieve it.

So, when the native display returns true for the parameter, st/egl will
set EGL_VG_ALPHA_FORMAT_PRE_BIT for all EGLConfig's with non-zero
EGL_ALPHA_SIZE.  EGL_VG_ALPHA_FORMAT attribute of a surface will affect
how the surface is presented.

Because st/vega does not support EGL_VG_ALPHA_FORMAT_PRE_BIT,
EGL_OPENVG_BIT will be cleared.

src/gallium/state_trackers/egl/common/egl_g3d.c
src/gallium/state_trackers/egl/common/egl_g3d_api.c
src/gallium/state_trackers/egl/common/native.h

index b5e3d99b81169bdda03f621a265adbf239a34911..1023849ed024825075c33017ba12255206c1efe3 100644 (file)
@@ -220,7 +220,8 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
 static EGLBoolean
 init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
                        EGLint api_mask, enum pipe_format depth_stencil_format,
-                       EGLBoolean preserve_buffer, EGLint max_swap_interval)
+                       EGLint preserve_buffer, EGLint max_swap_interval,
+                       EGLBoolean pre_alpha)
 {
    uint rgba[4], depth_stencil[2], buffer_size;
    EGLint surface_type;
@@ -262,6 +263,15 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
       surface_type |= EGL_PBUFFER_BIT;
    }
 
+   if (preserve_buffer)
+      surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+
+   if (pre_alpha && rgba[3]) {
+      surface_type |= EGL_VG_ALPHA_FORMAT_PRE_BIT;
+      /* st/vega does not support premultiplied alpha yet */
+      api_mask &= ~EGL_OPENVG_BIT;
+   }
+
    conf->Conformant = api_mask;
    conf->RenderableType = api_mask;
 
@@ -307,8 +317,6 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
 
    conf->MinSwapInterval = 0;
    conf->MaxSwapInterval = max_swap_interval;
-   if (preserve_buffer)
-      conf->SurfaceType |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
 
    return _eglValidateConfig(conf, EGL_FALSE);
 }
@@ -320,7 +328,8 @@ static EGLBoolean
 egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
                     _EGLConfig *conf, const struct native_config *nconf,
                     enum pipe_format depth_stencil_format,
-                    int preserve_buffer, int max_swap_interval)
+                    int preserve_buffer, int max_swap_interval,
+                    int pre_alpha)
 {
    struct egl_g3d_config *gconf = egl_g3d_config(conf);
    EGLint buffer_mask;
@@ -348,7 +357,7 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
 
    valid = init_config_attributes(&gconf->base,
          nconf, dpy->ClientAPIs, depth_stencil_format,
-         preserve_buffer, max_swap_interval);
+         preserve_buffer, max_swap_interval, pre_alpha);
    if (!valid) {
       _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id);
       return EGL_FALSE;
@@ -409,7 +418,7 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
    const struct native_config **native_configs;
    enum pipe_format depth_stencil_formats[8];
    int num_formats, num_configs, i, j;
-   int preserve_buffer, max_swap_interval;
+   int preserve_buffer, max_swap_interval, premultiplied_alpha;
 
    native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
    if (!num_configs) {
@@ -422,6 +431,8 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
       gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER);
    max_swap_interval =
       gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL);
+   premultiplied_alpha =
+      gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PREMULTIPLIED_ALPHA);
 
    num_formats = egl_g3d_fill_depth_stencil_formats(dpy,
          depth_stencil_formats);
@@ -435,7 +446,8 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
             _eglInitConfig(&gconf->base, dpy, id);
             if (!egl_g3d_init_config(drv, dpy, &gconf->base,
                      native_configs[i], depth_stencil_formats[j],
-                     preserve_buffer, max_swap_interval)) {
+                     preserve_buffer, max_swap_interval,
+                     premultiplied_alpha)) {
                FREE(gconf);
                break;
             }
index 27bc8be4e48d32016fe40723befc252a82e4f7b7..911540e83f278c1ed404f67d9030e433c5286da6 100644 (file)
@@ -574,6 +574,7 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
    ctrl.natt = NATIVE_ATTACHMENT_BACK_LEFT;
    ctrl.preserve = (gsurf->base.SwapBehavior == EGL_BUFFER_PRESERVED);
    ctrl.swap_interval = gsurf->base.SwapInterval;
+   ctrl.premultiplied_alpha = (gsurf->base.VGAlphaFormat == EGL_VG_ALPHA_FORMAT_PRE);
 
    return gsurf->native->present(gsurf->native, &ctrl);
 }
index c85aedfa5e1165f04c20399650165d6770a66f83..3b77cba073bec0e947c998db9b4ed7ea8e442753 100644 (file)
@@ -75,6 +75,11 @@ enum native_param_type {
    /**
     * Return TRUE if the display supports premultiplied alpha, regardless of
     * the surface color format.
+    *
+    * Note that returning TRUE for this parameter will make
+    * EGL_VG_ALPHA_FORMAT_PRE_BIT to be set for all EGLConfig's with non-zero
+    * EGL_ALPHA_SIZE.  EGL_VG_ALPHA_FORMAT attribute of a surface will affect
+    * how the surface is presented.
     */
    NATIVE_PARAM_PREMULTIPLIED_ALPHA
 };