-SUBDIRS = src drm_slp
+SUBDIRS = src
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libtbm.pc
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
AC_PREREQ(2.60)
-AC_INIT(libtbm, 1.0.0)
+AC_INIT(libtbm, 1.1.0)
AC_USE_SYSTEM_EXTENSIONS
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([dist-bzip2])
# Enable quiet compiles on automake 1.11.
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+dnl Make sure the pkg-config macros are defined
+m4_ifndef([PKG_PROG_PKG_CONFIG],
+ [m4_fatal([Could not locate the pkg-config autoconf macros.
+ These are usually located in /usr/share/aclocal/pkg.m4. If your macros
+ are in a different location, try setting the environment variable
+ ACLOCAL="aclocal -I/other/macro/dir" before running autoreconf.])])
+PKG_PROG_PKG_CONFIG()
+
# set the dir for the tbm module
-DEFAULT_BUFMGR_MODULE_PATH="/usr/lib/bufmgr"
+DEFAULT_BUFMGR_MODULE_PATH="${libdir}/bufmgr"
AC_ARG_WITH(bufmgr-module-path, AS_HELP_STRING([--with-bufmgr-module-path=PATH], [tbm bufmgr module dir]),
[ BUFMGR_MODULE_PATH="$withval" ],
[ BUFMGR_MODULE_PATH="${DEFAULT_BUFMGR_MODULE_PATH}" ])
+
+# set the window system platform where the bufmgr initializes
+AC_ARG_WITH(tbm-platform, AS_HELP_STRING([--with-tbm-platform=WINSYS], [tbm platform (default: X11)]),
+ [ TBM_PLATFORM="$withval" ],
+ [ TBM_PLATFORM="X11" ])
+AC_SUBST(TBM_PLATFORM)
+
#AC_DEFINE(BUFMGR_MODULE_DIR, "${BUFMGR_MODULE_PATH}", [Directory for the modules of tbm_bufmgr])
AC_DEFINE_UNQUOTED(BUFMGR_MODULE_DIR, "${BUFMGR_MODULE_PATH}", [Directory for the modules of tbm_bufmgr])
[AC_MSG_ERROR([Couldn't find clock_gettime])])])
AC_SUBST([CLOCK_LIB])
-PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs)
-PKG_CHECK_MODULES(LIBDRM, libdrm)
-PKG_CHECK_MODULES(LIBDRI2, libdri2)
-PKG_CHECK_MODULES(DLOG, dlog)
-PKG_CHECK_MODULES(X11, x11)
+
+if test "x$TBM_PLATFORM" = "xX11"; then
+ PKG_CHECK_MODULES(LIBDRI2, libdri2)
+ PKG_CHECK_MODULES(X11, x11)
+ LIBTBM_CFLAGS="$LIBDRI2_CFLAGS $X11_CFLAGS"
+ LIBTBM_LIBS="$LIBDRI2_LIBS $X11_LIBS"
+fi
+
+if test "x$TBM_PLATFORM" = "xWAYLAND"; then
+ PKG_CHECK_MODULES(WAYLAND_CLIENT, wayland-client wayland-server)
+ LIBTBM_CFLAGS="$WAYLAND_CLIENT_CFLAGS"
+ LIBTBM_LIBS="$WAYLAND_CLIENT_LIBS"
+
+ WAYLAND_PREFIX=`$PKG_CONFIG --variable=prefix wayland-client wayland-server`
+ AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner],,
+ [${WAYLAND_PREFIX}/bin$PATH_SEPARATOR$PATH])
+fi
+
PKG_CHECK_MODULES(CAPI, [capi-base-common >= 0.1.1], [capi_0_1_1=yes], [capi_0_1_1=no])
if test x"$capi_0_1_1" = xyes; then
AC_DEFINE(HAVE_CAPI_0_1_1,1,[The version of capi-base-common is over 0.1.1])
fi
-LIBTBM_CFLAGS="$PTHREADSTUBS_CFLAGS $LIBDRM_CFLAGS $LIBDRI2_CFLAGS $X11_CFLAGS $CAPI_CFLAGS"
-LIBTBM_LIBS="$PTHREADSTUBS_LIBS $LIBDRM_LIBS $LIBDRI2_LIBS $DLOG_LIBS $X11_LIBS $CAPI_LIBS"
+PKG_CHECK_MODULES(LIBDRM, libdrm)
+PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs)
+
+LIBTBM_CFLAGS+="$LIBTBM_CFALGS $LIBDRM_CFLAGS $PTHREADSTUBS_CFLAGS $CAPI_CFLAGS"
+LIBTBM_LIBS+="$LIBTBM_LIBS $LIBDRM_LIBS $PTHREADSTUBS_LIBS $CAPI_LIBS"
AC_SUBST(LIBTBM_CFLAGS)
AC_SUBST(LIBTBM_LIBS)
+if test "x$TBM_PLATFORM" = "xX11"; then
+ AC_DEFINE(HAVE_X11,1,[The window system is X11.])
+else
+ AC_DEFINE(HAVE_WAYLAND,1,[The window system is WAYLAND.])
+fi
+
+HOST_CPU_X86_64=no
+case $host_cpu in
+ x86_64*|amd64*)
+ HOST_CPU_X86_64=yes
+esac
+
+AM_CONDITIONAL(HAVE_TBM_PLATFORM_X11, test "x$TBM_PLATFORM" = "xX11")
+AM_CONDITIONAL(HAVE_TBM_PLATFORM_WAYLAND, test "x$TBM_PLATFORM" = "xWAYLAND")
+AM_CONDITIONAL(HOST_CPU_X86_64, test "x$HOST_CPU_X86_64" = "xyes")
+
AC_OUTPUT([
- src/Makefile
- drm_slp/Makefile
+ src/Makefile
Makefile
libtbm.pc])
echo "LIBTBM_CFLAGS : $LIBTBM_CFLAGS"
echo "LIBTBM_LIBS : $LIBTBM_LIBS"
echo "BUFMGR_MODULE_DIR : $BUFMGR_MODULE_PATH"
+echo "TBM_PLATFORM : $TBM_PLATFORM"
echo ""
-#ifndef __TIZEN_UI_TBM_SURFACE_DOC_H__
-#define __TIZEN_UI_TBM_SURFACE_DOC_H__
+#ifndef __SAMSUNG_UI_TBM_SURFACE_DOC_H__
+#define __SAMSUNG_UI_TBM_SURFACE_DOC_H__
/**
* @defgroup CAPI_UI_TBM_SURFACE_MODULE TBM Surface
* - Get the information of surface and planes.
*/
-#endif /* __TIZEN_UI_TBM_SURFACE_DOC_H__ */
+#endif /* __SAMSUNG_UI_TBM_SURFACE_DOC_H__ */
+++ /dev/null
-SUBDIRS = .
-
-AM_CFLAGS = \
- $(WARN_CFLAGS) \
- -I$(top_srcdir) \
- -I$(top_srcdir)/src \
- -I$(top_srcdir)/drm_slp \
- $(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
-
-libdrm_slp_la_LTLIBRARIES = libdrm_slp.la
-libdrm_slp_ladir = $(libdir)
-libdrm_slp_la_LDFLAGS = -version-number 1:0:0 -no-undefined
-libdrm_slp_la_LIBADD = ../src/libtbm.la @PTHREADSTUBS_LIBS@ @CLOCK_LIB@ -ldl
-
-libdrm_slp_la_SOURCES = \
- drm_slp_bufmgr.c \
- drm_slp_bufmgr.h
-
+++ /dev/null
-/**************************************************************************
-
-xserver-xorg-video-sec
-
-Copyright 2011 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@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 <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "drm_slp_bufmgr.h"
-#include "tbm_bufmgr.h"
-#include "tbm_bufmgr_int.h"
-
-drm_slp_bufmgr
-drm_slp_bufmgr_init(int fd, void *arg)
-{
- tbm_bufmgr bufmgr = NULL;
-
- bufmgr = tbm_bufmgr_init (fd);
- if (!bufmgr)
- {
- TBM_LOG ("[libdrm_slp:%d]: error bufmgr is null\n", getpid());
- return NULL;
- }
-
- return (drm_slp_bufmgr)bufmgr;
-}
-
-void
-drm_slp_bufmgr_destroy(drm_slp_bufmgr bufmgr)
-{
- tbm_bufmgr_deinit ((tbm_bufmgr)bufmgr);
-}
-
-void
-drm_slp_bo_unref(drm_slp_bo bo)
-{
- tbm_bo_unref ((tbm_bo)bo);
-}
-
-drm_slp_bo
-drm_slp_bo_import(drm_slp_bufmgr bufmgr, unsigned int key)
-{
- tbm_bo bo = NULL;
-
- bo = tbm_bo_import ((tbm_bufmgr)bufmgr, key);
- if (!bo)
- {
- TBM_LOG ("[libdrm_slp:%d]: error bo is null\n", getpid());
- return NULL;
- }
-
- return (drm_slp_bo)bo;
-}
-
-unsigned int
-drm_slp_bo_map(drm_slp_bo bo, int device, int opt)
-{
- tbm_bo_handle bo_handle;
- unsigned int ret = 0;
-
- bo_handle = tbm_bo_map ((tbm_bo)bo, device, opt);
- if (bo_handle.ptr == NULL)
- {
- TBM_LOG ("[libdrm_slp:%d]: error bo_handle is null\n", getpid());
- return 0;
- }
-
- switch (device)
- {
- case TBM_DEVICE_DEFAULT:
- case TBM_DEVICE_2D:
- case TBM_DEVICE_3D:
- case TBM_DEVICE_MM:
- ret = (unsigned int)bo_handle.u32;
- break;
- case TBM_DEVICE_CPU:
- ret = (unsigned int)bo_handle.ptr;
- break;
- default:
- TBM_LOG ("[libdrm_slp:%d]: error wrong device type\n", getpid());
- return 0;
- }
-
- return ret;
-}
-
-int
-drm_slp_bo_unmap(drm_slp_bo bo, int device)
-{
- tbm_bo_unmap ((tbm_bo)bo);
-
- return 1;
-}
-
+++ /dev/null
-/**************************************************************************
-
-xserver-xorg-video-sec
-
-Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
-
-Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@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 _DRM_SLP_BUFMGR_H_
-#define _DRM_SLP_BUFMGR_H_
-
-#include "tbm_bufmgr.h"
-
-typedef struct _drm_slp_bo * drm_slp_bo;
-typedef struct _drm_slp_bufmgr * drm_slp_bufmgr;
-
-/* Functions for buffer mnager */
-drm_slp_bufmgr drm_slp_bufmgr_init(int fd, void * arg);
-void drm_slp_bufmgr_destroy(drm_slp_bufmgr bufmgr);
-
-/*Functions for bo*/
-void drm_slp_bo_unref(drm_slp_bo bo);
-drm_slp_bo drm_slp_bo_import(drm_slp_bufmgr bufmgr, unsigned int key);
-unsigned int drm_slp_bo_map(drm_slp_bo bo, int device, int opt);
-int drm_slp_bo_unmap(drm_slp_bo bo, int device);
-
-#endif /* _DRM_SLP_BUFMGR_H_ */
+%bcond_with x
+%bcond_with wayland
+
Name: libtbm
-Version: 1.1.1
-Release: 5
+Version: 1.1.8
+Release: 1
License: MIT
Summary: The library for Tizen Buffer Manager
Group: System/Libraries
Source0: %{name}-%{version}.tar.gz
-BuildRequires: pkgconfig(pthread-stubs)
BuildRequires: pkgconfig(libdrm)
+BuildRequires: pkgconfig(pthread-stubs)
+%if %{with wayland}
+BuildRequires: pkgconfig
+BuildRequires: pkgconfig(wayland-client)
+%else
BuildRequires: pkgconfig(x11)
BuildRequires: pkgconfig(libdri2)
+%endif
BuildRequires: pkgconfig(capi-base-common)
-BuildRequires: pkgconfig(dlog)
%description
Description: %{summary}
%build
-%reconfigure --prefix=%{_prefix} \
+%if %{with wayland}
+%reconfigure --prefix=%{_prefix} --with-tbm-platform=WAYLAND \
CFLAGS="${CFLAGS} -Wall -Werror" LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed"
+%else
+%reconfigure --prefix=%{_prefix} --with-tbm-platform=X11 \
+ CFLAGS="${CFLAGS} -Wall -Werror" LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed"
+%endif
make %{?_smp_mflags}
%defattr(-,root,root,-)
/usr/share/license/%{name}
%{_libdir}/libtbm.so.*
-%{_libdir}/libdrm_slp.so.*
%files devel
%defattr(-,root,root,-)
%{_includedir}/tbm_bufmgr_backend.h
%{_includedir}/tbm_type.h
%{_libdir}/libtbm.so
-%{_libdir}/libdrm_slp.so
%{_libdir}/pkgconfig/libtbm.pc
-
-SUBDIRS = .
+SUBDIRS =
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -I./ \
-I$(top_srcdir) \
-I$(top_srcdir)/src \
$(PTHREADSTUBS_CFLAGS) \
libtbm_la_LDFLAGS = -version-number 1:0:0 -no-undefined
libtbm_la_LIBADD = @LIBTBM_LIBS@ @PTHREADSTUBS_LIBS@ @CLOCK_LIB@ -ldl
-libtbm_la_SOURCES = \
+libtbm_la_SOURCES =
+
+if HAVE_TBM_PLATFORM_X11
+ libtbm_la_SOURCES += \
+ tbm_x11.c
+endif
+
+if HAVE_TBM_PLATFORM_WAYLAND
+ libtbm_la_SOURCES += \
+ tbm_wayland.c
+endif
+
+libtbm_la_SOURCES += \
tbm_surface_internal.c \
tbm_surface.c \
tbm_bufmgr_backend.c \
#include "tbm_bufmgr_backend.h"
#include "tbm_bufmgr_tgl.h"
#include "list.h"
-#include <X11/Xmd.h>
-#include <dri2.h>
-#include <xf86drm.h>
#define DEBUG
#ifdef DEBUG
pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
tbm_bufmgr gBufMgr = NULL;
+static __thread tbm_error_e tbm_last_error = TBM_ERROR_NONE;
+
+static void
+_tbm_set_last_result(tbm_error_e err)
+{
+ tbm_last_error = err;
+}
+
static inline int
_tgl_init (int fd, unsigned int key)
{
tbm_bufmgr bufmgr = bo->bufmgr;
tbm_bo_cache_state cache_state;
+ if (bo->tgl_key == INITIAL_KEY)
+ bo->tgl_key = bufmgr->backend->bo_get_global_key (bo);
+
+ if (!bo->default_handle.u32)
+ bo->default_handle = bufmgr->backend->bo_get_handle (bo, TBM_DEVICE_DEFAULT);
+
RETURN_VAL_CHECK_FLAG (TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
cache_state.val = 0;
switch (opt)
{
case CACHE_OP_CREATE: /*Create*/
- if (bo->tgl_key == INITIAL_KEY)
- bo->tgl_key = bufmgr->backend->bo_get_global_key (bo);
_tgl_init (bufmgr->lock_fd, bo->tgl_key);
_tgl_set_data (bufmgr->lock_fd, bo->tgl_key, cache_state.val);
break;
case CACHE_OP_IMPORT: /*Import*/
- if (bo->tgl_key == INITIAL_KEY)
- bo->tgl_key = bufmgr->backend->bo_get_global_key (bo);
_tgl_init (bufmgr->lock_fd, bo->tgl_key);
break;
int ret = 0;
if (!bo)
- return ret;
+ return 0;
bufmgr = bo->bufmgr;
bo->lock_cnt++;
}
else
- TBM_DLOG ("[libtbm:%d] "
+ TBM_LOG ("[libtbm:%d] "
"error %s:%d bo:%p lock_type is wrong.\n",
getpid(), __FUNCTION__, __LINE__, bo);
abimaj = GET_ABI_MAJOR (data->abiversion);
abimin = GET_ABI_MINOR (data->abiversion);
- TBM_LOG ("[libtbm:%d] "
+ DBG ("[libtbm:%d] "
"TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
getpid(), data->modname ? data->modname : "UNKNOWN!",
data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
bufmgr->module_data = module_data;
- TBM_LOG ("[libtbm:%d] "
+ DBG ("[libtbm:%d] "
"Success to load module(%s)\n", getpid(), file);
return 1;
return ret;
}
-static int
-_tbm_bufmgr_get_drm_fd()
-{
- int screen;
- Display *display;
- int dri2Major, dri2Minor;
- int eventBase, errorBase;
- drm_magic_t magic;
- char *driver_name, *device_name;
- int fd;
-
- display = XOpenDisplay(NULL);
- if (!display)
- {
- TBM_LOG ("[libtbm:%d] Fail XOpenDisplay\n", getpid());
- return -1;
- }
-
- screen = DefaultScreen(display);
-
- if (!DRI2QueryExtension (display, &eventBase, &errorBase))
- {
- TBM_LOG ("[libtbm:%d] Fail DRI2QueryExtention\n", getpid());
- XCloseDisplay(display);
- return -1;
- }
-
- if (!DRI2QueryVersion (display, &dri2Major, &dri2Minor))
- {
- TBM_LOG ("[libtbm:%d] Fail DRI2QueryVersion\n", getpid());
- XCloseDisplay(display);
- return -1;
- }
-
- if (!DRI2Connect (display, RootWindow(display, screen), &driver_name, &device_name))
- {
- TBM_LOG ("[libtbm:%d] Fail DRI2Connect\n", getpid());
- XCloseDisplay(display);
- return -1;
- }
-
- fd = open (device_name, O_RDWR);
- if (fd < 0)
- {
- TBM_LOG ("[libtbm:%d] cannot open drm device (%s)\n", getpid(), device_name);
- free (driver_name);
- free (device_name);
- XCloseDisplay(display);
- return -1;
- }
-
- if (drmGetMagic (fd, &magic))
- {
- TBM_LOG ("[libtbm:%d] Fail drmGetMagic\n", getpid());
- free (driver_name);
- free (device_name);
- close(fd);
- XCloseDisplay(display);
- return -1;
- }
-
- if (!DRI2Authenticate(display, RootWindow(display, screen), magic))
- {
- TBM_LOG ("[libtbm:%d] Fail DRI2Authenticate\n", getpid());
- free (driver_name);
- free (device_name);
- close(fd);
- XCloseDisplay(display);
- return -1;
- }
-
- if(!drmAuthMagic(fd, magic))
- {
- TBM_LOG ("[libtbm:%d] Fail drmAuthMagic\n", getpid());
- free (driver_name);
- free (device_name);
- close(fd);
- XCloseDisplay(display);
- return -1;
- }
-
- free (driver_name);
- free (device_name);
- XCloseDisplay(display);
- return fd;
-}
-
tbm_bufmgr
tbm_bufmgr_init (int fd)
{
char *env;
int fd_flag = 0;
+ int backend_flag = 0;
pthread_mutex_lock (&gLock);
/* initialize buffer manager */
if (gBufMgr)
{
- TBM_LOG ("[libtbm:%d] use previous gBufMgr\n", getpid());
+ DBG ("[libtbm:%d] use previous gBufMgr\n", getpid());
gBufMgr->ref_count++;
- if (dup2(gBufMgr->fd, fd) < 0) {
- TBM_LOG ("[libtbm:%d] Fail to duplicate the drm fd\n", getpid());
- pthread_mutex_unlock (&gLock);
+ if (fd >= 0)
+ {
+ if (dup2(gBufMgr->fd, fd) < 0) {
+ _tbm_set_last_result (TBM_BO_ERROR_DUP_FD_FAILED);
+ DBG ("[libtbm:%d] Fail to duplicate(dup2) the drm fd\n", getpid());
+ pthread_mutex_unlock (&gLock);
+ return NULL;
+ }
+ DBG ("[libtbm:%d] duplicate the drm_fd(%d), new drm_fd(%d).\n",
+ getpid(), gBufMgr->fd, fd);
}
- TBM_LOG ("[libtbm:%d] duplicate the drm_fd(%d), new drm_fd(%d).\n",
- getpid(), gBufMgr->fd, fd);
- TBM_LOG ("[libtbm:%d] bufmgr ref: fd=%d, ref_count:%d\n",
+ DBG ("[libtbm:%d] bufmgr ref: fd=%d, ref_count:%d\n",
getpid(), gBufMgr->fd, gBufMgr->ref_count);
pthread_mutex_unlock (&gLock);
return gBufMgr;
if (fd < 0)
{
- fd = _tbm_bufmgr_get_drm_fd();
+#ifdef HAVE_X11
+ fd = tbm_bufmgr_get_drm_fd_x11();
+#elif HAVE_WAYLAND
+ fd = tbm_bufmgr_get_drm_fd_wayland();
+#endif
if (fd < 0)
{
+ _tbm_set_last_result (TBM_BO_ERROR_GET_FD_FAILED);
TBM_LOG ("[libtbm:%d] Fail get drm fd\n", getpid());
pthread_mutex_unlock (&gLock);
return NULL;
fd_flag = 1;
}
- TBM_LOG ("[libtbm:%d] bufmgr init: fd=%d\n", getpid(), fd);
+ DBG ("[libtbm:%d] bufmgr init: fd=%d\n", getpid(), fd);
/* allocate bufmgr */
gBufMgr = calloc (1, sizeof(struct _tbm_bufmgr));
if (!gBufMgr)
{
+ _tbm_set_last_result (TBM_BO_ERROR_HEAP_ALLOC_FAILED);
if (fd_flag)
- close (fd);
+ close(fd);
pthread_mutex_unlock (&gLock);
return NULL;
}
+ gBufMgr->fd_flag = fd_flag;
+
+ if (fd_flag)
+ {
+ gBufMgr->fd = fd;
+ }
+ else
+ {
+ gBufMgr->fd = dup(fd);
+ if (gBufMgr->fd < 0)
+ {
+ _tbm_set_last_result (TBM_BO_ERROR_DUP_FD_FAILED);
+ TBM_LOG ("[libtbm:%d] Fail to duplicate(dup) the drm fd\n", getpid());
+ free (gBufMgr);
+ gBufMgr = NULL;
+ pthread_mutex_unlock (&gLock);
+ return NULL;
+ }
+ DBG ("[libtbm:%d] duplicate the drm_fd(%d), bufmgr use fd(%d).\n",
+ getpid(), fd, gBufMgr->fd);
+ }
+
/* load bufmgr priv from env */
- if (!_tbm_load_module(gBufMgr, fd))
+ if (!_tbm_load_module(gBufMgr, gBufMgr->fd))
{
+ _tbm_set_last_result (TBM_BO_ERROR_LOAD_MODULE_FAILED);
TBM_LOG ("[libtbm:%d] "
"error : Fail to load bufmgr backend\n",
getpid());
+ close (gBufMgr->fd);
free (gBufMgr);
gBufMgr = NULL;
-
- if (fd_flag)
- close (fd);
-
pthread_mutex_unlock (&gLock);
return NULL;
}
+ else
+ {
+ backend_flag = gBufMgr->backend->flags;
+ /* log for tbm backend_flag */
+ DBG ("[libtbm:%d] ", getpid());
+ DBG ("cache_crtl:");
+ if (backend_flag&TBM_CACHE_CTRL_BACKEND) {
+ DBG ("BACKEND ");
+ } else {
+ DBG ("TBM ");
+ }
+ DBG ("lock_crtl:");
+ if (backend_flag&TBM_LOCK_CTRL_BACKEND) {
+ DBG ("BACKEND ");
+ } else {
+ DBG ("TBM ");
+ }
+ DBG ("\n");
+ }
- gBufMgr->fd_flag = fd_flag;
- gBufMgr->fd = fd;
gBufMgr->ref_count = 1;
- TBM_LOG ("[libtbm:%d] create tizen bufmgr: ref_count:%d\n", getpid(), gBufMgr->ref_count);
+ DBG ("[libtbm:%d] create tizen bufmgr: ref_count:%d\n", getpid(), gBufMgr->ref_count);
if (pthread_mutex_init (&gBufMgr->lock, NULL) != 0)
{
+ _tbm_set_last_result (TBM_BO_ERROR_THREAD_INIT_FAILED);
gBufMgr->backend->bufmgr_deinit (gBufMgr->backend->priv);
tbm_backend_free (gBufMgr->backend);
dlclose (gBufMgr->module_data);
+ close (gBufMgr->fd);
free (gBufMgr);
gBufMgr = NULL;
pthread_mutex_unlock (&gLock);
/* intialize the tizen global status */
if (!_tbm_bufmgr_init_state (gBufMgr))
{
+ _tbm_set_last_result (TBM_BO_ERROR_INIT_STATE_FAILED);
TBM_LOG ("[libtbm:%d] "
"error: Fail to init state\n",
getpid());
tbm_backend_free (gBufMgr->backend);
pthread_mutex_destroy (&gBufMgr->lock);
dlclose (gBufMgr->module_data);
+ close (gBufMgr->fd);
free (gBufMgr);
gBufMgr = NULL;
pthread_mutex_unlock (&gLock);
pthread_mutex_destroy (&bufmgr->lock);
- TBM_LOG ("[libtbm:%d] "
+ DBG ("[libtbm:%d] "
"tizen bufmgr destroy: bufmgr:%p\n",
getpid(), bufmgr);
dlclose (bufmgr->module_data);
- if(bufmgr->fd_flag)
- close(bufmgr->fd);
+ close(bufmgr->fd);
free (bufmgr);
bufmgr = NULL;
bo = calloc (1, sizeof(struct _tbm_bo));
if(!bo)
+ {
+ _tbm_set_last_result (TBM_BO_ERROR_HEAP_ALLOC_FAILED);
return NULL;
+ }
bo->bufmgr = bufmgr;
bo_priv = bufmgr->backend->bo_alloc (bo, size, flags);
if (!bo_priv)
{
+ _tbm_set_last_result (TBM_BO_ERROR_BO_ALLOC_FAILED);
free (bo);
pthread_mutex_unlock (&bufmgr->lock);
return NULL;
bo->flags = flags;
bo->tgl_key = INITIAL_KEY;
bo->priv = bo_priv;
+ bo->default_handle.u32 = 0;
/* init bo state */
if (!_tbm_bo_init_state (bo, CACHE_OP_CREATE))
{
+ _tbm_set_last_result (TBM_BO_ERROR_INIT_STATE_FAILED);
_tbm_bo_unref (bo);
pthread_mutex_unlock (&bufmgr->lock);
return NULL;
TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
tbm_bo bo = NULL;
+ tbm_bo bo2 = NULL;
+ tbm_bo tmp = NULL;
void * bo_priv = NULL;
+ pthread_mutex_lock (&bufmgr->lock);
+
+ /* find bo in list */
+ if(!LIST_IS_EMPTY (&bufmgr->bo_list))
+ {
+ LIST_FOR_EACH_ENTRY_SAFE (bo2, tmp, &bufmgr->bo_list, item_link)
+ {
+ if (bo2->tgl_key == key)
+ {
+ DBG ("[libtbm:%d] "
+ "find bo(%p, ref:%d key:%d) in list \n",
+ getpid(), bo2, bo2->ref_cnt, bo2->tgl_key);
+
+ bo2->ref_cnt++;
+ pthread_mutex_unlock (&bufmgr->lock);
+ return bo2;
+ }
+ }
+ }
+
bo = calloc (1, sizeof(struct _tbm_bo));
if(!bo)
+ {
+ pthread_mutex_unlock (&bufmgr->lock);
return NULL;
+ }
bo->bufmgr = bufmgr;
- pthread_mutex_lock (&bufmgr->lock);
-
bo_priv = bufmgr->backend->bo_import (bo, key);
if (!bo_priv)
{
+ _tbm_set_last_result (TBM_BO_ERROR_IMPORT_FAILED);
free (bo);
pthread_mutex_unlock (&bufmgr->lock);
return NULL;
bo->ref_cnt = 1;
bo->tgl_key = INITIAL_KEY;
bo->priv = bo_priv;
+ bo->default_handle.u32 = 0;
+
+ if (bufmgr->backend->bo_get_flags)
+ bo->flags = bufmgr->backend->bo_get_flags (bo);
+ else
+ bo->flags = TBM_BO_DEFAULT;
/* init bo state */
if (!_tbm_bo_init_state (bo, CACHE_OP_IMPORT))
{
+ _tbm_set_last_result (TBM_BO_ERROR_INIT_STATE_FAILED);
_tbm_bo_unref (bo);
pthread_mutex_unlock (&bufmgr->lock);
return NULL;
tbm_bo
tbm_bo_import_fd (tbm_bufmgr bufmgr, tbm_fd fd)
{
+ TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
+
tbm_bo bo = NULL;
+ tbm_bo bo2 = NULL;
+ tbm_bo tmp = NULL;
+ void * bo_priv = NULL;
+ tbm_bo_handle default_handle;
+
+ pthread_mutex_lock (&bufmgr->lock);
+
+ default_handle = bufmgr->backend->fd_to_handle (bufmgr, fd, TBM_DEVICE_DEFAULT);
+
+ /* find bo in list */
+ if(!LIST_IS_EMPTY (&bufmgr->bo_list))
+ {
+ LIST_FOR_EACH_ENTRY_SAFE (bo2, tmp, &bufmgr->bo_list, item_link)
+ {
+ if (bo2->default_handle.u32 == default_handle.u32)
+ {
+ DBG ("[libtbm:%d] "
+ "find bo(%p, ref:%d handle:%d) in list \n",
+ getpid(), bo2, bo2->ref_cnt, bo2->default_handle.u32);
+
+ bo2->ref_cnt++;
+ pthread_mutex_unlock (&bufmgr->lock);
+ return bo2;
+ }
+ }
+ }
+
+ bo = calloc (1, sizeof(struct _tbm_bo));
+ if(!bo)
+ {
+ pthread_mutex_unlock (&bufmgr->lock);
+ return NULL;
+ }
+
+ bo->bufmgr = bufmgr;
+
+ bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
+ if (!bo_priv)
+ {
+ _tbm_set_last_result (TBM_BO_ERROR_IMPORT_FD_FAILED);
+ free (bo);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return NULL;
+ }
+
+ bo->ref_cnt = 1;
+ bo->tgl_key = INITIAL_KEY;
+ bo->priv = bo_priv;
+ bo->default_handle.u32 = 0;
+
+ if (bufmgr->backend->bo_get_flags)
+ bo->flags = bufmgr->backend->bo_get_flags (bo);
+ else
+ bo->flags = TBM_BO_DEFAULT;
+
+ /* init bo state */
+ if (!_tbm_bo_init_state (bo, CACHE_OP_IMPORT))
+ {
+ _tbm_set_last_result (TBM_BO_ERROR_INIT_STATE_FAILED);
+ _tbm_bo_unref (bo);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return NULL;
+ }
+
+ LIST_INITHEAD (&bo->user_data_list);
+
+ LIST_ADD (&bo->item_link, &bufmgr->bo_list);
+
+ pthread_mutex_unlock (&bufmgr->lock);
return bo;
}
pthread_mutex_lock (&bufmgr->lock);
ret = bufmgr->backend->bo_export (bo);
+ if (!ret)
+ {
+ _tbm_set_last_result (TBM_BO_ERROR_EXPORT_FAILED);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return ret;
+ }
pthread_mutex_unlock (&bufmgr->lock);
return ret;
tbm_fd
tbm_bo_export_fd (tbm_bo bo)
{
- tbm_fd fd = 0;
+ TBM_RETURN_VAL_IF_FAIL (_tbm_bo_is_valid(bo), 0);
+
+ tbm_bufmgr bufmgr;
+ int ret;
+
+ bufmgr = bo->bufmgr;
+
+ pthread_mutex_lock (&bufmgr->lock);
+ ret = bufmgr->backend->bo_export_fd (bo);
+ if (!ret)
+ {
+ _tbm_set_last_result (TBM_BO_ERROR_EXPORT_FD_FAILED);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return ret;
+ }
+ pthread_mutex_unlock (&bufmgr->lock);
- return fd;
+ return ret;
}
pthread_mutex_lock (&bufmgr->lock);
bo_handle = bufmgr->backend->bo_get_handle (bo, device);
+ if (bo_handle.ptr == NULL)
+ {
+ _tbm_set_last_result (TBM_BO_ERROR_GET_HANDLE_FAILED);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return (tbm_bo_handle)NULL;
+ }
pthread_mutex_unlock (&bufmgr->lock);
return bo_handle;
tbm_bufmgr bufmgr;
tbm_bo_handle bo_handle;
- int ret = 0;
bufmgr = bo->bufmgr;
bo_handle = bufmgr->backend->bo_get_handle (bo, device);
- ret = _tbm_bo_lock (bo, device, opt);
- if(!ret)
+ if (!_tbm_bo_lock (bo, device, opt))
{
- pthread_mutex_unlock (&bufmgr->lock);
- TBM_DLOG ("[libtbm:%d] "
- "error %s:%d LOCK Failed \n",
- getpid(), __FUNCTION__, __LINE__);
- return (tbm_bo_handle)NULL;
-
+ _tbm_set_last_result (TBM_BO_ERROR_LOCK_FAILED);
+ TBM_LOG ("[libtbm:%d] "
+ "error %s:%d fail to lock bo:%p)\n",
+ getpid(), __FUNCTION__, __LINE__, bo);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return (tbm_bo_handle)NULL;
}
bo_handle = bufmgr->backend->bo_map (bo, device, opt);
- //As tbm_bo_handle is union just checking for NULL in first 32 bits only.
- if(bo_handle.u32 == 0)
+ if (bo_handle.ptr == NULL)
{
- //clean up lock if map fails.
- _tbm_bo_unlock (bo);
- pthread_mutex_unlock (&bufmgr->lock);
- TBM_DLOG ("[libtbm:%d] "
- "error %s:%d LOCK Failed \n",
- getpid(), __FUNCTION__, __LINE__);
- return (tbm_bo_handle)NULL;
+ _tbm_set_last_result (TBM_BO_ERROR_MAP_FAILED);
+ TBM_LOG ("[libtbm:%d] "
+ "error %s:%d fail to map bo:%p\n",
+ getpid(), __FUNCTION__, __LINE__, bo);
+ _tbm_bo_unlock(bo);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return (tbm_bo_handle)NULL;
}
if (bufmgr->use_map_cache == 1 && bo->map_cnt == 0)
pthread_mutex_lock (&bufmgr->lock);
-
ret = bufmgr->backend->bo_unmap (bo);
+ if (!ret)
+ {
+
+ _tbm_set_last_result (TBM_BO_ERROR_UNMAP_FAILED);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return ret;
+ }
/* decrease the map_count */
bo->map_cnt--;
void* temp;
unsigned int tmp_key;
+ tbm_bo_handle tmp_defualt_handle;
+
+ pthread_mutex_lock (&bo1->bufmgr->lock);
if (bo1->bufmgr->backend->bo_size (bo1) != bo2->bufmgr->backend->bo_size (bo2))
+ {
+ _tbm_set_last_result (TBM_BO_ERROR_SWAP_FAILED);
+ pthread_mutex_unlock (&bo1->bufmgr->lock);
return 0;
+ }
- pthread_mutex_lock (&bo1->bufmgr->lock);
tmp_key = bo1->tgl_key;
bo1->tgl_key = bo2->tgl_key;
bo2->tgl_key = tmp_key;
+ tmp_defualt_handle = bo1->default_handle;
+ bo1->default_handle = bo2->default_handle;
+ bo2->default_handle = tmp_defualt_handle;
+
temp = bo1->priv;
bo1->priv = bo2->priv;
bo2->priv = temp;
return 1;
}
-int
-tbm_bo_cache_flush(tbm_bo bo, int flags)
+tbm_error_e
+tbm_get_last_error (void)
{
- tbm_bufmgr bufmgr = bo->bufmgr;
+ return tbm_last_error;
+}
- bufmgr->backend->bo_cache_flush (bo, flags);
+unsigned int
+tbm_bufmgr_get_capability (tbm_bufmgr bufmgr)
+{
+ TBM_RETURN_VAL_IF_FAIL (TBM_BUFMGR_IS_VALID(bufmgr), 0);
- RETURN_VAL_CHECK_FLAG (TBM_CACHE_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
+ unsigned int capability = TBM_BUFMGR_CAPABILITY_NONE;
- unsigned short cntFlush = 0;
- unsigned int is_locked;
-
- /* get cache state of a bo */
- bo->cache_state.val = _tgl_get_data (bufmgr->lock_fd, bo->tgl_key, &is_locked);
+ if (bufmgr->backend->bo_import && bufmgr->backend->bo_export)
+ capability |= TBM_BUFMGR_CAPABILITY_SHARE_KEY;
- if (!bo->cache_state.data.isCacheable)
- return 1;
+ if (bufmgr->backend->bo_import_fd && bufmgr->backend->bo_export_fd)
+ capability |= TBM_BUFMGR_CAPABILITY_SHARE_FD;
- /* get global cache flush count */
- cntFlush = (unsigned short)_tgl_get_data (bufmgr->lock_fd, GLOBAL_KEY, NULL);
-
- bo->cache_state.data.isDirtied = DEVICE_NONE;
- bo->cache_state.data.isCached = 0;
-
- /* set global cache flush count */
- _tgl_set_data (bufmgr->lock_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
+ return capability;
+}
- DBG ("[libtbm:%d] \tcache(%d,%d,%d).... cntFlush(%d)\n", getpid(),
- bo->cache_state.data.isCacheable,
- bo->cache_state.data.isCached,
- bo->cache_state.data.isDirtied,
- cntFlush);
+int
+tbm_bo_get_flags (tbm_bo bo)
+{
+ TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
- return 1;
+ return bo->flags;
}
#include <tbm_type.h>
#include <stdint.h>
+/* tbm error base : this error base is same as TIZEN_ERROR_TBM in tizen_error.h */
+#ifndef TBM_ERROR_BASE
+#define TBM_ERROR_BASE -0x02830000
+#endif
+
/**
* \file tbm_bufmgr.h
* \brief Tizen Buffer Manager
TBM_BO_VENDOR = (0xffff0000), /**< vendor specific memory: it depends on the backend */
};
+
+/**
+ * @brief Enumeration for tbm error type.
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+ TBM_ERROR_NONE = 0, /**< Successful */
+ TBM_BO_ERROR_GET_FD_FAILED = TBM_ERROR_BASE|0x0101, /**< failed to get fd failed */
+ TBM_BO_ERROR_HEAP_ALLOC_FAILED = TBM_ERROR_BASE|0x0102, /**< failed to allocate the heap memory */
+ TBM_BO_ERROR_LOAD_MODULE_FAILED = TBM_ERROR_BASE|0x0103, /**< failed to load module*/
+ TBM_BO_ERROR_THREAD_INIT_FAILED = TBM_ERROR_BASE|0x0104, /**< failed to initialize the pthread */
+ TBM_BO_ERROR_BO_ALLOC_FAILED = TBM_ERROR_BASE|0x0105, /**< failed to allocate tbm_bo */
+ TBM_BO_ERROR_INIT_STATE_FAILED = TBM_ERROR_BASE|0x0106, /**< failed to initialize the state of tbm_bo */
+ TBM_BO_ERROR_IMPORT_FAILED = TBM_ERROR_BASE|0x0107, /**< failed to import the handle of tbm_bo */
+ TBM_BO_ERROR_IMPORT_FD_FAILED = TBM_ERROR_BASE|0x0108, /**< failed to import fd of tbm_bo */
+ TBM_BO_ERROR_EXPORT_FAILED = TBM_ERROR_BASE|0x0109, /**< failed to export the handle of the tbm_bo */
+ TBM_BO_ERROR_EXPORT_FD_FAILED = TBM_ERROR_BASE|0x01010, /**< failed to export fd of tbm_bo */
+ TBM_BO_ERROR_GET_HANDLE_FAILED = TBM_ERROR_BASE|0x0111, /**< failed to get the tbm_bo_handle */
+ TBM_BO_ERROR_LOCK_FAILED = TBM_ERROR_BASE|0x0112, /**< failed to lock the tbm_bo */
+ TBM_BO_ERROR_MAP_FAILED = TBM_ERROR_BASE|0x0113, /**< failed to map the tbm_bo to get the tbm_bo_handle */
+ TBM_BO_ERROR_UNMAP_FAILED = TBM_ERROR_BASE|0x0114, /**< failed to unmap the tbm_bo */
+ TBM_BO_ERROR_SWAP_FAILED = TBM_ERROR_BASE|0x0115, /**< failed to swap the tbm_bos */
+ TBM_BO_ERROR_DUP_FD_FAILED = TBM_ERROR_BASE|0x0116, /**< failed to duplicate fd */
+} tbm_error_e;
+
+/**
+ * @brief Enumeration of tbm buffer manager capability.
+ * @since_tizen 2.4
+ */
+enum TBM_BUFMGR_CAPABILITY
+{
+ TBM_BUFMGR_CAPABILITY_NONE = 0, /**< Not Support capability*/
+ TBM_BUFMGR_CAPABILITY_SHARE_KEY = (1<<0), /**< Support sharing buffer by tbm key */
+ TBM_BUFMGR_CAPABILITY_SHARE_FD = (1<<1), /**< Support sharing buffer by tbm fd */
+};
+
#ifdef __cplusplus
extern "C" {
#endif
int bufmgr_fd;
tbm_bufmgr bufmgr;
+ tbm_error_e error;
bufmgr = tbm_bufmgr_init (bufmgr_fd);
+ if (!bufmgr)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
....
int bufmgr_fd;
tbm_bufmgr bufmgr;
tbm_bo;
+ tbm_error_e error;
bufmgr = tbm_bufmgr_init (bufmgr_fd);
bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT);
+ if (!bo)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
....
* @param[in] device : the device type to get a handle
* @param[in] opt : the option to access the buffer object
* @return the handle of the buffer object
+ * @exception #TBM_ERROR_NONE Success
+ * @exception #TBM_ERROR_BO_LOCK_FAILED tbm_bo lock failed
+ * @exception #TBM_ERROR_BO_MAP_FAILED tbm_bo map failed
* @retval #tbm_bo
* @see tbm_bo_unmap()
* @par Example
tbm_bufmgr bufmgr;
tbm_bo bo;
tbm_bo_handle handle;
+ tbm_error_e error;
bufmgr = tbm_bufmgr_init (bufmgr_fd);
bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT);
...
handle = tbm_bo_map (bo, TBM_DEVICE_2D, TBM_OPTION_READ|TBM_OPTION_WRITE);
+ if (handle.ptr == NULL)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
...
tbm_bufmgr bufmgr;
tbm_bo bo;
tbm_bo_handle handle;
+ tbm_error_e error;
bufmgr = tbm_bufmgr_init (bufmgr_fd);
bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT);
...
handle = tbm_bo_get_handle (bo, TBM_DEVICE_2D);
+ if (handle.ptr == NULL)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
...
tbm_bufmgr bufmgr;
tbm_bo;
tbm_key key;
+ tbm_error_e error;
bufmgr = tbm_bufmgr_init (bufmgr_fd);
bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT);
key = tbm_bo_export (bo);
+ if (key == 0)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
...
* @brief Exports the buffer object by fd.
* @details The tbm_bo can be exported to the anther process with the unique fd associated with the the tbm_bo.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @remarks You must release the fd using close().
* @param[in] bo : the buffer object
* @return fd associated with the buffer object
* @retval #tbm_fd
tbm_fd bo_fd;
tbm_bufmgr bufmgr;
tbm_bo;
+ tbm_error_e error;
bufmgr = tbm_bufmgr_init (bufmgr_fd);
bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT);
bo_fd = tbm_bo_export (bo);
+ if (bo_fd == 0)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
...
int bo_key;
tbm_bufmgr bufmgr;
tbm_bo;
+ tbm_error_e error;
...
bufmgr = tbm_bufmgr_init (bufmgr_fd);
bo = tbm_bo_import (key);
+ if (bo == NULL)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
...
* @brief Imports the buffer object associated with the fd.
* @details The reference count of the tbm_bo is 1.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @remarks You must release the fd using close().
* @param[in] bufmgr : the buffer manager
* @param[in] fd : the fd associated with the buffer object
* @return a buffer object
tbm_fd bo_fd;
tbm_bufmgr bufmgr;
tbm_bo bo;
+ tbm_error_e error;
...
bufmgr = tbm_bufmgr_init (bufmgr_fd);
- bo = tbm_bo_import (bo_fd);
+ bo_fd = tbm_bo_import_fd (bo_fd);
+ if (bo_fd == 0)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
...
tbm_bo bo1;
tbm_bo bo2;
int ret;
+ tbm_error_e error;
bufmgr = tbm_bufmgr_init (bufmgr_fd);
bo1 = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT);
...
ret = tbm_bo_swap (bo1, bo2);
+ if (ret == 0)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
...
*/
int tbm_bo_get_user_data (tbm_bo bo, unsigned long key, void** data);
-int tbm_bo_cache_flush (tbm_bo bo, int flags);
+/**
+ * @brief Gets the latest tbm_error.
+ * @since_tizen 2.4
+ * @return the latest tbm_error
+ * @par Example
+ @code
+ #include <tbm_bufmgr.h>
+
+ int bufmgr_fd;
+ tbm_bufmgr bufmgr;
+ tbm_bo bo;
+ tbm_bo_handle handle;
+ tbm_error_e error;
+
+ bufmgr = tbm_bufmgr_init (bufmgr_fd);
+ bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT);
+ if (!bo)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
+
+ ...
+
+ handle = tbm_bo_map (bo, TBM_DEVICE_2D, TBM_OPTION_READ|TBM_OPTION_WRITE);
+ if (handle.ptr == NULL)
+ {
+ error = tbm_get_last_error ();
+ ...
+ }
+
+ ...
+
+ tbm_bo_unmap (bo);
+ tbm_bo_unref (bo);
+ tbm_bufmgr_deinit (bufmgr);
+ @endcode
+ */
+tbm_error_e tbm_get_last_error (void);
+
+/**
+ * @brief Gets the tbm buffer capability.
+ * @since_tizen 2.4
+ * @param[in] bufmgr : the buffer manager
+ * @return the tbm bufmgr capability
+ * @par Example
+ @code
+ #include <tbm_bufmgr.h>
+
+ int bufmgr_fd;
+ tbm_bufmgr bufmgr;
+ unsigned int capability;
+
+ bufmgr = tbm_bufmgr_init (bufmgr_fd);
+
+ capability = tbm_bufmgr_get_capability (bufmgr);
+ tbm_bufmgr_deinit (bufmgr);
+ @endcode
+ */
+unsigned int tbm_bufmgr_get_capability (tbm_bufmgr bufmgr);
+
+/**
+ * @brief Gets the tbm bo flags.
+ * @since_tizen 2.4
+ * @param[in] bo : the buffer object
+ * @return the tbm bo flags
+ * @see TBM_BO_FLAGS
+ * @par Example
+ @code
+ #include <tbm_bufmgr.h>
+
+ int bufmgr_fd;
+ tbm_bufmgr bufmgr;
+ tbm_bo;
+ int flags;
+
+ bufmgr = tbm_bufmgr_init (bufmgr_fd);
+ bo = tbm_bo_alloc (bufmgr, 128 * 128, TBM_BO_DEFAULT);
+ flags = tbm_bo_get_flags (bo);
+
+ ...
+
+ tbm_bo_unref (bo);
+ tbm_bufmgr_deinit (bufmgr);
+
+ @endcode
+ */
+int tbm_bo_get_flags (tbm_bo bo);
#ifdef __cplusplus
}
}
}
- /* log for tbm flags */
- TBM_LOG ("[libtbm:%d] ", getpid());
- TBM_LOG ("cache_crtl:");
- if (flags&TBM_CACHE_CTRL_BACKEND)
- TBM_LOG ("BACKEND ");
- else
- TBM_LOG ("TBM ");
- TBM_LOG ("lock_crtl:");
- if (flags&TBM_LOCK_CTRL_BACKEND)
- TBM_LOG ("BACKEND ");
- else
- TBM_LOG ("TBM ");
- TBM_LOG ("\n");
-
bufmgr->backend = backend;
return 1;
return backend->priv;
}
+void *
+tbm_backend_get_priv_from_bufmgr (tbm_bufmgr bufmgr)
+{
+ tbm_bufmgr_backend backend = bufmgr->backend;
+
+ return backend->priv;
+}
+
void
tbm_backend_set_bo_priv (tbm_bo bo, void *bo_priv)
{
/**
* @brief import the buffer object associated with the key.
+ * @remarks If the backend doesn't support a buffer sharing by tbm key,
+ fucntion pointer must be set to NULL.
* @param[in] bo : the buffer object
* @param[in] key : the key associated with the buffer object
* @return pointer of the bo private.
/**
* @brief export the buffer object
+ * @remarks If the backend doesn't support a buffer sharing by tbm key,
+ fucntion pointer must be set to NULL.
* @param[in] bo : the buffer object
* @return key associated with the buffer object
*/
* @param[out] size : the size of the plane
* @param[out] offset : the offset of the plane
* @param[out] pitch : the pitch of the plane
+ * @param[out] bo_idx : the bo index of the plane
* @return 1 if this function succeeds, otherwise 0.
*/
- int (*surface_get_plane_data) (tbm_surface_h surface, int width, int height, tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch);
+ int (*surface_get_plane_data) (tbm_surface_h surface, int width, int height, tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx);
+
+ /**
+ * @brief import the buffer object associated with the prime fd.
+ * @remarks tbm_fd must be free by user.
+ * @remarks If the backend doesn't support a buffer sharing by tbm fd,
+ fucntion pointer must be set to NULL.
+ * @param[in] bo : the buffer object
+ * @param[in] fd : the prime fd associated with the buffer object
+ * @return pointer of the bo private.
+ */
+ void * (*bo_import_fd) (tbm_bo bo, tbm_fd fd);
+
+ /**
+ * @brief export the buffer object
+ * @remarks tbm_fd must be free by user.
+ * @remarks If the backend doesn't support a buffer sharing by tbm fd,
+ fucntion pointer must be set to NULL.
+ * @param[in] bo : the buffer object
+ * @return tbm_fd associated with the buffer object
+ */
+ tbm_fd (*bo_export_fd) (tbm_bo bo);
+
+ /**
+ * @brief get the tbm_bo_handle according to the device type and the prime fd.
+ * @param[in] bufmgr : the tizen buffer manager
+ * @param[in] fd : the prime fd associated with the buffer object
+ * @param[in] device : the option to access the buffer object
+ * @return the handle of the buffer object
+ */
+ tbm_bo_handle (*fd_to_handle) (tbm_bufmgr bufmgr, tbm_fd fd, int device);
+
+ /**
+ * @brief get the num of bos with a format.
+ * @param[in] format : the format of the surface
+ * @return num of the bos if this function succeeds, otherwise 0.
+ */
+ int (*surface_get_num_bos) (tbm_format format);
+
+ /**
+ * @brief get the tbm flags of memory type
+ * @param[in] bo : the buffer object
+ * @see #TBM_BO_FLAGS
+ * @return tbm flags of memory type is this function succeeds, otherwise 0.
+ */
+ int (*bo_get_flags) (tbm_bo bo);
/* Padding for future extension */
void (*reserved1) (void);
void (*reserved4) (void);
void (*reserved5) (void);
void (*reserved6) (void);
- void (*reserved7) (void);
- void (*reserved8) (void);
};
/**
int tbm_backend_init (tbm_bufmgr bufmgr, tbm_bufmgr_backend backend);
void *tbm_backend_get_bufmgr_priv (tbm_bo bo);
+void *tbm_backend_get_priv_from_bufmgr (tbm_bufmgr bufmgr);
void *tbm_backend_get_bo_priv (tbm_bo bo);
#endif /* _TBM_BUFMGR_BACKEND_H_ */
#include <tbm_surface.h>
#include <tbm_bufmgr_backend.h>
-#include </usr/include/dlog/dlog.h>
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "TBM"
-
/* check condition */
#define TBM_RETURN_IF_FAIL(cond) {\
if (!(cond)) {\
- TBM_DLOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
+ TBM_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
return;\
}\
}
#define TBM_RETURN_VAL_IF_FAIL(cond, val) {\
if (!(cond)) {\
- TBM_DLOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
+ TBM_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
return val;\
}\
}
(flags&TBM_LOCK_CTRL_BACKEND)
#define TBM_LOG(...) fprintf (stderr, __VA_ARGS__)
-#define TBM_DLOG(...) LOGE (__VA_ARGS__)
-
typedef union _tbm_bo_cache_state tbm_bo_cache_state;
void *priv; /* bo private */
struct list_head item_link; /* link of bo */
+
+ tbm_bo_handle default_handle; /*default handle */
};
/**
int flags;
int num_bos; /* the number of buffer objects */
- tbm_bo bos[4]; /* the array of buffer objects */
+
+ tbm_bo bos[4];
+
+ int num_planes; /* the number of buffer objects */
+
+ int planes_bo_idx[TBM_SURF_PLANE_MAX];
+
+ int refcnt;
struct list_head item_link; /* link of surface */
};
+int tbm_bufmgr_get_drm_fd_x11(void);
+int tbm_bufmgr_get_drm_fd_wayland(void);
+
+/* functions for mutex */
+int tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map);
+void tbm_surface_internal_unmap (tbm_surface_h surface);
+unsigned int tbm_surface_internal_get_width (tbm_surface_h surface);
+unsigned int tbm_surface_internal_get_height (tbm_surface_h surface);
+tbm_format tbm_surface_internal_get_format (tbm_surface_h surface);
+
#endif /* _TBM_BUFMGR_INT_H_ */
#include "tbm_bufmgr_int.h"
#include "tbm_surface_internal.h"
-static int
-_tbm_surface_get_info (struct _tbm_surface *surf, int opt, tbm_surface_info_s *info, int map)
-{
- tbm_bo_handle bo_handles[4];
- int i;
-
- info->width = surf->info.width;
- info->height = surf->info.height;
- info->format = surf->info.format;
- info->bpp = surf->info.bpp;
- info->size = surf->info.size;
- info->num_planes = surf->info.num_planes;
-
- if (surf->num_bos == 1)
- {
- if (map == 1)
- {
- bo_handles[0] = tbm_bo_map (surf->bos[0], TBM_DEVICE_CPU, opt);
- if (bo_handles[0].ptr == NULL)
- return 0;
- }
- else
- {
- bo_handles[0] = tbm_bo_get_handle (surf->bos[0], TBM_DEVICE_CPU);
- if (bo_handles[0].ptr == NULL)
- return 0;
- }
-
- for (i = 0; i < surf->info.num_planes; i++)
- {
- info->planes[i].size = surf->info.planes[i].size;
- info->planes[i].offset = surf->info.planes[i].offset;
- info->planes[i].stride = surf->info.planes[i].stride;
- info->planes[i].ptr = bo_handles[0].ptr + surf->info.planes[i].offset;
- }
- }
- else
- {
- /* TODO: calculate the virtaul address when num_bos is over 1 */
- }
-
- return 1;
-}
-
int
tbm_surface_query_formats (uint32_t **formats, uint32_t *num)
{
TBM_RETURN_VAL_IF_FAIL (surface != NULL, TBM_SURFACE_ERROR_INVALID_PARAMETER);
TBM_RETURN_VAL_IF_FAIL (info != NULL, TBM_SURFACE_ERROR_INVALID_PARAMETER);
- struct _tbm_surface *surf = (struct _tbm_surface *)surface;
int ret = 0;
- ret = _tbm_surface_get_info (surf, opt, info, 1);
+ ret = tbm_surface_internal_get_info (surface, opt, info, 1);
if (ret == 0)
return TBM_SURFACE_ERROR_INVALID_OPERATION;
{
TBM_RETURN_VAL_IF_FAIL (surface != NULL, TBM_SURFACE_ERROR_INVALID_PARAMETER);
- struct _tbm_surface *surf = (struct _tbm_surface *)surface;
- int i;
-
- for (i = 0; i < surf->num_bos; i++)
- tbm_bo_unmap (surf->bos[i]);
+ tbm_surface_internal_unmap(surface);
return TBM_SURFACE_ERROR_NONE;
}
TBM_RETURN_VAL_IF_FAIL (surface != NULL, TBM_SURFACE_ERROR_INVALID_PARAMETER);
TBM_RETURN_VAL_IF_FAIL (info != NULL, TBM_SURFACE_ERROR_INVALID_PARAMETER);
- struct _tbm_surface *surf = (struct _tbm_surface *)surface;
int ret = 0;
- ret = _tbm_surface_get_info (surf, 0, info, 0);
+ ret = tbm_surface_internal_get_info (surface, 0, info, 0);
if (ret == 0)
return TBM_SURFACE_ERROR_INVALID_OPERATION;
{
TBM_RETURN_VAL_IF_FAIL (surface != NULL, TBM_SURFACE_ERROR_INVALID_PARAMETER);
- struct _tbm_surface *surf = (struct _tbm_surface *)surface;
-
- return surf->info.width;
+ return tbm_surface_internal_get_width(surface);
}
int
{
TBM_RETURN_VAL_IF_FAIL (surface != NULL, TBM_SURFACE_ERROR_INVALID_PARAMETER);
- struct _tbm_surface *surf = (struct _tbm_surface *)surface;
-
- return surf->info.height;
+ return tbm_surface_internal_get_height(surface);
}
tbm_format
return 0;
}
- struct _tbm_surface *surf = (struct _tbm_surface *)surface;
-
#ifdef HAVE_CAPI_0_1_1
set_last_result (TBM_SURFACE_ERROR_NONE);
#endif
- return surf->info.format;
+ return tbm_surface_internal_get_format(surface);
}
static tbm_bufmgr g_surface_bufmgr = NULL;
struct list_head g_surface_list; /* list of surfaces belonging to bufmgr */
+static pthread_mutex_t tbm_surface_lock;
+
+static bool
+_tbm_surface_mutex_init (void)
+{
+ static bool tbm_surface_mutex_init = false;
+
+ if (tbm_surface_mutex_init)
+ return true;
+
+ if (pthread_mutex_init (&tbm_surface_lock, NULL))
+ {
+ TBM_LOG ("[libtbm] fail: tbm_surface mutex init\n");
+ return false;
+ }
+
+ tbm_surface_mutex_init = true;
+
+ return true;
+}
+
+void
+_tbm_surface_mutex_lock (void)
+{
+ if (!_tbm_surface_mutex_init ())
+ return;
+
+ pthread_mutex_lock (&tbm_surface_lock);
+}
+
+void
+_tbm_surface_mutex_unlock (void)
+{
+ pthread_mutex_unlock (&tbm_surface_lock);
+}
+
static void
_init_surface_bufmgr()
{
TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
- pthread_mutex_lock (&mgr->lock);
+ if (!mgr->backend->surface_get_size)
+ return 0;
size = mgr->backend->surface_get_size (surf, surf->info.width, surf->info.height, surf->info.format);
- pthread_mutex_unlock (&mgr->lock);
-
return size;
}
static int
-_tbm_surface_internal_query_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
+_tbm_surface_internal_query_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
{
TBM_RETURN_VAL_IF_FAIL (surface, 0);
TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
- pthread_mutex_lock (&mgr->lock);
+ if (!mgr->backend->surface_get_plane_data)
+ return 0;
- ret = mgr->backend->surface_get_plane_data (surf, surf->info.width, surf->info.height, surf->info.format, plane_idx, size, offset, pitch);
+ ret = mgr->backend->surface_get_plane_data (surf, surf->info.width, surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
if (!ret)
- {
- pthread_mutex_unlock (&mgr->lock);
return 0;
+
+ return 1;
+}
+
+static int
+_tbm_surface_internal_query_num_bos (tbm_format format)
+{
+ TBM_RETURN_VAL_IF_FAIL (format > 0, 0);
+ struct _tbm_bufmgr *mgr;
+ int ret = 0;
+
+ mgr = g_surface_bufmgr;
+
+ if (!mgr->backend->surface_get_num_bos)
+ return 0;
+
+ ret = mgr->backend->surface_get_num_bos (format);
+ if (!ret)
+ return 0;
+
+ return ret;
+}
+
+static void
+_tbm_surface_internal_destroy (tbm_surface_h surface)
+{
+ int i;
+
+ for (i = 0; i < surface->num_bos; i++)
+ {
+ tbm_bo_unref (surface->bos[i]);
+ surface->bos[i] = NULL;
}
- pthread_mutex_unlock (&mgr->lock);
+ LIST_DEL (&surface->item_link);
+
+ free (surface);
+ surface = NULL;
+
+ if(LIST_IS_EMPTY (&g_surface_list))
+ {
+ _deinit_surface_bufmgr ();
+ LIST_DELINIT (&g_surface_list);
+ }
- return 1;
}
+
int
tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
{
+ struct _tbm_bufmgr *mgr;
+ int ret = 0;
+
+ _tbm_surface_mutex_lock();
+
if (!g_surface_bufmgr)
{
_init_surface_bufmgr();
LIST_INITHEAD (&g_surface_list);
}
- struct _tbm_bufmgr *mgr = g_surface_bufmgr;
- int ret = 0;
+ mgr = g_surface_bufmgr;
- pthread_mutex_lock (&mgr->lock);
+ if (!mgr->backend->surface_supported_format)
+ {
+ _tbm_surface_mutex_unlock();
+ return 0;
+ }
ret = mgr->backend->surface_supported_format (formats, num);
- pthread_mutex_unlock (&mgr->lock);
+ _tbm_surface_mutex_unlock();
return ret;
}
+
int tbm_surface_internal_get_num_planes (tbm_format format)
{
int num_planes = 0;
return bpp;
}
-
tbm_surface_h
tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
{
TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
+ struct _tbm_bufmgr *mgr;
+ struct _tbm_surface *surf = NULL;
+ uint32_t size = 0;
+ uint32_t offset = 0;
+ uint32_t stride = 0;
+ uint32_t bo_size = 0;
+ int bo_idx;
+ int i, j;
+
+ _tbm_surface_mutex_lock();
+
if (!g_surface_bufmgr)
{
_init_surface_bufmgr();
LIST_INITHEAD (&g_surface_list);
}
- struct _tbm_bufmgr *mgr = g_surface_bufmgr;
-
-
- TBM_RETURN_VAL_IF_FAIL (TBM_BUFMGR_IS_VALID(mgr), NULL);
-
- struct _tbm_surface *surf = NULL;
- uint32_t size = 0;
- uint32_t offset = 0;
- uint32_t stride = 0;
- int i;
-
+ mgr = g_surface_bufmgr;
+ if (!TBM_BUFMGR_IS_VALID(mgr))
+ {
+ _tbm_surface_mutex_unlock();
+ return NULL;
+ }
surf = calloc (1, sizeof(struct _tbm_surface));
if (!surf)
+ {
+ _tbm_surface_mutex_unlock();
return NULL;
+ }
surf->bufmgr = mgr;
surf->info.width = width;
surf->info.bpp = tbm_surface_internal_get_bpp (format);
surf->info.size = _tbm_surface_internal_query_size (surf);
surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
+ surf->num_bos = _tbm_surface_internal_query_num_bos(format);
+ surf->refcnt = 1;
- /* get size, stride and offset */
+ /* get size, stride and offset bo_idx*/
for (i = 0; i < surf->info.num_planes; i++)
{
- _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride);
+ _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride, &bo_idx);
surf->info.planes[i].size = size;
surf->info.planes[i].offset = offset;
surf->info.planes[i].stride = stride;
+ surf->planes_bo_idx[i] = bo_idx;
}
surf->flags = flags;
- /* create only one bo */
- surf->num_bos = 1;
- surf->bos[0] = tbm_bo_alloc (mgr, surf->info.size, flags);
- if (!surf->bos[0])
+ for (i = 0; i < surf->num_bos; i++)
{
- free (surf);
- surf = NULL;
-
- if(LIST_IS_EMPTY (&g_surface_list))
+ bo_size = 0;
+ for (j = 0; j < surf->info.num_planes; j++)
{
- _deinit_surface_bufmgr ();
- LIST_DELINIT (&g_surface_list);
+ if (surf->planes_bo_idx[i] == i)
+ bo_size += surf->info.planes[i].size;
+ }
+
+ surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
+ if (!surf->bos[i]) {
+ for (j = 0; j < i; j++)
+ tbm_bo_unref (surf->bos[j]);
+
+ free (surf);
+ surf = NULL;
+
+ if(LIST_IS_EMPTY (&g_surface_list))
+ {
+ _deinit_surface_bufmgr ();
+ LIST_DELINIT (&g_surface_list);
+ }
+
+ _tbm_surface_mutex_unlock();
return NULL;
}
}
LIST_ADD (&surf->item_link, &g_surface_list);
+ _tbm_surface_mutex_unlock();
+
return surf;
}
{
TBM_RETURN_VAL_IF_FAIL (bos, NULL);
TBM_RETURN_VAL_IF_FAIL (info, NULL);
+ TBM_RETURN_VAL_IF_FAIL (num == 1 || info->num_planes == num, NULL);
+
+ struct _tbm_bufmgr *mgr;
+ struct _tbm_surface *surf = NULL;
+ int i;
+
+ _tbm_surface_mutex_lock();
if (!g_surface_bufmgr)
{
LIST_INITHEAD (&g_surface_list);
}
- struct _tbm_bufmgr *mgr = g_surface_bufmgr;
-
- TBM_RETURN_VAL_IF_FAIL (TBM_BUFMGR_IS_VALID(mgr), NULL);
-
- struct _tbm_surface *surf = NULL;
- int i;
+ mgr = g_surface_bufmgr;
+ if (!TBM_BUFMGR_IS_VALID(mgr))
+ {
+ _tbm_surface_mutex_unlock();
+ return NULL;
+ }
surf = calloc (1, sizeof(struct _tbm_surface));
if (!surf)
+ {
+ _tbm_surface_mutex_unlock();
return NULL;
+ }
surf->bufmgr = mgr;
surf->info.width = info->width;
surf->info.height = info->height;
surf->info.format = info->format;
surf->info.bpp = info->bpp;
- surf->info.size = info->size;
surf->info.num_planes = info->num_planes;
+ surf->refcnt = 1;
/* get size, stride and offset */
for (i = 0; i < info->num_planes; i++)
{
- surf->info.planes[i].size = info->planes[i].size;
surf->info.planes[i].offset = info->planes[i].offset;
surf->info.planes[i].stride = info->planes[i].stride;
+
+ if (info->planes[i].size > 0)
+ surf->info.planes[i].size = info->planes[i].size;
+ else
+ surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
+
+ if (num == 1)
+ surf->planes_bo_idx[i] = 0;
+ else
+ surf->planes_bo_idx[i] = i;
+ }
+
+ if (info->size > 0)
+ {
+ surf->info.size = info->size;
+ }
+ else
+ {
+ surf->info.size = 0;
+ for (i = 0; i < info->num_planes; i++)
+ {
+ surf->info.size += surf->info.planes[i].size;
+ }
}
surf->flags = TBM_BO_DEFAULT;
LIST_ADD (&surf->item_link, &g_surface_list);
+ _tbm_surface_mutex_unlock();
+
return surf;
bail1:
for (i = 0; i < num; i++)
LIST_DELINIT (&g_surface_list);
}
+ _tbm_surface_mutex_unlock();
+
return NULL;
}
void
tbm_surface_internal_destroy (tbm_surface_h surface)
{
- int i;
-
if (!surface)
return;
- surface = (struct _tbm_surface *)surface;
+ _tbm_surface_mutex_lock();
- for (i = 0; i < surface->num_bos; i++)
- {
- tbm_bo_unref (surface->bos[i]);
- surface->bos[i] = NULL;
+ surface->refcnt--;
+
+ if (surface->refcnt > 0) {
+ _tbm_surface_mutex_unlock();
+ return;
}
- LIST_DEL (&surface->item_link);
+ if (surface->refcnt == 0)
+ _tbm_surface_internal_destroy(surface);
- free (surface);
- surface = NULL;
+ _tbm_surface_mutex_unlock();
+}
- if(LIST_IS_EMPTY (&g_surface_list))
- {
- _deinit_surface_bufmgr ();
- LIST_DELINIT (&g_surface_list);
- }
+
+void
+tbm_surface_internal_ref (tbm_surface_h surface)
+{
+ TBM_RETURN_IF_FAIL (surface);
+
+ _tbm_surface_mutex_lock();
+
+ surface->refcnt++;
+
+ _tbm_surface_mutex_unlock();
}
+void
+tbm_surface_internal_unref (tbm_surface_h surface)
+{
+ TBM_RETURN_IF_FAIL (surface);
+
+ _tbm_surface_mutex_lock();
+
+ surface->refcnt--;
+
+ if (surface->refcnt > 0) {
+ _tbm_surface_mutex_unlock();
+ return;
+ }
+
+ if (surface->refcnt == 0)
+ _tbm_surface_internal_destroy(surface);
+
+ _tbm_surface_mutex_unlock();
+}
int
tbm_surface_internal_get_num_bos (tbm_surface_h surface)
{
TBM_RETURN_VAL_IF_FAIL (surface, 0);
- struct _tbm_surface *surf = (struct _tbm_surface *) surface;
+ struct _tbm_surface *surf;
+ int num;
+
+ _tbm_surface_mutex_lock();
+
+ surf = (struct _tbm_surface *) surface;
+ num = surf->num_bos;
- return surf->num_bos;
+ _tbm_surface_mutex_unlock();
+
+ return num;
}
tbm_bo
TBM_RETURN_VAL_IF_FAIL (surface, NULL);
TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
- struct _tbm_surface *surf = (struct _tbm_surface *) surface;
+ struct _tbm_surface *surf;
+ tbm_bo bo;
+
+ _tbm_surface_mutex_lock();
+
+ surf = (struct _tbm_surface *) surface;
+ bo = surf->bos[bo_idx];
- return surf->bos[bo_idx];
+ _tbm_surface_mutex_unlock();
+
+ return bo;
}
int
{
TBM_RETURN_VAL_IF_FAIL (surface, 0);
- struct _tbm_surface *surf = (struct _tbm_surface *) surface;
+ struct _tbm_surface *surf;
+ unsigned int size;
+
+ _tbm_surface_mutex_lock();
- return surf->info.size;
+ surf = (struct _tbm_surface *) surface;
+ size = surf->info.size;
+
+ _tbm_surface_mutex_unlock();
+
+ return size;
}
int
TBM_RETURN_VAL_IF_FAIL (surface, 0);
TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
- struct _tbm_surface *surf = (struct _tbm_surface *) surface;
+ struct _tbm_surface *surf;
- TBM_RETURN_VAL_IF_FAIL (plane_idx < surf->info.num_planes, 0);
+ _tbm_surface_mutex_lock();
+
+ surf = (struct _tbm_surface *) surface;
+
+ if (plane_idx >= surf->info.num_planes)
+ {
+ _tbm_surface_mutex_unlock();
+ return 0;
+ }
*size = surf->info.planes[plane_idx].size;
*offset = surf->info.planes[plane_idx].offset;
*pitch = surf->info.planes[plane_idx].stride;
+ _tbm_surface_mutex_unlock();
+
+ return 1;
+}
+
+int
+tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
+{
+ struct _tbm_surface *surf;
+ tbm_bo_handle bo_handles[4];
+ int i, j;
+
+ _tbm_surface_mutex_lock();
+
+ memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
+
+ surf = (struct _tbm_surface *)surface;
+
+ info->width = surf->info.width;
+ info->height = surf->info.height;
+ info->format = surf->info.format;
+ info->bpp = surf->info.bpp;
+ info->size = surf->info.size;
+ info->num_planes = surf->info.num_planes;
+
+ if (map == 1)
+ {
+ for (i = 0; i < surf->num_bos; i++)
+ {
+ bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
+ if (bo_handles[i].ptr == NULL)
+ {
+ for (j = 0; j < i; j++)
+ tbm_bo_unmap (surf->bos[j]);
+
+ _tbm_surface_mutex_unlock();
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < surf->num_bos; i++)
+ {
+ bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
+ if (bo_handles[i].ptr == NULL)
+ {
+ _tbm_surface_mutex_unlock();
+ return 0;
+ }
+ }
+ }
+
+ for (i = 0; i < surf->info.num_planes; i++)
+ {
+ info->planes[i].size = surf->info.planes[i].size;
+ info->planes[i].offset = surf->info.planes[i].offset;
+ info->planes[i].stride = surf->info.planes[i].stride;
+ info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
+ }
+
+ _tbm_surface_mutex_unlock();
+
return 1;
}
+void
+tbm_surface_internal_unmap (tbm_surface_h surface)
+{
+ struct _tbm_surface *surf;
+ int i;
+
+ _tbm_surface_mutex_lock();
+
+ surf = (struct _tbm_surface *)surface;
+
+ for (i = 0; i < surf->num_bos; i++)
+ tbm_bo_unmap (surf->bos[i]);
+
+ _tbm_surface_mutex_unlock();
+}
+
+unsigned int
+tbm_surface_internal_get_width (tbm_surface_h surface)
+{
+ struct _tbm_surface *surf;
+ unsigned int width;
+
+ _tbm_surface_mutex_lock();
+
+ surf = (struct _tbm_surface *)surface;
+ width = surf->info.width;
+
+ _tbm_surface_mutex_unlock();
+
+ return width;
+}
+
+unsigned int
+tbm_surface_internal_get_height (tbm_surface_h surface)
+{
+ struct _tbm_surface *surf;
+ unsigned int height;
+
+ _tbm_surface_mutex_lock();
+
+ surf = (struct _tbm_surface *)surface;
+ height = surf->info.height;
+
+ _tbm_surface_mutex_unlock();
+
+ return height;
+
+}
+
+tbm_format
+tbm_surface_internal_get_format (tbm_surface_h surface)
+{
+ struct _tbm_surface *surf;
+ tbm_format format;
+
+ _tbm_surface_mutex_lock();
+
+ surf = (struct _tbm_surface *)surface;
+ format = surf->info.format;
+
+ _tbm_surface_mutex_unlock();
+
+ return format;
+}
+
+int
+tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
+{
+ TBM_RETURN_VAL_IF_FAIL (surface, 0);
+ TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
+ struct _tbm_surface *surf;
+ int bo_idx;
+
+ _tbm_surface_mutex_lock();
+
+ surf = (struct _tbm_surface *)surface;
+ bo_idx = surf->planes_bo_idx[plane_idx];
+
+ _tbm_surface_mutex_unlock();
+
+ return bo_idx;
+}
+
void tbm_surface_internal_destroy (tbm_surface_h surface);
/**
+ * @brief reference the tbm surface
+ TODO:
+ */
+void tbm_surface_internal_ref (tbm_surface_h surface);
+
+/**
+ * @brief unreference the tbm surface
+ TODO:
+ */
+void tbm_surface_internal_unref (tbm_surface_h surface);
+
+/**
* @brief Gets the number of buffer objects associated with the tbm_surface.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
* @param[in] surface : the tbm_surface_h
*/
int tbm_surface_internal_get_bpp (tbm_format format);
+/**
+ * @brief Gets bo index of plane.
+ * @since_tizen 2.4
+ * @param[in] surface : the tbm_surface_h
+ * @param[in] plane_idx : the bo index in the the tbm_surface
+ * @return bo index of plane, otherwise -1.
+ * @par Example
+ @code
+ #include <tbm_surface.h>
+ #include <tbm_surface_internal.h>
+
+ int bo_idx;
+ tbm_surface_h surface;
+
+ surface = tbm_surfacel_create (128, 128, TBM_FORMAT_YUV420);
+ bo_idx = tbm_surface_internal_get_plane_bo_idx (surface, 0);
+
+ ...
+
+ @endcode
+ */
+int tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx);
+
#ifdef __cplusplus
}
#endif
/**
* @brief Definition for the Tizen buffer surface.
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*/
typedef struct _tbm_surface * tbm_surface_h;
/**
* @brief Definition for the Tizen buffer surface format.
+ * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*/
typedef uint32_t tbm_format;
--- /dev/null
+/**************************************************************************
+
+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 "tbm_bufmgr_int.h"
+#include <xf86drm.h>
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-client.h"
+
+struct wl_client;
+struct wl_resource;
+
+struct wl_drm;
+
+#ifndef WL_DRM_ERROR_ENUM
+#define WL_DRM_ERROR_ENUM
+enum wl_drm_error {
+ WL_DRM_ERROR_AUTHENTICATE_FAIL = 0,
+ WL_DRM_ERROR_INVALID_FORMAT = 1,
+ WL_DRM_ERROR_INVALID_NAME = 2,
+};
+#endif /* WL_DRM_ERROR_ENUM */
+
+
+#ifndef WL_DRM_CAPABILITY_ENUM
+#define WL_DRM_CAPABILITY_ENUM
+/**
+ * wl_drm_capability - wl_drm capability bitmask
+ * @WL_DRM_CAPABILITY_PRIME: wl_drm prime available
+ *
+ * Bitmask of capabilities.
+ */
+enum wl_drm_capability {
+ WL_DRM_CAPABILITY_PRIME = 1,
+};
+#endif /* WL_DRM_CAPABILITY_ENUM */
+
+struct wl_drm_listener {
+ /**
+ * device - (none)
+ * @name: (none)
+ */
+ void (*device)(void *data,
+ struct wl_drm *wl_drm,
+ const char *name);
+ /**
+ * format - (none)
+ * @format: (none)
+ */
+ void (*format)(void *data,
+ struct wl_drm *wl_drm,
+ uint32_t format);
+ /**
+ * authenticated - (none)
+ */
+ void (*authenticated)(void *data,
+ struct wl_drm *wl_drm);
+ /**
+ * capabilities - (none)
+ * @value: (none)
+ */
+ void (*capabilities)(void *data,
+ struct wl_drm *wl_drm,
+ uint32_t value);
+};
+
+static inline int
+wl_drm_add_listener(struct wl_drm *wl_drm,
+ const struct wl_drm_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) wl_drm,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_DRM_AUTHENTICATE 0
+
+static inline void
+wl_drm_destroy(struct wl_drm *wl_drm)
+{
+ wl_proxy_destroy((struct wl_proxy *) wl_drm);
+}
+
+static inline void
+wl_drm_authenticate(struct wl_drm *wl_drm, uint32_t id)
+{
+ wl_proxy_marshal((struct wl_proxy *) wl_drm,
+ WL_DRM_AUTHENTICATE, id);
+}
+
+static const struct wl_interface *types[] = {
+ NULL,
+ &wl_buffer_interface,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &wl_buffer_interface,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &wl_buffer_interface,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static const struct wl_message wl_drm_requests[] = {
+ { "authenticate", "u", types + 0 },
+ { "create_buffer", "nuiiuu", types + 1 },
+ { "create_planar_buffer", "nuiiuiiiiii", types + 7 },
+ { "create_prime_buffer", "2nhiiuiiiiii", types + 18 },
+};
+
+static const struct wl_message wl_drm_events[] = {
+ { "device", "s", types + 0 },
+ { "format", "u", types + 0 },
+ { "authenticated", "", types + 0 },
+ { "capabilities", "u", types + 0 },
+};
+
+static const struct wl_interface wl_drm_interface = {
+ "wl_drm", 2,
+ 4, wl_drm_requests,
+ 4, wl_drm_events,
+};
+
+#define USE_QUEUE 1
+
+struct wl_drm_info {
+#if USE_QUEUE
+ struct wl_event_queue *wl_queue;
+#endif
+ struct wl_drm* wl_drm;
+ int authenticated;
+ int fd;
+};
+
+static void wl_client_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
+{
+ struct wl_drm_info *drm_info = (struct wl_drm_info *)data;
+ drm_magic_t magic;
+
+ printf("device[%s]\n", device);
+ drm_info->fd = open(device, O_RDWR | O_CLOEXEC);
+ if (drm_info->fd < 0) {
+ printf("Failed to open a device: %d (%s)\n", errno, device);
+ return;
+ }
+
+ drmGetMagic(drm_info->fd, &magic);
+ printf("magic[%x]\n", magic);
+ wl_drm_authenticate(drm_info->wl_drm, magic);
+}
+
+static void wl_client_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
+{
+ /* Do nothing */
+}
+
+static void wl_client_drm_handle_authenticated(void *data, struct wl_drm *drm)
+{
+ struct wl_drm_info *drm_info = (struct wl_drm_info *)data;
+ drm_info->authenticated = 1;
+}
+
+static void wl_client_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
+{
+ /* Do nothing */
+}
+
+
+
+static void wl_client_registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
+{
+ struct wl_drm_info *info = (struct wl_drm_info *)data;
+ static const struct wl_drm_listener wl_drm_client_listener = {
+ wl_client_drm_handle_device,
+ wl_client_drm_handle_format,
+ wl_client_drm_handle_authenticated,
+ wl_client_drm_handle_capabilities
+ };
+
+ printf("interface[%s]\n", interface);
+ if (!strcmp(interface, "wl_drm")) {
+ info->wl_drm = wl_registry_bind(registry, name, &wl_drm_interface, (version > 2) ? 2 : version);
+#if USE_QUEUE
+ wl_proxy_set_queue((struct wl_proxy *)info->wl_drm, info->wl_queue);
+#endif
+ wl_drm_add_listener(info->wl_drm, &wl_drm_client_listener, data);
+ }
+}
+
+static int tbm_util_get_drm_fd(void *dpy, int *fd)
+{
+ struct wl_display *disp = NULL;
+ struct wl_registry *wl_registry;
+ int ret = 0;
+ struct wl_drm_info info = {
+#if USE_QUEUE
+ .wl_queue = NULL,
+#endif
+ .wl_drm = NULL,
+ .authenticated = 0,
+ .fd = -1,
+ };
+ 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;
+ }
+
+#if USE_QUEUE
+ 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;
+ }
+#endif
+ wl_registry = wl_display_get_registry(dpy);
+ if (!wl_registry) {
+ printf("Failed to get registry\n");
+#if USE_QUEUE
+ wl_event_queue_destroy(info.wl_queue);
+#endif
+ if (disp == dpy) {
+ wl_display_disconnect(disp);
+ }
+ return -1;
+ }
+#if USE_QUEUE
+ wl_proxy_set_queue((struct wl_proxy *)wl_registry, info.wl_queue);
+#endif
+ wl_registry_add_listener(wl_registry, ®istry_listener, &info);
+ wl_display_roundtrip(dpy);
+
+ printf("Consuming Dispatch Queue begin\n");
+ while (ret != -1 && !info.authenticated) {
+#if USE_QUEUE
+ ret = wl_display_dispatch_queue(dpy, info.wl_queue);
+#else
+ ret = wl_display_dispatch(dpy);
+#endif
+ printf("Dispatch Queue consumed: %d\n", ret);
+ }
+ printf("Consuming Dispatch Queue end\n");
+
+#if USE_QUEUE
+ wl_event_queue_destroy(info.wl_queue);
+#endif
+ wl_registry_destroy(wl_registry);
+ wl_drm_destroy(info.wl_drm);
+
+ *fd = info.fd;
+ 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;
+}
\ No newline at end of file
--- /dev/null
+/**************************************************************************
+
+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 "tbm_bufmgr.h"
+#include "tbm_bufmgr_int.h"
+#include <xf86drm.h>
+#include <X11/Xmd.h>
+#include <dri2.h>
+
+int
+tbm_bufmgr_get_drm_fd_x11()
+{
+ int screen;
+ Display *display;
+ int dri2Major, dri2Minor;
+ int eventBase, errorBase;
+ drm_magic_t magic;
+ char *driver_name, *device_name;
+ int fd;
+
+ display = XOpenDisplay(NULL);
+ if (!display)
+ {
+ TBM_LOG ("[libtbm:%d] Fail XOpenDisplay\n", getpid());
+ return -1;
+ }
+
+ screen = DefaultScreen(display);
+
+ if (!DRI2QueryExtension (display, &eventBase, &errorBase))
+ {
+ TBM_LOG ("[libtbm:%d] Fail DRI2QueryExtention\n", getpid());
+ XCloseDisplay(display);
+ return -1;
+ }
+
+ if (!DRI2QueryVersion (display, &dri2Major, &dri2Minor))
+ {
+ TBM_LOG ("[libtbm:%d] Fail DRI2QueryVersion\n", getpid());
+ XCloseDisplay(display);
+ return -1;
+ }
+
+ if (!DRI2Connect (display, RootWindow(display, screen), &driver_name, &device_name))
+ {
+ TBM_LOG ("[libtbm:%d] Fail DRI2Connect\n", getpid());
+ XCloseDisplay(display);
+ return -1;
+ }
+
+ fd = open (device_name, O_RDWR);
+ if (fd < 0)
+ {
+ TBM_LOG ("[libtbm:%d] cannot open drm device (%s)\n", getpid(), device_name);
+ free (driver_name);
+ free (device_name);
+ XCloseDisplay(display);
+ return -1;
+ }
+
+ if (drmGetMagic (fd, &magic))
+ {
+ TBM_LOG ("[libtbm:%d] Fail drmGetMagic\n", getpid());
+ free (driver_name);
+ free (device_name);
+ close(fd);
+ XCloseDisplay(display);
+ return -1;
+ }
+
+ if (!DRI2Authenticate(display, RootWindow(display, screen), magic))
+ {
+ TBM_LOG ("[libtbm:%d] Fail DRI2Authenticate\n", getpid());
+ free (driver_name);
+ free (device_name);
+ close(fd);
+ XCloseDisplay(display);
+ return -1;
+ }
+
+ if(!drmAuthMagic(fd, magic))
+ {
+ TBM_LOG ("[libtbm:%d] Fail drmAuthMagic\n", getpid());
+ free (driver_name);
+ free (device_name);
+ close(fd);
+ XCloseDisplay(display);
+ return -1;
+ }
+
+ free (driver_name);
+ free (device_name);
+ XCloseDisplay(display);
+
+ return fd;
+}
+