From 425b7d435a0a242e93c375cc67e136a0943adc70 Mon Sep 17 00:00:00 2001 From: "JunSeok, Kim" Date: Thu, 11 Jan 2018 19:39:50 +0900 Subject: [PATCH 01/16] tizen-surface: renew tizen-surface protocol path Change-Id: I1453b28a64cbc5942c56acf381faf0be05d48e97 --- configure.ac | 2 +- packaging/libtpl-egl.spec | 1 + src/Makefile.am | 1 - src/protocol/tizen-surface-client.h | 118 ---------------------------------- src/protocol/tizen-surface-protocol.c | 37 ----------- src/protocol/tizen-surface.xml | 16 ----- src/tpl_wayland_egl.c | 2 +- src/tpl_wayland_egl_thread.c | 2 +- worker_test/Makefile | 2 - 9 files changed, 4 insertions(+), 177 deletions(-) delete mode 100644 src/protocol/tizen-surface-client.h delete mode 100644 src/protocol/tizen-surface-protocol.c delete mode 100644 src/protocol/tizen-surface.xml diff --git a/configure.ac b/configure.ac index 8a6985c..5379baa 100644 --- a/configure.ac +++ b/configure.ac @@ -58,7 +58,7 @@ AC_ARG_WITH([wayland], [with_wayland=yes]) AS_IF([test "${with_wayland}" = "yes" || test "${with_wayland}" = "1"], - [PKG_CHECK_MODULES([TPL_WL], [gbm libtdm-client wayland-tbm-client wayland-tbm-server glib-2.0]) + [PKG_CHECK_MODULES([TPL_WL], [gbm libtdm-client wayland-tbm-client wayland-tbm-server tizen-surface-client glib-2.0]) 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 0890369..9f1051a 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -76,6 +76,7 @@ BuildRequires: pkgconfig(gbm) BuildRequires: pkgconfig(libtdm-client) BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(wayland-tbm-server) +BuildRequires: pkgconfig(tizen-surface-client) BuildRequires: pkgconfig(glib-2.0) %endif diff --git a/src/Makefile.am b/src/Makefile.am index 8c4f651..bafc8fd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,6 @@ libtpl_egl_la_SOURCES = tpl.c \ if WITH_WAYLAND libtpl_egl_la_SOURCES += tpl_wayland_egl.c \ tpl_gbm.c \ - protocol/tizen-surface-protocol.c \ tpl_wl_egl_thread.c \ tpl_wayland_egl_thread.c \ tpl_wayland_vk_wsi.c \ diff --git a/src/protocol/tizen-surface-client.h b/src/protocol/tizen-surface-client.h deleted file mode 100644 index 6eaa459..0000000 --- a/src/protocol/tizen-surface-client.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef TIZEN_SURFACE_CLIENT_PROTOCOL_H -#define TIZEN_SURFACE_CLIENT_PROTOCOL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include "wayland-client.h" - -struct wl_client; -struct wl_resource; - -struct tizen_surface_shm; -struct tizen_surface_shm_flusher; -struct wl_surface; - -extern const struct wl_interface tizen_surface_shm_interface; -extern const struct wl_interface tizen_surface_shm_flusher_interface; - -#define TIZEN_SURFACE_SHM_GET_FLUSHER 0 - -#define TIZEN_SURFACE_SHM_GET_FLUSHER_SINCE_VERSION 1 - -static inline void -tizen_surface_shm_set_user_data(struct tizen_surface_shm *tizen_surface_shm, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) tizen_surface_shm, user_data); -} - -static inline void * -tizen_surface_shm_get_user_data(struct tizen_surface_shm *tizen_surface_shm) -{ - return wl_proxy_get_user_data((struct wl_proxy *) tizen_surface_shm); -} - -static inline uint32_t -tizen_surface_shm_get_version(struct tizen_surface_shm *tizen_surface_shm) -{ - return wl_proxy_get_version((struct wl_proxy *) tizen_surface_shm); -} - -static inline void -tizen_surface_shm_destroy(struct tizen_surface_shm *tizen_surface_shm) -{ - wl_proxy_destroy((struct wl_proxy *) tizen_surface_shm); -} - -static inline struct tizen_surface_shm_flusher * -tizen_surface_shm_get_flusher(struct tizen_surface_shm *tizen_surface_shm, struct wl_surface *surface) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_constructor((struct wl_proxy *) tizen_surface_shm, - TIZEN_SURFACE_SHM_GET_FLUSHER, &tizen_surface_shm_flusher_interface, NULL, surface); - - return (struct tizen_surface_shm_flusher *) id; -} - -struct tizen_surface_shm_flusher_listener { - /** - * flush - (none) - */ - void (*flush)(void *data, - struct tizen_surface_shm_flusher *tizen_surface_shm_flusher); - /** - * free_flush - (none) - * @since: 2 - */ - void (*free_flush)(void *data, - struct tizen_surface_shm_flusher *tizen_surface_shm_flusher); -}; - -static inline int -tizen_surface_shm_flusher_add_listener(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher, - const struct tizen_surface_shm_flusher_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) tizen_surface_shm_flusher, - (void (**)(void)) listener, data); -} - -#define TIZEN_SURFACE_SHM_FLUSHER_DESTROY 0 - -#define TIZEN_SURFACE_SHM_FLUSHER_DESTROY_SINCE_VERSION 1 - -static inline void -tizen_surface_shm_flusher_set_user_data(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) tizen_surface_shm_flusher, user_data); -} - -static inline void * -tizen_surface_shm_flusher_get_user_data(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) -{ - return wl_proxy_get_user_data((struct wl_proxy *) tizen_surface_shm_flusher); -} - -static inline uint32_t -tizen_surface_shm_flusher_get_version(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) -{ - return wl_proxy_get_version((struct wl_proxy *) tizen_surface_shm_flusher); -} - -static inline void -tizen_surface_shm_flusher_destroy(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) -{ - wl_proxy_marshal((struct wl_proxy *) tizen_surface_shm_flusher, - TIZEN_SURFACE_SHM_FLUSHER_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) tizen_surface_shm_flusher); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/protocol/tizen-surface-protocol.c b/src/protocol/tizen-surface-protocol.c deleted file mode 100644 index bd5e8a6..0000000 --- a/src/protocol/tizen-surface-protocol.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include "wayland-util.h" - -extern const struct wl_interface tizen_surface_shm_flusher_interface; -extern const struct wl_interface wl_surface_interface; - -static const struct wl_interface *types[] = { - &tizen_surface_shm_flusher_interface, - &wl_surface_interface, -}; - -static const struct wl_message tizen_surface_shm_requests[] = { - { "get_flusher", "no", types + 0 }, -}; - -WL_EXPORT const struct wl_interface tizen_surface_shm_interface = { - "tizen_surface_shm", 2, - 1, tizen_surface_shm_requests, - 0, NULL, -}; - -static const struct wl_message tizen_surface_shm_flusher_requests[] = { - { "destroy", "", types + 0 }, -}; - -static const struct wl_message tizen_surface_shm_flusher_events[] = { - { "flush", "", types + 0 }, - { "free_flush", "2", types + 0 }, -}; - -WL_EXPORT const struct wl_interface tizen_surface_shm_flusher_interface = { - "tizen_surface_shm_flusher", 2, - 1, tizen_surface_shm_flusher_requests, - 2, tizen_surface_shm_flusher_events, -}; - diff --git a/src/protocol/tizen-surface.xml b/src/protocol/tizen-surface.xml deleted file mode 100644 index ad516c0..0000000 --- a/src/protocol/tizen-surface.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index ef08f8b..503475c 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -19,7 +19,7 @@ #include #include #include -#include "protocol/tizen-surface-client.h" +#include /* In wayland, application and compositor create its own drawing buffers. Recommend size is more than 2. */ #define CLIENT_QUEUE_SIZE 3 diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index d48e619..8d0d640 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -8,12 +8,12 @@ #include #include #include +#include #include "tpl_utils.h" #include "tpl_internal.h" #include "wayland-egl/wayland-egl-priv.h" #include "tpl_wayland_egl_thread.h" -#include "protocol/tizen-surface-client.h" #include "wayland-vulkan/wayland-vulkan-client-protocol.h" #include "tpl_utils.h" diff --git a/worker_test/Makefile b/worker_test/Makefile index 6ce36ec..b6989e7 100644 --- a/worker_test/Makefile +++ b/worker_test/Makefile @@ -21,12 +21,10 @@ 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 -SRCS += ../src/protocol/tizen-surface-protocol.c HEADERS += ../src/tpl_wayland_egl_thread.h HEADERS += ../src/tpl_utils.h HEADERS += ../src/tpl_internal.h HEADERS += ../src/tpl.h -HEADERS += ../src/protocol/tizen-surface-client.h OBJS = $(SRCS:%.c=%.o) -- 2.7.4 From a816206cfc6e25f982ac0182e5d57cfb79d8f0ca Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 24 Jan 2018 15:11:56 +0900 Subject: [PATCH 02/16] Package version up to 1.5.3 Change-Id: Ie298e8f70a242eec37e645213bfa4e0a01d95b09 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 9f1051a..4b1e945 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 5 -%define TPL_VERSION_PATCH 2 +%define TPL_VERSION_PATCH 3 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From 2d8149fe316acabe82015d5310a721c4bacb046e Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 31 Jan 2018 13:36:28 +0900 Subject: [PATCH 03/16] tpl_wayland_egl: Added tdm_mutex to wayland_egl_display to guarantee thread safety. - RELATED COMMIT: Guaranteed thread safety for wl_event processing. - 750b2fe32de4438d3eb8e2ce1ee9a968a511c4f7 - Above commit can cover the wl_event processing only. - And in multi-surfaces or multi-threads situation, wayland_egl_display can be accessed at the same time in the processing of different surfaces. - The tdm_client in wayland_egl_display also dispatches wl_display internally, so thread_safety for tdm_client should be guaranteed. Change-Id: I30dbac42f90a003070c27a750d3a34354c4719ed Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 503475c..4565402 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -36,6 +36,7 @@ struct _tpl_wayland_egl_display { struct wl_event_queue *wl_tbm_event_queue; struct tizen_surface_shm *tizen_surface_shm; /* used for surface buffer_flush */ pthread_mutex_t wl_event_mutex; + pthread_mutex_t tdm_mutex; }; struct _tpl_wayland_egl_surface { @@ -199,6 +200,11 @@ __tpl_wayland_egl_display_init(tpl_display_t *display) goto free_wl_display; } + if (pthread_mutex_init(&wayland_egl_display->tdm_mutex, NULL)) { + TPL_ERR("Failed to initialize tdm_mutex."); + goto free_wl_display; + } + wayland_egl_display->wl_dpy = wl_dpy; __tpl_wayland_egl_display_buffer_flusher_init(wayland_egl_display); @@ -222,6 +228,9 @@ free_wl_display: if (wayland_egl_display->wl_tbm_client) wayland_tbm_client_deinit(wayland_egl_display->wl_tbm_client); + pthread_mutex_destroy(&wayland_egl_display->wl_event_mutex); + pthread_mutex_destroy(&wayland_egl_display->tdm_mutex); + wayland_egl_display->wl_tbm_event_queue = NULL; wayland_egl_display->wl_tbm_client = NULL; wayland_egl_display->tdm_client = NULL; @@ -242,6 +251,7 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) wayland_egl_display = (tpl_wayland_egl_display_t *)display->backend.data; if (wayland_egl_display) { int lock_res = 0; + int tdm_lock_res = 0; TPL_LOG_B("WL_EGL", "[FINI] tpl_wayland_egl_display_t(%p) wl_tbm_client(%p)", wayland_egl_display, wayland_egl_display->wl_tbm_client); @@ -249,8 +259,10 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) __tpl_wayland_egl_display_buffer_flusher_fini(wayland_egl_display); + tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); if (wayland_egl_display->tdm_client) tdm_client_destroy(wayland_egl_display->tdm_client); + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); if (wayland_egl_display->wl_tbm_client) wayland_tbm_client_set_event_queue(wayland_egl_display->wl_tbm_client, NULL); @@ -266,6 +278,10 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) TPL_ERR("Failed to destroy wl_event_mutex(%p)", &wayland_egl_display->wl_event_mutex); + if (pthread_mutex_destroy(&wayland_egl_display->tdm_mutex)) + TPL_ERR("Failed to destroy tdm_mutex(%p)", + &wayland_egl_display->tdm_mutex); + wayland_egl_display->wl_tbm_event_queue = NULL; wayland_egl_display->wl_tbm_client = NULL; wayland_egl_display->tdm_client = NULL; @@ -581,12 +597,15 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) /* tdm_vblank object decide to be maintained every tpl_wayland_egl_surface for the case where the several surfaces is created in one display connection. */ if (wayland_egl_display->tdm_client) { + int tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); if (TPL_ERROR_NONE != __tpl_wayland_egl_surface_create_vblank( wayland_egl_surface, wayland_egl_display->tdm_client)) { TPL_ERR("TBM surface create vblank failed!"); + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); goto create_vblank_fail; } + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); } __tpl_wayland_egl_surface_buffer_flusher_init(surface); @@ -648,10 +667,12 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) __tpl_wayland_egl_surface_buffer_flusher_fini(surface); if (wayland_egl_surface->tdm_vblank) { + int tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); TPL_LOG_B("WL_EGL", "[TDM_VBLANK_FINI] tpl_wayland_egl_surface_t(%p) tdm_vblank(%p)", wayland_egl_surface, wayland_egl_surface->tdm_vblank); tdm_client_vblank_destroy(wayland_egl_surface->tdm_vblank); + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); } wl_display_flush(wayland_egl_display->wl_dpy); @@ -705,17 +726,19 @@ __tpl_wayland_egl_surface_wait_vblank(tpl_surface_t *surface) (tpl_wayland_egl_display_t *)surface->display->backend.data; tpl_wayland_egl_surface_t *wayland_egl_surface = (tpl_wayland_egl_surface_t *)surface->backend.data; + int tdm_lock_res = 0; TPL_OBJECT_UNLOCK(surface); - do { + tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); + while (wayland_egl_surface->vblank_done == TPL_FALSE) { tdm_err = tdm_client_handle_events(wayland_egl_display->tdm_client); if (tdm_err != TDM_ERROR_NONE) { TPL_ERR("Failed to tdm_client_handle_events."); break; } - - } while (wayland_egl_surface->vblank_done == TPL_FALSE); + } + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); TPL_OBJECT_LOCK(surface); } @@ -834,6 +857,7 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, /* TPL_WAIT_VBLANK = 1 */ 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 */ __cb_tdm_client_wait_vblank, /* handler */ @@ -843,6 +867,7 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, wayland_egl_surface->vblank_done = TPL_FALSE; else TPL_ERR("Failed to tdm_client_wait_vblank. error:%d", tdm_err); + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); } TRACE_ASYNC_BEGIN((int)tbm_surface, "[COMMIT ~ RELEASE_CB] BO_NAME:%d", -- 2.7.4 From a5f11f5d46f72b4bd246aa53397edc46fdecd7c9 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 5 Jan 2018 14:57:05 +0900 Subject: [PATCH 04/16] tpl_wayland_egl_thread: Added useful trace logs for vulkan. Change-Id: Ie37f9075a72856747c6259a73e3af381aec10ba8 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 8d0d640..7704956 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1400,6 +1400,9 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, TPL_OBJECT_UNLOCK(&surf_source->obj); } + TRACE_MARK("[SET_BUFFER_INFO] BO(%d)", + 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)", buf_info, tbm_surface, @@ -1493,6 +1496,8 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, TPL_OBJECT_UNLOCK(&surf_source->obj); } + 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)", buf_info, tbm_surface, @@ -1610,6 +1615,8 @@ __cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, return; } + TRACE_ASYNC_END((int)surf_source, "WAIT_VBLANK"); + disp_source = surf_source->disp_source; surf_source->vblank_done = TPL_TRUE; @@ -1690,9 +1697,10 @@ _twe_surface_wait_vblank(twe_wl_surf_source *surf_source) __cb_tdm_client_wait_vblank, (void *)surf_source); - if (tdm_err == TDM_ERROR_NONE) + if (tdm_err == TDM_ERROR_NONE) { surf_source->vblank_done = TPL_FALSE; - else { + TRACE_ASYNC_BEGIN((int)surf_source, "WAIT_VBLANK"); + } else { TPL_ERR("Failed to tdm_client_vblank_wait. tdm_err(%d)", tdm_err); return TPL_ERROR_INVALID_OPERATION; } -- 2.7.4 From f0d6739dfa773f29af64ef9f76ee8b1734cc38af Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 5 Jan 2018 17:31:40 +0900 Subject: [PATCH 05/16] tpl_wl_vk_thread: Implemented reference count for swapchain. - The order of creation and destruction of swapchain is not clear when reset is needed by HWC or resize. - When regeneration is needed, the vulkan application can either destroy the old swapchain first, or create a new swapchain before that. - In Tizen, however, the tbm_surface_queue of swapchain does not actually need to be regenerated. - Therefore, the 'reference count' of swapchain is needed to prevent unintended regeneration of tbm_surface_queue. Change-Id: Ibe05f922ef149fa668a23c678065a89131ff547d Signed-off-by: joonbum.ko --- src/tpl_wl_vk_thread.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index b175f39..141a3f6 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -26,6 +26,7 @@ struct _tpl_wayland_vk_wsi_surface { int buffer_count; tpl_bool_t is_activated; tpl_bool_t reset; + tpl_util_atomic_uint swapchain_reference; }; static tpl_result_t __tpl_wl_vk_wsi_surface_destroy_swapchain( @@ -458,8 +459,8 @@ __tpl_wl_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, tsq_err = tbm_surface_queue_dequeue(wayland_vk_wsi_surface->tbm_queue, &tbm_surface); if (!tbm_surface) { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d", - tsq_err); + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue(%p) | tsq_err = %d", + wayland_vk_wsi_surface->tbm_queue, tsq_err); if (lock_ret == TPL_ERROR_NONE) twe_display_unlock(wayland_vk_wsi_display->twe_display); return NULL; @@ -510,8 +511,8 @@ __tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, for (i = 0 ; i < wayland_vk_wsi_surface->buffer_count ; i++) { tsq_err = tbm_surface_queue_dequeue(wayland_vk_wsi_surface->tbm_queue, &buffer); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d", - tsq_err); + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue(%p) | tsq_err = %d", + wayland_vk_wsi_surface->tbm_queue, tsq_err); dequeue_count = i; ret = TPL_ERROR_OUT_OF_MEMORY; goto get_buffer_fail; @@ -623,6 +624,9 @@ __tpl_wl_vk_wsi_surface_create_swapchain(tpl_surface_t *surface, wayland_vk_wsi_surface->buffer_count = tbm_surface_queue_get_size(wayland_vk_wsi_surface->tbm_queue); wayland_vk_wsi_surface->reset = TPL_FALSE; + + __tpl_util_atomic_inc(&wayland_vk_wsi_surface->swapchain_reference); + TPL_LOG_T("WL_VK", "[REUSE] wayland_vk_wsi_surface(%p) tbm_queue(%p) size(%d)", wayland_vk_wsi_surface, wayland_vk_wsi_surface->tbm_queue, wayland_vk_wsi_surface->buffer_count); @@ -654,6 +658,8 @@ __tpl_wl_vk_wsi_surface_create_swapchain(tpl_surface_t *surface, wayland_vk_wsi_surface->buffer_count = buffer_count; wayland_vk_wsi_surface->reset = TPL_FALSE; + __tpl_util_atomic_set(&wayland_vk_wsi_surface->swapchain_reference, 1); + return TPL_ERROR_NONE; } @@ -662,6 +668,7 @@ __tpl_wl_vk_wsi_surface_destroy_swapchain(tpl_surface_t *surface) { tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; tpl_result_t res = TPL_ERROR_NONE; + unsigned int ref; TPL_ASSERT(surface); TPL_ASSERT(surface->backend.data); @@ -670,6 +677,15 @@ __tpl_wl_vk_wsi_surface_destroy_swapchain(tpl_surface_t *surface) wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *) surface->backend.data; TPL_ASSERT(wayland_vk_wsi_surface); + ref = __tpl_util_atomic_dec(&wayland_vk_wsi_surface->swapchain_reference); + if (ref > 0) { + TPL_LOG_T("WL_VK", + "This swapchain is still valid. | twe_surface(%p)", + wayland_vk_wsi_surface->twe_surface); + return TPL_ERROR_NONE; + } + + if (wayland_vk_wsi_surface->reset) { TPL_LOG_T("WL_VK", "Since reset is in the TRUE state, it will not be destroyed."); -- 2.7.4 From b97db75972ce555526a391ba324b4c2d2ebf3f3d Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 9 Jan 2018 17:59:46 +0900 Subject: [PATCH 06/16] tpl_wayland_egl_thread: Added a new internal API to get swapchain buffers from wl_tbm_client. - Added internal API is twe_surface_get_swapchain_buffers. - This function uses the wayland-tbm API 'wayland_tbm_client_queue_get_surfaces()' to get the handle of tbm_surfaces to be used from the tbm_surface_queue of swapchain. Change-Id: If2d5d2f2d6bbb85ba586d56a9ffac6cb54cb689e Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 33 +++++++++++++++++++++++++++++++++ src/tpl_wayland_egl_thread.h | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 7704956..d800c4c 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -2658,6 +2658,39 @@ twe_surface_destroy_swapchain(twe_surface_h twe_surface) return TPL_ERROR_NONE; } +tpl_result_t +twe_surface_get_swapchain_buffers(twe_surface_h twe_surface, + tbm_surface_h *surfaces, + int *buffer_count) +{ + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface; + twe_wl_disp_source *disp_source = NULL; + int ret = 1; + + if (!surf_source || g_source_is_destroyed(&surf_source->gsource)) { + TPL_ERR("twe_surface(%p) is invalid.", twe_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (!surfaces) { + *buffer_count = tbm_surface_queue_get_size(surf_source->tbm_queue); + return TPL_ERROR_NONE; + } + + disp_source = surf_source->disp_source; + + ret = wayland_tbm_client_queue_get_surfaces( + disp_source->wl_tbm_client, + surf_source->tbm_queue, + surfaces, buffer_count); + if (!ret) { + TPL_ERR("Failed to get buffers from wl_tbm_client(%p) tbm_queue(%p)", + disp_source->wl_tbm_client, surf_source->tbm_queue); + return TPL_ERROR_INVALID_OPERATION; + } + + return TPL_ERROR_NONE; +} tpl_result_t twe_surface_set_rotate_callback(twe_surface_h twe_surface, diff --git a/src/tpl_wayland_egl_thread.h b/src/tpl_wayland_egl_thread.h index e89d527..bd32f1d 100644 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -55,6 +55,11 @@ twe_surface_create_swapchain(twe_surface_h twe_surface, tpl_result_t twe_surface_destroy_swapchain(twe_surface_h twe_surface); +tpl_result_t +twe_surface_get_swapchain_buffers(twe_surface_h twe_surface, + tbm_surface_h *surfaces, + int *buffer_count); + tbm_surface_queue_h twe_surface_get_tbm_queue(twe_surface_h twe_surface); -- 2.7.4 From 96fcf4d7efba17a80c67562716f602d5817cd7df Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 9 Jan 2018 19:09:45 +0900 Subject: [PATCH 07/16] tpl_wl_vk_thread: Modified get_swapchain_buffers to use internal function. - Before this commit, had to call tbm_surface_queue_dequeue() as much as wayland_vk_wsi_surface->buffer_count to get the handle of the buffers. - And dequeued buffers must be return to tbm_surface_queue with tbm_surface_queue_release(). - This method is complicated and not suitable for HWC situations, so I modified it to get handles of the buffers from wl_tbm_client via twe_surface_get_swapchain_buffers(). Change-Id: I535a531219cd2284a230cc4583b818aa16593c21 Signed-off-by: joonbum.ko --- src/tpl_wl_vk_thread.c | 51 ++++++++++++++------------------------------------ 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 141a3f6..f670382 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -487,11 +487,9 @@ __tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, tbm_surface_h **buffers, int *buffer_count) { - tbm_surface_h buffer = NULL; tbm_surface_h *swapchain_buffers = NULL; tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; - tbm_surface_queue_error_e tsq_err; - int i, dequeue_count; + int i; tpl_result_t ret = TPL_ERROR_NONE; TPL_ASSERT(surface); @@ -508,46 +506,25 @@ __tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, return TPL_ERROR_OUT_OF_MEMORY; } - for (i = 0 ; i < wayland_vk_wsi_surface->buffer_count ; i++) { - tsq_err = tbm_surface_queue_dequeue(wayland_vk_wsi_surface->tbm_queue, &buffer); - if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue(%p) | tsq_err = %d", - wayland_vk_wsi_surface->tbm_queue, tsq_err); - dequeue_count = i; - ret = TPL_ERROR_OUT_OF_MEMORY; - goto get_buffer_fail; - } - swapchain_buffers[i] = buffer; - TPL_DEBUG("swapchain_buffers[%d] = tbm_surface(%p)", i, buffer); + ret = twe_surface_get_swapchain_buffers(wayland_vk_wsi_surface->twe_surface, + swapchain_buffers, buffer_count); + if (ret != TPL_ERROR_NONE) { + TPL_ERR("Failed to get swapchain_buffers. wayland_vk_wsi_surface(%p) twe_surface(%p)", + wayland_vk_wsi_surface, wayland_vk_wsi_surface->twe_surface); + free(swapchain_buffers); + swapchain_buffers = NULL; + return ret; } - for (i = 0 ; i < wayland_vk_wsi_surface->buffer_count ; i++) { - tsq_err = tbm_surface_queue_release(wayland_vk_wsi_surface->tbm_queue, - swapchain_buffers[i]); - if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { - TPL_ERR("Failed to release tbm_surface. | tsq_err = %d", tsq_err); - ret = TPL_ERROR_INVALID_OPERATION; - goto release_buffer_fail; - } + for (i = 0; i < *buffer_count; i++) { + TPL_DEBUG("swapchain_buffers[%d] = tbm_surface(%p) bo(%d)", + i, swapchain_buffers[i], + tbm_bo_export(tbm_surface_internal_get_bo(swapchain_buffers[i], 0))); } *buffers = swapchain_buffers; - *buffer_count = wayland_vk_wsi_surface->buffer_count; - return TPL_ERROR_NONE; -get_buffer_fail: - for (i = 0 ; i < dequeue_count ; i++) { - tsq_err = tbm_surface_queue_release(wayland_vk_wsi_surface->tbm_queue, - swapchain_buffers[i]); - if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { - TPL_ERR("Failed to release tbm_surface. | tsq_err = %d", tsq_err); - goto release_buffer_fail; - } - } - -release_buffer_fail: - free(swapchain_buffers); - return ret; + return TPL_ERROR_NONE; } static void -- 2.7.4 From c34883b51af32f6756daf09e8daea5412ec0a24e Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 9 Jan 2018 20:10:09 +0900 Subject: [PATCH 08/16] Fixed some build warnings. Change-Id: Ia3b45e382cafe02e25f9aaf777338dbd4f9e191e Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 5 +++-- src/tpl_wl_egl_thread.c | 2 +- src/tpl_wl_vk_thread.c | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index d800c4c..4ae5313 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -2608,7 +2608,7 @@ twe_surface_destroy_swapchain(twe_surface_h twe_surface) } if (surf_source->vk_sub_thread) { - TPL_DEBUG("vk_sub_thread(%d) exit.", surf_source->vk_sub_thread); + TPL_DEBUG("vk_sub_thread(%p) exit.", surf_source->vk_sub_thread); g_mutex_lock(&surf_source->sub_thread_mutex); g_main_loop_quit(surf_source->vk_sub_loop); @@ -2837,7 +2837,8 @@ twe_surface_commit_without_enqueue(twe_surface_h twe_surface, if (!surf_source->is_destroying) _twe_thread_wl_surface_commit(surf_source, tbm_surface); else - TPL_WARN("surf_source(%p) native window is already destroyed."); + TPL_WARN("surf_source(%p) native window is already destroyed.", + surf_source); TPL_OBJECT_UNLOCK(&surf_source->obj); } diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index b7e2128..e4fa659 100644 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -698,7 +698,7 @@ __tpl_wl_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, surface->frontbuffer, tbm_bo_export(tbm_surface_internal_get_bo( surface->frontbuffer, 0))); - TRACE_ASYNC_BEGIN(surface->frontbuffer, + TRACE_ASYNC_BEGIN((int)surface->frontbuffer, "[DEQ]~[ENQ] BO_NAME:%d", tbm_bo_export(tbm_surface_internal_get_bo( surface->frontbuffer, 0))); diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index f670382..6f96b2f 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -433,12 +433,13 @@ __tpl_wl_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, lock_ret = twe_display_lock(wayland_vk_wsi_display->twe_display); if (res == TPL_ERROR_TIME_OUT) { - TPL_ERR("Failed to get buffer during timeout_ns(%u)", timeout_ns); + TPL_ERR("Failed to get buffer during timeout_ns(%" PRIu64 ")", + timeout_ns); if (lock_ret == TPL_ERROR_NONE) twe_display_unlock(wayland_vk_wsi_display->twe_display); return NULL; } else if (res != TPL_ERROR_NONE) { - TPL_ERR("Invalid parameter. twe_surface(%p) timeout_ns(%u)", + TPL_ERR("Invalid parameter. twe_surface(%p) timeout_ns(%" PRIu64 ")", wayland_vk_wsi_surface->twe_surface, timeout_ns); if (lock_ret == TPL_ERROR_NONE) twe_display_unlock(wayland_vk_wsi_display->twe_display); -- 2.7.4 From 0459ee298e0e1941b08c7d6e7563f228c5e57e7b Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 16 Jan 2018 13:58:03 +0900 Subject: [PATCH 09/16] tpl_wayland_egl_thread: Registered dequeueable callback to tbm_queue. - Signal to free_queue_cond when dequeuable callback is called. - wl_buffer release callback does not signal to free_queue_cond, and if dequeuable callback is called when tbm_surface_queue_release() is called, signal to free_queue_cond. Change-Id: I52d898f37ef6dc5074e98690399a04116869d177 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 58 +++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 4ae5313..6c4f1ef 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1273,8 +1273,6 @@ __cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer) twe_wl_surf_source *surf_source = buf_info->surf_source; tbm_surface_queue_error_e tsq_err; - g_mutex_lock(&surf_source->free_queue_mutex); - tsq_err = tbm_surface_queue_release(surf_source->tbm_queue, tbm_surface); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) @@ -1301,9 +1299,6 @@ __cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer) tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); tbm_surface_internal_unref(tbm_surface); - g_cond_signal(&surf_source->free_queue_cond); - g_mutex_unlock(&surf_source->free_queue_mutex); - return; } @@ -1543,16 +1538,23 @@ __cb_tbm_queue_reset_callback(tbm_surface_queue_h tbm_queue, { twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data; - if (surf_source && !g_source_is_destroyed(&surf_source->gsource)) { - surf_source->swapchain_properties.width = - tbm_surface_queue_get_width(tbm_queue); - surf_source->swapchain_properties.height = - tbm_surface_queue_get_height(tbm_queue); - surf_source->swapchain_properties.buffer_count = - tbm_surface_queue_get_size(tbm_queue); - surf_source->format = tbm_surface_queue_get_format(tbm_queue); + if (!surf_source || g_source_is_destroyed(&surf_source->gsource)) { + TPL_ERR("Invalid parameter. surf_source(%p)", surf_source); + return; } + surf_source->swapchain_properties.width = + tbm_surface_queue_get_width(tbm_queue); + surf_source->swapchain_properties.height = + tbm_surface_queue_get_height(tbm_queue); + surf_source->swapchain_properties.buffer_count = + tbm_surface_queue_get_size(tbm_queue); + surf_source->format = tbm_surface_queue_get_format(tbm_queue); + + g_mutex_lock(&surf_source->free_queue_mutex); + g_cond_signal(&surf_source->free_queue_cond); + g_mutex_unlock(&surf_source->free_queue_mutex); + TPL_LOG_T(BACKEND, "tbm_queue(%p) has been reset!", tbm_queue); } @@ -1594,6 +1596,25 @@ static void __cb_tbm_queue_trace_callback(tbm_surface_queue_h tbm_queue, } } +static void __cb_tbm_queue_dequeueable_callback(tbm_surface_queue_h tbm_queue, + void *data) +{ + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data; + + if (!surf_source || g_source_is_destroyed(&surf_source->gsource)) { + TPL_ERR("Invalid parameter. surf_source(%p)", surf_source); + return; + } + + g_mutex_lock(&surf_source->free_queue_mutex); + + TPL_LOG_T(BACKEND, "[DEQUEUEABLE_CB] surf_source(%p) tbm_queue(%p)", + surf_source, surf_source->tbm_queue); + + g_cond_signal(&surf_source->free_queue_cond); + g_mutex_unlock(&surf_source->free_queue_mutex); +} + static void _twe_thread_wl_vk_surface_commit(twe_wl_surf_source *surf_source, tbm_surface_h tbm_surface); @@ -2141,7 +2162,7 @@ _twe_surface_create_tbm_queue(twe_wl_surf_source *source, if (tbm_surface_queue_add_reset_cb(tbm_queue, __cb_tbm_queue_reset_callback, - NULL) != TBM_SURFACE_QUEUE_ERROR_NONE) { + (void *)source) != 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); @@ -2553,6 +2574,15 @@ twe_surface_create_swapchain(twe_surface_h twe_surface, return TPL_ERROR_INVALID_OPERATION; } + if (tbm_surface_queue_add_dequeuable_cb(surf_source->tbm_queue, + __cb_tbm_queue_dequeueable_callback, + (void *)surf_source) != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to register dequeueable callback to tbm_surface_queue(%p)", + surf_source->tbm_queue); + tbm_surface_queue_destroy(surf_source->tbm_queue); + return TPL_ERROR_INVALID_OPERATION; + } + if (present_mode == TPL_DISPLAY_PRESENT_MODE_FIFO || present_mode == TPL_DISPLAY_PRESENT_MODE_FIFO_RELAXED) { surf_source->vblank_waiting_buffers = __tpl_list_alloc(); -- 2.7.4 From b7c050ba63dc9f6940a65798211e4d6742b27b31 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 16 Jan 2018 15:36:58 +0900 Subject: [PATCH 10/16] tpl_wayland_egl_thread: Changed to use GMutex instead of tpl_object of the disp_source. Change-Id: Ieec00366d2084cfb9b77ed518bac7c3fb8c7d1b2 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 6c4f1ef..1a69167 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -75,7 +75,7 @@ struct _twe_wl_disp_source { tpl_bool_t prepared; twe_del_source *disp_del_source; twe_thread *thread; - tpl_object_t obj; + GMutex wl_event_mutex; /* TODO : surface list */ }; @@ -634,7 +634,7 @@ _twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer data) return G_SOURCE_REMOVE; } - TPL_OBJECT_LOCK(&disp_source->obj); + g_mutex_lock(&disp_source->wl_event_mutex); if (disp_source->gfd.revents & G_IO_IN) { if (wl_display_dispatch_queue_pending(disp_source->disp, disp_source->ev_queue) == -1) { @@ -643,7 +643,7 @@ _twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer data) } wl_display_flush(disp_source->disp); - TPL_OBJECT_UNLOCK(&disp_source->obj); + g_mutex_unlock(&disp_source->wl_event_mutex); return G_SOURCE_CONTINUE; } @@ -651,11 +651,7 @@ _twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer data) static void _twe_thread_wl_disp_finalize(GSource *source) { - twe_wl_disp_source *disp_source = (twe_wl_disp_source *)source; - - TPL_LOG_T(BACKEND, "finalize| disp_source(%p)", disp_source); - - __tpl_object_fini(&disp_source->obj); + TPL_LOG_T(BACKEND, "finalize| disp_source(%p)", source); return; } @@ -917,7 +913,7 @@ _twe_thread_wl_disp_source_destroy(void *source) } g_mutex_lock(&_twe_ctx->thread_mutex); - TPL_OBJECT_LOCK(&disp_source->obj); + g_mutex_lock(&disp_source->wl_event_mutex); /* If disp_source is in prepared state, cancel it */ if (disp_source->prepared) { @@ -931,11 +927,13 @@ _twe_thread_wl_disp_source_destroy(void *source) } wl_event_queue_destroy(disp_source->ev_queue); - TPL_OBJECT_UNLOCK(&disp_source->obj); + g_mutex_unlock(&disp_source->wl_event_mutex); TPL_LOG_T(BACKEND, "[DEL] twe_display(%p) wl_display(%p)", disp_source, disp_source->disp); + g_mutex_clear(&disp_source->wl_event_mutex); + g_source_remove_poll(&disp_source->gsource, &disp_source->gfd); g_source_destroy(&disp_source->gsource); g_source_unref(&disp_source->gsource); @@ -981,7 +979,7 @@ twe_display_add(twe_thread* thread, source->gfd.fd = wl_display_get_fd(display); source->gfd.events = G_IO_IN | G_IO_ERR; source->gfd.revents = 0; - __tpl_object_init(&source->obj, TPL_OBJECT_DISPLAY, NULL); + g_mutex_init(&source->wl_event_mutex); if (backend == TPL_BACKEND_WAYLAND_VULKAN_WSI || backend == TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD) { @@ -1062,7 +1060,9 @@ twe_display_lock(twe_display_h display) return TPL_ERROR_INVALID_PARAMETER; } - return TPL_OBJECT_LOCK(&disp_source->obj); + g_mutex_lock(&disp_source->wl_event_mutex); + + return TPL_ERROR_NONE; } void @@ -1074,7 +1074,7 @@ twe_display_unlock(twe_display_h display) return; } - TPL_OBJECT_UNLOCK(&disp_source->obj); + g_mutex_unlock(&disp_source->wl_event_mutex); } tpl_result_t @@ -2240,7 +2240,7 @@ _twe_thread_wl_surf_source_destroy(void *source) g_mutex_lock(&_twe_ctx->thread_mutex); - TPL_OBJECT_LOCK(&disp_source->obj); + g_mutex_lock(&disp_source->wl_event_mutex); if (surf_source->in_use_buffers) { __tpl_list_free(surf_source->in_use_buffers, @@ -2298,7 +2298,7 @@ _twe_thread_wl_surf_source_destroy(void *source) surf_source->surf = NULL; } - TPL_OBJECT_UNLOCK(&disp_source->obj); + g_mutex_unlock(&disp_source->wl_event_mutex); g_cond_clear(&surf_source->free_queue_cond); g_mutex_clear(&surf_source->free_queue_mutex); -- 2.7.4 From 169c9152399e169cc74005c8c14ed9a52e126467 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 17 Jan 2018 11:40:16 +0900 Subject: [PATCH 11/16] tpl_wayland_egl_thread: Changed to use GMutex instead of tpl_object of the surf_source. Change-Id: I05bdca4011f142fd39db939de49a9d83db55259c Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 54 ++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 1a69167..cc3e2e8 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -104,7 +104,6 @@ struct _twe_wl_surf_source { } swapchain_properties; tpl_surface_cb_func_t rotate_cb; tpl_bool_t rotation_capability; - tpl_object_t obj; /* for mutex lock */ tpl_list_t *committed_buffers; tpl_list_t *in_use_buffers; tpl_list_t *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */ @@ -117,6 +116,8 @@ struct _twe_wl_surf_source { twe_wl_disp_source *disp_source; twe_del_source *surf_del_source; + GMutex surf_mutex; + GMutex free_queue_mutex; GCond free_queue_cond; @@ -1123,12 +1124,12 @@ __cb_destroy_callback(void *private) if (surf_source) { TPL_LOG_T(BACKEND, "[DESTROY_CB] wl_egl_window(%p) surf_source(%p)", surf_source->wl_egl_window, surf_source); - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); surf_source->wl_egl_window->private = NULL; surf_source->wl_egl_window = NULL; surf_source->surf = NULL; surf_source->is_destroying = TPL_TRUE; - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } } @@ -1279,11 +1280,11 @@ __cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer) TPL_ERR("tbm_surface(%p) tsq_err(%d)", tbm_surface, tsq_err); if (surf_source->committed_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); __tpl_list_remove_data(surf_source->committed_buffers, (void *)tbm_surface, TPL_FIRST, NULL); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } buf_info->need_to_release = TPL_FALSE; @@ -1308,11 +1309,11 @@ __cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer) g_mutex_lock(&surf_source->free_queue_mutex); if (surf_source->committed_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); __tpl_list_remove_data(surf_source->committed_buffers, (void *)tbm_surface, TPL_FIRST, NULL); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } TRACE_MARK("[RELEASE] BO(%d)", @@ -1389,10 +1390,10 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info->sync_fd = -1; if (surf_source->in_use_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); __tpl_list_push_back(surf_source->in_use_buffers, (void *)tbm_surface); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } TRACE_MARK("[SET_BUFFER_INFO] BO(%d)", @@ -1485,10 +1486,10 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info); if (surf_source->in_use_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); __tpl_list_push_back(surf_source->in_use_buffers, (void *)tbm_surface); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } TRACE_MARK("[SET_BUFFER_INFO] BO(%d)", @@ -1524,11 +1525,11 @@ _twe_surface_cancel_dequeued_buffer(twe_wl_surf_source *surf_source, tbm_surface); if (surf_source->in_use_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); /* Stop tracking of this canceled tbm_surface */ __tpl_list_remove_data(surf_source->in_use_buffers, (void *)tbm_surface, TPL_FIRST, NULL); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } } @@ -1645,7 +1646,7 @@ __cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, if (!disp_source->is_vulkan_dpy) _twe_thread_wl_surface_acquire_and_commit(surf_source); else { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); switch (surf_source->swapchain_properties.present_mode) { case TPL_DISPLAY_PRESENT_MODE_MAILBOX: if (surf_source->draw_done_buffer) { @@ -1686,7 +1687,7 @@ __cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, break; } - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } } @@ -1928,7 +1929,7 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO, (void **)&buf_info); - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); if (!disp_source->is_vulkan_dpy) { /* wayland_egl */ TPL_LOG_T(BACKEND, "[ACQ] tbm_surface(%p) bo(%d)", tbm_surface, @@ -1996,7 +1997,7 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) break; } } - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } } @@ -2048,8 +2049,6 @@ _twe_thread_wl_surface_finalize(GSource *source) close(surf_source->event_fd); surf_source->event_fd = -1; - __tpl_object_fini(&surf_source->obj); - return; } @@ -2242,6 +2241,8 @@ _twe_thread_wl_surf_source_destroy(void *source) g_mutex_lock(&disp_source->wl_event_mutex); + g_mutex_lock(&surf_source->surf_mutex); + if (surf_source->in_use_buffers) { __tpl_list_free(surf_source->in_use_buffers, (tpl_free_func_t)__cb_buffer_remove_from_list); @@ -2298,6 +2299,9 @@ _twe_thread_wl_surf_source_destroy(void *source) surf_source->surf = NULL; } + g_mutex_unlock(&surf_source->surf_mutex); + g_mutex_clear(&surf_source->surf_mutex); + g_mutex_unlock(&disp_source->wl_event_mutex); g_cond_clear(&surf_source->free_queue_cond); @@ -2397,8 +2401,6 @@ twe_surface_add(twe_thread* thread, source->vk_sub_thread = NULL; source->draw_done_count = 0; - __tpl_object_init(&source->obj, TPL_OBJECT_SURFACE, NULL); - if (!disp_source->is_vulkan_dpy) { struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)native_handle; @@ -2430,6 +2432,8 @@ 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->free_queue_mutex); g_cond_init(&source->free_queue_cond); @@ -2662,7 +2666,7 @@ twe_surface_destroy_swapchain(twe_surface_h twe_surface) } if (surf_source->committed_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); while (!__tpl_list_is_empty(surf_source->committed_buffers)) { tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; tbm_surface_h tbm_surface = @@ -2677,7 +2681,7 @@ twe_surface_destroy_swapchain(twe_surface_h twe_surface) TPL_ERR("Failed to release. tbm_surface(%p) tsq_err(%d)", tbm_surface, tsq_err); } - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } if (surf_source->tbm_queue) { @@ -2863,13 +2867,13 @@ twe_surface_commit_without_enqueue(twe_surface_h twe_surface, return; } - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); if (!surf_source->is_destroying) _twe_thread_wl_surface_commit(surf_source, tbm_surface); else TPL_WARN("surf_source(%p) native window is already destroyed.", surf_source); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } static gboolean -- 2.7.4 From ce6410059a19cdf3ad442d767ae1dee2a3665d6c Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 17 Jan 2018 13:40:56 +0900 Subject: [PATCH 12/16] tpl_wl_vk_thread: Fixed the locking mechanism in dequeueable. Change-Id: Id63e92a3990a7f286d415760ed60aed93512ae0b Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 14 +++++++--- src/tpl_wl_vk_thread.c | 66 ++++++++++++++++++-------------------------- 2 files changed, 37 insertions(+), 43 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index cc3e2e8..03e6324 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -3086,6 +3086,7 @@ tpl_result_t twe_surface_wait_dequeueable(twe_surface_h twe_surface, uint64_t timeout_ns) { twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface; + twe_wl_disp_source *disp_source = NULL; gint64 end_time; if (!surf_source || g_source_is_destroyed(&surf_source->gsource)) { @@ -3093,8 +3094,7 @@ twe_surface_wait_dequeueable(twe_surface_h twe_surface, uint64_t timeout_ns) return TPL_ERROR_INVALID_PARAMETER; } - /* wait until dequeueable */ - g_mutex_lock(&surf_source->free_queue_mutex); + disp_source = surf_source->disp_source; if (timeout_ns != UINT64_MAX) end_time = g_get_monotonic_time() + (timeout_ns / 1000); @@ -3102,12 +3102,18 @@ twe_surface_wait_dequeueable(twe_surface_h twe_surface, uint64_t timeout_ns) while (!tbm_surface_queue_can_dequeue(surf_source->tbm_queue, 0)) { gboolean ret = FALSE; + g_mutex_unlock(&disp_source->wl_event_mutex); + + /* wait until dequeueable */ + g_mutex_lock(&surf_source->free_queue_mutex); + if (timeout_ns != UINT64_MAX) { ret = g_cond_wait_until(&surf_source->free_queue_cond, &surf_source->free_queue_mutex, end_time); if (ret == FALSE) { TPL_WARN("time out to wait dequeueable."); + g_mutex_lock(&disp_source->wl_event_mutex); g_mutex_unlock(&surf_source->free_queue_mutex); return TPL_ERROR_TIME_OUT; } @@ -3115,10 +3121,10 @@ twe_surface_wait_dequeueable(twe_surface_h twe_surface, uint64_t timeout_ns) g_cond_wait(&surf_source->free_queue_cond, &surf_source->free_queue_mutex); } + g_mutex_unlock(&surf_source->free_queue_mutex); + g_mutex_lock(&disp_source->wl_event_mutex); } - g_mutex_unlock(&surf_source->free_queue_mutex); - return TPL_ERROR_NONE; } diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 6f96b2f..9c7a8c1 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -408,50 +408,38 @@ __tpl_wl_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display = (tpl_wayland_vk_wsi_display_t *)surface->display->backend.data; tbm_surface_queue_error_e tsq_err = 0; - tpl_result_t lock_ret = TPL_ERROR_NONE; + tpl_result_t lock_res = TPL_ERROR_NONE; + tpl_result_t res = TPL_ERROR_NONE; if (sync_fence) *sync_fence = -1; - /* After the can dequeue state, call twe_display_lock to prevent other - * events from being processed in wayland_egl_thread - * during below dequeue procedure. */ - lock_ret = twe_display_lock(wayland_vk_wsi_display->twe_display); - - if (!tbm_surface_queue_can_dequeue(wayland_vk_wsi_surface->tbm_queue, 0)) { - if (timeout_ns == 0) return NULL; - else { - tpl_result_t res = TPL_ERROR_NONE; - if (lock_ret == TPL_ERROR_NONE) - twe_display_unlock(wayland_vk_wsi_display->twe_display); - TPL_OBJECT_UNLOCK(surface); - TRACE_BEGIN("WAIT_DEQUEUEABLE"); - res = twe_surface_wait_dequeueable(wayland_vk_wsi_surface->twe_surface, - timeout_ns); - TRACE_END(); - TPL_OBJECT_LOCK(surface); - lock_ret = twe_display_lock(wayland_vk_wsi_display->twe_display); - - if (res == TPL_ERROR_TIME_OUT) { - TPL_ERR("Failed to get buffer during timeout_ns(%" PRIu64 ")", - timeout_ns); - if (lock_ret == TPL_ERROR_NONE) - twe_display_unlock(wayland_vk_wsi_display->twe_display); - return NULL; - } else if (res != TPL_ERROR_NONE) { - TPL_ERR("Invalid parameter. twe_surface(%p) timeout_ns(%" PRIu64 ")", - wayland_vk_wsi_surface->twe_surface, timeout_ns); - if (lock_ret == TPL_ERROR_NONE) - twe_display_unlock(wayland_vk_wsi_display->twe_display); - return NULL; - } - } + TPL_OBJECT_UNLOCK(surface); + TRACE_BEGIN("WAIT_DEQUEUEABLE"); + lock_res = twe_display_lock(wayland_vk_wsi_display->twe_display); + res = twe_surface_wait_dequeueable(wayland_vk_wsi_surface->twe_surface, + timeout_ns); + TRACE_END(); + TPL_OBJECT_LOCK(surface); + + if (res == TPL_ERROR_TIME_OUT) { + TPL_ERR("Failed to get buffer during timeout_ns(%" PRIu64 ")", + timeout_ns); + if (lock_res == TPL_ERROR_NONE) + twe_display_unlock(wayland_vk_wsi_display->twe_display); + return NULL; + } else if (res != TPL_ERROR_NONE) { + TPL_ERR("Invalid operation. twe_surface(%p) timeout_ns(%" PRIu64 ")", + wayland_vk_wsi_surface->twe_surface, timeout_ns); + if (lock_res == TPL_ERROR_NONE) + twe_display_unlock(wayland_vk_wsi_display->twe_display); + return NULL; } if (wayland_vk_wsi_surface->reset) { TPL_LOG_T("WL_VK", "tbm_queue(%p) has been reset. Do not process dequeue.", wayland_vk_wsi_surface->tbm_queue); - if (lock_ret == TPL_ERROR_NONE) + if (lock_res == TPL_ERROR_NONE) twe_display_unlock(wayland_vk_wsi_display->twe_display); return NULL; } @@ -462,7 +450,7 @@ __tpl_wl_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, if (!tbm_surface) { TPL_ERR("Failed to get tbm_surface from tbm_surface_queue(%p) | tsq_err = %d", wayland_vk_wsi_surface->tbm_queue, tsq_err); - if (lock_ret == TPL_ERROR_NONE) + if (lock_res == TPL_ERROR_NONE) twe_display_unlock(wayland_vk_wsi_display->twe_display); return NULL; } @@ -473,11 +461,11 @@ __tpl_wl_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, *sync_fence = twe_surface_create_sync_fd(tbm_surface); } - TPL_LOG_T("WL_VK", "[DEQ] tbm_surface(%p) bo(%d)", - tbm_surface, + TPL_LOG_T("WL_VK", "[DEQ] tbm_queue(%p) tbm_surface(%p) bo(%d)", + wayland_vk_wsi_surface->tbm_queue, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); - if (lock_ret == TPL_ERROR_NONE) + if (lock_res == TPL_ERROR_NONE) twe_display_unlock(wayland_vk_wsi_display->twe_display); return tbm_surface; -- 2.7.4 From 09121cc41b1b124c4fc978ff9710bd5b3ede1e8a Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 8 Feb 2018 13:15:09 +0900 Subject: [PATCH 13/16] tpl_wayland_egl_thread: Deleted unnecessary locking that can occur deadlock. - To signal to free_queue_cond has been changed into dequeueable_callback() Change-Id: Ib4028f0d7561b7ebf8161054ef23ec1ee5e20f7b Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 03e6324..82d37ff 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1779,13 +1779,10 @@ _twe_thread_wl_vk_surface_commit(twe_wl_surf_source *surf_source, /* Presented buffer's sync operating dependent on tdm timeline fence. */ if (buf_info->sync_fd != -1) { - g_mutex_lock(&surf_source->free_queue_mutex); tsq_err = tbm_surface_queue_release(surf_source->tbm_queue, tbm_surface); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) TPL_ERR("Failed to release tbm_surface(%p) when vk_surface_commit.", tbm_surface); - g_cond_signal(&surf_source->free_queue_cond); - g_mutex_unlock(&surf_source->free_queue_mutex); buf_info->need_to_release = TPL_FALSE; } else { /* Dependent on wl_buffer release event. */ @@ -1947,7 +1944,6 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) case TPL_DISPLAY_PRESENT_MODE_MAILBOX: if (surf_source->draw_done_buffer) { - g_mutex_lock(&surf_source->free_queue_mutex); TPL_LOG_T(BACKEND, "[SKIP] tbm_surface(%p) bo(%d)", tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo( @@ -1955,8 +1951,6 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) tbm_surface_internal_unref(surf_source->draw_done_buffer); tbm_surface_queue_release(surf_source->tbm_queue, surf_source->draw_done_buffer); - g_cond_signal(&surf_source->free_queue_cond); - g_mutex_unlock(&surf_source->free_queue_mutex); } surf_source->draw_done_buffer = tbm_surface; -- 2.7.4 From 4d1f1392d93689e8da879bd4c43d54e28f05297f Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 8 Feb 2018 14:35:51 +0900 Subject: [PATCH 14/16] Package version up to 1.5.4 Change-Id: Ied81baf78938d7200526d5126de5d907f70dabf7 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 4b1e945..4efe9e2 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 5 -%define TPL_VERSION_PATCH 3 +%define TPL_VERSION_PATCH 4 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From d9822dae06672b889d78939b48b9e394d5b2f423 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 22 Feb 2018 11:05:31 +0900 Subject: [PATCH 15/16] tpl: Fixed an issue runtime_fini was not thread safe. Change-Id: Iea2ae18e9b2dd6042fa1e86eda54fa8ef7b5fdb6 Signed-off-by: joonbum.ko --- src/tpl.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/tpl.c b/src/tpl.c index d29e9de..7c834ce 100644 --- a/src/tpl.c +++ b/src/tpl.c @@ -38,19 +38,21 @@ __tpl_init(void) static void __attribute__((destructor)) __tpl_runtime_fini(void) { - if (runtime != NULL) { - int i; - - if (!pthread_mutex_lock(&runtime_mutex)) { + if (!pthread_mutex_lock(&runtime_mutex)) { + if (runtime != NULL) { + int i; for (i = 0; i < TPL_BACKEND_COUNT; i++) { if (runtime->displays[i] != NULL) __tpl_hashlist_destroy(&(runtime->displays[i])); + if (runtime->surfaces[i] != NULL) + __tpl_hashlist_destroy(&(runtime->surfaces[i])); } - pthread_mutex_unlock(&runtime_mutex); + + free(runtime); + runtime = NULL; } - free(runtime); - runtime = NULL; + pthread_mutex_unlock(&runtime_mutex); } #ifdef OBJECT_HASH_CHECK -- 2.7.4 From 4ec9e72e9434ab299767024406c39f1d0651c995 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 15 Mar 2018 14:07:48 +0900 Subject: [PATCH 16/16] wayland-egl-tizen: Added a new packaging for wayland-egl-tizen. - wayland-egl-tizen provides below RPMs libwayland-egl-tizen.rpm - libwayland-egl-tizen.so* libwayland-egl-tizen-devel.rpm - wayland-egl-tizen.pc - wayland-egl-tizen.h - wayland-egl-tizen is a separate package from the existing wayland-egl to provide tizen-specific extension APIs. - If wayland-client wants to use tizen-only wl_egl_window API, client should add wayland-egl-tizen.pc to their BuildRequires and include wayland-egl-tizen.h in their source code. - This change to the wayland-egl-tizen package is the first step in upgrading wayland in TIZEN, and the wayland-egl in libtpl-egl will be deprecated. Change-Id: Icb07de25890edc8c8eb228fbdf4a8e3e6673aa99 Signed-off-by: joonbum.ko --- configure.ac | 14 +++- packaging/libtpl-egl.spec | 41 ++++++++++ packaging/libwayland-egl-tizen.manifest | 5 ++ pkgconfig/Makefile.am | 2 +- pkgconfig/wayland-egl-tizen.pc.in | 10 +++ src/wayland-egl/Makefile.am | 15 ++++ src/wayland-egl/wayland-egl-tizen.c | 141 ++++++++++++++++++++++++++++++++ src/wayland-egl/wayland-egl-tizen.h | 22 ++++- src/wayland-egl/wayland-egl.c | 34 -------- 9 files changed, 242 insertions(+), 42 deletions(-) create mode 100644 packaging/libwayland-egl-tizen.manifest create mode 100644 pkgconfig/wayland-egl-tizen.pc.in create mode 100644 src/wayland-egl/wayland-egl-tizen.c diff --git a/configure.ac b/configure.ac index 5379baa..fbdb729 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,9 @@ AC_SUBST(TPL_VERSION_PATCH) AC_SUBST(WL_EGL_VERSION_MAJOR) AC_SUBST(WL_EGL_VERSION_MINOR) AC_SUBST(WL_EGL_VERSION_PATCH) - +AC_SUBST(WL_EGL_TIZEN_VERSION_MAJOR) +AC_SUBST(WL_EGL_TIZEN_VERSION_MINOR) +AC_SUBST(WL_EGL_TIZEN_VERSION_PATCH) # Checks for programs. AC_PROG_CXX AC_PROG_CC @@ -172,8 +174,10 @@ AS_IF([test "${enable_gcov}" = "yes" || test "${enable_gcov}" = "1"], [TPL_CFLAGS+=" -fprofile-arcs -ftest-coverage" TPL_LIBS+=" -lgcov " WL_EGL_CFLAGS+=" -fprofile-arcs -ftest-coverage" - WL_EGL_LIBS+=" -lgcov "], - []) + WL_EGL_LIBS+=" -lgcov " + WL_EGL_TIZEN_CFLAGS+=" -fprofile-arcs -ftest-coverage" + WL_EGL_TIZENLIBS+=" -lgcov ", + ]) AM_CONDITIONAL([ENABLE_GCOV], [test "${enable_gcov}" = "yes" || test "${enable_gcov}" = "1"]) @@ -186,6 +190,9 @@ AC_SUBST([TPL_LIBS]) AC_SUBST([WL_EGL_CFLAGS]) AC_SUBST([WL_EGL_LIBS]) +AC_SUBST([WL_EGL_TIZEN_CFLAGS]) +AC_SUBST([WL_EGL_TIZEN_LIBS]) + # Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE AC_TYPE_INT32_T @@ -209,6 +216,7 @@ AC_CONFIG_FILES([ pkgconfig/Makefile pkgconfig/tpl-egl.pc pkgconfig/wayland-egl.pc + pkgconfig/wayland-egl-tizen.pc ]) AM_COND_IF([WITH_UTEST], diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 4efe9e2..33b6159 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -29,6 +29,12 @@ %define WL_EGL_VERSION_PATCH 3 %define WL_EGL_VERSION %{WL_EGL_VERSION_MAJOR}.%{WL_EGL_VERSION_MINOR}.%{WL_EGL_VERSION_PATCH} +#WAYLAND-EGL-TIZEN VERSION MACROS +%define WL_EGL_TIZEN_VERSION_MAJOR 1 +%define WL_EGL_TIZEN_VERSION_MINOR 0 +%define WL_EGL_TIZEN_VERSION_PATCH 0 +%define WL_EGL_TIZEN_VERSION %{WL_EGL_TIZEN_VERSION_MAJOR}.%{WL_EGL_TIZEN_VERSION_MINOR}.%{WL_EGL_TIZEN_VERSION_PATCH} + #TPL WINDOW SYSTEM CHECK %if "%{TPL_WINSYS}" != "DRI2" && "%{TPL_WINSYS}" != "DRI3" && "%{TPL_WINSYS}" != "WL" BuildRequires: ERROR(No_window_system_designated) @@ -123,6 +129,23 @@ Requires: libwayland-egl %description -n libwayland-egl-devel Development header files for use with Wayland protocol + +%package -n libwayland-egl-tizen +Version: %{WL_EGL_TIZEN_VERSION} +Release: 0 +Summary: Wayland EGL TIZEN backend + +%description -n libwayland-egl-tizen +This package provides tizen specific extension fo wayland-egl. + +%package -n libwayland-egl-tizen-devel +Version: %{WL_EGL_TIZEN_VERSION} +Release: 0 +Summary: Development header files for wayland-egl tizen extensions. +Requires: libwayland-egl libwayland-egl-tizen + +%description -n libwayland-egl-tizen-devel +Development header files for wayland-egl tizen extensions. %endif %if %{with utest} || "%{ENABLE_TPL_TEST}" == "1" @@ -146,6 +169,10 @@ export WL_EGL_VERSION_MAJOR=%{WL_EGL_VERSION_MAJOR} export WL_EGL_VERSION_MINOR=%{WL_EGL_VERSION_MINOR} export WL_EGL_VERSION_PATCH=%{WL_EGL_VERSION_PATCH} +export WL_EGL_TIZEN_VERSION_MAJOR=%{WL_EGL_TIZEN_VERSION_MAJOR} +export WL_EGL_TIZEN_VERSION_MINOR=%{WL_EGL_TIZEN_VERSION_MINOR} +export WL_EGL_TIZEN_VERSION_PATCH=%{WL_EGL_TIZEN_VERSION_PATCH} + %reconfigure \ %ifarch aarch64 --with-arch=aarch64 \ @@ -181,6 +208,8 @@ rm -rf %{buildroot} %if "%{TPL_WINSYS}" == "WL" %post -n libwayland-egl -p /sbin/ldconfig %postun -n libwayland-egl -p /sbin/ldconfig +%post -n libwayland-egl-tizen -p /sbin/ldconfig +%postun -n libwayland-egl-tizen -p /sbin/ldconfig %endif %files @@ -208,6 +237,18 @@ rm -rf %{buildroot} %{_includedir}/wayland-egl-tizen.h %{_libdir}/libwayland-egl.so %{_libdir}/pkgconfig/wayland-egl.pc + +%files -n libwayland-egl-tizen +%manifest packaging/libwayland-egl-tizen.manifest +%license COPYING +%defattr(-,root,root,-) +%{_libdir}/libwayland-egl-tizen.so* + +%files -n libwayland-egl-tizen-devel +%defattr(-,root,root,-) +%{_includedir}/wayland-egl-tizen.h +%{_libdir}/libwayland-egl-tizen.so +%{_libdir}/pkgconfig/wayland-egl-tizen.pc %endif %if %{with utest} || "%{ENABLE_TPL_TEST}" == "1" diff --git a/packaging/libwayland-egl-tizen.manifest b/packaging/libwayland-egl-tizen.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/packaging/libwayland-egl-tizen.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index 9f4a13e..ac2f380 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -1,3 +1,3 @@ pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = tpl-egl.pc wayland-egl.pc +pkgconfig_DATA = tpl-egl.pc wayland-egl.pc wayland-egl-tizen.pc diff --git a/pkgconfig/wayland-egl-tizen.pc.in b/pkgconfig/wayland-egl-tizen.pc.in new file mode 100644 index 0000000..b474ee6 --- /dev/null +++ b/pkgconfig/wayland-egl-tizen.pc.in @@ -0,0 +1,10 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${exec_prefix}/@LIB@ +includedir=${prefix}/include + +Name: wayland-egl-tizen +Description: Wayland EGL Extension APIs for TIZEN +Version: 1.0.0 +Libs: -L${libdir} -lwayland-egl-tizen +Cflags: -I${includedir} diff --git a/src/wayland-egl/Makefile.am b/src/wayland-egl/Makefile.am index cf0a9e6..626fa7e 100644 --- a/src/wayland-egl/Makefile.am +++ b/src/wayland-egl/Makefile.am @@ -15,3 +15,18 @@ libwayland_egl_la_LIBADD = @WL_EGL_LIBS@ libwayland_egl_la_LDFLAGS = -version-number @WL_EGL_VERSION_MAJOR@:@WL_EGL_VERSION_MINOR@:@WL_EGL_VERSION_PATCH@ libwayland_egl_la_SOURCES = wayland-egl.c +libwayland_egl_tizen_la_LTLIBRARIES = libwayland-egl-tizen.la +libwayland_egl_tizen_ladir = $(libdir) + +libwayland_egl_tizen_lainclude_HEADERS = wayland-egl-tizen.h +libwayland_egl_tizen_laincludedir = $(includedir) + +libwayland_egl_tizen_la_CFLAGS = -I$(srcdir) \ + @WL_EGL_TIZEN_CFLAGS@ +if ENABLE_GCOV +libwayland_egl_la_CFLAGS += -DTIZEN_TEST_GCOV +endif + +libwayland_egl_tizen_la_LIBADD = @WL_EGL_TIZEN_LIBS@ +libwayland_egl_tizen_la_LDFLAGS = -version-number @WL_EGL_TIZEN_VERSION_MAJOR@:@WL_EGL_TIZEN_VERSION_MINOR@:@WL_EGL_TIZEN_VERSION_PATCH@ +libwayland_egl_tizen_la_SOURCES = wayland-egl-tizen.c diff --git a/src/wayland-egl/wayland-egl-tizen.c b/src/wayland-egl/wayland-egl-tizen.c new file mode 100644 index 0000000..a342cca --- /dev/null +++ b/src/wayland-egl/wayland-egl-tizen.c @@ -0,0 +1,141 @@ +#include +#include "wayland-egl-tizen.h" +#include "wayland-egl-priv.h" + +#define WL_EGL_DEBUG 1 +#if WL_EGL_DEBUG + +#include +#include +#include +#include +#include +#include + +unsigned int wl_egl_log_level; + +/* WL-EGL Log Level - 0:unintialized, 1:initialized(no logging), 2:min log, 3:more log */ +#define WL_EGL_LOG(lvl, f, x...) { \ + if (wl_egl_log_level == 1) { \ + } \ + else if (wl_egl_log_level > 1) { \ + if (wl_egl_log_level <= lvl) \ + WL_EGL_LOG_PRINT(f, ##x) \ + } \ + else { \ + char *env = getenv("WL_EGL_LOG_LEVEL"); \ + if (env == NULL) \ + wl_egl_log_level = 1; \ + else \ + wl_egl_log_level = atoi(env); \ + \ + if (wl_egl_log_level > 1 && wl_egl_log_level <= lvl)\ + WL_EGL_LOG_PRINT(f, ##x) \ + } \ + } + +#define WL_EGL_LOG_PRINT(fmt, args...) { \ + printf("[\x1b[32mWL-EGL\x1b[0m %d:%d|\x1b[32m%s\x1b[0m|%d] " fmt "\n", \ + getpid(), (int)syscall(SYS_gettid), __func__, __LINE__, ##args); \ + } + +#define WL_EGL_ERR(f, x...) { \ + printf("[\x1b[31mWL-EGL_ERR\x1b[0m %d:%d|\x1b[31m%s\x1b[0m|%d] " f "\n",\ + getpid(), (int)syscall(SYS_gettid), __func__, __LINE__, ##x); \ + } + +#else +#define WL_EGL_LOG(lvl, f, x...) +#endif + +void +wl_egl_window_tizen_set_rotation(struct wl_egl_window *egl_window, + wl_egl_window_tizen_rotation rotation) +{ + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return; + } + + if (egl_window->rotation == rotation) { + WL_EGL_LOG(2, "rotation(%d) egl_window->rotation(%d) already rotated", + rotation, egl_window->rotation); + return; + } + + egl_window->rotation = rotation; + + if (egl_window->rotate_callback) + egl_window->rotate_callback(egl_window, egl_window->private); +} + +int +wl_egl_window_tizen_get_capabilities(struct wl_egl_window *egl_window) +{ + int capabilities = WL_EGL_WINDOW_CAPABILITY_NONE; + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return capabilities; + } + + if (egl_window->get_rotation_capability) + capabilities = egl_window->get_rotation_capability(egl_window, egl_window->private); + else + capabilities = WL_EGL_WINDOW_CAPABILITY_ROTATION_UNKNOWN; + + return capabilities; +} + +void +wl_egl_window_tizen_set_buffer_transform(struct wl_egl_window *egl_window, + int wl_output_transform) +{ + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return; + } + + if (egl_window->transform == wl_output_transform) { + WL_EGL_LOG(2, + "wl_output_transform(%d) egl_window->transform(%d) already rotated", + wl_output_transform, egl_window->transform); + return; + } + + egl_window->transform = wl_output_transform; +} + +void +wl_egl_window_tizen_set_frontbuffer_mode(struct wl_egl_window *egl_window, + int set) +{ + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return; + } + + egl_window->frontbuffer_mode = set; + + if (egl_window->set_frontbuffer_callback) + egl_window->set_frontbuffer_callback(egl_window, egl_window->private, + set); +} + +void +wl_egl_window_tizen_set_window_transform(struct wl_egl_window *egl_window, + int window_transform) +{ + if (egl_window == NULL) { + WL_EGL_ERR("egl_window is NULL"); + return; + } + + if (egl_window->window_transform == window_transform) { + WL_EGL_LOG(2, + "window_transform(%d) already rotated", + window_transform); + return; + } + + egl_window->window_transform = window_transform; +} diff --git a/src/wayland-egl/wayland-egl-tizen.h b/src/wayland-egl/wayland-egl-tizen.h index ba2b6cf..cbc03f6 100644 --- a/src/wayland-egl/wayland-egl-tizen.h +++ b/src/wayland-egl/wayland-egl-tizen.h @@ -33,24 +33,38 @@ extern "C" { #include +typedef enum { + WL_EGL_WINDOW_TIZEN_CAPABILITY_NONE = 0, + WL_EGL_WINDOW_TIZEN_CAPABILITY_ROTATION_SUPPORTED = (1 << 0), + WL_EGL_WINDOW_TIZEN_CAPABILITY_ROTATION_UNSUPPORTED = (1 << 1), + WL_EGL_WINDOW_TIZEN_CAPABILITY_ROTATION_UNKNOWN = (1 << 2), +} wl_egl_window_tizen_capability; + +typedef enum { + WL_EGL_WINDOW_TIZEN_ROTATION_0 = 0, + WL_EGL_WINDOW_TIZEN_ROTATION_90 = 90, + WL_EGL_WINDOW_TIZEN_ROTATION_180 = 180, + WL_EGL_WINDOW_TIZEN_ROTATION_270 = 270 +} wl_egl_window_tizen_rotation; + void wl_egl_window_tizen_set_rotation(struct wl_egl_window *egl_window, - wl_egl_window_rotation rotation); + wl_egl_window_tizen_rotation rotation); int wl_egl_window_tizen_get_capabilities(struct wl_egl_window *egl_window); void wl_egl_window_tizen_set_buffer_transform(struct wl_egl_window *egl_window, - int wl_output_transform); + int wl_output_transform); void wl_egl_window_tizen_set_frontbuffer_mode(struct wl_egl_window *egl_window, - int set); + int set); void wl_egl_window_tizen_set_window_transform(struct wl_egl_window *egl_window, - int window_transform); + int window_transform); #ifdef __cplusplus } diff --git a/src/wayland-egl/wayland-egl.c b/src/wayland-egl/wayland-egl.c index 08a5fc4..5c16bcf 100644 --- a/src/wayland-egl/wayland-egl.c +++ b/src/wayland-egl/wayland-egl.c @@ -241,37 +241,3 @@ wl_egl_window_set_window_transform(struct wl_egl_window *egl_window, egl_window->window_transform = window_transform; } -void -wl_egl_window_tizen_set_rotation(struct wl_egl_window *egl_window, - wl_egl_window_rotation rotation) -{ - return wl_egl_window_set_rotation(egl_window, rotation); -} - -int -wl_egl_window_tizen_get_capabilities(struct wl_egl_window *egl_window) -{ - return wl_egl_window_get_capabilities(egl_window); -} - -void -wl_egl_window_tizen_set_buffer_transform(struct wl_egl_window *egl_window, - int wl_output_transform) -{ - return wl_egl_window_set_buffer_transform(egl_window, wl_output_transform); -} - -void -wl_egl_window_tizen_set_frontbuffer_mode(struct wl_egl_window *egl_window, - int set) -{ - return wl_egl_window_set_frontbuffer_mode(egl_window, set); -} - -void -wl_egl_window_tizen_set_window_transform(struct wl_egl_window *egl_window, - int window_transform) -{ - return wl_egl_window_set_window_transform(egl_window, window_transform); -} - -- 2.7.4