[Patch 3/5 v2] Improve wayland-drm to wayland-gbm to act as generic buffer manager for wayland
Zhao, Halley
halley.zhao at linux.intel.com
Mon Apr 23 03:11:07 PDT 2012
update patch with additional change:
change gbm_bo_create_from_handle to gbm_bo_create_from_native_handle
with parameter of gbm_bo_handle
diff --git a/src/egl/drivers/dri2/egl_dri2.c
b/src/egl/drivers/dri2/egl_dri2.c
old mode 100644
new mode 100755
index 7bb32bd..9065c42
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1321,7 +1321,7 @@ dri2_bind_wayland_display_wl(_EGLDriver *drv,
_EGLDisplay *disp,
(int(*)(void *, uint32_t)) dri2_dpy->authenticate;
dri2_dpy->wl_server_gbm =
- wl_gbm_init(wl_dpy, dri2_dpy->device_name,
+ wl_gbm_init(wl_dpy, dri2_dpy->device_name, dri2_dpy->fd,
&wl_gbm_callbacks, disp);
if (!dri2_dpy->wl_server_gbm)
diff --git a/src/egl/wayland/wayland-drm/Makefile.am
b/src/egl/wayland/wayland-drm/Makefile.am
old mode 100644
new mode 100755
index cf15eda..e7bd7b0
--- a/src/egl/wayland/wayland-drm/Makefile.am
+++ b/src/egl/wayland/wayland-drm/Makefile.am
@@ -1,5 +1,6 @@
AM_CFLAGS = -I$(top_srcdir)/src/egl/main \
-I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/gbm/main \
$(DEFINES) \
$(WAYLAND_CFLAGS)
@@ -7,8 +8,9 @@ noinst_LTLIBRARIES = libwayland-drm.la
libwayland_drm_la_SOURCES = wayland-drm.c wayland-drm-protocol.c
noinst_HEADERS = wayland-drm.h
+include_HEADERS = wayland-drm-client-protocol.h
+
BUILT_SOURCES = wayland-drm-protocol.c \
- wayland-drm-client-protocol.h \
wayland-drm-server-protocol.h
CLEANFILES = $(BUILT_SOURCES)
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.c
b/src/egl/wayland/wayland-drm/wayland-drm.c
old mode 100644
new mode 100755
index 3403555..033f87a
--- a/src/egl/wayland/wayland-drm/wayland-drm.c
+++ b/src/egl/wayland/wayland-drm/wayland-drm.c
@@ -35,7 +35,7 @@
#include <wayland-server.h>
#include "wayland-drm.h"
#include "wayland-drm-server-protocol.h"
-
+#include "gbm.h"
/* Git master of Wayland is moving towards a stable version of the
* protocol, but breaking from 0.85 in the process. For the time
* being, it's convenient to be able to build Mesa against both master
@@ -54,6 +54,7 @@ struct wl_gbm {
char *device_name;
struct wl_gbm_callbacks *callbacks;
+ struct gbm_device *gbm_device;
};
struct wl_gbm_buffer {
@@ -62,6 +63,7 @@ struct wl_gbm_buffer {
uint32_t format;
void *driver_buffer;
+ struct gbm_bo* bo;
};
static void
@@ -70,8 +72,7 @@ destroy_buffer(struct wl_resource *resource)
struct wl_gbm_buffer *buffer = resource->data;
struct wl_gbm *gbm = buffer->gbm;
- gbm->callbacks->release_buffer(gbm->user_data,
- buffer->driver_buffer);
+ gbm_bo_destroy (buffer->bo);
free(buffer);
}
@@ -107,10 +108,14 @@ gbm_create_buffer(struct wl_client *client, struct
wl_resource *resource,
{
struct wl_gbm *gbm = resource->data;
struct wl_gbm_buffer *buffer;
+ int gbm_format;
switch (format) {
case WL_GBM_FORMAT_ARGB8888:
+ gbm_format = GBM_BO_FORMAT_ARGB8888;
+ break;
case WL_GBM_FORMAT_XRGB8888:
+ gbm_format = GBM_BO_FORMAT_XRGB8888;
break;
default:
wl_resource_post_error(resource,
@@ -130,17 +135,16 @@ gbm_create_buffer(struct wl_client *client, struct
wl_resource *resource,
buffer->buffer.height = height;
buffer->format = format;
- buffer->driver_buffer =
- gbm->callbacks->reference_buffer(gbm->user_data, name,
- width, height,
- stride, format);
-
- if (buffer->driver_buffer == NULL) {
- wl_resource_post_error(resource,
- WL_GBM_ERROR_INVALID_NAME,
- "invalid name");
- return;
- }
+ union gbm_bo_handle handle;
+ handle.s32 = name;
+ buffer->bo = gbm_bo_create_from_native_handle(gbm->gbm_device,
handle, &(buffer->driver_buffer),
+ width, height, stride,
gbm_format, GBM_BO_USE_RENDERING);
+ if (buffer->driver_buffer == NULL) {
+ wl_resource_post_error(resource,
+ WL_GBM_ERROR_INVALID_NAME,
+ "invalid name");
+ return;
+ }
buffer->buffer.resource.object.id = id;
buffer->buffer.resource.object.interface = &wl_buffer_interface;
@@ -189,7 +193,7 @@ bind_gbm(struct wl_client *client, void *data,
uint32_t version, uint32_t id)
}
struct wl_gbm *
-wl_gbm_init(struct wl_display *display, char *device_name,
+wl_gbm_init(struct wl_display *display, char *device_name, int fd,
struct wl_gbm_callbacks *callbacks, void *user_data)
{
struct wl_gbm *gbm;
@@ -200,6 +204,7 @@ wl_gbm_init(struct wl_display *display, char
*device_name,
gbm->device_name = strdup(device_name);
gbm->callbacks = callbacks;
gbm->user_data = user_data;
+ gbm->gbm_device = gbm_create_device(fd);
wl_display_add_global(display, &wl_gbm_interface, gbm, bind_gbm);
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.h
b/src/egl/wayland/wayland-drm/wayland-drm.h
index 0422dc5..75447aa 100644
--- a/src/egl/wayland/wayland-drm/wayland-drm.h
+++ b/src/egl/wayland/wayland-drm/wayland-drm.h
@@ -1,9 +1,6 @@
#ifndef WAYLAND_GBM_H
#define WAYLAND_GBM_H
-#include "egldisplay.h"
-#include "eglimage.h"
-
#include <wayland-server.h>
#include "wayland-drm-server-protocol.h"
@@ -20,7 +17,7 @@ struct wl_gbm_callbacks {
};
struct wl_gbm *
-wl_gbm_init(struct wl_display *display, char *device_name,
+wl_gbm_init(struct wl_display *display, char *device_name, int fd,
struct wl_gbm_callbacks *callbacks, void *user_data);
void
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c
b/src/gallium/state_trackers/egl/drm/native_drm.c
old mode 100644
new mode 100755
index 4d1fba0..7d9deac
--- a/src/gallium/state_trackers/egl/drm/native_drm.c
+++ b/src/gallium/state_trackers/egl/drm/native_drm.c
@@ -213,7 +213,7 @@ drm_display_bind_wayland_display(struct
native_display *ndpy,
return FALSE;
drmdpy->wl_server_gbm = wl_gbm_init(wl_dpy,
- drmdpy->device_name,
+ drmdpy->device_name, drmdpy->fd,
&wl_gbm_callbacks, ndpy);
if (!drmdpy->wl_server_gbm)
diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c
b/src/gallium/state_trackers/egl/wayland/native_drm.c
index dcdc1d5..6738b2b 100644
--- a/src/gallium/state_trackers/egl/wayland/native_drm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_drm.c
@@ -263,7 +263,7 @@ wayland_drm_display_bind_wayland_display(struct
native_display *ndpy,
return FALSE;
drmdpy->wl_server_gbm =
- wl_gbm_init(wl_dpy, drmdpy->device_name,
+ wl_gbm_init(wl_dpy, drmdpy->device_name, drmdpy->fd,
&wl_gbm_callbacks, ndpy);
if (!drmdpy->wl_server_gbm)
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c
b/src/gallium/state_trackers/egl/x11/native_dri2.c
old mode 100644
new mode 100755
index ee3e0fe..cfd3c95
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -863,7 +863,7 @@ dri2_display_bind_wayland_display(struct
native_display *ndpy,
return FALSE;
dri2dpy->wl_server_gbm = wl_gbm_init(wl_dpy,
- x11_screen_get_device_name(dri2dpy->xscr),
+ x11_screen_get_device_name(dri2dpy->xscr),
x11_screen_get_dri_fd(dri2dpy->xscr),
&wl_gbm_callbacks, ndpy);
if (!dri2dpy->wl_server_gbm)
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c
b/src/gallium/state_trackers/egl/x11/x11_screen.c
old mode 100644
new mode 100755
index f8f9e2a..904dec3
--- a/src/gallium/state_trackers/egl/x11/x11_screen.c
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.c
@@ -321,6 +321,12 @@ x11_screen_get_device_name(struct x11_screen *xscr)
return xscr->dri_device;
}
+int
+x11_screen_get_dri_fd(struct x11_screen *xscr)
+{
+ return xscr->dri_fd;
+}
+
int
x11_screen_authenticate(struct x11_screen *xscr, uint32_t id)
{
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.h
b/src/gallium/state_trackers/egl/x11/x11_screen.h
old mode 100644
new mode 100755
index ad7aa97..16bc1a6
--- a/src/gallium/state_trackers/egl/x11/x11_screen.h
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.h
@@ -100,6 +100,9 @@ x11_screen_enable_dri2(struct x11_screen *xscr,
char *
x11_screen_get_device_name(struct x11_screen *xscr);
+int
+x11_screen_get_dri_fd(struct x11_screen *xscr);
+
int
x11_screen_authenticate(struct x11_screen *xscr, uint32_t id);
diff --git a/src/gbm/backends/dri/gbm_dri.c
b/src/gbm/backends/dri/gbm_dri.c
old mode 100644
new mode 100755
index 4df6e8f..581a616
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -381,6 +381,64 @@ gbm_dri_bo_create_from_egl_image(struct gbm_device
*gbm,
}
static struct gbm_bo *
+gbm_dri_bo_create_from_native_handle(struct gbm_device *gbm,
+ union gbm_bo_handle handle, void
**image ,
+ uint32_t width, uint32_t height,
uint32_t stride,
+ uint32_t format, uint32_t usage)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(gbm);
+ struct gbm_dri_bo *bo;
+ unsigned dri_use = 0;
+ int dri_format;
+ int name;
+
+ name = handle.s32;
+
+ bo = calloc(1, sizeof *bo);
+ if (bo == NULL)
+ return NULL;
+
+ bo->base.base.gbm = gbm;
+ bo->base.base.width = width;
+ bo->base.base.height = height;
+
+ switch (format) {
+ case GBM_BO_FORMAT_XRGB8888:
+ dri_format = __DRI_IMAGE_FORMAT_XRGB8888;
+ break;
+ case GBM_BO_FORMAT_ARGB8888:
+ dri_format = __DRI_IMAGE_FORMAT_ARGB8888;
+ break;
+ default:
+ return NULL;
+ }
+
+ bo->image = dri->image->createImageFromName(dri->screen,
+ width, height,
+ dri_format, name, stride / 4,
+ NULL);
+ *image = bo->image;
+
+ if (usage & GBM_BO_USE_SCANOUT)
+ dri_use |= __DRI_IMAGE_USE_SCANOUT;
+ if (usage & GBM_BO_USE_CURSOR_64X64)
+ dri_use |= __DRI_IMAGE_USE_CURSOR;
+
+ if (dri->image->base.version >= 2 &&
+ !dri->image->validateUsage(bo->image, dri_use)) {
+ free(bo);
+ return NULL;
+ }
+
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE,
+ &bo->base.base.handle.s32);
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE,
+ (int *) &bo->base.base.pitch);
+
+ return &bo->base.base;
+}
+
+static struct gbm_bo *
gbm_dri_bo_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t usage)
@@ -490,6 +548,7 @@ dri_device_create(int fd)
dri->base.base.fd = fd;
dri->base.base.bo_create = gbm_dri_bo_create;
dri->base.base.bo_create_from_egl_image =
gbm_dri_bo_create_from_egl_image;
+ dri->base.base.bo_create_from_native_handle =
gbm_dri_bo_create_from_native_handle;
dri->base.base.is_format_supported = gbm_dri_is_format_supported;
dri->base.base.bo_destroy = gbm_dri_bo_destroy;
dri->base.base.destroy = dri_destroy;
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
old mode 100644
new mode 100755
index 79ba650..84a9f27
--- a/src/gbm/main/gbm.c
+++ b/src/gbm/main/gbm.c
@@ -406,3 +406,17 @@ gbm_surface_has_free_buffers(struct gbm_surface
*surf)
{
return surf->gbm->surface_has_free_buffers(surf);
}
+
+GBM_EXPORT struct gbm_bo *
+gbm_bo_create_from_native_handle(struct gbm_device *gbm,
+ union gbm_bo_handle handle, void
**image/*temp out*/,
+ uint32_t width, uint32_t
height,uint32_t stride,
+ uint32_t format, uint32_t usage)
+{
+ if (width == 0 || height == 0)
+ return NULL;
+
+ return gbm->bo_create_from_native_handle(gbm, handle, image, width,
height, stride, format, usage);
+
+}
+
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
old mode 100644
new mode 100755
index 6748752..a8933af
--- a/src/gbm/main/gbm.h
+++ b/src/gbm/main/gbm.h
@@ -229,6 +229,11 @@ gbm_bo_create_from_egl_image(struct gbm_device
*gbm,
void *egl_dpy, void *egl_img,
uint32_t width, uint32_t height,
uint32_t usage);
+struct gbm_bo *
+gbm_bo_create_from_native_handle(struct gbm_device *gbm,
+ union gbm_bo_handle, void **image,
+ uint32_t width, uint32_t height,
uint32_t stride,
+ uint32_t format, uint32_t usage);
uint32_t
gbm_bo_get_width(struct gbm_bo *bo);
diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h
old mode 100644
new mode 100755
index 53d73f4..1a2cf59
--- a/src/gbm/main/gbmint.h
+++ b/src/gbm/main/gbmint.h
@@ -70,6 +70,10 @@ struct gbm_device {
void *egl_dpy, void
*egl_img,
uint32_t width, uint32_t
height,
uint32_t usage);
+ struct gbm_bo *(*bo_create_from_native_handle)(struct gbm_device
*gbm,
+ union gbm_bo_handle, void
**image/* temp out */,
+ uint32_t width, uint32_t
height, uint32_t stride,
+ uint32_t format, uint32_t
usage);
void (*bo_destroy)(struct gbm_bo *bo);
struct gbm_surface *(*surface_create)(struct gbm_device *gbm,
More information about the wayland-devel
mailing list