diff options
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 18 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.h | 2 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_wayland.c | 66 | ||||
-rw-r--r-- | src/egl/wayland/wayland-drm/protocol/wayland-drm.xml | 14 | ||||
-rw-r--r-- | src/egl/wayland/wayland-drm/wayland-drm.c | 34 | ||||
-rw-r--r-- | src/egl/wayland/wayland-drm/wayland-drm.h | 3 | ||||
-rw-r--r-- | src/egl/wayland/wayland-egl/wayland-egl-priv.h | 2 | ||||
-rw-r--r-- | src/egl/wayland/wayland-egl/wayland-egl.c | 8 |
8 files changed, 108 insertions, 39 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 6c1c17d4357..44c9bc18d66 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -1249,16 +1249,28 @@ dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, static void * dri2_wl_reference_buffer(void *user_data, uint32_t name, int32_t width, int32_t height, - uint32_t stride, struct wl_visual *visual) + uint32_t stride, uint32_t format) { _EGLDisplay *disp = user_data; struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); __DRIimage *image; + int dri_format; + + switch (format) { + case WL_DRM_FORMAT_ARGB32: + case WL_DRM_FORMAT_PREMULTIPLIED_ARGB32: + dri_format =__DRI_IMAGE_FORMAT_ARGB8888; + break; + case WL_DRM_FORMAT_XRGB32: + dri_format = __DRI_IMAGE_FORMAT_XRGB8888; + break; + default: + return NULL; + } image = dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, width, height, - __DRI_IMAGE_FORMAT_ARGB8888, - name, stride / 4, + dri_format, name, stride / 4, NULL); return image; diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 55b1256f6be..1c2c7fe5a64 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -113,6 +113,7 @@ struct dri2_egl_display struct wl_drm *wl_server_drm; struct wl_drm *wl_drm; int authenticated; + int formats; #endif int (*authenticate) (_EGLDisplay *disp, uint32_t id); @@ -162,6 +163,7 @@ struct dri2_egl_surface __DRIbuffer *third_buffer; __DRIbuffer *pending_buffer; EGLBoolean block_swap_buffers; + int format; #endif #ifdef HAVE_ANDROID_PLATFORM diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 81b23f67306..f5ede191ce6 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -40,6 +40,12 @@ #include <wayland-client.h> #include "wayland-drm-client-protocol.h" +enum wl_drm_format_flags { + HAS_ARGB32 = 1, + HAS_PREMUL_ARGB32 = 2, + HAS_XRGB32 = 4 +}; + static void wl_buffer_release(void *data, struct wl_buffer *buffer) { @@ -101,6 +107,13 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, dri2_surf->third_buffer = NULL; dri2_surf->block_swap_buffers = EGL_FALSE; + if (conf->AlphaSize == 0) + dri2_surf->format = WL_DRM_FORMAT_XRGB32; + else if (dri2_surf->base.VGAlphaFormat == EGL_VG_ALPHA_FORMAT_PRE) + dri2_surf->format = WL_DRM_FORMAT_PREMULTIPLIED_ARGB32; + else + dri2_surf->format = WL_DRM_FORMAT_ARGB32; + switch (type) { case EGL_WINDOW_BIT: dri2_surf->wl_win = (struct wl_egl_window *) window; @@ -220,8 +233,7 @@ dri2_wl_egl_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap) static struct wl_buffer * wayland_create_buffer(struct dri2_egl_surface *dri2_surf, - __DRIbuffer *buffer, - struct wl_visual *visual) + __DRIbuffer *buffer) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); @@ -229,7 +241,7 @@ wayland_create_buffer(struct dri2_egl_surface *dri2_surf, buf = wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name, dri2_surf->base.Width, dri2_surf->base.Height, - buffer->pitch, visual); + buffer->pitch, dri2_surf->format); wl_buffer_add_listener(buf, &wl_buffer_listener, dri2_surf); return buf; @@ -474,8 +486,7 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable, if (dri2_surf->base.Type == EGL_PIXMAP_BIT && !dri2_surf->wl_pix->buffer) dri2_surf->wl_pix->buffer = wayland_create_buffer(dri2_surf, - dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT], - dri2_surf->wl_pix->visual); + dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]); *out_count = dri2_surf->buffer_count; if (dri2_surf->buffer_count == 0) @@ -583,8 +594,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT]) dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] = wayland_create_buffer(dri2_surf, - dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT], - dri2_surf->wl_win->visual); + dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]); wl_buffer_damage(dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT], 0, 0, dri2_surf->base.Width, dri2_surf->base.Height); @@ -648,13 +658,15 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, wl_egl_pixmap->destroy = dri2_wl_egl_pixmap_destroy; wl_egl_pixmap->driver_private = dri2_buf; + /* FIXME: Get buffer format from attr_list somehow... or from the + wl_egl_piaxmap. */ wl_egl_pixmap->buffer = wl_drm_create_buffer(dri2_dpy->wl_drm, dri2_buf->dri_buffer->name, wl_egl_pixmap->width, wl_egl_pixmap->height, dri2_buf->dri_buffer->pitch, - wl_egl_pixmap->visual); + WL_DRM_FORMAT_PREMULTIPLIED_ARGB32); wl_attr_list[1] = wl_egl_pixmap->width; wl_attr_list[3] = wl_egl_pixmap->height; @@ -742,6 +754,24 @@ 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) +{ + struct dri2_egl_display *dri2_dpy = data; + + switch (format) { + case WL_DRM_FORMAT_ARGB32: + dri2_dpy->formats |= HAS_ARGB32; + break; + case WL_DRM_FORMAT_PREMULTIPLIED_ARGB32: + dri2_dpy->formats |= HAS_PREMUL_ARGB32; + break; + case WL_DRM_FORMAT_XRGB32: + dri2_dpy->formats |= HAS_XRGB32; + break; + } +} + +static void drm_handle_authenticated(void *data, struct wl_drm *drm) { struct dri2_egl_display *dri2_dpy = data; @@ -751,6 +781,7 @@ drm_handle_authenticated(void *data, struct wl_drm *drm) static const struct wl_drm_listener drm_listener = { drm_handle_device, + drm_handle_format, drm_handle_authenticated }; @@ -758,8 +789,12 @@ EGLBoolean dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) { struct dri2_egl_display *dri2_dpy; - uint32_t id; + const __DRIconfig *config; + uint32_t id, types; int i; + static const unsigned int argb_masks[4] = + { 0xff0000, 0xff00, 0xff, 0xff000000 }; + static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 }; drv->API.CreateWindowSurface = dri2_create_window_surface; drv->API.CreatePixmapSurface = dri2_create_pixmap_surface; @@ -825,10 +860,17 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) if (!dri2_create_screen(disp)) goto cleanup_driver; - for (i = 0; dri2_dpy->driver_configs[i]; i++) - dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0, - EGL_WINDOW_BIT | EGL_PIXMAP_BIT, NULL, NULL); + types = EGL_WINDOW_BIT | EGL_PIXMAP_BIT; + if (dri2_dpy->formats & HAS_PREMUL_ARGB32) + types |= EGL_VG_ALPHA_FORMAT_PRE_BIT; + for (i = 0; dri2_dpy->driver_configs[i]; i++) { + config = dri2_dpy->driver_configs[i]; + if (dri2_dpy->formats & HAS_XRGB32) + dri2_add_config(disp, config, i + 1, 0, types, NULL, rgb_masks); + if (dri2_dpy->formats & (HAS_ARGB32 | HAS_PREMUL_ARGB32)) + dri2_add_config(disp, config, i + 1, 0, types, NULL, argb_masks); + } disp->Extensions.KHR_image_pixmap = EGL_TRUE; diff --git a/src/egl/wayland/wayland-drm/protocol/wayland-drm.xml b/src/egl/wayland/wayland-drm/protocol/wayland-drm.xml index cde943060ca..f63bebdcaf5 100644 --- a/src/egl/wayland/wayland-drm/protocol/wayland-drm.xml +++ b/src/egl/wayland/wayland-drm/protocol/wayland-drm.xml @@ -32,10 +32,16 @@ <interface name="wl_drm" version="1"> <enum name="error"> <entry name="authenticate_fail" value="0"/> - <entry name="invalid_visual" value="1"/> + <entry name="invalid_format" value="1"/> <entry name="invalid_name" value="2"/> </enum> + <enum name="format"> + <entry name="argb32" value="0"/> + <entry name="premultiplied_argb32" value="1"/> + <entry name="xrgb32" value="2"/> + </enum> + <!-- Call this request with the magic received from drmGetMagic(). It will be passed on to the drmAuthMagic() or DRIAuthConnection() call. This authentication must be @@ -52,7 +58,7 @@ <arg name="width" type="int"/> <arg name="height" type="int"/> <arg name="stride" type="uint"/> - <arg name="visual" type="object" interface="wl_visual"/> + <arg name="format" type="uint"/> </request> <!-- Notification of the path of the drm device which is used by @@ -64,6 +70,10 @@ <arg name="name" type="string"/> </event> + <event name="format"> + <arg name="format" type="uint"/> + </event> + <!-- Raised if the authenticate request succeeded --> <event name="authenticated"/> </interface> diff --git a/src/egl/wayland/wayland-drm/wayland-drm.c b/src/egl/wayland/wayland-drm/wayland-drm.c index 3f51c89703f..372faf70806 100644 --- a/src/egl/wayland/wayland-drm/wayland-drm.c +++ b/src/egl/wayland/wayland-drm/wayland-drm.c @@ -48,7 +48,8 @@ struct wl_drm { struct wl_drm_buffer { struct wl_buffer buffer; struct wl_drm *drm; - + uint32_t format; + void *driver_buffer; }; @@ -83,11 +84,22 @@ const static struct wl_buffer_interface drm_buffer_interface = { static void drm_create_buffer(struct wl_client *client, struct wl_resource *resource, uint32_t id, uint32_t name, int32_t width, int32_t height, - uint32_t stride, struct wl_resource *visual_resource) + uint32_t stride, uint32_t format) { struct wl_drm *drm = resource->data; struct wl_drm_buffer *buffer; - struct wl_visual *visual = visual_resource->data; + + switch (format) { + case WL_DRM_FORMAT_ARGB32: + case WL_DRM_FORMAT_PREMULTIPLIED_ARGB32: + case WL_DRM_FORMAT_XRGB32: + break; + default: + wl_resource_post_error(resource, + WL_DRM_ERROR_INVALID_FORMAT, + "invalid format"); + return; + } buffer = calloc(1, sizeof *buffer); if (buffer == NULL) { @@ -98,20 +110,12 @@ drm_create_buffer(struct wl_client *client, struct wl_resource *resource, buffer->drm = drm; buffer->buffer.width = width; buffer->buffer.height = height; - buffer->buffer.visual = visual; - - if (!visual || visual_resource->object.interface != &wl_visual_interface) { - wl_resource_post_error(resource, - WL_DRM_ERROR_INVALID_VISUAL, - "invalid visual"); - free(buffer); - return; - } + buffer->format = format; buffer->driver_buffer = drm->callbacks->reference_buffer(drm->user_data, name, width, height, - stride, visual); + stride, format); if (buffer->driver_buffer == NULL) { wl_resource_post_error(resource, @@ -160,6 +164,10 @@ bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id) resource = wl_client_add_object(client, &wl_drm_interface, &drm_interface, id, data); wl_resource_post_event(resource, WL_DRM_DEVICE, drm->device_name); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_ARGB32); + wl_resource_post_event(resource, WL_DRM_FORMAT, + WL_DRM_FORMAT_PREMULTIPLIED_ARGB32); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_XRGB32); } struct wl_drm * diff --git a/src/egl/wayland/wayland-drm/wayland-drm.h b/src/egl/wayland/wayland-drm/wayland-drm.h index 4324b591425..c9a90cad1ba 100644 --- a/src/egl/wayland/wayland-drm/wayland-drm.h +++ b/src/egl/wayland/wayland-drm/wayland-drm.h @@ -5,6 +5,7 @@ #include "eglimage.h" #include <wayland-server.h> +#include "wayland-drm-server-protocol.h" struct wl_drm; @@ -13,7 +14,7 @@ struct wayland_drm_callbacks { void *(*reference_buffer)(void *user_data, uint32_t name, int32_t width, int32_t height, - uint32_t stride, struct wl_visual *visual); + uint32_t stride, uint32_t format); void (*release_buffer)(void *user_data, void *buffer); }; diff --git a/src/egl/wayland/wayland-egl/wayland-egl-priv.h b/src/egl/wayland/wayland-egl/wayland-egl-priv.h index 179f5cf199b..accd2ddca84 100644 --- a/src/egl/wayland/wayland-egl/wayland-egl-priv.h +++ b/src/egl/wayland/wayland-egl/wayland-egl-priv.h @@ -16,7 +16,6 @@ extern "C" { struct wl_egl_window { struct wl_surface *surface; - struct wl_visual *visual; int width; int height; @@ -28,7 +27,6 @@ struct wl_egl_window { }; struct wl_egl_pixmap { - struct wl_visual *visual; struct wl_buffer *buffer; int width; diff --git a/src/egl/wayland/wayland-egl/wayland-egl.c b/src/egl/wayland/wayland-egl/wayland-egl.c index c8f73ea8a3a..e950b4a644b 100644 --- a/src/egl/wayland/wayland-egl/wayland-egl.c +++ b/src/egl/wayland/wayland-egl/wayland-egl.c @@ -17,8 +17,7 @@ wl_egl_window_resize(struct wl_egl_window *egl_window, WL_EGL_EXPORT struct wl_egl_window * wl_egl_window_create(struct wl_surface *surface, - int width, int height, - struct wl_visual *visual) + int width, int height) { struct wl_egl_window *egl_window; @@ -27,7 +26,6 @@ wl_egl_window_create(struct wl_surface *surface, return NULL; egl_window->surface = surface; - egl_window->visual = visual; wl_egl_window_resize(egl_window, width, height, 0, 0); egl_window->attached_width = 0; egl_window->attached_height = 0; @@ -52,8 +50,7 @@ wl_egl_window_get_attached_size(struct wl_egl_window *egl_window, } WL_EGL_EXPORT struct wl_egl_pixmap * -wl_egl_pixmap_create(int width, int height, - struct wl_visual *visual, uint32_t flags) +wl_egl_pixmap_create(int width, int height, uint32_t flags) { struct wl_egl_pixmap *egl_pixmap; @@ -63,7 +60,6 @@ wl_egl_pixmap_create(int width, int height, egl_pixmap->width = width; egl_pixmap->height = height; - egl_pixmap->visual = visual; egl_pixmap->destroy = NULL; egl_pixmap->buffer = NULL; |