Add tpl_surface_vblank_t to manage vblank object 47/258547/1
authorJoonbum Ko <joonbum.ko@samsung.com>
Mon, 17 May 2021 05:37:14 +0000 (14:37 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Thu, 20 May 2021 05:36:55 +0000 (14:36 +0900)
Change-Id: I56b54ccf7c22c9ef03c6973483ba1c0cb52b959d
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/tpl_wl_egl_thread.c

index 7913614..7463197 100755 (executable)
@@ -37,6 +37,7 @@ static int wl_egl_buffer_key;
 typedef struct _tpl_wl_egl_display tpl_wl_egl_display_t;
 typedef struct _tpl_wl_egl_surface tpl_wl_egl_surface_t;
 typedef struct _tpl_wl_egl_buffer  tpl_wl_egl_buffer_t;
+typedef struct _surface_vblank     tpl_surface_vblank_t;
 
 struct _tpl_wl_egl_display {
        tpl_gsource                  *disp_source;
@@ -48,17 +49,19 @@ struct _tpl_wl_egl_display {
        struct wayland_tbm_client    *wl_tbm_client;
        int                           last_error; /* errno of the last wl_display error*/
 
-       tpl_bool_t                   wl_initialized;
-       tpl_bool_t                   tdm_initialized;
-
-       tdm_client                   *tdm_client;
-       tpl_gsource                  *tdm_source;
-       int                           tdm_display_fd;
+       tpl_bool_t                    wl_initialized;
 
        tpl_bool_t                    use_wait_vblank;
        tpl_bool_t                    use_explicit_sync;
        tpl_bool_t                    prepared;
 
+       struct {
+               tdm_client               *tdm_client;
+               tpl_gsource              *tdm_source;
+               int                       tdm_display_fd;
+               tpl_bool_t                tdm_initialized;
+       } tdm;
+
        struct tizen_surface_shm     *tss; /* used for surface buffer_flush */
        struct wp_presentation       *presentation; /* for presentation feedback */
        struct zwp_linux_explicit_synchronization_v1 *explicit_sync; /* for explicit fence sync */
@@ -74,7 +77,7 @@ struct _tpl_wl_egl_surface {
        struct zwp_linux_surface_synchronization_v1 *surface_sync; /* for explicit fence sync */
        struct tizen_surface_shm_flusher *tss_flusher; /* used for surface buffer_flush */
 
-       tdm_client_vblank            *vblank;
+       tpl_surface_vblank_t         *vblank;
 
        /* surface information */
        int                           render_done_cnt;
@@ -95,7 +98,6 @@ struct _tpl_wl_egl_surface {
        int                           buffer_cnt; /* the number of using wl_egl_buffers */
        tpl_gmutex                    buffers_mutex;
 
-       tpl_list_t                   *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */
        tpl_list_t                   *presentation_feedbacks; /* for tracing presentation feedbacks */
 
        struct {
@@ -121,6 +123,12 @@ struct _tpl_wl_egl_surface {
        tpl_bool_t                    set_serial_is_used;
 };
 
+struct _surface_vblank {
+       tdm_client_vblank            *tdm_vblank;
+       tpl_wl_egl_surface_t         *wl_egl_surface;
+       tpl_list_t                   *waiting_buffers; /* for FIFO/FIFO_RELAXED modes */
+};
+
 typedef enum buffer_status {
        RELEASED = 0,             // 0
        DEQUEUED,                 // 1
@@ -269,7 +277,7 @@ __thread_func_tdm_dispatch(tpl_gsource *gsource, uint64_t message)
                return TPL_FALSE;
        }
 
-       tdm_err = tdm_client_handle_events(wl_egl_display->tdm_client);
+       tdm_err = tdm_client_handle_events(wl_egl_display->tdm.tdm_client);
 
        /* If an error occurs in tdm_client_handle_events, it cannot be recovered.
         * When tdm_source is no longer available due to an unexpected situation,
@@ -283,7 +291,7 @@ __thread_func_tdm_dispatch(tpl_gsource *gsource, uint64_t message)
 
                tpl_gsource_destroy(gsource, TPL_FALSE);
 
-               wl_egl_display->tdm_source = NULL;
+               wl_egl_display->tdm.tdm_source = NULL;
 
                return TPL_FALSE;
        }
@@ -300,15 +308,16 @@ __thread_func_tdm_finalize(tpl_gsource *gsource)
 
        TPL_LOG_T("WL_EGL",
                          "tdm_destroy| wl_egl_display(%p) tdm_client(%p) tpl_gsource(%p)",
-                         wl_egl_display, wl_egl_display->tdm_client, gsource);
+                         wl_egl_display, wl_egl_display->tdm.tdm_client, gsource);
 
-       if (wl_egl_display->tdm_client) {
-               tdm_client_destroy(wl_egl_display->tdm_client);
-               wl_egl_display->tdm_client = NULL;
-               wl_egl_display->tdm_display_fd = -1;
+       if (wl_egl_display->tdm.tdm_client) {
+               tdm_client_destroy(wl_egl_display->tdm.tdm_client);
+               wl_egl_display->tdm.tdm_client = NULL;
+               wl_egl_display->tdm.tdm_display_fd = -1;
+               wl_egl_display->tdm.tdm_source = NULL;
        }
 
-       wl_egl_display->tdm_initialized = TPL_FALSE;
+       wl_egl_display->tdm.tdm_initialized = TPL_FALSE;
 }
 
 static tpl_gsource_functions tdm_funcs = {
@@ -338,10 +347,10 @@ _thread_tdm_init(tpl_wl_egl_display_t *wl_egl_display)
                return TPL_ERROR_INVALID_OPERATION;
        }
 
-       wl_egl_display->tdm_display_fd  = tdm_display_fd;
-       wl_egl_display->tdm_client      = tdm_client;
-       wl_egl_display->tdm_source      = NULL;
-       wl_egl_display->tdm_initialized = TPL_TRUE;
+       wl_egl_display->tdm.tdm_display_fd  = tdm_display_fd;
+       wl_egl_display->tdm.tdm_client      = tdm_client;
+       wl_egl_display->tdm.tdm_source      = NULL;
+       wl_egl_display->tdm.tdm_initialized = TPL_TRUE;
 
        TPL_INFO("[TDM_CLIENT_INIT]",
                         "wl_egl_display(%p) tdm_client(%p) tdm_display_fd(%d)",
@@ -617,7 +626,8 @@ _thread_init(void *data)
                                wl_egl_display, wl_egl_display->wl_display);
        }
 
-       if (_thread_tdm_init(wl_egl_display) != TPL_ERROR_NONE) {
+       if (wl_egl_display->use_wait_vblank &&
+               _thread_tdm_init(wl_egl_display) != TPL_ERROR_NONE) {
                TPL_WARN("Failed to initialize tdm-client. TPL_WAIT_VLANK:DISABLED");
        }
 
@@ -770,7 +780,11 @@ __tpl_wl_egl_display_init(tpl_display_t *display)
        display->backend.data             = wl_egl_display;
        display->bufmgr_fd                = -1;
 
-       wl_egl_display->tdm_initialized   = TPL_FALSE;
+       wl_egl_display->tdm.tdm_initialized   = TPL_FALSE;
+       wl_egl_display->tdm.tdm_client        = NULL;
+       wl_egl_display->tdm.tdm_display_fd    = -1;
+       wl_egl_display->tdm.tdm_source        = NULL;
+
        wl_egl_display->wl_initialized    = TPL_FALSE;
 
        wl_egl_display->ev_queue          = NULL;
@@ -815,15 +829,21 @@ __tpl_wl_egl_display_init(tpl_display_t *display)
                goto free_display;
        }
 
-       wl_egl_display->tdm_source = tpl_gsource_create(wl_egl_display->thread,
-                                                                                                       (void *)wl_egl_display,
-                                                                                                       wl_egl_display->tdm_display_fd,
-                                                                                                       &tdm_funcs, SOURCE_TYPE_NORMAL);
-       if (!wl_egl_display->tdm_source) {
-               TPL_ERR("Failed to create tdm_gsource\n");
-               goto free_display;
+       if (wl_egl_display->use_wait_vblank &&
+               wl_egl_display->tdm.tdm_initialized) {
+               wl_egl_display->tdm.tdm_source = tpl_gsource_create(wl_egl_display->thread,
+                                                                                                               (void *)wl_egl_display,
+                                                                                                               wl_egl_display->tdm.tdm_display_fd,
+                                                                                                               &tdm_funcs, SOURCE_TYPE_NORMAL);
+               if (!wl_egl_display->tdm.tdm_source) {
+                       TPL_ERR("Failed to create tdm_gsource\n");
+                       goto free_display;
+               }
        }
 
+       wl_egl_display->use_wait_vblank = (wl_egl_display->tdm.tdm_initialized &&
+                                                                          (wl_egl_display->tdm.tdm_source != NULL));
+
        TPL_INFO("[DISPLAY_INIT]",
                         "wl_egl_display(%p) tpl_gthread(%p) wl_display(%p)",
                         wl_egl_display,
@@ -840,8 +860,8 @@ __tpl_wl_egl_display_init(tpl_display_t *display)
 
 free_display:
        if (wl_egl_display->thread) {
-               if (wl_egl_display->tdm_source)
-                       tpl_gsource_destroy(wl_egl_display->tdm_source, TPL_TRUE);
+               if (wl_egl_display->tdm.tdm_source)
+                       tpl_gsource_destroy(wl_egl_display->tdm.tdm_source, TPL_TRUE);
                if (wl_egl_display->disp_source)
                        tpl_gsource_destroy(wl_egl_display->disp_source, TPL_TRUE);
 
@@ -870,9 +890,9 @@ __tpl_wl_egl_display_fini(tpl_display_t *display)
                                  wl_egl_display->thread,
                                  wl_egl_display->wl_display);
 
-               if (wl_egl_display->tdm_source && wl_egl_display->tdm_initialized) {
-                       tpl_gsource_destroy(wl_egl_display->tdm_source, TPL_TRUE);
-                       wl_egl_display->tdm_source = NULL;
+               if (wl_egl_display->tdm.tdm_source && wl_egl_display->tdm.tdm_initialized) {
+                       tpl_gsource_destroy(wl_egl_display->tdm.tdm_source, TPL_TRUE);
+                       wl_egl_display->tdm.tdm_source = NULL;
                }
 
                if (wl_egl_display->disp_source) {
@@ -1431,9 +1451,9 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface)
                wl_egl_surface->presentation_sync.fd = -1;
        }
 
-       if (wl_egl_surface->vblank_waiting_buffers) {
-               __tpl_list_free(wl_egl_surface->vblank_waiting_buffers, NULL);
-               wl_egl_surface->vblank_waiting_buffers = NULL;
+       if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) {
+               __tpl_list_free(wl_egl_surface->vblank->waiting_buffers, NULL);
+               wl_egl_surface->vblank->waiting_buffers = NULL;
        }
 
        tpl_gmutex_unlock(&wl_egl_surface->presentation_sync.mutex);
@@ -1455,10 +1475,16 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface)
        }
 
        if (wl_egl_surface->vblank) {
+               tpl_surface_vblank_t *vblank = wl_egl_surface->vblank;
                TPL_INFO("[VBLANK_DESTROY]",
-                                "wl_egl_surface(%p) vblank(%p)",
-                                wl_egl_surface, wl_egl_surface->vblank);
-               tdm_client_vblank_destroy(wl_egl_surface->vblank);
+                                "wl_egl_surface(%p) surface_vblank(%p) tdm_vblank(%p)",
+                                wl_egl_surface, vblank,
+                                vblank->tdm_vblank);
+               tdm_client_vblank_destroy(vblank->tdm_vblank);
+               vblank->tdm_vblank = NULL;
+               vblank->wl_egl_surface = NULL;
+               free(vblank);
+
                wl_egl_surface->vblank = NULL;
        }
 
@@ -1738,7 +1764,7 @@ _thread_create_tbm_queue(tpl_wl_egl_surface_t *wl_egl_surface,
 static tdm_client_vblank*
 _thread_create_tdm_client_vblank(tdm_client *tdm_client)
 {
-       tdm_client_vblank *vblank = NULL;
+       tdm_client_vblank *tdm_vblank = NULL;
        tdm_client_output *tdm_output = NULL;
        tdm_error tdm_err = TDM_ERROR_NONE;
 
@@ -1753,22 +1779,23 @@ _thread_create_tdm_client_vblank(tdm_client *tdm_client)
                return NULL;
        }
 
-       vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err);
-       if (!vblank || tdm_err != TDM_ERROR_NONE) {
-               TPL_ERR("Failed to create vblank. tdm_err(%d)", tdm_err);
+       tdm_vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err);
+       if (!tdm_vblank || tdm_err != TDM_ERROR_NONE) {
+               TPL_ERR("Failed to create tdm_vblank. tdm_err(%d)", tdm_err);
                return NULL;
        }
 
-       tdm_client_vblank_set_enable_fake(vblank, 1);
-       tdm_client_vblank_set_sync(vblank, 0);
+       tdm_client_vblank_set_enable_fake(tdm_vblank, 1);
+       tdm_client_vblank_set_sync(tdm_vblank, 0);
 
-       return vblank;
+       return tdm_vblank;
 }
 
 static void
 _thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface)
 {
        tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display;
+       tpl_surface_vblank_t *vblank         = NULL;
 
        wl_egl_surface->tbm_queue = _thread_create_tbm_queue(
                                                                        wl_egl_surface,
@@ -1792,15 +1819,30 @@ _thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface)
                         CLIENT_QUEUE_SIZE,
                         wl_egl_surface->format);
 
-       wl_egl_surface->vblank = _thread_create_tdm_client_vblank(
-                                                               wl_egl_display->tdm_client);
-       if (wl_egl_surface->vblank) {
-               TPL_INFO("[VBLANK_INIT]",
-                                "wl_egl_surface(%p) tdm_client(%p) vblank(%p)",
-                                wl_egl_surface, wl_egl_display->tdm_client,
-                                wl_egl_surface->vblank);
+       if (wl_egl_display->use_wait_vblank) {
+               vblank = (tpl_surface_vblank_t *)calloc(1, sizeof(tpl_surface_vblank_t));
+               if (vblank) {
+                       vblank->tdm_vblank = _thread_create_tdm_client_vblank(
+                                                                       wl_egl_display->tdm.tdm_client);
+                       if (!vblank->tdm_vblank) {
+                               TPL_ERR("Failed to create tdm_vblank from tdm_client(%p)",
+                                               wl_egl_display->tdm.tdm_client);
+                               free(vblank);
+                               vblank = NULL;
+                       } else {
+                               vblank->waiting_buffers = __tpl_list_alloc();
+                               vblank->wl_egl_surface = wl_egl_surface;
+
+                               TPL_INFO("[VBLANK_INIT]",
+                                                "wl_egl_surface(%p) tdm_client(%p) tdm_vblank(%p)",
+                                                wl_egl_surface, wl_egl_display->tdm.tdm_client,
+                                                vblank->tdm_vblank);
+                       }
+               }
        }
 
+       wl_egl_surface->vblank = vblank;
+
        if (wl_egl_display->tss) {
                wl_egl_surface->tss_flusher =
                        tizen_surface_shm_get_flusher(wl_egl_display->tss,
@@ -1831,7 +1873,6 @@ _thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface)
                }
        }
 
-       wl_egl_surface->vblank_waiting_buffers = __tpl_list_alloc();
        wl_egl_surface->presentation_feedbacks = __tpl_list_alloc();
 }
 
@@ -2572,7 +2613,6 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message)
        tpl_wl_egl_buffer_t *wl_egl_buffer      =
                (tpl_wl_egl_buffer_t *)tpl_gsource_get_data(gsource);
        tpl_wl_egl_surface_t *wl_egl_surface    = wl_egl_buffer->wl_egl_surface;
-       tpl_wl_egl_display_t *wl_egl_display    = wl_egl_surface->wl_egl_display;
        tbm_surface_h tbm_surface               = wl_egl_buffer->tbm_surface;
 
        wl_egl_surface->render_done_cnt++;
@@ -2590,10 +2630,10 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message)
 
        tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
 
-       if (!wl_egl_display->use_wait_vblank || wl_egl_surface->vblank_done)
+       if (wl_egl_surface->vblank == NULL || wl_egl_surface->vblank_done)
                _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
        else
-               __tpl_list_push_back(wl_egl_surface->vblank_waiting_buffers,
+               __tpl_list_push_back(wl_egl_surface->vblank->waiting_buffers,
                                                         wl_egl_buffer);
 
        tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
@@ -2696,11 +2736,11 @@ _thread_surface_queue_acquire(tpl_wl_egl_surface_t *wl_egl_surface)
                }
 
                if (ready_to_commit) {
-                       if (!wl_egl_display->use_wait_vblank || wl_egl_surface->vblank_done)
+                       if (wl_egl_surface->vblank == NULL || wl_egl_surface->vblank_done)
                                ready_to_commit = TPL_TRUE;
                        else {
                                wl_egl_buffer->status = WAITING_VBLANK;
-                               __tpl_list_push_back(wl_egl_surface->vblank_waiting_buffers, wl_egl_buffer);
+                               __tpl_list_push_back(wl_egl_surface->vblank->waiting_buffers, wl_egl_buffer);
                                ready_to_commit = TPL_FALSE;
                        }
                }
@@ -2734,7 +2774,7 @@ __cb_tdm_client_vblank(tdm_client_vblank *vblank, tdm_error error,
 
        tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
        wl_egl_buffer = (tpl_wl_egl_buffer_t *)__tpl_list_pop_front(
-                                               wl_egl_surface->vblank_waiting_buffers,
+                                               wl_egl_surface->vblank->waiting_buffers,
                                                NULL);
        if (wl_egl_buffer)
                _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
@@ -3012,19 +3052,9 @@ static tpl_result_t
 _thread_surface_vblank_wait(tpl_wl_egl_surface_t *wl_egl_surface)
 {
        tdm_error tdm_err                       = TDM_ERROR_NONE;
-       tpl_wl_egl_display_t *wl_egl_display    = wl_egl_surface->wl_egl_display;
+       tpl_surface_vblank_t *vblank            = wl_egl_surface->vblank;
 
-       if (wl_egl_surface->vblank == NULL) {
-               wl_egl_surface->vblank =
-                       _thread_create_tdm_client_vblank(wl_egl_display->tdm_client);
-               if (!wl_egl_surface->vblank) {
-                       TPL_WARN("Failed to create vblank. wl_egl_surface(%p)",
-                                        wl_egl_surface);
-                       return TPL_ERROR_OUT_OF_MEMORY;
-               }
-       }
-
-       tdm_err = tdm_client_vblank_wait(wl_egl_surface->vblank,
+       tdm_err = tdm_client_vblank_wait(vblank->tdm_vblank,
                        wl_egl_surface->post_interval,
                        __cb_tdm_client_vblank,
                        (void *)wl_egl_surface);
@@ -3198,7 +3228,7 @@ _thread_wl_surface_commit(tpl_wl_egl_surface_t *wl_egl_surface,
                          wl_egl_buffer, wl_egl_buffer->wl_buffer, wl_egl_buffer->tbm_surface,
                          wl_egl_buffer->bo_name);
 
-       if (wl_egl_display->use_wait_vblank &&
+       if (wl_egl_surface->vblank != NULL &&
                _thread_surface_vblank_wait(wl_egl_surface) != TPL_ERROR_NONE)
                TPL_ERR("Failed to set wait vblank.");