[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