From 20dfec69f7aed68022d43a0e4d496d92c591bcb3 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 27 Apr 2017 13:02:39 +0900 Subject: [PATCH] tpl_wayland_egl_thread: Added twe_surface_set_buffer API. - NEW API : twe_surface_set_buffer(twe_surface_h ,tbm_surface_h) - I expect it to be called immediately after tbm_surface_queue_dequeue() inside tpl_surface_dequeue_buffer(). - The input parameter tbm_surface_h must be a dequeued buffer from tbm_surface_queue. - Operation : * Create twe_wl_buffer_info and set to tbm_surface as user_data. * Create wl_buffer with wl_tbm_client, wl_surface and set to twe_wl_buffer_info. * Get wl_egl_window's size and set to twe_wl_buffer_info. Change-Id: I6b1b5d4a46ccb8cb7b475c8a068a1991dc156ab9 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 135 +++++++++++++++++++++++++++++++++++++++++++ src/tpl_wayland_egl_thread.h | 4 ++ 2 files changed, 139 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 89ac01f..eee1b5c 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -22,6 +22,7 @@ typedef struct _twe_thread twe_thread; 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" @@ -29,10 +30,14 @@ typedef void* twe_surface_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; @@ -73,6 +78,14 @@ struct _twe_wl_surf_source { 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 @@ -703,6 +716,128 @@ twe_surface_set_rotation_capablity(twe_surface_h twe_surface, tpl_bool_t set) 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, diff --git a/src/tpl_wayland_egl_thread.h b/src/tpl_wayland_egl_thread.h index 405f2a7..337d80d 100644 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -9,6 +9,7 @@ typedef struct _twe_thread_context twe_thread_context; typedef void* twe_display_h; typedef void* twe_surface_h; +typedef void* twe_buffer_h; twe_thread* twe_thread_create(void); @@ -39,3 +40,6 @@ twe_surface_get_rotation(twe_surface_h twe_surface); void twe_surface_set_rotation_capablity(twe_surface_h twe_surface, tpl_bool_t set); +tpl_result_t +twe_surface_set_buffer(twe_surface_h twe_surface, tbm_surface_h tbm_surface); + -- 2.7.4