Do not import multi-plane DMABUF.
[platform/adaptation/renesas_rcar/wayland-kms.git] / wayland-kms.c
index 0a86845..2ea3a8d 100644 (file)
@@ -41,6 +41,7 @@
 #include <xf86drm.h>
 #include <wayland-server.h>
 #include "wayland-kms.h"
+#include "wayland-kms-auth.h"
 #include "wayland-kms-server-protocol.h"
 
 #if defined(DEBUG)
 #      define WLKMS_DEBUG(s, x...) { }
 #endif
 
+/*
+ * Taken from EGL/egl.h. Better to refer the egl.h
+ * in the future.
+ */
+#ifndef EGL_TEXTURE_RGBA
+#      define EGL_TEXTURE_RGBA         0x305E
+#endif
+
 struct wl_kms {
        struct wl_display *display;
        int fd;                         /* FD for DRM */
        char *device_name;
+
+       struct kms_auth *auth;          /* for nested authentication */
 };
 
+/*
+ * wl_kms server
+ */
+
 static void destroy_buffer(struct wl_resource *resource)
 {
        struct wl_kms_buffer *buffer = resource->data;
+       struct drm_gem_close close;
+       int ret;
+
+       if (buffer->handle) {
+               close.handle = buffer->handle;
+               ret = drmIoctl(buffer->kms->fd, DRM_IOCTL_GEM_CLOSE, &close);
+               if (ret)
+                       WLKMS_DEBUG("%s: %s: DRM_IOCTL_GEM_CLOSE failed.(%s)\n",
+                                __FILE__, __func__, strerror(errno));
+       }
+
        free(buffer);
 }
 
