egl/wayland-drm: Generalize interface

Do not depend on _EGLDisplay and _EGLImage.
This commit is contained in:
Benjamin Franzke 2011-04-30 11:17:01 +02:00 committed by Kristian Høgsberg
parent a3e2c8f31f
commit 834b84149d
3 changed files with 113 additions and 63 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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