From 23169352aa55eb0237b09787583c6fed51a08417 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 26 Jul 2019 17:30:07 +0900 Subject: [PATCH 01/16] Package version up to 1.6.7 Change-Id: Ifa0c8fbbddd64e071234116a86ed1e8fea4637b4 --- packaging/libtpl-egl.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index a943cea..f8de9fe 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -4,7 +4,7 @@ #TPL VERSION MACROS %define TPL_VERSION_MAJOR 1 %define TPL_VERSION_MINOR 6 -%define TPL_VERSION_PATCH 6 +%define TPL_VERSION_PATCH 7 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From c255a0a2f270c3094e3e1556f7d84b3dc081d395 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 23 Jul 2019 17:15:46 +0900 Subject: [PATCH 02/16] tbm: Added reset callback for validate checking Change-Id: If17acc9a41c589dadb4d15800d799380334c9ee7 Signed-off-by: Joonbum Ko --- src/tpl_tbm.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/tpl_tbm.c b/src/tpl_tbm.c index 33dd453..43dee96 100644 --- a/src/tpl_tbm.c +++ b/src/tpl_tbm.c @@ -37,6 +37,8 @@ struct _tpl_tbm_surface { tpl_bool_t need_worker_clear; int present_mode; + + tpl_bool_t need_reset; }; struct _tpl_tbm_buffer { @@ -429,6 +431,22 @@ __tpl_tbm_surface_destroy_swapchain(tpl_surface_t *surface) return TPL_ERROR_NONE; } +static void +__cb_tbm_queue_reset_callback(tbm_surface_queue_h tbm_queue, + void *data) +{ + tpl_tbm_surface_t *tpl_tbm_surface = (tpl_tbm_surface_t *)data; + + if (!tpl_tbm_surface) { + TPL_ERR("Invalid parameter. tpl_tbm_surface(%p)", tpl_tbm_surface); + return; + } + + TPL_LOG_B("TBM", "tbm_queue(%p) has been reset!", tbm_queue); + + tpl_tbm_surface->need_reset = TPL_TRUE; +} + static tpl_result_t __tpl_tbm_surface_init(tpl_surface_t *surface) { @@ -443,6 +461,8 @@ __tpl_tbm_surface_init(tpl_surface_t *surface) surface->backend.data = (void *)tpl_tbm_surface; + tpl_tbm_surface->need_reset = TPL_FALSE; + if (surface->type == TPL_SURFACE_TYPE_WINDOW) { if (__tpl_tbm_display_get_window_info(surface->display, surface->native_handle, &surface->width, @@ -456,6 +476,11 @@ __tpl_tbm_surface_init(tpl_surface_t *surface) __tpl_tbm_surface_queue_notify_cb, surface); + /* Set reset_callback to tbm_queue */ + tbm_surface_queue_add_reset_cb((tbm_surface_queue_h)surface->native_handle, + __cb_tbm_queue_reset_callback, + (void *)tpl_tbm_surface); + TPL_LOG_B("TBM", "[INIT] tpl_surface(%p) tpl_tbm_surface_t(%p) tbm_surface_queue(%p)", surface, tpl_tbm_surface, surface->native_handle); @@ -633,9 +658,12 @@ __tpl_tbm_surface_enqueue_buffer(tpl_surface_t *surface, static tpl_bool_t __tpl_tbm_surface_validate(tpl_surface_t *surface) { - TPL_IGNORE(surface); + tpl_tbm_surface_t *tpl_tbm_surface = (tpl_tbm_surface_t *)surface->backend.data; + tpl_bool_t ret = TPL_TRUE; + + ret = !tpl_tbm_surface->need_reset; - return TPL_TRUE; + return ret; } static tbm_surface_h @@ -646,6 +674,7 @@ __tpl_tbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, tbm_surface_queue_h tbm_queue = NULL; tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE; tpl_tbm_buffer_t *tpl_tbm_buffer = NULL; + tpl_tbm_surface_t *tpl_tbm_surface = (tpl_tbm_surface_t *)surface->backend.data; TPL_ASSERT(surface); TPL_ASSERT(surface->native_handle); @@ -684,6 +713,8 @@ __tpl_tbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, /* It will be dec when before tbm_surface_queue_enqueue called */ tbm_surface_internal_ref(tbm_surface); + tpl_tbm_surface->need_reset = TPL_FALSE; + TPL_LOG_B("TBM", "[DEQ] tpl_surface(%p) tbm_queue(%p) tbm_surface(%p) bo(%d)", surface, tbm_queue, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); -- 2.7.4 From 53501ba5df9a6ce5ecbdad983e7371287b342f6f Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Tue, 13 Aug 2019 20:38:03 +0900 Subject: [PATCH 03/16] Package version up to 1.6.8 Change-Id: Ib8adc572ea1692e36bb623f0bde4f685170b0e76 --- packaging/libtpl-egl.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index f8de9fe..1c5433c 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -4,7 +4,7 @@ #TPL VERSION MACROS %define TPL_VERSION_MAJOR 1 %define TPL_VERSION_MINOR 6 -%define TPL_VERSION_PATCH 7 +%define TPL_VERSION_PATCH 8 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From 631f0f8b3764746b14e5a03012412ac823ec96ef Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 1 Nov 2019 13:25:26 +0900 Subject: [PATCH 04/16] package version up to 1.7.0 tizen 6.0 starts here. Change-Id: I607119bcfac5f8d3e1438bbe5e784475025ff319 --- packaging/libtpl-egl.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 1c5433c..a06d7ae 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -3,8 +3,8 @@ #TPL VERSION MACROS %define TPL_VERSION_MAJOR 1 -%define TPL_VERSION_MINOR 6 -%define TPL_VERSION_PATCH 8 +%define TPL_VERSION_MINOR 7 +%define TPL_VERSION_PATCH 0 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From 30f807920870e70360bffaa3a135e09d8b5ea34d Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Mon, 26 Aug 2019 11:48:59 +0900 Subject: [PATCH 05/16] tpl_wayland_egl: set need_to_release flag before commit it is possible that get release event before need_to_rlease flag is set Change-Id: I2010350256cbaa90eaa9f506acd1748f1bd247b6 --- src/tpl_wayland_egl.c | 3 ++- src/tpl_wayland_egl_thread.c | 12 +++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 54f9402..70e37a5 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -929,10 +929,11 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, wayland_tbm_client_set_buffer_serial(wayland_egl_display->wl_tbm_client, (void *)wayland_egl_buffer->wl_proxy, wayland_egl_buffer->serial); - wl_surface_commit(wl_egl_window->surface); wayland_egl_buffer->need_to_release = TPL_TRUE; + wl_surface_commit(wl_egl_window->surface); + wl_display_flush(wayland_egl_display->wl_dpy); TPL_LOG_B("WL_EGL", diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index f3c361f..1c5d5bf 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1810,6 +1810,10 @@ _twe_thread_wl_vk_surface_commit(twe_wl_surf_source *surf_source, } } } + + /* Dependent on wl_buffer release event. */ + buf_info->need_to_release = TPL_TRUE; + wl_surface_commit(wl_surface); TRACE_MARK("[COMMIT] BO(%d)", @@ -1847,10 +1851,6 @@ _twe_thread_wl_vk_surface_commit(twe_wl_surf_source *surf_source, TPL_ERR("Failed to release tbm_surface(%p) when vk_surface_commit.", tbm_surface); } - - /* Dependent on wl_buffer release event. */ - buf_info->need_to_release = TPL_TRUE; - } static void @@ -1928,13 +1928,15 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, wayland_tbm_client_set_buffer_serial(disp_source->wl_tbm_client, (void *)buf_info->wl_buffer, buf_info->serial); + + buf_info->need_to_release = TPL_TRUE; + wl_surface_commit(wl_surface); TRACE_ASYNC_BEGIN((int)tbm_surface, "[COMMIT ~ RELEASE] BO(%d)", tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); buf_info->need_to_commit = TPL_FALSE; - buf_info->need_to_release = TPL_TRUE; TPL_LOG_T(BACKEND, "[COMMIT] wl_buffer(%p) tbm_surface(%p) bo(%d)", buf_info->wl_buffer, tbm_surface, -- 2.7.4 From 514d363d7e82fe829dce3b2774d5e503be38d561 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Mon, 26 Aug 2019 12:51:30 +0900 Subject: [PATCH 06/16] tpl_wayland_egl: check latest_transform in surface_commit if rotated buffer is canceled dequeue, wl_surface_set_buffer_transform isn't called Change-Id: I19e9b363bf21a532ae05aa6bd0dd7644e88a72ab --- src/tpl_wayland_egl.c | 32 +++++++++----------------------- src/tpl_wayland_egl_thread.c | 29 +++++++++++------------------ 2 files changed, 20 insertions(+), 41 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 70e37a5..71f90c7 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -63,7 +63,6 @@ struct _tpl_wayland_egl_buffer { int window_transform; tbm_bo bo; tpl_bool_t w_rotated; /* TRUE if need to call wayland_tbm_client_set_buffer_transform */ - tpl_bool_t rotated; /* TRUE if need to call wl_surface_set_buffer_transform */ tpl_bool_t is_new; /* for frontbuffer mode */ tpl_bool_t need_to_release; /* for checking need release */ struct wl_proxy *wl_proxy; /* wl_buffer proxy */ @@ -878,10 +877,10 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, wayland_egl_buffer->w_rotated = TPL_FALSE; } - if (wayland_egl_buffer->rotated == TPL_TRUE) { + if (wayland_egl_surface->latest_transform != wayland_egl_buffer->transform) { + wayland_egl_surface->latest_transform = wayland_egl_buffer->transform; wl_surface_set_buffer_transform(wl_egl_window->surface, wayland_egl_buffer->transform); - wayland_egl_buffer->rotated = TPL_FALSE; } wl_surface_attach(wl_egl_window->surface, (void *)wayland_egl_buffer->wl_proxy, @@ -1324,6 +1323,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->dy = wl_egl_window->dy; wayland_egl_buffer->width = wl_egl_window->width; wayland_egl_buffer->height = wl_egl_window->height; + wayland_egl_buffer->transform = tizen_private->transform; if (wayland_egl_buffer->window_transform != tizen_private->window_transform) { wayland_egl_buffer->window_transform = tizen_private->window_transform; @@ -1332,14 +1332,6 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->w_rotated = TPL_FALSE; } - if (wayland_egl_surface->latest_transform != tizen_private->transform) { - wayland_egl_surface->latest_transform = tizen_private->transform; - wayland_egl_buffer->transform = tizen_private->transform; - wayland_egl_buffer->rotated = TPL_TRUE; - } else { - wayland_egl_buffer->rotated = TPL_FALSE; - } - if (wayland_egl_surface->is_activated != is_activated) wayland_egl_buffer->is_new = TPL_TRUE; @@ -1360,10 +1352,11 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->wl_proxy, tbm_surface, tbm_bo_export(wayland_egl_buffer->bo)); TPL_LOG_B("WL_EGL", - "[DEQ] size(%dx%d) transform(%d) rotated(%s)", + "[DEQ] size(%dx%d) transform(%d) w_transform(%d) w_rotated(%s)", wayland_egl_buffer->width, wayland_egl_buffer->height, wayland_egl_buffer->transform, - wayland_egl_buffer->rotated ? "[TRUE]" : "[FALSE]"); + wayland_egl_buffer->window_transform, + wayland_egl_buffer->w_rotated ? "[TRUE]" : "[FALSE]"); if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return tbm_surface; @@ -1412,7 +1405,6 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->bo = tbm_surface_internal_get_bo(tbm_surface, 0); wayland_egl_buffer->wayland_egl_surface = wayland_egl_surface; wayland_egl_buffer->transform = tizen_private->transform; - wayland_egl_buffer->rotated = TPL_TRUE; if (wayland_egl_buffer->window_transform != tizen_private->window_transform) { wayland_egl_buffer->window_transform = tizen_private->window_transform; @@ -1421,13 +1413,6 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->w_rotated = TPL_FALSE; } - if (wayland_egl_surface->latest_transform != tizen_private->transform) { - wayland_egl_surface->latest_transform = tizen_private->transform; - wayland_egl_buffer->rotated = TPL_TRUE; - } else { - wayland_egl_buffer->rotated = TPL_FALSE; - } - /* 'is_new' flag is to check wheter it is a new buffer need to commit * in frontbuffer mode. */ wayland_egl_buffer->is_new = TPL_TRUE; @@ -1448,10 +1433,11 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou tbm_bo_export(wayland_egl_buffer->bo)); TPL_LOG_B("WL_EGL", - "[DEQ] size(%dx%d) transform(%d) rotated(%s)", + "[DEQ] size(%dx%d) transform(%d) w_transform(%d) w_rotated(%s)", wayland_egl_buffer->width, wayland_egl_buffer->height, wayland_egl_buffer->transform, - wayland_egl_buffer->rotated ? "[TRUE]" : "[FALSE]"); + wayland_egl_buffer->window_transform, + wayland_egl_buffer->w_rotated ? "[TRUE]" : "[FALSE]"); if (wayland_egl_surface->dequeued_buffers) { TPL_OBJECT_LOCK(&wayland_egl_surface->base); diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 1c5d5bf..99b36b2 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -145,7 +145,6 @@ struct _twe_wl_buffer_info { tpl_bool_t w_rotated; /* for wl_surface_set_buffer_transform */ int transform; - tpl_bool_t rotated; /* for damage region */ int num_rects; int *rects; @@ -1382,11 +1381,6 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info->w_rotated = TPL_TRUE; } - if (surf_source->latest_transform != tizen_private->transform) { - surf_source->latest_transform = tizen_private->transform; - buf_info->rotated = TPL_TRUE; - } - buf_info->transform = tizen_private->transform; buf_info->dx = wl_egl_window->dx; buf_info->dy = wl_egl_window->dy; @@ -1419,10 +1413,12 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); TPL_LOG_T(BACKEND, - "[REUSE_BUF] buf_info(%p) tbm_surface(%p) bo(%d) (%dx%d) transform(%d)", + "[REUSE_BUF] buf_info(%p) tbm_surface(%p) bo(%d) (%dx%d) " + "transform(%d) w_transform(%d)", buf_info, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)), - buf_info->width, buf_info->height, buf_info->transform); + buf_info->width, buf_info->height, + buf_info->transform, buf_info->w_transform); return; } @@ -1454,11 +1450,6 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info->w_rotated = TPL_TRUE; } - if (surf_source->latest_transform != tizen_private->transform) { - surf_source->latest_transform = tizen_private->transform; - buf_info->rotated = TPL_TRUE; - } - buf_info->transform = tizen_private->transform; if (surf_source->set_serial_is_used) { @@ -1481,7 +1472,7 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info->height = surf_source->swapchain_properties.height; buf_info->w_transform = 0; buf_info->w_rotated = TPL_FALSE; - buf_info->rotated = TPL_FALSE; + buf_info->transform = 0; buf_info->serial = 0; } @@ -1522,10 +1513,12 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, TRACE_MARK("[SET_BUFFER_INFO] BO(%d)", tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); TPL_LOG_T(BACKEND, - "[NEW_BUF] buf_info(%p) tbm_surface(%p) bo(%d) (%dx%d) transform(%d)", + "[NEW_BUF] buf_info(%p) tbm_surface(%p) bo(%d) (%dx%d) " + "transform(%d) w_transform(%d)", buf_info, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)), - buf_info->width, buf_info->height, buf_info->transform); + buf_info->width, buf_info->height, + buf_info->transform, buf_info->w_transform); } static void @@ -1881,9 +1874,9 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, buf_info->w_rotated = TPL_FALSE; } - if (buf_info->rotated == TPL_TRUE) { + if (surf_source->latest_transform != buf_info->transform) { + surf_source->latest_transform = buf_info->transform; wl_surface_set_buffer_transform(wl_surface, buf_info->transform); - buf_info->rotated = TPL_FALSE; } if (wl_egl_window) { -- 2.7.4 From 16c88f212c6ec2642e6308f9baf77a12771495de Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Tue, 6 Aug 2019 19:53:07 +0900 Subject: [PATCH 07/16] tpl_surface: set post_interval in tdm_client_vblank_wait Change-Id: Ib936a993439f0bb3ab4c2d5049204305da013142 --- src/tpl_internal.h | 1 + src/tpl_surface.c | 19 +++++++++++++++++-- src/tpl_wayland_egl.c | 2 +- src/tpl_wayland_egl_thread.c | 23 ++++++++++++++++++++++- src/tpl_wayland_egl_thread.h | 2 ++ src/tpl_wl_egl_thread.c | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 4 deletions(-) mode change 100644 => 100755 src/tpl_internal.h mode change 100644 => 100755 src/tpl_surface.c mode change 100644 => 100755 src/tpl_wayland_egl.c mode change 100644 => 100755 src/tpl_wayland_egl_thread.c mode change 100644 => 100755 src/tpl_wayland_egl_thread.h mode change 100644 => 100755 src/tpl_wl_egl_thread.c diff --git a/src/tpl_internal.h b/src/tpl_internal.h old mode 100644 new mode 100755 index 6dff22f..ba161c9 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -110,6 +110,7 @@ struct _tpl_surface_backend { tpl_result_t (*destroy_swapchain)(tpl_surface_t *surface); tpl_result_t (*set_rotation_capability)(tpl_surface_t *surface, tpl_bool_t set); + tpl_result_t (*set_post_interval)(tpl_surface_t *surface, int post_interval); }; struct _tpl_object { diff --git a/src/tpl_surface.c b/src/tpl_surface.c old mode 100644 new mode 100755 index 8c14e82..994aec3 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -243,16 +243,29 @@ tpl_surface_validate(tpl_surface_t *surface) tpl_result_t tpl_surface_set_post_interval(tpl_surface_t *surface, int interval) { + tpl_result_t ret = TPL_ERROR_NONE; + if (!surface || (surface->type != TPL_SURFACE_TYPE_WINDOW)) { TPL_ERR("Invalid surface!"); return TPL_ERROR_INVALID_PARAMETER; } + if (interval <= 0) + return TPL_ERROR_NONE; + TPL_OBJECT_LOCK(surface); - surface->post_interval = interval; + + if (surface->backend.set_post_interval) + ret = surface->backend.set_post_interval(surface, interval); + + if (ret == TPL_ERROR_NONE) + surface->post_interval = interval; + TPL_OBJECT_UNLOCK(surface); - return TPL_ERROR_NONE; + TPL_LOG_F("tpl_surface_t(%p) post_interval(%d)", surface, surface->post_interval); + + return ret; } int @@ -269,6 +282,8 @@ tpl_surface_get_post_interval(tpl_surface_t *surface) interval = surface->post_interval; TPL_OBJECT_UNLOCK(surface); + TPL_LOG_F("tpl_surface_t(%p) post_interval(%d)", surface, interval); + return interval; } diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c old mode 100644 new mode 100755 index 71f90c7..69b34de --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -962,7 +962,7 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, if (wayland_egl_display->tdm_client) { int tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); tdm_err = tdm_client_vblank_wait(wayland_egl_surface->tdm_vblank, - 1, /* interval */ + surface->post_interval, /* interval */ __cb_tdm_client_wait_vblank, /* handler */ surface->backend.data); /* user_data */ diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c old mode 100644 new mode 100755 index 99b36b2..13a6a14 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -134,6 +134,8 @@ struct _twe_wl_surf_source { GMutex sub_thread_mutex; GCond sub_thread_cond; int draw_done_count; + + int post_interval; }; struct _twe_wl_buffer_info { @@ -1739,7 +1741,7 @@ _twe_surface_wait_vblank(twe_wl_surf_source *surf_source) } tdm_err = tdm_client_vblank_wait(surf_source->vblank, - 1, /* TODO: interval */ + surf_source->post_interval, /* TODO: interval */ __cb_tdm_client_wait_vblank, (void *)surf_source); @@ -2498,6 +2500,8 @@ twe_surface_add(twe_thread* thread, source->set_serial_is_used = TPL_FALSE; source->serial = 0; + source->post_interval = 1; + if (!disp_source->is_vulkan_dpy) { struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)native_handle; @@ -3371,3 +3375,20 @@ twe_get_native_buffer_from_pixmap(tpl_handle_t pixmap) return tbm_surface; } +tpl_result_t +twe_surface_set_post_interval(twe_surface_h twe_surface, int post_interval) +{ + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface; + + if (!surf_source || g_source_is_destroyed(&surf_source->gsource)) { + TPL_ERR("Invalid parameter. surf_source(%p)", surf_source); + return TPL_ERROR_INVALID_PARAMETER; + } + + surf_source->post_interval = post_interval; + + TPL_LOG_T(BACKEND, "surf_source(%p) post_interval(%d)", + surf_source, surf_source->post_interval); + + return TPL_ERROR_NONE; +} diff --git a/src/tpl_wayland_egl_thread.h b/src/tpl_wayland_egl_thread.h old mode 100644 new mode 100755 index 6cb9116..067def1 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -110,3 +110,5 @@ twe_get_native_window_info(tpl_handle_t window, int *width, int *height, tbm_for tbm_surface_h twe_get_native_buffer_from_pixmap(tpl_handle_t pixmap); +tpl_result_t +twe_surface_set_post_interval(twe_surface_h twe_surface, int post_interval); diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c old mode 100644 new mode 100755 index 4ebe168..980c599 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -477,6 +477,36 @@ __tpl_wl_egl_surface_set_rotation_capability(tpl_surface_t *surface, } static tpl_result_t +__tpl_wl_egl_surface_set_post_interval(tpl_surface_t *surface, + int post_interval) +{ + tpl_wayland_egl_surface_t *wayland_egl_surface = NULL; + + if (!surface) { + TPL_ERR("Invalid parameter. tpl_surface(%p)", surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + wayland_egl_surface = (tpl_wayland_egl_surface_t *)surface->backend.data; + if (!wayland_egl_surface) { + TPL_ERR("Invalid parameter. wayland_egl_surface(%p)", + wayland_egl_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (!wayland_egl_surface->twe_surface) { + TPL_ERR("Invalid parameter. wayland_egl_surface(%p) twe_surface(%p)", + wayland_egl_surface, wayland_egl_surface->twe_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + twe_surface_set_post_interval(wayland_egl_surface->twe_surface, + post_interval); + + return TPL_ERROR_NONE; +} + +static tpl_result_t __tpl_wl_egl_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, const int *rects, tbm_fd sync_fence) @@ -805,5 +835,7 @@ __tpl_surface_init_backend_wl_egl_thread(tpl_surface_backend_t *backend) backend->enqueue_buffer = __tpl_wl_egl_surface_enqueue_buffer; backend->set_rotation_capability = __tpl_wl_egl_surface_set_rotation_capability; + backend->set_post_interval = + __tpl_wl_egl_surface_set_post_interval; } -- 2.7.4 From 1192f77560a082299b777867cc143ae5463963d5 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Fri, 8 Nov 2019 13:30:39 +0900 Subject: [PATCH 08/16] Package version up to 1.7.1 Change-Id: Ifa18b79ce7d511e8d294fe59ab0713e36123b111 Signed-off-by: Joonbum Ko --- packaging/libtpl-egl.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index a06d7ae..7b4b3eb 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -4,7 +4,7 @@ #TPL VERSION MACROS %define TPL_VERSION_MAJOR 1 %define TPL_VERSION_MINOR 7 -%define TPL_VERSION_PATCH 0 +%define TPL_VERSION_PATCH 1 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From 1d38c642bbc5d42ff5d987aad1b01a7ed136f317 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Mon, 11 Nov 2019 11:38:59 +0900 Subject: [PATCH 09/16] Rename the directory of wayland-egl to wayland-egl-tizen. Change-Id: I4e2c8f4764a26ace10c26e0b55db9e6118d38a41 Signed-off-by: Joonbum Ko --- Makefile.am | 4 ++-- configure.ac | 2 +- src/tpl_wayland_egl.c | 4 ++-- src/tpl_wayland_egl_thread.c | 4 ++-- src/{wayland-egl => wayland-egl-tizen}/Makefile.am | 0 src/{wayland-egl => wayland-egl-tizen}/wayland-egl-tizen-priv.h | 0 src/{wayland-egl => wayland-egl-tizen}/wayland-egl-tizen.c | 0 src/{wayland-egl => wayland-egl-tizen}/wayland-egl-tizen.h | 0 tc/Makefile.am | 2 +- worker_test/Makefile | 9 +++------ 10 files changed, 11 insertions(+), 14 deletions(-) rename src/{wayland-egl => wayland-egl-tizen}/Makefile.am (100%) rename src/{wayland-egl => wayland-egl-tizen}/wayland-egl-tizen-priv.h (100%) rename src/{wayland-egl => wayland-egl-tizen}/wayland-egl-tizen.c (100%) rename src/{wayland-egl => wayland-egl-tizen}/wayland-egl-tizen.h (100%) diff --git a/Makefile.am b/Makefile.am index 66af45b..57ca9b8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,10 @@ if WITH_UTEST SUBDIRS = src \ - src/wayland-egl \ + src/wayland-egl-tizen \ tc \ pkgconfig else SUBDIRS = src \ - src/wayland-egl \ + src/wayland-egl-tizen \ pkgconfig endif diff --git a/configure.ac b/configure.ac index 8a4f706..077366e 100644 --- a/configure.ac +++ b/configure.ac @@ -212,7 +212,7 @@ AC_CHECK_FUNCS([clock_gettime memset]) AC_CONFIG_FILES([ Makefile src/Makefile - src/wayland-egl/Makefile + src/wayland-egl-tizen/Makefile pkgconfig/Makefile pkgconfig/tpl-egl.pc pkgconfig/wayland-egl-tizen.pc diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 69b34de..d3d4d38 100755 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -2,8 +2,8 @@ #include #include -#include "wayland-egl/wayland-egl-tizen.h" -#include "wayland-egl/wayland-egl-tizen-priv.h" +#include "wayland-egl-tizen/wayland-egl-tizen.h" +#include "wayland-egl-tizen/wayland-egl-tizen-priv.h" #undef inline diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 13a6a14..dca6597 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -13,8 +13,8 @@ #include "tpl_utils.h" #include "tpl_internal.h" -#include "wayland-egl/wayland-egl-tizen.h" -#include "wayland-egl/wayland-egl-tizen-priv.h" +#include "wayland-egl-tizen/wayland-egl-tizen.h" +#include "wayland-egl-tizen/wayland-egl-tizen-priv.h" #include "tpl_wayland_egl_thread.h" #include "wayland-vulkan/wayland-vulkan-client-protocol.h" #include "tpl_utils.h" diff --git a/src/wayland-egl/Makefile.am b/src/wayland-egl-tizen/Makefile.am similarity index 100% rename from src/wayland-egl/Makefile.am rename to src/wayland-egl-tizen/Makefile.am diff --git a/src/wayland-egl/wayland-egl-tizen-priv.h b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h similarity index 100% rename from src/wayland-egl/wayland-egl-tizen-priv.h rename to src/wayland-egl-tizen/wayland-egl-tizen-priv.h diff --git a/src/wayland-egl/wayland-egl-tizen.c b/src/wayland-egl-tizen/wayland-egl-tizen.c similarity index 100% rename from src/wayland-egl/wayland-egl-tizen.c rename to src/wayland-egl-tizen/wayland-egl-tizen.c diff --git a/src/wayland-egl/wayland-egl-tizen.h b/src/wayland-egl-tizen/wayland-egl-tizen.h similarity index 100% rename from src/wayland-egl/wayland-egl-tizen.h rename to src/wayland-egl-tizen/wayland-egl-tizen.h diff --git a/tc/Makefile.am b/tc/Makefile.am index 0c864ed..574dd53 100644 --- a/tc/Makefile.am +++ b/tc/Makefile.am @@ -26,4 +26,4 @@ tpl_test_LDFLAGS = ${LDFLAGS} \ @TPL_TEST_LIBS@ tpl_test_LDADD = ../src/libtpl-egl.la \ - ../src/wayland-egl/libwayland-egl.la + ../src/wayland-egl-tizen/libwayland-egl-tizen.la diff --git a/worker_test/Makefile b/worker_test/Makefile index b6989e7..7caa717 100644 --- a/worker_test/Makefile +++ b/worker_test/Makefile @@ -9,17 +9,14 @@ LDFLAGS += CFLAGS += -I../src -CFLAGS += `pkg-config --cflags libtbm glib-2.0 wayland-tbm-client wayland-tbm-server libtdm-client` -LDFLAGS += `pkg-config --libs libtbm glib-2.0 wayland-tbm-client wayland-tbm-server libtdm-client` - -WAYLAND_EGL_OBJ_PATH = ../src/wayland-egl/wayland-egl.o +CFLAGS += `pkg-config --cflags libtbm glib-2.0 wayland-tbm-client wayland-tbm-server libtdm-client wayland-egl` +LDFLAGS += `pkg-config --libs libtbm glib-2.0 wayland-tbm-client wayland-tbm-server libtdm-client wayland-egl` SRCS += $(SRC_DIR)/worker_test.c SRCS += ../src/tpl.c SRCS += ../src/tpl_utils_hlist.c SRCS += ../src/tpl_utils_map.c SRCS += ../src/tpl_object.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 @@ -33,7 +30,7 @@ all : $(BIN_NAME) %.o: %.c $(CC) -c -o $@ $< $(CFLAGS) $(LDFLAGS) -$(BIN_NAME) : $(OBJS) $(WAYLAND_EGL_OBJ_PATH) ${SRCS} $(HEADERS) +$(BIN_NAME) : $(OBJS) ${SRCS} $(HEADERS) $(CC) ${SRCS} -o $@ $(CFLAGS) $(LDFLAGS) clean: -- 2.7.4 From f05d29898d4ef28372a701b7f464c1d6e6c70c45 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Mon, 11 Nov 2019 13:32:48 +0900 Subject: [PATCH 10/16] wayland-egl-tizen: Added new API to create render sync fd. New API wl_egl_window_tizen_get_render_sync_fd(struct wl_egl_window*) /** * Create a sync fence fd that can tell render done. * * If eglSwapBuffers works async, it returns fd which tells * when the render job is finished. * This fd can wait asynchronously via poll or select. * * Important * * This requires the following premise: * - After ddk calls libplpl-egl's tpl_surface_dequeue_buffer to get the buffer, * and until it calls tpl_surface_enqueue_buffer, * it is called the gpu rendering job interval. * - Therefore, when using the dma_buf implicit fence, * there is no guarantee that the rendering job is finished * with the fence obtained through this API. * * The fence_fd obtained through this function is one-time available, * can not be reused, so caller must close it when finished using it. * * @param egl_window handle to wl_egl_window. * @return sync fd on success, -1 on failure. */ Change-Id: Ia19f88108cfe8d0e5e6477acbd83a2df173f5507 Signed-off-by: Joonbum Ko --- src/wayland-egl-tizen/wayland-egl-tizen-priv.h | 2 ++ src/wayland-egl-tizen/wayland-egl-tizen.c | 24 +++++++++++++++++++++++- src/wayland-egl-tizen/wayland-egl-tizen.h | 26 ++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h index 5b65a70..69df3bc 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h +++ b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h @@ -22,6 +22,7 @@ struct tizen_private { int (*get_rotation_capability)(struct wl_egl_window *, void *); void (*set_frontbuffer_callback)(struct wl_egl_window *, void *, int); void (*set_window_serial_callback)(struct wl_egl_window *, void *, unsigned int); + int (*create_render_sync_fd)(struct wl_egl_window *, void *); }; static struct tizen_private* tizen_private_create() @@ -40,6 +41,7 @@ static struct tizen_private* tizen_private_create() private->get_rotation_capability = NULL; private->set_window_serial_callback = NULL; private->set_frontbuffer_callback = NULL; + private->create_render_sync_fd = NULL; } return private; diff --git a/src/wayland-egl-tizen/wayland-egl-tizen.c b/src/wayland-egl-tizen/wayland-egl-tizen.c index 4c127bc..888f8af 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen.c +++ b/src/wayland-egl-tizen/wayland-egl-tizen.c @@ -250,4 +250,26 @@ wl_egl_window_tizen_set_window_serial(struct wl_egl_window *egl_window, if (private->set_window_serial_callback) private->set_window_serial_callback(egl_window, egl_window->driver_private, serial); -} \ No newline at end of file +} + +int +wl_egl_window_tizen_create_render_sync_fd(struct wl_egl_window *egl_window) +{ + struct tizen_private *private = NULL; + + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return -1; + } + + private = egl_window->driver_private; + if (private == NULL) { + WL_EGL_ERR("wl_egl_window(%p) dirver_private is NULL", egl_window); + return -1; + } + + if (private->create_render_sync_fd) + return private->create_render_sync_fd(egl_window, egl_window->driver_private); + + return -1; +} diff --git a/src/wayland-egl-tizen/wayland-egl-tizen.h b/src/wayland-egl-tizen/wayland-egl-tizen.h index b305e27..96127a0 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen.h +++ b/src/wayland-egl-tizen/wayland-egl-tizen.h @@ -73,6 +73,32 @@ void wl_egl_window_tizen_set_window_serial(struct wl_egl_window *egl_window, unsigned int serial); +/* temporary APIs for testing sync feature */ +/** + * Create a sync fence fd that can tell render done. + * + * If eglSwapBuffers works async, it returns fd which tells + * when the render job is finished. + * This fd can wait asynchronously via poll or select. + * + * Important * + * This requires the following premise: + * - After ddk calls libplpl-egl's tpl_surface_dequeue_buffer to get the buffer, + * and until it calls tpl_surface_enqueue_buffer, + * it is called the gpu rendering job interval. + * - Therefore, when using the dma_buf implicit fence, + * there is no guarantee that the rendering job is finished + * with the fence obtained through this API. + * + * The fence_fd obtained through this function is one-time available, + * can not be reused, so caller must close it when finished using it. + * + * @param egl_window handle to wl_egl_window. + * @return sync fd on success, -1 on failure. + */ +int +wl_egl_window_tizen_create_render_sync_fd(struct wl_egl_window *egl_window); + #ifdef __cplusplus } #endif -- 2.7.4 From 94f58f690824087365bf7835f7d5d4859e772063 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 12 Nov 2019 11:27:07 +0900 Subject: [PATCH 11/16] tpl_wayland_egl_thread: Implemented the render sync feature. - Create a timeline in surface units and create a sync fence to pass to the user. - The sync fence user get is signaled at the time of tpl surface enqueue. - This feature can help user sync by telling gpu render done, but this feature alone does not guarantee sync. Therefore, users should handle this sync_fence properly using poll or select. Change-Id: If1c8a894fc8e103141b88d4479274f926753e52f Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index dca6597..101cf8f 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -78,6 +78,7 @@ struct _twe_wl_disp_source { twe_del_source *disp_del_source; twe_thread *thread; GMutex wl_event_mutex; + /* TODO : surface list */ }; @@ -120,6 +121,10 @@ struct _twe_wl_surf_source { twe_wl_disp_source *disp_source; twe_del_source *surf_del_source; + tbm_fd render_sync_timeline; + int render_sync_timestamp; + unsigned int render_sync_fence_number; + GMutex surf_mutex; GMutex free_queue_mutex; @@ -1221,6 +1226,41 @@ __cb_set_window_serial_callback(struct wl_egl_window *wl_egl_window, } } +static int +__cb_create_render_sync_fd(struct wl_egl_window *wl_egl_window, void *private) +{ + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + + struct tizen_private *tizen_private = (struct tizen_private *)private; + twe_wl_surf_source *surf_source = NULL; + + tbm_fd render_sync_fd = -1; + + surf_source = (twe_wl_surf_source *)tizen_private->data; + if (!surf_source) { + TPL_ERR("Invalid parameter. twe_surface(%p)", surf_source); + return -1; + } + + if (surf_source->render_sync_timeline != -1) { + char name[32]; + snprintf(name, 32, "%u", surf_source->render_sync_fence_number++); + render_sync_fd = tbm_sync_fence_create(surf_source->render_sync_timeline, + name, + surf_source->render_sync_timestamp + 1); + TPL_DEBUG("[RENDER_SYNC] surf_source(%p) timeline(%d) timestamp(%d) name(%s) sync_fence(%d)", + surf_source, surf_source->render_sync_timeline, surf_source->render_sync_timestamp, + name, render_sync_fd); + + TRACE_ASYNC_BEGIN(surf_source->render_sync_timestamp + 1, "[SYNC_FENCE]"); + + return render_sync_fd; + } + + return -1; +} + static void __cb_tss_flusher_flush_callback(void *data, struct tizen_surface_shm_flusher *tss_flusher) @@ -1554,6 +1594,18 @@ _twe_surface_trace_enqueue_buffer(twe_wl_surf_source *surf_source, return; } + if (surf_source->render_sync_timeline != -1) { + + surf_source->render_sync_timestamp++; + TRACE_ASYNC_END(surf_source->render_sync_timestamp, "[SYNC_FENCE]"); + + TPL_DEBUG("[RENDER_SYNC][INC] surf_source(%p) timeline(%d) timestamp(%d)", + surf_source, surf_source->render_sync_timeline, surf_source->render_sync_timestamp); + if (!tbm_sync_timeline_inc(surf_source->render_sync_timeline, 1)) { + TPL_ERR("Failed to increase timeline(%d)", surf_source->render_sync_timeline); + } + } + if (surf_source->in_use_buffers) { g_mutex_lock(&surf_source->surf_mutex); /* Stop tracking of this canceled tbm_surface */ @@ -2502,6 +2554,10 @@ twe_surface_add(twe_thread* thread, source->post_interval = 1; + source->render_sync_timeline = tbm_sync_timeline_create(); + source->render_sync_timestamp = 0; + source->render_sync_fence_number = 0; + if (!disp_source->is_vulkan_dpy) { struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)native_handle; @@ -2521,6 +2577,7 @@ twe_surface_add(twe_thread* thread, __cb_get_rotation_capability; private->set_window_serial_callback = (void *) __cb_set_window_serial_callback; + private->create_render_sync_fd = (void *)__cb_create_render_sync_fd; source->latest_transform = private->transform; -- 2.7.4 From 76696ef8252c097185b333aa0472fa3e89f72f5e Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 13 Nov 2019 11:40:23 +0900 Subject: [PATCH 12/16] wayland-egl-tizen: Added new API to get presentation sync fd. /** * Create a sync fence fd that can tell presentation done. * * It returns fd which tells when the presentation is finished. * This fd can wait asynchronously via poll or select. * * Important * * This fence lets caller knows when wl_surface received PRESENT or DISCARD * events from the server. * In case of receiving DISCARD, it is not actually displayed on the display, * but it releases the fence like PRESENT. * In most cases that are not complicated, attached buffer will not be discarded. * * @param egl_window handle to wl_egl_window. * @return sync fd on success, -1 on failure. */ int wl_egl_window_tizen_create_presentation_sync_fd(struct wl_egl_window *egl_window) Change-Id: I9c69dea4b78aba34db284b25dd47dd0544672bb4 Signed-off-by: Joonbum Ko --- src/wayland-egl-tizen/wayland-egl-tizen-priv.h | 2 ++ src/wayland-egl-tizen/wayland-egl-tizen.c | 22 ++++++++++++++++++++++ src/wayland-egl-tizen/wayland-egl-tizen.h | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h index 69df3bc..6fd31ea 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h +++ b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h @@ -23,6 +23,7 @@ struct tizen_private { void (*set_frontbuffer_callback)(struct wl_egl_window *, void *, int); void (*set_window_serial_callback)(struct wl_egl_window *, void *, unsigned int); int (*create_render_sync_fd)(struct wl_egl_window *, void *); + int (*create_presentation_sync_fd)(struct wl_egl_window *, void *); }; static struct tizen_private* tizen_private_create() @@ -42,6 +43,7 @@ static struct tizen_private* tizen_private_create() private->set_window_serial_callback = NULL; private->set_frontbuffer_callback = NULL; private->create_render_sync_fd = NULL; + private->create_presentation_sync_fd = NULL; } return private; diff --git a/src/wayland-egl-tizen/wayland-egl-tizen.c b/src/wayland-egl-tizen/wayland-egl-tizen.c index 888f8af..831951c 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen.c +++ b/src/wayland-egl-tizen/wayland-egl-tizen.c @@ -273,3 +273,25 @@ wl_egl_window_tizen_create_render_sync_fd(struct wl_egl_window *egl_window) return -1; } + +int +wl_egl_window_tizen_create_presentation_sync_fd(struct wl_egl_window *egl_window) +{ + struct tizen_private *private = NULL; + + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return -1; + } + + private = egl_window->driver_private; + if (private == NULL) { + WL_EGL_ERR("wl_egl_window(%p) dirver_private is NULL", egl_window); + return -1; + } + + if (private->create_presentation_sync_fd) + return private->create_presentation_sync_fd(egl_window, egl_window->driver_private); + + return -1; +} diff --git a/src/wayland-egl-tizen/wayland-egl-tizen.h b/src/wayland-egl-tizen/wayland-egl-tizen.h index 96127a0..00b8b75 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen.h +++ b/src/wayland-egl-tizen/wayland-egl-tizen.h @@ -99,6 +99,25 @@ wl_egl_window_tizen_set_window_serial(struct wl_egl_window *egl_window, int wl_egl_window_tizen_create_render_sync_fd(struct wl_egl_window *egl_window); +/** + * Create a sync fence fd that can tell presentation done. + * + * It returns fd which tells when the presentation is finished. + * This fd can wait asynchronously via poll or select. + * + * Important * + * This fence lets caller knows when wl_surface received PRESENT or DISCARD + * events from the server. + * In case of receiving DISCARD, it is not actually displayed on the display, + * but it releases the fence like PRESENT. + * In most cases that are not complicated, attached buffer will not be discarded. + * + * @param egl_window handle to wl_egl_window. + * @return sync fd on success, -1 on failure. + */ +int +wl_egl_window_tizen_create_presentation_sync_fd(struct wl_egl_window *egl_window); + #ifdef __cplusplus } #endif -- 2.7.4 From e32a763836f8e61b9c3a00e62a975193e761fae6 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 14 Nov 2019 19:31:42 +0900 Subject: [PATCH 13/16] tpl_wayland_egl_thread: Implemented the presentation sync feature. - Create a timeline in surface and create a sync fence to pass to the user. - The sync fence user get is signaled at the time of presentation done. - This feature can help user sync by telling presentation done. Users should handle this sync_fence properly using poll or select. - This patch depends on wayland-extension and enlightenment. Change-Id: I180ac6b23cc89ed3f7f0ebfc934893efa873dd6a Signed-off-by: Joonbum Ko --- configure.ac | 2 +- packaging/libtpl-egl.spec | 1 + src/tpl_wayland_egl_thread.c | 175 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 077366e..7a761bb 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ AC_ARG_WITH([wayland], [with_wayland=yes]) AS_IF([test "${with_wayland}" = "yes" || test "${with_wayland}" = "1"], - [PKG_CHECK_MODULES([TPL_WL], [libtdm-client wayland-tbm-client wayland-tbm-server tizen-surface-client glib-2.0 wayland-egl wayland-egl-backend]) + [PKG_CHECK_MODULES([TPL_WL], [libtdm-client wayland-tbm-client wayland-tbm-server tizen-surface-client glib-2.0 wayland-egl presentation-time-client wayland-egl-backend]) TPL_CFLAGS+="$TPL_WL_CFLAGS" TPL_CFLAGS+=" -DTPL_WINSYS_WL=1 " TPL_LIBS+="$TPL_WL_LIBS"], diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 7b4b3eb..b49148a 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -79,6 +79,7 @@ BuildRequires: pkgconfig(wayland-egl-backend) BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(wayland-tbm-server) BuildRequires: pkgconfig(tizen-surface-client) +BuildRequires: pkgconfig(presentation-time-client) BuildRequires: pkgconfig(glib-2.0) %endif diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 101cf8f..f7fb447 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "tpl_utils.h" #include "tpl_internal.h" @@ -67,6 +68,7 @@ struct _twe_wl_disp_source { struct wl_event_queue *ev_queue; struct wayland_tbm_client *wl_tbm_client; struct tizen_surface_shm *tss; /* used for surface buffer_flush */ + struct wp_presentation *presentation; struct { int min_buffer; int max_buffer; @@ -125,6 +127,12 @@ struct _twe_wl_surf_source { int render_sync_timestamp; unsigned int render_sync_fence_number; + tbm_fd presentation_sync_timeline; + int presentation_sync_timestamp; + int presentation_sync_ts_backup; + int presentation_sync_req_cnt; + GMutex pst_mutex; + GMutex surf_mutex; GMutex free_queue_mutex; @@ -788,6 +796,13 @@ __cb_wl_resistry_global_callback(void *data, struct wl_registry *wl_registry, &wayland_vulkan_interface, version); } + + if (!strcmp(interface, wp_presentation_interface.name)) { + disp_source->presentation = + wl_registry_bind(wl_registry, + name, &wp_presentation_interface, 1); + TPL_DEBUG("bind wp_presentation_interface"); + } } void @@ -867,6 +882,12 @@ _twe_display_wayland_init(twe_wl_disp_source *disp_source) TPL_LOG_T(BACKEND, "wl_vk_client(%p) init.", disp_source->wl_vk_client); } + if (disp_source->presentation) { + wl_proxy_set_queue((struct wl_proxy *)disp_source->presentation, + disp_source->ev_queue); + TPL_LOG_T(BACKEND, "wp_presentation(%p) init.", disp_source->presentation); + } + fini: if (display_wrapper) wl_proxy_wrapper_destroy(display_wrapper); @@ -1261,6 +1282,44 @@ __cb_create_render_sync_fd(struct wl_egl_window *wl_egl_window, void *private) return -1; } +static int +__cb_create_presentation_sync_fd(struct wl_egl_window *wl_egl_window, void *private) +{ + TPL_ASSERT(private); + TPL_ASSERT(wl_egl_window); + + struct tizen_private *tizen_private = (struct tizen_private *)private; + twe_wl_surf_source *surf_source = NULL; + + tbm_fd presentation_sync_fd = -1; + + surf_source = (twe_wl_surf_source *)tizen_private->data; + if (!surf_source) { + TPL_ERR("Invalid parameter. twe_surface(%p)", surf_source); + return -1; + } + + if (surf_source->presentation_sync_timeline != -1) { + g_mutex_lock(&surf_source->pst_mutex); + + presentation_sync_fd = tbm_sync_fence_create(surf_source->presentation_sync_timeline, + NULL, + surf_source->presentation_sync_timestamp++); + TPL_DEBUG("[PRESENTATION_SYNC] surf_source(%p) timeline(%d) timestamp(%d) sync_fence(%d)", + surf_source, surf_source->presentation_sync_timeline, surf_source->presentation_sync_timestamp, + presentation_sync_fd); + + TRACE_ASYNC_BEGIN(surf_source->presentation_sync_timestamp, "[PRESENTATION]"); + + surf_source->presentation_sync_req_cnt++; + + g_mutex_unlock(&surf_source->pst_mutex); + return presentation_sync_fd; + } + + return -1; +} + static void __cb_tss_flusher_flush_callback(void *data, struct tizen_surface_shm_flusher *tss_flusher) @@ -1901,6 +1960,105 @@ _twe_thread_wl_vk_surface_commit(twe_wl_surf_source *surf_source, } static void +__cb_presentation_feedback_sync_output(void *data, + struct wp_presentation_feedback *presentation_feedback, + struct wl_output *output) +{ + TPL_IGNORE(data); + TPL_IGNORE(presentation_feedback); + TPL_IGNORE(output); +} + +static void +__cb_presentation_feedback_presented(void *data, + struct wp_presentation_feedback *presentation_feedback, + uint32_t tv_sec_hi, + uint32_t tv_sec_lo, + uint32_t tv_nsec, + uint32_t refresh_nsec, + uint32_t seq_hi, + uint32_t seq_lo, + uint32_t flags) +{ + TPL_IGNORE(tv_sec_hi); + TPL_IGNORE(tv_sec_lo); + TPL_IGNORE(tv_nsec); + TPL_IGNORE(refresh_nsec); + TPL_IGNORE(seq_hi); + TPL_IGNORE(seq_lo); + TPL_IGNORE(flags); + + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data; + + g_mutex_lock(&surf_source->pst_mutex); + + TPL_DEBUG("[FEEDBACK][PRESENTED] surf_source(%p) wl_surface(%p)", + surf_source, surf_source->surf); + + if (surf_source->presentation_sync_timeline != -1 && + surf_source->presentation_sync_req_cnt > 0) { + + surf_source->presentation_sync_ts_backup++; + surf_source->presentation_sync_req_cnt--; + + TRACE_ASYNC_END(surf_source->presentation_sync_ts_backup, "[PRESENTATION]"); + + TPL_DEBUG("[PRESENTATION][INC] surf_source(%p) timeline(%d) timestamp(%d)", + surf_source, surf_source->presentation_sync_timeline, + surf_source->presentation_sync_ts_backup); + if (!tbm_sync_timeline_inc(surf_source->presentation_sync_timeline, 1)) { + TPL_ERR("Failed to increase timeline(%d)", + surf_source->presentation_sync_timeline); + } + } + + if (presentation_feedback) + wp_presentation_feedback_destroy(presentation_feedback); + + g_mutex_unlock(&surf_source->pst_mutex); +} + +static void +__cb_presentation_feedback_discarded(void *data, + struct wp_presentation_feedback *presentation_feedback) +{ + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data; + + g_mutex_lock(&surf_source->pst_mutex); + + TPL_DEBUG("[FEEDBACK][DISCARDED] surf_source(%p) wl_surface(%p)", + surf_source, surf_source->surf); + + if (surf_source->presentation_sync_timeline != -1 && + surf_source->presentation_sync_req_cnt > 0) { + + surf_source->presentation_sync_ts_backup++; + surf_source->presentation_sync_req_cnt--; + + TRACE_ASYNC_END(surf_source->presentation_sync_ts_backup, "[PRESENTATION]"); + + TPL_DEBUG("[PRESENTATION][INC] surf_source(%p) timeline(%d) timestamp(%d)", + surf_source, surf_source->presentation_sync_timeline, + surf_source->presentation_sync_ts_backup); + if (!tbm_sync_timeline_inc(surf_source->presentation_sync_timeline, 1)) { + TPL_ERR("Failed to increase timeline(%d)", + surf_source->presentation_sync_timeline); + } + } + + if (presentation_feedback) + wp_presentation_feedback_destroy(presentation_feedback); + + g_mutex_unlock(&surf_source->pst_mutex); +} + +static const struct wp_presentation_feedback_listener feedback_listener = { + __cb_presentation_feedback_sync_output, /* sync_output feedback -*/ + __cb_presentation_feedback_presented, + __cb_presentation_feedback_discarded +}; + +static void _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, tbm_surface_h tbm_surface) { @@ -1909,6 +2067,7 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, struct wl_surface *wl_surface = surf_source->surf; struct wl_egl_window *wl_egl_window = surf_source->wl_egl_window; uint32_t version; + struct wp_presentation_feedback *p_feedback; tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO, (void **)&buf_info); @@ -1920,6 +2079,15 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, version = wl_proxy_get_version((struct wl_proxy *)wl_surface); + g_mutex_lock(&surf_source->pst_mutex); + if (disp_source->presentation && + surf_source->presentation_sync_req_cnt > 0) { + p_feedback = wp_presentation_feedback(disp_source->presentation, + wl_surface); + wp_presentation_feedback_add_listener(p_feedback, &feedback_listener, surf_source); + } + g_mutex_unlock(&surf_source->pst_mutex); + if (buf_info->w_rotated == TPL_TRUE) { wayland_tbm_client_set_buffer_transform( disp_source->wl_tbm_client, @@ -2558,6 +2726,11 @@ twe_surface_add(twe_thread* thread, source->render_sync_timestamp = 0; source->render_sync_fence_number = 0; + source->presentation_sync_timeline = tbm_sync_timeline_create(); + source->presentation_sync_timestamp = 0; + source->presentation_sync_ts_backup = 0; + source->presentation_sync_req_cnt = 0; + if (!disp_source->is_vulkan_dpy) { struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)native_handle; @@ -2578,6 +2751,7 @@ twe_surface_add(twe_thread* thread, private->set_window_serial_callback = (void *) __cb_set_window_serial_callback; private->create_render_sync_fd = (void *)__cb_create_render_sync_fd; + private->create_presentation_sync_fd = (void *)__cb_create_presentation_sync_fd; source->latest_transform = private->transform; @@ -2607,6 +2781,7 @@ twe_surface_add(twe_thread* thread, g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop)); g_mutex_init(&source->surf_mutex); + g_mutex_init(&source->pst_mutex); g_mutex_init(&source->free_queue_mutex); g_cond_init(&source->free_queue_cond); -- 2.7.4 From d6375a343b0cc5bf7945aa6bdcc456b4aec2bbae Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 14 Nov 2019 20:33:32 +0900 Subject: [PATCH 14/16] wayland-egl-tizen: Added new API to merge sync fds. New API /** * Get a new fence fd with fence1 and fence2 merged * * It returns a new fence fd waiting for both fences to be signaled. * If user succeed in obtaining a new merged fence using this API, * the two fence fds passed must be closed by the user. * * Multiple calls to this API allow to merge multiple fences. * * The two fence fds caller want to merge should be closed * if caller is not going to use them after * the new merged fd is created. * * @param egl_window handle to wl_egl_window * @param sync_fd1 first fd to merge with second fd * @param sync_fd2 seconde fd to merge with first fd * @return merged fd on success, -1 on failure. */ int wl_egl_window_tizen_merge_sync_fds(struct wl_egl_window *egl_window, int sync_fd1, int sync_fd2); Change-Id: I29ac248c836392b9e6acb141a30bb70dc5e9731f Signed-off-by: Joonbum Ko --- src/wayland-egl-tizen/wayland-egl-tizen-priv.h | 2 ++ src/wayland-egl-tizen/wayland-egl-tizen.c | 23 +++++++++++++++++++++++ src/wayland-egl-tizen/wayland-egl-tizen.h | 22 ++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h index 6fd31ea..9a6b812 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h +++ b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h @@ -24,6 +24,7 @@ struct tizen_private { void (*set_window_serial_callback)(struct wl_egl_window *, void *, unsigned int); int (*create_render_sync_fd)(struct wl_egl_window *, void *); int (*create_presentation_sync_fd)(struct wl_egl_window *, void *); + int (*merge_sync_fds)(void *, int, int); }; static struct tizen_private* tizen_private_create() @@ -44,6 +45,7 @@ static struct tizen_private* tizen_private_create() private->set_frontbuffer_callback = NULL; private->create_render_sync_fd = NULL; private->create_presentation_sync_fd = NULL; + private->merge_sync_fds = NULL; } return private; diff --git a/src/wayland-egl-tizen/wayland-egl-tizen.c b/src/wayland-egl-tizen/wayland-egl-tizen.c index 831951c..70e66a3 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen.c +++ b/src/wayland-egl-tizen/wayland-egl-tizen.c @@ -295,3 +295,26 @@ wl_egl_window_tizen_create_presentation_sync_fd(struct wl_egl_window *egl_window return -1; } + +int +wl_egl_window_tizen_merge_sync_fds(struct wl_egl_window *egl_window, + int sync_fd1, int sync_fd2) +{ + struct tizen_private *private = NULL; + + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return -1; + } + + private = egl_window->driver_private; + if (private == NULL) { + WL_EGL_ERR("wl_egl_window(%p) dirver_private is NULL", egl_window); + return -1; + } + + if (private->merge_sync_fds) + return private->merge_sync_fds(egl_window->driver_private, sync_fd1, sync_fd2); + + return -1; +} \ No newline at end of file diff --git a/src/wayland-egl-tizen/wayland-egl-tizen.h b/src/wayland-egl-tizen/wayland-egl-tizen.h index 00b8b75..041488c 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen.h +++ b/src/wayland-egl-tizen/wayland-egl-tizen.h @@ -118,6 +118,28 @@ wl_egl_window_tizen_create_render_sync_fd(struct wl_egl_window *egl_window); int wl_egl_window_tizen_create_presentation_sync_fd(struct wl_egl_window *egl_window); +/** + * Get a new fence fd with fence1 and fence2 merged + * + * It returns a new fence fd waiting for both fences to be signaled. + * If user succeed in obtaining a new merged fence using this API, + * the two fence fds passed must be closed by the user. + * + * Multiple calls to this API allow to merge multiple fences. + * + * The two fence fds caller want to merge should be closed + * if caller is not going to use them after + * the new merged fd is created. + * + * @param egl_window handle to wl_egl_window + * @param sync_fd1 first fd to merge with second fd + * @param sync_fd2 seconde fd to merge with first fd + * @return merged fd on success, -1 on failure. + */ +int +wl_egl_window_tizen_merge_sync_fds(struct wl_egl_window *egl_window, + int sync_fd1, int sync_fd2); + #ifdef __cplusplus } #endif -- 2.7.4 From 8645365b9a9d54f1e2f9fbf7fde5e69e5ad9ae49 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Fri, 15 Nov 2019 15:14:47 +0900 Subject: [PATCH 15/16] tpl_wayland_egl_thread: Implemented merge sync fence. Change-Id: Ic5697fd0dbade852d9340b2c490d6247a12f46f1 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index f7fb447..6368d91 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1320,6 +1320,35 @@ __cb_create_presentation_sync_fd(struct wl_egl_window *wl_egl_window, void *priv return -1; } +static int +__cb_merge_sync_fds(void *private, int sync_fd1, int sync_fd2) +{ + TPL_ASSERT(private); + + struct tizen_private *tizen_private = (struct tizen_private *)private; + twe_wl_surf_source *surf_source = NULL; + tbm_fd merged_fd; + + surf_source = (twe_wl_surf_source *)tizen_private->data; + if (!surf_source) { + TPL_ERR("Invalid parameter. twe_surface(%p)", surf_source); + return -1; + } + + if (surf_source->render_sync_timeline == -1 && + surf_source->presentation_sync_timeline == -1) { + TPL_ERR("There is no timeline for any sync fd in surf_source(%p)", surf_source); + return -1; + } + + merged_fd = tbm_sync_fence_merge(NULL, sync_fd1, sync_fd2); + + TPL_DEBUG("[FENCE_MERGE] surf_source(%p) fence1(%d) + fence2(%d) = merged(%d)", + surf_source, sync_fd1, sync_fd2, merged_fd); + + return merged_fd; +} + static void __cb_tss_flusher_flush_callback(void *data, struct tizen_surface_shm_flusher *tss_flusher) @@ -2752,6 +2781,7 @@ twe_surface_add(twe_thread* thread, __cb_set_window_serial_callback; private->create_render_sync_fd = (void *)__cb_create_render_sync_fd; private->create_presentation_sync_fd = (void *)__cb_create_presentation_sync_fd; + private->merge_sync_fds = (void *)__cb_merge_sync_fds; source->latest_transform = private->transform; -- 2.7.4 From 9f7b27bb3c91b6a0c02dcc8ca1310780bcc5e9c2 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 12 Mar 2020 14:04:16 +0900 Subject: [PATCH 16/16] wayland-egl-tizen: Changed API name render_sync_fd to commit_sync_fd. - If the user wants to know the render done using EGLSyncKHR, tpl_surface_dequeue_buffer, tpl_surface_enqueue_buffer and wl_surface_commit occur at similar moments. Therefore, it only tells when wl_surface_commit is done, but does not guarantee render done. - If EGLSyncKHR or dma_buf implicit fence is not used, render done can be guaranteed. Change-Id: I43d7bdd10a33d0b559ecd1d219261bbb5415b574 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 61 +++++++++++++------------- src/wayland-egl-tizen/wayland-egl-tizen-priv.h | 4 +- src/wayland-egl-tizen/wayland-egl-tizen.c | 6 +-- src/wayland-egl-tizen/wayland-egl-tizen.h | 19 ++++---- 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 6368d91..0176383 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -123,9 +123,9 @@ struct _twe_wl_surf_source { twe_wl_disp_source *disp_source; twe_del_source *surf_del_source; - tbm_fd render_sync_timeline; - int render_sync_timestamp; - unsigned int render_sync_fence_number; + tbm_fd commit_sync_timeline; + int commit_sync_timestamp; + unsigned int commit_sync_fence_number; tbm_fd presentation_sync_timeline; int presentation_sync_timestamp; @@ -1248,7 +1248,7 @@ __cb_set_window_serial_callback(struct wl_egl_window *wl_egl_window, } static int -__cb_create_render_sync_fd(struct wl_egl_window *wl_egl_window, void *private) +__cb_create_commit_sync_fd(struct wl_egl_window *wl_egl_window, void *private) { TPL_ASSERT(private); TPL_ASSERT(wl_egl_window); @@ -1256,7 +1256,7 @@ __cb_create_render_sync_fd(struct wl_egl_window *wl_egl_window, void *private) struct tizen_private *tizen_private = (struct tizen_private *)private; twe_wl_surf_source *surf_source = NULL; - tbm_fd render_sync_fd = -1; + tbm_fd commit_sync_fd = -1; surf_source = (twe_wl_surf_source *)tizen_private->data; if (!surf_source) { @@ -1264,19 +1264,19 @@ __cb_create_render_sync_fd(struct wl_egl_window *wl_egl_window, void *private) return -1; } - if (surf_source->render_sync_timeline != -1) { + if (surf_source->commit_sync_timeline != -1) { char name[32]; - snprintf(name, 32, "%u", surf_source->render_sync_fence_number++); - render_sync_fd = tbm_sync_fence_create(surf_source->render_sync_timeline, + snprintf(name, 32, "%u", surf_source->commit_sync_fence_number++); + commit_sync_fd = tbm_sync_fence_create(surf_source->commit_sync_timeline, name, - surf_source->render_sync_timestamp + 1); - TPL_DEBUG("[RENDER_SYNC] surf_source(%p) timeline(%d) timestamp(%d) name(%s) sync_fence(%d)", - surf_source, surf_source->render_sync_timeline, surf_source->render_sync_timestamp, - name, render_sync_fd); + surf_source->commit_sync_timestamp + 1); + TPL_DEBUG("[COMMIT_SYNC] surf_source(%p) timeline(%d) timestamp(%d) name(%s) sync_fence(%d)", + surf_source, surf_source->commit_sync_timeline, surf_source->commit_sync_timestamp, + name, commit_sync_fd); - TRACE_ASYNC_BEGIN(surf_source->render_sync_timestamp + 1, "[SYNC_FENCE]"); + TRACE_ASYNC_BEGIN(surf_source->commit_sync_timestamp + 1, "[SYNC_FENCE]"); - return render_sync_fd; + return commit_sync_fd; } return -1; @@ -1335,7 +1335,7 @@ __cb_merge_sync_fds(void *private, int sync_fd1, int sync_fd2) return -1; } - if (surf_source->render_sync_timeline == -1 && + if (surf_source->commit_sync_timeline == -1 && surf_source->presentation_sync_timeline == -1) { TPL_ERR("There is no timeline for any sync fd in surf_source(%p)", surf_source); return -1; @@ -1682,18 +1682,6 @@ _twe_surface_trace_enqueue_buffer(twe_wl_surf_source *surf_source, return; } - if (surf_source->render_sync_timeline != -1) { - - surf_source->render_sync_timestamp++; - TRACE_ASYNC_END(surf_source->render_sync_timestamp, "[SYNC_FENCE]"); - - TPL_DEBUG("[RENDER_SYNC][INC] surf_source(%p) timeline(%d) timestamp(%d)", - surf_source, surf_source->render_sync_timeline, surf_source->render_sync_timestamp); - if (!tbm_sync_timeline_inc(surf_source->render_sync_timeline, 1)) { - TPL_ERR("Failed to increase timeline(%d)", surf_source->render_sync_timeline); - } - } - if (surf_source->in_use_buffers) { g_mutex_lock(&surf_source->surf_mutex); /* Stop tracking of this canceled tbm_surface */ @@ -2193,6 +2181,17 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, if (surf_source->committed_buffers) { __tpl_list_push_back(surf_source->committed_buffers, tbm_surface); } + + if (surf_source->commit_sync_timeline != -1) { + surf_source->commit_sync_timestamp++; + TRACE_ASYNC_END(surf_source->commit_sync_timestamp, "[SYNC_FENCE]"); + + TPL_DEBUG("[COMMIT_SYNC][INC] surf_source(%p) timeline(%d) timestamp(%d)", + surf_source, surf_source->commit_sync_timeline, surf_source->commit_sync_timestamp); + if (!tbm_sync_timeline_inc(surf_source->commit_sync_timeline, 1)) { + TPL_ERR("Failed to increase timeline(%d)", surf_source->commit_sync_timeline); + } + } } /* The following function _twe_thread_wl_surface_acquire_and_commit can be @@ -2751,9 +2750,9 @@ twe_surface_add(twe_thread* thread, source->post_interval = 1; - source->render_sync_timeline = tbm_sync_timeline_create(); - source->render_sync_timestamp = 0; - source->render_sync_fence_number = 0; + source->commit_sync_timeline = tbm_sync_timeline_create(); + source->commit_sync_timestamp = 0; + source->commit_sync_fence_number = 0; source->presentation_sync_timeline = tbm_sync_timeline_create(); source->presentation_sync_timestamp = 0; @@ -2779,7 +2778,7 @@ twe_surface_add(twe_thread* thread, __cb_get_rotation_capability; private->set_window_serial_callback = (void *) __cb_set_window_serial_callback; - private->create_render_sync_fd = (void *)__cb_create_render_sync_fd; + private->create_commit_sync_fd = (void *)__cb_create_commit_sync_fd; private->create_presentation_sync_fd = (void *)__cb_create_presentation_sync_fd; private->merge_sync_fds = (void *)__cb_merge_sync_fds; diff --git a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h index 9a6b812..caeb5b0 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h +++ b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h @@ -22,7 +22,7 @@ struct tizen_private { int (*get_rotation_capability)(struct wl_egl_window *, void *); void (*set_frontbuffer_callback)(struct wl_egl_window *, void *, int); void (*set_window_serial_callback)(struct wl_egl_window *, void *, unsigned int); - int (*create_render_sync_fd)(struct wl_egl_window *, void *); + int (*create_commit_sync_fd)(struct wl_egl_window *, void *); int (*create_presentation_sync_fd)(struct wl_egl_window *, void *); int (*merge_sync_fds)(void *, int, int); }; @@ -43,7 +43,7 @@ static struct tizen_private* tizen_private_create() private->get_rotation_capability = NULL; private->set_window_serial_callback = NULL; private->set_frontbuffer_callback = NULL; - private->create_render_sync_fd = NULL; + private->create_commit_sync_fd = NULL; private->create_presentation_sync_fd = NULL; private->merge_sync_fds = NULL; } diff --git a/src/wayland-egl-tizen/wayland-egl-tizen.c b/src/wayland-egl-tizen/wayland-egl-tizen.c index 70e66a3..b4e679c 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen.c +++ b/src/wayland-egl-tizen/wayland-egl-tizen.c @@ -253,7 +253,7 @@ wl_egl_window_tizen_set_window_serial(struct wl_egl_window *egl_window, } int -wl_egl_window_tizen_create_render_sync_fd(struct wl_egl_window *egl_window) +wl_egl_window_tizen_create_commit_sync_fd(struct wl_egl_window *egl_window) { struct tizen_private *private = NULL; @@ -268,8 +268,8 @@ wl_egl_window_tizen_create_render_sync_fd(struct wl_egl_window *egl_window) return -1; } - if (private->create_render_sync_fd) - return private->create_render_sync_fd(egl_window, egl_window->driver_private); + if (private->create_commit_sync_fd) + return private->create_commit_sync_fd(egl_window, egl_window->driver_private); return -1; } diff --git a/src/wayland-egl-tizen/wayland-egl-tizen.h b/src/wayland-egl-tizen/wayland-egl-tizen.h index 041488c..921b193 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen.h +++ b/src/wayland-egl-tizen/wayland-egl-tizen.h @@ -75,20 +75,21 @@ wl_egl_window_tizen_set_window_serial(struct wl_egl_window *egl_window, /* temporary APIs for testing sync feature */ /** - * Create a sync fence fd that can tell render done. + * Create a sync fence fd that can tell wl_surface_commit done. * * If eglSwapBuffers works async, it returns fd which tells - * when the render job is finished. + * when wl_surface_commit called. * This fd can wait asynchronously via poll or select. * * Important * * This requires the following premise: - * - After ddk calls libplpl-egl's tpl_surface_dequeue_buffer to get the buffer, - * and until it calls tpl_surface_enqueue_buffer, - * it is called the gpu rendering job interval. - * - Therefore, when using the dma_buf implicit fence, - * there is no guarantee that the rendering job is finished - * with the fence obtained through this API. + * - If the user wants to know the render done using EGLSyncKHR, + * tpl_surface_dequeue_buffer, tpl_surface_enqueue_buffer and + * wl_surface_commit occur at similar moments. + * Therefore, it only tells when wl_surface_commit is done, + * but does not guarantee render done. + * - If EGLSyncKHR or dma_buf implicit fence is not used, + * render done can be guaranteed. * * The fence_fd obtained through this function is one-time available, * can not be reused, so caller must close it when finished using it. @@ -97,7 +98,7 @@ wl_egl_window_tizen_set_window_serial(struct wl_egl_window *egl_window, * @return sync fd on success, -1 on failure. */ int -wl_egl_window_tizen_create_render_sync_fd(struct wl_egl_window *egl_window); +wl_egl_window_tizen_create_commit_sync_fd(struct wl_egl_window *egl_window); /** * Create a sync fence fd that can tell presentation done. -- 2.7.4