diff options
author | SooChan Lim <sc1.lim@samsung.com> | 2018-03-19 16:56:17 +0900 |
---|---|---|
committer | SooChan Lim <sc1.lim@samsung.com> | 2018-03-19 19:47:22 +0900 |
commit | faad5059a110d6bd2064ef23b2e2afa66d5b3842 (patch) | |
tree | ae8b63f61820b85a017b3f78a1f11a602d868f7f | |
parent | 19a4f5103eae848166d7a0935543fa0cf1e6071f (diff) | |
download | libtbm-dumb-faad5059a110d6bd2064ef23b2e2afa66d5b3842.tar.gz libtbm-dumb-faad5059a110d6bd2064ef23b2e2afa66d5b3842.tar.bz2 libtbm-dumb-faad5059a110d6bd2064ef23b2e2afa66d5b3842.zip |
make the new backend inteface with tbm_backend.h
Change-Id: I482ee919e13a60f67616ebaf6bfd7998b91ff07e
-rw-r--r-- | src/tbm_bufmgr_dumb.c | 936 |
1 files changed, 551 insertions, 385 deletions
diff --git a/src/tbm_bufmgr_dumb.c b/src/tbm_bufmgr_dumb.c index bca0d4a..c8b8b13 100644 --- a/src/tbm_bufmgr_dumb.c +++ b/src/tbm_bufmgr_dumb.c @@ -32,6 +32,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include <libudev.h> + #include <stdio.h> #include <stdlib.h> #include <stdint.h> @@ -44,12 +46,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <fcntl.h> #include <errno.h> #include <xf86drm.h> -#include <tbm_bufmgr.h> -#include <tbm_bufmgr_backend.h> #include <pthread.h> -#include <tbm_surface.h> -#include <tbm_surface_internal.h> -#include <libudev.h> +#include <tbm_backend.h> #include <tbm_drm_helper.h> #define DEBUG @@ -64,24 +62,23 @@ static int bDebug = 0; static char * target_name() { - FILE *f; + static char app_name[128] = {0, }; + static int initialized = 0; char *slash; - static int initialized = 0; - static char app_name[128]; - + FILE *f; if (initialized) return app_name; /* get the application name */ f = fopen("/proc/self/cmdline", "r"); if (!f) - return 0; + return NULL; memset(app_name, 0x00, sizeof(app_name)); if (fgets(app_name, 100, f) == NULL) { fclose(f); - return 0; + return NULL; } fclose(f); @@ -94,13 +91,15 @@ target_name() return app_name; } -#define TBM_DUMB_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args) -#define DBG(fmt, args...) {if (bDebug&01) LOGE(fmt, ##args); } +#define TBM_DUMB_ERROR(fmt, args...) LOGE("\033[31m" "[%s] " fmt "\033[0m", target_name(), ##args) +#define TBM_DUMB_DEBUG(fmt, args...) {if (bDebug&01) LOGD("[%s] " fmt, target_name(), ##args); } #else -#define TBM_DUMB_LOG(...) -#define DBG(...) +#define TBM_DUMB_ERROR(...) +#define TBM_DUMB_DEBUG(...) #endif +#define STRERR_BUFSIZE 128 + #define SIZE_ALIGN(value, base) (((value) + ((base) - 1)) & ~((base) - 1)) #define TBM_SURFACE_ALIGNMENT_PLANE (64) @@ -110,13 +109,13 @@ target_name() /* check condition */ #define DUMB_RETURN_IF_FAIL(cond) {\ if (!(cond)) {\ - TBM_DUMB_LOG("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\ + TBM_DUMB_ERROR("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\ return;\ } \ } #define DUMB_RETURN_VAL_IF_FAIL(cond, val) {\ if (!(cond)) {\ - TBM_DUMB_LOG("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\ + TBM_DUMB_ERROR("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\ return val;\ } \ } @@ -170,6 +169,8 @@ struct _tbm_bo_dumb { struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX]; int device; int opt; + + tbm_bufmgr_dumb bufmgr_dumb; }; /* tbm bufmgr private for dumb */ @@ -181,6 +182,11 @@ struct _tbm_bufmgr_dumb { char *device_name; void *bind_display; + + tbm_backend_bufmgr_func *bufmgr_func; + tbm_backend_bo_func *bo_func; + + tbm_bufmgr bufmgr; }; char *STR_DEVICE[] = { @@ -221,7 +227,7 @@ _tbm_dumb_open_drm() udev = udev_new(); if (!udev) { - TBM_DUMB_LOG("udev_new() failed.\n"); + TBM_DUMB_ERROR("udev_new() failed.\n"); return -1; } @@ -259,7 +265,7 @@ _tbm_dumb_open_drm() /* Get device file path. */ filepath = udev_device_get_devnode(drm_device); if (!filepath) { - TBM_DUMB_LOG("udev_device_get_devnode() failed.\n"); + TBM_DUMB_ERROR("udev_device_get_devnode() failed.\n"); udev_device_unref(drm_device); udev_unref(udev); return -1; @@ -268,7 +274,7 @@ _tbm_dumb_open_drm() /* Open DRM device file and check validity. */ fd = open(filepath, O_RDWR | O_CLOEXEC); if (fd < 0) { - TBM_DUMB_LOG("open(%s, O_RDWR | O_CLOEXEC) failed.\n"); + TBM_DUMB_ERROR("open(%s, O_RDWR | O_CLOEXEC) failed.\n"); udev_device_unref(drm_device); udev_unref(udev); return -1; @@ -276,7 +282,7 @@ _tbm_dumb_open_drm() ret = fstat(fd, &s); if (ret) { - TBM_DUMB_LOG("fstat() failed %s.\n"); + TBM_DUMB_ERROR("fstat() failed %s.\n"); close(fd); udev_device_unref(drm_device); udev_unref(udev); @@ -314,8 +320,7 @@ _get_name(int fd, unsigned int gem) arg.handle = gem; if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &arg)) { - TBM_DUMB_LOG("error fail to get flink from gem:%d (DRM_IOCTL_GEM_FLINK)\n", - gem); + TBM_DUMB_ERROR("fail to DRM_IOCTL_GEM_FLINK gem:%d", gem); return 0; } @@ -326,6 +331,7 @@ static tbm_bo_handle _dumb_bo_handle(tbm_bo_dumb bo_dumb, int device) { tbm_bo_handle bo_handle; + memset(&bo_handle, 0x0, sizeof(uint64_t)); switch (device) { @@ -340,14 +346,14 @@ _dumb_bo_handle(tbm_bo_dumb bo_dumb, int device) arg.handle = bo_dumb->gem; if (drmIoctl(bo_dumb->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg)) { - TBM_DUMB_LOG("error Cannot map_ gem=%d\n", bo_dumb->gem); + TBM_DUMB_ERROR("Cannot map_ gem=%d\n", bo_dumb->gem); return (tbm_bo_handle) NULL; } map = mmap(NULL, bo_dumb->size, PROT_READ|PROT_WRITE, MAP_SHARED, bo_dumb->fd, arg.offset); if (map == MAP_FAILED) { - TBM_DUMB_LOG("error Cannot usrptr gem=%d\n", bo_dumb->gem); + TBM_DUMB_ERROR("Cannot usrptr gem=%d\n", bo_dumb->gem); return (tbm_bo_handle) NULL; } bo_dumb->pBase = map; @@ -361,7 +367,7 @@ _dumb_bo_handle(tbm_bo_dumb bo_dumb, int device) arg.handle = bo_dumb->gem; if (drmIoctl(bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) { - TBM_DUMB_LOG("error Cannot dmabuf=%d\n", bo_dumb->gem); + TBM_DUMB_ERROR("Cannot dmabuf=%d\n", bo_dumb->gem); return (tbm_bo_handle) NULL; } bo_dumb->dmabuf = arg.fd; @@ -376,7 +382,7 @@ _dumb_bo_handle(tbm_bo_dumb bo_dumb, int device) arg.handle = bo_dumb->gem; if (drmIoctl(bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) { - TBM_DUMB_LOG("error Cannot dmabuf=%d\n", bo_dumb->gem); + TBM_DUMB_ERROR("Cannot dmabuf=%d\n", bo_dumb->gem); return (tbm_bo_handle) NULL; } bo_dumb->dmabuf = arg.fd; @@ -385,7 +391,7 @@ _dumb_bo_handle(tbm_bo_dumb bo_dumb, int device) bo_handle.u32 = (uint32_t)bo_dumb->dmabuf; break; default: - TBM_DUMB_LOG("error Not supported device:%d\n", device); + TBM_DUMB_ERROR("Not supported device:%d\n", device); bo_handle.ptr = (void *) NULL; break; } @@ -397,40 +403,50 @@ _dumb_bo_handle(tbm_bo_dumb bo_dumb, int device) static int _dumb_cache_flush(int fd, tbm_bo_dumb bo_dumb, int flags) { - TBM_DUMB_LOG("warning fail to flush the cache.\n"); + TBM_DUMB_ERROR("warning fail to flush the cache.\n"); return 1; } #endif static int -tbm_dumb_bo_size(tbm_bo bo) +tbm_dumb_bo_get_size(tbm_backend_bo_data *bo_data, tbm_error_e *error) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, 0); + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; - tbm_bo_dumb bo_dumb; + if (!bo_dumb) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return 0; + } - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); + if (error) + *error = TBM_ERROR_NONE; return bo_dumb->size; } -static void * -tbm_dumb_bo_alloc(tbm_bo bo, int size, int flags) +static tbm_backend_bo_data * +tbm_dumb_bufmgr_alloc_bo(tbm_backend_bufmgr_data *bufmgr_data, int size, tbm_bo_memory_type flags, tbm_error_e *error) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, 0); - + tbm_bufmgr_dumb bufmgr_dumb = (tbm_bufmgr_dumb)bufmgr_data; tbm_bo_dumb bo_dumb; - tbm_bufmgr_dumb bufmgr_dumb; unsigned int dumb_flags; - bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bufmgr_dumb != NULL, 0); + if (bufmgr_dumb == NULL) { + TBM_DUMB_ERROR("bufmgr_data is null\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } bo_dumb = calloc(1, sizeof(struct _tbm_bo_dumb)); if (!bo_dumb) { - TBM_DUMB_LOG("error fail to allocate the bo private\n"); - return 0; + TBM_DUMB_ERROR("fail to allocate the bo_dumb private\n"); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + return NULL; } + bo_dumb->bufmgr_dumb = bufmgr_dumb; dumb_flags = _get_dumb_flag_from_tbm(flags); @@ -442,9 +458,12 @@ tbm_dumb_bo_alloc(tbm_bo bo, int size, int flags) arg.width = size; arg.flags = dumb_flags; if (drmIoctl(bufmgr_dumb->fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg)) { - TBM_DUMB_LOG("error Cannot create bo(flag:%x, size:%d)\n", arg.flags, (unsigned int)size); + TBM_DUMB_ERROR("Cannot create bo_dumb(flag:%x, size:%d)\n", arg.flags, + (unsigned int)size); free(bo_dumb); - return 0; + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } bo_dumb->fd = bufmgr_dumb->fd; @@ -456,57 +475,62 @@ tbm_dumb_bo_alloc(tbm_bo bo, int size, int flags) pthread_mutex_init(&bo_dumb->mutex, NULL); - if (bufmgr_dumb->use_dma_fence - && !bo_dumb->dmabuf) { + if (bufmgr_dumb->use_dma_fence && !bo_dumb->dmabuf) { struct drm_prime_handle arg = {0, }; arg.handle = bo_dumb->gem; if (drmIoctl(bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) { - TBM_DUMB_LOG("error Cannot dmabuf=%d\n", bo_dumb->gem); + TBM_DUMB_ERROR("Cannot dmabuf=%d\n", bo_dumb->gem); free(bo_dumb); - return 0; + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } bo_dumb->dmabuf = arg.fd; } /* add bo to hash */ if (drmHashInsert(bufmgr_dumb->hashBos, bo_dumb->name, (void *)bo_dumb) < 0) - TBM_DUMB_LOG("error Cannot insert bo to Hash(%d)\n", bo_dumb->name); + TBM_DUMB_ERROR("error Cannot insert bo to Hash(%d)\n", bo_dumb->name); + + TBM_DUMB_DEBUG(" bo_dumb:%p, gem:%d(%d), flags:%d(%d), size:%d\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->flags_tbm, + bo_dumb->size);; - DBG(" [%s] bo:%p, gem:%d(%d), flags:%d(%d), size:%d\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - flags, dumb_flags, - bo_dumb->size); + if (error) + *error = TBM_ERROR_NONE; - return (void *)bo_dumb; + return (tbm_backend_bo_data *)bo_dumb; } static void -tbm_dumb_bo_free(tbm_bo bo) +tbm_dumb_bo_free(tbm_backend_bo_data *bo_data) { - tbm_bo_dumb bo_dumb, temp; + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; + tbm_bo_dumb temp; tbm_bufmgr_dumb bufmgr_dumb; + char buf[STRERR_BUFSIZE]; + int ret; - if (!bo) + if (!bo_data) return; - bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo); - DUMB_RETURN_IF_FAIL(bufmgr_dumb != NULL); - - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); - DUMB_RETURN_IF_FAIL(bo_dumb != NULL); + bufmgr_dumb = bo_dumb->bufmgr_dumb; + if (!bufmgr_dumb) + return; - DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, size:%d\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf, - bo_dumb->size); + TBM_DUMB_DEBUG(" bo_dumb:%p, gem:%d(%d), fd:%d, size:%d\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf, + bo_dumb->size); if (bo_dumb->pBase) { if (munmap(bo_dumb->pBase, bo_dumb->size) == -1) { - TBM_DUMB_LOG("error bo:%p fail to munmap(%s)\n", - bo, strerror(errno)); + TBM_DUMB_ERROR("bo_dumb:%p fail to munmap(%s)\n", + bo_dumb, strerror_r(errno, buf, STRERR_BUFSIZE)); } } @@ -517,58 +541,64 @@ tbm_dumb_bo_free(tbm_bo bo) } /* delete bo from hash */ - int ret; - ret = drmHashLookup(bufmgr_dumb->hashBos, bo_dumb->name, (void**)&temp); if (ret == 0) drmHashDelete(bufmgr_dumb->hashBos, bo_dumb->name); else - TBM_DUMB_LOG("warning Cannot find bo to Hash(%d), ret =%d\n", bo_dumb->name, ret); + TBM_DUMB_ERROR("Cannot find bo_dumb to Hash(%d), ret=%d\n", bo_dumb->name, ret); if (temp != bo_dumb) - TBM_DUMB_LOG("hashBos probably has several BOs with same name!!!\n"); + TBM_DUMB_ERROR("hashBos probably has several BOs with same name!!!\n"); /* Free gem handle */ struct drm_gem_close arg = {0, }; + memset(&arg, 0, sizeof(arg)); arg.handle = bo_dumb->gem; - if (drmIoctl(bo_dumb->fd, DRM_IOCTL_GEM_CLOSE, &arg)) { - TBM_DUMB_LOG("error bo:%p fail to gem close.(%s)\n", - bo, strerror(errno)); - } + if (drmIoctl(bo_dumb->fd, DRM_IOCTL_GEM_CLOSE, &arg)) + TBM_DUMB_ERROR("bo_dumb:%p fail to gem close.(%s)\n", + bo_dumb, strerror_r(errno, buf, STRERR_BUFSIZE)); free(bo_dumb); } - -static void * -tbm_dumb_bo_import(tbm_bo bo, unsigned int key) +static tbm_backend_bo_data * +tbm_dumb_bufmgr_import_key(tbm_backend_bufmgr_data *bufmgr_data, tbm_key key, tbm_error_e *error) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, 0); - - tbm_bufmgr_dumb bufmgr_dumb; + tbm_bufmgr_dumb bufmgr_dumb = (tbm_bufmgr_dumb)bufmgr_data; tbm_bo_dumb bo_dumb; int ret; - bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bufmgr_dumb != NULL, 0); + if (bufmgr_dumb == NULL) { + TBM_DUMB_ERROR("bufmgr_data is null\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } ret = drmHashLookup(bufmgr_dumb->hashBos, key, (void **)&bo_dumb); - if (ret == 0) - return bo_dumb; + if (ret == 0) { + if (error) + *error = TBM_ERROR_NONE; + return (tbm_backend_bo_data *)bo_dumb; + } struct drm_gem_open arg = {0, }; arg.name = key; if (drmIoctl(bufmgr_dumb->fd, DRM_IOCTL_GEM_OPEN, &arg)) { - TBM_DUMB_LOG("error Cannot open gem name=%d\n", key); - return 0; + TBM_DUMB_ERROR("Cannot open gem name=%d\n", key); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } bo_dumb = calloc(1, sizeof(struct _tbm_bo_dumb)); if (!bo_dumb) { - TBM_DUMB_LOG("error fail to allocate the bo private\n"); - return 0; + TBM_DUMB_ERROR("fail to allocate the bo_dumb private\n"); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + return NULL; } bo_dumb->fd = bufmgr_dumb->fd; @@ -583,99 +613,123 @@ tbm_dumb_bo_import(tbm_bo bo, unsigned int key) arg.handle = bo_dumb->gem; if (drmIoctl(bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) { - TBM_DUMB_LOG("error Cannot dmabuf=%d\n", bo_dumb->gem); + TBM_DUMB_ERROR("fail to DRM_IOCTL_PRIME_HANDLE_TO_FD gem=%d\n", bo_dumb->gem); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; free(bo_dumb); - return 0; + return NULL; } bo_dumb->dmabuf = arg.fd; } /* add bo to hash */ if (drmHashInsert(bufmgr_dumb->hashBos, bo_dumb->name, (void *)bo_dumb) < 0) - TBM_DUMB_LOG("error Cannot insert bo to Hash(%d)\n", bo_dumb->name); + TBM_DUMB_ERROR("Cannot insert bo_dumb to Hash(%d)\n", bo_dumb->name); - DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf, - bo_dumb->flags_tbm, bo_dumb->flags_dumb, - bo_dumb->size); + TBM_DUMB_DEBUG(" bo_dumb:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf, + bo_dumb->flags_tbm, + bo_dumb->size); - return (void *)bo_dumb; + if (error) + *error = TBM_ERROR_NONE; + + return (tbm_backend_bo_data *)bo_dumb; } -static void * -tbm_dumb_bo_import_fd(tbm_bo bo, tbm_fd key) +static tbm_backend_bo_data * +tbm_dumb_bufmgr_import_fd(tbm_backend_bufmgr_data *bufmgr_data, tbm_fd key, tbm_error_e *error) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, 0); - - tbm_bufmgr_dumb bufmgr_dumb; + tbm_bufmgr_dumb bufmgr_dumb = (tbm_bufmgr_dumb)bufmgr_data; tbm_bo_dumb bo_dumb; - - bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bufmgr_dumb != NULL, 0); - + unsigned int gem = 0; + unsigned int name; int ret; + char buf[STRERR_BUFSIZE]; - unsigned int gem = 0; - unsigned int name = 0; - unsigned int real_size = -1; + if (bufmgr_dumb == NULL) { + TBM_DUMB_ERROR("bufmgr_data is null\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } //getting handle from fd struct drm_prime_handle arg = {0, }; - struct drm_gem_open gem_open = {0, }; arg.fd = key; arg.flags = 0; if (drmIoctl(bufmgr_dumb->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) { - TBM_DUMB_LOG("error bo:%p Cannot get gem handle from fd:%d (%s)\n", - bo, arg.fd, strerror(errno)); + TBM_DUMB_ERROR("Cannot get gem handle from fd:%d (%s)\n", + arg.fd, strerror_r(errno, buf, STRERR_BUFSIZE)); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; 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); - name = _get_name(bufmgr_dumb->fd, gem); if (name == 0) { - TBM_DUMB_LOG("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n", - bo, gem, key, strerror(errno)); - return 0; + TBM_DUMB_ERROR("Cannot get name from gem:%d, fd:%d (%s)\n", + gem, key, strerror_r(errno, buf, STRERR_BUFSIZE)); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } ret = drmHashLookup(bufmgr_dumb->hashBos, name, (void **)&bo_dumb); if (ret == 0) { - if (gem == bo_dumb->gem) + if (gem == bo_dumb->gem) { + if (error) + *error = TBM_ERROR_NONE; return bo_dumb; + } } + /* 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). */ + unsigned int real_size = -1; + struct drm_gem_open open_arg = {0, }; + + real_size = lseek(key, 0, SEEK_END); + /* Open the same GEM object only for finding out its size */ - gem_open.name = name; - if (drmIoctl(bufmgr_dumb->fd, DRM_IOCTL_GEM_OPEN, &gem_open)) { - TBM_DUMB_LOG("error Cannot open gem name=%d\n", key); - return 0; + open_arg.name = name; + if (drmIoctl(bufmgr_dumb->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) { + TBM_DUMB_ERROR("Cannot get gem info from gem:%d, fd:%d (%s)\n", + gem, key, strerror_r(errno, buf, STRERR_BUFSIZE)); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } + /* Free gem handle to avoid a memory leak*/ struct drm_gem_close gem_close; - gem_close.handle = gem_open.handle; + gem_close.handle = open_arg.handle; if (drmIoctl(bufmgr_dumb->fd, DRM_IOCTL_GEM_CLOSE, &gem_close)) { - TBM_DUMB_LOG("error bo:%p fail to gem close.(%s)\n", - bo, strerror(errno)); + TBM_DUMB_ERROR("Cannot close gem_handle.\n", + strerror_r(errno, buf, STRERR_BUFSIZE)); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } if (real_size == -1) - real_size = gem_open.size; + real_size = open_arg.size; bo_dumb = calloc(1, sizeof(struct _tbm_bo_dumb)); if (!bo_dumb) { - TBM_DUMB_LOG("error bo:%p fail to allocate the bo private\n", bo); - return 0; + TBM_DUMB_ERROR("bo_dumb:%p fail to allocate the bo_dumb\n", bo_dumb); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + return NULL; } + bo_dumb->bufmgr_dumb = bufmgr_dumb; bo_dumb->fd = bufmgr_dumb->fd; bo_dumb->gem = gem; @@ -685,194 +739,239 @@ tbm_dumb_bo_import_fd(tbm_bo bo, tbm_fd key) bo_dumb->flags_tbm = _get_tbm_flag_from_dumb(bo_dumb->flags_dumb); bo_dumb->name = name; - /* add bo to hash */ + /* add bo_dumb to hash */ if (drmHashInsert(bufmgr_dumb->hashBos, bo_dumb->name, (void *)bo_dumb) < 0) - TBM_DUMB_LOG("error Cannot insert bo to Hash(%d)\n", bo_dumb->name); + TBM_DUMB_ERROR("bo_dumb:%p Cannot insert bo_dumb to Hash(%d) from gem:%d, fd:%d\n", + bo_dumb, bo_dumb->name, gem, key); + + TBM_DUMB_DEBUG(" bo_dumb:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d, size:%d\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf, + key, + bo_dumb->flags_tbm, + bo_dumb->size); - DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf, - key, - bo_dumb->flags_tbm, bo_dumb->flags_dumb, - bo_dumb->size); + if (error) + *error = TBM_ERROR_NONE; - return (void *)bo_dumb; + return (tbm_backend_bo_data *)bo_dumb; } -static unsigned int -tbm_dumb_bo_export(tbm_bo bo) +static tbm_key +tbm_dumb_bo_export_key(tbm_backend_bo_data *bo_data, tbm_error_e *error) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, 0); + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; - tbm_bo_dumb bo_dumb; - - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bo_dumb != NULL, 0); + if (!bo_dumb) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return 0; + } if (!bo_dumb->name) { bo_dumb->name = _get_name(bo_dumb->fd, bo_dumb->gem); if (!bo_dumb->name) { - TBM_DUMB_LOG("error Cannot get name\n"); + TBM_DUMB_ERROR("error Cannot get name\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; return 0; } } - DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf, - bo_dumb->flags_tbm, bo_dumb->flags_dumb, - bo_dumb->size); + TBM_DUMB_DEBUG(" bo_dumb:%p, gem:%d(%d), fd:%d, flags:%d, size:%d\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf, + bo_dumb->flags_tbm, + bo_dumb->size); + + if (error) + *error = TBM_ERROR_NONE; - return (unsigned int)bo_dumb->name; + return (tbm_key)bo_dumb->name; } tbm_fd -tbm_dumb_bo_export_fd(tbm_bo bo) +tbm_dumb_bo_export_fd(tbm_backend_bo_data *bo_data, tbm_error_e *error) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, -1); - - tbm_bo_dumb bo_dumb; + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; int ret; + char buf[STRERR_BUFSIZE]; - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bo_dumb != NULL, -1); + if (!bo_dumb) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return -1; + } struct drm_prime_handle arg = {0, }; arg.handle = bo_dumb->gem; ret = drmIoctl(bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg); if (ret) { - TBM_DUMB_LOG("error bo:%p Cannot dmabuf=%d (%s)\n", - bo, bo_dumb->gem, strerror(errno)); + TBM_DUMB_ERROR("bo_dumb:%p Cannot dmabuf=%d (%s)\n", + bo_dumb, bo_dumb->gem, strerror_r(errno, buf, STRERR_BUFSIZE)); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; 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_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf, - arg.fd, - bo_dumb->flags_tbm, bo_dumb->flags_dumb, - bo_dumb->size); + TBM_DUMB_DEBUG(" bo_dumb:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d, size:%d\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf, + arg.fd, + bo_dumb->flags_tbm, + bo_dumb->size); return (tbm_fd)arg.fd; } static tbm_bo_handle -tbm_dumb_bo_get_handle(tbm_bo bo, int device) +tbm_dumb_bo_get_handle(tbm_backend_bo_data *bo_data, tbm_bo_device_type device, tbm_error_e *error) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL); - + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; tbm_bo_handle bo_handle; - tbm_bo_dumb bo_dumb; - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bo_dumb != NULL, (tbm_bo_handle) NULL); + if (!bo_dumb) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return (tbm_bo_handle) NULL; + } if (!bo_dumb->gem) { - TBM_DUMB_LOG("error Cannot map gem=%d\n", bo_dumb->gem); + TBM_DUMB_ERROR("Cannot map gem=%d\n", bo_dumb->gem); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; return (tbm_bo_handle) NULL; } - DBG("[%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d, %s\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf, - bo_dumb->flags_tbm, bo_dumb->flags_dumb, - bo_dumb->size, - STR_DEVICE[device]); + TBM_DUMB_DEBUG("bo_dumb:%p, gem:%d(%d), fd:%d, flags:%d, size:%d, %s\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf, + bo_dumb->flags_tbm, + bo_dumb->size, + STR_DEVICE[device]); /*Get mapped bo_handle*/ bo_handle = _dumb_bo_handle(bo_dumb, device); if (bo_handle.ptr == NULL) { - TBM_DUMB_LOG("error Cannot get handle: gem:%d, device:%d\n", bo_dumb->gem, device); + TBM_DUMB_ERROR("Cannot get handle: gem:%d, device:%d\n", + bo_dumb->gem, device); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; return (tbm_bo_handle) NULL; } + if (error) + *error = TBM_ERROR_NONE; + return bo_handle; } static tbm_bo_handle -tbm_dumb_bo_map(tbm_bo bo, int device, int opt) +tbm_dumb_bo_map(tbm_backend_bo_data *bo_data, tbm_bo_device_type device, + tbm_bo_access_option opt, tbm_error_e *error) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL); - + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; tbm_bo_handle bo_handle; - tbm_bo_dumb bo_dumb; + tbm_bufmgr_dumb bufmgr_dumb; - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bo_dumb != NULL, (tbm_bo_handle) NULL); + if (!bo_dumb) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return (tbm_bo_handle) NULL; + } + + bufmgr_dumb = bo_dumb->bufmgr_dumb; + if (!bufmgr_dumb) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return (tbm_bo_handle) NULL; + } if (!bo_dumb->gem) { - TBM_DUMB_LOG("error Cannot map gem=%d\n", bo_dumb->gem); + TBM_DUMB_ERROR("Cannot map gem=%d\n", bo_dumb->gem); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; return (tbm_bo_handle) NULL; } - DBG(" [%s] bo:%p, gem:%d(%d), fd:%d, %s, %s\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf, - STR_DEVICE[device], - STR_OPT[opt]); + TBM_DUMB_DEBUG(" bo_dumb:%p, gem:%d(%d), fd:%d, %s, %s\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf, + STR_DEVICE[device], + STR_OPT[opt]); /*Get mapped bo_handle*/ bo_handle = _dumb_bo_handle(bo_dumb, device); if (bo_handle.ptr == NULL) { - TBM_DUMB_LOG("error Cannot get handle: gem:%d, device:%d, opt:%d\n", bo_dumb->gem, device, opt); + TBM_DUMB_ERROR("Cannot get handle: gem:%d, device:%d, opt:%d\n", + bo_dumb->gem, device, opt); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; return (tbm_bo_handle) NULL; } + if (error) + *error = TBM_ERROR_NONE; + return bo_handle; } -static int -tbm_dumb_bo_unmap(tbm_bo bo) +static tbm_error_e +tbm_dumb_bo_unmap(tbm_backend_bo_data *bo_data) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, 0); + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; + tbm_bufmgr_dumb bufmgr_dumb; - tbm_bo_dumb bo_dumb; + if (!bo_dumb) + return TBM_ERROR_INVALID_PARAMETER; - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bo_dumb != NULL, 0); + bufmgr_dumb = bo_dumb->bufmgr_dumb; + if (!bufmgr_dumb) + return TBM_ERROR_INVALID_PARAMETER; if (!bo_dumb->gem) - return 0; + return TBM_ERROR_INVALID_PARAMETER; - DBG(" [%s] bo:%p, gem:%d(%d), fd:%d\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf); + TBM_DUMB_DEBUG(" bo_dumb:%p, gem:%d(%d), fd:%d\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf); - return 1; + return TBM_ERROR_NONE; } -static int -tbm_dumb_bo_lock(tbm_bo bo, int device, int opt) +static tbm_error_e +tbm_dumb_bo_lock(tbm_backend_bo_data *bo_data, tbm_bo_device_type device, + tbm_bo_access_option opt) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, 0); - #if USE_BACKEND_LOCK + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; tbm_bufmgr_dumb bufmgr_dumb; - tbm_bo_dumb bo_dumb; struct dma_buf_fence fence; struct flock filelock; int ret = 0; + char buf[STRERR_BUFSIZE]; - if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU) { - DBG("[libtbm-dumb:%d] %s not support device type,\n", getpid(), __FUNCTION__); - return 0; - } + if (!bo_dumb) + return TBM_ERROR_INVALID_PARAMETER; - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bo_dumb != NULL, 0); + bufmgr_dumb = bo_dumb->bufmgr_dumb; + if (!bufmgr_dumb) + return TBM_ERROR_INVALID_PARAMETER; - bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bufmgr_dumb != NULL, 0); + if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU) { + TBM_DUMB_DEBUG("Not support device type,\n"); + return TBM_ERROR_OPERATION_FAILED; + } if (!bufmgr_dumb->use_dma_fence) - return 1; + return TBM_ERROR_OPERATION_FAILED; memset(&fence, 0, sizeof(struct dma_buf_fence)); @@ -884,21 +983,21 @@ tbm_dumb_bo_lock(tbm_bo bo, int device, int opt) if (device == TBM_DEVICE_3D) fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA; } else { - TBM_DUMB_LOG("error Invalid argument\n"); - return 0; + TBM_DUMB_ERROR("error Invalid argument\n"); + return TBM_ERROR_INVALID_PARAMETER; } /* Check if the tbm manager supports dma fence or not. */ if (!bufmgr_dumb->use_dma_fence) { - TBM_DUMB_LOG("error Not support DMA FENCE(%s)\n", strerror(errno)); - return 0; + TBM_DUMB_ERROR("Not support DMA FENCE(%s)\n", strerror_r(errno, buf, STRERR_BUFSIZE)); + return TBM_ERROR_OPERATION_FAILED; } if (device == TBM_DEVICE_3D) { ret = ioctl(bo_dumb->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence); if (ret < 0) { - TBM_DUMB_LOG("error Cannot set GET FENCE(%s)\n", strerror(errno)); - return 0; + TBM_DUMB_ERROR("Cannot set GET FENCE(%s)\n", strerror_r(errno, buf, STRERR_BUFSIZE)); + return TBM_ERROR_OPERATION_FAILED; } } else { if (opt & TBM_OPTION_WRITE) @@ -911,7 +1010,7 @@ tbm_dumb_bo_lock(tbm_bo bo, int device, int opt) filelock.l_len = 0; if (-1 == fcntl(bo_dumb->dmabuf, F_SETLKW, &filelock)) - return 0; + return TBM_ERROR_OPERATION_FAILED; } pthread_mutex_lock(&bo_dumb->mutex); @@ -928,53 +1027,50 @@ tbm_dumb_bo_lock(tbm_bo bo, int device, int opt) if (i == DMA_FENCE_LIST_MAX) { //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim - TBM_DUMB_LOG("error fence list is full\n"); + TBM_DUMB_ERROR("fence list is full\n"); } } pthread_mutex_unlock(&bo_dumb->mutex); - DBG("[%s] DMABUF_IOCTL_GET_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf); - + TBM_DUMB_DEBUG("DMABUF_IOCTL_GET_FENCE! bo_dumb:%p, gem:%d(%d), fd:%ds\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf); #endif - return 1; + + return TBM_ERROR_NONE; } -static int -tbm_dumb_bo_unlock(tbm_bo bo) +static tbm_error_e +tbm_dumb_bo_unlock(tbm_backend_bo_data *bo_data) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, 0); - #if USE_BACKEND_LOCK - tbm_bo_dumb bo_dumb; + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; struct dma_buf_fence fence; struct flock filelock; unsigned int dma_type = 0; int ret = 0; + char buf[STRERR_BUFSIZE]; - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bo_dumb != NULL, 0); - - bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bufmgr_dumb != NULL, 0); + bufmgr_dumb = bo_dumb->bufmgr_dumb; + if (!bufmgr_dumb) + return TBM_ERROR_INVALID_PARAMETER; if (!bufmgr_dumb->use_dma_fence) - return 1; + return TBM_ERROR_OPERATION_FAILED; if (bo_dumb->dma_fence[0].type & DMA_BUF_ACCESS_DMA) dma_type = 1; if (!bo_dumb->dma_fence[0].ctx && dma_type) { - DBG("error FENCE not support or ignored,\n"); - return 0; + TBM_DUMB_DEBUG("FENCE not support or ignored,\n"); + return TBM_ERROR_OPERATION_FAILED; } if (!bo_dumb->dma_fence[0].ctx && dma_type) { - DBG("error device type is not 3D/CPU,\n"); - return 0; + TBM_DUMB_DEBUG("device type is not 3D/CPU,\n"); + return TBM_ERROR_OPERATION_FAILED; } pthread_mutex_lock(&bo_dumb->mutex); @@ -990,13 +1086,14 @@ tbm_dumb_bo_unlock(tbm_bo bo) bo_dumb->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0; bo_dumb->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0; } + pthread_mutex_unlock(&bo_dumb->mutex); if (dma_type) { ret = ioctl(bo_dumb->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence); if (ret < 0) { - TBM_DUMB_LOG("error Can not set PUT FENCE(%s)\n", strerror(errno)); - return 0; + TBM_DUMB_ERROR("Can not set PUT FENCE(%s)\n", strerror_r(errno, buf, STRERR_BUFSIZE)); + return TBM_ERROR_OPERATION_FAILED; } } else { filelock.l_type = F_UNLCK; @@ -1005,31 +1102,35 @@ tbm_dumb_bo_unlock(tbm_bo bo) filelock.l_len = 0; if (-1 == fcntl(bo_dumb->dmabuf, F_SETLKW, &filelock)) - return 0; + return TBM_ERROR_OPERATION_FAILED; } - DBG("[%s] DMABUF_IOCTL_PUT_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(), - bo, - bo_dumb->gem, bo_dumb->name, - bo_dumb->dmabuf); - + TBM_DUMB_DEBUG("DMABUF_IOCTL_PUT_FENCE! bo_dumb:%p, gem:%d(%d), fd:%ds\n", + bo_dumb, + bo_dumb->gem, bo_dumb->name, + bo_dumb->dmabuf); #endif - return 1; + + return TBM_ERROR_NONE; } static void -tbm_dumb_bufmgr_deinit(void *priv) +tbm_dumb_deinit(tbm_backend_bufmgr_data *bufmgr_data) { - DUMB_RETURN_IF_FAIL(priv != NULL); + tbm_bufmgr_dumb bufmgr_dumb = (tbm_bufmgr_dumb)bufmgr_data; + tbm_bufmgr bufmgr; + tbm_error_e error; + unsigned long key; + void *value; - tbm_bufmgr_dumb bufmgr_dumb; + DUMB_RETURN_IF_FAIL(bufmgr_dumb != NULL); - bufmgr_dumb = (tbm_bufmgr_dumb)priv; + bufmgr = bufmgr_dumb->bufmgr; - if (bufmgr_dumb->hashBos) { - unsigned long key; - void *value; + tbm_backend_bufmgr_free_bufmgr_func(bufmgr, bufmgr_dumb->bufmgr_func); + tbm_backend_bufmgr_free_bo_func(bufmgr, bufmgr_dumb->bo_func); + if (bufmgr_dumb->hashBos) { while (drmHashFirst(bufmgr_dumb->hashBos, &key, &value) > 0) { free(value); drmHashDelete(bufmgr_dumb->hashBos, key); @@ -1045,55 +1146,55 @@ tbm_dumb_bufmgr_deinit(void *priv) if (bufmgr_dumb->device_name) free(bufmgr_dumb->device_name); - if (tbm_backend_is_display_server()) + if (tbm_backend_bufmgr_query_display_server(bufmgr, &error)) tbm_drm_helper_unset_tbm_master_fd(); + else + tbm_drm_helper_unset_fd(); close(bufmgr_dumb->fd); free(bufmgr_dumb); } -int -tbm_dumb_surface_supported_format(uint32_t **formats, uint32_t *num) +static tbm_error_e +tbm_dumb_bufmgr_get_supported_formats(tbm_backend_bufmgr_data *bufmgr_data, + uint32_t **formats, uint32_t *num) { - uint32_t* color_formats = NULL; + tbm_bufmgr_dumb bufmgr_dumb = (tbm_bufmgr_dumb)bufmgr_data; + uint32_t *color_formats; - color_formats = (uint32_t*)calloc(1, sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT); + DUMB_RETURN_VAL_IF_FAIL(bufmgr_dumb != 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_dumb_color_format_list , sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT); + memcpy(color_formats, tbm_dumb_color_format_list, sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT); *formats = color_formats; *num = TBM_COLOR_FORMAT_COUNT; - return 1; + TBM_DUMB_DEBUG("supported format count = %d\n", *num); + + 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_dumb_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_dumb_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; + tbm_bufmgr_dumb bufmgr_dumb = (tbm_bufmgr_dumb)bufmgr_data; int bpp; int _offset = 0; int _pitch = 0; int _size = 0; int _bo_idx = 0; + DUMB_RETURN_VAL_IF_FAIL(bufmgr_dumb != NULL, TBM_ERROR_INVALID_PARAMETER); + switch (format) { /* 16 bpp RGB */ case TBM_FORMAT_XRGB4444: @@ -1317,105 +1418,125 @@ tbm_dumb_surface_get_plane_data(int width, int height, tbm_format format, int p *pitch = _pitch; *bo_idx = _bo_idx; - return ret; + return TBM_ERROR_NONE; } -int -tbm_dumb_bo_get_flags(tbm_bo bo) +static tbm_bo_memory_type +tbm_dumb_bo_get_memory_type(tbm_backend_bo_data *bo_data, tbm_error_e *error) { - DUMB_RETURN_VAL_IF_FAIL(bo != NULL, 0); + tbm_bo_dumb bo_dumb = (tbm_bo_dumb)bo_data; - tbm_bo_dumb bo_dumb; + if (!bo_dumb) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return TBM_BO_DEFAULT; + } - bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo); - DUMB_RETURN_VAL_IF_FAIL(bo_dumb != NULL, 0); + if (error) + *error = TBM_ERROR_NONE; return bo_dumb->flags_tbm; } -int -tbm_dumb_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display) +static tbm_bufmgr_capability +tbm_dumb_bufmgr_get_capabilities(tbm_backend_bufmgr_data *bufmgr_data, tbm_error_e *error) { - tbm_bufmgr_dumb bufmgr_dumb; + tbm_bufmgr_capability capabilities = TBM_BUFMGR_CAPABILITY_NONE; + + capabilities = TBM_BUFMGR_CAPABILITY_SHARE_KEY|TBM_BUFMGR_CAPABILITY_SHARE_FD; - bufmgr_dumb = tbm_backend_get_priv_from_bufmgr(bufmgr); - DUMB_RETURN_VAL_IF_FAIL(bufmgr_dumb != NULL, 0); + if (error) + *error = TBM_ERROR_NONE; + + return capabilities; +} + +static tbm_error_e +tbm_dumb_bufmgr_bind_native_display(tbm_backend_bufmgr_data *bufmgr_data, tbm_native_display *native_display) +{ + tbm_bufmgr_dumb bufmgr_dumb = (tbm_bufmgr_dumb)bufmgr_data; + DUMB_RETURN_VAL_IF_FAIL(bufmgr_dumb != NULL, TBM_ERROR_INVALID_PARAMETER); if (!tbm_drm_helper_wl_auth_server_init(native_display, bufmgr_dumb->fd, - bufmgr_dumb->device_name, 0)) { - TBM_DUMB_LOG("error:Fail to tbm_drm_helper_wl_server_init\n"); - return 0; + bufmgr_dumb->device_name, 0)) { + TBM_DUMB_ERROR("fail to tbm_drm_helper_wl_server_init\n"); + return TBM_ERROR_OPERATION_FAILED; } bufmgr_dumb->bind_display = native_display; - return 1; + return TBM_ERROR_NONE; } -MODULEINITPPROTO(init_tbm_bufmgr_priv); - -static TBMModuleVersionInfo DumbVersRec = { - "dumb", - "Samsung", - TBM_ABI_VERSION, -}; - -TBMModuleData tbmModuleData = { &DumbVersRec, init_tbm_bufmgr_priv}; - -int -init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd) +static tbm_backend_bufmgr_data * +tbm_dumb_init(tbm_bufmgr bufmgr, tbm_error_e *error) { - tbm_bufmgr_dumb bufmgr_dumb; - tbm_bufmgr_backend bufmgr_backend; + tbm_bufmgr_dumb bufmgr_dumb = NULL; + tbm_backend_bufmgr_func *bufmgr_func = NULL; + tbm_backend_bo_func *bo_func = NULL; + int fp; + tbm_error_e err; uint64_t cap = 0; uint32_t ret; - int fp; int length; char buf[1]; - if (!bufmgr) - return 0; + if (!bufmgr) { + TBM_DUMB_ERROR("bufmgr is null.\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } bufmgr_dumb = calloc(1, sizeof(struct _tbm_bufmgr_dumb)); if (!bufmgr_dumb) { - TBM_DUMB_LOG("error: Fail to alloc bufmgr_dumb!\n"); - return 0; + TBM_DUMB_ERROR("fail to alloc bufmgr_dumb!\n"); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + return NULL; } - if (tbm_backend_is_display_server()) { - + if (tbm_backend_bufmgr_query_display_server(bufmgr, &err)) { bufmgr_dumb->fd = tbm_drm_helper_get_master_fd(); - if (bufmgr_dumb->fd < 0) - bufmgr_dumb->fd = _tbm_dumb_open_drm(); - if (bufmgr_dumb->fd < 0) { - TBM_DUMB_LOG("error:Fail to create drm!\n"); - goto fail_open_drm; + bufmgr_dumb->fd = _tbm_dumb_open_drm(); + if (bufmgr_dumb->fd < 0) { + TBM_DUMB_ERROR("fail to open drm!\n"); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + goto fail_open_drm; + } } tbm_drm_helper_set_tbm_master_fd(bufmgr_dumb->fd); bufmgr_dumb->device_name = drmGetDeviceNameFromFd(bufmgr_dumb->fd); if (!bufmgr_dumb->device_name) { - TBM_DUMB_LOG("error:Fail to get device name!\n"); + TBM_DUMB_ERROR("fail to get device name!\n"); + tbm_drm_helper_unset_tbm_master_fd(); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; goto fail_get_device_name; } + tbm_drm_helper_set_fd(bufmgr_dumb->fd); } else { if (!tbm_drm_helper_get_auth_info(&(bufmgr_dumb->fd), &(bufmgr_dumb->device_name), NULL)) { - TBM_DUMB_LOG("error:Fail to get auth drm info!\n"); + TBM_DUMB_ERROR("fail to get auth drm info!\n"); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; goto fail_get_auth_info; } + tbm_drm_helper_set_fd(bufmgr_dumb->fd); } ret = drmGetCap(bufmgr_dumb->fd, DRM_CAP_DUMB_BUFFER, &cap); if (ret || cap == 0) { - TBM_DUMB_LOG("error: drm buffer isn't supported !\n"); + TBM_DUMB_ERROR("drm buffer isn't supported !\n"); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; goto fail_get_cap; } - //Create Hash Table - bufmgr_dumb->hashBos = drmHashCreate(); - //Check if the tbm manager supports dma fence or not. fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY); if (fp != -1) { @@ -1427,35 +1548,65 @@ init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd) close(fp); } - bufmgr_backend = tbm_backend_alloc(); - if (!bufmgr_backend) { - TBM_DUMB_LOG("error: Fail to create drm!\n"); - goto fail_alloc_backend; + /*Create Hash Table*/ + bufmgr_dumb->hashBos = drmHashCreate(); + + /* alloc and register bufmgr_funcs */ + bufmgr_func = tbm_backend_bufmgr_alloc_bufmgr_func(bufmgr, &err); + if (!bufmgr_func) { + TBM_DUMB_ERROR("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_dumb_bufmgr_get_capabilities; + //if (tbm_backend_bufmgr_query_display_server(bufmgr, &err) && !_check_render_node()) + bufmgr_func->bufmgr_bind_native_display = tbm_dumb_bufmgr_bind_native_display; + bufmgr_func->bufmgr_get_supported_formats = tbm_dumb_bufmgr_get_supported_formats; + bufmgr_func->bufmgr_get_plane_data = tbm_dumb_bufmgr_get_plane_data; + bufmgr_func->bufmgr_alloc_bo = tbm_dumb_bufmgr_alloc_bo; + bufmgr_func->bufmgr_alloc_bo_with_format = NULL; + bufmgr_func->bufmgr_import_fd = tbm_dumb_bufmgr_import_fd; + bufmgr_func->bufmgr_import_key = tbm_dumb_bufmgr_import_key; + + err = tbm_backend_bufmgr_register_bufmgr_func(bufmgr, bufmgr_func); + if (err != TBM_ERROR_NONE) { + TBM_DUMB_ERROR("fail to register bufmgr_func! err(%d)\n", err); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + goto fail_register_bufmgr_func; + } + bufmgr_dumb->bufmgr_func = bufmgr_func; + + /* alloc and register bo_funcs */ + bo_func = tbm_backend_bufmgr_alloc_bo_func(bufmgr, &err); + if (!bo_func) { + TBM_DUMB_ERROR("fail to alloc bo_func! err(%d)\n", err); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + goto fail_alloc_bo_func; } - bufmgr_backend->priv = (void *)bufmgr_dumb; - bufmgr_backend->bufmgr_deinit = tbm_dumb_bufmgr_deinit, - bufmgr_backend->bo_size = tbm_dumb_bo_size, - bufmgr_backend->bo_alloc = tbm_dumb_bo_alloc, - bufmgr_backend->bo_free = tbm_dumb_bo_free, - bufmgr_backend->bo_import = tbm_dumb_bo_import, - bufmgr_backend->bo_import_fd = tbm_dumb_bo_import_fd, - bufmgr_backend->bo_export = tbm_dumb_bo_export, - bufmgr_backend->bo_export_fd = tbm_dumb_bo_export_fd, - bufmgr_backend->bo_get_handle = tbm_dumb_bo_get_handle, - bufmgr_backend->bo_map = tbm_dumb_bo_map, - bufmgr_backend->bo_unmap = tbm_dumb_bo_unmap, - bufmgr_backend->surface_get_plane_data = tbm_dumb_surface_get_plane_data; - bufmgr_backend->surface_supported_format = tbm_dumb_surface_supported_format; - bufmgr_backend->bo_get_flags = tbm_dumb_bo_get_flags; - bufmgr_backend->bo_lock = tbm_dumb_bo_lock; - bufmgr_backend->bo_unlock = tbm_dumb_bo_unlock; - bufmgr_backend->bufmgr_bind_native_display = tbm_dumb_bufmgr_bind_native_display; - - if (!tbm_backend_init(bufmgr, bufmgr_backend)) { - TBM_DUMB_LOG("error: Fail to init backend!\n"); - goto fail_init_backend; + bo_func->bo_free = tbm_dumb_bo_free; + bo_func->bo_get_size = tbm_dumb_bo_get_size; + bo_func->bo_get_memory_types = tbm_dumb_bo_get_memory_type; + bo_func->bo_get_handle = tbm_dumb_bo_get_handle; + bo_func->bo_map = tbm_dumb_bo_map; + bo_func->bo_unmap = tbm_dumb_bo_unmap; + bo_func->bo_lock = tbm_dumb_bo_lock; + bo_func->bo_unlock = tbm_dumb_bo_unlock; + bo_func->bo_export_fd = tbm_dumb_bo_export_fd; + bo_func->bo_export_key = tbm_dumb_bo_export_key; + + err = tbm_backend_bufmgr_register_bo_func(bufmgr, bo_func); + if (err != TBM_ERROR_NONE) { + TBM_DUMB_ERROR("fail to register bo_func! err(%d)\n", err); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + goto fail_register_bo_func; } + bufmgr_dumb->bo_func = bo_func; #ifdef DEBUG { @@ -1463,36 +1614,51 @@ init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd) env = getenv("TBM_DUMB_DEBUG"); if (env) { bDebug = atoi(env); - TBM_DUMB_LOG("TBM_DUMB_DEBUG=%s\n", env); + TBM_DUMB_ERROR("TBM_DUMB_DEBUG=%s\n", env); } else bDebug = 0; } #endif - DBG("[%s] DMABUF FENCE is %s\n", target_name(), - bufmgr_dumb->use_dma_fence ? "supported!" : "NOT supported!"); + TBM_DUMB_DEBUG("DMABUF FENCE is %s\n", bufmgr_dumb->use_dma_fence ? "supported!" : "NOT supported!"); + TBM_DUMB_DEBUG("drm_fd:%d\n", bufmgr_dumb->fd); - DBG("[%s] drm_fd:%d\n", target_name(), bufmgr_dumb->fd); + if (error) + *error = TBM_ERROR_NONE; - return 1; + bufmgr_dumb->bufmgr = bufmgr; + + return (tbm_backend_bufmgr_data *)bufmgr_dumb; -fail_init_backend: - tbm_backend_free(bufmgr_backend); -fail_alloc_backend: +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: if (bufmgr_dumb->hashBos) drmHashDestroy(bufmgr_dumb->hashBos); if (bufmgr_dumb->device_name) free(bufmgr_dumb->device_name); fail_get_cap: fail_get_device_name: - if (tbm_backend_is_display_server()) + if (tbm_backend_bufmgr_query_display_server(bufmgr, &err)) tbm_drm_helper_unset_tbm_master_fd(); + else + tbm_drm_helper_unset_fd(); if (bufmgr_dumb->fd >= 0) close(bufmgr_dumb->fd); fail_get_auth_info: fail_open_drm: free(bufmgr_dumb); - return 0; + return NULL; } +tbm_backend_module tbm_backend_module_data = { + "dumb", + "Samsung", + TBM_BACKEND_ABI_VERSION_2_0, + tbm_dumb_init, + tbm_dumb_deinit +}; |