implement wl-protocol for exchanging meta_data 62/258362/2
authorSooChan Lim <sc1.lim@samsung.com>
Fri, 14 May 2021 04:20:37 +0000 (13:20 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Fri, 2 Jul 2021 03:19:49 +0000 (12:19 +0900)
Change-Id: I4c1d2d83ab531d3c225d0f49c3414794145a0bee

src/wayland-tbm-client.c
src/wayland-tbm-server.c

index c13d7db..7d1c743 100644 (file)
@@ -135,7 +135,9 @@ _wayland_tbm_client_create_surface_from_param(tbm_bufmgr bufmgr,
                         int32_t num_buf,
                         uint32_t buf0,
                         uint32_t buf1,
-                        uint32_t buf2);
+                        uint32_t buf2,
+                        uint32_t num_meta_data,
+                        struct wl_array *meta_data);
 
 static void
 handle_tbm_buffer_import_with_id(void *data,
@@ -155,7 +157,9 @@ handle_tbm_buffer_import_with_id(void *data,
                int32_t num_buf,
                uint32_t buf0,
                uint32_t buf1,
-               uint32_t buf2)
+               uint32_t buf2,
+               uint32_t num_meta_data,
+               struct wl_array *meta_data)
 {
        struct wayland_tbm_client *tbm_client = (struct wayland_tbm_client *)data;
        tbm_surface_h tbm_surface;
@@ -167,7 +171,9 @@ handle_tbm_buffer_import_with_id(void *data,
                              plane_buf_idx, plane_offset, plane_stride, plane_size,
                              0,
                              num_buf,
-                             buf0, buf1, buf2);
+                             buf0, buf1, buf2,
+                             num_meta_data,
+                             meta_data);
        WL_TBM_GOTO_IF_FAIL(tbm_surface != NULL, fail);
        wl_buffer_set_user_data(wl_buffer, tbm_surface);
 
@@ -202,7 +208,9 @@ handle_tbm_buffer_import_with_fd(void *data,
                int32_t num_buf,
                int32_t buf0,
                int32_t buf1,
-               int32_t buf2)
+               int32_t buf2,
+               uint32_t num_meta_data,
+               struct wl_array *meta_data)
 {
        struct wayland_tbm_client *tbm_client = (struct wayland_tbm_client *)data;
        tbm_surface_h tbm_surface;
@@ -214,7 +222,9 @@ handle_tbm_buffer_import_with_fd(void *data,
                              plane_buf_idx, plane_offset, plane_stride, plane_size,
                              0,
                              num_buf,
-                             buf0, buf1, buf2);
+                             buf0, buf1, buf2,
+                             num_meta_data,
+                             meta_data);
        WL_TBM_GOTO_IF_FAIL(tbm_surface != NULL, fail);
 
        wl_buffer_set_user_data(wl_buffer, tbm_surface);
