implement the backend funtion for hal_tbm_surface. 82/258282/8
authorSooChan Lim <sc1.lim@samsung.com>
Thu, 13 May 2021 05:41:55 +0000 (14:41 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 8 Jul 2021 08:33:47 +0000 (17:33 +0900)
Change-Id: I3866398d537d38f0225e83ee96f961222761354b

src/libhal-backend-tbm-vc4/tbm_backend_vc4.c

index 7f45e83..f401a9b 100644 (file)
@@ -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