From db90e71f23b23d30bbea125d2789ae7dde7c083b Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Mon, 17 May 2021 14:37:14 +0900 Subject: [PATCH] Add tpl_surface_vblank_t to manage vblank object Change-Id: I56b54ccf7c22c9ef03c6973483ba1c0cb52b959d Signed-off-by: Joonbum Ko --- src/tpl_wl_egl_thread.c | 178 +++++++++++++++++++++++----------------- 1 file changed, 104 insertions(+), 74 deletions(-) diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index 7913614..7463197 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -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."); -- 2.34.1