From: Sehong Na Date: Sat, 31 May 2014 03:48:51 +0000 (+0900) Subject: Initialize Tizen 2.3 X-Git-Tag: 2.3a_release X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7743853b5f6aa63701c62855dac99c7dcad74cc0;p=framework%2Fuifw%2Flibtbm.git Initialize Tizen 2.3 --- 7743853b5f6aa63701c62855dac99c7dcad74cc0 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..edf3b5c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +SooChan Lim +SangJin Lee +Boram Park diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..52fd458 --- /dev/null +++ b/COPYING @@ -0,0 +1,18 @@ +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. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..a11ecfd --- /dev/null +++ b/Makefile.am @@ -0,0 +1,5 @@ +SUBDIRS = src drm_slp + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libtbm.pc + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..904cd67 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,12 @@ +#! /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 "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..c05ad14 --- /dev/null +++ b/configure.ac @@ -0,0 +1,73 @@ +# +# 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 + drm_slp/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 "" + diff --git a/drm_slp/Makefile.am b/drm_slp/Makefile.am new file mode 100644 index 0000000..835562c --- /dev/null +++ b/drm_slp/Makefile.am @@ -0,0 +1,19 @@ +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 new file mode 100755 index 0000000..b5ae07d --- /dev/null +++ b/drm_slp/drm_slp_bufmgr.c @@ -0,0 +1,121 @@ +/************************************************************************** + +xserver-xorg-video-sec + +Copyright 2011 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "config.h" +#include +#include +#include +#include +#include "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 new file mode 100644 index 0000000..0add67a --- /dev/null +++ b/drm_slp/drm_slp_bufmgr.h @@ -0,0 +1,49 @@ +/************************************************************************** + +xserver-xorg-video-sec + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef _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_ */ diff --git a/libtbm.manifest b/libtbm.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/libtbm.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/libtbm.pc.in b/libtbm.pc.in new file mode 100644 index 0000000..ca8f058 --- /dev/null +++ b/libtbm.pc.in @@ -0,0 +1,11 @@ +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@ diff --git a/packaging/libtbm.spec b/packaging/libtbm.spec new file mode 100644 index 0000000..f96efc6 --- /dev/null +++ b/packaging/libtbm.spec @@ -0,0 +1,62 @@ +Name: libtbm +Version: 1.0.9 +Release: 1 +VCS: framework/uifw/libtbm#REBASE-31-gdb11679e1cc2e6d3c56bbfe621fc0820322cc2dc +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 +%manifest libtbm.manifest +%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}/libdrm_slp.so +%{_libdir}/pkgconfig/libtbm.pc + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..feacb17 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,21 @@ +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 + diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..e967b93 --- /dev/null +++ b/src/list.h @@ -0,0 +1,131 @@ +/* + * + * 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 + +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_*/ diff --git a/src/tbm_bufmgr.c b/src/tbm_bufmgr.c new file mode 100755 index 0000000..a13ae5f --- /dev/null +++ b/src/tbm_bufmgr.c @@ -0,0 +1,1440 @@ +/************************************************************************** + +libtbm + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tbm_bufmgr.h" +#include "tbm_bufmgr_tgl.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) TBM_LOG (__VA_ARGS__) +#define DBG_LOCK(...) if(bDebug&0x2) TBM_LOG (__VA_ARGS__) +#else +#define DBG(...) +#define DBG_LOCK(...) +#endif + +/* check condition */ +#define TBM_RETURN_IF_FAIL(cond) {\ + if (!(cond)) {\ + TBM_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\ + return;\ + }\ +} +#define TBM_RETURN_VAL_IF_FAIL(cond, val) {\ + if (!(cond)) {\ + TBM_LOG ("[%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 TBM_ALL_CTRL_BACKEND_VALID(flags) \ + ((flags&TBM_CACHE_CTRL_BACKEND) &&\ + (flags&TBM_LOCK_CTRL_BACKEND)) +#define TBM_CACHE_CTRL_BACKEND_VALID(flags) \ + (flags&TBM_CACHE_CTRL_BACKEND) +#define TBM_LOCK_CTRL_BACKEND_VALID(flags) \ + (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) + { + TBM_LOG ( "[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) + { + TBM_LOG ( "[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) + { + TBM_LOG ("[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) + { + TBM_LOG ("[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) + { + TBM_LOG ("[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) + { + TBM_LOG ("[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, int device, int opt) +{ + tbm_bufmgr bufmgr = bo->bufmgr; + int ret = 0; + + if (TBM_LOCK_CTRL_BACKEND_VALID(bufmgr->backend->flags)) + { + if (bufmgr->backend->bo_lock2) + { + /* use bo_lock2 backend lock */ + ret = bufmgr->backend->bo_lock2 (bo, device, opt); + } + else if (bufmgr->backend->bo_lock) + { + /* use bo_lock backend lock */ + ret = bufmgr->backend->bo_lock (bo); + } + else + TBM_LOG ("[libtbm:%d] " + "error %s:%d no backend lock functions\n", + getpid(), __FUNCTION__, __LINE__); + } + 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 (TBM_LOCK_CTRL_BACKEND_VALID(bufmgr->backend->flags)) + { + if (bufmgr->backend->bo_unlock) + { + /* use backend unlock */ + bufmgr->backend->bo_unlock (bo); + } + else + TBM_LOG ("[libtbm:%d] " + "error %s:%d no backend unlock functions\n", + getpid(), __FUNCTION__, __LINE__); + } + else + { + /* use tizen global unlock */ + _tgl_unlock (bufmgr->lock_fd, bo->tgl_key); + } +} + +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 (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); + + 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 (TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags)); + + _tgl_destroy (bufmgr->lock_fd, bo->tgl_key); +} + +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 (TBM_CACHE_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 + { + if( bo->cache_state.data.isDirtied != DEVICE_CA ) + 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 + { + if( bo->cache_state.data.isDirtied != DEVICE_CO ) + bo->cache_state.data.isDirtied = DEVICE_NONE; + } + } + + if (need_flush) + { + /* set global cache flush count */ + if (need_flush & TBM_CACHE_ALL) + _tgl_set_data (bufmgr->lock_fd, GLOBAL_KEY, (unsigned int)(++cntFlush)); + + /* call backend cache flush */ + bufmgr->backend->bo_cache_flush (bo, need_flush); + + 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 (TBM_CACHE_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_lock (tbm_bo bo, int device, int opt) +{ + tbm_bufmgr bufmgr = NULL; + int old; + int ret = 0; + + if (!bo) + return 0; + + bufmgr = bo->bufmgr; + + /* do not try to lock the bo */ + if (bufmgr->lock_type == LOCK_TRY_NEVER) + return 1; + + if (bo->lock_cnt < 0) + { + TBM_LOG ("[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; + if (bufmgr->lock_type == LOCK_TRY_ONCE) + { + if (bo->lock_cnt == 0) + { + pthread_mutex_unlock (&bufmgr->lock); + ret = _bo_lock (bo, device, opt); + pthread_mutex_lock (&bufmgr->lock); + if (ret) + bo->lock_cnt++; + } + } + else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) + { + pthread_mutex_unlock (&bufmgr->lock); + ret = _bo_lock (bo, device, opt); + pthread_mutex_lock (&bufmgr->lock); + if(ret) + bo->lock_cnt++; + } + else + TBM_LOG ("[libtbm:%d] " + "error %s:%d bo:%p lock_type is wrong.\n", + getpid(), __FUNCTION__, __LINE__, bo); + + 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; + + /* do not try to unlock the bo */ + if (bufmgr->lock_type == LOCK_TRY_NEVER) + return; + + old = bo->lock_cnt; + if (bufmgr->lock_type == LOCK_TRY_ONCE) + { + if (bo->lock_cnt > 0) + { + bo->lock_cnt--; + if (bo->lock_cnt == 0) + _bo_unlock (bo); + } + } + else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) + { + if (bo->lock_cnt > 0) + { + bo->lock_cnt--; + _bo_unlock (bo); + } + } + else + TBM_LOG ("[libtbm:%d] " + "error %s:%d bo:%p lock_type is wrong.\n", + getpid(), __FUNCTION__, __LINE__, bo); + + 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 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) + { + TBM_LOG ("[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 (TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1); + + bufmgr->lock_fd = open (tgl_devfile, O_RDWR); + + if(bufmgr->lock_fd < 0) + { + bufmgr->lock_fd = open (tgl_devfile1, O_RDWR); + if(bufmgr->lock_fd < 0) + { + + TBM_LOG ("[libtbm:%d] " + "error: Fail to open global_lock:%s\n", + getpid(), tgl_devfile); + return 0; + } + } + + if (!_tgl_init(bufmgr->lock_fd, GLOBAL_KEY)) + { + TBM_LOG ("[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 (TBM_ALL_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); + + TBM_LOG ("[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) + { + TBM_LOG ("[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) + { + TBM_LOG ("[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) + { + TBM_LOG ("[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 + { + TBM_LOG ("[libtbm:%d] " + "Error: module does not supply version information.\n", + getpid()); + + dlclose (module_data); + return 0; + } + + if (init) + { + if(!init (bufmgr, fd)) + { + TBM_LOG ("[libtbm:%d] " + "Fail to init module(%s)\n", + getpid(), file); + dlclose (module_data); + return 0; + } + + if (!bufmgr->backend || !bufmgr->backend->priv) + { + TBM_LOG ("[libtbm:%d] " + "Error: module(%s) wrong operation. Check backend or backend's priv.\n", + getpid(), file); + dlclose (module_data); + return 0; + } + } + else + { + TBM_LOG ("[libtbm:%d] " + "Error: module does not supply init symbol.\n", getpid()); + dlclose (module_data); + return 0; + } + } + else + { + TBM_LOG ("[libtbm:%d] " + "Error: module does not have data object.\n", getpid()); + dlclose (module_data); + return 0; + } + + bufmgr->module_data = module_data; + + TBM_LOG ("[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) + TBM_LOG ("[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 = NULL; + +#ifdef DEBUG + env = getenv("GEM_DEBUG"); + if(env) + { + bDebug = atoi(env); + TBM_LOG ("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++; + TBM_LOG ("[libtbm:%d] bufmgr ref: fd=%d, ref_count:%d\n", + getpid(), fd, bufmgr->ref_count); + return bufmgr; + } + } + bufmgr = NULL; + } + TBM_LOG ("[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)) + { + TBM_LOG ("[libtbm:%d] " + "error : Fail to load bufmgr backend\n", + getpid()); + free (bufmgr); + bufmgr = NULL; + return NULL; + } + + bufmgr->ref_count = 1; + bufmgr->fd = fd; + + TBM_LOG ("[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->backend->priv); + tbm_backend_free (bufmgr->backend); + dlclose (bufmgr->module_data); + free (bufmgr); + bufmgr = NULL; + return NULL; + } + + /* intialize the tizen global status */ + if (!_tbm_bufmgr_init_state (bufmgr)) + { + TBM_LOG ("[libtbm:%d] " + "error: Fail to init state\n", + getpid()); + bufmgr->backend->bufmgr_deinit (bufmgr->backend->priv); + tbm_backend_free (bufmgr->backend); + pthread_mutex_destroy (&bufmgr->lock); + dlclose (bufmgr->module_data); + 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 if(env && !strcmp(env, "once")) + bufmgr->lock_type = LOCK_TRY_ONCE; + else + bufmgr->lock_type = LOCK_TRY_ALWAYS; + + 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) + { + TBM_LOG ("[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) + { + TBM_LOG ("[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); + + TBM_LOG ("[libtbm:%d] " + "tizen bufmgr destroy: bufmgr:%p, ref_cnt:%d\n", + getpid(), bufmgr, bufmgr->ref_count); + + dlclose (bufmgr->module_data); + + LIST_DEL (&bufmgr->link); + + 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); + + bo_handle = bufmgr->backend->bo_get_handle (bo, device); + + _tbm_bo_lock (bo, device, opt); + + bo_handle = bufmgr->backend->bo_map (bo, device, opt); + + 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); + + 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) + { + TBM_LOG ("[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; +} + +int +tbm_bo_cache_flush(tbm_bo bo, int flags) +{ + tbm_bufmgr bufmgr = bo->bufmgr; + + bufmgr->backend->bo_cache_flush (bo, flags); + + RETURN_VAL_CHECK_FLAG (TBM_CACHE_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1); + + 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 (!bo->cache_state.data.isCacheable) + return 1; + + /* 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)); + + 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); + + return 1; +} diff --git a/src/tbm_bufmgr.h b/src/tbm_bufmgr.h new file mode 100755 index 0000000..150fbb6 --- /dev/null +++ b/src/tbm_bufmgr.h @@ -0,0 +1,240 @@ +/************************************************************************** + +libtbm + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef _TBM_BUFMGR_H_ +#define _TBM_BUFMGR_H_ + +#include + +/** + * \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 memory */ +#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 */ + +#define TBM_CACHE_INV 0x01 +#define TBM_CACHE_CLN 0x02 + +/* TBM_OPTION */ +#define TBM_OPTION_READ (1 << 0) /**< access option to read */ +#define TBM_OPTION_WRITE (1 << 1) /**< access option to write */ +#define TBM_OPTION_VENDOR (0xffff0000) /**< vendor specific option: it depends on the backend */ + +/** + * @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, /**< default memory: it depends on the backend */ + TBM_BO_SCANOUT = (1<<0), /**< scanout memory */ + TBM_BO_NONCACHABLE = (1<<1), /**< non-cachable memory */ + TBM_BO_WC = (1<<2), /**< write-combine memory */ + TBM_BO_VENDOR = (0xffff0000), /**< vendor specific memory: it depends on the backend */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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); + +/** + * @brief flush the cache of the buffer object. + * @param[in] bo : the buffer object + * @param[in] flags : the flags of cache flush type + * @return 1 if this function succeeds, otherwise 0. + */ +int tbm_bo_cache_flush (tbm_bo bo, int flags); + +#ifdef __cplusplus +} +#endif + +#endif /* _TBM_BUFMGR_H_ */ + diff --git a/src/tbm_bufmgr_backend.c b/src/tbm_bufmgr_backend.c new file mode 100755 index 0000000..dd82402 --- /dev/null +++ b/src/tbm_bufmgr_backend.c @@ -0,0 +1,135 @@ +/************************************************************************** + +libtbm + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "config.h" + +#include +#include +#include +#include +#include "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) + { + TBM_LOG ("[libtbm:%d] " + "error (%s): fail to init tbm backend... bufmgr is null\n", + getpid(), __FUNCTION__); + return 0; + } + + if (!backend) + { + TBM_LOG ("[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) + { + TBM_LOG ("[libtbm:%d] " + "error (%s): TBM_FLAG_CACHE_CTRL_TBM needs backend->bo_cache_flush\n", + getpid(), __FUNCTION__); + return 0; + } + } + + /* 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; +} + +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; +} + + + diff --git a/src/tbm_bufmgr_backend.h b/src/tbm_bufmgr_backend.h new file mode 100755 index 0000000..b0b3501 --- /dev/null +++ b/src/tbm_bufmgr_backend.h @@ -0,0 +1,243 @@ +/************************************************************************** + +libtbm + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * This file is referenced by the xf86Module.h in xorg server. + */ + +#ifndef _TBM_BUFMGR_BACKEND_H_ +#define _TBM_BUFMGR_BACKEND_H_ + +#include +#include + +/** + * \file tbm_bufmgr_backend.h + * \brief backend header for Tizen Buffer Manager + * This header is for the implementation of the TBM backend module. + */ + + +#define ABI_MINOR_MASK 0x0000FFFF +#define ABI_MAJOR_MASK 0xFFFF0000 +#define GET_ABI_MINOR(v) ((v) & ABI_MINOR_MASK) +#define GET_ABI_MAJOR(v) (((v) & ABI_MAJOR_MASK) >> 16) + +/* + * ABI versions. Each version has a major and minor revision. Modules + * using lower minor revisions must work with servers of a higher minor + * revision. There is no compatibility between different major revisions. + * Whenever the ABI_ANSIC_VERSION is changed, the others must also be + * changed. The minor revision mask is 0x0000FFFF and the major revision + * mask is 0xFFFF0000. + */ +#define SET_ABI_VERSION(maj, min) \ + ((((maj) << 16) & ABI_MAJOR_MASK) | ((min) & ABI_MINOR_MASK)) + +#define TBM_ABI_VERSION SET_ABI_VERSION(1, 0) /**< current abi vertion */ + +/* TBM_CACHE */ +#define TBM_CACHE_INV 0x01 /**< cache invalidate */ +#define TBM_CACHE_CLN 0x02 /**< cache clean */ +#define TBM_CACHE_ALL 0x10 /**< cache all */ +#define TBM_CACHE_FLUSH (TBM_CACHE_INV|TBM_CACHE_CLN) /**< cache flush */ +#define TBM_CACHE_FLUSH_ALL (TBM_CACHE_FLUSH|TBM_CACHE_ALL) /**< cache flush all */ + +/* TBM flag for cache control and lock control */ +/** + * TBM_CACHE_CTRL_BACKEND indicates that the backend control the cache coherency. + */ +#define TBM_CACHE_CTRL_BACKEND (1 << 0) + +/** + * TBM_LOCK_CTRL_BACKEND indicates that the backend control the lock of bos. + */ +#define TBM_LOCK_CTRL_BACKEND (1 << 1) + +typedef struct _tbm_bufmgr_backend *tbm_bufmgr_backend; + +/** + * @brief TBM backend functions + * the set of function pointers for the backend module of TBM. + */ +struct _tbm_bufmgr_backend +{ + int flags; + + void *priv; /**< bufmgr private */ + + /** + * @brief deinitialize the bufmgr private. + * @param[in] bufmgr : the private of the bufmgr + * @return 1 if this function succeeds, otherwise 0. + */ + void (*bufmgr_deinit) (void *priv); + + /** + * @brief get the size of a bo. + * @param[in] bo : the buffer object + * @return 1 if this function succeeds, otherwise 0. + */ + int (*bo_size) (tbm_bo bo); + + /** + * @brief allocate the buffer object + * @param[in] bo : the buffer object + * @param[in] size : the size of buffer object + * @param[in] flags : the flags of memory type + * @return pointer of the bo private. + */ + void * (*bo_alloc) (tbm_bo bo, int size, int flags); + + /** + * @brief free the buffer object. + * @param[in] bo : the buffer object + */ + void (*bo_free) (tbm_bo bo); + + /** + * @brief import the buffer object associated with the key. + * @param[in] bo : the buffer object + * @param[in] key : the key associated with the buffer object + * @return pointer of the bo private. + */ + void * (*bo_import) (tbm_bo bo, unsigned int key); + + /** + * @brief export the buffer object + * @param[in] bo : the buffer object + * @return key associated with the buffer object + */ + unsigned int (*bo_export) (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 (*bo_get_handle) (tbm_bo bo, int device); + + /** + * @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 (*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 (*bo_unmap) (tbm_bo bo); + + /** + * @brief flush the cache of the buffer object. + * @param[in] bo : the buffer object + * @param[in] flags : the flags of cache flush type + * @return 1 if this function succeeds, otherwise 0. + */ + int (*bo_cache_flush) (tbm_bo bo, int flags); + + /** + * @brief get the global key associated with the buffer object. + * @param[in] bo : the buffer object + * @return global key associated with the buffer object. + */ + int (*bo_get_global_key) (tbm_bo bo); + + /** + * @brief lock the buffer object. + * @param[in] bo : the buffer object + * @return 1 if this function succeeds, otherwise 0. + * @remark This function pointer could be null. (default: use the tizen global lock) + */ + int (*bo_lock) (tbm_bo bo); + + /** + * @brief unlock the buffer object. + * @param[in] bo : the buffer object + * @return 1 if this function succeeds, otherwise 0. + * @remark This function pointer could be null. (default: use the tizen global lock) + */ + int (*bo_unlock) (tbm_bo bo); + + /** + * @brief lock the buffer object with a device and an opt. + * @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 1 if this function succeeds, otherwise 0. + * @remark This function pointer could be null. (default: use the tizen global lock) + */ + int (*bo_lock2) (tbm_bo bo, int device, int opt); + + /* Padding for future extension */ + void (*reserved1) (void); + void (*reserved2) (void); + void (*reserved3) (void); +}; + +/** + * @brief tbm module information + * data type for the module information + */ +typedef struct +{ + const char *modname; /**< name of module, e.g. "foo" */ + const char *vendor; /**< vendor specific string */ + unsigned long abiversion; /**< ABI version */ +} TBMModuleVersionInfo; + +typedef int (*ModuleInitProc) (tbm_bufmgr, int); + +#define MODULEINITPPROTO(func) int func(tbm_bufmgr, int) /**< prototype for init symbol of bakcend module */ + +/** + * @brief tbm module data + * data type for the entry point of the backend module + */ +typedef struct +{ + TBMModuleVersionInfo *vers; /**< tbm module informtaion */ + ModuleInitProc init; /**< init function of a backend module */ +} TBMModuleData; + +tbm_bufmgr_backend tbm_backend_alloc (void); +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_bo_priv (tbm_bo bo); + +#endif /* _TBM_BUFMGR_BACKEND_H_ */ diff --git a/src/tbm_bufmgr_int.h b/src/tbm_bufmgr_int.h new file mode 100755 index 0000000..e13535a --- /dev/null +++ b/src/tbm_bufmgr_int.h @@ -0,0 +1,113 @@ +/************************************************************************** + +libtbm + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef _TBM_BUFMGR_INT_H_ +#define _TBM_BUFMGR_INT_H_ + +#include +#include +#include "tbm_bufmgr_backend.h" + +#define TBM_LOG(...) fprintf (stderr, __VA_ARGS__) + +typedef union _tbm_bo_cache_state tbm_bo_cache_state; + +struct list_head +{ + struct list_head *prev; + struct list_head *next; +}; + +union _tbm_bo_cache_state +{ + unsigned int val; + struct { + unsigned int cntFlush:16; /*Flush all index for sync*/ + unsigned int isCacheable:1; + unsigned int isCached:1; + unsigned int isDirtied:2; + } data; +}; + +/** + * @brief tbm buffer object + * buffer object of Tizen Buffer Manager + */ +struct _tbm_bo +{ + tbm_bufmgr bufmgr; /**< tbm buffer manager */ + + int ref_cnt; /**< ref count of bo */ + + int flags; /**< TBM_BO_FLAGS :bo memory type */ + + unsigned int tgl_key; /**< global key for tizen global lock */ + + /* for cache control */ + unsigned int map_cnt; /**< device map count */ + tbm_bo_cache_state cache_state; /**< cache state */ + + int lock_cnt; /**< lock count of bo */ + + struct list_head user_data_list; /**< list of the user_date in bo */ + + void *priv; /**< bo private */ + + struct list_head item_link; /**< link of bo */ +}; + +/** + * @brief tbm_bufmgr : structure for tizen buffer manager + * + */ +struct _tbm_bufmgr +{ + int ref_count; /**< ref count of bufmgr */ + + pthread_mutex_t lock; /**< mutex lock */ + + int fd; /**< bufmgr fd */ + + int lock_fd; /**< fd of tizen global lock */ + + int lock_type; /**< lock_type of bufmgr */ + + int use_map_cache; /**< flag to use the map_cahce */ + + struct list_head bo_list; /**< list of bos belonging to bufmgr */ + + void *module_data; + + tbm_bufmgr_backend backend; /**< bufmgr backend */ + + struct list_head link; /**< link of bufmgr */ +}; + +#endif /* _TBM_BUFMGR_INT_H_ */ diff --git a/src/tbm_bufmgr_tgl.h b/src/tbm_bufmgr_tgl.h new file mode 100644 index 0000000..10ec1a8 --- /dev/null +++ b/src/tbm_bufmgr_tgl.h @@ -0,0 +1,49 @@ +/* + * 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_TGL_H__ +#define __TBM_BUFMGR_TGL_H__ + +#include + +static char tgl_devfile[] = "/dev/slp_global_lock"; +static char tgl_devfile1[] = "/dev/tgl"; + +#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_TGL_H__ */