tizen 2.4 release accepted/tizen_2.4_mobile tizen_2.4 accepted/tizen/2.4/mobile/20151029.030857 submit/tizen_2.4/20151028.065050 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 08:17:36 +0000 (17:17 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 08:17:36 +0000 (17:17 +0900)
20 files changed:
Makefile.am
configure.ac
doc/ui_tbm_surface_doc.h
drm_slp/Makefile.am [deleted file]
drm_slp/drm_slp_bufmgr.c [deleted file]
drm_slp/drm_slp_bufmgr.h [deleted file]
packaging/libtbm.spec
src/Makefile.am
src/tbm_bufmgr.c [changed mode: 0755->0644]
src/tbm_bufmgr.h [changed mode: 0755->0644]
src/tbm_bufmgr_backend.c [changed mode: 0755->0644]
src/tbm_bufmgr_backend.h
src/tbm_bufmgr_int.h [changed mode: 0755->0644]
src/tbm_surface.c [changed mode: 0755->0644]
src/tbm_surface.h [changed mode: 0755->0644]
src/tbm_surface_internal.c [changed mode: 0755->0644]
src/tbm_surface_internal.h [changed mode: 0755->0644]
src/tbm_type.h [changed mode: 0755->0644]
src/tbm_wayland.c [new file with mode: 0644]
src/tbm_x11.c [new file with mode: 0644]

index a11ecfd..ceb4251 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS = src drm_slp
+SUBDIRS = src
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libtbm.pc
index e753bdf..7343f5c 100644 (file)
@@ -18,7 +18,7 @@
 #  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])
@@ -36,11 +36,26 @@ AC_FUNC_ALLOCA
 # 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])
 
@@ -49,24 +64,55 @@ AC_CHECK_FUNCS([clock_gettime], [CLOCK_LIB=],
                              [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])
 
@@ -76,5 +122,6 @@ echo "LDFLAGS           : $LDFLAGS"
 echo "LIBTBM_CFLAGS     : $LIBTBM_CFLAGS"
 echo "LIBTBM_LIBS       : $LIBTBM_LIBS"
 echo "BUFMGR_MODULE_DIR : $BUFMGR_MODULE_PATH"
+echo "TBM_PLATFORM      : $TBM_PLATFORM"
 echo ""
 
index 05e1e60..487ccd2 100755 (executable)
@@ -1,6 +1,6 @@
 
-#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
@@ -21,5 +21,5 @@
  *  - Get the information of surface and planes.
  */
 
-#endif /* __TIZEN_UI_TBM_SURFACE_DOC_H__ */
+#endif /* __SAMSUNG_UI_TBM_SURFACE_DOC_H__ */
 
diff --git a/drm_slp/Makefile.am b/drm_slp/Makefile.am
deleted file mode 100644 (file)
index 835562c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-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
-
diff --git a/drm_slp/drm_slp_bufmgr.c b/drm_slp/drm_slp_bufmgr.c
deleted file mode 100755 (executable)
index b5ae07d..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/**************************************************************************
-
-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;
-}
-
diff --git a/drm_slp/drm_slp_bufmgr.h b/drm_slp/drm_slp_bufmgr.h
deleted file mode 100644 (file)
index 0add67a..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**************************************************************************
-
-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_ */
index 92c5cd9..8cce215 100644 (file)
@@ -1,17 +1,24 @@
+%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}
@@ -32,8 +39,13 @@ Development Files.
 
 %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}
 
@@ -56,7 +68,6 @@ rm -rf %{buildroot}
 %defattr(-,root,root,-)
 /usr/share/license/%{name}
 %{_libdir}/libtbm.so.*
-%{_libdir}/libdrm_slp.so.*
 
 %files devel
 %defattr(-,root,root,-)
@@ -67,6 +78,4 @@ rm -rf %{buildroot}
 %{_includedir}/tbm_bufmgr_backend.h
 %{_includedir}/tbm_type.h
 %{_libdir}/libtbm.so
-%{_libdir}/libdrm_slp.so
 %{_libdir}/pkgconfig/libtbm.pc
-
index 2e4ce26..7458888 100644 (file)
@@ -1,7 +1,8 @@
-SUBDIRS = .
+SUBDIRS =
 
 AM_CFLAGS = \
        $(WARN_CFLAGS) \
