summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSooChan Lim <sc1.lim@samsung.com>2021-05-13 14:41:55 +0900
committerSooChan Lim <sc1.lim@samsung.com>2021-07-08 17:33:47 +0900
commitc039634488fc97ce22511750fd6c21300e19c704 (patch)
tree8c89be94ac1fd23edb61f83d66a04accb2c107fe
parent4ad82dab477a26c9eb5eba3489a5c77770a06954 (diff)
downloadlibtbm-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.c226
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