wayland-drm: Add protocol to create planar buffers
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 5 Jul 2012 20:27:05 +0000 (16:27 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Wed, 11 Jul 2012 19:28:35 +0000 (15:28 -0400)
src/egl/drivers/dri2/egl_dri2.c
src/egl/wayland/wayland-drm/protocol/wayland-drm.xml
src/egl/wayland/wayland-drm/wayland-drm.c
src/egl/wayland/wayland-drm/wayland-drm.h
src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c

index bb30e699fe4335ac2216acd60ce76e192aefd7c3..0fc33e01513fccef75469d65fd533c99b49a6f2e 100644 (file)
@@ -1243,7 +1243,7 @@ dri2_wl_reference_buffer(void *user_data, uint32_t name,
                                            buffer->buffer.width,
                                            buffer->buffer.height, 
                                            buffer->driver_format, name,
-                                           buffer->stride0 / 4,
+                                           buffer->stride[0] / 4,
                                            NULL);
 }
 
index 89fd8f08872f075bc2b3d82e8f2f368577ead004..265d4f892af241ad07ed322cb8299dd90cdbc960 100644 (file)
       <arg name="format" type="uint"/>
     </request>
 
+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
+         surface must have a name using the flink ioctl -->
+    <request name="create_planar_buffer">
+      <arg name="id" type="new_id" interface="wl_buffer"/>
+      <arg name="name" type="uint"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+      <arg name="format" type="uint"/>
+      <arg name="offset0" type="int"/>
+      <arg name="stride0" type="int"/>
+      <arg name="offset1" type="int"/>
+      <arg name="stride1" type="int"/>
+      <arg name="offset2" type="int"/>
+      <arg name="stride2" type="int"/>
+    </request>
+
     <!-- Notification of the path of the drm device which is used by
          the server.  The client should use this device for creating
          local buffers.  Only buffers created from this device should
index af176b72d125ec105ddde5dc8b645f41ef2dab6c..45b307f3a888c90b7588842dcd2b0a3e4c129008 100644 (file)
@@ -92,24 +92,16 @@ 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, uint32_t format)
+create_buffer(struct wl_client *client, struct wl_resource *resource,
+              uint32_t id, uint32_t name, int32_t width, int32_t height,
+              uint32_t format,
+              int32_t offset0, int32_t stride0,
+              int32_t offset1, int32_t stride1,
+              int32_t offset2, int32_t stride2)
 {
        struct wl_drm *drm = resource->data;
        struct wl_drm_buffer *buffer;
 
-       switch (format) {
-       case WL_DRM_FORMAT_ARGB8888:
-       case WL_DRM_FORMAT_XRGB8888:
-               break;
-       default:
-               wl_resource_post_error(resource,
-                                      WL_DRM_ERROR_INVALID_FORMAT,
-                                      "invalid format");
-               return;
-       }
-
        buffer = calloc(1, sizeof *buffer);
        if (buffer == NULL) {
                wl_resource_post_no_memory(resource);
@@ -120,8 +112,12 @@ drm_create_buffer(struct wl_client *client, struct wl_resource *resource,
        buffer->buffer.width = width;
        buffer->buffer.height = height;
        buffer->format = format;
-       buffer->offset0 = 0;
-       buffer->stride0 = stride;
+       buffer->offset[0] = offset0;
+       buffer->stride[0] = stride0;
+       buffer->offset[1] = offset1;
+       buffer->stride[1] = stride1;
+       buffer->offset[2] = offset2;
+       buffer->stride[2] = stride2;
 
         drm->callbacks->reference_buffer(drm->user_data, name, buffer);
        if (buffer->driver_buffer == NULL) {
@@ -143,6 +139,56 @@ drm_create_buffer(struct wl_client *client, struct wl_resource *resource,
        wl_client_add_resource(resource->client, &buffer->buffer.resource);
 }
 
+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, uint32_t format)
+{
+        switch (format) {
+        case WL_DRM_FORMAT_ARGB8888:
+        case WL_DRM_FORMAT_XRGB8888:
+        case WL_DRM_FORMAT_YUYV:
+                break;
+        default:
+                wl_resource_post_error(resource,
+                                       WL_DRM_ERROR_INVALID_FORMAT,
+                                       "invalid format");
+           return;
+        }
+
+        create_buffer(client, resource, id,
+                      name, width, height, format, 0, stride, 0, 0, 0, 0);
+}
+
+static void
+drm_create_planar_buffer(struct wl_client *client,
+                         struct wl_resource *resource,
+                         uint32_t id, uint32_t name,
+                         int32_t width, int32_t height, uint32_t format,
+                         int32_t offset0, int32_t stride0,
+                         int32_t offset1, int32_t stride1,
+                         int32_t offset2, int32_t stride2)
+{
+        switch (format) {
+       case WL_DRM_FORMAT_YUV410:
+       case WL_DRM_FORMAT_YUV411:
+       case WL_DRM_FORMAT_YUV420:
+       case WL_DRM_FORMAT_YUV422:
+       case WL_DRM_FORMAT_YUV444:
+       case WL_DRM_FORMAT_NV12:
+        case WL_DRM_FORMAT_NV16:
+                break;
+        default:
+                wl_resource_post_error(resource,
+                                       WL_DRM_ERROR_INVALID_FORMAT,
+                                       "invalid format");
+           return;
+        }
+
+        create_buffer(client, resource, id, name, width, height, format,
+                      offset0, stride0, offset1, stride1, offset2, stride2);
+}
+
 static void
 drm_authenticate(struct wl_client *client,
                 struct wl_resource *resource, uint32_t id)
@@ -159,7 +205,8 @@ drm_authenticate(struct wl_client *client,
 
 const static struct wl_drm_interface drm_interface = {
        drm_authenticate,
-       drm_create_buffer
+       drm_create_buffer,
+        drm_create_planar_buffer
 };
 
 static void
@@ -175,6 +222,14 @@ bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id)
                               WL_DRM_FORMAT_ARGB8888);
        wl_resource_post_event(resource, WL_DRM_FORMAT,
                               WL_DRM_FORMAT_XRGB8888);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV410);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV411);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV420);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV422);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV444);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV12);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV16);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUYV);
 }
 
 struct wl_drm *
index f3df7eeaddd2cb3beccb27d0049fd7e5fd4c9cb1..46aab6984d12e28a18359f6d5fe5f29104b5c932 100644 (file)
@@ -14,9 +14,8 @@ struct wl_drm_buffer {
        struct wl_drm *drm;
        uint32_t format;
        uint32_t driver_format;
-        int32_t offset0;
-        int32_t stride0;
-
+        int32_t offset[3];
+        int32_t stride[3];
        void *driver_buffer;
 };
 
index 6d72ce14774cc524a73cc86116d9e483acc51091..c520b536483b0c8f8ca2c94f9af1b02cc8e1fef7 100644 (file)
@@ -47,7 +47,7 @@ egl_g3d_wl_drm_helper_reference_buffer(void *user_data, uint32_t name,
 
    memset(&wsh, 0, sizeof(wsh));
    wsh.handle = name;
-   wsh.stride = buffer->stride0;
+   wsh.stride = buffer->stride[0];
 
    buffer->driver_buffer =
       ndpy->screen->resource_from_handle(ndpy->screen, &templ, &wsh);