diff options
author | lsj119 <lsj119@samsung.com> | 2018-10-29 14:31:14 +0900 |
---|---|---|
committer | lsj119 <lsj119@samsung.com> | 2018-10-29 14:36:38 +0900 |
commit | 38bce88818bdb6156661d17d49d8a8de018f0293 (patch) | |
tree | 51a6384ee83051b793c0ea82c48607070879fa36 | |
parent | a5527f723ef20287ee386d3051d4c9f45f9d6baf (diff) | |
download | libtbm-shm-38bce88818bdb6156661d17d49d8a8de018f0293.tar.gz libtbm-shm-38bce88818bdb6156661d17d49d8a8de018f0293.tar.bz2 libtbm-shm-38bce88818bdb6156661d17d49d8a8de018f0293.zip |
Support the shm backend for fd base
- Change fd base from shmget
- Change to ABI_3.0 from ABI_2.0
Change-Id: I7689a6f4a896cdc60f590207ebf60fcf6f902d22
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | packaging/libtbm-shm.spec | 3 | ||||
-rw-r--r-- | src/tbm_bufmgr_shm.c | 822 |
3 files changed, 457 insertions, 369 deletions
diff --git a/configure.ac b/configure.ac index ccb5639..c4d269f 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,6 @@ 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(DLOG, dlog) diff --git a/packaging/libtbm-shm.spec b/packaging/libtbm-shm.spec index ead88ac..c7b481b 100644 --- a/packaging/libtbm-shm.spec +++ b/packaging/libtbm-shm.spec @@ -1,5 +1,5 @@ Name: libtbm-shm -Version: 1.0.11 +Version: 2.0.0 Release: 1 License: MIT Summary: Tizen Buffer Manager - drm shm backend @@ -8,7 +8,6 @@ ExcludeArch: i586 Source0: %{name}-%{version}.tar.gz Source1001: %{name}.manifest -BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(dlog) diff --git a/src/tbm_bufmgr_shm.c b/src/tbm_bufmgr_shm.c index c96516e..8d4cfb0 100644 --- a/src/tbm_bufmgr_shm.c +++ b/src/tbm_bufmgr_shm.c @@ -42,18 +42,16 @@ #include <sys/mman.h> #include <sys/stat.h> #include <sys/ipc.h> -#include <sys/shm.h> #include <linux/unistd.h> #include <fcntl.h> #include <errno.h> -#include <tbm_bufmgr.h> -#include <tbm_bufmgr_backend.h> #include <pthread.h> -#include <tbm_surface.h> -#include <tbm_surface_internal.h> + +#include <tbm_backend.h> +#include <tbm_log.h> + #define DEBUG -#define USE_DMAIMPORT #define TBM_COLOR_FORMAT_COUNT 4 #ifdef DEBUG @@ -126,14 +124,13 @@ typedef struct _tbm_bo_shm *tbm_bo_shm; /* tbm buffor object for shm */ struct _tbm_bo_shm { - int shmid; key_t key; void * pBase; unsigned int size; - unsigned int flags_shm; unsigned int flags_tbm; + tbm_fd fd; pthread_mutex_t mutex; int device; @@ -144,6 +141,11 @@ struct _tbm_bo_shm { struct _tbm_bufmgr_shm { int isLocal; void* hashBos; + + tbm_backend_bufmgr_func *bufmgr_func; + tbm_backend_bo_func *bo_func; + + tbm_bufmgr bufmgr; }; char *STR_DEVICE[] = { @@ -162,11 +164,11 @@ char *STR_OPT[] = { }; uint32_t tbm_shm_color_format_list[TBM_COLOR_FORMAT_COUNT] = { - TBM_FORMAT_ARGB8888, - TBM_FORMAT_XRGB8888, - TBM_FORMAT_NV12, - TBM_FORMAT_YUV420 - }; + TBM_FORMAT_ARGB8888, + TBM_FORMAT_XRGB8888, + TBM_FORMAT_NV12, + TBM_FORMAT_YUV420 + }; static tbm_bo_handle _shm_bo_handle(tbm_bo_shm bo_shm, int device) @@ -177,7 +179,7 @@ _shm_bo_handle(tbm_bo_shm bo_shm, int device) switch (device) { case TBM_DEVICE_DEFAULT: case TBM_DEVICE_2D: - bo_handle.u32 = (uint32_t) bo_shm->shmid; + bo_handle.u32 = (uint32_t) bo_shm->fd; break; case TBM_DEVICE_CPU: bo_handle.ptr = (void *) bo_shm->pBase; @@ -186,7 +188,7 @@ _shm_bo_handle(tbm_bo_shm bo_shm, int device) case TBM_DEVICE_MM: default: TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Not supported device:%d\n", getpid(), __FUNCTION__, __LINE__, device); - bo_handle.ptr = (void *) NULL; + bo_handle.ptr = (void *) bo_shm->pBase; break; } @@ -194,274 +196,154 @@ _shm_bo_handle(tbm_bo_shm bo_shm, int device) } static int -tbm_shm_bo_size(tbm_bo bo) -{ - SHM_RETURN_VAL_IF_FAIL(bo != NULL, 0); - - tbm_bo_shm bo_shm; - - bo_shm = (tbm_bo_shm) tbm_backend_get_bo_priv(bo); - - return bo_shm->size; -} - -static void * -tbm_shm_bo_alloc(tbm_bo bo, int size, int flags) +_shm_os_fd_set_cloexec(int fd) { - SHM_RETURN_VAL_IF_FAIL(bo != NULL, 0); - - tbm_bo_shm bo_shm; - tbm_bufmgr_shm bufmgr_shm; + long flags; - static key_t key = 1; + if (fd == -1) + return -1; - bufmgr_shm = (tbm_bufmgr_shm) tbm_backend_get_bufmgr_priv(bo); - SHM_RETURN_VAL_IF_FAIL(bufmgr_shm != NULL, 0); + flags = fcntl(fd, F_GETFD); + if (flags == -1) + return -1; - if (flags & TBM_BO_SCANOUT) - TBM_SHM_LOG("[libtbm-shm:%d] warning %s:%d TBM_BO_SCANOUT ins't supported\n", getpid(), __FUNCTION__, __LINE__); + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) + return -1; - bo_shm = calloc(1, sizeof(struct _tbm_bo_shm)); - if (!bo_shm) { - TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to allocate the bo private\n", getpid(), __FUNCTION__, __LINE__); - return 0; - } - - //get next key for a allocated shm segment - key += 1; - - while ((bo_shm->shmid = shmget(key, size, IPC_CREAT | IPC_EXCL | 0666)) < 0) { - if (errno != EEXIST) { - TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to allocate the shared memory segment (%s)\n", getpid(), - __FUNCTION__, __LINE__, strerror(errno)); - free(bo_shm); - return 0; - } - - //try to allocate the segment with next key; - key += 1; - } - - bo_shm->key = key; - - if ((bo_shm->pBase = shmat(bo_shm->shmid, NULL, 0)) == (char *) -1) { - TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to attach the shared memory segment (%s)\n", getpid(), - __FUNCTION__, __LINE__, strerror(errno)); - free(bo_shm); - return 0; - } - - bo_shm->size = size; - bo_shm->flags_shm = 0; - bo_shm->flags_tbm = TBM_BO_DEFAULT | TBM_BO_NONCACHABLE; - - DBG(" [%s] bo:%p, shmid:%d(%d), flags:%d(%d), size:%d\n", target_name(), bo, bo_shm->shmid, bo_shm->key, - bo_shm->flags_tbm, bo_shm->flags_shm, bo_shm->size); - - return (void *) bo_shm; + return 0; } -static void -tbm_shm_bo_free(tbm_bo bo) +static int +_shm_set_cloexec_or_close(int fd) { - tbm_bo_shm bo_shm; - tbm_bufmgr_shm bufmgr_shm; - - if (!bo) - return; - - bufmgr_shm = (tbm_bufmgr_shm) tbm_backend_get_bufmgr_priv(bo); - SHM_RETURN_IF_FAIL(bufmgr_shm != NULL); - - bo_shm = (tbm_bo_shm) tbm_backend_get_bo_priv(bo); - SHM_RETURN_IF_FAIL(bo_shm != NULL); - - DBG(" [%s] bo:%p, shm:%d(%d), size:%d\n", target_name(), bo, bo_shm->shmid, bo_shm->key, bo_shm->size); - - /* Free shm object*/ - if (shmdt(bo_shm->pBase) == -1) { - TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to detach shared memory segment bo:%p (%s)\n", getpid(), - __FUNCTION__, __LINE__, bo, strerror(errno)); + if (_shm_os_fd_set_cloexec(fd) != 0) { + close(fd); + return -1; } - - free(bo_shm); + return fd; } -static void * -tbm_shm_bo_import(tbm_bo bo, unsigned int key) +static int +_shm_create_tmpfile_cloexec(char *tmpname) { - SHM_RETURN_VAL_IF_FAIL(bo != NULL, 0); - - tbm_bo_shm bo_shm; - struct shmid_ds buf; - - bo_shm = calloc(1, sizeof(struct _tbm_bo_shm)); - if (!bo_shm) { - TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to allocate the bo private\n", getpid(), __FUNCTION__, __LINE__); - return 0; - } + int fd; - if ((bo_shm->shmid = shmget(key, 0, 0666)) < 0) { - TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to import the shared memory segment key=%d (%s)\n", getpid(), - __FUNCTION__, __LINE__, key, strerror(errno)); - free(bo_shm); - return 0; - } - - if ((bo_shm->pBase = shmat(bo_shm->shmid, NULL, 0)) == (char *) -1) { - TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to attach the shared memory segment (%s)\n", getpid(), - __FUNCTION__, __LINE__, strerror(errno)); - free(bo_shm); - return 0; - } - - /*Get the original data for this shmid data structure first.*/ - if (shmctl(bo_shm->shmid, IPC_STAT, &buf) < 0) { - TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to get IPC_STAT(%s)\n", getpid(), __FUNCTION__, __LINE__, - strerror(errno)); - free(bo_shm); - return 0; +#ifdef HAVE_MKOSTEMP + fd = mkostemp(tmpname, O_CLOEXEC); + if (fd >= 0) + unlink(tmpname); +#else + fd = mkstemp(tmpname); + if (fd >= 0) { + fd = _shm_set_cloexec_or_close(fd); + unlink(tmpname); } +#endif - bo_shm->size = buf.shm_segsz; - bo_shm->flags_shm = 0; - bo_shm->key = key; - bo_shm->flags_tbm = TBM_BO_DEFAULT | TBM_BO_NONCACHABLE; - - DBG(" [%s] bo:%p, shm:%d(%d), flags:%d(%d), size:%d\n", target_name(), bo, bo_shm->shmid, bo_shm->key, - bo_shm->flags_tbm, bo_shm->flags_shm, bo_shm->size); - - return (void *) bo_shm; -} - -static unsigned int -tbm_shm_bo_export(tbm_bo bo) -{ - SHM_RETURN_VAL_IF_FAIL(bo != NULL, 0); - - tbm_bo_shm bo_shm; - - bo_shm = (tbm_bo_shm) tbm_backend_get_bo_priv(bo); - SHM_RETURN_VAL_IF_FAIL(bo_shm != NULL, 0); - - DBG(" [%s] bo:%p, shm:%d(%d), flags:%d(%d), size:%d\n", target_name(), bo, bo_shm->shmid, bo_shm->key, - bo_shm->flags_tbm, bo_shm->flags_shm, bo_shm->size); - - return (unsigned int) bo_shm->key; + return fd; } -static tbm_bo_handle -tbm_shm_bo_get_handle(tbm_bo bo, int device) +static tbm_fd +_shm_create_anonymous_file(off_t size) { - SHM_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL); - - tbm_bo_handle bo_handle; - tbm_bo_shm bo_shm; - - bo_shm = (tbm_bo_shm) tbm_backend_get_bo_priv(bo); - SHM_RETURN_VAL_IF_FAIL(bo_shm != NULL, (tbm_bo_handle) NULL); - - DBG("[%s] bo:%p, shm:%d(%d), flags:%d(%d), size:%d, %s\n", target_name(), bo, bo_shm->shmid, bo_shm->key, - bo_shm->flags_tbm, bo_shm->flags_shm, bo_shm->size, STR_DEVICE[device]); - - /*Get mapped bo_handle*/ - bo_handle = _shm_bo_handle(bo_shm, device); - if (bo_handle.ptr == NULL) { - TBM_SHM_LOG("error Cannot get handle: shm:%d, device:%d\n", bo_shm->shmid, device); - return (tbm_bo_handle) NULL; + static const char template[] = "/tbm-shared-XXXXXX"; + const char *path; + char *name; + int fd; + int ret; + + path = getenv("XDG_RUNTIME_DIR"); + if (!path) { + errno = ENOENT; + return -1; } - return bo_handle; -} + name = malloc(strlen(path) + sizeof(template)); + if (!name) + return -1; -static tbm_bo_handle -tbm_shm_bo_map(tbm_bo bo, int device, int opt) -{ - SHM_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL); + strcpy(name, path); + strcat(name, template); - tbm_bo_handle bo_handle; - tbm_bo_shm bo_shm; + fd = _shm_create_tmpfile_cloexec(name); - bo_shm = (tbm_bo_shm) tbm_backend_get_bo_priv(bo); - SHM_RETURN_VAL_IF_FAIL(bo_shm != NULL, (tbm_bo_handle) NULL); + free(name); - DBG(" [%s] bo:%p, shm:%d(%d), %s, %s\n", target_name(), bo, bo_shm->shmid, bo_shm->key, STR_DEVICE[device], - STR_OPT[opt]); + if (fd < 0) + return -1; - /*Get mapped bo_handle*/ - bo_handle = _shm_bo_handle(bo_shm, device); - if (bo_handle.ptr == NULL) { - TBM_SHM_LOG("error Cannot get handle: shm:%d, device:%d, opt:%d\n", bo_shm->shmid, device, opt); - return (tbm_bo_handle) NULL; +#ifdef HAVE_POSIX_FALLOCATE + do { + ret = posix_fallocate(fd, 0, size); + } while (ret == EINTR); + if (ret != 0) { + close(fd); + errno = ret; + return -1; } +#else + do { + ret = ftruncate(fd, size); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + close(fd); + return -1; + } +#endif - return bo_handle; + return (tbm_fd)fd; } -static int -tbm_shm_bo_unmap(tbm_bo bo) +static tbm_bufmgr_capability +tbm_shm_bufmgr_get_capabilities(tbm_backend_bufmgr_data *bufmgr_data, tbm_error_e *error) { - SHM_RETURN_VAL_IF_FAIL(bo != NULL, 0); + tbm_bufmgr_capability capabilities = TBM_BUFMGR_CAPABILITY_NONE; - tbm_bo_shm bo_shm; + capabilities = TBM_BUFMGR_CAPABILITY_SHARE_FD; - bo_shm = (tbm_bo_shm) tbm_backend_get_bo_priv(bo); - SHM_RETURN_VAL_IF_FAIL(bo_shm != NULL, 0); + if (error) + *error = TBM_ERROR_NONE; - DBG(" [%s] bo:%p, shm:%d(%d)\n", target_name(), bo, bo_shm->shmid, bo_shm->key); - - return 1; + return capabilities; } -static void -tbm_shm_bufmgr_deinit(void *priv) +static tbm_error_e +tbm_shm_bufmgr_bind_native_display(tbm_backend_bufmgr_data *bufmgr_data, tbm_native_display *native_display) { - SHM_RETURN_IF_FAIL(priv != NULL); - - tbm_bufmgr_shm bufmgr_shm; - - bufmgr_shm = (tbm_bufmgr_shm) priv; - - free(bufmgr_shm); + return TBM_ERROR_NONE; } -int -tbm_shm_surface_supported_format(uint32_t **formats, uint32_t *num) +static tbm_error_e +tbm_shm_bufmgr_get_supported_formats(tbm_backend_bufmgr_data *bufmgr_data, + uint32_t **formats, uint32_t *num) { - uint32_t* color_formats = NULL; + tbm_bufmgr_shm bufmgr_shm = (tbm_bufmgr_shm)bufmgr_data; + uint32_t *color_formats; - color_formats = (uint32_t*) calloc(1, sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT); + TBM_RETURN_VAL_IF_FAIL(bufmgr_shm != NULL, TBM_ERROR_INVALID_PARAMETER); + color_formats = (uint32_t *)calloc(1, sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT); if (color_formats == NULL) - return 0; + return TBM_ERROR_OUT_OF_MEMORY; - memcpy(color_formats, tbm_shm_color_format_list, sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT); + memcpy(color_formats, tbm_shm_color_format_list, sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT); *formats = color_formats; *num = TBM_COLOR_FORMAT_COUNT; - fprintf(stderr, "tbm_shm_surface_supported_format count = %d \n", *num); + TBM_DBG("supported format count = %d\n", *num); - return 1; + return TBM_ERROR_NONE; } -/** - * @brief get the plane data of 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_shm_surface_get_plane_data(int width, int height, tbm_format format, int plane_idx, uint32_t *size, - uint32_t *offset, uint32_t *pitch, int *bo_idx) +static tbm_error_e +tbm_shm_bufmgr_get_plane_data(tbm_backend_bufmgr_data *bufmgr_data, + tbm_format format, int plane_idx, int width, + int height, uint32_t *size, uint32_t *offset, + uint32_t *pitch, int *bo_idx) + { - int ret = 1; + int ret = TBM_ERROR_NONE; int bpp; int _offset = 0; int _pitch = 0; @@ -708,164 +590,372 @@ tbm_shm_surface_get_plane_data(int width, int height, tbm_format format, int pla return ret; } -int -tbm_shm_surface_get_num_bos(tbm_format format) +static tbm_backend_bo_data * +tbm_shm_bufmgr_alloc_bo(tbm_backend_bufmgr_data *bufmgr_data, unsigned int size, + tbm_bo_memory_type flags, tbm_error_e *error) + { - int num = 0; + tbm_bufmgr_shm bufmgr_shm = (tbm_bufmgr_shm)bufmgr_data; + tbm_bo_shm bo_shm; - 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_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; + if (bufmgr_shm == NULL) { + TBM_ERR("bufmgr_data is null\n"); + if (error) *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } - case TBM_FORMAT_NV12: - num = 2; - break; + tbm_fd fd = -1; - default: - num = 0; - break; + if (flags & TBM_BO_SCANOUT) + TBM_SHM_LOG("[libtbm-shm:%d] warning %s:%d TBM_BO_SCANOUT ins't supported\n", getpid(), __FUNCTION__, __LINE__); + + bo_shm = calloc(1, sizeof(struct _tbm_bo_shm)); + if (!bo_shm) { + TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to allocate the bo private\n", getpid(), __FUNCTION__, __LINE__); + if (error) *error = TBM_ERROR_INVALID_OPERATION; + return 0; } - return num; -} + bo_shm->fd = -1; + fd = _shm_create_anonymous_file((off_t)size); + if (fd < 0) { + TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to create a buffer file(size: %d) %m\n", getpid(), + __FUNCTION__, __LINE__, size); + free(bo_shm); + if (error) *error = TBM_ERROR_INVALID_OPERATION; + return 0; + } -MODULEINITPPROTO(init_tbm_bufmgr_priv); + bo_shm->fd = fd; + bo_shm->pBase = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (bo_shm->pBase == MAP_FAILED) { + TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to mmap: %m\n", getpid(), + __FUNCTION__, __LINE__); + close(fd); + free(bo_shm); + if (error) *error = TBM_ERROR_INVALID_OPERATION; + return 0; + } -static TBMModuleVersionInfo DumbVersRec = { - "shm", - "Samsung", - TBM_ABI_VERSION, -}; + bo_shm->size = size; + bo_shm->flags_tbm = TBM_BO_DEFAULT | TBM_BO_NONCACHABLE; -TBMModuleData tbmModuleData = { - &DumbVersRec, - init_tbm_bufmgr_priv -}; + DBG(" [%s] bo:%p, fd:%d, flags:%d, size:%d\n", target_name(), bo_shm, bo_shm->fd, bo_shm->flags_tbm, bo_shm->size); + if (error) *error = TBM_ERROR_NONE; + + return (tbm_backend_bo_data *) bo_shm; +} -int -init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd) +static tbm_backend_bo_data * +tbm_shm_bufmgr_import_fd(tbm_backend_bufmgr_data *bufmgr_data, tbm_fd key, tbm_error_e *error) { - tbm_bufmgr_shm bufmgr_shm; - tbm_bufmgr_backend bufmgr_backend; + tbm_bo_shm bo_shm; + int real_size; - if (!bufmgr) + if (key < 0) { + TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Invalid fd(%d)\n", getpid(), __FUNCTION__, __LINE__, key); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; return 0; + } - bufmgr_shm = calloc(1, sizeof(struct _tbm_bufmgr_shm)); - if (!bufmgr_shm) { - TBM_SHM_LOG("error: Fail to alloc bufmgr_shm!\n"); + bo_shm = calloc(1, sizeof(struct _tbm_bo_shm)); + if (!bo_shm) { + TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to allocate the bo private\n", getpid(), __FUNCTION__, __LINE__); + if (error) + *error = TBM_ERROR_INVALID_OPERATION; return 0; } - bufmgr_backend = tbm_backend_alloc(); - if (!bufmgr_backend) { - TBM_SHM_LOG("error: Fail to create drm!\n"); - free(bufmgr_shm); + real_size = lseek(key, 0, SEEK_END); + bo_shm->pBase = mmap(NULL, real_size, + PROT_READ | PROT_WRITE, MAP_SHARED, key, 0); + if (bo_shm->pBase == MAP_FAILED) { + TBM_SHM_LOG("[libtbm-shm:%d] error %s:%d Fail to mmap (fd: %d, size:%d)\n", getpid(), __FUNCTION__, __LINE__, + bo_shm->fd, real_size, strerror(errno)); + free(bo_shm); + if (error) + *error = TBM_ERROR_INVALID_OPERATION; return 0; } - bufmgr_backend->priv = (void *) bufmgr_shm; - bufmgr_backend->bufmgr_deinit = tbm_shm_bufmgr_deinit; - bufmgr_backend->bo_size = tbm_shm_bo_size; - bufmgr_backend->bo_alloc = tbm_shm_bo_alloc; - bufmgr_backend->bo_free = tbm_shm_bo_free; - bufmgr_backend->bo_import = tbm_shm_bo_import; - bufmgr_backend->bo_import_fd = NULL; - bufmgr_backend->bo_export = tbm_shm_bo_export; - bufmgr_backend->bo_export_fd = NULL; - bufmgr_backend->bo_get_handle = tbm_shm_bo_get_handle; - bufmgr_backend->bo_map = tbm_shm_bo_map; - bufmgr_backend->bo_unmap = tbm_shm_bo_unmap; - bufmgr_backend->surface_get_plane_data = tbm_shm_surface_get_plane_data; - bufmgr_backend->surface_supported_format = tbm_shm_surface_supported_format; - bufmgr_backend->bo_lock = NULL; - bufmgr_backend->bo_unlock = NULL; - - if (!tbm_backend_init(bufmgr, bufmgr_backend)) { - TBM_SHM_LOG("error: Fail to init backend!\n"); - tbm_backend_free(bufmgr_backend); - free(bufmgr_shm); + bo_shm->size = real_size; + bo_shm->fd = key; + bo_shm->flags_tbm = TBM_BO_DEFAULT | TBM_BO_NONCACHABLE; + + DBG(" [%s] bo:%p, shm:%d(%d), flags:%d, size:%d\n", target_name(), bo_shm, bo_shm->fd, + bo_shm->flags_tbm, bo_shm->size); + if (error) + *error = TBM_ERROR_NONE; + + return (tbm_backend_bo_data *) bo_shm; +} + +static void +tbm_shm_bo_free(tbm_backend_bo_data *bo_data) +{ + tbm_bo_shm bo_shm = (tbm_bo_shm)bo_data; + + SHM_RETURN_IF_FAIL(bo_shm != NULL); + + DBG(" [%s] bo:%p, shm:%d, size:%d\n", target_name(), bo_shm, bo_shm->fd, bo_shm->size); + + /* Free shm object*/ + close(bo_shm->fd); + free(bo_shm); +} + +static int +tbm_shm_bo_get_size(tbm_backend_bo_data *bo_data, tbm_error_e *error) +{ + tbm_bo_shm bo_shm = (tbm_bo_shm)bo_data; + + if (!bo_shm) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; return 0; } -#ifdef DEBUG - { - char* env; - env = getenv("TBM_SHM_DEBUG"); - if (env) { - bDebug = atoi(env); - TBM_SHM_LOG("TBM_SHM_DEBUG=%s\n", env); - } else { - bDebug = 0; - } + if (error) + *error = TBM_ERROR_NONE; + + return bo_shm->size; +} + + +static tbm_bo_memory_type +tbm_shm_bo_get_memory_type(tbm_backend_bo_data *bo_data, tbm_error_e *error) +{ + tbm_bo_shm bo_shm = (tbm_bo_shm)bo_data; + + if (!bo_shm) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return TBM_BO_DEFAULT; } -#endif - return 1; + if (error) + *error = TBM_ERROR_NONE; + + return bo_shm->flags_tbm; +} + +static tbm_bo_handle +tbm_shm_bo_get_handle(tbm_backend_bo_data *bo_data, tbm_bo_device_type device, tbm_error_e *error) +{ + tbm_bo_handle bo_handle; + tbm_bo_shm bo_shm = (tbm_bo_shm)bo_data;; + + if (!bo_shm) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return (tbm_bo_handle) NULL; + } + + DBG("[%s] bo:%p, shm:%d, flags:%d, size:%d, %s\n", target_name(), bo_shm, bo_shm->fd, + bo_shm->flags_tbm, bo_shm->size, STR_DEVICE[device]); + + /*Get mapped bo_handle*/ + bo_handle = _shm_bo_handle(bo_shm, device); + if (bo_handle.ptr == NULL) { + TBM_SHM_LOG("error Cannot get handle: shm:%d, device:%d\n", bo_shm->fd, device); + + if (error) + *error = TBM_ERROR_INVALID_OPERATION; + return (tbm_bo_handle) NULL; + } + + if (error) + *error = TBM_ERROR_NONE; + + return bo_handle; } + +static tbm_bo_handle +tbm_shm_bo_map(tbm_backend_bo_data *bo_data, tbm_bo_device_type device, + tbm_bo_access_option opt, tbm_error_e *error) +{ + tbm_bo_handle bo_handle; + tbm_bo_shm bo_shm = (tbm_bo_shm)bo_data;; + + if (!bo_shm) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return (tbm_bo_handle) NULL; + } + + DBG(" [%s] bo:%p, shm:%d, %s, %s\n", target_name(), bo_shm, bo_shm->fd, STR_DEVICE[device], + STR_OPT[opt]); + + /*Get mapped bo_handle*/ + bo_handle = _shm_bo_handle(bo_shm, device); + if (bo_handle.ptr == NULL) { + TBM_SHM_LOG("error Cannot get handle: shm:%d, device:%d, opt:%d\n", bo_shm->fd, device, opt); + if (error) + *error = TBM_ERROR_INVALID_OPERATION; + return (tbm_bo_handle) NULL; + } + + if (error) + *error = TBM_ERROR_NONE; + + return bo_handle; +} + +static tbm_error_e +tbm_shm_bo_unmap(tbm_backend_bo_data *bo_data) + +{ + tbm_bo_shm bo_shm = (tbm_bo_shm)bo_data;; + if (!bo_shm) + return TBM_ERROR_INVALID_PARAMETER; + + DBG(" [%s] bo:%p, shm:%d\n", target_name(), bo_shm, bo_shm->fd); + + return TBM_ERROR_NONE; +} + +static tbm_fd +tbm_sprd_bo_export_fd(tbm_backend_bo_data *bo_data, tbm_error_e *error) +{ + tbm_bo_shm bo_shm = (tbm_bo_shm)bo_data;; + + if (!bo_shm) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return -1; + } + + DBG(" [%s] bo:%p, shm:%d, flags:%d, size:%d\n", target_name(), bo_shm, bo_shm->fd, + bo_shm->flags_tbm, bo_shm->size); + + if (error) + *error = TBM_ERROR_NONE; + + return bo_shm->fd; +} + +static tbm_backend_bufmgr_data * +tbm_shm_init(tbm_bufmgr bufmgr, tbm_error_e *error) +{ + tbm_bufmgr_shm bufmgr_shm = NULL; + tbm_backend_bufmgr_func *bufmgr_func = NULL; + tbm_backend_bo_func *bo_func = NULL; + tbm_error_e err; + + if (!bufmgr) { + TBM_ERR("bufmgr is null.\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + bufmgr_shm = calloc(1, sizeof(struct _tbm_bufmgr_shm)); + if (!bufmgr_shm) { + TBM_ERR("fail to alloc bufmgr_shm!\n"); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + return NULL; + } + + /* alloc and register bufmgr_funcs */ + bufmgr_func = tbm_backend_bufmgr_alloc_bufmgr_func(bufmgr, &err); + if (!bufmgr_func) { + TBM_ERR("fail to alloc bufmgr_func! err(%d)\n", err); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + goto fail_alloc_bufmgr_func; + } + + bufmgr_func->bufmgr_get_capabilities = tbm_shm_bufmgr_get_capabilities; + bufmgr_func->bufmgr_bind_native_display = tbm_shm_bufmgr_bind_native_display; + bufmgr_func->bufmgr_get_supported_formats = tbm_shm_bufmgr_get_supported_formats; + bufmgr_func->bufmgr_get_plane_data = tbm_shm_bufmgr_get_plane_data; + bufmgr_func->bufmgr_alloc_bo = tbm_shm_bufmgr_alloc_bo; + bufmgr_func->bufmgr_alloc_bo_with_format = NULL; + bufmgr_func->bufmgr_import_fd = tbm_shm_bufmgr_import_fd; + bufmgr_func->bufmgr_import_key = NULL; + + err = tbm_backend_bufmgr_register_bufmgr_func(bufmgr, bufmgr_func); + if (err != TBM_ERROR_NONE) { + TBM_ERR("fail to register bufmgr_func! err(%d)\n", err); + if (error) + *error = TBM_ERROR_INVALID_OPERATION; + goto fail_register_bufmgr_func; + } + bufmgr_shm->bufmgr_func = bufmgr_func; + + /* alloc and register bo_funcs */ + bo_func = tbm_backend_bufmgr_alloc_bo_func(bufmgr, &err); + if (!bo_func) { + TBM_ERR("fail to alloc bo_func! err(%d)\n", err); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + goto fail_alloc_bo_func; + } + + bo_func->bo_free = tbm_shm_bo_free; + bo_func->bo_get_size = tbm_shm_bo_get_size; + bo_func->bo_get_memory_types = tbm_shm_bo_get_memory_type; + bo_func->bo_get_handle = tbm_shm_bo_get_handle; + bo_func->bo_map = tbm_shm_bo_map; + bo_func->bo_unmap = tbm_shm_bo_unmap; + bo_func->bo_lock = NULL; + bo_func->bo_unlock = NULL; + bo_func->bo_export_fd = tbm_sprd_bo_export_fd; + bo_func->bo_export_key = NULL; + + err = tbm_backend_bufmgr_register_bo_func(bufmgr, bo_func); + if (err != TBM_ERROR_NONE) { + TBM_ERR("fail to register bo_func! err(%d)\n", err); + if (error) + *error = TBM_ERROR_INVALID_OPERATION; + goto fail_register_bo_func; + } + bufmgr_shm->bo_func = bo_func; + + TBM_DBG("tbm_shm_init: done\n"); + + if (error) + *error = TBM_ERROR_NONE; + + bufmgr_shm->bufmgr = bufmgr; + + return (tbm_backend_bufmgr_data *)bufmgr_shm; + +fail_register_bo_func: + tbm_backend_bufmgr_free_bo_func(bufmgr, bo_func); +fail_alloc_bo_func: +fail_register_bufmgr_func: + tbm_backend_bufmgr_free_bufmgr_func(bufmgr, bufmgr_func); +fail_alloc_bufmgr_func: + free(bufmgr_shm); + return NULL; +} + +static void +tbm_shm_deinit(tbm_backend_bufmgr_data *bufmgr_data) +{ + tbm_bufmgr_shm bufmgr_shm = (tbm_bufmgr_shm)bufmgr_data; + tbm_bufmgr bufmgr; + + TBM_RETURN_IF_FAIL(bufmgr_shm != NULL); + + bufmgr = bufmgr_shm->bufmgr; + + tbm_backend_bufmgr_free_bufmgr_func(bufmgr, bufmgr_shm->bufmgr_func); + tbm_backend_bufmgr_free_bo_func(bufmgr, bufmgr_shm->bo_func); + + free(bufmgr_shm); +} + + +tbm_backend_module tbm_backend_module_data = { + "shm", + "Samsung", + TBM_BACKEND_ABI_VERSION_3_0, + tbm_shm_init, + tbm_shm_deinit +}; + |