X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=wayland-kms.c;h=2ea3a8d853c3301fe7c25fae46601f2e9e9a6a31;hb=79ef0ee652e146c879b83acaee9baf438704d73b;hp=0a8684558a695d74d9b4aa3a1ccdc6a3cf30a738;hpb=ce654772cc1130eed1838060d3be03c92e400f60;p=platform%2Fadaptation%2Frenesas_rcar%2Fwayland-kms.git diff --git a/wayland-kms.c b/wayland-kms.c index 0a86845..2ea3a8d 100644 --- a/wayland-kms.c +++ b/wayland-kms.c @@ -41,6 +41,7 @@ #include #include #include "wayland-kms.h" +#include "wayland-kms-auth.h" #include "wayland-kms-server-protocol.h" #if defined(DEBUG) @@ -49,15 +50,40 @@ # 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; }