+       -I./ \
        -I$(top_srcdir) \
        -I$(top_srcdir)/src \
        $(PTHREADSTUBS_CFLAGS) \
@@ -12,7 +13,19 @@ libtbm_ladir = $(libdir)
 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 \
old mode 100755 (executable)
new mode 100644 (file)
index ecdfa77..61e5a70
@@ -36,9 +36,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #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
@@ -102,6 +99,14 @@ typedef struct
 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)
 {
@@ -323,14 +328,18 @@ _tbm_bo_init_state (tbm_bo bo, int opt)
     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);
 
@@ -342,8 +351,6 @@ _tbm_bo_init_state (tbm_bo bo, int opt)
         _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;
@@ -462,7 +469,7 @@ _tbm_bo_lock (tbm_bo bo, int device, int opt)
     int ret = 0;
 
     if (!bo)
-        return ret;
+        return 0;
 
     bufmgr = bo->bufmgr;
 
@@ -500,7 +507,7 @@ _tbm_bo_lock (tbm_bo bo, int device, int opt)
             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);
 
@@ -676,7 +683,7 @@ _check_version (TBMModuleVersionInfo *data)
     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);
@@ -786,7 +793,7 @@ _tbm_bufmgr_load_module (tbm_bufmgr bufmgr, int fd, const char *file)
 
     bufmgr->module_data = module_data;
 
-    TBM_LOG ("[libtbm:%d] "
+    DBG ("[libtbm:%d] "
             "Success to load module(%s)\n", getpid(), file);
 
     return 1;
@@ -833,98 +840,12 @@ static int _tbm_load_module (tbm_bufmgr bufmgr, int fd)
     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);
 
