tpl_wayland_egl_thread: Implemented destroy callback of wl_egl_window. 91/151891/2
authorjoonbum.ko <joonbum.ko@samsung.com>
Wed, 20 Sep 2017 00:25:11 +0000 (09:25 +0900)
committerjoonbum.ko <joonbum.ko@samsung.com>
Fri, 22 Sep 2017 09:01:16 +0000 (18:01 +0900)
 - 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 <joonbum.ko@samsung.com>
src/tpl_wayland_egl_thread.c

index 4fc7976..8823d8c 100644 (file)
@@ -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