--- /dev/null
+SooChan Lim <sc1.lim@samsung.com>
+SangJin Lee <lsj119@samsung.com>
+Boram Park <boram1288.park@samsung.com>
--- /dev/null
+Copyright (C) 2000 - 2012 Samsung Electronics co., Ltd. All Rights Reserved.
+
+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, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice 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, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null
+SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libtbm.pc
+
--- /dev/null
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
--- /dev/null
+#
+# 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
+# on 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
+# ADAM JACKSON 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.
+
+AC_PREREQ(2.60)
+AC_INIT(libtbm, 1.0.0)
+AC_USE_SYSTEM_EXTENSIONS
+AC_CONFIG_SRCDIR([Makefile.am])
+AM_INIT_AUTOMAKE([dist-bzip2])
+
+AM_CONFIG_HEADER([config.h])
+
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_PROG_CC
+
+AC_HEADER_STDC
+AC_SYS_LARGEFILE
+AC_FUNC_ALLOCA
+
+# Enable quiet compiles on automake 1.11.
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+# set the dir for the tbm module
+DEFAULT_BUFMGR_MODULE_PATH="/usr/lib/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}" ])
+#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_CHECK_FUNCS([clock_gettime], [CLOCK_LIB=],
+ [AC_CHECK_LIB([rt], [clock_gettime], [CLOCK_LIB=-lrt],
+ [AC_MSG_ERROR([Couldn't find clock_gettime])])])
+AC_SUBST([CLOCK_LIB])
+
+PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs)
+PKG_CHECK_MODULES(LIBDRM, libdrm)
+
+LIBTBM_CFLAGS="$PTHREADSTUBS_CFLAGS $LIBDRM_CFLAGS "
+LIBTBM_LIBS="$PTHREADSTUBS_LIBS $LIBDRM_LIBS "
+AC_SUBST(LIBTBM_CFLAGS)
+AC_SUBST(LIBTBM_LIBS)
+
+AC_OUTPUT([
+ src/Makefile
+ Makefile
+ libtbm.pc])
+
+echo ""
+echo "CFLAGS : $CFLAGS"
+echo "LDFLAGS : $LDFLAGS"
+echo "LIBTBM_CFLAGS : $LIBTBM_CFLAGS"
+echo "LIBTBM_LIBS : $LIBTBM_LIBS"
+echo "BUFMGR_MODULE_DIR : $BUFMGR_MODULE_PATH"
+echo ""
+
--- /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"
+
+drm_slp_bufmgr
+drm_slp_bufmgr_init(int fd, void *arg)
+{
+ tbm_bufmgr bufmgr = NULL;
+
+ bufmgr = tbm_bufmgr_init (fd);
+ if (!bufmgr)
+ {
+ fprintf (stderr, "[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)
+ {
+ fprintf (stderr, "[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)
+ {
+ fprintf (stderr, "[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:
+ fprintf (stderr, "[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_ */
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libtbm
+Description: the library for Tizen Buffer Manager
+Version: @PACKAGE_VERSION@
+Requires: libdrm
+Libs: -L${libdir} -ltbm @LIBTBM_LIBS@
+Cflags: -I${includedir} @LIBTBM_CFLAGS@
--- /dev/null
+Name: libtbm
+Version: 1.0.4
+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)
+
+%description
+Description: %{summary}
+
+%package devel
+Summary: the library for Tizen Buffer Manager
+Group: Development/Libraries
+Requires: libdrm2
+
+%description devel
+the library for Tizen Buffer Manager
+
+%prep
+%setup -q
+
+%build
+
+%reconfigure --prefix=%{_prefix} \
+ CFLAGS="${CFLAGS} -Wall -Werror" LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed"
+
+make %{?_smp_mflags}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp -af COPYING %{buildroot}/usr/share/license/%{name}
+%make_install
+
+
+%clean
+rm -rf %{buildroot}
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+
+
+%files
+%defattr(-,root,root,-)
+/usr/share/license/%{name}
+%{_libdir}/libtbm.so.*
+#%{_libdir}/libdrm_slp.so.*
+
+%files devel
+%defattr(-,root,root,-)
+%dir %{_includedir}
+%{_includedir}/tbm_bufmgr.h
+%{_includedir}/tbm_bufmgr_backend.h
+%{_libdir}/libtbm.so
+%{_libdir}/pkgconfig/libtbm.pc
+
--- /dev/null
+SUBDIRS = .
+
+AM_CFLAGS = \
+ $(WARN_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src \
+ $(PTHREADSTUBS_CFLAGS) \
+ @LIBTBM_CFLAGS@
+
+libtbm_la_LTLIBRARIES = libtbm.la
+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 = \
+ tbm_bufmgr_backend.c \
+ tbm_bufmgr.c
+
+libtbmincludedir=$(includedir)
+libtbminclude_HEADERS = tbm_bufmgr.h tbm_bufmgr_backend.h
+
--- /dev/null
+/*
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
+ * All Rights Reserved.
+ *
+ * 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+
+/**
+ * \file
+ * List macros heavily inspired by the Linux kernel
+ * list handling. No list looping yet.
+ *
+ * Is not threadsafe, so common operations need to
+ * be protected using an external mutex.
+ */
+#ifndef _U_DOUBLE_LIST_H_
+#define _U_DOUBLE_LIST_H_
+
+#include <stddef.h>
+
+static void list_inithead(struct list_head *item)
+{
+ item->prev = item;
+ item->next = item;
+}
+
+static inline void list_add(struct list_head *item, struct list_head *list)
+{
+ item->prev = list;
+ item->next = list->next;
+ list->next->prev = item;
+ list->next = item;
+}
+
+static inline void list_addtail(struct list_head *item, struct list_head *list)
+{
+ item->next = list;
+ item->prev = list->prev;
+ list->prev->next = item;
+ list->prev = item;
+}
+
+static inline void list_replace(struct list_head *from, struct list_head *to)
+{
+ to->prev = from->prev;
+ to->next = from->next;
+ from->next->prev = to;
+ from->prev->next = to;
+}
+
+static inline void list_del(struct list_head *item)
+{
+ item->prev->next = item->next;
+ item->next->prev = item->prev;
+}
+
+static inline void list_delinit(struct list_head *item)
+{
+ item->prev->next = item->next;
+ item->next->prev = item->prev;
+ item->next = item;
+ item->prev = item;
+}
+
+#define LIST_INITHEAD(__item) list_inithead(__item)
+#define LIST_ADD(__item, __list) list_add(__item, __list)
+#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
+#define LIST_REPLACE(__from, __to) list_replace(__from, __to)
+#define LIST_DEL(__item) list_del(__item)
+#define LIST_DELINIT(__item) list_delinit(__item)
+
+#define LIST_ENTRY(__type, __item, __field) \
+ ((__type *)(((char *)(__item)) - offsetof(__type, __field)))
+
+#define LIST_IS_EMPTY(__list) \
+ ((__list)->next == (__list))
+
+#ifndef container_of
+#define container_of(ptr, sample, member) \
+ (void *)((char *)(ptr) \
+ - ((char *)&(sample)->member - (char *)(sample)))
+#endif
+
+#define LIST_FOR_EACH_ENTRY(pos, head, member) \
+ for (pos = container_of((head)->next, pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.next, pos, member))
+
+#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \
+ for (pos = container_of((head)->next, pos, member), \
+ storage = container_of(pos->member.next, pos, member); \
+ &pos->member != (head); \
+ pos = storage, storage = container_of(storage->member.next, storage, member))
+
+#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \
+ for (pos = container_of((head)->prev, pos, member), \
+ storage = container_of(pos->member.prev, pos, member); \
+ &pos->member != (head); \
+ pos = storage, storage = container_of(storage->member.prev, storage, member))
+
+#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \
+ for (pos = container_of((start), pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.next, pos, member))
+
+#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \
+ for (pos = container_of((start), pos, member); \
+ &pos->member != (head); \
+ pos = container_of(pos->member.prev, pos, member))
+
+#endif /*_U_DOUBLE_LIST_H_*/
--- /dev/null
+/**************************************************************************
+
+libtbm
+
+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.
+
+**************************************************************************/
+
+#include "config.h"
+
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <dirent.h>
+#include <string.h>
+#include <errno.h>
+#include <pthread.h>
+#include "tbm_bufmgr.h"
+#include "tbm_bufmgr_glock.h"
+#include "tbm_bufmgr_backend.h"
+#include "tbm_bufmgr_int.h"
+#include "list.h"
+
+#define DEBUG
+#ifdef DEBUG
+static int bDebug = 0;
+#define DBG(...) if(bDebug&0x1) fprintf(stderr, __VA_ARGS__)
+#define DBG_LOCK(...) if(bDebug&0x2) fprintf(stderr, __VA_ARGS__)
+#else
+#define DBG(...)
+#define DBG_LOCK(...)
+#endif
+
+/* check condition */
+#define TBM_RETURN_IF_FAIL(cond) {\
+ if (!(cond)) {\
+ fprintf (stderr, "[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
+ return;\
+ }\
+}
+#define TBM_RETURN_VAL_IF_FAIL(cond, val) {\
+ if (!(cond)) {\
+ fprintf (stderr, "[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
+ return val;\
+ }\
+}
+
+/* check flags */
+#define RETURN_CHECK_FLAG(cond) {\
+ if ((cond)) {\
+ return;\
+ }\
+}
+#define RETURN_VAL_CHECK_FLAG(cond, val) {\
+ if ((cond)) {\
+ return val;\
+ }\
+}
+
+
+/* check validation */
+#define TBM_BUFMGR_IS_VALID(mgr) (mgr && \
+ mgr->link.next &&\
+ mgr->link.next->prev == &mgr->link)
+#define TBM_BO_IS_VALID(bo) (bo && \
+ TBM_BUFMGR_IS_VALID(bo->bufmgr) && \
+ bo->item_link.next && \
+ bo->item_link.next->prev == &bo->item_link)
+
+#define CTRL_BACKEND_VALID(flags) ((flags&TBM_CACHE_CTRL_BACKEND) && \
+ (flags&TBM_LOCK_CTRL_BACKEND))
+
+#define PREFIX_LIB "libtbm_"
+#define SUFFIX_LIB ".so"
+#define DEFAULT_LIB PREFIX_LIB"default"SUFFIX_LIB
+
+#define BO_IS_CACHEABLE(bo) ((bo->flags & TBM_BO_NONCACHABLE)?0:1)
+#define DEVICE_IS_CACHE_AWARE(device) ((device == TBM_DEVICE_CPU)?(1):(0))
+
+/* tgl key values */
+#define GLOBAL_KEY ((unsigned int)(-1))
+#define INITIAL_KEY ((unsigned int)(-2))
+
+#define CACHE_OP_CREATE (-1)
+#define CACHE_OP_ATTACH (-2)
+#define CACHE_OP_IMPORT (-3)
+
+/* values to indicate unspecified fields in XF86ModReqInfo. */
+#define MAJOR_UNSPEC 0xFF
+#define MINOR_UNSPEC 0xFF
+#define PATCH_UNSPEC 0xFFFF
+#define ABI_VERS_UNSPEC 0xFFFFFFFF
+
+#define MODULE_VERSION_NUMERIC(maj, min, patch) \
+ ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
+#define GET_MODULE_MAJOR_VERSION(vers) (((vers) >> 24) & 0xFF)
+#define GET_MODULE_MINOR_VERSION(vers) (((vers) >> 16) & 0xFF)
+#define GET_MODULE_PATCHLEVEL(vers) ((vers) & 0xFFFF)
+
+enum {
+ LOCK_TRY_ONCE,
+ LOCK_TRY_ALWAYS,
+ LOCK_TRY_NEVER
+};
+
+enum {
+ DEVICE_NONE = 0,
+ DEVICE_CA, /* cache aware device */
+ DEVICE_CO /* cache oblivious device */
+};
+
+typedef struct
+{
+ unsigned long key;
+ void *data;
+ tbm_data_free free_func ;
+
+ /* link of user_data */
+ struct list_head item_link;
+} tbm_user_data;
+
+/* list of bufmgr */
+static struct list_head *gBufMgrs = NULL;
+
+
+static inline int
+_tgl_init (int fd, unsigned int key)
+{
+ struct tgl_attribute attr;
+ int err;
+
+ attr.key = key;
+ attr.timeout_ms = 1000;
+
+ err = ioctl (fd, TGL_IOC_INIT_LOCK, &attr);
+ if (err)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error(%s) %s:%d key:%d\n",
+ getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
+ return 0;
+ }
+
+ return 1;
+}
+
+static inline int
+_tgl_destroy (int fd, unsigned int key)
+{
+ int err;
+ err = ioctl (fd, TGL_IOC_DESTROY_LOCK, key);
+ if (err)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error(%s) %s:%d key:%d\n",
+ getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
+ return 0;
+ }
+
+ return 1;
+}
+
+static inline int
+_tgl_lock (int fd, unsigned int key)
+{
+ int err;
+ err = ioctl (fd, TGL_IOC_LOCK_LOCK, key);
+ if (err)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error(%s) %s:%d key:%d\n",
+ getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
+ return 0;
+ }
+
+ return 1;
+}
+
+static inline int
+_tgl_unlock (int fd, unsigned int key)
+{
+ int err;
+ err = ioctl (fd, TGL_IOC_UNLOCK_LOCK, key);
+ if (err)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error(%s) %s:%d key:%d\n",
+ getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
+ return 0;
+ }
+
+ return 1;
+}
+
+static inline int
+_tgl_set_data (int fd, unsigned int key, unsigned int val)
+{
+ int err;
+ struct tgl_user_data arg;
+
+ arg.key = key;
+ arg.data1 = val;
+ err = ioctl (fd, TGL_IOC_SET_DATA, &arg);
+ if (err)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error(%s) %s:%d key:%d\n",
+ getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
+ return 0;
+ }
+
+ return 1;
+}
+
+static inline unsigned int
+_tgl_get_data (int fd, unsigned int key, unsigned int *locked)
+{
+ int err;
+ struct tgl_user_data arg = {0,};
+
+ arg.key = key;
+ err = ioctl (fd, TGL_IOC_GET_DATA, &arg);
+ if (err)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error(%s) %s:%d key:%d\n",
+ getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
+ return 0;
+ }
+
+ if (locked)
+ *locked = arg.locked;
+
+ return arg.data1;
+}
+
+static tbm_user_data *
+_user_data_lookup (struct list_head *user_data_list, unsigned long key)
+{
+ tbm_user_data *user_data = NULL;
+ tbm_user_data *old_data = NULL, *tmp = NULL;
+
+ if (!LIST_IS_EMPTY (user_data_list))
+ {
+ LIST_FOR_EACH_ENTRY_SAFE (old_data, tmp, user_data_list, item_link)
+ {
+ if (old_data->key == key)
+ {
+ user_data = old_data;
+ return user_data;
+ }
+ }
+ }
+
+ return user_data;
+}
+
+static tbm_user_data *
+_user_data_create (unsigned long key, tbm_data_free data_free_func)
+{
+ tbm_user_data * user_data = NULL;
+
+ user_data = calloc (1, sizeof (tbm_user_data));
+ if (!user_data)
+ return NULL;
+
+ user_data->key = key;
+ user_data->free_func = data_free_func;
+ user_data->data = (void *)0;
+
+ return user_data;
+}
+
+static void
+_user_data_delete (tbm_user_data *user_data)
+{
+ if (user_data->data && user_data->free_func)
+ user_data->free_func(user_data->data);
+
+ LIST_DEL (&user_data->item_link);
+
+ free(user_data);
+}
+
+static int
+_bo_lock (tbm_bo bo)
+{
+ tbm_bufmgr bufmgr = bo->bufmgr;
+ int ret = 0;
+
+ if (bufmgr->backend->flags&TBM_LOCK_CTRL_BACKEND &&
+ bufmgr->backend->bo_lock)
+ {
+ /* use backend lock */
+ ret = bufmgr->backend->bo_lock (bo);
+ }
+ else
+ {
+ /* use tizen global lock */
+ ret = _tgl_lock (bufmgr->lock_fd, bo->tgl_key);
+ }
+
+ return ret;
+}
+
+static void
+_bo_unlock (tbm_bo bo)
+{
+ tbm_bufmgr bufmgr = bo->bufmgr;
+
+ if (bufmgr->backend->flags&TBM_LOCK_CTRL_BACKEND &&
+ bufmgr->backend->bo_unlock)
+ {
+ /* use backend unlock */
+ bufmgr->backend->bo_unlock (bo);
+ }
+ else
+ {
+ /* use tizen global unlock */
+ _tgl_unlock (bufmgr->lock_fd, bo->tgl_key);
+ }
+}
+
+static int
+_tbm_bo_lock (tbm_bo bo)
+{
+ tbm_bufmgr bufmgr = NULL;
+ int old;
+ int ret = 0;
+
+ if (!bo)
+ return 0;
+
+ bufmgr = bo->bufmgr;
+
+ RETURN_VAL_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
+
+ if (bo->lock_cnt < 0)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error %s:%d bo:%p(%d) LOCK_CNT=%d\n",
+ getpid(), __FUNCTION__, __LINE__, bo, bo->tgl_key, bo->lock_cnt);
+ }
+
+ old = bo->lock_cnt;
+ switch (bufmgr->lock_type)
+ {
+ case LOCK_TRY_ALWAYS: /* LOCK_TRY_ALWAYS */
+ pthread_mutex_unlock (&bufmgr->lock);
+ ret = _bo_lock (bo);
+ pthread_mutex_lock (&bufmgr->lock);
+ if(ret)
+ bo->lock_cnt++;
+ break;
+ case LOCK_TRY_NEVER: /* LOCK_TRY_NEVER */
+ return 1;
+ break;
+ default:
+ if (bo->lock_cnt == 0)
+ {
+ pthread_mutex_unlock (&bufmgr->lock);
+ ret = _bo_lock (bo);
+ pthread_mutex_lock (&bufmgr->lock);
+ if (ret)
+ bo->lock_cnt++;
+ }
+
+ break;
+ }
+
+ DBG_LOCK ("[libtbm:%d] >> LOCK bo:%p(%d, %d->%d)\n", getpid(),
+ bo, bo->tgl_key, old, bo->lock_cnt);
+
+ return 1;
+}
+
+static void
+_tbm_bo_unlock (tbm_bo bo)
+{
+ tbm_bufmgr bufmgr = NULL;
+
+ int old;
+
+ if (!bo)
+ return;
+
+ bufmgr = bo->bufmgr;
+
+ RETURN_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags));
+
+ old = bo->lock_cnt;
+ if (bo->lock_cnt > 0)
+ {
+ bo->lock_cnt--;
+ if (bo->lock_cnt == 0)
+ _bo_unlock (bo);
+ }
+ else if (bo->lock_cnt < 0)
+ {
+ bo->lock_cnt = 0;
+ }
+
+ DBG_LOCK ("[libtbm:%d] << unlock bo:%p(%d, %d->%d)\n", getpid(),
+ bo, bo->tgl_key, old, bo->lock_cnt);
+}
+
+
+static int
+_tbm_bo_set_state (tbm_bo bo, int device, int opt)
+{
+ tbm_bufmgr bufmgr = bo->bufmgr;
+ char need_flush = 0;
+ unsigned short cntFlush = 0;
+ unsigned int is_locked;
+
+ RETURN_VAL_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
+
+ /* get cache state of a bo */
+ bo->cache_state.val = _tgl_get_data (bufmgr->lock_fd, bo->tgl_key, &is_locked);
+
+ if (!bo->cache_state.data.isCacheable)
+ return 1;
+
+ /* get global cache flush count */
+ cntFlush = (unsigned short)_tgl_get_data (bufmgr->lock_fd, GLOBAL_KEY, NULL);
+
+ if (DEVICE_IS_CACHE_AWARE (device))
+ {
+ if (bo->cache_state.data.isDirtied == DEVICE_CO &&
+ bo->cache_state.data.isCached)
+ {
+ need_flush = TBM_CACHE_INV;
+ }
+
+ bo->cache_state.data.isCached = 1;
+ if (opt & TBM_OPTION_WRITE)
+ bo->cache_state.data.isDirtied = DEVICE_CA;
+ else
+ bo->cache_state.data.isDirtied = DEVICE_NONE;
+ }
+ else
+ {
+ if (bo->cache_state.data.isDirtied == DEVICE_CA &&
+ bo->cache_state.data.isCached &&
+ bo->cache_state.data.cntFlush == cntFlush)
+ {
+ need_flush = TBM_CACHE_CLN | TBM_CACHE_ALL;
+ }
+
+ if (opt & TBM_OPTION_WRITE)
+ bo->cache_state.data.isDirtied = DEVICE_CO;
+ else
+ bo->cache_state.data.isDirtied = DEVICE_NONE;
+ }
+
+ if (need_flush)
+ {
+ /* call backend cache flush */
+ bufmgr->backend->bo_cache_flush (bo, need_flush);
+
+ /* set global cache flush count */
+ if (need_flush & TBM_CACHE_ALL)
+ _tgl_set_data (bufmgr->lock_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
+
+ DBG ("[libtbm:%d] \tcache(%d,%d,%d)....flush:0x%x, cntFlush(%d)\n", getpid(),
+ bo->cache_state.data.isCacheable,
+ bo->cache_state.data.isCached,
+ bo->cache_state.data.isDirtied,
+ need_flush, cntFlush);
+ }
+
+ return 1;
+}
+
+static void
+_tbm_bo_save_state (tbm_bo bo)
+{
+ tbm_bufmgr bufmgr = bo->bufmgr;
+ unsigned short cntFlush = 0;
+
+ RETURN_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags));
+
+ /* get global cache flush count */
+ cntFlush = (unsigned short)_tgl_get_data (bufmgr->lock_fd, GLOBAL_KEY, NULL);
+
+ /* save global cache flush count */
+ bo->cache_state.data.cntFlush = cntFlush;
+ _tgl_set_data(bufmgr->lock_fd, bo->tgl_key, bo->cache_state.val);
+}
+
+static int
+_tbm_bo_init_state (tbm_bo bo, int opt)
+{
+ tbm_bufmgr bufmgr = bo->bufmgr;
+ tbm_bo_cache_state cache_state;
+
+ RETURN_VAL_CHECK_FLAG (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);
+
+ cache_state.data.isCacheable = BO_IS_CACHEABLE(bo);
+ cache_state.data.isDirtied = DEVICE_NONE;
+ cache_state.data.isCached = 0;
+ cache_state.data.cntFlush = 0;
+
+ _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;
+ default:
+ break;
+ }
+
+ return 1;
+}
+
+static void
+_tbm_bo_destroy_state (tbm_bo bo)
+{
+ tbm_bufmgr bufmgr = bo->bufmgr;
+
+ RETURN_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags));
+
+ _tgl_destroy (bufmgr->lock_fd, bo->tgl_key);
+}
+
+static void
+_tbm_bo_ref (tbm_bo bo)
+{
+ bo->ref_cnt++;
+}
+
+static void
+_tbm_bo_unref (tbm_bo bo)
+{
+ tbm_bufmgr bufmgr = bo->bufmgr;
+ tbm_user_data *old_data = NULL, *tmp = NULL;
+
+ if (bo->ref_cnt <= 0)
+ return;
+
+ bo->ref_cnt--;
+ if (bo->ref_cnt == 0)
+ {
+ /* destory the user_data_list */
+ if (!LIST_IS_EMPTY (&bo->user_data_list))
+ {
+ LIST_FOR_EACH_ENTRY_SAFE (old_data, tmp, &bo->user_data_list, item_link)
+ {
+ DBG ("[libtbm:%d] free user_data \n", getpid());
+ _user_data_delete (old_data);
+ }
+ }
+
+ if (bo->lock_cnt > 0)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error %s:%d lock_cnt:%d\n",
+ getpid(), __FUNCTION__, __LINE__, bo->lock_cnt);
+ _bo_unlock (bo);
+ }
+
+ /* Destroy Global Lock */
+ _tbm_bo_destroy_state (bo);
+
+ /* call the bo_free */
+ bufmgr->backend->bo_free (bo);
+ bo->priv = NULL;
+
+ LIST_DEL (&bo->item_link);
+ free(bo);
+ bo = NULL;
+ }
+
+}
+
+static int
+_tbm_bufmgr_init_state (tbm_bufmgr bufmgr)
+{
+ RETURN_VAL_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
+
+ bufmgr->lock_fd = open(tgl_devfile, O_RDWR);
+
+ if(bufmgr->lock_fd < 0)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error: Fail to open global_lock:%s\n",
+ getpid(), tgl_devfile);
+ return 0;
+ }
+
+ if (!_tgl_init(bufmgr->lock_fd, GLOBAL_KEY))
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error: Fail to initialize the tgl\n",
+ getpid());
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+_tbm_bufmgr_destroy_state (tbm_bufmgr bufmgr)
+{
+ RETURN_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags));
+
+ close (bufmgr->lock_fd);
+}
+
+static int
+_check_version (TBMModuleVersionInfo *data)
+{
+ int abimaj, abimin;
+ int vermaj, vermin;
+
+ abimaj = GET_ABI_MAJOR (data->abiversion);
+ abimin = GET_ABI_MINOR (data->abiversion);
+
+ fprintf (stderr, "[libtbm:%d] "
+ "TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
+ getpid(), data->modname ? data->modname : "UNKNOWN!",
+ data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
+
+ vermaj = GET_ABI_MAJOR (TBM_ABI_VERSION);
+ vermin = GET_ABI_MINOR (TBM_ABI_VERSION);
+
+ DBG ("[libtbm:%d] " "TBM ABI version %d.%d\n", getpid(), vermaj, vermin);
+
+ if (abimaj != vermaj)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
+ getpid(), abimaj, vermaj);
+ return 0;
+ }
+ else if (abimin > vermin)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
+ getpid(), abimin, vermin);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+_tbm_bufmgr_load_module (tbm_bufmgr bufmgr, int fd, const char *file)
+{
+ char path[PATH_MAX] = {0,};
+ TBMModuleData *initdata = NULL;
+ void * module_data;
+
+ snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
+
+ module_data = dlopen (path, RTLD_LAZY);
+ if (!module_data)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "failed to load module: %s(%s)\n",
+ getpid(), dlerror(), file);
+ return 0;
+ }
+
+ initdata = dlsym (module_data, "tbmModuleData");
+ if (initdata)
+ {
+ ModuleInitProc init;
+ TBMModuleVersionInfo *vers;
+
+ vers = initdata->vers;
+ init = initdata->init;
+
+ if (vers)
+ {
+ if (!_check_version (vers))
+ {
+ dlclose (module_data);
+ return 0;
+ }
+ }
+ else
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "Error: module does not supply version information.\n",
+ getpid());
+
+ dlclose (module_data);
+ return 0;
+ }
+
+ if (init)
+ {
+ if(!init (bufmgr, fd))
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "Fail to init module(%s)\n",
+ getpid(), file);
+ dlclose (module_data);
+ return 0;
+ }
+ }
+ else
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "Error: module does not supply init symbol.\n", getpid());
+ dlclose (module_data);
+ return 0;
+ }
+ }
+ else
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "Error: module does not have data object.\n", getpid());
+ dlclose (module_data);
+ return 0;
+ }
+
+ bufmgr->module_data = module_data;
+
+ fprintf (stderr,"[libtbm:%d] "
+ "Success to load module(%s)\n", getpid(), file);
+
+ return 1;
+}
+
+static int _tbm_load_module (tbm_bufmgr bufmgr, int fd)
+{
+ struct dirent **namelist;
+ const char *p = NULL;
+ int n;
+ int ret = 0;
+
+ /* load bufmgr priv from default lib */
+ ret = _tbm_bufmgr_load_module (bufmgr, fd, DEFAULT_LIB);
+
+ /* load bufmgr priv from configured path */
+ if (!ret)
+ {
+ n = scandir (BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
+ if (n < 0)
+ fprintf (stderr,"[libtbm:%d] "
+ "no files : %s\n", getpid(), BUFMGR_MODULE_DIR);
+ else
+ {
+ while(n--)
+ {
+ if (!ret && strstr (namelist[n]->d_name, PREFIX_LIB))
+ {
+ p = strstr (namelist[n]->d_name, SUFFIX_LIB);
+ if (!strcmp (p, SUFFIX_LIB))
+ {
+ ret = _tbm_bufmgr_load_module (bufmgr, fd, namelist[n]->d_name);
+ }
+ }
+ free(namelist[n]);
+ }
+ free(namelist);
+ }
+ }
+
+ return ret;
+}
+
+tbm_bufmgr
+tbm_bufmgr_init (int fd)
+{
+ char *env;
+ tbm_bufmgr bufmgr;
+
+#ifdef DEBUG
+ env = getenv("GEM_DEBUG");
+ if(env)
+ {
+ bDebug = atoi(env);
+ fprintf(stderr, "GEM_DEBUG=%s\n", env);
+ }
+ else
+ bDebug = 0;
+#endif
+
+ /* initialize buffer manager */
+ if (fd < 0)
+ return NULL;
+
+ if(gBufMgrs == NULL)
+ {
+ gBufMgrs = malloc(sizeof(struct list_head));
+ LIST_INITHEAD(gBufMgrs);
+ }
+ else
+ {
+ LIST_FOR_EACH_ENTRY(bufmgr, gBufMgrs, link)
+ {
+ if(bufmgr->fd == fd)
+ {
+ bufmgr->ref_count++;
+ fprintf (stderr, "[libtbm:%d] bufmgr ref: fd=%d, ref_count:%d\n",
+ getpid(), fd, bufmgr->ref_count);
+ return bufmgr;
+ }
+ }
+ bufmgr = NULL;
+ }
+ fprintf(stderr, "[libtbm:%d] bufmgr init: fd=%d\n", getpid(), fd);
+
+ /* allocate bufmgr */
+ bufmgr = calloc (1, sizeof(struct _tbm_bufmgr));
+ if (!bufmgr)
+ return NULL;
+
+ /* load bufmgr priv from env */
+ if (!_tbm_load_module(bufmgr, fd))
+ {
+ fprintf (stderr,"[libtbm:%d] "
+ "error : Fail to load bufmgr backend\n",
+ getpid());
+ free (bufmgr);
+ bufmgr = NULL;
+ return NULL;
+ }
+
+ bufmgr->ref_count = 1;
+ bufmgr->fd = fd;
+
+ fprintf(stderr, "[libtbm:%d] create tizen bufmgr: ref_count:%d\n",
+ getpid(), bufmgr->ref_count);
+
+ if (pthread_mutex_init (&bufmgr->lock, NULL) != 0)
+ {
+ bufmgr->backend->bufmgr_deinit (bufmgr);
+ free (bufmgr);
+ bufmgr = NULL;
+ return NULL;
+ }
+
+ /* intialize the tizen global status */
+ if (!_tbm_bufmgr_init_state (bufmgr))
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error: Fail to init state\n",
+ getpid());
+ bufmgr->backend->bufmgr_deinit (bufmgr);
+ free (bufmgr);
+ bufmgr = NULL;
+ return NULL;
+ }
+
+ /* setup the lock_type */
+ env = getenv ("BUFMGR_LOCK_TYPE");
+ if (env && !strcmp (env, "always"))
+ bufmgr->lock_type = LOCK_TRY_ALWAYS;
+ else if(env && !strcmp(env, "none"))
+ bufmgr->lock_type = LOCK_TRY_NEVER;
+ else
+ bufmgr->lock_type = LOCK_TRY_ONCE;
+ DBG ("[libtbm:%d] BUFMGR_LOCK_TYPE=%s\n", getpid(), env?env:"default:once");
+
+ /* setup the map_cache */
+ env = getenv ("BUFMGR_MAP_CACHE");
+ if (env && !strcmp (env, "false"))
+ bufmgr->use_map_cache = 0;
+ else
+ bufmgr->use_map_cache = 1;
+ DBG ("[libtbm:%d] BUFMGR_MAP_CACHE=%s\n", getpid(), env?env:"default:true");
+
+ /* intialize bo_list */
+ LIST_INITHEAD (&bufmgr->bo_list);
+
+ /* add bufmgr to the gBufMgrs */
+ LIST_ADD(&bufmgr->link, gBufMgrs);
+
+ return bufmgr;
+}
+
+void
+tbm_bufmgr_deinit (tbm_bufmgr bufmgr)
+{
+ TBM_RETURN_IF_FAIL (TBM_BUFMGR_IS_VALID(bufmgr));
+
+ tbm_bo bo = NULL;
+ tbm_bo tmp = NULL;
+
+ bufmgr->ref_count--;
+ if (bufmgr->ref_count > 0)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "tizen bufmgr destroy: bufmgr:%p, ref_cnt:%d\n",
+ getpid(), bufmgr, bufmgr->ref_count);
+ return;
+ }
+
+ /* destroy bo_list */
+ if(!LIST_IS_EMPTY (&bufmgr->bo_list))
+ {
+ LIST_FOR_EACH_ENTRY_SAFE (bo, tmp, &bufmgr->bo_list, item_link)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "Un-freed bo(%p, ref:%d) \n",
+ getpid(), bo, bo->ref_cnt);
+ bo->ref_cnt = 1;
+ tbm_bo_unref(bo);
+ }
+ }
+
+ /* destroy the tizen global status */
+ _tbm_bufmgr_destroy_state (bufmgr);
+
+ /* destroy bufmgr priv */
+ bufmgr->backend->bufmgr_deinit (bufmgr->backend->priv);
+ bufmgr->backend->priv = NULL;
+ tbm_backend_free (bufmgr->backend);
+ bufmgr->backend = NULL;
+
+ pthread_mutex_destroy (&bufmgr->lock);
+
+ fprintf (stderr, "[libtbm:%d] "
+ "tizen bufmgr destroy: bufmgr:%p, ref_cnt:%d\n",
+ getpid(), bufmgr, bufmgr->ref_count);
+
+ dlclose (bufmgr->module_data);
+
+ free (bufmgr);
+ bufmgr = NULL;
+}
+
+
+int
+tbm_bo_size (tbm_bo bo)
+{
+ TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), 0);
+
+ tbm_bufmgr bufmgr = bo->bufmgr;
+ int size;
+
+ pthread_mutex_lock(&bufmgr->lock);
+ size = bufmgr->backend->bo_size(bo);
+ pthread_mutex_unlock(&bufmgr->lock);
+
+ return size;
+}
+
+tbm_bo
+tbm_bo_ref (tbm_bo bo)
+{
+ TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), NULL);
+
+ tbm_bufmgr bufmgr = bo->bufmgr;
+
+ pthread_mutex_lock(&bufmgr->lock);
+
+ _tbm_bo_ref (bo);
+
+ pthread_mutex_unlock(&bufmgr->lock);
+
+ return bo;
+}
+
+void
+tbm_bo_unref (tbm_bo bo)
+{
+ TBM_RETURN_IF_FAIL(TBM_BO_IS_VALID(bo));
+
+ tbm_bufmgr bufmgr = bo->bufmgr;
+
+ pthread_mutex_lock (&bufmgr->lock);
+
+ _tbm_bo_unref (bo);
+
+ pthread_mutex_unlock(&bufmgr->lock);
+}
+
+tbm_bo
+tbm_bo_alloc (tbm_bufmgr bufmgr, int size, int flags)
+{
+ TBM_RETURN_VAL_IF_FAIL (TBM_BUFMGR_IS_VALID(bufmgr) && (size > 0), NULL);
+
+ tbm_bo bo = NULL;
+ void * bo_priv = NULL;
+
+ bo = calloc (1, sizeof(struct _tbm_bo));
+ if(!bo)
+ return NULL;
+
+ bo->bufmgr = bufmgr;
+
+ pthread_mutex_lock (&bufmgr->lock);
+
+ bo_priv = bufmgr->backend->bo_alloc (bo, size, flags);
+ if (!bo_priv)
+ {
+ free (bo);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return NULL;
+ }
+
+ bo->ref_cnt = 1;
+ bo->flags = flags;
+ bo->tgl_key = INITIAL_KEY;
+ bo->priv = bo_priv;
+
+ /* init bo state */
+ if (!_tbm_bo_init_state (bo, CACHE_OP_CREATE))
+ {
+ _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;
+}
+
+tbm_bo
+tbm_bo_import (tbm_bufmgr bufmgr, unsigned int key)
+{
+ TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
+
+ tbm_bo bo = NULL;
+ void * bo_priv = NULL;
+
+ bo = calloc (1, sizeof(struct _tbm_bo));
+ if(!bo)
+ return NULL;
+
+ bo->bufmgr = bufmgr;
+
+ pthread_mutex_lock (&bufmgr->lock);
+
+ bo_priv = bufmgr->backend->bo_import (bo, key);
+ if (!bo_priv)
+ {
+ free (bo);
+ pthread_mutex_unlock (&bufmgr->lock);
+ return NULL;
+ }
+
+ bo->ref_cnt = 1;
+ bo->tgl_key = INITIAL_KEY;
+ bo->priv = bo_priv;
+
+ /* init bo state */
+ if (!_tbm_bo_init_state (bo, CACHE_OP_IMPORT))
+ {
+ _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;
+}
+
+unsigned int
+tbm_bo_export (tbm_bo bo)
+{
+ 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 (bo);
+ pthread_mutex_unlock (&bufmgr->lock);
+
+ return ret;
+}
+
+tbm_bo_handle
+tbm_bo_get_handle (tbm_bo bo, int device)
+{
+ TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), (tbm_bo_handle)0);
+
+ tbm_bufmgr bufmgr;
+ tbm_bo_handle bo_handle;
+
+ bufmgr = bo->bufmgr;
+
+ pthread_mutex_lock (&bufmgr->lock);
+ bo_handle = bufmgr->backend->bo_get_handle (bo, device);
+ pthread_mutex_unlock (&bufmgr->lock);
+
+ return bo_handle;
+}
+
+tbm_bo_handle
+tbm_bo_map (tbm_bo bo, int device, int opt)
+{
+ TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), (tbm_bo_handle)0);
+
+ tbm_bufmgr bufmgr;
+ tbm_bo_handle bo_handle;
+
+ bufmgr = bo->bufmgr;
+
+ pthread_mutex_lock (&bufmgr->lock);
+
+ _tbm_bo_lock (bo);
+ bo_handle = bufmgr->backend->bo_map (bo, device, opt);
+
+ /* increase the ref_count */
+// _tbm_bo_ref (bo);
+
+ if (bufmgr->use_map_cache == 1 && bo->map_cnt == 0)
+ _tbm_bo_set_state (bo, device, opt);
+
+ /* increase the map_count */
+ bo->map_cnt++;
+
+ pthread_mutex_unlock (&bufmgr->lock);
+
+ return bo_handle;
+}
+
+int
+tbm_bo_unmap (tbm_bo bo)
+{
+ 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_unmap (bo);
+
+ /* decrease the map_count */
+ bo->map_cnt--;
+
+ if (bo->map_cnt == 0)
+ _tbm_bo_save_state (bo);
+
+ _tbm_bo_unlock (bo);
+
+ /* decrease the ref_count */
+// _tbm_bo_unref (bo);
+
+ pthread_mutex_unlock (&bufmgr->lock);
+
+ return ret;
+}
+
+int
+tbm_bo_swap (tbm_bo bo1, tbm_bo bo2)
+{
+ TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo1), 0);
+ TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo2), 0);
+
+ void* temp;
+ unsigned int tmp_key;
+
+ if (bo1->bufmgr->backend->bo_size (bo1) != bo2->bufmgr->backend->bo_size (bo2))
+ return 0;
+
+ pthread_mutex_lock (&bo1->bufmgr->lock);
+
+ tmp_key = bo1->tgl_key;
+ bo1->tgl_key = bo2->tgl_key;
+ bo2->tgl_key = tmp_key;
+
+ temp = bo1->priv;
+ bo1->priv = bo2->priv;
+ bo2->priv = temp;
+
+ pthread_mutex_unlock (&bo1->bufmgr->lock);
+
+ return 1;
+}
+
+int
+tbm_bo_locked (tbm_bo bo)
+{
+ TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), 0);
+
+ tbm_bufmgr bufmgr;
+
+ bufmgr = bo->bufmgr;
+
+ if (bufmgr->lock_type == LOCK_TRY_NEVER)
+ return 0;
+
+ pthread_mutex_lock (&bufmgr->lock);
+
+ if (bo->lock_cnt > 0)
+ {
+ pthread_mutex_unlock (&bufmgr->lock);
+ return 1;
+ }
+
+ pthread_mutex_unlock (&bufmgr->lock);
+
+ return 0;
+}
+
+
+int
+tbm_bo_add_user_data (tbm_bo bo, unsigned long key, tbm_data_free data_free_func)
+{
+ TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), 0);
+
+ tbm_user_data *data;
+
+ /* check if the data according to the key exist if so, return false.*/
+ data = _user_data_lookup (&bo->user_data_list, key);
+ if (data)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "waring: %s:%d user data already exist. key:%ld\n",
+ getpid(), __FUNCTION__, __LINE__, key);
+ return 0;
+ }
+
+ data = _user_data_create (key, data_free_func);
+ if (!data)
+ return 0;
+
+ LIST_ADD (&data->item_link, &bo->user_data_list);
+
+ return 1;
+}
+
+int
+tbm_bo_set_user_data (tbm_bo bo, unsigned long key, void* data)
+{
+ TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), 0);
+
+ tbm_user_data *old_data;
+
+ if (LIST_IS_EMPTY (&bo->user_data_list))
+ return 0;
+
+ old_data = _user_data_lookup (&bo->user_data_list, key);
+ if (!old_data)
+ return 0;
+
+ if (old_data->data && old_data->free_func)
+ old_data->free_func(old_data->data);
+
+ old_data->data = data;
+
+ return 1;
+}
+
+int
+tbm_bo_get_user_data (tbm_bo bo, unsigned long key, void** data)
+{
+ TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), 0);
+
+ tbm_user_data* old_data;
+
+ if (!data || LIST_IS_EMPTY (&bo->user_data_list))
+ return 0;
+
+ old_data = _user_data_lookup (&bo->user_data_list, key);
+ if (!old_data)
+ {
+ *data = NULL;
+ return 0;
+ }
+
+ *data = old_data->data;
+
+ return 1;
+}
+
+int
+tbm_bo_delete_user_data (tbm_bo bo, unsigned long key)
+{
+ TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), 0);
+
+ tbm_user_data *old_data = (void *)0;
+
+ if (LIST_IS_EMPTY (&bo->user_data_list))
+ return 0;
+
+ old_data = _user_data_lookup (&bo->user_data_list, key);
+ if (!old_data)
+ return 0;
+
+ _user_data_delete (old_data);
+
+ return 1;
+}
+
+
--- /dev/null
+/**************************************************************************
+
+libtbm
+
+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 _TBM_BUFMGR_H_
+#define _TBM_BUFMGR_H_
+
+#include <stdint.h>
+
+/**
+ * \file tbm_bufmgr.h
+ * \brief Tizen Buffer Manager
+ */
+
+typedef struct _tbm_bufmgr *tbm_bufmgr;
+typedef struct _tbm_bo *tbm_bo;
+
+/* TBM_DEVICE_TYPE */
+#define TBM_DEVICE_DEFAULT 0 /**< device type to get the default handle */
+#define TBM_DEVICE_CPU 1 /**< device type to get the virtual pointer */
+#define TBM_DEVICE_2D 2 /**< device type to get the 2D memory handle */
+#define TBM_DEVICE_3D 3 /**< device type to get the 3D memory handle */
+#define TBM_DEVICE_MM 4 /**< device type to get the multimedia handle */
+
+/* TBM_OPTION */
+#define TBM_OPTION_READ (1 << 0) /**< access option to read */
+#define TBM_OPTION_WRITE (1 << 1) /**< access option to write */
+
+/**
+ * @brief tbm_bo_handle
+ * abstraction of the memory handle by TBM_DEVICE_TYPE
+ */
+typedef union _tbm_bo_handle
+{
+ void *ptr;
+ int32_t s32;
+ uint32_t u32;
+ int64_t s64;
+ uint64_t u64;
+} tbm_bo_handle;
+
+/**
+ * @brief Enumeration of bo memory type
+ */
+enum TBM_BO_FLAGS
+{
+ TBM_BO_DEFAULT = 0, /**< physically non-contiguous memory */
+ TBM_BO_SCANOUT = (1<<0), /**< physically contiguous memory */
+ TBM_BO_NONCACHABLE = (1<<1), /**< non-cachable memory */
+ TBM_BO_WC = (1<<2), /**< write-combine memory */
+};
+
+/* Functions for buffer manager */
+
+/**
+ * @brief initialize the buffer manager.
+ * @param[in] fd : file descripter of the system buffer manager
+ * @return a buffer manager
+ */
+tbm_bufmgr tbm_bufmgr_init (int fd);
+
+/**
+ * @brief deinitialize the buffer manager.
+ * @param[in] bufmgr : the buffer manager
+ */
+void tbm_bufmgr_deinit (tbm_bufmgr bufmgr);
+
+/* Functions for bo */
+
+/**
+ * @brief allocate the buffer object
+ * @param[in] bufmgr : the buffer manager
+ * @param[in] size : the size of buffer object
+ * @param[in] flags : the flags of memory type
+ * @return a buffer object
+ */
+tbm_bo tbm_bo_alloc (tbm_bufmgr bufmgr, int size, int flags);
+
+/**
+ * @brief increase the reference count of bo.
+ * @param[in] bo : the buffer object
+ * @return a buffer object
+ */
+tbm_bo tbm_bo_ref (tbm_bo bo);
+
+/**
+ * @brief increase the reference count of bo.
+ * @param[in] bo : the buffer object
+ */
+void tbm_bo_unref (tbm_bo bo);
+
+/**
+ * @brief map the buffer object according to the device type and the option.
+ * @param[in] bo : the buffer object
+ * @param[in] device : the device type to get a handle
+ * @param[in] option : the option to access the buffer object
+ * @return the handle of the buffer object
+ */
+tbm_bo_handle tbm_bo_map (tbm_bo bo, int device, int opt);
+
+/**
+ * @brief unmap the buffer object.
+ * @param[in] bo : the buffer object
+ * @return 1 if this function succeeds, otherwise 0.
+ */
+int tbm_bo_unmap (tbm_bo bo);
+
+/**
+ * @brief get the tbm_bo_handle according to the device type.
+ * @param[in] bo : the buffer object
+ * @param[in] device : the device type to get a handle
+ * @return the handle of the buffer object
+ */
+tbm_bo_handle tbm_bo_get_handle (tbm_bo bo, int device);
+
+/**
+ * @brief export the buffer object
+ * @param[in] bo : the buffer object
+ * @return key associated with the buffer object
+ */
+unsigned int tbm_bo_export (tbm_bo bo);
+
+/**
+ * @brief import the buffer object associated with the key.
+ * @param[in] bufmgr : the buffer manager
+ * @param[in] key : the key associated with the buffer object
+ * @return a buffer object
+ */
+tbm_bo tbm_bo_import (tbm_bufmgr bufmgr, unsigned int key);
+
+/**
+ * @brief get the size of a bo.
+ * @param[in] bo : the buffer object
+ * @return 1 if this function succeeds, otherwise 0.
+ */
+int tbm_bo_size (tbm_bo bo);
+
+/**
+ * @brief get the state where the buffer object is locked.
+ * @param[in] bo : the buffer object
+ * @return 1 if this function succeeds, otherwise 0.
+ */
+int tbm_bo_locked (tbm_bo bo);
+
+/**
+ * @brief swap the buffer object.
+ * @param[in] bo1 : the buffer object
+ * @param[in] bo2 : the buffer object
+ * @return 1 if this function succeeds, otherwise 0.
+ */
+int tbm_bo_swap (tbm_bo bo1, tbm_bo bo2);
+
+
+/* Functions for userdata of bo */
+typedef void (*tbm_data_free)(void *);
+
+/**
+ * @brief add a user_data to the buffer object
+ * @param[in] bo : the buffer object
+ * @param[in] key : the key associated with the user_date
+ * @param[in] data_free_func : the function pointer to free the user_data
+ * @return 1 if this function succeeds, otherwise 0.
+ */
+int tbm_bo_add_user_data (tbm_bo bo, unsigned long key, tbm_data_free data_free_func);
+
+/**
+ * @brief delete the user_data in the buffer object.
+ * @param[in] bo : the buffer object
+ * @param[in] key : the key associated with the user_date
+ * @return 1 if this function succeeds, otherwise 0.
+ */
+int tbm_bo_delete_user_data (tbm_bo bo, unsigned long key);
+
+/**
+ * @brief set a user_date to the buffer object.
+ * @param[in] bo : the buffer object
+ * @param[in] key : the key associated with the user_date
+ * @param[in] data : a pointer of the user_data
+ * @return 1 if this function succeeds, otherwise 0.
+ */
+int tbm_bo_set_user_data (tbm_bo bo, unsigned long key, void* data);
+
+/**
+ * @brief get a user_date from the buffer object with the key.
+ * @param[in] bo : the buffer object
+ * @param[in] key : the key associated with the user_date
+ * @param[out] data : to get the user data
+ * @return 1 if this function succeeds, otherwise 0.
+ */
+int tbm_bo_get_user_data (tbm_bo bo, unsigned long key, void** data);
+
+#endif /* _TBM_BUFMGR_H_ */
+
--- /dev/null
+/**************************************************************************
+
+libtbm
+
+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.
+
+**************************************************************************/
+
+#include "config.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include "tbm_bufmgr_int.h"
+
+tbm_bufmgr_backend
+tbm_backend_alloc (void)
+{
+ tbm_bufmgr_backend bufmgr_backend;
+
+ bufmgr_backend = calloc (1, sizeof(struct _tbm_bufmgr_backend));
+ if (!bufmgr_backend)
+ return NULL;
+
+ return bufmgr_backend;
+}
+
+void
+tbm_backend_free (tbm_bufmgr_backend backend)
+{
+ if (!backend)
+ return;
+
+ free (backend);
+ backend = NULL;
+}
+
+int
+tbm_backend_init (tbm_bufmgr bufmgr, tbm_bufmgr_backend backend)
+{
+ int flags = 0;
+
+ if (!bufmgr)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error (%s): fail to init tbm backend... bufmgr is null\n",
+ getpid(), __FUNCTION__);
+ return 0;
+ }
+
+ if (!backend)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error (%s): fail to init tbm backend... backend is null\n",
+ getpid(), __FUNCTION__);
+ return 0;
+ }
+
+ flags = backend->flags;
+ /* check the backend flags */
+ if (!(flags&TBM_CACHE_CTRL_BACKEND))
+ {
+ if (!backend->bo_cache_flush)
+ {
+ fprintf (stderr, "[libtbm:%d] "
+ "error (%s): TBM_FLAG_CACHE_CTRL_TBM needs backend->bo_cache_flush\n",
+ getpid(), __FUNCTION__);
+ return 0;
+ }
+ }
+
+ /* log for tbm flags */
+ fprintf (stderr, "[libtbm:%d] ", getpid());
+ fprintf (stderr, "cache_crtl:");
+ if (flags&TBM_CACHE_CTRL_BACKEND)
+ fprintf (stderr, "BACKEND ");
+ else
+ fprintf (stderr, "TBM ");
+ fprintf (stderr, "lock_crtl:");
+ if (flags&TBM_LOCK_CTRL_BACKEND)
+ fprintf (stderr, "BACKEND ");
+ else
+ fprintf (stderr, "TBM ");
+ fprintf (stderr, "\n");
+
+ bufmgr->backend = backend;
+
+ return 1;
+}
+
+void *
+tbm_backend_get_bufmgr_priv (tbm_bo bo)
+{
+ tbm_bufmgr_backend backend = bo->bufmgr->backend;
+
+ return backend->priv;
+}
+
+void
+tbm_backend_set_bo_priv (tbm_bo bo, void *bo_priv)
+{
+ bo->priv = bo_priv;
+}
+
+void *
+tbm_backend_get_bo_priv (tbm_bo bo)
+{
+ return bo->priv;
+}
+
+
+
--- /dev/null
+/**************************************************************************\r
+\r
+libtbm\r
+\r
+Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.\r
+\r
+Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a\r
+copy of this software and associated documentation files (the\r
+"Software"), to deal in the Software without restriction, including\r
+without limitation the rights to use, copy, modify, merge, publish,\r
+distribute, sub license, and/or sell copies of the Software, and to\r
+permit persons to whom the Software is furnished to do so, subject to\r
+the following conditions:\r
+\r
+The above copyright notice and this permission notice (including the\r
+next paragraph) shall be included in all copies or substantial portions\r
+of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\r
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR\r
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+\r
+**************************************************************************/\r
+\r
+/*\r
+ * This file is referenced by the xf86Module.h in xorg server.\r
+ */\r
+\r
+#ifndef _TBM_BUFMGR_BACKEND_H_\r
+#define _TBM_BUFMGR_BACKEND_H_\r
+\r
+#include <tbm_bufmgr.h>\r
+#include <pthread.h>\r
+\r
+/**\r
+ * \file tbm_bufmgr_backend.h\r
+ * \brief backend header for Tizen Buffer Manager\r
+ * This header is for the implementation of the TBM backend module.\r
+ */\r
+\r
+\r
+#define ABI_MINOR_MASK 0x0000FFFF\r
+#define ABI_MAJOR_MASK 0xFFFF0000\r
+#define GET_ABI_MINOR(v) ((v) & ABI_MINOR_MASK)\r
+#define GET_ABI_MAJOR(v) (((v) & ABI_MAJOR_MASK) >> 16)\r
+\r
+/*\r
+ * ABI versions. Each version has a major and minor revision. Modules\r
+ * using lower minor revisions must work with servers of a higher minor\r
+ * revision. There is no compatibility between different major revisions.\r
+ * Whenever the ABI_ANSIC_VERSION is changed, the others must also be\r
+ * changed. The minor revision mask is 0x0000FFFF and the major revision\r
+ * mask is 0xFFFF0000.\r
+ */\r
+#define SET_ABI_VERSION(maj, min) \\r
+ ((((maj) << 16) & ABI_MAJOR_MASK) | ((min) & ABI_MINOR_MASK))\r
+\r
+#define TBM_ABI_VERSION SET_ABI_VERSION(1, 0) /**< current abi vertion */\r
+\r
+/* TBM_CACHE */\r
+#define TBM_CACHE_INV 0x01 /**< cache invalidate */\r
+#define TBM_CACHE_CLN 0x02 /**< cache clean */\r
+#define TBM_CACHE_ALL 0x10 /**< cache all */\r
+#define TBM_CACHE_FLUSH (TBM_CACHE_INV|TBM_CACHE_CLN) /**< cache flush */\r
+#define TBM_CACHE_FLUSH_ALL (TBM_CACHE_FLUSH|TBM_CACHE_ALL) /**< cache flush all */\r
+\r
+/* TBM flag for cache control and lock control */\r
+/**\r
+ * TBM_CACHE_CTRL_BACKEND indicates that the backend control the cache coherency.\r
+ */
+#define TBM_CACHE_CTRL_BACKEND (1 << 0)\r
+
+/**
+ * TBM_LOCK_CTRL_BACKEND indicates that the backend control the lock of bos.\r
+ */
+#define TBM_LOCK_CTRL_BACKEND (1 << 1)\r
+\r
+typedef struct _tbm_bufmgr_backend *tbm_bufmgr_backend;\r
+\r
+/**\r
+ * @brief TBM backend functions\r
+ * the set of function pointers for the backend module of TBM.\r
+ */\r
+struct _tbm_bufmgr_backend\r
+{\r
+ int flags;\r
+\r
+ void *priv; /**< bufmgr private */\r
+\r
+ /**\r
+ * @brief deinitialize the bufmgr private.\r
+ * @param[in] bufmgr : the private of the bufmgr\r
+ * @return 1 if this function succeeds, otherwise 0.\r
+ */\r
+ void (*bufmgr_deinit) (void *priv);\r
+\r
+ /**\r
+ * @brief get the size of a bo.\r
+ * @param[in] bo : the buffer object\r
+ * @return 1 if this function succeeds, otherwise 0.\r
+ */\r
+ int (*bo_size) (tbm_bo bo);\r
+\r
+ /**\r
+ * @brief allocate the buffer object\r
+ * @param[in] bo : the buffer object\r
+ * @param[in] size : the size of buffer object\r
+ * @param[in] flags : the flags of memory type\r
+ * @return pointer of the bo private.\r
+ */\r
+ void * (*bo_alloc) (tbm_bo bo, int size, int flags);\r
+\r
+ /**\r
+ * @brief free the buffer object.\r
+ * @param[in] bo : the buffer object\r
+ */\r
+ void (*bo_free) (tbm_bo bo);\r
+\r
+ /**\r
+ * @brief import the buffer object associated with the key.\r
+ * @param[in] bo : the buffer object\r
+ * @param[in] key : the key associated with the buffer object\r
+ * @return pointer of the bo private.\r
+ */\r
+ void * (*bo_import) (tbm_bo bo, unsigned int key);\r
+\r
+ /**\r
+ * @brief export the buffer object\r
+ * @param[in] bo : the buffer object\r
+ * @return key associated with the buffer object\r
+ */\r
+ unsigned int (*bo_export) (tbm_bo bo);\r
+\r
+ /**\r
+ * @brief get the tbm_bo_handle according to the device type.\r
+ * @param[in] bo : the buffer object\r
+ * @param[in] device : the device type to get a handle\r
+ * @return the handle of the buffer object\r
+ */\r
+ tbm_bo_handle (*bo_get_handle) (tbm_bo bo, int device);\r
+\r
+ /**\r
+ * @brief map the buffer object according to the device type and the option.\r
+ * @param[in] bo : the buffer object\r
+ * @param[in] device : the device type to get a handle\r
+ * @param[in] option : the option to access the buffer object\r
+ * @return the handle of the buffer object\r
+ */\r
+ tbm_bo_handle (*bo_map) (tbm_bo bo, int device, int opt);\r
+\r
+ /**\r
+ * @brief unmap the buffer object.\r
+ * @param[in] bo : the buffer object\r
+ * @return 1 if this function succeeds, otherwise 0.\r
+ */\r
+ int (*bo_unmap) (tbm_bo bo);\r
+\r
+ /**\r
+ * @brief flush the cache of the buffer object.\r
+ * @param[in] bo : the buffer object\r
+ * @param[in] flags : the flags of cache flush type\r
+ * @return 1 if this function succeeds, otherwise 0.\r
+ */\r
+ int (*bo_cache_flush) (tbm_bo bo, int flags);\r
+\r
+ /**\r
+ * @brief get the global key associated with the buffer object.\r
+ * @param[in] bo : the buffer object\r
+ * @return global key associated with the buffer object.\r
+ */\r
+ int (*bo_get_global_key) (tbm_bo bo);\r
+\r
+ /**\r
+ * @brief lock the buffer object.\r
+ * @param[in] bo : the buffer object\r
+ * @return 1 if this function succeeds, otherwise 0.\r
+ * @remark This function pointer could be null. (default: use the tizen global lock)\r
+ */\r
+ int (*bo_lock) (tbm_bo bo);\r
+\r
+ /**\r
+ * @brief unlock the buffer object.\r
+ * @param[in] bo : the buffer object\r
+ * @return 1 if this function succeeds, otherwise 0.\r
+ * @remark This function pointer could be null. (default: use the tizen global lock)\r
+ */\r
+ int (*bo_unlock) (tbm_bo bo);\r
+\r
+ /* Padding for future extension */\r
+ void (*reserved1) (void);\r
+ void (*reserved2) (void);\r
+ void (*reserved3) (void);\r
+ void (*reserved4) (void);\r
+};\r
+\r
+/**\r
+ * @brief tbm module information\r
+ * data type for the module information\r
+ */\r
+typedef struct\r
+{\r
+ const char *modname; /**< name of module, e.g. "foo" */\r
+ const char *vendor; /**< vendor specific string */\r
+ unsigned long abiversion; /**< ABI version */\r
+} TBMModuleVersionInfo;\r
+\r
+typedef int (*ModuleInitProc) (tbm_bufmgr, int);\r
+\r
+#define MODULEINITPPROTO(func) int func(tbm_bufmgr, int) /**< prototype for init symbol of bakcend module */\r
+\r
+/**\r
+ * @brief tbm module data\r
+ * data type for the entry point of the backend module\r
+ */\r
+typedef struct\r
+{\r
+ TBMModuleVersionInfo *vers; /**< tbm module informtaion */\r
+ ModuleInitProc init; /**< init function of a backend module */\r
+} TBMModuleData;\r
+\r
+tbm_bufmgr_backend tbm_backend_alloc (void);\r
+void tbm_backend_free (tbm_bufmgr_backend backend);\r
+int tbm_backend_init (tbm_bufmgr bufmgr, tbm_bufmgr_backend backend);\r
+\r
+void *tbm_backend_get_bufmgr_priv (tbm_bo bo);\r
+void *tbm_backend_get_bo_priv (tbm_bo bo);\r
+\r
+#endif /* _TBM_BUFMGR_BACKEND_H_ */\r
--- /dev/null
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __TBM_BUFMGR_GLOCK_H__
+#define __TBM_BUFMGR_GLOCK_H__
+
+#include <linux/ioctl.h>
+
+static char tgl_devfile[] = "/dev/slp_global_lock";
+
+#define TGL_IOC_BASE 0x32
+
+struct tgl_attribute {
+ unsigned int key;
+ unsigned int timeout_ms;
+};
+
+struct tgl_user_data {
+ unsigned int key;
+ unsigned int data1;
+ unsigned int data2;
+ unsigned int locked;
+};
+
+typedef enum {
+ _TGL_INIT_LOCK = 1,
+ _TGL_DESTROY_LOCK,
+ _TGL_LOCK_LOCK,
+ _TGL_UNLOCK_LOCK,
+ _TGL_SET_DATA,
+ _TGL_GET_DATA,
+} _tgl_ioctls;
+
+#define TGL_IOC_INIT_LOCK _IOW(TGL_IOC_BASE, _TGL_INIT_LOCK, struct tgl_attribute *)
+#define TGL_IOC_DESTROY_LOCK _IOW(TGL_IOC_BASE, _TGL_DESTROY_LOCK, unsigned int)
+#define TGL_IOC_LOCK_LOCK _IOW(TGL_IOC_BASE, _TGL_LOCK_LOCK, unsigned int)
+#define TGL_IOC_UNLOCK_LOCK _IOW(TGL_IOC_BASE, _TGL_UNLOCK_LOCK, unsigned int)
+#define TGL_IOC_SET_DATA _IOW(TGL_IOC_BASE, _TGL_SET_DATA, struct tgl_user_data *)
+#define TGL_IOC_GET_DATA _IOW(TGL_IOC_BASE, _TGL_GET_DATA, struct tgl_user_data *)
+
+#endif /* __TBM_BUFMGR_GLOCK_H__ */
--- /dev/null
+/**************************************************************************\r
+\r
+libtbm\r
+\r
+Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.\r
+\r
+Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a\r
+copy of this software and associated documentation files (the\r
+"Software"), to deal in the Software without restriction, including\r
+without limitation the rights to use, copy, modify, merge, publish,\r
+distribute, sub license, and/or sell copies of the Software, and to\r
+permit persons to whom the Software is furnished to do so, subject to\r
+the following conditions:\r
+\r
+The above copyright notice and this permission notice (including the\r
+next paragraph) shall be included in all copies or substantial portions\r
+of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\r
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR\r
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\r
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+\r
+**************************************************************************/\r
+\r
+#ifndef _TBM_BUFMGR_INT_H_\r
+#define _TBM_BUFMGR_INT_H_\r
+\r
+#include <tbm_bufmgr.h>\r
+#include <pthread.h>\r
+#include "tbm_bufmgr_backend.h"\r
+\r
+typedef union _tbm_bo_cache_state tbm_bo_cache_state;\r
+\r
+struct list_head\r
+{\r
+ struct list_head *prev;\r
+ struct list_head *next;\r
+};\r
+\r
+union _tbm_bo_cache_state\r
+{\r
+ unsigned int val;\r
+ struct {\r
+ unsigned int cntFlush:16; /*Flush all index for sync*/\r
+ unsigned int isCacheable:1;\r
+ unsigned int isCached:1;\r
+ unsigned int isDirtied:2;\r
+ } data;\r
+};\r
+\r
+/**\r
+ * @brief tbm buffer object\r
+ * buffer object of Tizen Buffer Manager\r
+ */\r
+struct _tbm_bo\r
+{\r
+ tbm_bufmgr bufmgr; /**< tbm buffer manager */\r
+\r
+ int ref_cnt; /**< ref count of bo */\r
+\r
+ int flags; /**< TBM_BO_FLAGS :bo memory type */\r
+\r
+ unsigned int tgl_key; /**< global key for tizen global lock */\r
+\r
+ /* for cache control */\r
+ unsigned int map_cnt; /**< device map count */\r
+ tbm_bo_cache_state cache_state; /**< cache state */\r
+\r
+ int lock_cnt; /**< lock count of bo */\r
+\r
+ struct list_head user_data_list; /**< list of the user_date in bo */\r
+\r
+ void *priv; /**< bo private */\r
+\r
+ struct list_head item_link; /**< link of bo */\r
+};\r
+\r
+/**\r
+ * @brief tbm_bufmgr : structure for tizen buffer manager\r
+ *\r
+ */\r
+struct _tbm_bufmgr\r
+{\r
+ int ref_count; /**< ref count of bufmgr */\r
+\r
+ pthread_mutex_t lock; /**< mutex lock */\r
+\r
+ int fd; /**< bufmgr fd */\r
+\r
+ int lock_fd; /**< fd of tizen global lock */\r
+\r
+ int lock_type; /**< lock_type of bufmgr */\r
+\r
+ int use_map_cache; /**< flag to use the map_cahce */\r
+\r
+ struct list_head bo_list; /**< list of bos belonging to bufmgr */\r
+\r
+ void *module_data;\r
+\r
+ tbm_bufmgr_backend backend; /**< bufmgr backend */\r
+\r
+ struct list_head link; /**< link of bufmgr */\r
+};\r
+\r
+#endif /* _TBM_BUFMGR_INT_H_ */\r