tpl_wayland_egl_thread: Added a list of in_use_buffers to keep track of the buffers... 10/135010/4
authorjoonbum.ko <joonbum.ko@samsung.com>
Fri, 12 May 2017 08:08:28 +0000 (17:08 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 22 Jun 2017 08:51:21 +0000 (08:51 +0000)
 - When twe_surface_del is called, if the surface is deleted even though the DDK still has a buffer,
  it can cause problems at commit time.
 - Tracking the buffers in use can solve the problem by waiting for the surface to be deleted unitl it is finished.

Change-Id: If01bd98d409c5f94b956fcfc3ac20d26ca50df55
Signed-off-by: joonbum.ko <joonbum.ko@samsung.com>
src/tpl_wayland_egl_thread.c

index 6bd49ba..227a0ba 100644 (file)
@@ -62,6 +62,7 @@ struct _twe_wl_surf_source {
        tpl_bool_t vblank_done;
        tpl_object_t obj; /* for mutex lock */
        tpl_list_t *committed_buffers;
+       tpl_list_t *in_use_buffers;
        tdm_client_vblank *vblank;
        tbm_surface_queue_h tbm_queue;
        twe_wl_disp_source *disp_source;
@@ -511,7 +512,7 @@ static void
 __cb_tbm_queue_reset_callback(tbm_surface_queue_h tbm_queue,
                                                          void *data)
 {
-       TPL_DEBUG("tbm_queue(%p) has been reset!", tbm_queue);
+       TPL_LOG_T("WL_EGL", "tbm_queue(%p) has been reset!", tbm_queue);
 }
 
 static void
@@ -566,6 +567,14 @@ static void __cb_tbm_queue_trace_callback(tbm_surface_queue_h tbm_queue,
                        buf_info->rects = NULL;
                        buf_info->num_rects = 0;
                }
+
+               if (surf_source->in_use_buffers) {
+                       TPL_OBJECT_LOCK(&surf_source->obj);
+                       __tpl_list_push_back(surf_source->in_use_buffers,
+                                                                (void *)buf_info);
+                       TPL_OBJECT_UNLOCK(&surf_source->obj);
+               }
+
                TPL_LOG_T("WL_EGL",
                                  "[REUSE_BUF] buf_info(%p) tbm_surface(%p) bo(%d) (%dx%d) rot(%d)",
                                  buf_info, tbm_surface,
@@ -610,6 +619,13 @@ static void __cb_tbm_queue_trace_callback(tbm_surface_queue_h tbm_queue,
        tbm_surface_internal_set_user_data(tbm_surface, KEY_BUFFER_INFO,
                                                                           buf_info);
 
+       if (surf_source->in_use_buffers) {
+               TPL_OBJECT_LOCK(&surf_source->obj);
+               __tpl_list_push_back(surf_source->in_use_buffers,
+                                                        (void *)buf_info);
+               TPL_OBJECT_UNLOCK(&surf_source->obj);
+       }
+
        TPL_LOG_T("WL_EGL",
                          "[NEW_BUF] buf_info(%p) tbm_surface(%p) bo(%d) (%dx%d) rot(%d)",
                          buf_info, tbm_surface,
@@ -695,6 +711,9 @@ _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 *)buf_info, TPL_FIRST, NULL);
                TPL_OBJECT_UNLOCK(&surf_source->obj);
        }
 }
@@ -964,6 +983,7 @@ twe_surface_add(twe_thread* thread,
        source->vblank = _twe_surface_create_vblank(_twe_ctx->tdm_client);
        source->vblank_done = TPL_TRUE;
        source->committed_buffers = __tpl_list_alloc();
+       source->in_use_buffers = __tpl_list_alloc();
 
        __tpl_object_init(&source->obj, TPL_OBJECT_SURFACE, NULL);
 
@@ -1009,6 +1029,14 @@ twe_surface_del(twe_surface_h twe_surface)
        TPL_LOG_T("WL_EGL", "twe_surface(%p) wl_egl_window(%p) wl_surface(%p)",
                          surf_source, surf_source->wl_egl_window, surf_source->surf);
 
+       /* Should be waited until all in_use_buffers has been retrieved. */
+       while (!__tpl_list_is_empty(surf_source->in_use_buffers)) {
+               sched_yield();
+       }
+
+       __tpl_list_free(surf_source->in_use_buffers, NULL);
+       surf_source->in_use_buffers = NULL;
+
        if (surf_source->tbm_queue) {
                tbm_surface_queue_destroy(surf_source->tbm_queue);
                surf_source->tbm_queue = NULL;