If drm fd is negative value, get fd with wayland protocol 51/61351/1
authorChangyeon Lee <cyeon.lee@samsung.com>
Sun, 10 Jan 2016 08:52:13 +0000 (17:52 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 7 Mar 2016 10:41:50 +0000 (19:41 +0900)
Change-Id: I71dfe3aab0f4e2b502f1a96613aa48a0baefecea

configure.ac
packaging/libtbm-dumb.spec
src/Makefile.am
src/tbm_bufmgr_dumb.c
src/tbm_wayland.c [new file with mode: 0644]
src/tbm_wayland.h [new file with mode: 0644]

index 510fe0c..15826cf 100644 (file)
@@ -39,6 +39,10 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 PKG_CHECK_MODULES(LIBDRM, libdrm)
 PKG_CHECK_MODULES(LIBTBM, libtbm)
 PKG_CHECK_MODULES(DLOG, dlog)
+PKG_CHECK_MODULES(WAYLAND_CLIENT, wayland-client wayland-server)
+
+WYLAND_PREFIX=`$PKG_CONFIG --variable=prefix wayland-client wayland-server`
+AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner],, [${WAYLAND_PREFIX}/bin$PATH_SEPARATOR$PATH])
 
 AC_ARG_ENABLE(cachectrl,
              AS_HELP_STRING([--enable-cachectrl],
@@ -49,8 +53,8 @@ if test "x$CACHE_CTRL" = xyes; then
     AC_DEFINE(ENABLE_CACHECRTL, 1, [Enable cache control])
 fi
 
-LIBTBM_DUMB_CFLAGS="$LIBDRM_CFLAGS $LIBTBM_CFLAGS $DLOG_CFLAGS "
-LIBTBM_DUMB_LIBS="$LIBDRM_LIBS $LIBTBM_LIBS $DLOG_LIBS "
+LIBTBM_DUMB_CFLAGS="$LIBDRM_CFLAGS $LIBTBM_CFLAGS $DLOG_CFLAGS $WAYLAND_CLIENT_CLFAGS "
+LIBTBM_DUMB_LIBS="$LIBDRM_LIBS $LIBTBM_LIBS $DLOG_LIBS $WAYLAND_CLIENT_LIBS "
 AC_SUBST(LIBTBM_DUMB_CFLAGS)
 AC_SUBST(LIBTBM_DUMB_LIBS)
 
index ce22ee3..9b4ad6a 100644 (file)
@@ -12,6 +12,7 @@ BuildRequires:  pkgconfig(pthread-stubs)
 BuildRequires:  pkgconfig(libdrm)
 BuildRequires:  pkgconfig(libtbm)
 BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(wayland-client)
 
 %description
 descriptionion: Tizen Buffer manager backend module uses drm dumb
index 864f44b..161a61a 100644 (file)
@@ -1,11 +1,13 @@
 AM_CFLAGS = \
        @LIBTBM_DUMB_CFLAGS@ \
        -I$(top_srcdir) \
-       -I$(top_srcdir)/src
+       -I$(top_srcdir)/src \
+       -I/usr/include/drm
 
 libtbm_dumb_la_LTLIBRARIES = libtbm_dumb.la
 libtbm_dumb_ladir = /${bufmgr_dir}
 libtbm_dumb_la_LIBADD = @LIBTBM_DUMB_LIBS@
 
 libtbm_dumb_la_SOURCES = \
-       tbm_bufmgr_dumb.c
+       tbm_bufmgr_dumb.c \
+       tbm_wayland.c
index d806f73..620e200 100644 (file)
@@ -49,6 +49,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <pthread.h>
 #include <tbm_surface.h>
 #include <tbm_surface_internal.h>
+#include "tbm_wayland.h"
 
 #define DEBUG
 #define USE_DMAIMPORT
@@ -191,6 +192,8 @@ struct _tbm_bufmgr_dumb
     void* hashBos;
 
     int use_dma_fence;
+
+    int fd_owner;
 };
 
 char *STR_DEVICE[]=
@@ -1137,6 +1140,9 @@ tbm_dumb_bufmgr_deinit (void *priv)
         bufmgr_dumb->hashBos = NULL;
     }
 
+    if (bufmgr_dumb->fd_owner)
+        close(bufmgr_dumb->fd);
+
     free (bufmgr_dumb);
 }
 
@@ -1789,8 +1795,15 @@ init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
         return 0;
     }
 
