Fixed to use last_enq_buffer instead of last_deq_buffer. 21/269421/1
authorJoonbum Ko <joonbum.ko@samsung.com>
Fri, 14 Jan 2022 01:51:51 +0000 (10:51 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Fri, 14 Jan 2022 03:45:03 +0000 (12:45 +0900)
 - last_deq_buffer has a risk to be free from thread.

Change-Id: I677704a5b9bbf8a7c405689663a856d83df595f4
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/tpl_wl_egl_thread.c

index d7b730e..18652be 100755 (executable)
@@ -116,7 +116,7 @@ struct _tpl_wl_egl_surface {
        tpl_wl_egl_buffer_t          *buffers[BUFFER_ARRAY_SIZE];
        int                           buffer_cnt; /* the number of using wl_egl_buffers */
        tpl_gmutex                    buffers_mutex;
-       tpl_wl_egl_buffer_t          *last_deq_buffer;
+       tpl_wl_egl_buffer_t          *last_enq_buffer;
 
        tpl_list_t                   *presentation_feedbacks; /* for tracing presentation feedbacks */
 
@@ -1708,7 +1708,7 @@ __tpl_wl_egl_surface_init(tpl_surface_t *surface)
                wl_egl_surface->buffer_cnt         = 0;
        }
 
-       wl_egl_surface->last_deq_buffer        = NULL;
+       wl_egl_surface->last_enq_buffer        = NULL;
 
        {
                struct tizen_private *tizen_private = NULL;
@@ -2145,7 +2145,7 @@ __tpl_wl_egl_surface_fini(tpl_surface_t *surface)
                wl_egl_surface->wl_egl_window = NULL;
        }
 
-       wl_egl_surface->last_deq_buffer = NULL;
+       wl_egl_surface->last_enq_buffer = NULL;
 
        wl_egl_surface->wl_surface = NULL;
        wl_egl_surface->wl_egl_display = NULL;
@@ -2442,25 +2442,32 @@ __tpl_wl_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns,
        tbm_surface_h   tbm_surface          = NULL;
 
        TPL_OBJECT_UNLOCK(surface);
-       if (wl_egl_surface->reset == TPL_TRUE && wl_egl_surface->last_deq_buffer) {
-               tpl_wl_egl_buffer_t *last_deq_buffer = wl_egl_surface->last_deq_buffer;
+       tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
+       if (wl_egl_surface->reset == TPL_TRUE && wl_egl_surface->last_enq_buffer) {
+               tpl_wl_egl_buffer_t *last_enq_buffer = wl_egl_surface->last_enq_buffer;
 
-               tpl_gmutex_lock(&last_deq_buffer->mutex);
-               if (last_deq_buffer->status > ENQUEUED &&
-                       last_deq_buffer->status < COMMITTED) {
+               tpl_gmutex_lock(&last_enq_buffer->mutex);
+               if (last_enq_buffer->status > ENQUEUED &&
+                       last_enq_buffer->status < COMMITTED) {
                        tpl_result_t wait_result;
-                       wait_result = tpl_cond_timed_wait(&last_deq_buffer->cond,
-                                                                                         &last_deq_buffer->mutex,
+                       TPL_INFO("[DEQ_AFTER_RESET]",
+                                        "waiting for previous buffer(%p) commit", last_enq_buffer);
+                       tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
+                       wait_result = tpl_cond_timed_wait(&last_enq_buffer->cond,
+                                                                                         &last_enq_buffer->mutex,
                                                                                          200); /* 200ms */
-
-                       if (wait_result == TPL_ERROR_TIME_OUT)
+                       tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
+                       if (wait_result == TPL_ERROR_TIME_OUT) {
                                TPL_WARN("timeout occured waiting signaled. wl_egl_buffer(%p)",
-                                                last_deq_buffer);
+                                                last_enq_buffer);
+                               wl_egl_surface->last_enq_buffer = NULL;
+                       }
                }
-               tpl_gmutex_unlock(&last_deq_buffer->mutex);
+               tpl_gmutex_unlock(&last_enq_buffer->mutex);
 
-               wl_egl_surface->last_deq_buffer = NULL;
        }
+       tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
+
        tsq_err = tbm_surface_queue_can_dequeue_wait_timeout(
                                wl_egl_surface->tbm_queue, CAN_DEQUEUE_TIMEOUT_MS);
        TPL_OBJECT_LOCK(surface);
@@ -2552,8 +2559,6 @@ __tpl_wl_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns,
        tpl_gmutex_lock(&wl_egl_buffer->mutex);
        wl_egl_buffer->status = DEQUEUED;
 
-       wl_egl_surface->last_deq_buffer = wl_egl_buffer;
-
        /* If wl_egl_buffer->release_fence_fd is -1,
         * the tbm_surface can be used immediately.
         * If not, user(EGL) have to wait until signaled. */
@@ -2614,9 +2619,6 @@ __tpl_wl_egl_surface_cancel_buffer(tpl_surface_t *surface,
                tpl_gmutex_unlock(&wl_egl_buffer->mutex);
        }
 
-       if (wl_egl_buffer == wl_egl_surface->last_deq_buffer)
-               wl_egl_surface->last_deq_buffer = NULL;
-
        tbm_surface_internal_unref(tbm_surface);
 
        tsq_err = tbm_surface_queue_cancel_dequeue(wl_egl_surface->tbm_queue,
@@ -2754,6 +2756,10 @@ __tpl_wl_egl_surface_enqueue_buffer(tpl_surface_t *surface,
                return TPL_ERROR_INVALID_OPERATION;
        }
 
+       tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
+       wl_egl_surface->last_enq_buffer = wl_egl_buffer;
+       tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
+
        tbm_surface_internal_unref(tbm_surface);
 
        TRACE_ASYNC_END((int)tbm_surface, "[DEQ]~[ENQ] BO_NAME:%d", bo_name);
@@ -3416,6 +3422,8 @@ _thread_wl_surface_commit(tpl_wl_egl_surface_t *wl_egl_surface,
 
        tpl_gmutex_unlock(&wl_egl_buffer->mutex);
 
+       wl_egl_surface->last_enq_buffer = NULL;
+
        TPL_LOG_T("WL_EGL",
                          "[COMMIT] wl_egl_buffer(%p) wl_buffer(%p) tbm_surface(%p) bo(%d)",
                          wl_egl_buffer, wl_egl_buffer->wl_buffer, wl_egl_buffer->tbm_surface,
@@ -3522,10 +3530,6 @@ __cb_wl_egl_buffer_free(tpl_wl_egl_buffer_t *wl_egl_buffer)
 
                wl_egl_buffer->idx = -1;
        }
-
-       if (wl_egl_surface->last_deq_buffer == wl_egl_buffer)
-               wl_egl_surface->last_deq_buffer = NULL;
-
        tpl_gmutex_unlock(&wl_egl_surface->buffers_mutex);
 
        if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) {