From 69f382fa608c2d7755fd0682d4ad0dab31fa0345 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 15:34:21 +0900 Subject: [PATCH 01/16] tpl_util: Added logging for threads. Change-Id: I4c89bb464f0becba6bf2b5267777c4b28bfc1b6a Signed-off-by: joonbum.ko --- src/tpl_utils.h | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/tpl_utils.h b/src/tpl_utils.h index c888022..f4bdb47 100644 --- a/src/tpl_utils.h +++ b/src/tpl_utils.h @@ -61,6 +61,7 @@ extern unsigned int tpl_dump_lvl; #define FONT_GREEN "\033[32m" /* for frontend API logs */ #define FONT_BLUE "\033[34m" /* for backend logs */ #define FONT_MAGENTA "\033[35m" /* for debug logs */ +#define FONT_CYAN "\033[36m" /* for thread logs */ #ifdef DLOG_DEFAULT_ENABLE #define LOG_TAG "TPL" @@ -71,24 +72,28 @@ extern unsigned int tpl_dump_lvl; #define tpl_log_f(t, f, x...) LOGD(FONT_GREEN t FONT_DEFAULT " " f, ##x) #define tpl_log_b(t, f, x...) LOGD(FONT_BLUE t FONT_DEFAULT " " f, ##x) #define tpl_log_d(t, f, x...) LOGD(FONT_MAGENTA t FONT_DEFAULT " " f, ##x) +#define tpl_log_t(t, f, x...) LOGD(FONT_CYAN t FONT_DEFAULT " " f, ##x) #define tpl_log_e(t, f, x...) LOGE(FONT_RED t " " f FONT_DEFAULT, ##x) #define tpl_log_w(t, f, x...) LOGW(FONT_YELLOW t " " f FONT_DEFAULT, ##x) #else /* DLOG_DEFAULT_ENABLE */ #define tpl_log_f(t, f, x...) \ - fprintf(stderr, FONT_GREEN t FONT_DEFAULT "[(pid:%d)(%s)] " f "\n", \ - getpid(), __func__, ##x) + fprintf(stderr, FONT_GREEN t FONT_DEFAULT "[(tid:%li)(%s)] " f "\n", \ + syscall(SYS_gettid), __func__, ##x) #define tpl_log_b(t, f, x...) \ - fprintf(stderr, FONT_BLUE t FONT_DEFAULT "[(pid:%d)(%s)] " f "\n", \ - getpid(), __func__, ##x) + fprintf(stderr, FONT_BLUE t FONT_DEFAULT "[(tid:%li)(%s)] " f "\n", \ + syscall(SYS_gettid), __func__, ##x) #define tpl_log_d(t, f, x...) \ - fprintf(stderr, FONT_MAGENTA t FONT_DEFAULT "[(pid:%d)(%s)] " f "\n",\ - getpid(), __func__, ##x) + fprintf(stderr, FONT_MAGENTA t FONT_DEFAULT "[(tid:%li)(%s)] " f "\n",\ + syscall(SYS_gettid), __func__, ##x) +#define tpl_log_t(t, f, x...) \ + fprintf(stderr, FONT_CYAN t FONT_DEFAULT "[(tid:%li)(%s)]" f "\n", \ + syscall(SYS_gettid), __func__, ##x) #define tpl_log_e(t, f, x...) \ - fprintf(stderr, FONT_RED t "[(pid:%d)(%s)] " f FONT_DEFAULT "\n", \ - getpid(), __func__, ##x) + fprintf(stderr, FONT_RED t "[(tid:%li)(%s)] " f FONT_DEFAULT "\n", \ + syscall(SYS_gettid), __func__, ##x) #define tpl_log_w(t, f, x...) \ - fprintf(stderr, FONT_YELLOW t "[(pid:%d)(%s)] " f FONT_DEFAULT "\n",\ - getpid(), __func__, ##x) + fprintf(stderr, FONT_YELLOW t "[(tid:%li)(%s)] " f FONT_DEFAULT "\n",\ + syscall(SYS_gettid), __func__, ##x) #endif /* DLOG_DEFAULT_ENABLE */ @@ -99,6 +104,13 @@ extern unsigned int tpl_dump_lvl; #define TPL_LOG_F(f, x...) tpl_log_f("[TPL_F]", f, ##x) #define TPL_LOG_B(b, f, x...) tpl_log_b("[TPL_" b "]", f, ##x) #define TPL_DEBUG(f, x...) tpl_log_d("[TPL_DEBUG]", f, ##x) +#define TPL_LOG_T(b, f, x...) \ + { \ + if ((int)getpid() != (int)syscall(SYS_gettid)) \ + tpl_log_t("[TPL_" b "_T]", f, ##x); \ + else \ + tpl_log_b("[TPL_" b "]", f, ##x); \ + } #else /* LOG_DEFAULT_ENABLE */ /* * TPL_LOG_LEVEL -- 2.7.4 From 885ea2ded2e1cd75ed33554e9911abe3914258dd Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 16:31:56 +0900 Subject: [PATCH 02/16] tpl_wayland_egl_thread: Applied new logs for thread test. Change-Id: I49ac182b9c3ee52d296a10a95d3a5eaaa23e1f3f Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 78 ++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 6e67fb5..22b6b8a 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -15,36 +15,14 @@ #ifdef WORKER_TEST_ONLY #include #include "wayland-egl/wayland-egl-priv.h" -#define FONT_DEFAULT "\033[0m" /* for reset to default color */ -#define FONT_RED "\033[31m" /* for error logs */ -#define FONT_GREEN "\033[32m" /* for frontend API logs */ -#define FONT_MAGENTA "\033[35m" /* for debug logs */ - -#define tpl_log_d(t, f, x...) \ - fprintf(stderr, FONT_MAGENTA t FONT_DEFAULT "[(tid:%li)(%s)] " f "\n",\ - syscall(SYS_gettid), __func__, ##x) -#define tpl_log_t(t, f, x...) \ - fprintf(stderr, FONT_GREEN t FONT_DEFAULT "[(tid:%li)(%s)] " f "\n", \ - syscall(SYS_gettid), __func__, ##x) -#define tpl_log_e(t, f, x...) \ - fprintf(stderr, FONT_RED t "[(tid:%li)(%s)] " f FONT_DEFAULT "\n", \ - syscall(SYS_gettid), __func__, ##x) - -#define TPL_ERR(f, x...) tpl_log_e("[TPL_ERROR]", f, ##x) -#define TPL_DEBUG(f, x...) \ - ((int)getpid() == (int)syscall(SYS_gettid)) ? tpl_log_d("[MAIN]", f, ##x) : tpl_log_t("[THREAD]", f, ##x) +#include "tpl.h" +#include "tpl_utils.h" + 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 enum { - TPL_ERROR_NONE = 0, /* Successfull */ - TPL_ERROR_INVALID_PARAMETER, /* Invalid parmeter */ - TPL_ERROR_INVALID_OPERATION, /* Invalid operation */ - TPL_ERROR_OUT_OF_MEMORY /* Out of memory */ -} tpl_result_t; - #else #include "wayland-egl/wayland-egl-priv.h" #include "tpl_wayland_egl_thread.h" @@ -111,7 +89,7 @@ _twe_thread_tdm_source_dispatch(gpointer user_data) twe_thread_context* context = user_data; tdm_error tdm_err; - TPL_DEBUG("tdm_dispatch| tdm_client(%p)", context->tdm_client); + TPL_LOG_T("WL_EGL", "tdm_dispatch| tdm_client(%p)", context->tdm_client); tdm_err = tdm_client_handle_events(context->tdm_client); if (tdm_err) { TPL_ERR("TDM_ERROR:%d context:%p, tdm_cleint:%p\n", tdm_err, context, context->tdm_client); @@ -126,7 +104,7 @@ _twe_thread_tdm_source_destroy(gpointer user_data) { twe_thread_context* context = user_data; - TPL_DEBUG("tdm_destroy| tdm_gsource(%p) tdm_client(%p)", + TPL_LOG_T("WL_EGL", "tdm_destroy| tdm_gsource(%p) tdm_client(%p)", context->tdm_gsource, context->tdm_client); g_source_destroy(context->tdm_gsource); g_source_unref(context->tdm_gsource); @@ -172,7 +150,7 @@ twe_thread_create(void) _twe_ctx, _twe_thread_tdm_source_destroy); g_source_attach(_twe_ctx->tdm_gsource, g_main_loop_get_context(_twe_ctx->twe_loop)); - TPL_DEBUG("tdm g_source(%p) attached to twe_loop(%p)", + TPL_LOG_T("WL_EGL", "tdm g_source(%p) attached to twe_loop(%p)", _twe_ctx->tdm_gsource, _twe_ctx->twe_loop); } } @@ -181,7 +159,7 @@ twe_thread_create(void) thread->ctx = _twe_ctx; _twe_ctx->ref_cnt++; - TPL_DEBUG("_twe_ctx(%p) twe_thread(%p)", _twe_ctx, thread); + TPL_LOG_T("WL_EGL", "_twe_ctx(%p) twe_thread(%p)", _twe_ctx, thread); return thread; } @@ -203,7 +181,7 @@ twe_thread_destroy(twe_thread* thread) thread->ctx = NULL; } - TPL_DEBUG("twe_thread(%p)", thread); + TPL_LOG_T("WL_EGL", "twe_thread(%p)", thread); thread->ctx = NULL; free(thread); @@ -214,7 +192,8 @@ _twe_thread_wl_disp_prepare(GSource *source, gint *time) { twe_wl_disp_source *wl_source = (twe_wl_disp_source *)source; - TPL_DEBUG("prepare| gsource(%p) wl_display(%p)", source, wl_source->disp); + TPL_LOG_T("WL_EGL", "prepare| gsource(%p) wl_display(%p)", + source, wl_source->disp); while (wl_display_prepare_read_queue(wl_source->disp, wl_source->ev_queue) != 0) { wl_display_dispatch_queue_pending(wl_source->disp, wl_source->ev_queue); } @@ -231,12 +210,12 @@ _twe_thread_wl_disp_check(GSource *source) twe_wl_disp_source *wl_source = (twe_wl_disp_source *)source; if (wl_source->gfd.revents) { - TPL_DEBUG("read_events| gsource(%p) wl_display(%p)", + TPL_LOG_T("WL_EGL", "read_events| gsource(%p) wl_display(%p)", source, wl_source->disp); wl_display_read_events(wl_source->disp); return TRUE; } else { - TPL_DEBUG("cancel_read| gsource(%p) wl_display(%p)", + TPL_LOG_T("WL_EGL", "cancel_read| gsource(%p) wl_display(%p)", source, wl_source->disp); wl_display_cancel_read(wl_source->disp); } @@ -250,7 +229,7 @@ _twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer date) twe_wl_disp_source *wl_source = (twe_wl_disp_source *)source; if (wl_source->gfd.revents & G_IO_IN) { - TPL_DEBUG("dispatch| gsource(%p) wl_display(%p)", + TPL_LOG_T("WL_EGL", "dispatch| gsource(%p) wl_display(%p)", source, wl_source->disp); wl_display_dispatch_queue_pending(wl_source->disp, wl_source->ev_queue); } @@ -268,7 +247,7 @@ _twe_thread_wl_disp_finalize(GSource *source) wl_display_dispatch_queue_pending(wl_source->disp, wl_source->ev_queue); wl_event_queue_destroy(wl_source->ev_queue); - TPL_DEBUG("finalize| wl_event_queue(%p)", + TPL_LOG_T("WL_EGL", "finalize| wl_event_queue(%p)", wl_source->ev_queue); return; } @@ -302,7 +281,7 @@ _twe_display_init_wl_tbm_client(struct wl_display *display, wl_proxy_set_queue(wl_tbm, ev_queue); - TPL_DEBUG("wl_tbm_client init| wl_tbm_client(%p)", wl_tbm_client); + TPL_LOG_T("WL_EGL", "wl_tbm_client init| wl_tbm_client(%p)", wl_tbm_client); return wl_tbm_client; } @@ -316,7 +295,7 @@ _twe_display_fini_wl_tbm_client(struct wayland_tbm_client *wl_tbm_client) wl_proxy_set_queue(wl_tbm, NULL); } - TPL_DEBUG("wl_tbm_client deinit| wl_tbm_client(%p)", wl_tbm_client); + TPL_LOG_T("WL_EGL", "wl_tbm_client deinit| wl_tbm_client(%p)", wl_tbm_client); wayland_tbm_client_deinit(wl_tbm_client); } @@ -356,7 +335,7 @@ twe_display_add(twe_thread* thread, struct wl_display *display) g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop)); g_source_unref(&source->gsource); - TPL_DEBUG("add| gsource(%p) ev_queue(%p) wl_display(%p)", + TPL_LOG_T("WL_EGL", "add| gsource(%p) ev_queue(%p) wl_display(%p)", source, source->ev_queue, display); return (twe_display_h)source; @@ -385,7 +364,8 @@ twe_display_del(twe_display_h twe_display) g_source_destroy(&source->gsource); g_source_unref(&source->gsource); - TPL_DEBUG("del| twe_display(%p) wl_display(%p)", source, source->disp); + TPL_LOG_T("WL_EGL", "del| twe_display(%p) wl_display(%p)", + source, source->disp); return TPL_ERROR_NONE; } @@ -402,7 +382,7 @@ _twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer date) ssize_t s; uint64_t u; - TPL_DEBUG("finalize| gsource(%p) read event_fd(%d)", + TPL_LOG_T("WL_EGL", "finalize| gsource(%p) read event_fd(%d)", wl_surf_source, wl_surf_source->event_fd); s = read(wl_surf_source->event_fd, &u, sizeof(uint64_t)); if (s != sizeof(uint64_t)) @@ -420,7 +400,7 @@ _twe_thread_wl_surface_finalize(GSource *source) g_source_remove_unix_fd(source, wl_surf_source->tag); - TPL_DEBUG("gsource(%p) event_fd(%d)", + TPL_LOG_T("WL_EGL", "gsource(%p) event_fd(%d)", source, wl_surf_source->event_fd); close(wl_surf_source->event_fd); @@ -468,7 +448,12 @@ tbm_surface_queue_h twe_surface_get_tbm_queue(twe_surface_h twe_surface) { twe_wl_surf_source *source = (twe_wl_surf_source *)twe_surface; - if (!source || !source->tbm_surface_queue) { + if (!source) { + TPL_ERR("Invalid parameters. twe_surface(%p)", source); + return NULL; + } + + if (!source->tbm_surface_queue) { TPL_ERR("Invalid parameters. twe_surface(%p) tbm_surface_queue(%p)", source, source->tbm_surface_queue); return NULL; @@ -533,7 +518,8 @@ twe_surface_add(twe_thread* thread, g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop)); g_source_unref(&source->gsource); - TPL_DEBUG("gsource(%p) wl_egl_window(%p) wl_surface(%p) event_fd(%d)", + TPL_LOG_T("WL_EGL", + "gsource(%p) wl_egl_window(%p) wl_surface(%p) event_fd(%d)", source, wl_egl_window, surface, source->event_fd); return (twe_surface_h)source; @@ -561,7 +547,7 @@ twe_surface_del(twe_surface_h twe_surface) return TPL_ERROR_INVALID_PARAMETER; } - TPL_DEBUG("twe_surface(%p) wl_egl_window(%p) wl_surface(%p)", + TPL_LOG_T("WL_EGL", "twe_surface(%p) wl_egl_window(%p) wl_surface(%p)", surf_source, surf_source->wl_egl_window, surf_source->surf); if (surf_source->tbm_surface_queue) { @@ -572,7 +558,7 @@ twe_surface_del(twe_surface_h twe_surface) /* TODO : surf_source will be removed from surfaces list in disp_source */ surf_source->wl_egl_window = NULL; - surf_source->surface = NULL; + surf_source->surf = NULL; g_source_destroy(&surf_source->gsource); g_source_unref(&surf_source->gsource); @@ -587,7 +573,7 @@ static void reg_global(void *data, const char *interface, uint32_t version) { - TPL_DEBUG("reg_global: %s_v_%d\n", interface, version); + TPL_LOG_T("WL_EGL", "reg_global: %s_v_%d\n", interface, version); } -- 2.7.4 From c51e90a8da80018a87808579c49747d208cafaf0 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 17:28:22 +0900 Subject: [PATCH 03/16] tpl_wayland_egl_thread: Registered tbm_surface_queue_reset callback. - But it is only for testing, it does not do anything yet. Change-Id: I74e94267144d0727ff5ec0d97e087f7cc48b67e6 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 22b6b8a..98d8acf 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -415,6 +415,13 @@ static GSourceFuncs _twe_wl_surface_funcs = { .finalize = _twe_thread_wl_surface_finalize, }; +static void +__cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h tbm_queue, + void *data) +{ + TPL_DEBUG("tbm_queue(%p) has been reset!", tbm_queue); +} + static tbm_surface_queue_h _twe_surface_create_tbm_queue(struct wayland_tbm_client *wl_tbm_client, struct wl_egl_window* wl_egl_window) @@ -440,6 +447,15 @@ _twe_surface_create_tbm_queue(struct wayland_tbm_client *wl_tbm_client, return NULL; } + if (tbm_surface_queue_add_reset_cb(tbm_queue, + __cb_tbm_surface_queue_reset_callback, + NULL) != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to register reset callback to tbm_surface_queue(%p)", + tbm_queue); + tbm_surface_queue_destroy(tbm_queue); + return NULL; + } + return tbm_queue; } -- 2.7.4 From ddefd43abad76b59147f1e5e2e10d16daa7b5eae Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 19:24:07 +0900 Subject: [PATCH 04/16] tpl_wayland_egl_thread: Registered wl_egl_window resize callback. Change-Id: I15dbf11f280bab7e37fa699914f522b2fee6ba65 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 45 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 98d8acf..ef38f00 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -67,7 +67,7 @@ struct _twe_wl_surf_source { int event_fd; struct wl_surface *surf; struct wl_egl_window *wl_egl_window; - tbm_surface_queue_h tbm_surface_queue; + tbm_surface_queue_h tbm_queue; twe_wl_disp_source *disp_source; }; @@ -416,6 +416,32 @@ static GSourceFuncs _twe_wl_surface_funcs = { }; static void +__cb_client_window_resize_callback(struct wl_egl_window *wl_egl_window, + void *private) +{ + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + + twe_wl_surf_source *source = (twe_wl_surf_source *)private; + int cur_w, cur_h, req_w, req_h, format; + + format = tbm_surface_queue_get_format(source->tbm_queue); + cur_w = tbm_surface_queue_get_width(source->tbm_queue); + cur_h = tbm_surface_queue_get_height(source->tbm_queue); + req_w = wl_egl_window->width; + req_h = wl_egl_window->height; + + TPL_LOG_T("WL_EGL", "[RESIZE_CB] wl_egl_window(%p) (%dx%d) -> (%dx%d)", + wl_egl_window, cur_w, cur_h, req_w, req_h); + + if (tbm_surface_queue_reset(source->tbm_queue, req_w, req_h, format) + != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to reset tbm_surface_queue(%p)", source->tbm_queue); + return; + } +} + +static void __cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h tbm_queue, void *data) { @@ -469,13 +495,13 @@ twe_surface_get_tbm_queue(twe_surface_h twe_surface) return NULL; } - if (!source->tbm_surface_queue) { + if (!source->tbm_queue) { TPL_ERR("Invalid parameters. twe_surface(%p) tbm_surface_queue(%p)", - source, source->tbm_surface_queue); + source, source->tbm_queue); return NULL; } - return source->tbm_surface_queue; + return source->tbm_queue; } @@ -527,9 +553,12 @@ twe_surface_add(twe_thread* thread, G_IO_IN); source->surf = surface; source->wl_egl_window = wl_egl_window; - source->tbm_surface_queue = tbm_queue; + source->tbm_queue = tbm_queue; source->disp_source = (twe_wl_disp_source *)twe_display; + wl_egl_window->private = (void *)source; + wl_egl_window->resize_callback = (void *)__cb_client_window_resize_callback; + g_source_set_callback(&source->gsource, NULL, surface, NULL); g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop)); g_source_unref(&source->gsource); @@ -566,9 +595,9 @@ twe_surface_del(twe_surface_h twe_surface) TPL_LOG_T("WL_EGL", "twe_surface(%p) wl_egl_window(%p) wl_surface(%p)", surf_source, surf_source->wl_egl_window, surf_source->surf); - if (surf_source->tbm_surface_queue) { - tbm_surface_queue_destroy(surf_source->tbm_surface_queue); - surf_source->tbm_surface_queue = NULL; + if (surf_source->tbm_queue) { + tbm_surface_queue_destroy(surf_source->tbm_queue); + surf_source->tbm_queue = NULL; } /* TODO : surf_source will be removed from surfaces list in disp_source */ -- 2.7.4 From 9c5b660fc13ec3c867a02696b4e4373deb4fb062 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 19:39:51 +0900 Subject: [PATCH 05/16] tpl_wayland_egl_thread: Registered wl_egl_window rotate callback. Change-Id: Ie5a6afc303bf36cceca6046e053450bb9b42b04a Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index ef38f00..0a095ca 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -67,6 +67,7 @@ struct _twe_wl_surf_source { int event_fd; struct wl_surface *surf; struct wl_egl_window *wl_egl_window; + int rotation; tbm_surface_queue_h tbm_queue; twe_wl_disp_source *disp_source; }; @@ -442,6 +443,22 @@ __cb_client_window_resize_callback(struct wl_egl_window *wl_egl_window, } static void +__cb_client_window_rotate_callback(struct wl_egl_window *wl_egl_window, + void *private) +{ + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + + int rotation = wl_egl_window->rotation; + twe_wl_surf_source *source = (twe_wl_surf_source *)private; + + TPL_LOG_T("WL_EGL", "[ROTATE_CB] wl_egl_window(%p) (%d) -> (%d)", + wl_egl_window, source->rotation, rotation); + + source->rotation = rotation; +} + +static void __cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h tbm_queue, void *data) { @@ -555,9 +572,11 @@ twe_surface_add(twe_thread* thread, source->wl_egl_window = wl_egl_window; source->tbm_queue = tbm_queue; source->disp_source = (twe_wl_disp_source *)twe_display; + source->rotation = 0; wl_egl_window->private = (void *)source; wl_egl_window->resize_callback = (void *)__cb_client_window_resize_callback; + wl_egl_window->rotate_callback = (void *)__cb_client_window_rotate_callback; g_source_set_callback(&source->gsource, NULL, surface, NULL); g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop)); -- 2.7.4 From d3c933c637ac934835f3180451299909f5357bed Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 19:51:44 +0900 Subject: [PATCH 06/16] tpl_wayland_egl_thread: Added API to get rotation value. Change-Id: I444f2ef708026f42fe25f7ae1dec5994d9ad4f5f Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 12 ++++++++++++ src/tpl_wayland_egl_thread.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 0a095ca..1b99663 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -630,6 +630,18 @@ twe_surface_del(twe_surface_h twe_surface) return TPL_ERROR_NONE; } +int +twe_surface_get_rotation(twe_surface_h twe_surface) +{ + twe_wl_surf_source *source = (twe_wl_surf_source *)twe_surface; + if (!source) { + TPL_ERR("Invalid parameter. twe_surface(%p)", twe_surface); + return -1; + } + + return source->rotation; +} + #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 26f9bea..5cca186 100644 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -33,3 +33,6 @@ twe_surface_del(twe_surface_h twe_surface); tbm_surface_queue_h twe_surface_get_tbm_queue(twe_surface_h twe_surface); +int +twe_surface_get_rotation(twe_surface_h twe_surface); + -- 2.7.4 From bd82230f5ecef6de04d461810bb1dd97548f35b2 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 20:05:28 +0900 Subject: [PATCH 07/16] tpl_wayland_egl_thread: Added API to set rotation capability. Change-Id: I28fdc7cabac80155aa21fe9fdcb5ee684339d27e Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 17 +++++++++++++++++ src/tpl_wayland_egl_thread.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 1b99663..c66d290 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -68,6 +68,7 @@ struct _twe_wl_surf_source { struct wl_surface *surf; struct wl_egl_window *wl_egl_window; int rotation; + tpl_bool_t rotation_capability; tbm_surface_queue_h tbm_queue; twe_wl_disp_source *disp_source; }; @@ -573,6 +574,7 @@ twe_surface_add(twe_thread* thread, source->tbm_queue = tbm_queue; source->disp_source = (twe_wl_disp_source *)twe_display; source->rotation = 0; + source->rotation_capability = TPL_FALSE; wl_egl_window->private = (void *)source; wl_egl_window->resize_callback = (void *)__cb_client_window_resize_callback; @@ -642,6 +644,21 @@ twe_surface_get_rotation(twe_surface_h twe_surface) return source->rotation; } +void +twe_surface_set_rotation_capablity(twe_surface_h twe_surface, tpl_bool_t set) +{ + twe_wl_surf_source *source = (twe_wl_surf_source *)twe_surface; + if (!source) { + TPL_ERR("Invalid parameter. twe_surface(%p)", twe_surface); + return; + } + + TPL_LOG_T("WL_EGL", "twe_surface(%p) rotation capability set to [%s]", + source, (set ? "TRUE" : "FALSE")); + + source->rotation_capability = set; +} + #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 5cca186..405f2a7 100644 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -36,3 +36,6 @@ twe_surface_get_tbm_queue(twe_surface_h twe_surface); int twe_surface_get_rotation(twe_surface_h twe_surface); +void +twe_surface_set_rotation_capablity(twe_surface_h twe_surface, tpl_bool_t set); + -- 2.7.4 From c401d2f7b9f1211871f395b426e45549571731a8 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 20:12:26 +0900 Subject: [PATCH 08/16] tpl_wayland_egl_thread: Registered wl_egl_window get_rotation_capability callback. Change-Id: I2753c8e4b658cdc95c6992976c9db0142d5a572c Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index c66d290..4a7f899 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -459,6 +459,23 @@ __cb_client_window_rotate_callback(struct wl_egl_window *wl_egl_window, source->rotation = rotation; } +static int +__cb_client_window_get_rotation_capability(struct wl_egl_window *wl_egl_window, + void *private) +{ + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + + int rotation_capability = WL_EGL_WINDOW_CAPABILITY_NONE; + twe_wl_surf_source *source = (twe_wl_surf_source *)private; + if (source->rotation_capability == TPL_TRUE) + rotation_capability = WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED; + else + rotation_capability = WL_EGL_WINDOW_CAPABILITY_ROTATION_UNSUPPORTED; + + return rotation_capability; +} + static void __cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h tbm_queue, void *data) @@ -579,6 +596,8 @@ twe_surface_add(twe_thread* thread, wl_egl_window->private = (void *)source; wl_egl_window->resize_callback = (void *)__cb_client_window_resize_callback; wl_egl_window->rotate_callback = (void *)__cb_client_window_rotate_callback; + wl_egl_window->get_rotation_capability = (void *) + __cb_client_window_get_rotation_capability; g_source_set_callback(&source->gsource, NULL, surface, NULL); g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop)); -- 2.7.4 From c678d20afae5ede8c185af130e60af298b82650e Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 20:46:45 +0900 Subject: [PATCH 09/16] tpl_wayland_egl_thread: Registered tbm_surface_queue acquirable callback. - acquirable callback is called when tbm_surface enqueued to tbm_surface_queue. In callback function, event will be sent to thread by writing to registered event_fd. Change-Id: I424f75bf164d25678d5a6300884a97f627bb952b Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 4a7f899..ce4a472 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -483,8 +483,25 @@ __cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h tbm_queue, TPL_DEBUG("tbm_queue(%p) has been reset!", tbm_queue); } +static void +__cb_tbm_surface_queue_acquirable_callback(tbm_surface_queue_h surface_queue, + void *data) +{ + twe_wl_surf_source *source = (twe_wl_surf_source *)data; + uint64_t value = 1; + int ret; + + ret = write(source->event_fd, &value, sizeof(uint64_t)); + if (ret == -1) { + TPL_ERR("failed to send acquirable event. twe_wl_surf_source(%p)", + source); + return; + } +} + static tbm_surface_queue_h -_twe_surface_create_tbm_queue(struct wayland_tbm_client *wl_tbm_client, +_twe_surface_create_tbm_queue(twe_wl_surf_source *source, + struct wayland_tbm_client *wl_tbm_client, struct wl_egl_window* wl_egl_window) { tbm_surface_queue_h tbm_queue = NULL; @@ -517,6 +534,15 @@ _twe_surface_create_tbm_queue(struct wayland_tbm_client *wl_tbm_client, return NULL; } + if (tbm_surface_queue_add_acquirable_cb(tbm_queue, + __cb_tbm_surface_queue_acquirable_callback, + (void *)source) != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to register acquirable callback to tbm_surface_queue(%p)", + tbm_queue); + tbm_surface_queue_destroy(tbm_queue); + return NULL; + } + return tbm_queue; } @@ -560,12 +586,6 @@ twe_surface_add(twe_thread* thread, return NULL; } - if (!(tbm_queue = _twe_surface_create_tbm_queue(disp_source->wl_tbm_client, - wl_egl_window))) { - TPL_ERR("Failed to create tbm_surface_queue."); - return NULL; - } - source = (twe_wl_surf_source *)g_source_new(&_twe_wl_surface_funcs, sizeof(twe_wl_surf_source)); if (!source) { @@ -581,6 +601,14 @@ twe_surface_add(twe_thread* thread, return NULL; } + if (!(tbm_queue = _twe_surface_create_tbm_queue(source, + disp_source->wl_tbm_client, + wl_egl_window))) { + TPL_ERR("Failed to create tbm_surface_queue."); + g_source_unref(&source->gsource); + return NULL; + } + /* TODO : surface source will be listed in twe_wl_disp_source */ source->tag = g_source_add_unix_fd(&source->gsource, -- 2.7.4 From f9cd65dd5a61abbced15e33bf9fd07ca2a371ec8 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 25 Apr 2017 21:35:48 +0900 Subject: [PATCH 10/16] tpl_wayland_egl_thread: Simplified the name of internal functions. Change-Id: I6182eb953091ad5fdabd738248832dcf9ec27b9d Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 117 +++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 60 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index ce4a472..89ac01f 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -372,54 +372,8 @@ twe_display_del(twe_display_h twe_display) return TPL_ERROR_NONE; } -static gboolean -_twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer date) -{ - twe_wl_surf_source *wl_surf_source = (twe_wl_surf_source *)source; - GIOCondition cond; - - cond = g_source_query_unix_fd(source, wl_surf_source->tag); - - if (cond & G_IO_IN) { - ssize_t s; - uint64_t u; - - TPL_LOG_T("WL_EGL", "finalize| gsource(%p) read event_fd(%d)", - wl_surf_source, wl_surf_source->event_fd); - s = read(wl_surf_source->event_fd, &u, sizeof(uint64_t)); - if (s != sizeof(uint64_t)) - TPL_ERR("Failed to read from event_fd(%d)\n", - wl_surf_source->event_fd); - } - - return G_SOURCE_CONTINUE; -} - -static void -_twe_thread_wl_surface_finalize(GSource *source) -{ - twe_wl_surf_source *wl_surf_source = (twe_wl_surf_source *)source; - - g_source_remove_unix_fd(source, wl_surf_source->tag); - - TPL_LOG_T("WL_EGL", "gsource(%p) event_fd(%d)", - source, wl_surf_source->event_fd); - close(wl_surf_source->event_fd); - - return; -} - - -static GSourceFuncs _twe_wl_surface_funcs = { - .prepare = NULL, - .check = NULL, - .dispatch = _twe_thread_wl_surface_dispatch, - .finalize = _twe_thread_wl_surface_finalize, -}; - static void -__cb_client_window_resize_callback(struct wl_egl_window *wl_egl_window, - void *private) +__cb_resize_callback(struct wl_egl_window *wl_egl_window, void *private) { TPL_ASSERT(private); TPL_ASSERT(wl_egl_window); @@ -444,8 +398,7 @@ __cb_client_window_resize_callback(struct wl_egl_window *wl_egl_window, } static void -__cb_client_window_rotate_callback(struct wl_egl_window *wl_egl_window, - void *private) +__cb_rotate_callback(struct wl_egl_window *wl_egl_window, void *private) { TPL_ASSERT(private); TPL_ASSERT(wl_egl_window); @@ -460,8 +413,8 @@ __cb_client_window_rotate_callback(struct wl_egl_window *wl_egl_window, } static int -__cb_client_window_get_rotation_capability(struct wl_egl_window *wl_egl_window, - void *private) +__cb_get_rotation_capability(struct wl_egl_window *wl_egl_window, + void *private) { TPL_ASSERT(private); TPL_ASSERT(wl_egl_window); @@ -477,15 +430,15 @@ __cb_client_window_get_rotation_capability(struct wl_egl_window *wl_egl_window, } static void -__cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h tbm_queue, - void *data) +__cb_tbm_queue_reset_callback(tbm_surface_queue_h tbm_queue, + void *data) { TPL_DEBUG("tbm_queue(%p) has been reset!", tbm_queue); } static void -__cb_tbm_surface_queue_acquirable_callback(tbm_surface_queue_h surface_queue, - void *data) +__cb_tbm_queue_acquirable_callback(tbm_surface_queue_h surface_queue, + void *data) { twe_wl_surf_source *source = (twe_wl_surf_source *)data; uint64_t value = 1; @@ -499,6 +452,50 @@ __cb_tbm_surface_queue_acquirable_callback(tbm_surface_queue_h surface_queue, } } +static gboolean +_twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer date) +{ + twe_wl_surf_source *wl_surf_source = (twe_wl_surf_source *)source; + GIOCondition cond; + + cond = g_source_query_unix_fd(source, wl_surf_source->tag); + + if (cond & G_IO_IN) { + ssize_t s; + uint64_t u; + + TPL_LOG_T("WL_EGL", "finalize| gsource(%p) read event_fd(%d)", + wl_surf_source, wl_surf_source->event_fd); + s = read(wl_surf_source->event_fd, &u, sizeof(uint64_t)); + if (s != sizeof(uint64_t)) + TPL_ERR("Failed to read from event_fd(%d)", + wl_surf_source->event_fd); + } + + return G_SOURCE_CONTINUE; +} + +static void +_twe_thread_wl_surface_finalize(GSource *source) +{ + twe_wl_surf_source *wl_surf_source = (twe_wl_surf_source *)source; + + g_source_remove_unix_fd(source, wl_surf_source->tag); + + TPL_LOG_T("WL_EGL", "gsource(%p) event_fd(%d)", + source, wl_surf_source->event_fd); + close(wl_surf_source->event_fd); + + return; +} + +static GSourceFuncs _twe_wl_surface_funcs = { + .prepare = NULL, + .check = NULL, + .dispatch = _twe_thread_wl_surface_dispatch, + .finalize = _twe_thread_wl_surface_finalize, +}; + static tbm_surface_queue_h _twe_surface_create_tbm_queue(twe_wl_surf_source *source, struct wayland_tbm_client *wl_tbm_client, @@ -526,7 +523,7 @@ _twe_surface_create_tbm_queue(twe_wl_surf_source *source, } if (tbm_surface_queue_add_reset_cb(tbm_queue, - __cb_tbm_surface_queue_reset_callback, + __cb_tbm_queue_reset_callback, NULL) != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("Failed to register reset callback to tbm_surface_queue(%p)", tbm_queue); @@ -535,7 +532,7 @@ _twe_surface_create_tbm_queue(twe_wl_surf_source *source, } if (tbm_surface_queue_add_acquirable_cb(tbm_queue, - __cb_tbm_surface_queue_acquirable_callback, + __cb_tbm_queue_acquirable_callback, (void *)source) != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("Failed to register acquirable callback to tbm_surface_queue(%p)", tbm_queue); @@ -622,10 +619,10 @@ twe_surface_add(twe_thread* thread, source->rotation_capability = TPL_FALSE; wl_egl_window->private = (void *)source; - wl_egl_window->resize_callback = (void *)__cb_client_window_resize_callback; - wl_egl_window->rotate_callback = (void *)__cb_client_window_rotate_callback; + wl_egl_window->resize_callback = (void *)__cb_resize_callback; + wl_egl_window->rotate_callback = (void *)__cb_rotate_callback; wl_egl_window->get_rotation_capability = (void *) - __cb_client_window_get_rotation_capability; + __cb_get_rotation_capability; g_source_set_callback(&source->gsource, NULL, surface, NULL); g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop)); -- 2.7.4 From 20dfec69f7aed68022d43a0e4d496d92c591bcb3 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 27 Apr 2017 13:02:39 +0900 Subject: [PATCH 11/16] 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 From f4e6e86e1e927c3c69a25f31a48b1c1f1dc33513 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 27 Apr 2017 16:25:14 +0900 Subject: [PATCH 12/16] tpl_wayland_egl_thread: Added twe_surface_set_damage_region. - NEW API : twe_surface_set_damage_region(tbm_surface_h, int num_rects, const int* rects) - I expect it to be called before tbm_surface_queue_enqueue() inside tpl_surface_enqueue_buffer(). - The input parameter tbm_surface_h must be a dequeued buffer from tbm_surface_queue. - Operation : * Get twe_wl_buffer_info from tbm_surface user_data. * If buf_info->rects already exists, free this old one and re allocate new rects. Change-Id: Ib9e552dab4450caad3aa9c1e941f9190abe79252 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ src/tpl_wayland_egl_thread.h | 4 +++ 2 files changed, 69 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index eee1b5c..c1bc32a 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -83,6 +83,9 @@ struct _twe_wl_buffer_info { int dx, dy; int width, height; int rotation; + /* for damage region */ + int num_rects; + int *rects; twe_wl_surf_source *surf_source; }; @@ -795,6 +798,11 @@ twe_surface_set_buffer(twe_surface_h twe_surface, tbm_surface_h tbm_surface) buf_info->dx = wl_egl_window->dx; buf_info->dy = wl_egl_window->dy; + if (buf_info->rects) { + free(buf_info->rects); + buf_info->rects = NULL; + buf_info->num_rects = 0; + } return TPL_ERROR_NONE; } else { buf_info = (twe_wl_buffer_info *)calloc(1, sizeof(twe_wl_buffer_info)); @@ -816,6 +824,14 @@ twe_surface_set_buffer(twe_surface_h twe_surface, tbm_surface_h tbm_surface) return TPL_ERROR_INVALID_OPERATION; } + buf_info->rotation = wl_egl_window->rotation; + buf_info->dx = wl_egl_window->dx; + buf_info->dy = wl_egl_window->dy; + buf_info->width = wl_egl_window->width; + buf_info->height = wl_egl_window->height; + buf_info->num_rects = 0; + buf_info->rects = NULL; + wl_buffer_add_listener((void *)buf_info->wl_buffer, &wl_buffer_release_listener, tbm_surface); wl_display_flush(source->disp_source->disp); @@ -834,9 +850,58 @@ twe_surface_set_buffer(twe_surface_h twe_surface, tbm_surface_h tbm_surface) return TPL_ERROR_INVALID_OPERATION; } + TPL_LOG_T("WL_EGL", + "[NEW_BUF] buf_info(%p) tbm_surface(%p) bo(%d) (%dx%d) rot(%d)", + buf_info, tbm_surface, + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)), + buf_info->width, buf_info->height, buf_info->rotation); + return TPL_ERROR_NONE; } +tpl_result_t +twe_surface_set_damage_region(tbm_surface_h tbm_surface, + int num_rects, + const int *rects) +{ + twe_wl_buffer_info *buf_info = NULL; + + if (!tbm_surface || !tbm_surface_internal_is_valid(tbm_surface)) { + TPL_ERR("Invalid parameter. tbm_surface(%p)", tbm_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (num_rects == 0 || rects == NULL) { + return TPL_ERROR_NONE; + } + + tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO, + (void **)&buf_info); + if (!buf_info) { + TPL_ERR("Failed to get twe_wl_buffer_info from tbm_surface(%p)", + tbm_surface); + return TPL_ERROR_INVALID_OPERATION; + } + + /* Destroy old region if there are old region info. */ + if (buf_info->rects != NULL) { + free(buf_info->rects); + buf_info->rects = NULL; + buf_info->num_rects = 0; + } + + buf_info->rects = (int *)calloc(1, (sizeof(int) * 4 * num_rects)); + buf_info->num_rects = num_rects; + + if (!buf_info->rects) { + TPL_ERR("Failed to allocate memory fo damage rects info."); + return TPL_ERROR_INVALID_OPERATION; + } + + memcpy((char *)buf_info->rects, (char *)rects, sizeof(int) * 4 * num_rects); + + return TPL_ERROR_NONE; +} #ifdef WORKER_TEST_ONLY static void reg_global(void *data, diff --git a/src/tpl_wayland_egl_thread.h b/src/tpl_wayland_egl_thread.h index 337d80d..1173aa2 100644 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -43,3 +43,7 @@ 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); +tpl_result_t +twe_surface_set_damage_region(tbm_surface_h tbm_surface, + int num_rects, const int *rects); + -- 2.7.4 From 4e3bfff80587d37bec6b9d1f1d0550a3db22014d Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 28 Apr 2017 10:53:21 +0900 Subject: [PATCH 13/16] tpl_wayland_egl_thread: Added internal function for acquire and commit. Change-Id: Ifb322ae2623d69906c0c44ee2f6de46a807a3022 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 82 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index c1bc32a..5cd4159 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -468,6 +468,80 @@ __cb_tbm_queue_acquirable_callback(tbm_surface_queue_h surface_queue, } } +static void +_twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, + tbm_surface_h tbm_surface) +{ + twe_wl_buffer_info *buf_info = NULL; + struct wl_surface *wl_surface = surf_source->surf; + struct wl_egl_window *wl_egl_window = surf_source->wl_egl_window; + + tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO, + (void **)&buf_info); + if (!buf_info) { + TPL_ERR("Failed to get twe_wl_buffer_info from tbm_surface(%p)", + tbm_surface); + return; + } + + wl_egl_window->attached_width = buf_info->width; + wl_egl_window->attached_height = buf_info->height; + + wl_surface_attach(wl_surface, (struct wl_buffer *)buf_info->wl_buffer, + buf_info->dx, buf_info->dy); + + if (buf_info->num_rects < 1 || buf_info->rects == NULL) { + wl_surface_damage_buffer(wl_surface, + buf_info->dx, buf_info->dy, + buf_info->width, buf_info->height); + } else { + int i; + for (i = 0; i < buf_info->num_rects; i++) { + int inverted_y = + buf_info->height - (buf_info->rects[i * 4 + 1] + + buf_info->rects[i * 4 + 3]); + wl_surface_damage_buffer(wl_surface, + buf_info->rects[i * 4 + 0], + inverted_y, + buf_info->rects[i * 4 + 2], + buf_info->rects[i * 4 + 3]); + } + } + + wl_surface_commit(wl_surface); + + TPL_LOG_T("WL_EGL", "[COMMIT] wl_buffer(%p) tbm_surface(%p) bo(%d)", + buf_info->wl_buffer, tbm_surface, + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); +} + +static void +_twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) +{ + tbm_surface_h tbm_surface = NULL; + tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; + + if (!tbm_surface_queue_can_acquire(surf_source->tbm_queue, 0)) { + TPL_ERR("Received acquirable event, but nothing to commit."); + return; + } + + tsq_err = tbm_surface_queue_acquire(surf_source->tbm_queue, &tbm_surface); + if (!tbm_surface || tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to acquire from tbm_queue(%p)", + surf_source->tbm_queue); + return; + } + + tbm_surface_internal_ref(tbm_surface); + + TPL_LOG_T("WL_EGL", "[ACQ] tbm_surface(%p) bo(%d)", + tbm_surface, + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); + + _twe_thread_wl_surface_commit(surf_source, tbm_surface); +} + static gboolean _twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer date) { @@ -486,6 +560,8 @@ _twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer date) if (s != sizeof(uint64_t)) TPL_ERR("Failed to read from event_fd(%d)", wl_surf_source->event_fd); + + _twe_thread_wl_surface_acquire_and_commit(wl_surf_source); } return G_SOURCE_CONTINUE; @@ -743,9 +819,6 @@ __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); @@ -758,6 +831,9 @@ __cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer) if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) TPL_ERR("tbm_surface(%p) tsq_err(%d)", tbm_surface, tsq_err); + TPL_LOG_T("WL_EGL", "[REL] wl_buffer(%p) tbm_surface(%p) bo(%d)", + buf_info->wl_buffer, tbm_surface, + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); tbm_surface_internal_unref(tbm_surface); } -- 2.7.4 From 14e97c17ce2c5ffd375999b51ac41e0291d57ace Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 4 May 2017 12:42:11 +0900 Subject: [PATCH 14/16] tpl_wayland_egl_thread: Added implementation about waiting vblank event. Change-Id: Idc206c2be1b410fdbeea30b6c5de138810a8fc14 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 136 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 115 insertions(+), 21 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 5cd4159..b4601c1 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -74,6 +74,8 @@ struct _twe_wl_surf_source { struct wl_egl_window *wl_egl_window; int rotation; tpl_bool_t rotation_capability; + tpl_bool_t vblank_done; + tdm_client_vblank *vblank; tbm_surface_queue_h tbm_queue; twe_wl_disp_source *disp_source; }; @@ -136,6 +138,7 @@ twe_thread* twe_thread_create(void) { twe_thread *thread; + char *env = getenv("TPL_WAIT_VBLANK"); if (!_twe_ctx) { GMainContext *context; @@ -146,31 +149,44 @@ twe_thread_create(void) _twe_ctx->twe_loop = g_main_loop_new(context, FALSE); g_main_context_unref(context); - _twe_ctx->twe_thread = g_thread_new("twe_thread", _twe_thread_loop, _twe_ctx); + _twe_ctx->twe_thread = g_thread_new("twe_thread", _twe_thread_loop, + _twe_ctx); - /*Connect to tdm server*/ - _twe_ctx->tdm_client = tdm_client_create(&tdm_err); - if (!_twe_ctx->tdm_client) { - TPL_ERR("Failed to create tdm_client\n"); - } - - _twe_ctx->tdm_fd = tdm_client_get_fd(_twe_ctx->tdm_client, &_twe_ctx->tdm_fd); - if (_twe_ctx->tdm_fd < 0) { - TPL_ERR("Failed to get tdm_client fd\n"); - } else { - _twe_ctx->tdm_gsource = g_unix_fd_source_new(_twe_ctx->tdm_fd, G_IO_IN); - if (!_twe_ctx->tdm_gsource) { - TPL_ERR("Failed to create tdm_gsource\n"); + if (env == NULL || atoi(env)) { + /*Connect to tdm server*/ + _twe_ctx->tdm_client = tdm_client_create(&tdm_err); + if (!_twe_ctx->tdm_client) { + TPL_ERR("Failed to create tdm_client\n"); } - g_source_set_callback(_twe_ctx->tdm_gsource, - _twe_thread_tdm_source_dispatch, - _twe_ctx, - _twe_thread_tdm_source_destroy); - g_source_attach(_twe_ctx->tdm_gsource, g_main_loop_get_context(_twe_ctx->twe_loop)); - TPL_LOG_T("WL_EGL", "tdm g_source(%p) attached to twe_loop(%p)", - _twe_ctx->tdm_gsource, _twe_ctx->twe_loop); + TPL_LOG_T("WL_EGL", "TPL_WAIT_VBLANK:DEFAULT_ENABLED"); + + _twe_ctx->tdm_fd = tdm_client_get_fd(_twe_ctx->tdm_client, + &_twe_ctx->tdm_fd); + if (_twe_ctx->tdm_fd < 0) { + TPL_ERR("Failed to get tdm_client fd\n"); + tdm_client_destroy(_twe_ctx->tdm_client); + } else { + _twe_ctx->tdm_gsource = g_unix_fd_source_new(_twe_ctx->tdm_fd, + G_IO_IN); + if (!_twe_ctx->tdm_gsource) { + TPL_ERR("Failed to create tdm_gsource\n"); + tdm_client_destroy(_twe_ctx->tdm_client); + } + + g_source_set_callback(_twe_ctx->tdm_gsource, + _twe_thread_tdm_source_dispatch, + _twe_ctx, + _twe_thread_tdm_source_destroy); + g_source_attach(_twe_ctx->tdm_gsource, + g_main_loop_get_context(_twe_ctx->twe_loop)); + TPL_LOG_T("WL_EGL", "tdm g_source(%p) attached to twe_loop(%p)", + _twe_ctx->tdm_gsource, _twe_ctx->twe_loop); + } + } else { + TPL_LOG_T("WL_EGL", "TPL_WAIT_VBLANK:DISABLED"); } + } thread = calloc(1, sizeof(twe_thread)); @@ -469,6 +485,21 @@ __cb_tbm_queue_acquirable_callback(tbm_surface_queue_h surface_queue, } static void +__cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, + unsigned int sequence, unsigned int tv_sec, + unsigned int tv_usec, void *user_data) +{ + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)user_data; + + if (!surf_source) { + TPL_ERR("Invalid parameter. user_data(%p)", user_data); + return; + } + + surf_source->vblank_done = TPL_TRUE; +} + +static void _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, tbm_surface_h tbm_surface) { @@ -513,6 +544,19 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, TPL_LOG_T("WL_EGL", "[COMMIT] wl_buffer(%p) tbm_surface(%p) bo(%d)", buf_info->wl_buffer, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); + + if (_twe_ctx->tdm_client && surf_source->vblank) { + tdm_error tdm_err = TDM_ERROR_NONE; + tdm_err = tdm_client_vblank_wait(surf_source->vblank, + 1, /* TODO: interval */ + __cb_tdm_client_wait_vblank, + (void *)surf_source); + + if (tdm_err == TDM_ERROR_NONE) + surf_source->vblank_done = TPL_FALSE; + else + TPL_ERR("Failed to tdm_client_vblank_wait. tdm_err(%d)", tdm_err); + } } static void @@ -539,6 +583,16 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); + while (!surf_source->vblank_done) { + tdm_error tdm_err = TDM_ERROR_NONE; + + tdm_err = tdm_client_handle_events(_twe_ctx->tdm_client); + if (tdm_err != TDM_ERROR_NONE) { + TPL_ERR("Failed to tdm_client_handle_events."); + break; + } + } + _twe_thread_wl_surface_commit(surf_source, tbm_surface); } @@ -588,6 +642,38 @@ static GSourceFuncs _twe_wl_surface_funcs = { .finalize = _twe_thread_wl_surface_finalize, }; +static tdm_client_vblank* +_twe_surface_create_vblank(tdm_client *tdm_client) +{ + tdm_client_vblank *vblank = NULL; + tdm_client_output *tdm_output = NULL; + tdm_error tdm_err = TDM_ERROR_NONE; + + if (!tdm_client) { + TPL_ERR("Invalid parameter. tdm_client(%p)", tdm_client); + return NULL; + } + + tdm_output = tdm_client_get_output(tdm_client, "primary", &tdm_err); + if (!tdm_output || tdm_err != TDM_ERROR_NONE) { + TPL_ERR("Failed to get tdm_client_output. tdm_err(%d)", tdm_err); + return NULL; + } + + vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err); + if (!vblank || tdm_err != TDM_ERROR_NONE) { + TPL_ERR("Failed to create vblank. tdm_err(%d)", tdm_err); + return NULL; + } + + tdm_client_vblank_set_enable_fake(vblank, 1); + tdm_client_vblank_set_sync(vblank, 0); + + TPL_LOG_T("WL_EGL", "[VBLANK INIT] vblank(%p)", vblank); + + return vblank; +} + static tbm_surface_queue_h _twe_surface_create_tbm_queue(twe_wl_surf_source *source, struct wayland_tbm_client *wl_tbm_client, @@ -709,6 +795,8 @@ twe_surface_add(twe_thread* thread, source->disp_source = (twe_wl_disp_source *)twe_display; source->rotation = 0; source->rotation_capability = TPL_FALSE; + source->vblank = _twe_surface_create_vblank(_twe_ctx->tdm_client); + source->vblank_done = TPL_TRUE; wl_egl_window->private = (void *)source; wl_egl_window->resize_callback = (void *)__cb_resize_callback; @@ -757,6 +845,12 @@ twe_surface_del(twe_surface_h twe_surface) surf_source->tbm_queue = NULL; } + if (surf_source->vblank) { + TPL_LOG_T("WL_EGL", "[VBLANK FINI] twe_wl_surf_source(%p) vblank(%p)", + surf_source, surf_source->vblank); + tdm_client_vblank_destroy(surf_source->vblank); + } + /* TODO : surf_source will be removed from surfaces list in disp_source */ surf_source->wl_egl_window = NULL; -- 2.7.4 From f2071144b74e1be913810e7e0efea20b74449b7d Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 8 May 2017 15:23:59 +0900 Subject: [PATCH 15/16] tpl_wayland_egl_thread: Added the missing info to the twe_wl_buffer_info when it is created. Change-Id: I274ae06a2de772425bbc1800b1cd05ca7afa8052 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index b4601c1..c45fcad 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -994,6 +994,7 @@ twe_surface_set_buffer(twe_surface_h twe_surface, tbm_surface_h tbm_surface) return TPL_ERROR_INVALID_OPERATION; } + buf_info->surf_source = source; buf_info->rotation = wl_egl_window->rotation; buf_info->dx = wl_egl_window->dx; buf_info->dy = wl_egl_window->dy; -- 2.7.4 From 5ec24d41364bb5476d6e80e496d925ee7365fe67 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 8 May 2017 15:11:20 +0900 Subject: [PATCH 16/16] tpl_wayland_egl_thread: Separated the file for testing worker thread. Change-Id: Ie00ad8ca16d88b6cecccbd8ba3e86f116d21d6c2 Signed-off-by: joonbum.ko --- Makefile | 14 ++-- packaging/libtpl-egl.spec | 27 +++--- src/tpl_utils.h | 11 +++ src/tpl_wayland_egl_thread.c | 114 +------------------------ worker_test/Makefile | 39 +++++++++ worker_test/worker_test.c | 194 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 266 insertions(+), 133 deletions(-) create mode 100644 worker_test/Makefile create mode 100644 worker_test/worker_test.c diff --git a/Makefile b/Makefile index e7a334f..3747cd6 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,8 @@ ifneq ($(call is-feature-enabled,arm_atomic_operation),) CFLAGS += -DARM_ATOMIC_OPERATION endif +WAYLAND_EGL_OBJ_PATH = ../src/wayland-egl/wayland-egl.o + TPL_HEADERS += $(SRC_DIR)/tpl.h TPL_HEADERS += $(SRC_DIR)/tpl_internal.h TPL_HEADERS += $(SRC_DIR)/tpl_utils.h @@ -102,7 +104,7 @@ endif OBJS = $(TPL_SRCS:%.c=%.o) ################################################################################ -all: $(BIN_NAME) glib_wl_test +all: $(BIN_NAME) $(BIN_NAME) : $(OBJS) $(TPL_HEADERS) $(CC) -o $@ $(OBJS) -shared -Wl,-soname,$(SO_NAME) $(CFLAGS) $(LDFLAGS) @@ -111,19 +113,19 @@ $(BIN_NAME) : $(OBJS) $(TPL_HEADERS) $(CC) -c -o $@ $< $(CFLAGS) #Make for test file -glib_wl_test : $(OBJS) $(TPL_HEADERS) - $(CC) -o glib_wl_test $(SRC_DIR)/tpl_wayland_egl_thread.c -O0 $(CFLAGS) -DWORKER_TEST_ONLY $(LDFLAGS) +#glib_wl_test : $(OBJS) $(WAYLAND_EGL_OBJ_PATH) $(TPL_HEADERS) +# $(CC) -o glib_wl_test $(SRC_DIR)/tpl_wayland_egl_thread.c -O0 $(CFLAGS) $(LDFLAGS) clean: find . -name "*.o" -exec rm -vf {} \; find . -name "*~" -exec rm -vf {} \; rm -vf $(BIN_NAME) - rm -vf glib_wl_test +# rm -vf glib_wl_test install: all cp -va $(BIN_NAME) $(INST_DIR)/ - cp glib_wl_test $(bindir)/ +# cp glib_wl_test $(bindir)/ uninstall: rm -f $(INST_DIR)/$(BIN_NAME) - rm -f $(bindir)/glib_wl_test +# rm -f $(bindir)/glib_wl_test diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 0e87da9..49c626d 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -158,10 +158,6 @@ TPL_OPTIONS=${TPL_OPTIONS}-default_dump TPL_OPTIONS=${TPL_OPTIONS}-object_hash_check %endif -%if "%{ENABLE_WORKER_TEST_ONLY}" == "1" -TPL_OPTIONS=${TPL_OPTIONS}-worker_test -%endif - %ifarch %arm aarch64 TPL_OPTIONS=${TPL_OPTIONS}-arm_atomic_operation %endif @@ -190,6 +186,12 @@ make cd ../../ %endif +%if "%{ENABLE_WORKER_TEST_ONLY}" == "1" +cd worker_test/ +make +cd ../ +%endif + #tpl-test build %if "%{ENABLE_TPL_TEST}" == "1" cd tc/ @@ -208,21 +210,13 @@ mkdir -p %{buildroot} mkdir -p %{buildroot}%{_libdir} mkdir -p %{buildroot}%{_includedir} mkdir -p %{buildroot}%{_libdir}/pkgconfig -%if "%{ENABLE_WORKER_TEST_ONLY}" == "1" -mkdir -p %{buildroot}%{_bindir} -%endif export TPL_VER_MAJOR=%{TPL_VER_MAJOR} export TPL_VER_MINOR=%{TPL_VER_MINOR} export TPL_RELEASE=%{TPL_RELEASE} -%if "%{ENABLE_WORKER_TEST_ONLY}" == "1" -make install libdir=%{buildroot}%{_libdir} bindir=%{buildroot}%{_bindir} -%endif - -%if "%{ENABLE_WORKER_TEST_ONLY}" == "0" make install libdir=%{buildroot}%{_libdir} -%endif + ln -sf libtpl-egl.so.%{TPL_VER_FULL} %{buildroot}%{_libdir}/libtpl-egl.so.%{TPL_VERSION} ln -sf libtpl-egl.so.%{TPL_VERSION} %{buildroot}%{_libdir}/libtpl-egl.so.%{TPL_VER_MAJOR} ln -sf libtpl-egl.so.%{TPL_VER_MAJOR} %{buildroot}%{_libdir}/libtpl-egl.so @@ -244,6 +238,11 @@ cd src/wayland-vulkan cd - %endif +%if "%{ENABLE_WORKER_TEST_ONLY}" == "1" +mkdir -p %{buildroot}%{_bindir} +cp -arp ./worker_test/worker_test %{buildroot}%{_bindir}/worker_test +%endif + #tpl-test install %if "%{ENABLE_TPL_TEST}" == "1" mkdir -p %{buildroot}/opt/usr/tpl-test @@ -272,7 +271,7 @@ cp -a %{_builddir}/%{buildsubdir}/tc/libs/gtest/googletest/LICENSE %{buildroot}/ %{_libdir}/libtpl-egl.so.%{TPL_VER_FULL} %if "%{ENABLE_WORKER_TEST_ONLY}" == "1" -%{_bindir}/glib_wl_test +%{_bindir}/worker_test %endif #tpl-test files diff --git a/src/tpl_utils.h b/src/tpl_utils.h index f4bdb47..11aad8c 100644 --- a/src/tpl_utils.h +++ b/src/tpl_utils.h @@ -149,6 +149,17 @@ extern unsigned int tpl_dump_lvl; tpl_log_b("[TPL_" b "]", f, ##x); \ } +#define TPL_LOG_T(b, f, x...) \ + { \ + LOG_INIT(); \ + if (tpl_log_lvl > 1 && tpl_log_lvl < 4) { \ + if ((int)getpid() != (int)syscall(SYS_gettid)) \ + tpl_log_t("[TPL_" b "_T]", f, ##x); \ + else \ + tpl_log_b("[TPL_" b "]", f, ##x); \ + } \ + } + #define TPL_DEBUG(f, x...) \ { \ LOG_INIT(); \ diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index c45fcad..9022870 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -8,27 +8,10 @@ #include #include -#ifndef WORKER_TEST_ONLY -#define WORKER_TEST_ONLY -#endif - -#ifdef WORKER_TEST_ONLY -#include -#include "wayland-egl/wayland-egl-priv.h" -#include "tpl.h" #include "tpl_utils.h" - -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" #include "tpl_wayland_egl_thread.h" #include "tpl_utils.h" -#endif static int buffer_info_key; #define KEY_BUFFER_INFO (unsigned long)(&buffer_info_key) @@ -608,7 +591,7 @@ _twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer date) ssize_t s; uint64_t u; - TPL_LOG_T("WL_EGL", "finalize| gsource(%p) read event_fd(%d)", + TPL_LOG_T("WL_EGL", "dispatch| gsource(%p) read event_fd(%d)", wl_surf_source, wl_surf_source->event_fd); s = read(wl_surf_source->event_fd, &u, sizeof(uint64_t)); if (s != sizeof(uint64_t)) @@ -1074,98 +1057,3 @@ twe_surface_set_damage_region(tbm_surface_h tbm_surface, return TPL_ERROR_NONE; } -#ifdef WORKER_TEST_ONLY -static void reg_global(void *data, - struct wl_registry *wl_registry, - uint32_t name, - const char *interface, - uint32_t version) -{ - TPL_LOG_T("WL_EGL", "reg_global: %s_v_%d\n", interface, version); -} - - -static void reg_global_remove(void *data, - struct wl_registry *wl_registry, - uint32_t name) -{ -} - - -static const struct wl_registry_listener registry_listener = { - reg_global, - reg_global_remove -}; - -static gboolean -timeout_cb(gpointer data) -{ - static int count = 0; - TPL_DEBUG("TIMEOUT count:%d", ++count); - return TRUE; -} - -static GSource* -_twe_test_add_timeout(twe_thread *thread, struct wl_display *display) -{ - GSource *timeout; - timeout = g_timeout_source_new(1000); - g_source_set_callback(timeout, timeout_cb, display, NULL); - g_source_attach(timeout, g_main_loop_get_context(thread->ctx->twe_loop)); - g_source_unref(timeout); - - return timeout; -} - -static void -_twe_test_del_timeout(GSource *timeout) -{ - g_source_destroy(timeout); - g_source_unref(timeout); -} - -void -main(void) -{ - struct wl_display *display; - struct wl_registry *registry; - struct wl_event_queue *ev_queue; - int count = 0; - GSource *timeout; - twe_display_h twe_display = NULL; - - twe_thread *t_thread = NULL; - - TPL_DEBUG("[[GLIB_WL_THREAD_TEST]]"); - - /*Create the twe_thread*/ - t_thread = twe_thread_create(); - - /*Add the wl_display to twe_thread*/ - display = wl_display_connect(NULL); - ev_queue = wl_display_create_queue(display); - - wl_proxy_set_queue((struct wl_proxy *)display, ev_queue); - - registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, NULL); - - twe_display = twe_display_add(t_thread, display); - - while (1) { - sleep(1); - count++; - - if (count == 3) { - TPL_DEBUG("#### PRE_DEL"); - twe_display_del(twe_display); - TPL_DEBUG("#### DEL"); - } - } - - _twe_test_del_timeout(timeout); - twe_thread_destroy(t_thread); -} - -#endif - diff --git a/worker_test/Makefile b/worker_test/Makefile new file mode 100644 index 0000000..62e1a8c --- /dev/null +++ b/worker_test/Makefile @@ -0,0 +1,39 @@ +BIN_NAME := worker_test + +SRC_DIR = . + +CC ?= gcc + +CFLAGS += -Wall -fPIC -I$(SRC_DIR) +LDFLAGS += + +CFLAGS += -I../src + +CFLAGS += `pkg-config --cflags libtbm glib-2.0 wayland-tbm-client libtdm-client` +LDFLAGS += `pkg-config --libs libtbm glib-2.0 wayland-tbm-client libtdm-client` + +WAYLAND_EGL_OBJ_PATH = ../src/wayland-egl/wayland-egl.o + +SRCS += $(SRC_DIR)/worker_test.c +SRCS += ../src/tpl.c +SRCS += ../src/tpl_utils_hlist.c +SRCS += ../src/tpl_utils_map.c +SRCS += ../src/wayland-egl/wayland-egl.c +SRCS += ../src/tpl_wayland_egl_thread.c +HEADERS += ../src/tpl_wayland_egl_thread.h +HEADERS += ../src/tpl_utils.h +HEADERS += ../src/tpl.h + +OBJS = $(SRCS:%.c=%.o) + +all : $(BIN_NAME) + +%.o: %.c + $(CC) -c -o $@ $< $(CFLAGS) $(LDFLAGS) + +$(BIN_NAME) : $(OBJS) $(WAYLAND_EGL_OBJ_PATH) ${SRCS} $(HEADERS) + $(CC) ${SRCS} -o $@ $(CFLAGS) $(LDFLAGS) + +clean: + rm -vf $(BIN_NAME) + diff --git a/worker_test/worker_test.c b/worker_test/worker_test.c new file mode 100644 index 0000000..a91be37 --- /dev/null +++ b/worker_test/worker_test.c @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef LOG_DEFAULT_ENABLE +#define LOG_DEFAULT_ENABLE 1 +#endif + +#include "../src/tpl_utils.h" +#include "../src/tpl_wayland_egl_thread.h" + +struct Display { + struct wl_display *display; + struct wl_registry *registry; + struct wl_compositor *compositor; +}; + +struct Window { + struct Display *display; + struct wl_surface *surface; + struct wl_egl_window *wl_egl_window; +}; + +static void reg_global(void *data, + struct wl_registry *wl_registry, + uint32_t name, + const char *interface, + uint32_t version) +{ + struct Display *d = (struct Display *)data; + + if (strcmp(interface, "wl_compositor") == 0) { + d->compositor = wl_registry_bind(d->registry, name, &wl_compositor_interface, + version); + } + + printf("reg_global: %s_v_%d\n", interface, version); +} + +static void reg_global_remove(void *data, + struct wl_registry *wl_registry, + uint32_t name) +{ +} + + +static const struct wl_registry_listener registry_listener = { + reg_global, + reg_global_remove +}; + +#if 0 +static gboolean +timeout_cb(gpointer data) +{ + static int count = 0; + printf("TIMEOUT count:%d", ++count); + return TRUE; +} + +static GSource* +_twe_test_add_timeout(twe_thread *thread, struct wl_display *display) +{ + GSource *timeout; + timeout = g_timeout_source_new(1000); + g_source_set_callback(timeout, timeout_cb, display, NULL); + g_source_attach(timeout, g_main_loop_get_context(thread->ctx->twe_loop)); + g_source_unref(timeout); + + return timeout; +} + +static void +_twe_test_del_timeout(GSource *timeout) +{ + g_source_destroy(timeout); + g_source_unref(timeout); +} + +#endif + + +#define MAX_COUNT 100 +#define WIDTH 400 +#define HEIGHT 400 + +void +_paint_color(tbm_surface_h tbm_surface) +{ + tbm_surface_info_s info; + int height, stride; + unsigned char *ptr; + int i, j; + + tbm_surface_map(tbm_surface, TBM_SURF_OPTION_WRITE|TBM_SURF_OPTION_READ, + &info); + ptr = info.planes[0].ptr; + stride = info.planes[0].stride / 4; + height = tbm_surface_get_height(tbm_surface); + + for (i = 0; i < height; i++) { + for (j = 0; j < stride; j++) { + ptr[0] = 255; + ptr[1] = 0; + ptr[2] = 0; + ptr[3] = 255; + ptr += 4; + } + } + + tbm_surface_unmap(tbm_surface); +} + +void +main(void) +{ + struct wl_event_queue *ev_queue; + struct Display wl_disp = { 0 }; + struct Window wl_surf = { 0 }; + int count = 0; + twe_display_h twe_display = NULL; + twe_surface_h twe_surface = NULL; + tbm_surface_queue_h tbm_queue = NULL; + tbm_surface_h tbm_surface = NULL; + twe_thread *t_thread = NULL; + + printf("[[GLIB_WL_THREAD_TEST]]"); + + /*Create the twe_thread*/ + t_thread = twe_thread_create(); + + /*Add the wl_display to twe_thread*/ + wl_disp.display = wl_display_connect(NULL); + ev_queue = wl_display_create_queue(wl_disp.display); + + wl_proxy_set_queue((struct wl_proxy *)wl_disp.display, ev_queue); + + wl_disp.registry = wl_display_get_registry(wl_disp.display); + wl_registry_add_listener(wl_disp.registry, ®istry_listener, &wl_disp); + + wl_display_roundtrip_queue(wl_disp.display, ev_queue); + + twe_display = twe_display_add(t_thread, wl_disp.display); + + /* wl_egl_window creation */ + wl_surf.display = &wl_disp; + wl_surf.surface = wl_compositor_create_surface(wl_disp.compositor); + + wl_surf.wl_egl_window = wl_egl_window_create(wl_surf.surface, + WIDTH, HEIGHT); + + twe_surface = twe_surface_add(t_thread, twe_display, wl_surf.wl_egl_window); + + tbm_queue = twe_surface_get_tbm_queue(twe_surface); + + while (count < MAX_COUNT) { + //sleep(1); + count++; + + if (tbm_surface_queue_can_dequeue(tbm_queue, 1)) + tbm_surface_queue_dequeue(tbm_queue, &tbm_surface); + else + printf("[TEST] Failed to dequeue"); + + twe_surface_set_buffer(twe_surface, tbm_surface); + + if (tbm_surface) { + tbm_surface_internal_ref(tbm_surface); + + _paint_color(tbm_surface); + + tbm_surface_queue_enqueue(tbm_queue, tbm_surface); + + tbm_surface_internal_unref(tbm_surface); + tbm_surface = NULL; + } + } + + twe_surface_del(twe_surface); + twe_display_del(twe_display); + + twe_thread_destroy(t_thread); +} + + -- 2.7.4