@@ -942,17 +863,22 @@ tbm_bufmgr_init (int fd)
     /* 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;
@@ -960,9 +886,14 @@ tbm_bufmgr_init (int fd)
 
     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;
@@ -970,46 +901,86 @@ tbm_bufmgr_init (int fd)
         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);
@@ -1019,6 +990,7 @@ tbm_bufmgr_init (int fd)
     /* 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());
@@ -1026,6 +998,7 @@ tbm_bufmgr_init (int fd)
         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);
@@ -1122,14 +1095,13 @@ tbm_bufmgr_deinit (tbm_bufmgr bufmgr)
 
     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;
@@ -1195,7 +1167,10 @@ tbm_bo_alloc (tbm_bufmgr bufmgr, int size, int flags)
 
     bo = calloc (1, sizeof(struct _tbm_bo));
     if(!bo)
+    {
+        _tbm_set_last_result (TBM_BO_ERROR_HEAP_ALLOC_FAILED);
         return NULL;
+    }
 
     bo->bufmgr = bufmgr;
 
@@ -1204,6 +1179,7 @@ tbm_bo_alloc (tbm_bufmgr bufmgr, int size, int flags)
     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;
@@ -1213,10 +1189,12 @@ tbm_bo_alloc (tbm_bufmgr bufmgr, int size, int flags)
     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;
@@ -1237,19 +1215,43 @@ tbm_bo_import (tbm_bufmgr bufmgr, unsigned int key)
     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;
@@ -1258,10 +1260,17 @@ tbm_bo_import (tbm_bufmgr bufmgr, unsigned int key)
     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;
@@ -1279,7 +1288,78 @@ tbm_bo_import (tbm_bufmgr bufmgr, unsigned int key)
 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;
 }
@@ -1296,6 +1376,12 @@ tbm_bo_export (tbm_bo 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;
@@ -1304,9 +1390,24 @@ tbm_bo_export (tbm_bo bo)
 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;
 }
 
 
@@ -1322,6 +1423,12 @@ tbm_bo_get_handle (tbm_bo bo, int device)
 
     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;
@@ -1334,7 +1441,6 @@ tbm_bo_map (tbm_bo bo, int device, int opt)
 
     tbm_bufmgr bufmgr;
     tbm_bo_handle bo_handle;
-    int ret = 0;
 
     bufmgr = bo->bufmgr;
 
@@ -1342,29 +1448,27 @@ tbm_bo_map (tbm_bo bo, int device, int opt)
 
     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)
@@ -1390,8 +1494,14 @@ tbm_bo_unmap (tbm_bo bo)
 
     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--;
@@ -1414,16 +1524,26 @@ tbm_bo_swap (tbm_bo bo1, tbm_bo bo2)
 
     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;
@@ -1548,38 +1668,32 @@ tbm_bo_delete_user_data (tbm_bo bo, unsigned long key)
     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;
 }
old mode 100755 (executable)
new mode 100644 (file)
index 2b5b951..5b276ee
@@ -35,6 +35,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #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
@@ -146,6 +151,43 @@ enum TBM_BO_FLAGS
     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
@@ -200,7 +242,13 @@ tbm_bufmgr tbm_bufmgr_init   (int fd);
 
    int bufmgr_fd;
    tbm_bufmgr bufmgr;
+   tbm_error_e error;
    bufmgr = tbm_bufmgr_init (bufmgr_fd);
+   if (!bufmgr)
+   {
+      error = tbm_get_last_error ();
+      ...
+   }
 
    ....
 
@@ -233,9 +281,15 @@ void       tbm_bufmgr_deinit (tbm_bufmgr bufmgr);
    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 ();
+      ...
+   }
 
    ....
 
@@ -318,6 +372,9 @@ void          tbm_bo_unref      (tbm_bo bo);
  * @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
@@ -328,6 +385,7 @@ void          tbm_bo_unref      (tbm_bo bo);
    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);
@@ -335,6 +393,11 @@ void          tbm_bo_unref      (tbm_bo bo);
    ...
 
    handle = tbm_bo_map (bo, TBM_DEVICE_2D, TBM_OPTION_READ|TBM_OPTION_WRITE);
+   if (handle.ptr == NULL)
+   {
+      error = tbm_get_last_error ();
+      ...
+   }
 
    ...
 
@@ -398,6 +461,7 @@ int           tbm_bo_unmap      (tbm_bo bo);
    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);
@@ -405,6 +469,11 @@ int           tbm_bo_unmap      (tbm_bo bo);
    ...
 
    handle = tbm_bo_get_handle (bo, TBM_DEVICE_2D);
+   if (handle.ptr == NULL)
+   {
+      error = tbm_get_last_error ();
+      ...
+   }
 
    ...
 
@@ -430,10 +499,16 @@ tbm_bo_handle tbm_bo_get_handle (tbm_bo bo, int device);
    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 ();
+      ...
+   }
 
    ...
 
@@ -447,6 +522,7 @@ tbm_key  tbm_bo_export     (tbm_bo bo);
  * @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
@@ -459,10 +535,16 @@ tbm_key  tbm_bo_export     (tbm_bo bo);
    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 ();
+      ...
+   }
 
    ...
 
@@ -489,11 +571,17 @@ tbm_fd tbm_bo_export_fd (tbm_bo bo);
    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 ();
+      ...
+   }
 
    ...
 
@@ -507,6 +595,7 @@ tbm_bo        tbm_bo_import     (tbm_bufmgr bufmgr, tbm_key key);
  * @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
@@ -520,11 +609,17 @@ tbm_bo        tbm_bo_import     (tbm_bufmgr bufmgr, tbm_key key);
    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 ();
+      ...
+   }
 
    ...
 
@@ -607,6 +702,7 @@ int           tbm_bo_locked     (tbm_bo bo);
    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);
@@ -615,6 +711,11 @@ int           tbm_bo_locked     (tbm_bo bo);
    ...
 
    ret = tbm_bo_swap (bo1, bo2);
+   if (ret == 0)
+   {
+      error = tbm_get_last_error ();
+      ...
+   }
 
    ...
 
@@ -847,8 +948,95 @@ int tbm_bo_set_user_data    (tbm_bo bo, unsigned long key, void* data);
  */
 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
 }
old mode 100755 (executable)
new mode 100644 (file)
index 462103b..18fed8c
@@ -93,20 +93,6 @@ tbm_backend_init (tbm_bufmgr bufmgr, tbm_bufmgr_backend backend)
         }
     }
 
-    /* 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;
@@ -120,6 +106,14 @@ tbm_backend_get_bufmgr_priv (tbm_bo bo)
     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)
 {
index fe4d3a7..43974ad 100755 (executable)
@@ -125,6 +125,8 @@ struct _tbm_bufmgr_backend
 
     /**
     * @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.
@@ -133,6 +135,8 @@ struct _tbm_bufmgr_backend
 
     /**
     * @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
     */
