First thanks for taking this on.

There are some things I'd like to have addtionally/differently:

Supported shm formats are exposed via a "format" event as well
(like the supported drm formats), so the config creation logic is the
same for drm and shm, and I think it can remain in native_wayland.c

We need roundtrips to check that we get at least one supported format.

I've attached two patches (heavily based on your last two) that do this,
are you ok with using them?

2011/9/8 Chia-I Wu <olva...@gmail.com>:
> From: Chia-I Wu <o...@lunarg.com>
>
> When wl_drm is avaiable and enabled, handle "format" events and return
> configs for the supported formats.  Otherwise, assume all formats of
> wl_shm are supported.
> ---
>  .../state_trackers/egl/wayland/native_drm.c        |   70 
> +++++++++++++++++++-
>  .../state_trackers/egl/wayland/native_shm.c        |   41 +++++++++++-
>  .../state_trackers/egl/wayland/native_wayland.c    |   28 +-------
>  .../state_trackers/egl/wayland/native_wayland.h    |    4 +-
>  4 files changed, 113 insertions(+), 30 deletions(-)
>
> diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c 
> b/src/gallium/state_trackers/egl/wayland/native_drm.c
> index 05c32f4..facab32 100644
> --- a/src/gallium/state_trackers/egl/wayland/native_drm.c
> +++ b/src/gallium/state_trackers/egl/wayland/native_drm.c
> @@ -58,6 +58,11 @@ struct wayland_drm_display {
>    int fd;
>    char *device_name;
>    boolean authenticated;
> +
> +   /* supported formats */
> +   boolean argb32;
> +   boolean argb32_pre;
> +   boolean xrgb32;
>  };
>
>  static INLINE struct wayland_drm_display *
> @@ -77,8 +82,8 @@ wayland_drm_display_destroy(struct native_display *ndpy)
>       wl_drm_destroy(drmdpy->wl_drm);
>    if (drmdpy->device_name)
>       FREE(drmdpy->device_name);
> -   if (drmdpy->base.config)
> -      FREE(drmdpy->base.config);
> +   if (drmdpy->base.configs)
> +      FREE(drmdpy->base.configs);
>    if (drmdpy->base.own_dpy)
>       wl_display_destroy(drmdpy->base.dpy);
>
> @@ -124,6 +129,50 @@ wayland_create_drm_buffer(struct wayland_display 
> *display,
>                                width, height, wsh.stride, format);
>  }
>
> +static boolean
> +wayland_drm_display_add_configs(struct wayland_drm_display *drmdpy)
> +{
> +   struct wayland_config *configs;
> +   enum pipe_format formats[2];
> +   int i, num_formats = 0;
> +
> +   /*
> +    * Only argb32 counts here.  If we make (!argbb32 && argb32_pre) count, we
> +    * will not be able to support the case where
> +    * native_present_control::premultiplied_alpha is FALSE.
> +    */
> +   if (drmdpy->argb32)
> +      formats[num_formats++] = PIPE_FORMAT_B8G8R8A8_UNORM;
> +
> +   if (drmdpy->xrgb32)
> +      formats[num_formats++] = PIPE_FORMAT_B8G8R8X8_UNORM;
> +
> +   if (!num_formats)
> +      return FALSE;
> +
> +   configs = CALLOC(num_formats, sizeof(*configs));
> +   if (!configs)
> +      return FALSE;
> +
> +   for (i = 0; i < num_formats; i++) {
> +      struct native_config *nconf = &configs[i].base;
> +
> +      nconf->buffer_mask =
> +         (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
> +         (1 << NATIVE_ATTACHMENT_BACK_LEFT);
> +
> +      nconf->color_format = formats[i];
> +
> +      nconf->window_bit = TRUE;
> +      nconf->pixmap_bit = TRUE;
> +   }
> +
> +   drmdpy->base.configs = configs;
> +   drmdpy->base.num_configs = num_formats;
> +
> +   return TRUE;
> +}
> +
>  static void
>  drm_handle_device(void *data, struct wl_drm *drm, const char *device)
>  {
> @@ -148,7 +197,19 @@ drm_handle_device(void *data, struct wl_drm *drm, const 
> char *device)
>  static void
>  drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
>  {
> -   /* TODO */
> +   struct wayland_drm_display *drmdpy = data;
> +
> +   switch (format) {
> +   case WL_DRM_FORMAT_ARGB32:
> +      drmdpy->argb32 = TRUE;
> +      break;
> +   case WL_DRM_FORMAT_PREMULTIPLIED_ARGB32:
> +      drmdpy->argb32_pre = TRUE;
> +      break;
> +   case WL_DRM_FORMAT_XRGB32:
> +      drmdpy->xrgb32 = TRUE;
> +      break;
> +   }
>  }
>
>  static void
> @@ -191,6 +252,9 @@ wayland_drm_display_init_screen(struct native_display 
> *ndpy)
>    if (!drmdpy->authenticated)
>       return FALSE;
>
> +   if (!wayland_drm_display_add_configs(drmdpy))
> +      return FALSE;
> +
>    drmdpy->base.base.screen =
>       drmdpy->event_handler->new_drm_screen(&drmdpy->base.base,
>                                             NULL, drmdpy->fd);
> diff --git a/src/gallium/state_trackers/egl/wayland/native_shm.c 
> b/src/gallium/state_trackers/egl/wayland/native_shm.c
> index 598df9f..5882e74 100644
> --- a/src/gallium/state_trackers/egl/wayland/native_shm.c
> +++ b/src/gallium/state_trackers/egl/wayland/native_shm.c
> @@ -63,8 +63,8 @@ wayland_shm_display_destroy(struct native_display *ndpy)
>  {
>    struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy);
>
> -   if (shmdpy->base.config)
> -      FREE(shmdpy->base.config);
> +   if (shmdpy->base.configs)
> +      FREE(shmdpy->base.configs);
>    if (shmdpy->base.own_dpy)
>       wl_display_destroy(shmdpy->base.dpy);
>
> @@ -111,6 +111,40 @@ wayland_create_shm_buffer(struct wayland_display 
> *display,
>  }
>
>  static boolean
> +wayland_shm_display_add_configs(struct wayland_shm_display *shmdpy)
> +{
> +   struct wayland_config *configs;
> +   enum pipe_format formats[2];
> +   int i, num_formats = 0;
> +
> +   /* assume all formats are supported */
> +   formats[num_formats++] = PIPE_FORMAT_B8G8R8A8_UNORM;
> +   formats[num_formats++] = PIPE_FORMAT_B8G8R8X8_UNORM;
> +
> +   configs = CALLOC(num_formats, sizeof(*configs));
> +   if (!configs)
> +      return FALSE;
> +
> +   for (i = 0; i < num_formats; i++) {
> +      struct native_config *nconf = &configs[i].base;
> +
> +      nconf->buffer_mask =
> +         (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
> +         (1 << NATIVE_ATTACHMENT_BACK_LEFT);
> +
> +      nconf->color_format = formats[i];
> +
> +      nconf->window_bit = TRUE;
> +      nconf->pixmap_bit = TRUE;
> +   }
> +
> +   shmdpy->base.configs = configs;
> +   shmdpy->base.num_configs = num_formats;
> +
> +   return TRUE;
> +}
> +
> +static boolean
>  wayland_shm_display_init_screen(struct native_display *ndpy)
>  {
>    struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy);
> @@ -128,6 +162,9 @@ wayland_shm_display_init_screen(struct native_display 
> *ndpy)
>    if (!shmdpy->wl_shm)
>       return FALSE;
>
> +   if (!wayland_shm_display_add_configs(shmdpy))
> +      return FALSE;
> +
>    winsys = wayland_create_sw_winsys(shmdpy->base.dpy);
>    if (!winsys)
>       return FALSE;
> diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c 
> b/src/gallium/state_trackers/egl/wayland/native_wayland.c
> index 29c9b46..14cc908 100644
> --- a/src/gallium/state_trackers/egl/wayland/native_wayland.c
> +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c
> @@ -44,31 +44,11 @@ wayland_display_get_configs (struct native_display *ndpy, 
> int *num_configs)
>    const struct native_config **configs;
>    int i;
>
> -   if (!display->config) {
> -      struct native_config *nconf;
> -      display->config = CALLOC(2, sizeof(*display->config));
> -      if (!display->config)
> -         return NULL;
> -
> -      for (i = 0; i < 2; ++i) {
> -         nconf = &display->config[i].base;
> -
> -         nconf->buffer_mask =
> -            (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
> -            (1 << NATIVE_ATTACHMENT_BACK_LEFT);
> -
> -         nconf->window_bit = TRUE;
> -         nconf->pixmap_bit = TRUE;
> -      }
> -
> -      display->config[0].base.color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
> -      display->config[1].base.color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
> -   }
> -
> -   configs = MALLOC(2 * sizeof(*configs));
> +   configs = MALLOC(display->num_configs * sizeof(*configs));
>    if (configs) {
> -      configs[0] = &display->config[0].base;
> -      configs[1] = &display->config[1].base;
> +      for (i = 0; i < display->num_configs; i++) {
> +         configs[i] = &display->configs[i].base;
> +      }
>       if (num_configs)
>          *num_configs = 2;
>    }
> diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h 
> b/src/gallium/state_trackers/egl/wayland/native_wayland.h
> index 5390f2f..93e670b 100644
> --- a/src/gallium/state_trackers/egl/wayland/native_wayland.h
> +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h
> @@ -39,10 +39,12 @@ struct wayland_surface;
>  struct wayland_display {
>    struct native_display base;
>
> -   struct wayland_config *config;
>    struct wl_display *dpy;
>    boolean own_dpy;
>
> +   struct wayland_config *configs;
> +   int num_configs;
> +
>    struct wl_buffer *(*create_buffer)(struct wayland_display *display,
>                                       struct wayland_surface *surface,
>                                       enum native_attachment attachment);
> --
> 1.7.5.4
>
>
From b903cf0b74038e932404214afb658cb6e20b0238 Mon Sep 17 00:00:00 2001
From: Benjamin Franzke <benjaminfran...@googlemail.com>
Date: Thu, 8 Sep 2011 08:03:34 +0200
Subject: [PATCH 1/2] st/egl: correctly return configs under wayland

Handle "format" events and return configs for the supported formats.

(Based on Chia-I Wu's patch)
---
 .../state_trackers/egl/wayland/native_drm.c        |   25 ++++++++++--
 .../state_trackers/egl/wayland/native_shm.c        |   37 ++++++++++++++++--
 .../state_trackers/egl/wayland/native_wayland.c    |   41 +++++++++++++-------
 .../state_trackers/egl/wayland/native_wayland.h    |   12 +++++-
 4 files changed, 92 insertions(+), 23 deletions(-)

diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c
index 05c32f4..9f6757b 100644
--- a/src/gallium/state_trackers/egl/wayland/native_drm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_drm.c
@@ -77,8 +77,8 @@ wayland_drm_display_destroy(struct native_display *ndpy)
       wl_drm_destroy(drmdpy->wl_drm);
    if (drmdpy->device_name)
       FREE(drmdpy->device_name);
-   if (drmdpy->base.config)
-      FREE(drmdpy->base.config);
+   if (drmdpy->base.configs)
+      FREE(drmdpy->base.configs);
    if (drmdpy->base.own_dpy)
       wl_display_destroy(drmdpy->base.dpy);
 
@@ -97,7 +97,7 @@ wayland_create_drm_buffer(struct wayland_display *display,
    struct pipe_resource *resource;
    struct winsys_handle wsh;
    uint width, height;
-   uint32_t format;
+   enum wl_drm_format format;
 
    resource = resource_surface_get_single_resource(surface->rsurf, attachment);
    resource_surface_get_size(surface->rsurf, &width, &height);
@@ -148,7 +148,19 @@ drm_handle_device(void *data, struct wl_drm *drm, const char *device)
 static void
 drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
 {
-   /* TODO */
+   struct wayland_drm_display *drmdpy = data;
+
+   switch (format) {
+   case WL_DRM_FORMAT_ARGB32:
+      drmdpy->base.formats |= HAS_ARGB32;
+      break;
+   case WL_DRM_FORMAT_PREMULTIPLIED_ARGB32:
+      drmdpy->base.formats |= HAS_PREMUL_ARGB32;
+      break;
+   case WL_DRM_FORMAT_XRGB32:
+      drmdpy->base.formats |= HAS_XRGB32;
+      break;
+   }
 }
 
 static void
@@ -191,6 +203,11 @@ wayland_drm_display_init_screen(struct native_display *ndpy)
    if (!drmdpy->authenticated)
       return FALSE;
 
+   if (drmdpy->base.formats == 0)
+      wl_display_roundtrip(drmdpy->base.dpy);
+   if (drmdpy->base.formats == 0)
+      return FALSE;
+
    drmdpy->base.base.screen =
       drmdpy->event_handler->new_drm_screen(&drmdpy->base.base,
                                             NULL, drmdpy->fd);
diff --git a/src/gallium/state_trackers/egl/wayland/native_shm.c b/src/gallium/state_trackers/egl/wayland/native_shm.c
index 598df9f..8a50915 100644
--- a/src/gallium/state_trackers/egl/wayland/native_shm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_shm.c
@@ -63,8 +63,8 @@ wayland_shm_display_destroy(struct native_display *ndpy)
 {
    struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy);
 
-   if (shmdpy->base.config)
-      FREE(shmdpy->base.config);
+   if (shmdpy->base.configs)
+      FREE(shmdpy->base.configs);
    if (shmdpy->base.own_dpy)
       wl_display_destroy(shmdpy->base.dpy);
 
@@ -73,7 +73,6 @@ wayland_shm_display_destroy(struct native_display *ndpy)
    FREE(shmdpy);
 }
 
-
 static struct wl_buffer *
 wayland_create_shm_buffer(struct wayland_display *display,
                           struct wayland_surface *surface,
@@ -84,7 +83,7 @@ wayland_create_shm_buffer(struct wayland_display *display,
    struct pipe_resource *resource;
    struct winsys_handle wsh;
    uint width, height;
-   uint32_t format;
+   enum wl_shm_format format;
 
    resource = resource_surface_get_single_resource(surface->rsurf, attachment);
    resource_surface_get_size(surface->rsurf, &width, &height);
@@ -95,6 +94,7 @@ wayland_create_shm_buffer(struct wayland_display *display,
 
    switch (surface->color_format) {
    case PIPE_FORMAT_B8G8R8A8_UNORM:
+      /* assume premultiplied */
       format = WL_SHM_FORMAT_PREMULTIPLIED_ARGB32;
       break;
    case PIPE_FORMAT_B8G8R8X8_UNORM:
@@ -110,6 +110,28 @@ wayland_create_shm_buffer(struct wayland_display *display,
                                wsh.stride, format);
 }
 
+static void
+shm_handle_format(void *data, struct wl_shm *shm, uint32_t format)
+{
+   struct wayland_shm_display *shmdpy = data;
+
+   switch (format) {
+   case WL_SHM_FORMAT_ARGB32:
+      shmdpy->base.formats |= HAS_ARGB32;
+      break;
+   case WL_SHM_FORMAT_PREMULTIPLIED_ARGB32:
+      shmdpy->base.formats |= HAS_PREMUL_ARGB32;
+      break;
+   case WL_SHM_FORMAT_XRGB32:
+      shmdpy->base.formats |= HAS_XRGB32;
+      break;
+   }
+}
+
+static const struct wl_shm_listener shm_listener = {
+   shm_handle_format
+};
+
 static boolean
 wayland_shm_display_init_screen(struct native_display *ndpy)
 {
@@ -128,6 +150,13 @@ wayland_shm_display_init_screen(struct native_display *ndpy)
    if (!shmdpy->wl_shm)
       return FALSE;
 
+   wl_shm_add_listener(shmdpy->wl_shm, &shm_listener, shmdpy);
+
+   if (shmdpy->base.formats == 0)
+      wl_display_roundtrip(shmdpy->base.dpy);
+   if (shmdpy->base.formats == 0)
+      return FALSE;
+
    winsys = wayland_create_sw_winsys(shmdpy->base.dpy);
    if (!winsys)
       return FALSE;
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c
index 29c9b46..f341ec8 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.c
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c
@@ -37,40 +37,53 @@
 
 static const struct native_event_handler *wayland_event_handler;
 
+const static struct {
+   enum pipe_format format;
+   enum wayland_format_flag flag;
+} wayland_formats[] = {
+   { PIPE_FORMAT_B8G8R8A8_UNORM, HAS_ARGB32 | HAS_PREMUL_ARGB32 },
+   { PIPE_FORMAT_B8G8R8X8_UNORM, HAS_XRGB32 },
+};
+
 static const struct native_config **
-wayland_display_get_configs (struct native_display *ndpy, int *num_configs)
+wayland_display_get_configs(struct native_display *ndpy, int *num_configs)
 {
    struct wayland_display *display = wayland_display(ndpy);
    const struct native_config **configs;
    int i;
 
-   if (!display->config) {
+   if (!display->configs) {
       struct native_config *nconf;
-      display->config = CALLOC(2, sizeof(*display->config));
-      if (!display->config)
+
+      display->num_configs = 0;
+      display->configs = CALLOC(Elements(wayland_formats),
+                                sizeof(*display->configs));
+      if (!display->configs)
          return NULL;
 
-      for (i = 0; i < 2; ++i) {
-         nconf = &display->config[i].base;
-         
+      for (i = 0; i < Elements(wayland_formats); ++i) {
+         if (!(display->formats & wayland_formats[i].flag))
+            continue;
+
+         nconf = &display->configs[display->num_configs].base;
          nconf->buffer_mask =
             (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
             (1 << NATIVE_ATTACHMENT_BACK_LEFT);
          
          nconf->window_bit = TRUE;
          nconf->pixmap_bit = TRUE;
+         
+         nconf->color_format = wayland_formats[i].format;
+         display->num_configs++;
       }
-
-      display->config[0].base.color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
-      display->config[1].base.color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
    }
 
-   configs = MALLOC(2 * sizeof(*configs));
+   configs = MALLOC(display->num_configs * sizeof(*configs));
    if (configs) {
-      configs[0] = &display->config[0].base;
-      configs[1] = &display->config[1].base;
+      for (i = 0; i < display->num_configs; ++i)
+         configs[i] = &display->configs[i].base;
       if (num_configs)
-         *num_configs = 2;
+         *num_configs = display->num_configs;
    }
 
    return configs;
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h
index 5390f2f..0350a95 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.h
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h
@@ -36,12 +36,22 @@
 
 struct wayland_surface;
 
+enum wayland_format_flag {
+   HAS_ARGB32        = (1 << 0),
+   HAS_PREMUL_ARGB32 = (1 << 1),
+   HAS_XRGB32        = (1 << 2)
+};
+
 struct wayland_display {
    struct native_display base;
 
-   struct wayland_config *config;
    struct wl_display *dpy;
    boolean own_dpy;
+   /* supported formats */
+   uint32_t formats;
+
+   struct wayland_config *configs;
+   int num_configs;
 
    struct wl_buffer *(*create_buffer)(struct wayland_display *display,
                                       struct wayland_surface *surface,
-- 
1.7.3.4

From 902b8b0ed6dc9ed3a7c6dee5120e55d794569449 Mon Sep 17 00:00:00 2001
From: Benjamin Franzke <benjaminfran...@googlemail.com>
Date: Thu, 8 Sep 2011 08:01:46 +0200
Subject: [PATCH 2/2] st/egl: add premultiplied alpha support to wayland

Return true for NATIVE_PARAM_PREMULTIPLIED_ALPHA when all formats with
alpha support premultiplied alpha.

(Based on Chia-I Wu's patch)
---
 .../state_trackers/egl/wayland/native_drm.c        |    7 +++++--
 .../state_trackers/egl/wayland/native_shm.c        |    7 +++++--
 .../state_trackers/egl/wayland/native_wayland.c    |   18 ++++++++++++++++++
 .../state_trackers/egl/wayland/native_wayland.h    |    3 +++
 4 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c
index 9f6757b..6d19596 100644
--- a/src/gallium/state_trackers/egl/wayland/native_drm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_drm.c
@@ -109,8 +109,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;
@@ -208,6 +208,9 @@ wayland_drm_display_init_screen(struct native_display *ndpy)
    if (drmdpy->base.formats == 0)
       return FALSE;
 
+   if (drmdpy->base.formats & HAS_ARGB32)
+      drmdpy->base.param_premultiplied_alpha = TRUE;
+
    drmdpy->base.base.screen =
       drmdpy->event_handler->new_drm_screen(&drmdpy->base.base,
                                             NULL, drmdpy->fd);
diff --git a/src/gallium/state_trackers/egl/wayland/native_shm.c b/src/gallium/state_trackers/egl/wayland/native_shm.c
index 8a50915..80a4c9b 100644
--- a/src/gallium/state_trackers/egl/wayland/native_shm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_shm.c
@@ -94,8 +94,8 @@ wayland_create_shm_buffer(struct wayland_display *display,
 
    switch (surface->color_format) {
    case PIPE_FORMAT_B8G8R8A8_UNORM:
-      /* assume premultiplied */
-      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;
@@ -157,6 +157,9 @@ wayland_shm_display_init_screen(struct native_display *ndpy)
    if (shmdpy->base.formats == 0)
       return FALSE;
 
+   if (shmdpy->base.formats & HAS_ARGB32)
+      shmdpy->base.param_premultiplied_alpha = TRUE;
+
    winsys = wayland_create_sw_winsys(shmdpy->base.dpy);
    if (!winsys)
       return FALSE;
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c
index f341ec8..db4ccd1 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.c
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c
@@ -93,9 +93,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:
@@ -316,6 +320,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;
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h
index 0350a95..76db3da 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.h
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h
@@ -52,6 +52,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,
@@ -87,6 +89,7 @@ struct wayland_surface {
    unsigned int attachment_mask;
 
    boolean block_swap_buffers;
+   boolean premultiplied_alpha;
 };
 
 struct wayland_config {
-- 
1.7.3.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to