@@ -80,7 +106,13 @@ kms_authenticate(struct wl_client *client, struct wl_resource *resource,
 
        WLKMS_DEBUG("%s: %s: magic=%lu\n", __FILE__, __func__, magic);
 
-       if (drmAuthMagic(kms->fd, magic) < 0) {
+       if (kms->auth) {
+               err = kms_auth_request(kms->auth, magic);
+       } else {
+               err = drmAuthMagic(kms->fd, magic);
+       }
+
+       if (err < 0) {
                wl_resource_post_error(resource, WL_KMS_ERROR_AUTHENTICATION_FAILED,
                                       "authentication failed");
                WLKMS_DEBUG("%s: %s: authentication failed.\n", __FILE__, __func__);
@@ -91,18 +123,36 @@ kms_authenticate(struct wl_client *client, struct wl_resource *resource,
 }
 
 static void
-kms_create_buffer(struct wl_client *client, struct wl_resource *resource,
-                 uint32_t id, int32_t prime_fd, int32_t width, int32_t height,
-                 uint32_t stride, uint32_t format, uint32_t handle)
+kms_create_mp_buffer(struct wl_client *client, struct wl_resource *resource,
+                    uint32_t id, int32_t width, int32_t height, uint32_t format,
+                    int32_t fd0, uint32_t stride0, int32_t fd1, uint32_t stride1,
+                    int32_t fd2, uint32_t stride2)
 {
        struct wl_kms *kms = resource->data;
        struct wl_kms_buffer *buffer;
-       int err;
+       int err, nplanes;
 
        switch (format) {
        case WL_KMS_FORMAT_ARGB8888:
        case WL_KMS_FORMAT_XRGB8888:
+       case WL_KMS_FORMAT_ABGR8888:
+       case WL_KMS_FORMAT_XBGR8888:
+       case WL_KMS_FORMAT_RGB888:
+       case WL_KMS_FORMAT_BGR888:
+       case WL_KMS_FORMAT_YUYV:
+       case WL_KMS_FORMAT_UYVY:
+       case WL_KMS_FORMAT_RGB565:
+       case WL_KMS_FORMAT_BGR565:
+               nplanes = 1;
+               break;
+
+       case WL_KMS_FORMAT_NV12:
+       case WL_KMS_FORMAT_NV21:
+       case WL_KMS_FORMAT_NV16:
+       case WL_KMS_FORMAT_NV61:
+               nplanes = 2;
                break;
+
        default:
                wl_resource_post_error(resource,
                                       WL_KMS_ERROR_INVALID_FORMAT,
@@ -120,35 +170,30 @@ kms_create_buffer(struct wl_client *client, struct wl_resource *resource,
        buffer->width = width;
        buffer->height = height;
        buffer->format = format;
-       buffer->stride = stride;
-       buffer->fd = prime_fd;
+       buffer->num_planes = nplanes;
+       buffer->stride = buffer->planes[0].stride = stride0;
+       buffer->fd = buffer->planes[0].fd = fd0;
+
+       if (nplanes > 1) {
+               buffer->planes[1].stride = stride1;
+               buffer->planes[1].fd = fd1;
+       }
+
+       if (nplanes > 2) {
+               buffer->planes[2].stride = stride2;
+               buffer->planes[2].fd = fd2;
+       }
 
-       WLKMS_DEBUG("%s: %s: prime_fd=%d\n", __FILE__, __func__, prime_fd);
-#if 0
-       if ((err = drmPrimeFDToHandle(kms->fd, prime_fd, &buffer->handle))) {
+       WLKMS_DEBUG("%s: %s: %d planes (%d, %d, %d)\n", __FILE__, __func__, nplanes, fd0, fd1, fd2);
+
+       // XXX: Do we need to support multiplaner KMS BO?
+       if ((nplanes == 1) && (err = drmPrimeFDToHandle(kms->fd, fd0, &buffer->handle))) {
                WLKMS_DEBUG("%s: %s: drmPrimeFDToHandle() failed...%d (%s)\n", __FILE__, __func__, err, strerror(errno));
                wl_resource_post_error(resource,
                                       WL_KMS_ERROR_INVALID_FD,
                                       "invalid prime FD");
                return;
        }
-#else
-       {
-               struct drm_gem_open op;
-               int ret;
-
-               op.name   = prime_fd;
-               op.handle = 0;
-
-               ret = drmIoctl(kms->fd, DRM_IOCTL_GEM_OPEN, &op);
-               if (ret) {
-                       WLKMS_DEBUG("%s: %s: DRM_IOCTL_GEM_OPEN failed...(%s)\n", __FILE__, __func__, strerror(errno));
-                       wl_resource_post_error(resource, WL_KMS_ERROR_INVALID_FD, "invalid prime FD");
-                       return;
-               }
-               buffer->handle = op.handle;
-       }
-#endif
 
        // We create a wl_buffer
        buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, id);
@@ -163,9 +208,20 @@ kms_create_buffer(struct wl_client *client, struct wl_resource *resource,
                                       buffer, destroy_buffer);
 }
 
+
+static void
+kms_create_buffer(struct wl_client *client, struct wl_resource *resource,
+                 uint32_t id, int32_t prime_fd, int32_t width, int32_t height,
+                 uint32_t stride, uint32_t format, uint32_t handle)
+{
+       kms_create_mp_buffer(client, resource, id, width, height, format, prime_fd, stride,
+                            0, 0, 0, 0);
+}
+
 const static struct wl_kms_interface kms_interface = {
        .authenticate = kms_authenticate,
        .create_buffer = kms_create_buffer,
+       .create_mp_buffer = kms_create_mp_buffer,
 };
 
 static void
@@ -188,6 +244,11 @@ bind_kms(struct wl_client *client, void *data, uint32_t version, uint32_t id)
        wl_resource_post_event(resource, WL_KMS_FORMAT, WL_KMS_FORMAT_XRGB8888);
 }
 
+int wayland_kms_fd_get(struct wl_kms* kms)
+{
+       return kms->fd;
+}
+
 struct wl_kms_buffer *wayland_kms_buffer_get(struct wl_resource *resource)
 {
        if (resource == NULL)
@@ -200,19 +261,44 @@ struct wl_kms_buffer *wayland_kms_buffer_get(struct wl_resource *resource)
                return NULL;
 }
 
-struct wl_kms *wayland_kms_init(struct wl_display *display, char *device_name, int fd)
+struct wl_kms *wayland_kms_init(struct wl_display *display,
+                               struct wl_display *server, char *device_name, int fd)
 {
        struct wl_kms *kms;
 
-       kms = malloc(sizeof *kms);
+       if (!(kms = calloc(1, sizeof(struct wl_kms))))
+               return NULL;
 
        kms->display = display;
        kms->device_name = strdup(device_name);
        kms->fd = fd;
 
-       wl_global_create(display, &wl_kms_interface, 1, kms, bind_kms);
+       wl_global_create(display, &wl_kms_interface, 2, kms, bind_kms);
+
+       /*
+        * we're the server in the middle. we should forward the auth
+        * request to our server.
+        */
+       if (server) {
+               drm_magic_t magic;
+
+               if (!(kms->auth = kms_auth_init(server)))
+                       goto error;
+
+               /* get a magic */
+               if (drmGetMagic(fd, &magic) < 0)
+                       goto error;
+
+               /* authenticate myself */
+               if (kms_auth_request(kms->auth, magic) < 0)
+                       goto error;
+       }
 
        return kms;
+
+error:
+       free(kms);
+       return NULL;
 }
 
 void wayland_kms_uninit(struct wl_kms *kms)
@@ -246,7 +332,7 @@ int wayland_kms_query_buffer(struct wl_kms *kms, struct wl_resource *resource,
                return 0;
        
        case WL_KMS_TEXTURE_FORMAT:
-               *value = WL_KMS_FORMAT_ARGB8888;
+               *value = EGL_TEXTURE_RGBA;
                return 0;
        }