From 42ff2bcad0fb1b4a3ce4b7c96382fa0507e06cf6 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Sun, 10 Jan 2016 17:52:13 +0900 Subject: [PATCH] If drm fd is negative value, get fd with wayland protocol Change-Id: I71dfe3aab0f4e2b502f1a96613aa48a0baefecea --- configure.ac | 8 +- packaging/libtbm-dumb.spec | 1 + src/Makefile.am | 6 +- src/tbm_bufmgr_dumb.c | 25 +++- src/tbm_wayland.c | 279 +++++++++++++++++++++++++++++++++++++++++++++ src/tbm_wayland.h | 38 ++++++ 6 files changed, 351 insertions(+), 6 deletions(-) create mode 100644 src/tbm_wayland.c create mode 100644 src/tbm_wayland.h diff --git a/configure.ac b/configure.ac index 510fe0c..15826cf 100644 --- a/configure.ac +++ b/configure.ac @@ -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) diff --git a/packaging/libtbm-dumb.spec b/packaging/libtbm-dumb.spec index ce22ee3..9b4ad6a 100644 --- a/packaging/libtbm-dumb.spec +++ b/packaging/libtbm-dumb.spec @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index 864f44b..161a61a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/tbm_bufmgr_dumb.c b/src/tbm_bufmgr_dumb.c index d806f73..620e200 100644 --- a/src/tbm_bufmgr_dumb.c +++ b/src/tbm_bufmgr_dumb.c @@ -49,6 +49,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#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 index 0000000..57286ff --- /dev/null +++ b/src/tbm_wayland.c @@ -0,0 +1,279 @@ +/************************************************************************** + +libtbm + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee +Boram Park , Changyeon Lee + +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 + +#include +#include +#include +#include +#include +#include + +#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, ®istry_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 index 0000000..32ba395 --- /dev/null +++ b/src/tbm_wayland.h @@ -0,0 +1,38 @@ +/************************************************************************** + +libtbm + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee +Boram Park , Changyeon Lee + +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_ */ + -- 2.7.4