typedef struct _twe_thread_context twe_thread_context;
typedef void* twe_display_h;
typedef void* twe_surface_h;
+typedef void* twe_buffer_h;
#else
#include "wayland-egl/wayland-egl-priv.h"
#include "tpl_utils.h"
#endif
+static int buffer_info_key;
+#define KEY_BUFFER_INFO (unsigned long)(&buffer_info_key)
+
#define CLIENT_QUEUE_SIZE 3
typedef struct _twe_wl_disp_source twe_wl_disp_source;
typedef struct _twe_wl_surf_source twe_wl_surf_source;
+typedef struct _twe_wl_buffer_info twe_wl_buffer_info;
struct _twe_thread_context {
int ref_cnt;
twe_wl_disp_source *disp_source;
};
+struct _twe_wl_buffer_info {
+ struct wl_proxy *wl_buffer;
+ int dx, dy;
+ int width, height;
+ int rotation;
+ twe_wl_surf_source *surf_source;
+};
+
static twe_thread_context *_twe_ctx;
static gpointer
source->rotation_capability = set;
}
+void
+__cb_twe_buffer_free_callback(twe_wl_buffer_info *buf_info)
+{
+ twe_wl_surf_source *surf_source = buf_info->surf_source;
+ twe_wl_disp_source *disp_source = surf_source->disp_source;
+
+ TPL_LOG_T("WL_EGL", "[FREE] twe_buffer(%p) wl_buffer(%p)",
+ buf_info, buf_info->wl_buffer);
+
+ wl_display_flush(disp_source->disp);
+
+ if (buf_info->wl_buffer)
+ wayland_tbm_client_destroy_buffer(disp_source->wl_tbm_client,
+ (void *)buf_info->wl_buffer);
+
+ free(buf_info);
+}
+
+static void
+__cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer)
+{
+ twe_wl_buffer_info *buf_info = NULL;
+ tbm_surface_h tbm_surface = (tbm_surface_h)data;
+
+ TPL_LOG_T("WL_EGL", "[RELEASE_CB] wl_buffer(%p) tbm_surface(%p)",
+ wl_buffer, tbm_surface);
+
+ if (tbm_surface_internal_is_valid(tbm_surface)) {
+ tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
+ (void **)&buf_info);
+ if (buf_info) {
+ twe_wl_surf_source *surf_source = buf_info->surf_source;
+ tbm_surface_queue_error_e tsq_err;
+
+ tsq_err = tbm_surface_queue_release(surf_source->tbm_queue,
+ tbm_surface);
+ if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE)
+ TPL_ERR("tbm_surface(%p) tsq_err(%d)", tbm_surface, tsq_err);
+
+ tbm_surface_internal_unref(tbm_surface);
+ }
+
+ } else {
+ TPL_ERR("Invalid parameter | tbm_surface(%p)", tbm_surface);
+ }
+}
+
+static const struct wl_buffer_listener wl_buffer_release_listener = {
+ (void *)__cb_buffer_release_callback,
+};
+
+tpl_result_t
+twe_surface_set_buffer(twe_surface_h twe_surface, tbm_surface_h tbm_surface)
+{
+ twe_wl_surf_source *source = (twe_wl_surf_source *)twe_surface;
+ twe_wl_buffer_info *buf_info = NULL;
+ struct wl_egl_window *wl_egl_window = NULL;
+ int ret = 0;
+
+ if (!source) {
+ TPL_ERR("Invalid parameter. twe_surface(%p)", twe_surface);
+ return TPL_ERROR_INVALID_PARAMETER;
+ }
+
+ wl_egl_window = source->wl_egl_window;
+
+ if (!tbm_surface || !tbm_surface_internal_is_valid(tbm_surface)) {
+ TPL_ERR("Invalid parameter. tbm_surface(%p)", tbm_surface);
+ return TPL_ERROR_INVALID_PARAMETER;
+ }
+
+ tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
+ (void **)&buf_info);
+ /* If buf_info is already existed, reuse it. */
+ if (buf_info) {
+ buf_info->rotation = wl_egl_window->rotation;
+ buf_info->dx = wl_egl_window->dx;
+ buf_info->dy = wl_egl_window->dy;
+
+ return TPL_ERROR_NONE;
+ } else {
+ buf_info = (twe_wl_buffer_info *)calloc(1, sizeof(twe_wl_buffer_info));
+ }
+
+ if (!buf_info) {
+ TPL_ERR("Failed to allocate memory for twe_wl_buffer_info.");
+ return TPL_ERROR_INVALID_OPERATION;
+ }
+
+ buf_info->wl_buffer =
+ (struct wl_proxy *)wayland_tbm_client_create_buffer(
+ source->disp_source->wl_tbm_client, tbm_surface);
+
+ if (!buf_info->wl_buffer) {
+ TPL_ERR("Failed to create wl_buffer from tbm_surface(%p)",
+ tbm_surface);
+ free(buf_info);
+ return TPL_ERROR_INVALID_OPERATION;
+ }
+
+ wl_buffer_add_listener((void *)buf_info->wl_buffer,
+ &wl_buffer_release_listener, tbm_surface);
+ wl_display_flush(source->disp_source->disp);
+
+ ret = tbm_surface_internal_add_user_data(tbm_surface, KEY_BUFFER_INFO,
+ (tbm_data_free)__cb_twe_buffer_free_callback);
+ if (ret) {
+ ret = tbm_surface_internal_set_user_data(tbm_surface,
+ KEY_BUFFER_INFO,
+ buf_info);
+ }
+
+ if (!ret) {
+ TPL_ERR("Failed to set user_data to tbm_surface(%p)", tbm_surface);
+ free(buf_info);
+ return TPL_ERROR_INVALID_OPERATION;
+ }
+
+ return TPL_ERROR_NONE;
+}
+
+
#ifdef WORKER_TEST_ONLY
static void reg_global(void *data,
struct wl_registry *wl_registry,