diff options
author | SooChan Lim <sc1.lim@samsung.com> | 2021-05-13 14:41:55 +0900 |
---|---|---|
committer | SooChan Lim <sc1.lim@samsung.com> | 2021-07-08 17:33:47 +0900 |
commit | c039634488fc97ce22511750fd6c21300e19c704 (patch) | |
tree | 8c89be94ac1fd23edb61f83d66a04accb2c107fe | |
parent | 4ad82dab477a26c9eb5eba3489a5c77770a06954 (diff) | |
download | libtbm-vc4-c039634488fc97ce22511750fd6c21300e19c704.tar.gz libtbm-vc4-c039634488fc97ce22511750fd6c21300e19c704.tar.bz2 libtbm-vc4-c039634488fc97ce22511750fd6c21300e19c704.zip |
implement the backend funtion for hal_tbm_surface.
Change-Id: I3866398d537d38f0225e83ee96f961222761354b
-rw-r--r-- | src/libhal-backend-tbm-vc4/tbm_backend_vc4.c | 226 |
1 files changed, 223 insertions, 3 deletions
diff --git a/src/libhal-backend-tbm-vc4/tbm_backend_vc4.c b/src/libhal-backend-tbm-vc4/tbm_backend_vc4.c index 7f45e83..f401a9b 100644 --- a/src/libhal-backend-tbm-vc4/tbm_backend_vc4.c +++ b/src/libhal-backend-tbm-vc4/tbm_backend_vc4.c @@ -1507,6 +1507,69 @@ static hal_tbm_surface * tbm_vc4_bufmgr_alloc_surface(hal_tbm_bufmgr *bufmgr, uint32_t width, uint32_t height, hal_tbm_format format, hal_tbm_bo_memory_type mem_types, uint64_t *modifiers, uint32_t num_modifiers, hal_tbm_error *error) { + tbm_vc4_bufmgr *bufmgr_data = (tbm_vc4_bufmgr *)bufmgr; + tbm_vc4_surface *surface_data; + tbm_vc4_bo *bo_data; + uint32_t size = 0, offset = 0, pitch = 0; + int bo_idx = 0, bo_size = 0; + int i, num_planes; + + if (bufmgr_data == NULL) { + TBM_BACKEND_ERR("bufmgr is null"); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + surface_data = _tbm_vc4_surface_data_create(bufmgr_data, width, height, format, error); + if (!surface_data) { + TBM_BACKEND_ERR("fail to create surface_data"); + return NULL; + } + + num_planes = _tbm_vc4_bufmgr_get_num_planes(format); + if (num_planes == 0) { + TBM_BACKEND_ERR("fail to get num_planes"); + _tbm_vc4_surface_data_destroy(surface_data); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + for (i = 0; i < num_planes; i++) { + *error = tbm_vc4_bufmgr_get_plane_data(bufmgr, format, i, (int)width, (int)height, &size, &offset, &pitch, &bo_idx); + if (*error != HAL_TBM_ERROR_NONE) { + _tbm_vc4_surface_data_destroy(surface_data); + TBM_BACKEND_ERR("fail to get plane_data"); + return NULL; + } + bo_size += size; + } + + bo_data = tbm_vc4_bufmgr_alloc_bo(bufmgr, bo_size, mem_types, error); + if (!bo_data) { + TBM_BACKEND_ERR("fail to allocate the bo_data"); + _tbm_vc4_surface_data_destroy(surface_data); + if (error) + *error = HAL_TBM_ERROR_OUT_OF_MEMORY; + return NULL; + } + _tbm_vc4_surface_data_set_bo_data(surface_data, bo_data); + + return (hal_tbm_surface *)surface_data; +} + +static tbm_vc4_surface * +_tbm_vc4_surface_find_same_surface(tbm_vc4_bufmgr *bufmgr_data, tbm_vc4_bo *bo_data) +{ + tbm_vc4_surface *s = NULL; + + LIST_FOR_EACH_ENTRY(s, &bufmgr_data->surface_data_list, link) { + if (s->bo_data == bo_data) { + return s; + } + } + return NULL; } @@ -1514,7 +1577,64 @@ static hal_tbm_surface * tbm_vc4_bufmgr_import_surface(hal_tbm_bufmgr *bufmgr, uint32_t width, uint32_t height, hal_tbm_format format, hal_tbm_surface_buffer_data *buffer_data, hal_tbm_error *error) { - return NULL; + tbm_vc4_bufmgr *bufmgr_data = (tbm_vc4_bufmgr *)bufmgr; + tbm_vc4_surface *surface_data, *surface_data1; + tbm_vc4_bo *bo_data; + + if (bufmgr_data == NULL) { + TBM_BACKEND_ERR("bufmgr is null"); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + if (buffer_data == NULL) { + TBM_BACKEND_ERR("buffer_data is null"); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + // vc4 backend allows to import only one dmabuf-fd. + if (buffer_data->num_fds != 1) { + TBM_BACKEND_ERR("buffer_data->num_fds MUST BE 1."); + TBM_BACKEND_ERR("vc4 backend can only import surface with just one dmabuf-fd."); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + if (buffer_data->fds == NULL) { + TBM_BACKEND_ERR("buffer_data->fds is null"); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + surface_data = _tbm_vc4_surface_data_create(bufmgr_data, width, height, format, error); + if (!surface_data) { + TBM_BACKEND_ERR("fail to create surface_data"); + return NULL; + } + + bo_data = tbm_vc4_bufmgr_import_fd(bufmgr, buffer_data->fds[0], error); + if (!bo_data) { + TBM_BACKEND_ERR("fail to import the bo_data"); + _tbm_vc4_surface_data_destroy(surface_data); + return NULL; + } + + // reuse the surface_data when there is a surface_data which already has the same bo_data. + surface_data1 = _tbm_vc4_surface_find_same_surface(bufmgr_data, bo_data); + if (surface_data1) { + _tbm_vc4_surface_data_destroy(surface_data); + surface_data = surface_data1; + surface_data->refcnt++; + } else { + _tbm_vc4_surface_data_set_bo_data(surface_data, bo_data); + } + + return (hal_tbm_surface *)surface_data; } static hal_tbm_bo * @@ -1833,25 +1953,125 @@ tbm_vc4_bufmgr_import_key(hal_tbm_bufmgr *bufmgr, hal_tbm_key key, hal_tbm_error static void tbm_vc4_surface_free(hal_tbm_surface *surface) { + tbm_vc4_surface *surface_data = (tbm_vc4_surface *)surface; + + if (!surface_data) + return; + _tbm_vc4_surface_data_destroy(surface_data); } static hal_tbm_bo ** tbm_vc4_surface_get_bos(hal_tbm_surface *surface, int *num_bos, hal_tbm_error *error) { - return NULL; + tbm_vc4_surface *surface_data = (tbm_vc4_surface *)surface; + hal_tbm_surface **bos; + + if (surface_data == NULL) { + TBM_BACKEND_ERR("surface_data is null\n"); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + if (num_bos == NULL) { + TBM_BACKEND_ERR("num_bos is null\n"); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + *num_bos = surface_data->num_bos; + + /* will be freed in frontend */ + bos = calloc(*num_bos, sizeof(tbm_vc4_bo *)); + if (!bos) { + TBM_BACKEND_ERR("failed: alloc bos"); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + bos[0] = surface_data->bo_data; + + if (error) + *error = HAL_TBM_ERROR_NONE; + + return bos; } static hal_tbm_error tbm_vc4_surface_get_plane_data(hal_tbm_surface *surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx) { + tbm_vc4_surface *surface_data = (tbm_vc4_surface *)surface; + hal_tbm_error error; + tbm_vc4_bufmgr *bufmgr; + uint32_t width, height; + hal_tbm_format format; + + if (surface_data == NULL) { + TBM_BACKEND_ERR("surface_data is null"); + return HAL_TBM_ERROR_INVALID_PARAMETER; + } + + bufmgr = surface_data->bufmgr_data; + width = surface_data->width; + height = surface_data->height; + format = surface_data->format; + + error = tbm_vc4_bufmgr_get_plane_data((tbm_vc4_bufmgr *)bufmgr, format, plane_idx, + (int)width, (int)height, size, offset, pitch, bo_idx); + if (error != HAL_TBM_ERROR_NONE) { + TBM_BACKEND_ERR("fail to get plane_data"); + return HAL_TBM_ERROR_INVALID_PARAMETER; + } + return HAL_TBM_ERROR_NONE; } static hal_tbm_surface_buffer_data * tbm_vc4_surface_export(hal_tbm_surface *surface, hal_tbm_error *error) { - return NULL; + tbm_vc4_surface *surface_data = (tbm_vc4_surface *)surface; + hal_tbm_surface_buffer_data *buffer_data; + + if (surface == NULL) { + TBM_BACKEND_ERR("surface is null"); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + return NULL; + } + + buffer_data = calloc(1, sizeof(struct _hal_tbm_surface_buffer_data)); + if (!buffer_data) { + TBM_BACKEND_ERR("fail to allocate a buffer_data"); + if (error) + *error = HAL_TBM_ERROR_OUT_OF_MEMORY; + return NULL; + } + buffer_data->num_fds = surface_data->num_bos; + + /* will be freed in frontend */ + buffer_data->fds = calloc(buffer_data->num_fds, sizeof(int)); + if (!buffer_data->fds) { + TBM_BACKEND_ERR("failed: alloc bos"); + if (error) + *error = HAL_TBM_ERROR_INVALID_PARAMETER; + free(buffer_data); + return NULL; + } + + buffer_data->fds[0] = tbm_vc4_bo_export_fd(surface_data->bo_data, error); + if (buffer_data->fds[0] < 0) { + TBM_BACKEND_ERR("fail to export bo_data"); + free(buffer_data->fds); + free(buffer_data); + return NULL; + } + + if (error) + *error = HAL_TBM_ERROR_NONE; + + return buffer_data; } static void |