From 15571b8f2abb32551528c3cba7c5b5dbbad8ef26 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 20 Sep 2017 09:25:11 +0900 Subject: [PATCH] tpl_wayland_egl_thread: Implemented destroy callback of wl_egl_window. - If wl_egl_window is destroyed before the surface is destroyed, wl_egl_window and wl_surface are not accessed by any routine. Change-Id: I15dd945fbe50007eda7bd6783f687f705fb97852 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 61 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 4fc7976..8823d8c 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -86,6 +86,7 @@ struct _twe_wl_surf_source { tpl_list_t *in_use_buffers; tdm_client_vblank *vblank; tpl_bool_t vblank_done; + tpl_bool_t is_destroying; struct tizen_surface_shm_flusher *tss_flusher; tbm_surface_queue_h tbm_queue; twe_wl_disp_source *disp_source; @@ -285,9 +286,9 @@ twe_thread_destroy(twe_thread* thread) thread->ctx->ref_cnt--; if (thread->ctx->ref_cnt == 0) { - if (thread->ctx->tdm_source) { - _twe_thread_tdm_source_destroy(thread->ctx->tdm_source); - thread->ctx->tdm_source = NULL; + if (_twe_ctx->tdm_source) { + _twe_thread_tdm_source_destroy(_twe_ctx->tdm_source); + _twe_ctx->tdm_source = NULL; } g_main_loop_quit(thread->ctx->twe_loop); @@ -795,6 +796,23 @@ twe_display_unlock(twe_display_h display) } static void +__cb_destroy_callback(void *private) +{ + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)private; + + if (surf_source) { + TPL_LOG_T("WL_EGL", "[DESTROY_CB] wl_egl_window(%p) surf_source(%p)", + surf_source->wl_egl_window, surf_source); + TPL_OBJECT_LOCK(&surf_source->obj); + 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); + } +} + +static void __cb_resize_callback(struct wl_egl_window *wl_egl_window, void *private) { TPL_ASSERT(private); @@ -1319,12 +1337,10 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, } if (surf_source->committed_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); __tpl_list_push_back(surf_source->committed_buffers, tbm_surface); /* Stop tracking of this released tbm_surface. */ __tpl_list_remove_data(surf_source->in_use_buffers, (void *)tbm_surface, TPL_FIRST, NULL); - TPL_OBJECT_UNLOCK(&surf_source->obj); } } @@ -1341,12 +1357,22 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) tbm_surface_h tbm_surface = NULL; tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; + TPL_OBJECT_LOCK(&surf_source->obj); + + if (surf_source->is_destroying) { + TPL_WARN("surf_source(%p) native window is already destroyed.", + surf_source); + TPL_OBJECT_UNLOCK(&surf_source->obj); + return; + } + if (tbm_surface_queue_can_acquire(surf_source->tbm_queue, 0)) { if (surf_source->vblank_done == TPL_TRUE) { tsq_err = tbm_surface_queue_acquire(surf_source->tbm_queue, &tbm_surface); if (!tbm_surface || tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("Failed to acquire from tbm_queue(%p)", surf_source->tbm_queue); + TPL_OBJECT_UNLOCK(&surf_source->obj); return; } @@ -1362,6 +1388,8 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) TPL_LOG_T("WL_EGL", "[ACQ_skip] It will be acquired next vblank."); } } + + TPL_OBJECT_UNLOCK(&surf_source->obj); } static gboolean @@ -1623,6 +1651,7 @@ twe_surface_add(twe_thread* thread, source->rotation_capability = TPL_FALSE; source->vblank = NULL; source->vblank_done = TPL_TRUE; + source->is_destroying = TPL_FALSE; source->committed_buffers = __tpl_list_alloc(); source->in_use_buffers = __tpl_list_alloc(); source->cb_data = NULL; @@ -1633,6 +1662,7 @@ twe_surface_add(twe_thread* thread, _twe_surface_buffer_flusher_init(source); wl_egl_window->private = (void *)source; + wl_egl_window->destroy_window_callback = (void *)__cb_destroy_callback; wl_egl_window->resize_callback = (void *)__cb_resize_callback; wl_egl_window->rotate_callback = (void *)__cb_rotate_callback; wl_egl_window->get_rotation_capability = (void *) @@ -1717,11 +1747,15 @@ twe_surface_del(twe_surface_h twe_surface) surf_source->cb_data = NULL; surf_source->rotate_cb = NULL; - TPL_LOG_T("WL_EGL", "twe_surface(%p) wl_egl_window(%p) wl_surface(%p)", - surf_source, surf_source->wl_egl_window, surf_source->surf); - - surf_source->wl_egl_window = NULL; - surf_source->surf = NULL; + if (surf_source->wl_egl_window) { + TPL_LOG_T("WL_EGL", "twe_surface(%p) wl_egl_window(%p) wl_surface(%p)", + surf_source, surf_source->wl_egl_window, surf_source->surf); + surf_source->wl_egl_window->private = NULL; + surf_source->wl_egl_window = NULL; + surf_source->surf = NULL; + } else { + TPL_LOG_T("WL_EGL", "twe_surface(%p) native window is already destroyed"); + } TPL_OBJECT_UNLOCK(&disp_source->obj); @@ -1872,7 +1906,12 @@ twe_surface_commit_without_enqueue(twe_surface_h twe_surface, return; } - _twe_thread_wl_surface_commit(surf_source, tbm_surface); + TPL_OBJECT_LOCK(&surf_source->obj); + 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_OBJECT_UNLOCK(&surf_source->obj); } tpl_result_t -- 2.7.4