From 95b445699d7f049116ee0927387a958a9933766b Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 8 Sep 2011 02:29:55 +0800 Subject: [PATCH] st/egl: correctly return configs under wayland 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 ++++++++++- .../egl/wayland/native_wayland.c | 28 ++------ .../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 05c32f47734..facab3218fb 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 598df9fe2ce..5882e74c653 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); @@ -110,6 +110,40 @@ wayland_create_shm_buffer(struct wayland_display *display, wsh.stride, format); } +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) { @@ -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 29c9b46d612..14cc908cf7a 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 5390f2f08c9..93e670babeb 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); -- 2.30.2