@@ -486,6 +496,16 @@ _wayland_tbm_client_create_wl_buffer(struct wayland_tbm_client *tbm_client, tbm_
        uint32_t flags = 0;
        struct wl_array plane_buf_idx, plane_offset, plane_stride, plane_size;
        int *p;
+       uint32_t num_meta_data = 0;
+       struct wl_array meta_data;
+       tbm_error_e terror = TBM_ERROR_NONE;
+       tbm_surface_buffer_data *buffer_data = NULL;
+
+       wl_array_init(&plane_buf_idx);
+       wl_array_init(&plane_offset);
+       wl_array_init(&plane_stride);
+       wl_array_init(&plane_size);
+       wl_array_init(&meta_data);
 
        if (tbm_surface_get_info(surface, &info) != TBM_SURFACE_ERROR_NONE) {
                WL_TBM_LOG_E("Failed to create buffer from surface");
@@ -497,42 +517,51 @@ _wayland_tbm_client_create_wl_buffer(struct wayland_tbm_client *tbm_client, tbm_
                return NULL;
        }
 
-       num_buf = tbm_surface_internal_get_num_bos(surface);
-       if (num_buf == 0) {
-               WL_TBM_LOG_E("surface doesn't have any bo.");
-               return NULL;
-       }
-
-       for (i = 0; i < num_buf; i++) {
-               tbm_bo bo = tbm_surface_internal_get_bo(surface, i);
-               if (bo == NULL) {
-                       WL_TBM_LOG_E("Failed to get bo from surface");
-                       goto err;
+       // export surface
+       buffer_data = tbm_surface_internal_export(surface, &terror);
+       if (buffer_data) {
+               num_buf = buffer_data->num_fds;
+               for (i = 0; i < num_buf; i++)
+                       bufs[i] = buffer_data->fds[i];
+
+               num_meta_data = buffer_data->num_meta_data;
+               for(i = 0; i < num_meta_data; i++) {
+                       p = wl_array_add(&meta_data, sizeof(unsigned int));
+                       *p = buffer_data->meta_data[i];
+               }
+       } else {
+               num_buf = tbm_surface_internal_get_num_bos(surface);
+               if (num_buf == 0) {
+                       WL_TBM_LOG_E("surface doesn't have any bo.");
+                       return NULL;
                }
 
-               if (with_fd) {
-                       buf = tbm_bo_export_fd(bo);
-                       if (!_wayland_tbm_client_fd_is_valid(buf)) {
+               for (i = 0; i < num_buf; i++) {
+                       tbm_bo bo = tbm_surface_internal_get_bo(surface, i);
+                       if (bo == NULL) {
+                               WL_TBM_LOG_E("Failed to get bo from surface");
                                goto err;
                        }
-               }
-               else {
-                       buf = tbm_bo_export(bo);
-               }
 
-               if (((with_fd) && (buf < 0)) ||
-                   ((!with_fd) && (buf <= 0))) {
-                       WL_TBM_LOG_E("Failed to export(with_fd:%d, bufs:%d)", with_fd, bufs[i]);
-                       goto err;
-               }
+                       if (with_fd) {
+                               buf = tbm_bo_export_fd(bo);
+                               if (!_wayland_tbm_client_fd_is_valid(buf)) {
+                                       goto err;
+                               }
+                       }
+                       else {
+                               buf = tbm_bo_export(bo);
+                       }
 
-               bufs[i] = buf;
-       }
+                       if (((with_fd) && (buf < 0)) ||
+                           ((!with_fd) && (buf <= 0))) {
+                               WL_TBM_LOG_E("Failed to export(with_fd:%d, bufs:%d)", with_fd, bufs[i]);
+                               goto err;
+                       }
 
-       wl_array_init(&plane_buf_idx);
-       wl_array_init(&plane_offset);
-       wl_array_init(&plane_stride);
-       wl_array_init(&plane_size);
+                       bufs[i] = buf;
+               }
+       }
 
        for (i = 0; i < 3; i++) {
                p = wl_array_add(&plane_buf_idx, sizeof(int));
@@ -551,18 +580,23 @@ _wayland_tbm_client_create_wl_buffer(struct wayland_tbm_client *tbm_client, tbm_
                                &plane_buf_idx, &plane_offset, &plane_stride, &plane_size,
                                flags, num_buf, bufs[0],
                                (bufs[1] == -1) ? bufs[0] : bufs[1],
-                               (bufs[2] == -1) ? bufs[0] : bufs[2]);
+                               (bufs[2] == -1) ? bufs[0] : bufs[2],
+                               num_meta_data,
+                               &meta_data);
        else
                wl_buffer = wl_tbm_create_buffer(tbm_client->wl_tbm,
                                 info.width, info.height, info.format, info.bpp, info.size, info.num_planes,
                                 &plane_buf_idx, &plane_offset, &plane_stride, &plane_size,
                                 flags,
-                                num_buf, bufs[0], bufs[1], bufs[2]);
+                                num_buf, bufs[0], bufs[1], bufs[2],
+                                num_meta_data,
+                                &meta_data);
 
        wl_array_release(&plane_buf_idx);
        wl_array_release(&plane_offset);
        wl_array_release(&plane_stride);
        wl_array_release(&plane_size);
+       wl_array_release(&meta_data);
 
        if (!wl_buffer) {
                TBM_ERR("Failed to wl_tbm_create_buffer(with_fd:%d)", with_fd);
@@ -572,9 +606,16 @@ _wayland_tbm_client_create_wl_buffer(struct wayland_tbm_client *tbm_client, tbm_
        WL_TBM_TRACE("wl_buffer:%p tbm_surface:%p (%dx%d) size:%d fmt:%c%c%c%c",
                wl_buffer, surface, info.width, info.height, info.size, FOURCC_STR(info.format));
 
-       for (i = 0; i < TBM_SURF_PLANE_MAX; i++) {
-               if ((with_fd) && (bufs[i] >= 0))
-                       close(bufs[i]);
+       if (buffer_data) {
+               for (i = 0; i < buffer_data->num_fds; i++) {
+                       close(buffer_data->fds[i]);
+               }
+               free(buffer_data);
+       } else {
+               for (i = 0; i < TBM_SURF_PLANE_MAX; i++) {
+                       if ((with_fd) && (bufs[i] >= 0))
+                               close(bufs[i]);
+               }
        }
 
        return wl_buffer;
@@ -585,6 +626,9 @@ err:
                        close(bufs[i]);
        }
 
+       if (buffer_data)
+               free(buffer_data);
+
        return NULL;
 }
 
@@ -771,13 +815,17 @@ _wayland_tbm_client_create_surface_from_param(tbm_bufmgr bufmgr,
                                                         int32_t num_buf,
                                                         uint32_t buf0,
                                                         uint32_t buf1,
-                                                        uint32_t buf2)
+                                                        uint32_t buf2,
+                                                        uint32_t num_meta_data,
+                                                        struct wl_array *meta_data)
 {
        int32_t names[TBM_SURF_PLANE_MAX] = { -1, -1, -1, -1};
        tbm_surface_info_s info = { 0, };
        tbm_bo bos[TBM_SURF_PLANE_MAX];
        int i, numPlane, numName;
-       tbm_surface_h tbm_surface;
+       tbm_surface_h tbm_surface = NULL;
+       tbm_surface_buffer_data *buffer_data = NULL;
+       tbm_error_e terror = TBM_ERROR_NONE;
 
        numPlane = tbm_surface_internal_get_num_planes(format);
        WL_TBM_RETURN_VAL_IF_FAIL(numPlane == num_plane, NULL);
@@ -802,21 +850,50 @@ _wayland_tbm_client_create_surface_from_param(tbm_bufmgr bufmgr,
        names[1] = buf1;
        names[2] = buf2;
 
+       // make a buffer_data
+       buffer_data = calloc(1, sizeof(struct _tbm_surface_buffer_data));
+       if (!buffer_data) {
+               WL_TBM_LOG_E("fail to alloc buffer_data.");
+               goto done;
+       }
+
+       buffer_data->fds = calloc(num_buf, sizeof(int));
+       if (!buffer_data->fds) {
+               WL_TBM_LOG_E("fail to alloc fds.");
+               goto done;
+       }
+
+       buffer_data->num_fds = numName;
        for (i = 0; i < numName; i++) {
-               if (is_fd)
-                       bos[i] = tbm_bo_import_fd(bufmgr, names[i]);
-               else
-                       bos[i] = tbm_bo_import(bufmgr, names[i]);
+               buffer_data->fds[i] = names[i];
+       }
+       for (i = 0; i < num_meta_data; i++) {
+               buffer_data->meta_data[i] = *WL_TBM_ARRAY_NTH_DATA(meta_data, uint32_t, i);
        }
 
-       tbm_surface = tbm_surface_internal_create_with_bos(&info, bos, numName);
-       if (tbm_surface == NULL) {
-               if (is_fd) {
-                       close(buf0);
-                       close(buf1);
-                       close(buf2);
+       // import surface
+       tbm_surface = tbm_surface_internal_import(&info, buffer_data, &terror);
+       if (!tbm_surface) {
+               for (i = 0; i < numName; i++) {
+                       if (is_fd)
+                               bos[i] = tbm_bo_import_fd(bufmgr, names[i]);
+                       else
+                               bos[i] = tbm_bo_import(bufmgr, names[i]);
                }
-               return NULL;
+
+               tbm_surface = tbm_surface_internal_create_with_bos(&info, bos, numName);
+               if (tbm_surface == NULL) {
+                       goto done;
+               }
+
+               for (i = 0; i < numName; i++)
+                       tbm_bo_unref(bos[i]);
+       }
+
+done:
+       if (buffer_data) {
+               free(buffer_data->fds);
+               free(buffer_data);
        }
 
        if (is_fd) {
@@ -825,9 +902,6 @@ _wayland_tbm_client_create_surface_from_param(tbm_bufmgr bufmgr,
                close(buf2);
        }
 
-       for (i = 0; i < numName; i++)
-               tbm_bo_unref(bos[i]);
-
        return tbm_surface;
 }
 
index cfa1b58..e877b23 100644 (file)
@@ -325,7 +325,8 @@ _wayland_tbm_server_impl_create_buffer(struct wl_client *client,
               struct wl_array *plane_buf_idx, struct wl_array *plane_offset,
               struct wl_array *plane_stride, struct wl_array *plane_size,
               uint32_t flags,
-              int32_t num_buf, uint32_t buf0, uint32_t buf1, uint32_t buf2)
+              int32_t num_buf, uint32_t buf0, uint32_t buf1, uint32_t buf2,
+              uint32_t num_meta_data, struct wl_array *meta_data)
 {
        struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(wl_tbm);
        int32_t names[TBM_SURF_PLANE_MAX] = { -1, -1, -1, -1};
@@ -402,7 +403,8 @@ _wayland_tbm_server_impl_create_buffer_with_fd(struct wl_client *client,
                struct wl_array *plane_buf_idx, struct wl_array *plane_offset,
                struct wl_array *plane_stride, struct wl_array *plane_size,
                uint32_t flags,
-               int32_t num_buf, int32_t buf0, int32_t buf1, int32_t buf2)
+               int32_t num_buf, int32_t buf0, int32_t buf1, int32_t buf2,
+               uint32_t num_meta_data, struct wl_array *meta_data)
 {
        struct wayland_tbm_server *tbm_srv = wl_resource_get_user_data(wl_tbm);
        int32_t names[TBM_SURF_PLANE_MAX] = { -1, -1, -1, -1};
@@ -411,6 +413,8 @@ _wayland_tbm_server_impl_create_buffer_with_fd(struct wl_client *client,
        tbm_bo bos[TBM_SURF_PLANE_MAX];
        tbm_surface_h surface;
        int i, numPlane;
+       tbm_surface_buffer_data *buffer_data = NULL;
+       tbm_error_e terror = TBM_ERROR_NONE;
 
        numPlane = tbm_surface_internal_get_num_planes(format);
        if (numPlane != num_plane) {
@@ -438,18 +442,43 @@ _wayland_tbm_server_impl_create_buffer_with_fd(struct wl_client *client,
        names[1] = buf1;
        names[2] = buf2;
 
-       for (i = 0; i < num_buf; i++)
-               bos[i] = tbm_bo_import_fd(tbm_srv->bufmgr, names[i]);
+       // make a buffer_data
+       buffer_data = calloc(1, sizeof(struct _tbm_surface_buffer_data));
+       if (!buffer_data) {
+               WL_TBM_LOG_E("fail to alloc buffer_data.");
+               goto done;
+       }
 
-       surface = tbm_surface_internal_create_with_bos(&info, bos, num_buf);
-       if (surface == NULL) {
-               WL_TBM_LOG_E("fail to create the tbm_surface.");
-               wl_resource_post_no_memory(wl_tbm);
+       buffer_data->fds = calloc(num_buf, sizeof(int));
+       if (!buffer_data->fds) {
+               WL_TBM_LOG_E("fail to alloc fds.");
                goto done;
        }
 
-       for (i = 0; i < num_buf; i++)
-               tbm_bo_unref(bos[i]);
+       buffer_data->num_fds = num_buf;
+       for (i = 0; i < num_buf; i++) {
+               buffer_data->fds[i] = names[i];
+       }
+       for (i = 0; i < num_meta_data; i++) {
+               buffer_data->meta_data[i] = *WL_TBM_ARRAY_NTH_DATA(meta_data, uint32_t, i);
+       }
+
+       // import surface
+       surface = tbm_surface_internal_import(&info, buffer_data, &terror);
+       if (!surface) {
+               for (i = 0; i < num_buf; i++)
+                       bos[i] = tbm_bo_import_fd(tbm_srv->bufmgr, names[i]);
+
+               surface = tbm_surface_internal_create_with_bos(&info, bos, num_buf);
+               if (surface == NULL) {
+                       WL_TBM_LOG_E("fail to create the tbm_surface.");
+                       wl_resource_post_no_memory(wl_tbm);
+                       goto done;
+               }
+
+               for (i = 0; i < num_buf; i++)
+                       tbm_bo_unref(bos[i]);
+       }
 
        tbm_buffer = _wayland_tbm_server_tbm_buffer_create(wl_tbm, client, surface, id, flags);
        if (tbm_buffer == NULL) {
@@ -469,6 +498,11 @@ _wayland_tbm_server_impl_create_buffer_with_fd(struct wl_client *client,
 #endif
 
 done:
+       if (buffer_data) {
+               free(buffer_data->fds);
+               free(buffer_data);
+       }
+
        close(buf0);
        close(buf1);
        close(buf2);
@@ -870,6 +904,16 @@ _wayland_tbm_server_export_surface(struct wl_resource *wl_tbm,
        tbm_surface_info_s info;
        struct wl_array plane_buf_idx, plane_offset, plane_stride, plane_size;
        int *p;
+       uint32_t num_meta_data = 0;
+       struct wl_array meta_data;
+       tbm_error_e terror = TBM_ERROR_NONE;
+       tbm_surface_buffer_data *buffer_data = NULL;
+
+       wl_array_init(&plane_buf_idx);
+       wl_array_init(&plane_offset);
+       wl_array_init(&plane_stride);
+       wl_array_init(&plane_size);
+       wl_array_init(&meta_data);
 
        if (tbm_surface_get_info(surface, &info) != TBM_SURFACE_ERROR_NONE) {
                WL_TBM_LOG_E("Failed to create buffer from surface");
@@ -881,48 +925,58 @@ _wayland_tbm_server_export_surface(struct wl_resource *wl_tbm,
                return 0;
        }
 
-       num_buf = tbm_surface_internal_get_num_bos(surface);
-       if (num_buf == 0) {
-               WL_TBM_LOG_E("surface doesn't have any bo.");
-               return 0;
-       }
-
-       flag = tbm_bo_get_flags(tbm_surface_internal_get_bo(surface, 0));
-
-       for (i = 0; i < num_buf; i++) {
-               tbm_bo bo = tbm_surface_internal_get_bo(surface, i);
-               if (bo == NULL) {
-                       WL_TBM_LOG_E("fail to get the bo.");
-                       goto err;
+       // export surface
+       buffer_data = tbm_surface_internal_export(surface, &terror);
+       if (buffer_data) {
+               num_buf = buffer_data->num_fds;
+               for (i = 0; i < num_buf; i++)
+                       bufs[i] = buffer_data->fds[i];
+
+               num_meta_data = buffer_data->num_meta_data;
+               for(i = 0; i < num_meta_data; i++) {
+                       p = wl_array_add(&meta_data, sizeof(unsigned int));
+                       *p = buffer_data->meta_data[i];
                }
-
-               /* try to get fd first */
-               if (is_fd == -1 || is_fd == 1) {
-                       bufs[i] = tbm_bo_export_fd(bo);
-                       if (is_fd == -1 && bufs[i] >= 0)
-                               is_fd = 1;
-               }
-
-               /* if fail to get fd, try to get name second */
-               if (is_fd == -1 || is_fd == 0) {
-                       bufs[i] = tbm_bo_export(bo);
-                       if (is_fd == -1 && bufs[i] > 0)
-                               is_fd = 0;
+               flag = 0; // TODO: What is the bo flags at this moment?
+       } else {
+               num_buf = tbm_surface_internal_get_num_bos(surface);
+               if (num_buf == 0) {
+                       WL_TBM_LOG_E("surface doesn't have any bo.");
+                       return 0;
                }
 
-               if (is_fd == -1 ||
-                   (is_fd == 1 && bufs[i] < 0) ||
-                   (is_fd == 0 && bufs[i] <= 0)) {
-                       WL_TBM_LOG_E("Failed to export(is_fd:%d, bufs:%d)", is_fd, bufs[i]);
-                       goto err;
+               flag = tbm_bo_get_flags(tbm_surface_internal_get_bo(surface, 0));
+
+               for (i = 0; i < num_buf; i++) {
+                       tbm_bo bo = tbm_surface_internal_get_bo(surface, i);
+                       if (bo == NULL) {
+                               WL_TBM_LOG_E("fail to get the bo.");
+                               goto err;
+                       }
+
+                       /* try to get fd first */
+                       if (is_fd == -1 || is_fd == 1) {
+                               bufs[i] = tbm_bo_export_fd(bo);
+                               if (is_fd == -1 && bufs[i] >= 0)
+                                       is_fd = 1;
+                       }
+
+                       /* if fail to get fd, try to get name second */
+                       if (is_fd == -1 || is_fd == 0) {
+                               bufs[i] = tbm_bo_export(bo);
+                               if (is_fd == -1 && bufs[i] > 0)
+                                       is_fd = 0;
+                       }
+
+                       if (is_fd == -1 ||
+                           (is_fd == 1 && bufs[i] < 0) ||
+                           (is_fd == 0 && bufs[i] <= 0)) {
+                               WL_TBM_LOG_E("Failed to export(is_fd:%d, bufs:%d)", is_fd, bufs[i]);
+                               goto err;
+                       }
                }
        }
 
-       wl_array_init(&plane_buf_idx);
-       wl_array_init(&plane_offset);
-       wl_array_init(&plane_stride);
-       wl_array_init(&plane_size);
-
        for (i = 0; i < 3; i++) {
                p = wl_array_add(&plane_buf_idx, sizeof(int));
                *p = tbm_surface_internal_get_plane_bo_idx(surface, i);
@@ -941,7 +995,9 @@ _wayland_tbm_server_export_surface(struct wl_resource *wl_tbm,
                                &plane_buf_idx, &plane_offset, &plane_stride, &plane_size,
                                flag, num_buf, bufs[0],
                                (bufs[1] == -1) ? bufs[0] : bufs[1],
-                               (bufs[2] == -1) ? bufs[0] : bufs[2]);
+                               (bufs[2] == -1) ? bufs[0] : bufs[2],
+                               num_meta_data,
+                               &meta_data);
        else
                wl_tbm_send_buffer_import_with_id(wl_tbm,
                                wl_buffer,
@@ -949,16 +1005,27 @@ _wayland_tbm_server_export_surface(struct wl_resource *wl_tbm,
                                &plane_buf_idx, &plane_offset, &plane_stride, &plane_size,
                                flag, num_buf, bufs[0],
                                (bufs[1] == -1) ? bufs[0] : bufs[1],
-                               (bufs[2] == -1) ? bufs[0] : bufs[2]);
+                               (bufs[2] == -1) ? bufs[0] : bufs[2],
+                               num_meta_data,
+                               &meta_data);
 
        wl_array_release(&plane_buf_idx);
        wl_array_release(&plane_offset);
        wl_array_release(&plane_stride);
        wl_array_release(&plane_size);
+       wl_array_release(&meta_data);
 
-       for (i = 0; i < TBM_SURF_PLANE_MAX; i++) {
-               if (is_fd == 1 && (bufs[i] >= 0))
-                       close(bufs[i]);
+
+       if (buffer_data) {
+               for (i = 0; i < buffer_data->num_fds; i++) {
+                       close(buffer_data->fds[i]);
+               }
+               free(buffer_data);
+       } else {
+               for (i = 0; i < TBM_SURF_PLANE_MAX; i++) {
+                       if (is_fd == 1 && (bufs[i] >= 0))
+                               close(bufs[i]);
+               }
        }
 
        return 1;
@@ -969,6 +1036,8 @@ err:
                        close(bufs[i]);
        }
 
+       free(buffer_data);
+
        return 0;
 }