-    bufmgr_dumb->fd = fd;
-    if (bufmgr_dumb->fd < 0)
+    if (fd < 0)
+    {
+        bufmgr_dumb->fd = tbm_bufmgr_get_drm_fd_wayland();
+        bufmgr_dumb->fd_owner = 1;
+    }
+    else
+        bufmgr_dumb->fd = fd;
+
+    if (bufmgr_dumb->fd  < 0)
     {
         TBM_DUMB_LOG ("error: Fail to create drm!\n");
         free (bufmgr_dumb);
@@ -1820,6 +1833,10 @@ init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
         TBM_DUMB_LOG ("error: Fail to create drm!\n");
         if (bufmgr_dumb->hashBos)
             drmHashDestroy (bufmgr_dumb->hashBos);
+
+        if (bufmgr_dumb->fd_owner)
+            close(bufmgr_dumb->fd);
+
         free (bufmgr_dumb);
         return 0;
     }
@@ -1861,6 +1878,10 @@ init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
     if (!tbm_backend_init (bufmgr, bufmgr_backend))
     {
         TBM_DUMB_LOG ("error: Fail to init backend!\n");
+
+        if (bufmgr_dumb->fd_owner)
+            close(bufmgr_dumb->fd);
+
         tbm_backend_free (bufmgr_backend);
         free (bufmgr_dumb);
         return 0;
diff --git a/src/tbm_wayland.c b/src/tbm_wayland.c
new file mode 100644 (file)
index 0000000..57286ff
--- /dev/null
@@ -0,0 +1,279 @@
+/**************************************************************************
+
+libtbm
+
+Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
+Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "config.h"
+
+#include <xf86drm.h>
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <wayland-client.h>
+
+#include "wayland-util.h"
+
+extern const struct wl_interface wl_buffer_interface;
+
+static const struct wl_interface *types[] = {
+       NULL,
+       NULL,
+       NULL,
+       &wl_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &wl_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+};
+
+static const struct wl_message wl_tbm_requests[] = {
+       {"create_buffer", "niiuiiiiiiiiiiuiuuu", types + 3},
+       {"create_buffer_with_fd", "niiuiiiiiiiiiiuihhh", types + 22},
+       {"get_authentication_info", "", types + 0},
+};
+
+static const struct wl_message wl_tbm_events[] = {
+       {"authentication_info", "suh", types + 0},
+};
+
+WL_EXPORT const struct wl_interface wl_tbm_interface = {
+       "wl_tbm", 1,
+       3, wl_tbm_requests,
+       1, wl_tbm_events,
+};
+
+struct wl_buffer;
+struct wl_tbm;
+
+extern const struct wl_interface wl_tbm_interface;
+
+#ifndef WL_TBM_ERROR_ENUM
+#define WL_TBM_ERROR_ENUM
+enum wl_tbm_error {
+       WL_TBM_ERROR_AUTHENTICATE_FAIL = 0,
+       WL_TBM_ERROR_INVALID_FORMAT = 1,
+       WL_TBM_ERROR_INVALID_NAME = 2,
+};
+#endif                                                 /* WL_TBM_ERROR_ENUM */
+
+struct wl_tbm_listener {
+       /**
+     * authentication_info - (none)
+     * @device_name: (none)
+     * @capabilities: (none)
+     * @auth_fd: (none)
+     */
+       void (*authentication_info) (void *data, struct wl_tbm * wl_tbm, const char *device_name, uint32_t capabilities, int32_t auth_fd);
+};
+
+static inline int wl_tbm_add_listener(struct wl_tbm *wl_tbm, const struct wl_tbm_listener *listener, void *data)
+{
+       return wl_proxy_add_listener((struct wl_proxy *)wl_tbm, (void (**)(void))listener, data);
+}
+
+#define WL_TBM_CREATE_BUFFER    0
+#define WL_TBM_CREATE_BUFFER_WITH_FD    1
+#define WL_TBM_GET_AUTHENTICATION_INFO  2
+
+static inline void wl_tbm_set_user_data(struct wl_tbm *wl_tbm, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *)wl_tbm, user_data);
+}
+
+static inline void *wl_tbm_get_user_data(struct wl_tbm *wl_tbm)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *)wl_tbm);
+}
+
+static inline void wl_tbm_destroy(struct wl_tbm *wl_tbm)
+{
+       wl_proxy_destroy((struct wl_proxy *)wl_tbm);
+}
+
+static inline void wl_tbm_get_authentication_info(struct wl_tbm *wl_tbm)
+{
+       wl_proxy_marshal((struct wl_proxy *)wl_tbm, WL_TBM_GET_AUTHENTICATION_INFO);
+}
+
+struct wl_tbm_info {
+       struct wl_display *dpy;
+       struct wl_event_queue *wl_queue;
+       struct wl_tbm *wl_tbm;
+
+       uint32_t capabilities;
+       char *device;
+       int32_t fd;
+};
+
+static void handle_tbm_authentication_info(void *data, struct wl_tbm *wl_tbm, const char *device_name, uint32_t capabilities, int32_t auth_fd)
+{
+       struct wl_tbm_info *info = (struct wl_tbm_info *)data;
+
+       info->fd = auth_fd;
+       info->capabilities = capabilities;
+       if (device_name)
+               info->device = strndup(device_name, 256);
+}
+
+static const struct wl_tbm_listener wl_tbm_client_listener = {
+       handle_tbm_authentication_info
+};
+
+static void wl_client_registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
+{
+       struct wl_tbm_info *info = (struct wl_tbm_info *)data;
+
+       if (!strcmp(interface, "wl_tbm")) {
+               info->wl_tbm = wl_registry_bind(registry, name, &wl_tbm_interface, version);
+               if (!info->wl_tbm) {
+                       printf("Failed to bind wl_tbm\n");
+                       return;
+               }
+
+               wl_tbm_add_listener(info->wl_tbm, &wl_tbm_client_listener, info);
+               wl_proxy_set_queue((struct wl_proxy *)info->wl_tbm, info->wl_queue);
+       }
+}
+
+static int tbm_util_get_drm_fd(void *dpy, int *fd)
+{
+       struct wl_display *disp = NULL;
+       struct wl_registry *wl_registry;
+       struct wl_tbm_info info = {
+               .dpy = NULL,
+               .wl_queue = NULL,
+               .wl_tbm = NULL,
+               .capabilities = 0,
+               .device = NULL,
+               .fd = 0,
+       };
+
+       static const struct wl_registry_listener registry_listener = {
+               wl_client_registry_handle_global,
+               NULL
+       };
+
+       if (!fd)
+               return -1;
+
+       if (!dpy) {
+               disp = wl_display_connect(NULL);
+               if (!disp) {
+                       printf("Failed to create a new display connection\n");
+                       return -1;
+               }
+               dpy = disp;
+       }
+
+       info.dpy = dpy;
+       info.wl_queue = wl_display_create_queue(dpy);
+       if (!info.wl_queue) {
+               printf("Failed to create a WL Queue\n");
+               if (disp == dpy)
+                       wl_display_disconnect(disp);
+
+               return -1;
+       }
+
+       wl_registry = wl_display_get_registry(dpy);
+       if (!wl_registry) {
+               printf("Failed to get registry\n");
+               wl_event_queue_destroy(info.wl_queue);
+               if (disp == dpy)
+                       wl_display_disconnect(disp);
+
+               return -1;
+       }
+       wl_proxy_set_queue((struct wl_proxy *)wl_registry, info.wl_queue);
+       wl_registry_add_listener(wl_registry, &registry_listener, &info);
+       wl_display_roundtrip_queue(dpy, info.wl_queue);
+
+       wl_tbm_get_authentication_info(info.wl_tbm);
+       wl_display_roundtrip_queue(dpy, info.wl_queue);
+
+       *fd = info.fd;
+
+       wl_event_queue_destroy(info.wl_queue);
+       wl_registry_destroy(wl_registry);
+
+       free(info.device);
+       wl_tbm_set_user_data(info.wl_tbm, NULL);
+       wl_tbm_destroy(info.wl_tbm);
+
+       if (disp == dpy)
+               wl_display_disconnect(disp);
+
+       return *fd >= 0 ? 0 : -1;
+}
+
+int tbm_bufmgr_get_drm_fd_wayland()
+{
+       int fd = -1;
+
+       if (tbm_util_get_drm_fd(NULL, &fd))
+               printf("Failed to get drm_fd\n");
+
+       return fd;
+}
diff --git a/src/tbm_wayland.h b/src/tbm_wayland.h
new file mode 100644 (file)
index 0000000..32ba395
--- /dev/null
@@ -0,0 +1,38 @@
+/**************************************************************************
+
+libtbm
+
+Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
+Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef _TBM_UTIL_H_
+#define _TBM_UTIL_H_
+
+int tbm_bufmgr_get_drm_fd_wayland();
+
+#endif /* _TBM_UTIL_H_ */
+