From 7743853b5f6aa63701c62855dac99c7dcad74cc0 Mon Sep 17 00:00:00 2001 From: Sehong Na Date: Sat, 31 May 2014 12:48:51 +0900 Subject: [PATCH] Initialize Tizen 2.3 --- AUTHORS | 3 + COPYING | 18 + ChangeLog | 0 Makefile.am | 5 + NEWS | 0 README | 0 autogen.sh | 12 + configure.ac | 73 +++ drm_slp/Makefile.am | 19 + drm_slp/drm_slp_bufmgr.c | 121 ++++ drm_slp/drm_slp_bufmgr.h | 49 ++ libtbm.manifest | 5 + libtbm.pc.in | 11 + packaging/libtbm.spec | 62 ++ src/Makefile.am | 21 + src/list.h | 131 +++++ src/tbm_bufmgr.c | 1440 ++++++++++++++++++++++++++++++++++++++++++++++ src/tbm_bufmgr.h | 240 ++++++++ src/tbm_bufmgr_backend.c | 135 +++++ src/tbm_bufmgr_backend.h | 243 ++++++++ src/tbm_bufmgr_int.h | 113 ++++ src/tbm_bufmgr_tgl.h | 49 ++ 22 files changed, 2750 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 drm_slp/Makefile.am create mode 100755 drm_slp/drm_slp_bufmgr.c create mode 100644 drm_slp/drm_slp_bufmgr.h create mode 100644 libtbm.manifest create mode 100644 libtbm.pc.in create mode 100644 packaging/libtbm.spec create mode 100644 src/Makefile.am create mode 100644 src/list.h create mode 100755 src/tbm_bufmgr.c create mode 100755 src/tbm_bufmgr.h create mode 100755 src/tbm_bufmgr_backend.c create mode 100755 src/tbm_bufmgr_backend.h create mode 100755 src/tbm_bufmgr_int.h create mode 100644 src/tbm_bufmgr_tgl.h 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__ */ -- 2.7.4