From f91de75f40bb178cf96d18991d4eb5b094c97c61 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 19 Mar 2018 15:00:52 +0900 Subject: [PATCH] make the new backend inteface with tbm_backend.h Change-Id: I45391fe3aaf90967502057d80140cde6db9a00c4 --- src/tbm_bufmgr_vc4.c | 828 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 487 insertions(+), 341 deletions(-) diff --git a/src/tbm_bufmgr_vc4.c b/src/tbm_bufmgr_vc4.c index 22209a6..8601f2f 100644 --- a/src/tbm_bufmgr_vc4.c +++ b/src/tbm_bufmgr_vc4.c @@ -32,6 +32,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include + #include #include #include @@ -44,16 +46,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include -#include -#include #include #include -#include -#include +#include #include - -#include - #include "tbm_bufmgr_tgl.h" #define DEBUG @@ -69,25 +65,24 @@ static int bDebug; char *target_name() { - FILE *f; - char *slash; + static char app_name[128] = {0, }; static int initialized = 0; - static char app_name[128]; + char *slash; + 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); @@ -108,6 +103,8 @@ char *target_name() #define TBM_VC4_DEBUG(...) #endif +#define STRERR_BUFSIZE 128 + #define SIZE_ALIGN(value, base) (((value) + ((base) - 1)) & ~((base) - 1)) #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -225,6 +222,8 @@ struct _tbm_bo_vc4 { tbm_bo_cache_state cache_state; unsigned int map_cnt; int last_map_device; + + tbm_bufmgr_vc4 bufmgr_vc4; }; /* tbm bufmgr private for vc4 */ @@ -239,6 +238,11 @@ struct _tbm_bufmgr_vc4 { char *device_name; void *bind_display; + + tbm_backend_bufmgr_func *bufmgr_func; + tbm_backend_bo_func *bo_func; + + tbm_bufmgr bufmgr; }; char *STR_DEVICE[] = { @@ -271,10 +275,12 @@ _tgl_get_version(int fd) { struct tgl_ver_data data; int err; + char buf[STRERR_BUFSIZE]; err = ioctl(fd, TGL_IOCTL_GET_VERSION, &data); if (err) { - TBM_VC4_ERROR("error(%s) %s:%d\n", strerror(errno)); + TBM_VC4_ERROR("error(%s) %s:%d\n", + strerror_r(errno, buf, STRERR_BUFSIZE)); return 0; } @@ -289,13 +295,15 @@ _tgl_init(int fd, unsigned int key) { struct tgl_reg_data data; int err; + char buf[STRERR_BUFSIZE]; data.key = key; data.timeout_ms = 1000; err = ioctl(fd, TGL_IOCTL_REGISTER, &data); if (err) { - TBM_VC4_ERROR("error(%s) key:%d\n", strerror(errno), key); + TBM_VC4_ERROR("error(%s) key:%d\n", + strerror_r(errno, buf, STRERR_BUFSIZE), key); return 0; } @@ -307,11 +315,13 @@ _tgl_destroy(int fd, unsigned int key) { struct tgl_reg_data data; int err; + char buf[STRERR_BUFSIZE]; data.key = key; err = ioctl(fd, TGL_IOCTL_UNREGISTER, &data); if (err) { - TBM_VC4_ERROR("error(%s) key:%d\n", strerror(errno), key); + TBM_VC4_ERROR("error(%s) key:%d\n", + strerror_r(errno, buf, STRERR_BUFSIZE), key); return 0; } @@ -324,6 +334,7 @@ _tgl_lock(int fd, unsigned int key, int opt) struct tgl_lock_data data; enum tgl_type_data tgl_type; int err; + char buf[STRERR_BUFSIZE]; switch (opt) { case TBM_OPTION_READ: @@ -343,7 +354,7 @@ _tgl_lock(int fd, unsigned int key, int opt) err = ioctl(fd, TGL_IOCTL_LOCK, &data); if (err) { TBM_VC4_ERROR("error(%s) key:%d opt:%d\n", - strerror(errno), key, opt); + strerror_r(errno, buf, STRERR_BUFSIZE), key, opt); return 0; } @@ -355,6 +366,7 @@ _tgl_unlock(int fd, unsigned int key) { struct tgl_lock_data data; int err; + char buf[STRERR_BUFSIZE]; data.key = key; data.type = TGL_TYPE_NONE; @@ -362,7 +374,7 @@ _tgl_unlock(int fd, unsigned int key) err = ioctl(fd, TGL_IOCTL_UNLOCK, &data); if (err) { TBM_VC4_ERROR("error(%s) key:%d\n", - strerror(errno), key); + strerror_r(errno, buf, STRERR_BUFSIZE), key); return 0; } @@ -374,6 +386,7 @@ _tgl_set_data(int fd, unsigned int key, unsigned int val) { struct tgl_usr_data data; int err; + char buf[STRERR_BUFSIZE]; data.key = key; data.data1 = val; @@ -381,7 +394,7 @@ _tgl_set_data(int fd, unsigned int key, unsigned int val) err = ioctl(fd, TGL_IOCTL_SET_DATA, &data); if (err) { TBM_VC4_ERROR("error(%s) key:%d\n", - strerror(errno), key); + strerror_r(errno, buf, STRERR_BUFSIZE), key); return 0; } @@ -393,13 +406,14 @@ _tgl_get_data(int fd, unsigned int key) { struct tgl_usr_data data = { 0, }; int err; + char buf[STRERR_BUFSIZE]; data.key = key; err = ioctl(fd, TGL_IOCTL_GET_DATA, &data); if (err) { TBM_VC4_ERROR("error(%s) key:%d\n", - strerror(errno), key); + strerror_r(errno, buf, STRERR_BUFSIZE), key); return 0; } @@ -497,7 +511,7 @@ _bo_set_cache_state(tbm_bufmgr_vc4 bufmgr_vc4, tbm_bo_vc4 bo_vc4, int device, in char need_flush = 0; unsigned short cntFlush = 0; - /* get cache state of a bo */ + /* get cache state of a bo_vc4 */ bo_vc4->cache_state.val = _tgl_get_data(bufmgr_vc4->tgl_fd, bo_vc4->name); @@ -726,7 +740,7 @@ _tbm_vc4_open_drm() } static int -_check_render_node(void) //TODO +_check_render_node(void) { #ifndef USE_RENDER_NODE return 0; @@ -778,7 +792,7 @@ _check_render_node(void) //TODO } static int -_get_render_node(void)//TODO +_get_render_node(void) { struct udev *udev = NULL; struct udev_enumerate *e = NULL; @@ -880,11 +894,12 @@ _vc4_bo_handle(tbm_bo_vc4 bo_vc4, int device) break; case TBM_DEVICE_CPU: if (!bo_vc4->pBase) { - void *map = NULL; struct drm_vc4_mmap_bo arg = {0, }; + void *map = NULL; + arg.handle = bo_vc4->gem; if (drmIoctl(bo_vc4->fd, DRM_IOCTL_VC4_MMAP_BO, &arg)) { - TBM_VC4_ERROR("Cannot map_dumb gem=%d\n", bo_vc4->gem); + TBM_VC4_ERROR("Cannot map_vc4 gem=%d\n", bo_vc4->gem); return (tbm_bo_handle) NULL; } @@ -943,43 +958,55 @@ _vc4_bo_handle(tbm_bo_vc4 bo_vc4, int device) } static int -tbm_vc4_bo_size(tbm_bo bo) +tbm_vc4_bo_get_size(tbm_backend_bo_data *bo_data, tbm_error_e *error) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, 0); + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; - tbm_bo_vc4 bo_vc4; + if (!bo_vc4) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return 0; + } - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bo_vc4 != NULL, 0); + if (error) + *error = TBM_ERROR_NONE; return bo_vc4->size; } -static void * -tbm_vc4_bo_alloc(tbm_bo bo, int size, int flags) +static tbm_backend_bo_data * +tbm_vc4_bufmgr_alloc_bo(tbm_backend_bufmgr_data *bufmgr_data, int size, tbm_bo_memory_type flags, tbm_error_e *error) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, 0); - + tbm_bufmgr_vc4 bufmgr_vc4 = (tbm_bufmgr_vc4)bufmgr_data; tbm_bo_vc4 bo_vc4; - tbm_bufmgr_vc4 bufmgr_vc4; - bufmgr_vc4 = (tbm_bufmgr_vc4)tbm_backend_get_bufmgr_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != NULL, 0); + if (bufmgr_vc4 == NULL) { + TBM_VC4_ERROR("bufmgr_data is null\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } bo_vc4 = calloc(1, sizeof(struct _tbm_bo_vc4)); if (!bo_vc4) { - TBM_VC4_ERROR("fail to allocate the bo private\n"); - return 0; + TBM_VC4_ERROR("fail to allocate the bo_vc4 private\n"); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + return NULL; } + bo_vc4->bufmgr_vc4 = bufmgr_vc4; struct drm_vc4_create_bo arg = {0, }; - arg.flags = flags;/*currently no values for the flags,but it may be used in future extension*/ + arg.size = (__u32)size; + arg.flags = flags;/*currently no values for the flags,but it may be used in future extension*/ if (drmIoctl(bufmgr_vc4->fd, DRM_IOCTL_VC4_CREATE_BO, &arg)) { - TBM_VC4_ERROR("Cannot create bo(flag:%x, size:%d)\n", arg.flags, + TBM_VC4_ERROR("Cannot create bo_vc4(flag:%x, size:%d)\n", arg.flags, (unsigned int)arg.size); free(bo_vc4); - return 0; + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } bo_vc4->fd = bufmgr_vc4->fd; @@ -991,64 +1018,69 @@ tbm_vc4_bo_alloc(tbm_bo bo, int size, int flags) if (!_bo_init_cache_state(bufmgr_vc4, bo_vc4, 0)) { TBM_VC4_ERROR("fail init cache state(%d)\n", bo_vc4->name); free(bo_vc4); - return 0; + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } pthread_mutex_init(&bo_vc4->mutex, NULL); - if (bufmgr_vc4->use_dma_fence - && !bo_vc4->dmabuf) { + if (bufmgr_vc4->use_dma_fence && !bo_vc4->dmabuf) { struct drm_prime_handle arg = {0, }; arg.handle = bo_vc4->gem; if (drmIoctl(bo_vc4->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) { TBM_VC4_ERROR("Cannot dmabuf=%d\n", bo_vc4->gem); free(bo_vc4); - return 0; + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } bo_vc4->dmabuf = arg.fd; } - /* add bo to hash */ - if (drmHashInsert(bufmgr_vc4->hashBos, bo_vc4->name, - (void *)bo_vc4) < 0) { - TBM_VC4_ERROR("Cannot insert bo to Hash(%d)\n", bo_vc4->name); - } + /* add bo_vc4 to hash */ + if (drmHashInsert(bufmgr_vc4->hashBos, bo_vc4->name, (void *)bo_vc4) < 0) + TBM_VC4_ERROR("Cannot insert bo_vc4 to Hash(%d)\n", bo_vc4->name); - TBM_VC4_DEBUG(" bo:%p, gem:%d(%d), flags:%d, size:%d\n", - bo, - bo_vc4->gem, bo_vc4->name, - flags, - bo_vc4->size); + TBM_VC4_DEBUG(" bo_vc4:%p, gem:%d(%d), flags:%d(%d), size:%d\n", + bo_vc4, + bo_vc4->gem, bo_vc4->name, + bo_vc4->flags_tbm, + bo_vc4->size); + + if (error) + *error = TBM_ERROR_NONE; - return (void *)bo_vc4; + return (tbm_backend_bo_data *)bo_vc4; } static void -tbm_vc4_bo_free(tbm_bo bo) +tbm_vc4_bo_free(tbm_backend_bo_data *bo_data) { - tbm_bo_vc4 bo_vc4, temp; + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; + tbm_bo_vc4 temp; tbm_bufmgr_vc4 bufmgr_vc4; + char buf[STRERR_BUFSIZE]; + int ret; - if (!bo) + if (!bo_data) return; - bufmgr_vc4 = (tbm_bufmgr_vc4)tbm_backend_get_bufmgr_priv(bo); - VC4_RETURN_IF_FAIL(bufmgr_vc4 != NULL); - - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_IF_FAIL(bo_vc4 != NULL); + bufmgr_vc4 = bo_vc4->bufmgr_vc4; + if (!bufmgr_vc4) + return; - TBM_VC4_DEBUG(" bo:%p, gem:%d(%d), fd:%d, size:%d\n", - bo, + TBM_VC4_DEBUG(" bo_vc4:%p, gem:%d(%d), fd:%d, size:%d\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf, bo_vc4->size); if (bo_vc4->pBase) { if (munmap(bo_vc4->pBase, bo_vc4->size) == -1) { - TBM_VC4_ERROR("bo:%p fail to munmap(%s)\n", - bo, strerror(errno)); + TBM_VC4_ERROR("bo_vc4:%p fail to munmap(%s)\n", + bo_vc4, strerror_r(errno, buf, STRERR_BUFSIZE)); } } @@ -1058,17 +1090,12 @@ tbm_vc4_bo_free(tbm_bo bo) bo_vc4->dmabuf = 0; } - /* delete bo from hash */ - int ret; - - ret = drmHashLookup(bufmgr_vc4->hashBos, bo_vc4->name, - (void **)&temp); - if (ret == 0) { + /* delete bo_vc4 from hash */ + ret = drmHashLookup(bufmgr_vc4->hashBos, bo_vc4->name, (void **)&temp); + if (ret == 0) drmHashDelete(bufmgr_vc4->hashBos, bo_vc4->name); - } else { - TBM_VC4_ERROR("Cannot find bo to Hash(%d), ret=%d\n", - bo_vc4->name, ret); - } + else + TBM_VC4_ERROR("Cannot find bo_vc4 to Hash(%d), ret=%d\n", bo_vc4->name, ret); if (temp != bo_vc4) TBM_VC4_ERROR("hashBos probably has several BOs with same name!!!\n"); @@ -1080,43 +1107,50 @@ tbm_vc4_bo_free(tbm_bo bo) memset(&arg, 0, sizeof(arg)); arg.handle = bo_vc4->gem; - if (drmIoctl(bo_vc4->fd, DRM_IOCTL_GEM_CLOSE, &arg)) { - TBM_VC4_ERROR("bo:%p fail to gem close.(%s)\n", - bo, strerror(errno)); - } + if (drmIoctl(bo_vc4->fd, DRM_IOCTL_GEM_CLOSE, &arg)) + TBM_VC4_ERROR("bo_vc4:%p fail to gem close.(%s)\n", + bo_vc4, strerror_r(errno, buf, STRERR_BUFSIZE)); free(bo_vc4); } - -static void * -tbm_vc4_bo_import(tbm_bo bo, unsigned int key) +static tbm_backend_bo_data * +tbm_vc4_bufmgr_import_key(tbm_backend_bufmgr_data *bufmgr_data, tbm_key key, tbm_error_e *error) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, 0); - - tbm_bufmgr_vc4 bufmgr_vc4; + tbm_bufmgr_vc4 bufmgr_vc4 = (tbm_bufmgr_vc4)bufmgr_data; tbm_bo_vc4 bo_vc4; int ret; - bufmgr_vc4 = (tbm_bufmgr_vc4)tbm_backend_get_bufmgr_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != NULL, 0); + if (bufmgr_vc4 == NULL) { + TBM_VC4_ERROR("bufmgr_data is null\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } ret = drmHashLookup(bufmgr_vc4->hashBos, key, (void **)&bo_vc4); - if (ret == 0) - return bo_vc4; + if (ret == 0) { + if (error) + *error = TBM_ERROR_NONE; + return (tbm_backend_bo_data *)bo_vc4; + } struct drm_gem_open arg = {0, }; arg.name = key; if (drmIoctl(bufmgr_vc4->fd, DRM_IOCTL_GEM_OPEN, &arg)) { TBM_VC4_ERROR("Cannot open gem name=%d\n", key); - return 0; + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } bo_vc4 = calloc(1, sizeof(struct _tbm_bo_vc4)); if (!bo_vc4) { - TBM_VC4_ERROR("fail to allocate the bo private\n"); - return 0; + TBM_VC4_ERROR("fail to allocate the bo_vc4 private\n"); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + return NULL; } bo_vc4->fd = bufmgr_vc4->fd; @@ -1128,7 +1162,9 @@ tbm_vc4_bo_import(tbm_bo bo, unsigned int key) if (!_bo_init_cache_state(bufmgr_vc4, bo_vc4, 1)) { TBM_VC4_ERROR("fail init cache state(%d)\n", bo_vc4->name); free(bo_vc4); - return 0; + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } if (!bo_vc4->dmabuf) { @@ -1137,92 +1173,110 @@ tbm_vc4_bo_import(tbm_bo bo, unsigned int key) arg.handle = bo_vc4->gem; if (drmIoctl(bo_vc4->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg)) { TBM_VC4_ERROR("fail to DRM_IOCTL_PRIME_HANDLE_TO_FD gem=%d\n", bo_vc4->gem); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; free(bo_vc4); - return 0; + return NULL; } bo_vc4->dmabuf = arg.fd; } - /* add bo to hash */ - if (drmHashInsert(bufmgr_vc4->hashBos, bo_vc4->name, - (void *)bo_vc4) < 0) { - TBM_VC4_ERROR("Cannot insert bo to Hash(%d)\n", bo_vc4->name); - } + /* add bo_vc4 to hash */ + if (drmHashInsert(bufmgr_vc4->hashBos, bo_vc4->name, (void *)bo_vc4) < 0) + TBM_VC4_ERROR("Cannot insert bo_vc4 to Hash(%d)\n", bo_vc4->name); - TBM_VC4_DEBUG(" bo:%p, gem:%d(%d), fd:%d, flags:%d, size:%d\n", - bo, + TBM_VC4_DEBUG(" bo_vc4:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf, bo_vc4->flags_tbm, bo_vc4->size); - return (void *)bo_vc4; + if (error) + *error = TBM_ERROR_NONE; + + return (tbm_backend_bo_data *)bo_vc4; } -static void * -tbm_vc4_bo_import_fd(tbm_bo bo, tbm_fd key) +static tbm_backend_bo_data * +tbm_vc4_bufmgr_import_fd(tbm_backend_bufmgr_data *bufmgr_data, tbm_fd key, tbm_error_e *error) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, 0); - - tbm_bufmgr_vc4 bufmgr_vc4; + tbm_bufmgr_vc4 bufmgr_vc4 = (tbm_bufmgr_vc4)bufmgr_data; tbm_bo_vc4 bo_vc4; + unsigned int gem = 0; unsigned int name; int ret; + char buf[STRERR_BUFSIZE]; - bufmgr_vc4 = (tbm_bufmgr_vc4)tbm_backend_get_bufmgr_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != NULL, 0); + if (bufmgr_vc4 == NULL) { + TBM_VC4_ERROR("bufmgr_data is null\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } /*getting handle from fd*/ - unsigned int gem = 0; struct drm_prime_handle arg = {0, }; arg.fd = key; arg.flags = 0; if (drmIoctl(bufmgr_vc4->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg)) { - TBM_VC4_ERROR("bo:%p Cannot get gem handle from fd:%d (%s)\n", - bo, arg.fd, strerror(errno)); + TBM_VC4_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; name = _get_name(bufmgr_vc4->fd, gem); if (!name) { - TBM_VC4_ERROR("bo:%p Cannot get name from gem:%d, fd:%d (%s)\n", - bo, gem, key, strerror(errno)); - return 0; + TBM_VC4_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_vc4->hashBos, name, (void **)&bo_vc4); if (ret == 0) { - if (gem == bo_vc4->gem) + if (gem == bo_vc4->gem) { + if (error) + *error = TBM_ERROR_NONE; return bo_vc4; + } } - unsigned int real_size = -1; - - /* Determine size of bo. The fd-to-handle ioctl really should + /* Determine size of bo_vc4. 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); - + unsigned int real_size = -1; struct drm_gem_open open_arg = {0, }; + real_size = lseek(key, 0, SEEK_END); + open_arg.name = name; if (drmIoctl(bufmgr_vc4->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) { - TBM_VC4_ERROR("Cannot open gem name=%d\n", name); - return 0; + TBM_VC4_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 close_arg = {0, }; memset(&close_arg, 0, sizeof(close_arg)); close_arg.handle = open_arg.handle; if (drmIoctl(bufmgr_vc4->fd, DRM_IOCTL_GEM_CLOSE, &close_arg)) { - TBM_VC4_ERROR("Cannot close gem_handle (%d)\n", open_arg.handle, - strerror(errno)); - return 0; + TBM_VC4_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) @@ -1230,9 +1284,12 @@ tbm_vc4_bo_import_fd(tbm_bo bo, tbm_fd key) bo_vc4 = calloc(1, sizeof(struct _tbm_bo_vc4)); if (!bo_vc4) { - TBM_VC4_ERROR("bo:%p fail to allocate the bo private\n", bo); - return 0; + TBM_VC4_ERROR("bo_vc4:%p fail to allocate the bo_vc4\n", bo_vc4); + if (error) + *error = TBM_ERROR_OUT_OF_MEMORY; + return NULL; } + bo_vc4->bufmgr_vc4 = bufmgr_vc4; bo_vc4->fd = bufmgr_vc4->fd; bo_vc4->gem = gem; @@ -1243,78 +1300,91 @@ tbm_vc4_bo_import_fd(tbm_bo bo, tbm_fd key) if (!_bo_init_cache_state(bufmgr_vc4, bo_vc4, 1)) { TBM_VC4_ERROR("fail init cache state(%d)\n", bo_vc4->name); free(bo_vc4); - return 0; + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + return NULL; } - /* add bo to hash */ - if (drmHashInsert(bufmgr_vc4->hashBos, bo_vc4->name, - (void *)bo_vc4) < 0) { - TBM_VC4_ERROR("bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n", - bo, bo_vc4->name, gem, key); - } + /* add bo_vc4 to hash */ + if (drmHashInsert(bufmgr_vc4->hashBos, bo_vc4->name, (void *)bo_vc4) < 0) + TBM_VC4_ERROR("bo_vc4:%p Cannot insert bo_vc4 to Hash(%d) from gem:%d, fd:%d\n", + bo_vc4, bo_vc4->name, gem, key); - TBM_VC4_DEBUG(" bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d, size:%d\n", - bo, + TBM_VC4_DEBUG(" bo_vc4:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d, size:%d\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf, key, bo_vc4->flags_tbm, bo_vc4->size); - return (void *)bo_vc4; + if (error) + *error = TBM_ERROR_NONE; + + return (tbm_backend_bo_data *)bo_vc4; } -static unsigned int -tbm_vc4_bo_export(tbm_bo bo) +static tbm_key +tbm_vc4_bo_export_key(tbm_backend_bo_data *bo_data, tbm_error_e *error) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, 0); + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; - tbm_bo_vc4 bo_vc4; - - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bo_vc4 != NULL, 0); + if (!bo_vc4) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return 0; + } if (!bo_vc4->name) { bo_vc4->name = _get_name(bo_vc4->fd, bo_vc4->gem); if (!bo_vc4->name) { - TBM_VC4_ERROR("Cannot get name\n"); + TBM_VC4_ERROR("error Cannot get name\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; return 0; } } - TBM_VC4_DEBUG(" bo:%p, gem:%d(%d), fd:%d, flags:%d, size:%d\n", - bo, + TBM_VC4_DEBUG(" bo_vc4:%p, gem:%d(%d), fd:%d, flags:%d, size:%d\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf, bo_vc4->flags_tbm, bo_vc4->size); - return (unsigned int)bo_vc4->name; + if (error) + *error = TBM_ERROR_NONE; + + return (tbm_key)bo_vc4->name; } -tbm_fd -tbm_vc4_bo_export_fd(tbm_bo bo) +static tbm_fd +tbm_vc4_bo_export_fd(tbm_backend_bo_data *bo_data, tbm_error_e *error) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, -1); - - tbm_bo_vc4 bo_vc4; + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; int ret; + char buf[STRERR_BUFSIZE]; - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bo_vc4 != NULL, -1); + if (!bo_vc4) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return -1; + } struct drm_prime_handle arg = {0, }; arg.handle = bo_vc4->gem; ret = drmIoctl(bo_vc4->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg); if (ret) { - TBM_VC4_ERROR("bo:%p Cannot dmabuf=%d (%s)\n", - bo, bo_vc4->gem, strerror(errno)); + TBM_VC4_ERROR("bo_vc4:%p Cannot dmabuf=%d (%s)\n", + bo_vc4, bo_vc4->gem, strerror_r(errno, buf, STRERR_BUFSIZE)); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; return (tbm_fd) ret; } - TBM_VC4_DEBUG(" bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d, size:%d\n", - bo, + TBM_VC4_DEBUG(" bo_vc4:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d, size:%d\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf, arg.fd, @@ -1325,23 +1395,26 @@ tbm_vc4_bo_export_fd(tbm_bo bo) } static tbm_bo_handle -tbm_vc4_bo_get_handle(tbm_bo bo, int device) +tbm_vc4_bo_get_handle(tbm_backend_bo_data *bo_data, tbm_bo_device_type device, tbm_error_e *error) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL); - + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; tbm_bo_handle bo_handle; - tbm_bo_vc4 bo_vc4; - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bo_vc4 != NULL, (tbm_bo_handle) NULL); + if (!bo_vc4) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return (tbm_bo_handle) NULL; + } if (!bo_vc4->gem) { TBM_VC4_ERROR("Cannot map gem=%d\n", bo_vc4->gem); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; return (tbm_bo_handle) NULL; } - TBM_VC4_DEBUG("bo:%p, gem:%d(%d), fd:%d, flags:%d, size:%d, %s\n", - bo, + TBM_VC4_DEBUG("bo_vc4:%p, gem:%d(%d), fd:%d, flags:%d, size:%d, %s\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf, bo_vc4->flags_tbm, @@ -1353,34 +1426,47 @@ tbm_vc4_bo_get_handle(tbm_bo bo, int device) if (bo_handle.ptr == NULL) { TBM_VC4_ERROR("Cannot get handle: gem:%d, device:%d\n", bo_vc4->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_vc4_bo_map(tbm_bo bo, int device, int opt) +tbm_vc4_bo_map(tbm_backend_bo_data *bo_data, tbm_bo_device_type device, + tbm_bo_access_option opt, tbm_error_e *error) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, (tbm_bo_handle) NULL); - + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; tbm_bo_handle bo_handle; - tbm_bo_vc4 bo_vc4; tbm_bufmgr_vc4 bufmgr_vc4; - bufmgr_vc4 = (tbm_bufmgr_vc4)tbm_backend_get_bufmgr_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != NULL, (tbm_bo_handle)NULL); + if (!bo_vc4) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return (tbm_bo_handle) NULL; + } - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bo_vc4 != NULL, (tbm_bo_handle) NULL); + bufmgr_vc4 = bo_vc4->bufmgr_vc4; + if (!bufmgr_vc4) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return (tbm_bo_handle) NULL; + } if (!bo_vc4->gem) { TBM_VC4_ERROR("Cannot map gem=%d\n", bo_vc4->gem); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; return (tbm_bo_handle) NULL; } - TBM_VC4_DEBUG(" bo:%p, gem:%d(%d), fd:%d, %s, %s\n", - bo, + TBM_VC4_DEBUG(" bo_vc4:%p, gem:%d(%d), fd:%d, %s, %s\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf, STR_DEVICE[device], @@ -1391,6 +1477,8 @@ tbm_vc4_bo_map(tbm_bo bo, int device, int opt) if (bo_handle.ptr == NULL) { TBM_VC4_ERROR("Cannot get handle: gem:%d, device:%d, opt:%d\n", bo_vc4->gem, device, opt); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; return (tbm_bo_handle) NULL; } @@ -1401,26 +1489,27 @@ tbm_vc4_bo_map(tbm_bo bo, int device, int opt) bo_vc4->map_cnt++; + if (error) + *error = TBM_ERROR_NONE; + return bo_handle; } -static int -tbm_vc4_bo_unmap(tbm_bo bo) +static tbm_error_e +tbm_vc4_bo_unmap(tbm_backend_bo_data *bo_data) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, 0); - - tbm_bo_vc4 bo_vc4; + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; tbm_bufmgr_vc4 bufmgr_vc4; - bufmgr_vc4 = (tbm_bufmgr_vc4)tbm_backend_get_bufmgr_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != NULL, 0); - - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bo_vc4 != NULL, 0); + if (!bo_vc4) + return TBM_ERROR_INVALID_PARAMETER; + bufmgr_vc4 = bo_vc4->bufmgr_vc4; + if (!bufmgr_vc4) + return TBM_ERROR_INVALID_PARAMETER; if (!bo_vc4->gem) - return 0; + return TBM_ERROR_INVALID_PARAMETER; bo_vc4->map_cnt--; @@ -1434,37 +1523,38 @@ tbm_vc4_bo_unmap(tbm_bo bo) bo_vc4->last_map_device = -1; - TBM_VC4_DEBUG(" bo:%p, gem:%d(%d), fd:%d\n", - bo, + TBM_VC4_DEBUG(" bo_vc4:%p, gem:%d(%d), fd:%d\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf); - return 1; + return TBM_ERROR_NONE; } -static int -tbm_vc4_bo_lock(tbm_bo bo, int device, int opt) +static tbm_error_e +tbm_vc4_bo_lock(tbm_backend_bo_data *bo_data, tbm_bo_device_type device, + tbm_bo_access_option opt) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, 0); - #ifndef ALWAYS_BACKEND_CTRL + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; tbm_bufmgr_vc4 bufmgr_vc4; - tbm_bo_vc4 bo_vc4; struct dma_buf_fence fence; struct flock filelock; int ret = 0; + char buf[STRERR_BUFSIZE]; + + if (!bo_vc4) + return TBM_ERROR_INVALID_PARAMETER; + + bufmgr_vc4 = bo_vc4->bufmgr_vc4; + if (!bufmgr_vc4) + return TBM_ERROR_INVALID_PARAMETER; if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU) { TBM_VC4_DEBUG("Not support device type,\n"); - return 0; + return TBM_ERROR_OPERATION_FAILED; } - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bo_vc4 != NULL, 0); - - bufmgr_vc4 = (tbm_bufmgr_vc4)tbm_backend_get_bufmgr_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != NULL, 0); - memset(&fence, 0, sizeof(struct dma_buf_fence)); /* Check if the given type is valid or not. */ @@ -1476,21 +1566,21 @@ tbm_vc4_bo_lock(tbm_bo bo, int device, int opt) fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA; } else { TBM_VC4_ERROR("Invalid argument\n"); - return 0; + return TBM_ERROR_INVALID_PARAMETER; } /* Check if the tbm manager supports dma fence or not. */ if (!bufmgr_vc4->use_dma_fence) { - TBM_VC4_ERROR("Not support DMA FENCE(%s)\n", strerror(errno)); - return 0; + TBM_VC4_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_vc4->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence); if (ret < 0) { - TBM_VC4_ERROR("Cannot set GET FENCE(%s)\n", strerror(errno)); - return 0; + TBM_VC4_ERROR("Cannot set GET FENCE(%s)\n", strerror_r(errno, buf, STRERR_BUFSIZE)); + return TBM_ERROR_OPERATION_FAILED; } } else { if (opt & TBM_OPTION_WRITE) @@ -1503,7 +1593,7 @@ tbm_vc4_bo_lock(tbm_bo bo, int device, int opt) filelock.l_len = 0; if (-1 == fcntl(bo_vc4->dmabuf, F_SETLKW, &filelock)) - return 0; + return TBM_ERROR_OPERATION_FAILED; } pthread_mutex_lock(&bo_vc4->mutex); @@ -1527,41 +1617,41 @@ tbm_vc4_bo_lock(tbm_bo bo, int device, int opt) pthread_mutex_unlock(&bo_vc4->mutex); - TBM_VC4_DEBUG("DMABUF_IOCTL_GET_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", - bo, + TBM_VC4_DEBUG("DMABUF_IOCTL_GET_FENCE! bo_vc4:%p, gem:%d(%d), fd:%ds\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf); #endif /* ALWAYS_BACKEND_CTRL */ - return 1; + return TBM_ERROR_NONE; } -static int -tbm_vc4_bo_unlock(tbm_bo bo) +static tbm_error_e +tbm_vc4_bo_unlock(tbm_backend_bo_data *bo_data) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, 0); - #ifndef ALWAYS_BACKEND_CTRL - tbm_bo_vc4 bo_vc4; + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; struct dma_buf_fence fence; struct flock filelock; unsigned int dma_type = 0; int ret = 0; + char buf[STRERR_BUFSIZE]; - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bo_vc4 != NULL, 0); + bufmgr_vc4 = bo_vc4->bufmgr_vc4; + if (!bufmgr_vc4) + return TBM_ERROR_INVALID_PARAMETER; if (bo_vc4->dma_fence[0].type & DMA_BUF_ACCESS_DMA) dma_type = 1; if (!bo_vc4->dma_fence[0].ctx && dma_type) { TBM_VC4_DEBUG("FENCE not support or ignored,\n"); - return 0; + return TBM_ERROR_OPERATION_FAILED; } if (!bo_vc4->dma_fence[0].ctx && dma_type) { TBM_VC4_DEBUG("device type is not 3D/CPU,\n"); - return 0; + return TBM_ERROR_OPERATION_FAILED; } pthread_mutex_lock(&bo_vc4->mutex); @@ -1578,13 +1668,14 @@ tbm_vc4_bo_unlock(tbm_bo bo) bo_vc4->dma_fence[DMA_FENCE_LIST_MAX - 1].type = 0; bo_vc4->dma_fence[DMA_FENCE_LIST_MAX - 1].ctx = 0; } + pthread_mutex_unlock(&bo_vc4->mutex); if (dma_type) { ret = ioctl(bo_vc4->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence); if (ret < 0) { - TBM_VC4_ERROR("Can not set PUT FENCE(%s)\n", strerror(errno)); - return 0; + TBM_VC4_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; @@ -1593,31 +1684,35 @@ tbm_vc4_bo_unlock(tbm_bo bo) filelock.l_len = 0; if (-1 == fcntl(bo_vc4->dmabuf, F_SETLKW, &filelock)) - return 0; + return TBM_ERROR_OPERATION_FAILED; } - TBM_VC4_DEBUG("DMABUF_IOCTL_PUT_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", - bo, + TBM_VC4_DEBUG("DMABUF_IOCTL_PUT_FENCE! bo_vc4:%p, gem:%d(%d), fd:%ds\n", + bo_vc4, bo_vc4->gem, bo_vc4->name, bo_vc4->dmabuf); #endif /* ALWAYS_BACKEND_CTRL */ - return 1; + return TBM_ERROR_NONE; } static void -tbm_vc4_bufmgr_deinit(void *priv) +tbm_vc4_deinit(tbm_backend_bufmgr_data *bufmgr_data) { - VC4_RETURN_IF_FAIL(priv != NULL); + tbm_bufmgr_vc4 bufmgr_vc4 = (tbm_bufmgr_vc4)bufmgr_data; + tbm_bufmgr bufmgr; + tbm_error_e error; + unsigned long key; + void *value; - tbm_bufmgr_vc4 bufmgr_vc4; + VC4_RETURN_IF_FAIL(bufmgr_vc4 != NULL); - bufmgr_vc4 = (tbm_bufmgr_vc4)priv; + bufmgr = bufmgr_vc4->bufmgr; - if (bufmgr_vc4->hashBos) { - unsigned long key; - void *value; + tbm_backend_bufmgr_free_bufmgr_func(bufmgr, bufmgr_vc4->bufmgr_func); + tbm_backend_bufmgr_free_bo_func(bufmgr, bufmgr_vc4->bo_func); + if (bufmgr_vc4->hashBos) { while (drmHashFirst(bufmgr_vc4->hashBos, &key, &value) > 0) { free(value); drmHashDelete(bufmgr_vc4->hashBos, key); @@ -1635,7 +1730,7 @@ tbm_vc4_bufmgr_deinit(void *priv) if (bufmgr_vc4->device_name) free(bufmgr_vc4->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(); @@ -1645,26 +1740,27 @@ tbm_vc4_bufmgr_deinit(void *priv) free(bufmgr_vc4); } -int -tbm_vc4_surface_supported_format(uint32_t **formats, uint32_t *num) +static tbm_error_e +tbm_vc4_bufmgr_get_supported_formats(tbm_backend_bufmgr_data *bufmgr_data, + uint32_t **formats, uint32_t *num) { - uint32_t *color_formats = NULL; + tbm_bufmgr_vc4 bufmgr_vc4 = (tbm_bufmgr_vc4)bufmgr_data; + uint32_t *color_formats; - color_formats = (uint32_t *)calloc(1, - sizeof(uint32_t) * TBM_COLOR_FORMAT_COUNT); + VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != 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_vc4_color_format_list, - sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT); + memcpy(color_formats, tbm_vc4_color_format_list, sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT); *formats = color_formats; *num = TBM_COLOR_FORMAT_COUNT; - TBM_VC4_DEBUG("tbm_vc4_surface_supported_format count = %d\n", *num); + TBM_VC4_DEBUG("supported format count = %d\n", *num); - return 1; + return TBM_ERROR_NONE; } static int @@ -1720,30 +1816,21 @@ _new_calc_uvplane_nv12(int width, int height) TBM_SURFACE_ALIGNMENT_PLANE_NV12); } -/** - * @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_vc4_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_vc4_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_vc4 bufmgr_vc4 = (tbm_bufmgr_vc4)bufmgr_data; int bpp; int _offset = 0; int _pitch = 0; int _size = 0; int _bo_idx = 0; + VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != NULL, TBM_ERROR_INVALID_PARAMETER); + switch (format) { /* 16 bpp RGB */ case TBM_FORMAT_XRGB4444: @@ -2009,73 +2096,88 @@ tbm_vc4_surface_get_plane_data(int width, int height, *pitch = _pitch; *bo_idx = _bo_idx; - return ret; + return TBM_ERROR_NONE; } -int -tbm_vc4_bo_get_flags(tbm_bo bo) +static tbm_bo_memory_type +tbm_vc4_bo_get_memory_type(tbm_backend_bo_data *bo_data, tbm_error_e *error) { - VC4_RETURN_VAL_IF_FAIL(bo != NULL, 0); + tbm_bo_vc4 bo_vc4 = (tbm_bo_vc4)bo_data; - tbm_bo_vc4 bo_vc4; + if (!bo_vc4) { + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return TBM_BO_DEFAULT; + } - bo_vc4 = (tbm_bo_vc4)tbm_backend_get_bo_priv(bo); - VC4_RETURN_VAL_IF_FAIL(bo_vc4 != NULL, 0); + if (error) + *error = TBM_ERROR_NONE; return bo_vc4->flags_tbm; } -int -tbm_vc4_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display) +static tbm_bufmgr_capability +tbm_vc4_bufmgr_get_capabilities(tbm_backend_bufmgr_data *bufmgr_data, tbm_error_e *error) { - tbm_bufmgr_vc4 bufmgr_vc4; + tbm_bufmgr_capability capabilities = TBM_BUFMGR_CAPABILITY_NONE; - bufmgr_vc4 = tbm_backend_get_priv_from_bufmgr(bufmgr); - VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != NULL, 0); + capabilities = TBM_BUFMGR_CAPABILITY_SHARE_KEY|TBM_BUFMGR_CAPABILITY_SHARE_FD; + + if (error) + *error = TBM_ERROR_NONE; + + return capabilities; +} + +static tbm_error_e +tbm_vc4_bufmgr_bind_native_display(tbm_backend_bufmgr_data *bufmgr_data, tbm_native_display *native_display) +{ + tbm_bufmgr_vc4 bufmgr_vc4 = (tbm_bufmgr_vc4)bufmgr_data; + VC4_RETURN_VAL_IF_FAIL(bufmgr_vc4 != NULL, TBM_ERROR_INVALID_PARAMETER); if (!tbm_drm_helper_wl_auth_server_init(native_display, bufmgr_vc4->fd, bufmgr_vc4->device_name, 0)) { TBM_VC4_ERROR("fail to tbm_drm_helper_wl_server_init\n"); - return 0; + return TBM_ERROR_OPERATION_FAILED; } bufmgr_vc4->bind_display = native_display; - return 1; + return TBM_ERROR_NONE; } -MODULEINITPPROTO(init_tbm_bufmgr_priv); - -static TBMModuleVersionInfo BcmVersRec = { - "vc42837", - "Broadcom", - TBM_ABI_VERSION, -}; - -TBMModuleData tbmModuleData = { &BcmVersRec, init_tbm_bufmgr_priv}; - -int -init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd) +static tbm_backend_bufmgr_data * +tbm_vc4_init(tbm_bufmgr bufmgr, tbm_error_e *error) { - tbm_bufmgr_backend bufmgr_backend; - tbm_bufmgr_vc4 bufmgr_vc4; + tbm_bufmgr_vc4 bufmgr_vc4 = NULL; + tbm_backend_bufmgr_func *bufmgr_func = NULL; + tbm_backend_bo_func *bo_func = NULL; int fp; + tbm_error_e err; - if (!bufmgr) - return 0; + if (!bufmgr) { + TBM_VC4_ERROR("bufmgr is null.\n"); + if (error) + *error = TBM_ERROR_INVALID_PARAMETER; + return NULL; + } bufmgr_vc4 = calloc(1, sizeof(struct _tbm_bufmgr_vc4)); if (!bufmgr_vc4) { TBM_VC4_ERROR("fail to alloc bufmgr_vc4!\n"); - return 0; + 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_vc4->fd = tbm_drm_helper_get_master_fd(); if (bufmgr_vc4->fd < 0) { bufmgr_vc4->fd = _tbm_vc4_open_drm(); if (bufmgr_vc4->fd < 0) { - TBM_VC4_ERROR("fail to open drm!\n", getpid()); + TBM_VC4_ERROR("fail to open drm!\n"); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; goto fail_open_drm; } } @@ -2084,9 +2186,10 @@ init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd) bufmgr_vc4->device_name = drmGetDeviceNameFromFd(bufmgr_vc4->fd); if (!bufmgr_vc4->device_name) { - TBM_VC4_ERROR("fail to get device name!\n", getpid()); - + TBM_VC4_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_vc4->fd); @@ -2095,15 +2198,18 @@ init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd) bufmgr_vc4->fd = _get_render_node();//TODO if (bufmgr_vc4->fd < 0) { TBM_VC4_ERROR("fail to get render node\n"); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; goto fail_get_render_node; } TBM_VC4_DEBUG("Use render node:%d\n", bufmgr_vc4->fd); } else { if (!tbm_drm_helper_get_auth_info(&(bufmgr_vc4->fd), &(bufmgr_vc4->device_name), NULL)) { TBM_VC4_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_vc4->fd); } } @@ -2128,37 +2234,62 @@ init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd) /*Create Hash Table*/ bufmgr_vc4->hashBos = drmHashCreate(); - bufmgr_backend = tbm_backend_alloc(); - if (!bufmgr_backend) { - TBM_VC4_ERROR("fail to alloc backend!\n"); - goto fail_alloc_backend; - } - - bufmgr_backend->priv = (void *)bufmgr_vc4; - bufmgr_backend->bufmgr_deinit = tbm_vc4_bufmgr_deinit; - bufmgr_backend->bo_size = tbm_vc4_bo_size; - bufmgr_backend->bo_alloc = tbm_vc4_bo_alloc; - bufmgr_backend->bo_free = tbm_vc4_bo_free; - bufmgr_backend->bo_import = tbm_vc4_bo_import; - bufmgr_backend->bo_import_fd = tbm_vc4_bo_import_fd; - bufmgr_backend->bo_export = tbm_vc4_bo_export; - bufmgr_backend->bo_export_fd = tbm_vc4_bo_export_fd; - bufmgr_backend->bo_get_handle = tbm_vc4_bo_get_handle; - bufmgr_backend->bo_map = tbm_vc4_bo_map; - bufmgr_backend->bo_unmap = tbm_vc4_bo_unmap; - bufmgr_backend->surface_get_plane_data = tbm_vc4_surface_get_plane_data; - bufmgr_backend->surface_supported_format = tbm_vc4_surface_supported_format; - bufmgr_backend->bo_get_flags = tbm_vc4_bo_get_flags; - bufmgr_backend->bo_lock = tbm_vc4_bo_lock; - bufmgr_backend->bo_unlock = tbm_vc4_bo_unlock; - - if (tbm_backend_is_display_server() && !_check_render_node()) - bufmgr_backend->bufmgr_bind_native_display = tbm_vc4_bufmgr_bind_native_display; - - if (!tbm_backend_init(bufmgr, bufmgr_backend)) { - TBM_VC4_ERROR("fail to init backend!\n"); - goto fail_init_backend; - } + /* alloc and register bufmgr_funcs */ + bufmgr_func = tbm_backend_bufmgr_alloc_bufmgr_func(bufmgr, &err); + if (!bufmgr_func) { + TBM_VC4_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_vc4_bufmgr_get_capabilities; + //if (tbm_backend_bufmgr_query_display_server(bufmgr, &err) && !_check_render_node()) + bufmgr_func->bufmgr_bind_native_display = tbm_vc4_bufmgr_bind_native_display; + bufmgr_func->bufmgr_get_supported_formats = tbm_vc4_bufmgr_get_supported_formats; + bufmgr_func->bufmgr_get_plane_data = tbm_vc4_bufmgr_get_plane_data; + bufmgr_func->bufmgr_alloc_bo = tbm_vc4_bufmgr_alloc_bo; + bufmgr_func->bufmgr_alloc_bo_with_format = NULL; + bufmgr_func->bufmgr_import_fd = tbm_vc4_bufmgr_import_fd; + bufmgr_func->bufmgr_import_key = tbm_vc4_bufmgr_import_key; + + err = tbm_backend_bufmgr_register_bufmgr_func(bufmgr, bufmgr_func); + if (err != TBM_ERROR_NONE) { + TBM_VC4_ERROR("fail to register bufmgr_func! err(%d)\n", err); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + goto fail_register_bufmgr_func; + } + bufmgr_vc4->bufmgr_func = bufmgr_func; + + /* alloc and register bo_funcs */ + bo_func = tbm_backend_bufmgr_alloc_bo_func(bufmgr, &err); + if (!bo_func) { + TBM_VC4_ERROR("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_vc4_bo_free; + bo_func->bo_get_size = tbm_vc4_bo_get_size; + bo_func->bo_get_memory_types = tbm_vc4_bo_get_memory_type; + bo_func->bo_get_handle = tbm_vc4_bo_get_handle; + bo_func->bo_map = tbm_vc4_bo_map; + bo_func->bo_unmap = tbm_vc4_bo_unmap; + bo_func->bo_lock = tbm_vc4_bo_lock; + bo_func->bo_unlock = tbm_vc4_bo_unlock; + bo_func->bo_export_fd = tbm_vc4_bo_export_fd; + bo_func->bo_export_key = tbm_vc4_bo_export_key; + + err = tbm_backend_bufmgr_register_bo_func(bufmgr, bo_func); + if (err != TBM_ERROR_NONE) { + TBM_VC4_ERROR("fail to register bo_func! err(%d)\n", err); + if (error) + *error = TBM_ERROR_OPERATION_FAILED; + goto fail_register_bo_func; + } + bufmgr_vc4->bo_func = bo_func; #ifdef DEBUG { @@ -2175,16 +2306,24 @@ init_tbm_bufmgr_priv(tbm_bufmgr bufmgr, int fd) TBM_VC4_DEBUG("drm_fd:%d\n", bufmgr_vc4->fd); - return 1; + if (error) + *error = TBM_ERROR_NONE; -fail_init_backend: - tbm_backend_free(bufmgr_backend); -fail_alloc_backend: + bufmgr_vc4->bufmgr = bufmgr; + + return (tbm_backend_bufmgr_data *)bufmgr_vc4; + +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: + _bufmgr_deinit_cache_state(bufmgr_vc4); if (bufmgr_vc4->hashBos) drmHashDestroy(bufmgr_vc4->hashBos); - _bufmgr_deinit_cache_state(bufmgr_vc4); fail_init_cache_state: - 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(); @@ -2194,6 +2333,13 @@ fail_get_auth_info: fail_get_render_node: fail_open_drm: free(bufmgr_vc4); - return 0; + return NULL; } +tbm_backend_module tbm_backend_module_data = { + "vc4", + "Samsung", + TBM_BACKEND_ABI_VERSION_2_0, + tbm_vc4_init, + tbm_vc4_deinit +}; -- 2.7.4