@@ -231,9 +235,55 @@ struct _tbm_bufmgr_backend
     * @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);
@@ -242,8 +292,6 @@ struct _tbm_bufmgr_backend
     void (*reserved4)    (void);
     void (*reserved5)    (void);
     void (*reserved6)    (void);
-    void (*reserved7)    (void);
-    void (*reserved8)    (void);
 };
 
 /**
@@ -276,6 +324,7 @@ void                tbm_backend_free  (tbm_bufmgr_backend backend);
 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_ */
old mode 100755 (executable)
new mode 100644 (file)
index b86d8ac..c82646c
@@ -49,22 +49,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #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;\
     }\
 }
@@ -102,8 +96,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         (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;
 
@@ -148,6 +140,8 @@ struct _tbm_bo
     void *priv; /* bo private */
 
     struct list_head item_link; /* link of bo */
+
+    tbm_bo_handle default_handle; /*default handle */
 };
 
 /**
@@ -191,9 +185,26 @@ struct _tbm_surface {
     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_ */
old mode 100755 (executable)
new mode 100644 (file)
index fb9c710..db05c32
@@ -34,50 +34,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #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)
 {
@@ -133,10 +89,9 @@ tbm_surface_map (tbm_surface_h surface, int opt, tbm_surface_info_s *info)
     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;
 
@@ -148,11 +103,7 @@ tbm_surface_unmap (tbm_surface_h surface)
 {
     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;
 }
@@ -163,10 +114,9 @@ tbm_surface_get_info (tbm_surface_h surface, tbm_surface_info_s *info)
     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;
 
@@ -178,9 +128,7 @@ tbm_surface_get_width (tbm_surface_h surface)
 {
     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
@@ -188,9 +136,7 @@ tbm_surface_get_height (tbm_surface_h surface)
 {
     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
@@ -204,11 +150,9 @@ tbm_surface_get_format (tbm_surface_h surface)
         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);
 }
 
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index b9409b2..90947a2
@@ -38,6 +38,42 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 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()
 {
@@ -68,17 +104,16 @@ _tbm_surface_internal_query_size (tbm_surface_h surface)
     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);
@@ -92,41 +127,90 @@ _tbm_surface_internal_query_plane_data (tbm_surface_h surface, int plane_idx, ui
     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;
@@ -296,33 +380,41 @@ int tbm_surface_internal_get_bpp (tbm_format format)
     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;
@@ -331,36 +423,53 @@ tbm_surface_internal_create_with_flags (int width, int height, int format, int f
     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;
 }
 
@@ -369,6 +478,13 @@ tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int
 {
     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)
     {
@@ -376,31 +492,56 @@ tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int
         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;
@@ -417,6 +558,8 @@ tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int
 
     LIST_ADD (&surf->item_link, &g_surface_list);
 
+    _tbm_surface_mutex_unlock();
+
     return surf;
 bail1:
     for (i = 0; i < num; i++)
@@ -437,6 +580,8 @@ bail1:
         LIST_DELINIT (&g_surface_list);
     }
 
+    _tbm_surface_mutex_unlock();
+
     return NULL;
 }
 
@@ -444,40 +589,73 @@ bail1:
 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
@@ -486,9 +664,17 @@ tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
     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
@@ -496,9 +682,17 @@ tbm_surface_internal_get_size (tbm_surface_h surface)
 {
     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
@@ -507,14 +701,168 @@ tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint3
     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;
+}
+
old mode 100755 (executable)
new mode 100644 (file)
index 242fd54..a9ada40
@@ -161,6 +161,18 @@ tbm_surface_h tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tb
 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
@@ -302,6 +314,29 @@ int tbm_surface_internal_get_num_planes (tbm_format format);
  */
 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
old mode 100755 (executable)
new mode 100644 (file)
index b4057ff..51794c8
@@ -42,10 +42,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /**
  * @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;
 
diff --git a/src/tbm_wayland.c b/src/tbm_wayland.c
new file mode 100644 (file)
index 0000000..062e392
--- /dev/null
@@ -0,0 +1,332 @@
+/**************************************************************************
+
+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, &registry_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
diff --git a/src/tbm_x11.c b/src/tbm_x11.c
new file mode 100644 (file)
index 0000000..f4e8a87
--- /dev/null
@@ -0,0 +1,127 @@
+/**************************************************************************
+
+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;
+}
+