From 834b84149d99526e4e7a3cfa6ba9fe81e5fb9eda Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sat, 30 Apr 2011 11:17:01 +0200 Subject: [PATCH] egl/wayland-drm: Generalize interface Do not depend on _EGLDisplay and _EGLImage. --- src/egl/drivers/dri2/egl_dri2.c | 71 +++++++++++++++----- src/egl/wayland/wayland-drm/wayland-drm.c | 81 ++++++++++++----------- src/egl/wayland/wayland-drm/wayland-drm.h | 24 ++++--- 3 files changed, 113 insertions(+), 63 deletions(-) diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 5e47fbe126a..b03ffc3cf9b 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -922,14 +922,11 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, return &dri2_img->base; } -static EGLBoolean -dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, - EGLint *name, EGLint *handle, EGLint *stride); - static _EGLImage * dri2_reference_drm_image(_EGLDisplay *disp, _EGLContext *ctx, - _EGLImage *image, EGLint width, EGLint height) + __DRIimage *dri_image, EGLint width, EGLint height) { + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); EGLint attr_list[] = { EGL_WIDTH, 0, EGL_HEIGHT, 0, @@ -939,8 +936,8 @@ dri2_reference_drm_image(_EGLDisplay *disp, _EGLContext *ctx, }; EGLint name, stride; - dri2_export_drm_image_mesa(disp->Driver, disp, image, - &name, NULL, &stride); + dri2_dpy->image->queryImage(dri_image, __DRI_IMAGE_ATTRIB_NAME, &name); + dri2_dpy->image->queryImage(dri_image, __DRI_IMAGE_ATTRIB_STRIDE, &stride); attr_list[1] = width; attr_list[3] = height; @@ -954,16 +951,19 @@ dri2_reference_drm_image(_EGLDisplay *disp, _EGLContext *ctx, #ifdef HAVE_WAYLAND_PLATFORM static _EGLImage * dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx, - EGLClientBuffer buffer, + EGLClientBuffer _buffer, const EGLint *attr_list) { - struct wl_drm_buffer *wl_drm_buffer = (struct wl_drm_buffer *) buffer; + struct wl_buffer *buffer = (struct wl_buffer *) _buffer; + (void) attr_list; - (void) attr_list; + if (!wayland_buffer_is_drm(buffer)) + return NULL; - return dri2_reference_drm_image(disp, ctx, wl_drm_buffer->image, - wl_drm_buffer->buffer.width, - wl_drm_buffer->buffer.height); + return dri2_reference_drm_image(disp, ctx, + wayland_drm_buffer_get_buffer(buffer), + buffer->width, + buffer->height); } #endif @@ -1112,6 +1112,41 @@ dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, } #ifdef HAVE_WAYLAND_PLATFORM + +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) +{ + _EGLDisplay *disp = user_data; + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + __DRIimage *image; + + image = dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, + width, height, + __DRI_IMAGE_FORMAT_ARGB8888, + name, stride / 4, + NULL); + + return image; +} + +static void +dri2_wl_release_buffer(void *user_data, void *buffer) +{ + _EGLDisplay *disp = user_data; + __DRIimage *image = buffer; + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + + dri2_dpy->image->destroyImage(image); +} + +static struct wayland_drm_callbacks wl_drm_callbacks = { + .authenticate = NULL, + .reference_buffer = dri2_wl_reference_buffer, + .release_buffer = dri2_wl_release_buffer +}; + static EGLBoolean dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, struct wl_display *wl_dpy) @@ -1123,10 +1158,12 @@ dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, if (dri2_dpy->wl_server_drm) return EGL_FALSE; + wl_drm_callbacks.authenticate = + (int(*)(void *, uint32_t)) dri2_dpy->authenticate; + dri2_dpy->wl_server_drm = - wayland_drm_init(wl_dpy, disp, - dri2_dpy->authenticate, - dri2_dpy->device_name); + wayland_drm_init(wl_dpy, dri2_dpy->device_name, + &wl_drm_callbacks, disp); if (!dri2_dpy->wl_server_drm) return EGL_FALSE; @@ -1145,7 +1182,7 @@ dri2_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, if (!dri2_dpy->wl_server_drm) return EGL_FALSE; - wayland_drm_destroy(dri2_dpy->wl_server_drm); + wayland_drm_uninit(dri2_dpy->wl_server_drm); dri2_dpy->wl_server_drm = NULL; return EGL_TRUE; diff --git a/src/egl/wayland/wayland-drm/wayland-drm.c b/src/egl/wayland/wayland-drm/wayland-drm.c index 3d5cb399e57..050f540ddfa 100644 --- a/src/egl/wayland/wayland-drm/wayland-drm.c +++ b/src/egl/wayland/wayland-drm/wayland-drm.c @@ -1,5 +1,6 @@ /* * Copyright © 2011 Kristian Høgsberg + * Copyright © 2011 Benjamin Franzke * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -35,19 +36,21 @@ #include "wayland-drm.h" #include "wayland-drm-server-protocol.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglimage.h" -#include "egltypedefs.h" - struct wl_drm { struct wl_object object; struct wl_display *display; - _EGLDisplay *edisp; - + void *user_data; char *device_name; - authenticate_t authenticate; + + struct wayland_drm_callbacks *callbacks; +}; + +struct wl_drm_buffer { + struct wl_buffer buffer; + struct wl_drm *drm; + + void *driver_buffer; }; static void @@ -60,9 +63,10 @@ static void destroy_buffer(struct wl_resource *resource, struct wl_client *client) { struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) resource; - _EGLDriver *drv = buffer->drm->edisp->Driver; + struct wl_drm *drm = buffer->drm; - drv->API.DestroyImageKHR(drv, buffer->drm->edisp, buffer->image); + drm->callbacks->release_buffer(drm->user_data, + buffer->driver_buffer); free(buffer); } @@ -72,7 +76,7 @@ buffer_destroy(struct wl_client *client, struct wl_buffer *buffer) wl_resource_destroy(&buffer->resource, client); } -const static struct wl_buffer_interface buffer_interface = { +const static struct wl_buffer_interface drm_buffer_interface = { buffer_damage, buffer_destroy }; @@ -83,14 +87,6 @@ drm_create_buffer(struct wl_client *client, struct wl_drm *drm, uint32_t stride, struct wl_visual *visual) { struct wl_drm_buffer *buffer; - EGLint attribs[] = { - EGL_WIDTH, 0, - EGL_HEIGHT, 0, - EGL_DRM_BUFFER_STRIDE_MESA, 0, - EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, - EGL_NONE - }; - _EGLDriver *drv = drm->edisp->Driver; buffer = malloc(sizeof *buffer); if (buffer == NULL) { @@ -114,16 +110,12 @@ drm_create_buffer(struct wl_client *client, struct wl_drm *drm, return; } - attribs[1] = width; - attribs[3] = height; - attribs[5] = stride / 4; - buffer->image = drv->API.CreateImageKHR(drv, drm->edisp, - EGL_NO_CONTEXT, - EGL_DRM_BUFFER_MESA, - (EGLClientBuffer) (intptr_t) name, - attribs); + buffer->driver_buffer = + drm->callbacks->reference_buffer(drm->user_data, name, + width, height, + stride, visual); - if (buffer->image == NULL) { + if (buffer->driver_buffer == NULL) { /* FIXME: Define a real exception event instead of * abusing this one */ wl_client_post_event(client, @@ -136,7 +128,7 @@ drm_create_buffer(struct wl_client *client, struct wl_drm *drm, buffer->buffer.resource.object.id = id; buffer->buffer.resource.object.interface = &wl_buffer_interface; buffer->buffer.resource.object.implementation = (void (**)(void)) - &buffer_interface; + &drm_buffer_interface; buffer->buffer.resource.destroy = destroy_buffer; @@ -147,7 +139,7 @@ static void drm_authenticate(struct wl_client *client, struct wl_drm *drm, uint32_t id) { - if (drm->authenticate(drm->edisp, id) < 0) + if (drm->callbacks->authenticate(drm->user_data, id) < 0) wl_client_post_event(client, (struct wl_object *) drm->display, WL_DISPLAY_INVALID_OBJECT, 0); @@ -162,9 +154,7 @@ const static struct wl_drm_interface drm_interface = { }; static void -post_drm_device(struct wl_client *client, - struct wl_object *global, - uint32_t version) +post_drm_device(struct wl_client *client, struct wl_object *global) { struct wl_drm *drm = (struct wl_drm *) global; @@ -172,17 +162,17 @@ post_drm_device(struct wl_client *client, } struct wl_drm * -wayland_drm_init(struct wl_display *display, _EGLDisplay *disp, - authenticate_t authenticate, char *device_name) +wayland_drm_init(struct wl_display *display, char *device_name, + struct wayland_drm_callbacks *callbacks, void *user_data) { struct wl_drm *drm; drm = malloc(sizeof *drm); drm->display = display; - drm->edisp = disp; - drm->authenticate = authenticate; drm->device_name = strdup(device_name); + drm->callbacks = callbacks; + drm->user_data = user_data; drm->object.interface = &wl_drm_interface; drm->object.implementation = (void (**)(void)) &drm_interface; @@ -193,7 +183,7 @@ wayland_drm_init(struct wl_display *display, _EGLDisplay *disp, } void -wayland_drm_destroy(struct wl_drm *drm) +wayland_drm_uninit(struct wl_drm *drm) { free(drm->device_name); @@ -201,3 +191,18 @@ wayland_drm_destroy(struct wl_drm *drm) free(drm); } + +int +wayland_buffer_is_drm(struct wl_buffer *buffer) +{ + return buffer->resource.object.implementation == + (void (**)(void)) &drm_buffer_interface; +} + +void * +wayland_drm_buffer_get_buffer(struct wl_buffer *buffer_base) +{ + struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) buffer_base; + + return buffer->driver_buffer; +} diff --git a/src/egl/wayland/wayland-drm/wayland-drm.h b/src/egl/wayland/wayland-drm/wayland-drm.h index 675a6a5ce43..4324b591425 100644 --- a/src/egl/wayland/wayland-drm/wayland-drm.h +++ b/src/egl/wayland/wayland-drm/wayland-drm.h @@ -8,19 +8,27 @@ struct wl_drm; -typedef int (*authenticate_t) (_EGLDisplay *disp, uint32_t id); +struct wayland_drm_callbacks { + int (*authenticate)(void *user_data, uint32_t id); -struct wl_drm_buffer { - struct wl_buffer buffer; - struct wl_drm *drm; - _EGLImage *image; + void *(*reference_buffer)(void *user_data, uint32_t name, + int32_t width, int32_t height, + uint32_t stride, struct wl_visual *visual); + + void (*release_buffer)(void *user_data, void *buffer); }; struct wl_drm * -wayland_drm_init(struct wl_display *display, _EGLDisplay *disp, - authenticate_t authenticate, char *device_name); +wayland_drm_init(struct wl_display *display, char *device_name, + struct wayland_drm_callbacks *callbacks, void *user_data); void -wayland_drm_destroy(struct wl_drm *drm); +wayland_drm_uninit(struct wl_drm *drm); + +int +wayland_buffer_is_drm(struct wl_buffer *buffer); + +void * +wayland_drm_buffer_get_buffer(struct wl_buffer *buffer); #endif -- 2.30.2