st/egl: add premultiplied alpha support to wayland
authorChia-I Wu <olv@lunarg.com>
Wed, 7 Sep 2011 19:00:31 +0000 (03:00 +0800)
committerChia-I Wu <olv@lunarg.com>
Thu, 8 Sep 2011 03:16:12 +0000 (11:16 +0800)
Return true for NATIVE_PARAM_PREMULTIPLIED_ALPHA when all formats with
alpha support premultiplied alpha.  Currently, it means when argb32 and
argb32_pre are both supported.

src/gallium/state_trackers/egl/wayland/native_drm.c
src/gallium/state_trackers/egl/wayland/native_shm.c
src/gallium/state_trackers/egl/wayland/native_wayland.c
src/gallium/state_trackers/egl/wayland/native_wayland.h

index facab3218fb3ea11f438d322041340b1d798b1c8..e177e7cd6c9ae5e8510b6453950c758472b490b0 100644 (file)
@@ -114,8 +114,8 @@ wayland_create_drm_buffer(struct wayland_display *display,
 
    switch (surface->color_format) {
    case PIPE_FORMAT_B8G8R8A8_UNORM:
-      /* assume premultiplied */
-      format = WL_DRM_FORMAT_PREMULTIPLIED_ARGB32;
+      format = (surface->premultiplied_alpha) ?
+         WL_DRM_FORMAT_PREMULTIPLIED_ARGB32 : WL_DRM_FORMAT_ARGB32;
       break;
    case PIPE_FORMAT_B8G8R8X8_UNORM:
       format = WL_DRM_FORMAT_XRGB32;
@@ -255,6 +255,10 @@ wayland_drm_display_init_screen(struct native_display *ndpy)
    if (!wayland_drm_display_add_configs(drmdpy))
       return FALSE;
 
+   /* check that premultiplied alpha is supported for all formats with alpha */
+   if (!drmdpy->argb32 || drmdpy->argb32_pre)
+      drmdpy->base.param_premultiplied_alpha = TRUE;
+
    drmdpy->base.base.screen =
       drmdpy->event_handler->new_drm_screen(&drmdpy->base.base,
                                             NULL, drmdpy->fd);
index 5882e74c65310188dcb1b939d6599bf413a91b4e..e2d24379342b782a5839adc363138b7d957b70e2 100644 (file)
@@ -95,7 +95,8 @@ wayland_create_shm_buffer(struct wayland_display *display,
 
    switch (surface->color_format) {
    case PIPE_FORMAT_B8G8R8A8_UNORM:
-      format = WL_SHM_FORMAT_PREMULTIPLIED_ARGB32;
+      format = (surface->premultiplied_alpha) ?
+         WL_SHM_FORMAT_PREMULTIPLIED_ARGB32 : WL_SHM_FORMAT_ARGB32;
       break;
    case PIPE_FORMAT_B8G8R8X8_UNORM:
       format = WL_SHM_FORMAT_XRGB32;
@@ -165,6 +166,9 @@ wayland_shm_display_init_screen(struct native_display *ndpy)
    if (!wayland_shm_display_add_configs(shmdpy))
       return FALSE;
 
+   /* assume all formats are supported */
+   shmdpy->base.param_premultiplied_alpha = TRUE;
+
    winsys = wayland_create_sw_winsys(shmdpy->base.dpy);
    if (!winsys)
       return FALSE;
index 14cc908cf7a9209b8c9bbeb073b372c48439221f..b2dab8fae53a810bec3b5d03765d053cb3c9fb89 100644 (file)
@@ -60,9 +60,13 @@ static int
 wayland_display_get_param(struct native_display *ndpy,
                           enum native_param_type param)
 {
+   struct wayland_display *display = wayland_display(ndpy);
    int val;
 
    switch (param) {
+   case NATIVE_PARAM_PREMULTIPLIED_ALPHA:
+      val = display->param_premultiplied_alpha;
+      break;
    case NATIVE_PARAM_USE_NATIVE_BUFFER:
    case NATIVE_PARAM_PRESERVE_BUFFER:
    case NATIVE_PARAM_MAX_SWAP_INTERVAL:
@@ -283,6 +287,20 @@ wayland_surface_present(struct native_surface *nsurf,
    if (ctrl->preserve || ctrl->swap_interval)
       return FALSE;
 
+   /* force buffers to be re-created if they will be presented differently */
+   if (surface->premultiplied_alpha != ctrl->premultiplied_alpha) {
+      enum wayland_buffer_type buffer;
+
+      for (buffer = 0; buffer < WL_BUFFER_COUNT; ++buffer) {
+         if (surface->buffer[buffer]) {
+            wl_buffer_destroy(surface->buffer[buffer]);
+            surface->buffer[buffer] = NULL;
+         }
+      }
+
+      surface->premultiplied_alpha = ctrl->premultiplied_alpha;
+   }
+
    switch (ctrl->natt) {
    case NATIVE_ATTACHMENT_FRONT_LEFT:
       ret = TRUE;
index 93e670babeb2e9d9e0fbb9d47bcf6f4d90e02adb..6cf98a8e91c407b444d31e2860b1b77826e7955e 100644 (file)
@@ -44,6 +44,8 @@ struct wayland_display {
 
    struct wayland_config *configs;
    int num_configs;
+   /* true if all formats with alpha support premultiplied alpha */
+   boolean param_premultiplied_alpha;
 
    struct wl_buffer *(*create_buffer)(struct wayland_display *display,
                                       struct wayland_surface *surface,
@@ -79,6 +81,7 @@ struct wayland_surface {
    unsigned int attachment_mask;
 
    boolean block_swap_buffers;
+   boolean premultiplied_alpha;
 };
 
 struct wayland_config {