From e7650dff90fec984fb7e1eb2a7b71dffeb052df8 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 23 Nov 2015 13:19:04 +0900 Subject: [PATCH 02/12] add initial codes Change-Id: I31582209771bae7887837dd4c7a5614f62e37296 --- AUTHORS | 2 + COPYING | 18 + ChangeLog | 0 Makefile.am | 1 + NEWS | 0 README | 0 autogen.sh | 12 + configure.ac | 62 ++ packaging/libtbm-sprd.spec | 52 ++ src/Makefile.am | 12 + src/tbm_bufmgr_sprd.c | 1723 ++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 1882 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 100755 configure.ac create mode 100644 packaging/libtbm-sprd.spec create mode 100644 src/Makefile.am create mode 100755 src/tbm_bufmgr_sprd.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..05bc6fa --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Debi Prasanna Mohanty +Harsh Aggarwal diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..be13227 --- /dev/null +++ b/COPYING @@ -0,0 +1,18 @@ +Copyright (C) 2000 - 2015 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..af437a6 --- /dev/null +++ b/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src 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 100755 index 0000000..149ebc1 --- /dev/null +++ b/configure.ac @@ -0,0 +1,62 @@ +# +# 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-sprd, 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])]) + +PKG_CHECK_MODULES(LIBDRM, libdrm) +PKG_CHECK_MODULES(LIBTBM, libtbm) +PKG_CHECK_MODULES(LIBDLOG, dlog) + +LIBTBM_SPRD_CFLAGS="$LIBDRM_CFLAGS $LIBTBM_CFLAGS $LIBDLOG_CFLAGS " +LIBTBM_SPRD_LIBS="$LIBDRM_LIBS $LIBTBM_LIBS $LIBDLOG_LIBS " +AC_SUBST(LIBTBM_SPRD_CFLAGS) +AC_SUBST(LIBTBM_SPRD_LIBS) + +bufmgr_dir=${libdir#*/} +AC_SUBST(bufmgr_dir) + +AC_OUTPUT([ + Makefile + src/Makefile]) + +echo "" +echo "CFLAGS : $CFLAGS" +echo "LDFLAGS : $LDFLAGS" +echo "LIBTBM_SPRD_CFLAGS : $LIBTBM_SPRD_CFLAGS" +echo "LIBTBM_SPRD_LIBS : $LIBTBM_SPRD_LIBS" +echo "bufmgr_dir : $bufmgr_dir" +echo "" + diff --git a/packaging/libtbm-sprd.spec b/packaging/libtbm-sprd.spec new file mode 100644 index 0000000..a13584e --- /dev/null +++ b/packaging/libtbm-sprd.spec @@ -0,0 +1,52 @@ +Name: libtbm-sprd +Version: 1.0.0 +Release: 0 +License: MIT +Summary: Tizen Buffer Manager - sprd backend +Group: System/Libraries +ExcludeArch: i586 +Source0: %{name}-%{version}.tar.gz + +BuildRequires: pkgconfig(pthread-stubs) +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(libtbm) +BuildRequires: pkgconfig(dlog) +BuildRequires: linux-glibc-devel +BuildRequires: kernel-headers-tizen-dev +#!BuildIgnore: kernel-headers +BuildConflicts: linux-glibc-devel +Requires: libtbm +Requires: libdrm2 + +%description +descriptionion: ${summary} + +%prep +%setup -q + +%build + +%reconfigure --prefix=%{_prefix} --libdir=%{_libdir}/bufmgr \ + CFLAGS="${CFLAGS} -Wall -Werror `pkg-config --cflags dlog`" 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 + + +%post +if [ -f %{_libdir}/bufmgr/libtbm_default.so ]; then + rm -rf %{_libdir}/bufmgr/libtbm_default.so +fi +ln -s libtbm_sprd.so %{_libdir}/bufmgr/libtbm_default.so + +%postun -p /sbin/ldconfig + +%files +%{_libdir}/bufmgr/libtbm_*.so* +/usr/share/license/%{name} + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..ebe5b35 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,12 @@ +AM_CFLAGS = \ + @LIBTBM_SPRD_CFLAGS@ \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src \ + -I/usr/include/drm + +libtbm_sprd_la_LTLIBRARIES = libtbm_sprd.la +libtbm_sprd_ladir = /${bufmgr_dir} +libtbm_sprd_la_LIBADD = @LIBTBM_SPRD_LIBS@ + +libtbm_sprd_la_SOURCES = \ + tbm_bufmgr_sprd.c diff --git a/src/tbm_bufmgr_sprd.c b/src/tbm_bufmgr_sprd.c new file mode 100755 index 0000000..3f28f0c --- /dev/null +++ b/src/tbm_bufmgr_sprd.c @@ -0,0 +1,1723 @@ +/************************************************************************** + +libtbm_sprd + +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. + +**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG + +//#define USE_CONTIG_ONLY +#define USE_DMAIMPORT + +#define TBM_COLOR_FORMAT_COUNT 8 + + + +#ifdef DEBUG +#define LOG_TAG "TBM_BACKEND" +#include +static int bDebug=0; + +char* target_name() +{ + FILE *f; + char *slash; + static int initialized = 0; + static char app_name[128]; + + if ( initialized ) + return app_name; + + /* get the application name */ + f = fopen("/proc/self/cmdline", "r"); + + if ( !f ) + { + return 0; + } + + memset(app_name, 0x00, sizeof(app_name)); + + if ( fgets(app_name, 100, f) == NULL ) + { + fclose(f); + return 0; + } + + fclose(f); + + if ( (slash=strrchr(app_name, '/')) != NULL ) + { + memmove(app_name, slash+1, strlen(slash)); + } + + initialized = 1; + + return app_name; +} +#define TBM_SPRD_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args) +#define DBG(fmt, args...) if(bDebug&01) LOGE("[%s]" fmt, target_name(), ##args) +#else +#define TBM_SPRD_LOG(...) +#define DBG(...) +#endif + +#define SIZE_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1)) + +#define TBM_SURFACE_ALIGNMENT_PLANE (64) +#define TBM_SURFACE_ALIGNMENT_PITCH_RGB (64) +#define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16) + + +/* check condition */ +#define SPRD_RETURN_IF_FAIL(cond) {\ + if (!(cond)) {\ + TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\ + return;\ + }\ +} +#define SPRD_RETURN_VAL_IF_FAIL(cond, val) {\ + if (!(cond)) {\ + TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\ + return val;\ + }\ +} + +struct dma_buf_info { + unsigned long size; + unsigned int fence_supported; + unsigned int padding; +}; + +#define DMA_BUF_ACCESS_READ 0x1 +#define DMA_BUF_ACCESS_WRITE 0x2 +#define DMA_BUF_ACCESS_DMA 0x4 +#define DMA_BUF_ACCESS_MAX 0x8 + +#define DMA_FENCE_LIST_MAX 5 + +struct dma_buf_fence { + unsigned long ctx; + unsigned int type; +}; + +#define DMABUF_IOCTL_BASE 'F' +#define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type) + +#define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info) +#define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence) +#define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence) + +typedef struct _tbm_bufmgr_sprd *tbm_bufmgr_sprd; +typedef struct _tbm_bo_sprd *tbm_bo_sprd; + +typedef struct _sprd_private +{ + int ref_count; +} PrivGem; + +/* tbm buffor object for sprd */ +struct _tbm_bo_sprd +{ + int fd; + + unsigned int name; /* FLINK ID */ + + unsigned int gem; /* GEM Handle */ + + unsigned int dmabuf; /* fd for dmabuf */ + + void *pBase; /* virtual address */ + + unsigned int size; + + unsigned int flags_sprd; + unsigned int flags_tbm; + + PrivGem* private; + + pthread_mutex_t mutex; + struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX]; + int device; + int opt; +}; + +/* tbm bufmgr private for sprd */ +struct _tbm_bufmgr_sprd +{ + int fd; + void* hashBos; + + int use_dma_fence; +}; + +char *STR_DEVICE[]= +{ + "DEF", + "CPU", + "2D", + "3D", + "MM" +}; + +char *STR_OPT[]= +{ + "NONE", + "RD", + "WR", + "RDWR" +}; + + +uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888, + TBM_FORMAT_BGRA8888, + TBM_FORMAT_RGBX8888, + TBM_FORMAT_RGB888, + TBM_FORMAT_NV12, + TBM_FORMAT_NV21, + TBM_FORMAT_YUV420, + TBM_FORMAT_YVU420 }; + + +#ifndef USE_CONTIG_ONLY +static unsigned int +_get_sprd_flag_from_tbm (unsigned int ftbm) +{ + unsigned int flags = 0; + +/* + * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM + * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM + * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY + * To be updated appropriately once DRM-GEM supports different heap id masks. + * */ + + if (ftbm & TBM_BO_SCANOUT) + { + flags = SPRD_BO_CONTIG; + } + else + { + flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM; + } + + if (ftbm & TBM_BO_WC) + flags |= SPRD_BO_WC; + else if (ftbm & TBM_BO_NONCACHABLE) + flags |= SPRD_BO_NONCACHABLE; + + return flags; +} + +static unsigned int +_get_tbm_flag_from_sprd (unsigned int fsprd) +{ + unsigned int flags = 0; + + if (fsprd & SPRD_BO_NONCONTIG) + flags |= TBM_BO_DEFAULT; + else + flags |= TBM_BO_SCANOUT; + + if (fsprd & SPRD_BO_WC) + flags |= TBM_BO_WC; + else if (fsprd & SPRD_BO_CACHABLE) + flags |= TBM_BO_DEFAULT; + else + flags |= TBM_BO_NONCACHABLE; + + return flags; +} +#endif + +static unsigned int +_get_name (int fd, unsigned int gem) +{ + struct drm_gem_flink arg = {0,}; + + arg.handle = gem; + if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg)) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d fail to get flink gem=%d\n", + getpid(), __FUNCTION__, __LINE__, gem); + return 0; + } + + return (unsigned int)arg.name; +} + +static tbm_bo_handle +_sprd_bo_handle (tbm_bo_sprd bo_sprd, int device) +{ + tbm_bo_handle bo_handle; + memset (&bo_handle, 0x0, sizeof (uint64_t)); + + switch(device) + { + case TBM_DEVICE_DEFAULT: + case TBM_DEVICE_2D: + bo_handle.u32 = (uint32_t)bo_sprd->gem; + break; + case TBM_DEVICE_CPU: + if (!bo_sprd->pBase) + { + struct drm_sprd_gem_mmap arg = {0,}; + + arg.handle = bo_sprd->gem; + arg.size = bo_sprd->size; + if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg))) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot usrptr gem=%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->gem); + return (tbm_bo_handle) NULL; + } + bo_sprd->pBase = (void*)((uint32_t)arg.mapped); + } + + bo_handle.ptr = (void *)bo_sprd->pBase; + break; + case TBM_DEVICE_3D: +#ifdef USE_DMAIMPORT + if (!bo_sprd->dmabuf) + { + struct drm_prime_handle arg = {0, }; + arg.handle = bo_sprd->gem; + if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot dmabuf=%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->gem); + return (tbm_bo_handle) NULL; + } + bo_sprd->dmabuf = arg.fd; + } + + bo_handle.u32 = (uint32_t)bo_sprd->dmabuf; + +#endif + break; + + case TBM_DEVICE_MM: +#ifdef USE_HEAP_ID + //TODO : Add ioctl for GSP MAP once available. + DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(), + __FUNCTION_);_ + +#else + if (!bo_sprd->dmabuf) + { + struct drm_prime_handle arg = {0, }; + + arg.handle = bo_sprd->gem; + if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot dmabuf=%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->gem); + return (tbm_bo_handle) NULL; + } + bo_sprd->dmabuf = arg.fd; + } + + bo_handle.u32 = (uint32_t)bo_sprd->dmabuf; +#endif + break; + default: + bo_handle.ptr = (void *) NULL; + break; + } + + return bo_handle; +} + +#ifdef USE_CACHE +static int +_sprd_cache_flush (int fd, tbm_bo_sprd bo_sprd, int flags) +{ + struct drm_sprd_gem_cache_op cache_op = {0, }; + int ret; + + /* if bo_sprd is null, do cache_flush_all */ + if(bo_sprd) + { + cache_op.flags = 0; + cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase); + cache_op.size = bo_sprd->size; + } + else + { + flags = TBM_CACHE_FLUSH_ALL; + cache_op.flags = 0; + cache_op.usr_addr = 0; + cache_op.size = 0; + } + + if (flags & TBM_CACHE_INV) + { + if(flags & TBM_CACHE_ALL) + cache_op.flags |= SPRD_DRM_CACHE_INV_ALL; + else + cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE; + } + + if (flags & TBM_CACHE_CLN) + { + if(flags & TBM_CACHE_ALL) + cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL; + else + cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE; + } + + if(flags & TBM_CACHE_ALL) + cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES; + + ret = drmCommandWriteRead (fd, DRM_SPRD_GEM_CACHE_OP, &cache_op, sizeof(cache_op)); + if (ret) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d fail to flush the cache.\n", + getpid(), __FUNCTION__, __LINE__); + return 0; + } + + return 1; +} +#endif + +static int +tbm_sprd_bo_size (tbm_bo bo) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + + tbm_bo_sprd bo_sprd; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + + return bo_sprd->size; +} + +static void * +tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + + tbm_bo_sprd bo_sprd; + tbm_bufmgr_sprd bufmgr_sprd; + unsigned int sprd_flags; + + bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0); + + bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd)); + if (!bo_sprd) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d fail to allocate the bo private\n", + getpid(), __FUNCTION__, __LINE__); + return 0; + } + +#ifdef USE_CONTIG_ONLY + flags = TBM_BO_SCANOUT; + sprd_flags = SPRD_BO_CONTIG; +#else + sprd_flags = _get_sprd_flag_from_tbm (flags); + if((flags & TBM_BO_SCANOUT) && + size <= 4*1024) + { + sprd_flags |= SPRD_BO_NONCONTIG; + } +#endif // USE_CONTIG_ONLY + struct drm_sprd_gem_create arg = {0, }; + arg.size = size; + arg.flags = sprd_flags; + if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg, sizeof(arg))) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot create bo(flag:%x, size:%d)\n", + getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size); + free (bo_sprd); + return 0; + } + + bo_sprd->fd = bufmgr_sprd->fd; + bo_sprd->gem = arg.handle; + bo_sprd->size = size; + bo_sprd->flags_tbm = flags; + bo_sprd->flags_sprd = sprd_flags; + bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem); + + pthread_mutex_init(&bo_sprd->mutex, NULL); + + if (bufmgr_sprd->use_dma_fence + && !bo_sprd->dmabuf) + { + struct drm_prime_handle arg = {0, }; + + arg.handle = bo_sprd->gem; + if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot dmabuf=%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->gem); + free (bo_sprd); + return 0; + } + bo_sprd->dmabuf = arg.fd; + } + + /* add bo to hash */ + PrivGem* privGem = calloc (1, sizeof(PrivGem)); + privGem->ref_count = 1; + if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot insert bo to Hash(%d)\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->name); + } + + DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(), + __FUNCTION__, bo_sprd->size, + bo_sprd->gem, bo_sprd->name, + flags, sprd_flags); + + return (void *)bo_sprd; +} + +static void +tbm_sprd_bo_free(tbm_bo bo) +{ + tbm_bo_sprd bo_sprd; + tbm_bufmgr_sprd bufmgr_sprd; + + if (!bo) + return; + + bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo); + SPRD_RETURN_IF_FAIL (bufmgr_sprd!=NULL); + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_IF_FAIL (bo_sprd!=NULL); + + DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n", + getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name); + + if (bo_sprd->pBase) + { + if (munmap(bo_sprd->pBase, bo_sprd->size) == -1) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d\n", + getpid(), __FUNCTION__, __LINE__); + } + } + + /* close dmabuf */ + if (bo_sprd->dmabuf) + { + close (bo_sprd->dmabuf); + bo_sprd->dmabuf = 0; + } + + /* delete bo from hash */ + PrivGem *privGem = NULL; + int ret; + + ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem); + if (ret == 0) + { + privGem->ref_count--; + if (privGem->ref_count == 0) + { + drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name); + free (privGem); + privGem = NULL; + } + } + else + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret); + } + + /* Free gem handle */ + struct drm_gem_close arg = {0, }; + memset (&arg, 0, sizeof(arg)); + arg.handle = bo_sprd->gem; + if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg)) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d\n", + getpid(), __FUNCTION__, __LINE__); + } + + free (bo_sprd); +} + + +static void * +tbm_sprd_bo_import (tbm_bo bo, unsigned int key) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + + tbm_bufmgr_sprd bufmgr_sprd; + tbm_bo_sprd bo_sprd; + + bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0); + + struct drm_gem_open arg = {0, }; + struct drm_sprd_gem_info info = {0, }; + + arg.name = key; + if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg)) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot open gem name=%d\n", + getpid(), __FUNCTION__, __LINE__, key); + return 0; + } + + info.handle = arg.handle; + if (drmCommandWriteRead(bufmgr_sprd->fd, + DRM_SPRD_GEM_GET, + &info, + sizeof(struct drm_sprd_gem_info))) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot get gem info=%d\n", + getpid(), __FUNCTION__, __LINE__, key); + return 0; + } + + bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd)); + if (!bo_sprd) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d fail to allocate the bo private\n", + getpid(), __FUNCTION__, __LINE__); + return 0; + } + + bo_sprd->fd = bufmgr_sprd->fd; + bo_sprd->gem = arg.handle; + bo_sprd->size = arg.size; + bo_sprd->flags_sprd = info.flags; + bo_sprd->name = key; +#ifdef USE_CONTIG_ONLY + bo_sprd->flags_sprd = SPRD_BO_CONTIG; + bo_sprd->flags_tbm |= TBM_BO_SCANOUT; +#else + bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd); +#endif + + + if (!bo_sprd->dmabuf) + { + struct drm_prime_handle arg = {0, }; + + arg.handle = bo_sprd->gem; + if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot dmabuf=%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->gem); + free (bo_sprd); + return 0; + } + bo_sprd->dmabuf = arg.fd; + } + + /* add bo to hash */ + PrivGem *privGem = NULL; + int ret; + + ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem); + if (ret == 0) + { + privGem->ref_count++; + } + else if (ret == 1) + { + privGem = calloc (1, sizeof(PrivGem)); + privGem->ref_count = 1; + if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot insert bo to Hash(%d)\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->name); + } + } + else + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot insert bo to Hash(%d)\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->name); + } + + DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(), + __FUNCTION__, bo_sprd->size, + bo_sprd->gem, bo_sprd->name, + bo_sprd->flags_tbm, bo_sprd->flags_sprd); + + return (void *)bo_sprd; +} + +static unsigned int +tbm_sprd_bo_export (tbm_bo bo) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + + tbm_bo_sprd bo_sprd; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0); + + if (!bo_sprd->name) + { + bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem); + if (!bo_sprd->name) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot get name\n", + getpid(), __FUNCTION__, __LINE__); + return 0; + } + } + + DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(), + __FUNCTION__, bo_sprd->size, + bo_sprd->gem, bo_sprd->name, + bo_sprd->flags_tbm, bo_sprd->flags_sprd); + + return (unsigned int)bo_sprd->name; +} + +static tbm_bo_handle +tbm_sprd_bo_get_handle (tbm_bo bo, int device) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL); + + tbm_bo_handle bo_handle; + tbm_bo_sprd bo_sprd; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL); + + if (!bo_sprd->gem) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot map gem=%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->gem); + return (tbm_bo_handle) NULL; + } + + DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(), + __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]); + + /*Get mapped bo_handle*/ + bo_handle = _sprd_bo_handle (bo_sprd, device); + if (bo_handle.ptr == NULL) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot get handle: gem:%d, device:%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device); + return (tbm_bo_handle) NULL; + } + + return bo_handle; +} + +static tbm_bo_handle +tbm_sprd_bo_map (tbm_bo bo, int device, int opt) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL); + + tbm_bo_handle bo_handle; + tbm_bo_sprd bo_sprd; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL); + + if (!bo_sprd->gem) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot map gem=%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->gem); + return (tbm_bo_handle) NULL; + } + + DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(), + __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]); + + /*Get mapped bo_handle*/ + bo_handle = _sprd_bo_handle (bo_sprd, device); + if (bo_handle.ptr == NULL) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n", + getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt); + return (tbm_bo_handle) NULL; + } + + return bo_handle; +} + +static int +tbm_sprd_bo_unmap (tbm_bo bo) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + + tbm_bo_sprd bo_sprd; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0); + + if (!bo_sprd->gem) + return 0; + + DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(), + __FUNCTION__, bo_sprd->gem, bo_sprd->name); + + return 1; +} + +static int +tbm_sprd_bo_cache_flush (tbm_bo bo, int flags) +{ + tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0); + + /* cache flush is managed by kernel side when using dma-fence. */ + if (bufmgr_sprd->use_dma_fence) + return 1; + + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + + tbm_bo_sprd bo_sprd; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0); + +#ifdef USE_CACHE + if (!_sprd_cache_flush(bo_sprd->fd, bo_sprd, flags)) + return 0; +#endif + + return 1; +} + +static int +tbm_sprd_bo_get_global_key (tbm_bo bo) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + + tbm_bo_sprd bo_sprd; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0); + + if (!bo_sprd->name) + { + if (!bo_sprd->gem) + return 0; + + bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem); + } + + return bo_sprd->name; +} + +static int +tbm_sprd_bo_lock(tbm_bo bo, int device, int opt) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + +#if USE_BACKEND_LOCK + tbm_bufmgr_sprd bufmgr_sprd; + tbm_bo_sprd bo_sprd; + struct dma_buf_fence fence; + int ret=0; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0); + + bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0); + + memset(&fence, 0, sizeof(struct dma_buf_fence)); + + /* Check if the given type is valid or not. */ + if (opt & TBM_OPTION_WRITE) + { + if (device == TBM_DEVICE_CPU) + fence.type = DMA_BUF_ACCESS_WRITE; + else if (device == TBM_DEVICE_3D) + fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA; + else + { + DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__); + return 0; + } + } + else if (opt & TBM_OPTION_READ) + { + if (device == TBM_DEVICE_CPU) + fence.type = DMA_BUF_ACCESS_READ; + else if (device == TBM_DEVICE_3D) + fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA; + else + { + DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__); + return 0; + } + } + else + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__); + return 0; + } + + /* Check if the tbm manager supports dma fence or not. */ + if (!bufmgr_sprd->use_dma_fence) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Not support DMA FENCE(%s)\n", + getpid(), __FUNCTION__, __LINE__, strerror(errno) ); + return 0; + + } + + ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence); + if (ret < 0) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Can not set GET FENCE(%s)\n", + getpid(), __FUNCTION__, __LINE__, strerror(errno) ); + return 0; + } + + pthread_mutex_lock(&bo_sprd->mutex); + int i; + for (i = 0; i < DMA_FENCE_LIST_MAX; i++) + { + if (bo_sprd->dma_fence[i].ctx == 0) + { + bo_sprd->dma_fence[i].type = fence.type; + bo_sprd->dma_fence[i].ctx = fence.ctx; + break; + } + } + if (i == DMA_FENCE_LIST_MAX) + { + //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d fence list is full\n", + getpid(), __FUNCTION__, __LINE__); + } + pthread_mutex_unlock(&bo_sprd->mutex); + + DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(), + __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf); + +#endif + return 1; +} + +static int +tbm_sprd_bo_unlock(tbm_bo bo) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + +#if USE_BACKEND_LOCK + tbm_bo_sprd bo_sprd; + struct dma_buf_fence fence; + int ret=0; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0); + + if (!bo_sprd->dma_fence[0].ctx) + { + DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__); + return 0; + } + + if (!bo_sprd->dma_fence[0].type) + { + DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__); + return 0; + } + + pthread_mutex_lock(&bo_sprd->mutex); + fence.type = bo_sprd->dma_fence[0].type; + fence.ctx = bo_sprd->dma_fence[0].ctx; + int i; + for (i = 1; i < DMA_FENCE_LIST_MAX; i++) + { + bo_sprd->dma_fence[i-1].type = bo_sprd->dma_fence[i].type; + bo_sprd->dma_fence[i-1].ctx = bo_sprd->dma_fence[i].ctx; + } + bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0; + bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0; + pthread_mutex_unlock(&bo_sprd->mutex); + + ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence); + if (ret < 0) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Can not set PUT FENCE(%s)\n", + getpid(), __FUNCTION__, __LINE__, strerror(errno) ); + return 0; + } + + DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(), + __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf); + +#endif + return 1; +} + +static void +tbm_sprd_bufmgr_deinit (void *priv) +{ + SPRD_RETURN_IF_FAIL (priv!=NULL); + + tbm_bufmgr_sprd bufmgr_sprd; + + bufmgr_sprd = (tbm_bufmgr_sprd)priv; + + if (bufmgr_sprd->hashBos) + { + unsigned long key; + void *value; + + while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0) + { + free (value); + drmHashDelete (bufmgr_sprd->hashBos, key); + } + + drmHashDestroy (bufmgr_sprd->hashBos); + bufmgr_sprd->hashBos = NULL; + } + + free (bufmgr_sprd); +} + +int +tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num) +{ + uint32_t* color_formats=NULL; + + color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT); + + if( color_formats == NULL ) + { + return 0; + } + memcpy( color_formats, tbm_sprd_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT ); + + + *formats = color_formats; + *num = TBM_COLOR_FORMAT_COUNT; + + + return 1; +} + + +/** + * @brief get the plane data of the surface. + * @param[in] surface : the surface + * @param[in] width : the width of the surface + * @param[in] height : the height of the surface + * @param[in] format : the format of the surface + * @param[in] plane_idx : the format of the surface + * @param[out] size : the size of the plane + * @param[out] offset : the offset of the plane + * @param[out] pitch : the pitch of the plane + * @param[out] padding : the padding of the plane + * @return 1 if this function succeeds, otherwise 0. + */ +int +tbm_sprd_surface_get_plane_data(tbm_surface_h surface, int width, int height, tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx) +{ + int ret = 1; + int bpp; + int _offset =0; + int _pitch =0; + int _size =0; + int _bo_idx = 0; + + switch(format) + { + /* 16 bpp RGB */ + case TBM_FORMAT_XRGB4444: + case TBM_FORMAT_XBGR4444: + case TBM_FORMAT_RGBX4444: + case TBM_FORMAT_BGRX4444: + case TBM_FORMAT_ARGB4444: + case TBM_FORMAT_ABGR4444: + case TBM_FORMAT_RGBA4444: + case TBM_FORMAT_BGRA4444: + case TBM_FORMAT_XRGB1555: + case TBM_FORMAT_XBGR1555: + case TBM_FORMAT_RGBX5551: + case TBM_FORMAT_BGRX5551: + case TBM_FORMAT_ARGB1555: + case TBM_FORMAT_ABGR1555: + case TBM_FORMAT_RGBA5551: + case TBM_FORMAT_BGRA5551: + case TBM_FORMAT_RGB565: + bpp = 16; + _offset = 0; + _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + break; + /* 24 bpp RGB */ + case TBM_FORMAT_RGB888: + case TBM_FORMAT_BGR888: + bpp = 24; + _offset = 0; + _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + break; + /* 32 bpp RGB */ + case TBM_FORMAT_XRGB8888: + case TBM_FORMAT_XBGR8888: + case TBM_FORMAT_RGBX8888: + case TBM_FORMAT_BGRX8888: + case TBM_FORMAT_ARGB8888: + case TBM_FORMAT_ABGR8888: + case TBM_FORMAT_RGBA8888: + case TBM_FORMAT_BGRA8888: + bpp = 32; + _offset = 0; + _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + break; + + /* packed YCbCr */ + case TBM_FORMAT_YUYV: + case TBM_FORMAT_YVYU: + case TBM_FORMAT_UYVY: + case TBM_FORMAT_VYUY: + case TBM_FORMAT_AYUV: + bpp = 32; + _offset = 0; + _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + break; + + /* + * 2 plane YCbCr + * index 0 = Y plane, [7:0] Y + * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian + * or + * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian + */ + case TBM_FORMAT_NV12: + case TBM_FORMAT_NV21: + bpp = 12; + if(plane_idx == 0) + { + _offset = 0; + _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + } + else if( plane_idx ==1 ) + { + _offset = width*height; + _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + } + break; + + case TBM_FORMAT_NV16: + case TBM_FORMAT_NV61: + bpp = 16; + //if(plane_idx == 0) + { + _offset = 0; + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + if(plane_idx == 0) + break; + } + //else if( plane_idx ==1 ) + { + _offset += _size; + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + } + break; + + /* + * 3 plane YCbCr + * index 0: Y plane, [7:0] Y + * index 1: Cb plane, [7:0] Cb + * index 2: Cr plane, [7:0] Cr + * or + * index 1: Cr plane, [7:0] Cr + * index 2: Cb plane, [7:0] Cb + */ + /* + NATIVE_BUFFER_FORMAT_YV12 + NATIVE_BUFFER_FORMAT_I420 + */ + case TBM_FORMAT_YUV410: + case TBM_FORMAT_YVU410: + bpp = 9; + break; + case TBM_FORMAT_YUV411: + case TBM_FORMAT_YVU411: + case TBM_FORMAT_YUV420: + case TBM_FORMAT_YVU420: + bpp = 12; + //if(plane_idx == 0) + { + _offset = 0; + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + if(plane_idx == 0) + break; + } + //else if( plane_idx == 1 ) + { + _offset += _size; + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + if(plane_idx == 1) + break; + } + //else if (plane_idx == 2 ) + { + _offset += _size; + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + } + break; + case TBM_FORMAT_YUV422: + case TBM_FORMAT_YVU422: + bpp = 16; + //if(plane_idx == 0) + { + _offset = 0; + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + if(plane_idx == 0) + break; + } + //else if( plane_idx == 1 ) + { + _offset += _size; + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + if(plane_idx == 1) + break; + } + //else if (plane_idx == 2 ) + { + _offset += _size; + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + } + break; + case TBM_FORMAT_YUV444: + case TBM_FORMAT_YVU444: + bpp = 24; + //if(plane_idx == 0) + { + _offset = 0; + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + if(plane_idx == 0) + break; + } + //else if( plane_idx == 1 ) + { + _offset += _size; + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + if(plane_idx == 1) + break; + } + //else if (plane_idx == 2 ) + { + _offset += _size; + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _bo_idx = 0; + } + break; + default: + bpp = 0; + break; + } + + *size = _size; + *offset = _offset; + *pitch = _pitch; + *bo_idx = _bo_idx; + + return ret; +} +/** +* @brief get the size of the surface with a format. +* @param[in] surface : the surface +* @param[in] width : the width of the surface +* @param[in] height : the height of the surface +* @param[in] format : the format of the surface +* @return size of the surface if this function succeeds, otherwise 0. +*/ + +int +tbm_sprd_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format) +{ + int ret = 0; + int bpp = 0; + int _pitch =0; + int _size =0; + int align =TBM_SURFACE_ALIGNMENT_PLANE; + + + switch(format) + { + /* 16 bpp RGB */ + case TBM_FORMAT_XRGB4444: + case TBM_FORMAT_XBGR4444: + case TBM_FORMAT_RGBX4444: + case TBM_FORMAT_BGRX4444: + case TBM_FORMAT_ARGB4444: + case TBM_FORMAT_ABGR4444: + case TBM_FORMAT_RGBA4444: + case TBM_FORMAT_BGRA4444: + case TBM_FORMAT_XRGB1555: + case TBM_FORMAT_XBGR1555: + case TBM_FORMAT_RGBX5551: + case TBM_FORMAT_BGRX5551: + case TBM_FORMAT_ARGB1555: + case TBM_FORMAT_ABGR1555: + case TBM_FORMAT_RGBA5551: + case TBM_FORMAT_BGRA5551: + case TBM_FORMAT_RGB565: + bpp = 16; + _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + break; + /* 24 bpp RGB */ + case TBM_FORMAT_RGB888: + case TBM_FORMAT_BGR888: + bpp = 24; + _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + break; + /* 32 bpp RGB */ + case TBM_FORMAT_XRGB8888: + case TBM_FORMAT_XBGR8888: + case TBM_FORMAT_RGBX8888: + case TBM_FORMAT_BGRX8888: + case TBM_FORMAT_ARGB8888: + case TBM_FORMAT_ABGR8888: + case TBM_FORMAT_RGBA8888: + case TBM_FORMAT_BGRA8888: + bpp = 32; + _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + break; + /* packed YCbCr */ + case TBM_FORMAT_YUYV: + case TBM_FORMAT_YVYU: + case TBM_FORMAT_UYVY: + case TBM_FORMAT_VYUY: + case TBM_FORMAT_AYUV: + bpp = 32; + _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + break; + /* + * 2 plane YCbCr + * index 0 = Y plane, [7:0] Y + * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian + * or + * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian + */ + case TBM_FORMAT_NV12: + case TBM_FORMAT_NV21: + bpp = 12; + //plane_idx == 0 + { + _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + } + //plane_idx ==1 + { + _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE); + } + break; + case TBM_FORMAT_NV16: + case TBM_FORMAT_NV61: + bpp = 16; + //plane_idx == 0 + { + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + } + //plane_idx ==1 + { + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + } + + break; + /* + * 3 plane YCbCr + * index 0: Y plane, [7:0] Y + * index 1: Cb plane, [7:0] Cb + * index 2: Cr plane, [7:0] Cr + * or + * index 1: Cr plane, [7:0] Cr + * index 2: Cb plane, [7:0] Cb + */ + case TBM_FORMAT_YUV410: + case TBM_FORMAT_YVU410: + bpp = 9; + align = TBM_SURFACE_ALIGNMENT_PITCH_YUV; + break; + case TBM_FORMAT_YUV411: + case TBM_FORMAT_YVU411: + case TBM_FORMAT_YUV420: + case TBM_FORMAT_YVU420: + bpp = 12; + //plane_idx == 0 + { + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + } + //plane_idx == 1 + { + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE); + } + //plane_idx == 2 + { + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE); + } + + break; + case TBM_FORMAT_YUV422: + case TBM_FORMAT_YVU422: + bpp = 16; + //plane_idx == 0 + { + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + } + //plane_idx == 1 + { + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + } + //plane_idx == 2 + { + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + } + break; + case TBM_FORMAT_YUV444: + case TBM_FORMAT_YVU444: + bpp = 24; + align = TBM_SURFACE_ALIGNMENT_PITCH_YUV; + break; + + default: + bpp = 0; + break; + } + + if(_size > 0) + ret = _size; + else + ret = SIZE_ALIGN( (width * height * bpp) >> 3, align); + + return ret; + +} + +int +tbm_sprd_surface_get_num_bos(tbm_format format) +{ + int num = 0; + + switch(format) + { + /* 16 bpp RGB */ + case TBM_FORMAT_XRGB4444: + case TBM_FORMAT_XBGR4444: + case TBM_FORMAT_RGBX4444: + case TBM_FORMAT_BGRX4444: + case TBM_FORMAT_ARGB4444: + case TBM_FORMAT_ABGR4444: + case TBM_FORMAT_RGBA4444: + case TBM_FORMAT_BGRA4444: + case TBM_FORMAT_XRGB1555: + case TBM_FORMAT_XBGR1555: + case TBM_FORMAT_RGBX5551: + case TBM_FORMAT_BGRX5551: + case TBM_FORMAT_ARGB1555: + case TBM_FORMAT_ABGR1555: + case TBM_FORMAT_RGBA5551: + case TBM_FORMAT_BGRA5551: + case TBM_FORMAT_RGB565: + /* 24 bpp RGB */ + case TBM_FORMAT_RGB888: + case TBM_FORMAT_BGR888: + /* 32 bpp RGB */ + case TBM_FORMAT_XRGB8888: + case TBM_FORMAT_XBGR8888: + case TBM_FORMAT_RGBX8888: + case TBM_FORMAT_BGRX8888: + case TBM_FORMAT_ARGB8888: + case TBM_FORMAT_ABGR8888: + case TBM_FORMAT_RGBA8888: + case TBM_FORMAT_BGRA8888: + /* packed YCbCr */ + case TBM_FORMAT_YUYV: + case TBM_FORMAT_YVYU: + case TBM_FORMAT_UYVY: + case TBM_FORMAT_VYUY: + case TBM_FORMAT_AYUV: + /* + * 2 plane YCbCr + * index 0 = Y plane, [7:0] Y + * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian + * or + * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian + */ + case TBM_FORMAT_NV12: + case TBM_FORMAT_NV21: + case TBM_FORMAT_NV16: + case TBM_FORMAT_NV61: + /* + * 3 plane YCbCr + * index 0: Y plane, [7:0] Y + * index 1: Cb plane, [7:0] Cb + * index 2: Cr plane, [7:0] Cr + * or + * index 1: Cr plane, [7:0] Cr + * index 2: Cb plane, [7:0] Cb + */ + case TBM_FORMAT_YUV410: + case TBM_FORMAT_YVU410: + case TBM_FORMAT_YUV411: + case TBM_FORMAT_YVU411: + case TBM_FORMAT_YUV420: + case TBM_FORMAT_YVU420: + case TBM_FORMAT_YUV422: + case TBM_FORMAT_YVU422: + case TBM_FORMAT_YUV444: + case TBM_FORMAT_YVU444: + num = 1; + break; + + default: + num = 0; + break; + } + + return num; +} + +MODULEINITPPROTO (init_tbm_bufmgr_priv); + +static TBMModuleVersionInfo SprdVersRec = +{ + "sprd", + "Samsung", + TBM_ABI_VERSION, +}; + +TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv}; + +int +init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd) +{ + tbm_bufmgr_sprd bufmgr_sprd; + tbm_bufmgr_backend bufmgr_backend; + + if (!bufmgr) + return 0; + + bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd)); + if (!bufmgr_sprd) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid()); + return 0; + } + + bufmgr_sprd->fd = fd; + if (bufmgr_sprd->fd < 0) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid()); + free (bufmgr_sprd); + return 0; + } + + //Create Hash Table + bufmgr_sprd->hashBos = drmHashCreate (); + + //Check if the tbm manager supports dma fence or not. + int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY); + int length; + char buf[1]; + if (fp != -1) + { + length = read(fp, buf, 1); + + if (length == 1 && buf[0] == '1') + bufmgr_sprd->use_dma_fence = 1; + + close(fp); + } + + bufmgr_backend = tbm_backend_alloc(); + if (!bufmgr_backend) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid()); + free (bufmgr_sprd); + return 0; + } + + bufmgr_backend->priv = (void *)bufmgr_sprd; + bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit, + bufmgr_backend->bo_size = tbm_sprd_bo_size, + bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc, + bufmgr_backend->bo_free = tbm_sprd_bo_free, + bufmgr_backend->bo_import = tbm_sprd_bo_import, + bufmgr_backend->bo_export = tbm_sprd_bo_export, + bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle, + bufmgr_backend->bo_map = tbm_sprd_bo_map, + bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap, + bufmgr_backend->bo_cache_flush = tbm_sprd_bo_cache_flush, + bufmgr_backend->bo_get_global_key = tbm_sprd_bo_get_global_key; + bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data; + bufmgr_backend->surface_get_size = tbm_sprd_surface_get_size; + bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format; + bufmgr_backend->surface_get_num_bos = tbm_sprd_surface_get_num_bos; + + if (bufmgr_sprd->use_dma_fence) + { + bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND); + bufmgr_backend->bo_lock = NULL; + bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock; + bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock; + } + else + { + bufmgr_backend->flags = 0; + bufmgr_backend->bo_lock = NULL; + bufmgr_backend->bo_unlock = NULL; + } + + if (!tbm_backend_init (bufmgr, bufmgr_backend)) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid()); + tbm_backend_free (bufmgr_backend); + free (bufmgr_sprd); + return 0; + } + +#ifdef DEBUG + { + char* env; + env = getenv ("TBM_SPRD_DEBUG"); + if (env) + { + bDebug = atoi (env); + TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env); + } + else + { + bDebug = 0; + } + } +#endif + + DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(), + __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!"); + + DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(), + __FUNCTION__, bufmgr_sprd->fd); + + return 1; +} + + -- 2.7.4 From ea2beb3eb3a188a00296d0a52b5484d1d4062a71 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Mon, 23 Nov 2015 16:52:03 +0900 Subject: [PATCH 03/12] Align RGB format with 128 byte Change-Id: I478a8d99e97517af148cb88a53aa9e4580b08bab --- src/tbm_bufmgr_sprd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tbm_bufmgr_sprd.c b/src/tbm_bufmgr_sprd.c index 3f28f0c..73621c7 100755 --- a/src/tbm_bufmgr_sprd.c +++ b/src/tbm_bufmgr_sprd.c @@ -111,7 +111,7 @@ char* target_name() #define SIZE_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1)) #define TBM_SURFACE_ALIGNMENT_PLANE (64) -#define TBM_SURFACE_ALIGNMENT_PITCH_RGB (64) +#define TBM_SURFACE_ALIGNMENT_PITCH_RGB (128) #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16) -- 2.7.4 From 2d6b0fc940c6e531855d11323685c3cd571cb400 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 23 Nov 2015 16:34:40 +0900 Subject: [PATCH 04/12] remove install dependency libdrm2 and libtbm Change-Id: I5756e8d60a685ee98ad53091b9841b56f976b83a --- packaging/libtbm-sprd.spec | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packaging/libtbm-sprd.spec b/packaging/libtbm-sprd.spec index a13584e..f0966c1 100644 --- a/packaging/libtbm-sprd.spec +++ b/packaging/libtbm-sprd.spec @@ -11,15 +11,11 @@ BuildRequires: pkgconfig(pthread-stubs) BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(dlog) -BuildRequires: linux-glibc-devel BuildRequires: kernel-headers-tizen-dev -#!BuildIgnore: kernel-headers BuildConflicts: linux-glibc-devel -Requires: libtbm -Requires: libdrm2 %description -descriptionion: ${summary} +descriptionion:Tizen Buffer manager backend module for spreadtrum %prep %setup -q -- 2.7.4 From cb90a47cdd8fa668617f7f24f37063a9ed559cd9 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Tue, 24 Nov 2015 11:46:24 +0900 Subject: [PATCH 05/12] if profile isn't mobile, ExcludeArch armv7l aarch64 Change-Id: I06a9c7fcdb1e28019cdbbd473ba4f546a0d6d6b8 --- packaging/libtbm-sprd.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packaging/libtbm-sprd.spec b/packaging/libtbm-sprd.spec index f0966c1..7900dd9 100644 --- a/packaging/libtbm-sprd.spec +++ b/packaging/libtbm-sprd.spec @@ -5,6 +5,9 @@ License: MIT Summary: Tizen Buffer Manager - sprd backend Group: System/Libraries ExcludeArch: i586 +%if ("%{?profile}" != "mobile") +ExcludeArch: armv7l aarch64 +%endif Source0: %{name}-%{version}.tar.gz BuildRequires: pkgconfig(pthread-stubs) -- 2.7.4 From c93405441bec66b8429c7afedfb4503730dc3e4e Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Tue, 24 Nov 2015 13:31:07 +0900 Subject: [PATCH 06/12] Build only tm1 Change-Id: I6e6858f63e1cb8377c2d6fb38d632726f0e122a0 --- packaging/libtbm-sprd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtbm-sprd.spec b/packaging/libtbm-sprd.spec index 7900dd9..34c0765 100644 --- a/packaging/libtbm-sprd.spec +++ b/packaging/libtbm-sprd.spec @@ -5,7 +5,7 @@ License: MIT Summary: Tizen Buffer Manager - sprd backend Group: System/Libraries ExcludeArch: i586 -%if ("%{?profile}" != "mobile") +%if ("%{?tizen_target_name}" != "TM1") ExcludeArch: armv7l aarch64 %endif Source0: %{name}-%{version}.tar.gz -- 2.7.4 From 6e0f7d6876795b3eaeda2a0e24c36170e2e8bdd9 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Tue, 24 Nov 2015 13:45:37 +0900 Subject: [PATCH 07/12] ExcludeArch x86_64 Change-Id: I3c77f0dfd8cc604a89755cb95900d4a3549ac2fa --- packaging/libtbm-sprd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtbm-sprd.spec b/packaging/libtbm-sprd.spec index 34c0765..0af6539 100644 --- a/packaging/libtbm-sprd.spec +++ b/packaging/libtbm-sprd.spec @@ -4,7 +4,7 @@ Release: 0 License: MIT Summary: Tizen Buffer Manager - sprd backend Group: System/Libraries -ExcludeArch: i586 +ExcludeArch: i586 x86_64 %if ("%{?tizen_target_name}" != "TM1") ExcludeArch: armv7l aarch64 %endif -- 2.7.4 From 7625c47a079b856ff32c8a689f64061c3a7ed406 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Tue, 24 Nov 2015 15:06:30 +0900 Subject: [PATCH 08/12] if target_name isn't TM1, ExclusiveArch Change-Id: Ia3baa532230cf668c2c154d13e7b8a36e436fe7b --- packaging/libtbm-sprd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtbm-sprd.spec b/packaging/libtbm-sprd.spec index 0af6539..eb80ab8 100644 --- a/packaging/libtbm-sprd.spec +++ b/packaging/libtbm-sprd.spec @@ -6,7 +6,7 @@ Summary: Tizen Buffer Manager - sprd backend Group: System/Libraries ExcludeArch: i586 x86_64 %if ("%{?tizen_target_name}" != "TM1") -ExcludeArch: armv7l aarch64 +ExclusiveArch: %endif Source0: %{name}-%{version}.tar.gz -- 2.7.4 From b1d72b21253bdd02b0b91ecf6e08098c4f43e940 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 7 Dec 2015 20:10:28 +0900 Subject: [PATCH 09/12] implement the missing backend functions tbm_sprd_bo_import_fd tbm_sprd_bo_export_fd tbm_sprd_fd_to_handle tbm_sprd_bo_get_flags Change-Id: I0a2afd0f281f46901a633f232f7d8b2cb63bf79b --- src/tbm_bufmgr_sprd.c | 298 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 257 insertions(+), 41 deletions(-) diff --git a/src/tbm_bufmgr_sprd.c b/src/tbm_bufmgr_sprd.c index 73621c7..0610ada 100755 --- a/src/tbm_bufmgr_sprd.c +++ b/src/tbm_bufmgr_sprd.c @@ -60,7 +60,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef DEBUG -#define LOG_TAG "TBM_BACKEND" +#define LOG_TAG "TBM_BACKEND" #include static int bDebug=0; @@ -68,7 +68,7 @@ char* target_name() { FILE *f; char *slash; - static int initialized = 0; + static int initialized = 0; static char app_name[128]; if ( initialized ) @@ -101,8 +101,8 @@ char* target_name() return app_name; } -#define TBM_SPRD_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args) -#define DBG(fmt, args...) if(bDebug&01) LOGE("[%s]" fmt, target_name(), ##args) +#define TBM_SPRD_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args) +#define DBG(fmt, args...) if(bDebug&01) LOGE("[%s]" fmt, target_name(), ##args) #else #define TBM_SPRD_LOG(...) #define DBG(...) @@ -130,29 +130,29 @@ char* target_name() } struct dma_buf_info { - unsigned long size; - unsigned int fence_supported; - unsigned int padding; + unsigned long size; + unsigned int fence_supported; + unsigned int padding; }; -#define DMA_BUF_ACCESS_READ 0x1 -#define DMA_BUF_ACCESS_WRITE 0x2 -#define DMA_BUF_ACCESS_DMA 0x4 -#define DMA_BUF_ACCESS_MAX 0x8 +#define DMA_BUF_ACCESS_READ 0x1 +#define DMA_BUF_ACCESS_WRITE 0x2 +#define DMA_BUF_ACCESS_DMA 0x4 +#define DMA_BUF_ACCESS_MAX 0x8 -#define DMA_FENCE_LIST_MAX 5 +#define DMA_FENCE_LIST_MAX 5 struct dma_buf_fence { - unsigned long ctx; - unsigned int type; + unsigned long ctx; + unsigned int type; }; -#define DMABUF_IOCTL_BASE 'F' -#define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type) +#define DMABUF_IOCTL_BASE 'F' +#define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type) -#define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info) -#define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence) -#define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence) +#define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info) +#define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence) +#define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence) typedef struct _tbm_bufmgr_sprd *tbm_bufmgr_sprd; typedef struct _tbm_bo_sprd *tbm_bo_sprd; @@ -712,6 +712,122 @@ tbm_sprd_bo_import (tbm_bo bo, unsigned int key) return (void *)bo_sprd; } +static void * +tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0); + + tbm_bufmgr_sprd bufmgr_sprd; + tbm_bo_sprd bo_sprd; + + bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0); + + unsigned int gem = 0; + unsigned int real_size = -1; + struct drm_sprd_gem_info info = {0, }; + + //getting handle from fd + struct drm_prime_handle arg = {0, }; + + arg.fd = key; + arg.flags = 0; + if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) + { + TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n", + bo, arg.fd, strerror(errno)); + return NULL; + } + gem = arg.handle; + + /* Determine size of bo. The fd-to-handle ioctl really should + * return the size, but it doesn't. If we have kernel 3.12 or + * later, we can lseek on the prime fd to get the size. Older + * kernels will just fail, in which case we fall back to the + * provided (estimated or guess size). */ + real_size = lseek(key, 0, SEEK_END); + + info.handle = gem; + if (drmCommandWriteRead(bufmgr_sprd->fd, + DRM_SPRD_GEM_GET, + &info, + sizeof(struct drm_sprd_gem_info))) + { + TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n", + bo, gem, key, strerror(errno)); + return 0; + } + + if (real_size == -1) + real_size = info.size; + + bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd)); + if (!bo_sprd) + { + TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo); + return 0; + } + + bo_sprd->fd = bufmgr_sprd->fd; + bo_sprd->gem = gem; + bo_sprd->size = real_size; + bo_sprd->flags_sprd = info.flags; + bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd); + + bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem); + if (!bo_sprd->name) + { + TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n", + bo, gem, key, strerror(errno)); + free (bo_sprd); + return 0; + } + + /* add bo to hash */ + PrivGem *privGem = NULL; + int ret; + + ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem); + if (ret == 0) + { + privGem->ref_count++; + } + else if (ret == 1) + { + privGem = calloc (1, sizeof(PrivGem)); + if (!privGem) + { + TBM_SPRD_LOG ("[libtbm-sprd:%d] " + "error %s:%d Fail to calloc privGem\n", + getpid(), __FUNCTION__, __LINE__); + free (bo_sprd); + return 0; + } + + privGem->ref_count = 1; + if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0) + { + TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n", + bo, bo_sprd->name, gem, key); + } + } + else + { + TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n", + bo, bo_sprd->name, gem, key); + } + + DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(), + bo, + bo_sprd->gem, bo_sprd->name, + bo_sprd->dmabuf, + key, + bo_sprd->flags_tbm, bo_sprd->flags_sprd, + bo_sprd->size); + + return (void *)bo_sprd; +} + static unsigned int tbm_sprd_bo_export (tbm_bo bo) { @@ -742,6 +858,40 @@ tbm_sprd_bo_export (tbm_bo bo) return (unsigned int)bo_sprd->name; } +tbm_fd +tbm_sprd_bo_export_fd (tbm_bo bo) +{ + SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, -1); + + tbm_bo_sprd bo_sprd; + int ret; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, -1); + + struct drm_prime_handle arg = {0, }; + + arg.handle = bo_sprd->gem; + ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg); + if (ret) + { + TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n", + bo, bo_sprd->gem, strerror(errno)); + return (tbm_fd) ret; + } + + DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(), + bo, + bo_sprd->gem, bo_sprd->name, + bo_sprd->dmabuf, + arg.fd, + bo_sprd->flags_tbm, bo_sprd->flags_sprd, + bo_sprd->size); + + return (tbm_fd)arg.fd; +} + + static tbm_bo_handle tbm_sprd_bo_get_handle (tbm_bo bo, int device) { @@ -1191,20 +1341,20 @@ tbm_sprd_surface_get_plane_data(tbm_surface_h surface, int width, int height, tb case TBM_FORMAT_NV16: case TBM_FORMAT_NV61: - bpp = 16; + bpp = 16; //if(plane_idx == 0) { _offset = 0; - _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); _bo_idx = 0; - if(plane_idx == 0) - break; + if(plane_idx == 0) + break; } //else if( plane_idx ==1 ) { _offset += _size; - _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); _bo_idx = 0; } @@ -1449,26 +1599,26 @@ tbm_sprd_surface_get_size(tbm_surface_h surface, int width, int height, tbm_form case TBM_FORMAT_YUV410: case TBM_FORMAT_YVU410: bpp = 9; - align = TBM_SURFACE_ALIGNMENT_PITCH_YUV; + align = TBM_SURFACE_ALIGNMENT_PITCH_YUV; break; case TBM_FORMAT_YUV411: case TBM_FORMAT_YVU411: case TBM_FORMAT_YUV420: case TBM_FORMAT_YVU420: bpp = 12; - //plane_idx == 0 + //plane_idx == 0 { - _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); } //plane_idx == 1 { - _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); - _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE); + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE); } //plane_idx == 2 { - _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE); } @@ -1476,26 +1626,26 @@ tbm_sprd_surface_get_size(tbm_surface_h surface, int width, int height, tbm_form case TBM_FORMAT_YUV422: case TBM_FORMAT_YVU422: bpp = 16; - //plane_idx == 0 + //plane_idx == 0 { - _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); + _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV); _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); } //plane_idx == 1 { - _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); - _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); } //plane_idx == 2 { - _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); + _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2); _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE); } break; case TBM_FORMAT_YUV444: case TBM_FORMAT_YVU444: bpp = 24; - align = TBM_SURFACE_ALIGNMENT_PITCH_YUV; + align = TBM_SURFACE_ALIGNMENT_PITCH_YUV; break; default: @@ -1503,10 +1653,10 @@ tbm_sprd_surface_get_size(tbm_surface_h surface, int width, int height, tbm_form break; } - if(_size > 0) - ret = _size; - else - ret = SIZE_ALIGN( (width * height * bpp) >> 3, align); + if(_size > 0) + ret = _size; + else + ret = SIZE_ALIGN( (width * height * bpp) >> 3, align); return ret; @@ -1515,7 +1665,7 @@ tbm_sprd_surface_get_size(tbm_surface_h surface, int width, int height, tbm_form int tbm_sprd_surface_get_num_bos(tbm_format format) { - int num = 0; + int num = 0; switch(format) { @@ -1596,6 +1746,68 @@ tbm_sprd_surface_get_num_bos(tbm_format format) return num; } +tbm_bo_handle +tbm_sprd_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device) +{ + SPRD_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL); + SPRD_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL); + + tbm_bo_handle bo_handle; + memset (&bo_handle, 0x0, sizeof (uint64_t)); + + tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_priv_from_bufmgr(bufmgr); + + switch(device) + { + case TBM_DEVICE_DEFAULT: + case TBM_DEVICE_2D: + { + //getting handle from fd + struct drm_prime_handle arg = {0, }; + + arg.fd = fd; + arg.flags = 0; + if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) + { + TBM_SPRD_LOG ("error Cannot get gem handle from fd:%d (%s)\n", + arg.fd, strerror(errno)); + return (tbm_bo_handle) NULL; + } + + bo_handle.u32 = (uint32_t)arg.handle;; + break; + } + case TBM_DEVICE_CPU: + TBM_SPRD_LOG ("Not supported device:%d\n", device); + bo_handle.ptr = (void *) NULL; + break; + case TBM_DEVICE_3D: + case TBM_DEVICE_MM: + bo_handle.u32 = (uint32_t)fd; + break; + default: + TBM_SPRD_LOG ("error Not supported device:%d\n", device); + bo_handle.ptr = (void *) NULL; + break; + } + + return bo_handle; +} + +int +tbm_sprd_bo_get_flags (tbm_bo bo) +{ + SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0); + + tbm_bo_sprd bo_sprd; + + bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo); + SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0); + + return bo_sprd->flags_tbm; +} + + MODULEINITPPROTO (init_tbm_bufmgr_priv); static TBMModuleVersionInfo SprdVersRec = @@ -1662,7 +1874,9 @@ init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd) bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc, bufmgr_backend->bo_free = tbm_sprd_bo_free, bufmgr_backend->bo_import = tbm_sprd_bo_import, + bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd, bufmgr_backend->bo_export = tbm_sprd_bo_export, + bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd, bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle, bufmgr_backend->bo_map = tbm_sprd_bo_map, bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap, @@ -1671,7 +1885,9 @@ init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd) bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data; bufmgr_backend->surface_get_size = tbm_sprd_surface_get_size; bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format; + bufmgr_backend->fd_to_handle = tbm_sprd_fd_to_handle; bufmgr_backend->surface_get_num_bos = tbm_sprd_surface_get_num_bos; + bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags; if (bufmgr_sprd->use_dma_fence) { -- 2.7.4 From 706031b30579a779b9cc59a8a6008677c4701a3b Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Sun, 10 Jan 2016 17:52:13 +0900 Subject: [PATCH 10/12] If drm fd is negative value, get fd with wayland protocol Change-Id: I71dfe3aab0f4e2b502f1a96613aa48a0baefecea --- configure.ac | 8 +- packaging/libtbm-sprd.spec | 1 + src/Makefile.am | 3 +- src/tbm_bufmgr_sprd.c | 25 +++- src/tbm_wayland.c | 279 +++++++++++++++++++++++++++++++++++++++++++++ src/tbm_wayland.h | 38 ++++++ 6 files changed, 349 insertions(+), 5 deletions(-) create mode 100644 src/tbm_wayland.c create mode 100644 src/tbm_wayland.h diff --git a/configure.ac b/configure.ac index 149ebc1..922d3e3 100755 --- a/configure.ac +++ b/configure.ac @@ -39,9 +39,13 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) PKG_CHECK_MODULES(LIBDRM, libdrm) PKG_CHECK_MODULES(LIBTBM, libtbm) PKG_CHECK_MODULES(LIBDLOG, dlog) +PKG_CHECK_MODULES(WAYLAND_CLIENT, wayland-client wayland-server) -LIBTBM_SPRD_CFLAGS="$LIBDRM_CFLAGS $LIBTBM_CFLAGS $LIBDLOG_CFLAGS " -LIBTBM_SPRD_LIBS="$LIBDRM_LIBS $LIBTBM_LIBS $LIBDLOG_LIBS " +WYLAND_PREFIX=`$PKG_CONFIG --variable=prefix wayland-client wayland-server` +AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner],, [${WAYLAND_PREFIX}/bin$PATH_SEPARATOR$PATH]) + +LIBTBM_SPRD_CFLAGS="$LIBDRM_CFLAGS $LIBTBM_CFLAGS $LIBDLOG_CFLAGS $WAYLAND_CLIENT_CLFAGS " +LIBTBM_SPRD_LIBS="$LIBDRM_LIBS $LIBTBM_LIBS $LIBDLOG_LIBS $WAYLAND_CLIENT_LIBS " AC_SUBST(LIBTBM_SPRD_CFLAGS) AC_SUBST(LIBTBM_SPRD_LIBS) diff --git a/packaging/libtbm-sprd.spec b/packaging/libtbm-sprd.spec index eb80ab8..1a1b0a2 100644 --- a/packaging/libtbm-sprd.spec +++ b/packaging/libtbm-sprd.spec @@ -14,6 +14,7 @@ BuildRequires: pkgconfig(pthread-stubs) BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(wayland-client) BuildRequires: kernel-headers-tizen-dev BuildConflicts: linux-glibc-devel diff --git a/src/Makefile.am b/src/Makefile.am index ebe5b35..7296dba 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,4 +9,5 @@ libtbm_sprd_ladir = /${bufmgr_dir} libtbm_sprd_la_LIBADD = @LIBTBM_SPRD_LIBS@ libtbm_sprd_la_SOURCES = \ - tbm_bufmgr_sprd.c + tbm_bufmgr_sprd.c \ + tbm_wayland.c diff --git a/src/tbm_bufmgr_sprd.c b/src/tbm_bufmgr_sprd.c index 0610ada..670b58c 100755 --- a/src/tbm_bufmgr_sprd.c +++ b/src/tbm_bufmgr_sprd.c @@ -49,6 +49,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include "tbm_wayland.h" #define DEBUG @@ -195,6 +196,8 @@ struct _tbm_bufmgr_sprd void* hashBos; int use_dma_fence; + + int fd_owner; }; char *STR_DEVICE[]= @@ -1201,6 +1204,9 @@ tbm_sprd_bufmgr_deinit (void *priv) bufmgr_sprd->hashBos = NULL; } + if (bufmgr_sprd->fd_owner) + close (bufmgr_sprd->fd_owner); + free (bufmgr_sprd); } @@ -1835,8 +1841,15 @@ init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd) return 0; } - bufmgr_sprd->fd = fd; - if (bufmgr_sprd->fd < 0) + if (fd < 0) + { + bufmgr_sprd->fd = tbm_bufmgr_get_drm_fd_wayland(); + bufmgr_sprd->fd_owner = 1; + } + else + bufmgr_sprd->fd = fd; + + if (bufmgr_sprd->fd < 0) { TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid()); free (bufmgr_sprd); @@ -1864,6 +1877,10 @@ init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd) if (!bufmgr_backend) { TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid()); + + if (bufmgr_sprd->fd_owner) + close(bufmgr_sprd->fd); + free (bufmgr_sprd); return 0; } @@ -1907,6 +1924,10 @@ init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd) { TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid()); tbm_backend_free (bufmgr_backend); + + if (bufmgr_sprd->fd_owner) + close(bufmgr_sprd->fd); + free (bufmgr_sprd); return 0; } diff --git a/src/tbm_wayland.c b/src/tbm_wayland.c new file mode 100644 index 0000000..57286ff --- /dev/null +++ b/src/tbm_wayland.c @@ -0,0 +1,279 @@ +/************************************************************************** + +libtbm + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee +Boram Park , Changyeon 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 "wayland-util.h" + +extern const struct wl_interface wl_buffer_interface; + +static const struct wl_interface *types[] = { + NULL, + NULL, + NULL, + &wl_buffer_interface, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &wl_buffer_interface, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +static const struct wl_message wl_tbm_requests[] = { + {"create_buffer", "niiuiiiiiiiiiiuiuuu", types + 3}, + {"create_buffer_with_fd", "niiuiiiiiiiiiiuihhh", types + 22}, + {"get_authentication_info", "", types + 0}, +}; + +static const struct wl_message wl_tbm_events[] = { + {"authentication_info", "suh", types + 0}, +}; + +WL_EXPORT const struct wl_interface wl_tbm_interface = { + "wl_tbm", 1, + 3, wl_tbm_requests, + 1, wl_tbm_events, +}; + +struct wl_buffer; +struct wl_tbm; + +extern const struct wl_interface wl_tbm_interface; + +#ifndef WL_TBM_ERROR_ENUM +#define WL_TBM_ERROR_ENUM +enum wl_tbm_error { + WL_TBM_ERROR_AUTHENTICATE_FAIL = 0, + WL_TBM_ERROR_INVALID_FORMAT = 1, + WL_TBM_ERROR_INVALID_NAME = 2, +}; +#endif /* WL_TBM_ERROR_ENUM */ + +struct wl_tbm_listener { + /** + * authentication_info - (none) + * @device_name: (none) + * @capabilities: (none) + * @auth_fd: (none) + */ + void (*authentication_info) (void *data, struct wl_tbm * wl_tbm, const char *device_name, uint32_t capabilities, int32_t auth_fd); +}; + +static inline int wl_tbm_add_listener(struct wl_tbm *wl_tbm, const struct wl_tbm_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *)wl_tbm, (void (**)(void))listener, data); +} + +#define WL_TBM_CREATE_BUFFER 0 +#define WL_TBM_CREATE_BUFFER_WITH_FD 1 +#define WL_TBM_GET_AUTHENTICATION_INFO 2 + +static inline void wl_tbm_set_user_data(struct wl_tbm *wl_tbm, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *)wl_tbm, user_data); +} + +static inline void *wl_tbm_get_user_data(struct wl_tbm *wl_tbm) +{ + return wl_proxy_get_user_data((struct wl_proxy *)wl_tbm); +} + +static inline void wl_tbm_destroy(struct wl_tbm *wl_tbm) +{ + wl_proxy_destroy((struct wl_proxy *)wl_tbm); +} + +static inline void wl_tbm_get_authentication_info(struct wl_tbm *wl_tbm) +{ + wl_proxy_marshal((struct wl_proxy *)wl_tbm, WL_TBM_GET_AUTHENTICATION_INFO); +} + +struct wl_tbm_info { + struct wl_display *dpy; + struct wl_event_queue *wl_queue; + struct wl_tbm *wl_tbm; + + uint32_t capabilities; + char *device; + int32_t fd; +}; + +static void handle_tbm_authentication_info(void *data, struct wl_tbm *wl_tbm, const char *device_name, uint32_t capabilities, int32_t auth_fd) +{ + struct wl_tbm_info *info = (struct wl_tbm_info *)data; + + info->fd = auth_fd; + info->capabilities = capabilities; + if (device_name) + info->device = strndup(device_name, 256); +} + +static const struct wl_tbm_listener wl_tbm_client_listener = { + handle_tbm_authentication_info +}; + +static void wl_client_registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) +{ + struct wl_tbm_info *info = (struct wl_tbm_info *)data; + + if (!strcmp(interface, "wl_tbm")) { + info->wl_tbm = wl_registry_bind(registry, name, &wl_tbm_interface, version); + if (!info->wl_tbm) { + printf("Failed to bind wl_tbm\n"); + return; + } + + wl_tbm_add_listener(info->wl_tbm, &wl_tbm_client_listener, info); + wl_proxy_set_queue((struct wl_proxy *)info->wl_tbm, info->wl_queue); + } +} + +static int tbm_util_get_drm_fd(void *dpy, int *fd) +{ + struct wl_display *disp = NULL; + struct wl_registry *wl_registry; + struct wl_tbm_info info = { + .dpy = NULL, + .wl_queue = NULL, + .wl_tbm = NULL, + .capabilities = 0, + .device = NULL, + .fd = 0, + }; + + static const struct wl_registry_listener registry_listener = { + wl_client_registry_handle_global, + NULL + }; + + if (!fd) + return -1; + + if (!dpy) { + disp = wl_display_connect(NULL); + if (!disp) { + printf("Failed to create a new display connection\n"); + return -1; + } + dpy = disp; + } + + info.dpy = dpy; + info.wl_queue = wl_display_create_queue(dpy); + if (!info.wl_queue) { + printf("Failed to create a WL Queue\n"); + if (disp == dpy) + wl_display_disconnect(disp); + + return -1; + } + + wl_registry = wl_display_get_registry(dpy); + if (!wl_registry) { + printf("Failed to get registry\n"); + wl_event_queue_destroy(info.wl_queue); + if (disp == dpy) + wl_display_disconnect(disp); + + return -1; + } + wl_proxy_set_queue((struct wl_proxy *)wl_registry, info.wl_queue); + wl_registry_add_listener(wl_registry, ®istry_listener, &info); + wl_display_roundtrip_queue(dpy, info.wl_queue); + + wl_tbm_get_authentication_info(info.wl_tbm); + wl_display_roundtrip_queue(dpy, info.wl_queue); + + *fd = info.fd; + + wl_event_queue_destroy(info.wl_queue); + wl_registry_destroy(wl_registry); + + free(info.device); + wl_tbm_set_user_data(info.wl_tbm, NULL); + wl_tbm_destroy(info.wl_tbm); + + if (disp == dpy) + wl_display_disconnect(disp); + + return *fd >= 0 ? 0 : -1; +} + +int tbm_bufmgr_get_drm_fd_wayland() +{ + int fd = -1; + + if (tbm_util_get_drm_fd(NULL, &fd)) + printf("Failed to get drm_fd\n"); + + return fd; +} diff --git a/src/tbm_wayland.h b/src/tbm_wayland.h new file mode 100644 index 0000000..32ba395 --- /dev/null +++ b/src/tbm_wayland.h @@ -0,0 +1,38 @@ +/************************************************************************** + +libtbm + +Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: SooChan Lim , Sangjin Lee +Boram Park , Changyeon 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_UTIL_H_ +#define _TBM_UTIL_H_ + +int tbm_bufmgr_get_drm_fd_wayland(); + +#endif /* _TBM_UTIL_H_ */ + -- 2.7.4 From 791c0e2daf69cf0dfd132b021f08252f0ad9324c Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Fri, 12 Feb 2016 17:22:15 +0200 Subject: [PATCH 11/12] fix a leak of file descriptors Change-Id: I4b1c4fe3119d720c13e158e5aa9cc3d79d760124 Signed-off-by: Roman Marchenko --- src/tbm_bufmgr_sprd.c | 1 + 1 file changed, 1 insertion(+) mode change 100755 => 100644 src/tbm_bufmgr_sprd.c diff --git a/src/tbm_bufmgr_sprd.c b/src/tbm_bufmgr_sprd.c old mode 100755 new mode 100644 index 670b58c..0b06f8b --- a/src/tbm_bufmgr_sprd.c +++ b/src/tbm_bufmgr_sprd.c @@ -773,6 +773,7 @@ tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key) bo_sprd->fd = bufmgr_sprd->fd; bo_sprd->gem = gem; + bo_sprd->dmabuf = key; bo_sprd->size = real_size; bo_sprd->flags_sprd = info.flags; bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd); -- 2.7.4 From f67d4e0f6b894cfb454ed98af8c2b85723cd629c Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Tue, 16 Feb 2016 01:51:56 -0800 Subject: [PATCH 12/12] Revert "fix a leak of file descriptors" This reverts commit 791c0e2daf69cf0dfd132b021f08252f0ad9324c. The user of libtbm have to control state of "fd" by himself. So libtbm shouldn't save fd which received by tbm_bo_import_fd() Change-Id: Ic62d6a6363762691bfd06bab913949e907ee660a --- src/tbm_bufmgr_sprd.c | 1 - 1 file changed, 1 deletion(-) mode change 100644 => 100755 src/tbm_bufmgr_sprd.c diff --git a/src/tbm_bufmgr_sprd.c b/src/tbm_bufmgr_sprd.c old mode 100644 new mode 100755 index 0b06f8b..670b58c --- a/src/tbm_bufmgr_sprd.c +++ b/src/tbm_bufmgr_sprd.c @@ -773,7 +773,6 @@ tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key) bo_sprd->fd = bufmgr_sprd->fd; bo_sprd->gem = gem; - bo_sprd->dmabuf = key; bo_sprd->size = real_size; bo_sprd->flags_sprd = info.flags; bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd); -- 2.7.4