From: TaeHyeon Jeong Date: Tue, 22 Oct 2024 06:39:04 +0000 (+0900) Subject: wl_egl: Implement status_sync to improve buffers finalize logic. X-Git-Tag: accepted/tizen/unified/20241106.141121~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=40dfebc4ebb5f50e79803a593154ae91e35ef1de;p=platform%2Fcore%2Fuifw%2Flibtpl-egl.git wl_egl: Implement status_sync to improve buffers finalize logic. AS-IS - When wl_egl_display->thread is idle, call the __idle_cb_buffers_finalize() to check the buffer status and change the buffer status to RELEASED. - If the buffer status cannot be changed to RELEASED, continue to call the function until possible. PROBLEMS - Call the function even if the buffer status has not changed. So the function is unnecessarily called a lot. TO-BE - Call the function only when the buffer status changes. Change-Id: I76d401a1413d144dcde2e4743162d9a09bc86983 --- diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index b4886ff..3eb76f4 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -46,6 +46,8 @@ typedef struct _surface_vblank tpl_surface_vblank_t; #define wl_egl_buffer(ptr) *wl_egl_buffer = (tpl_wl_egl_buffer_t *)ptr; #define tizen_private(ptr) *tizen_private = (struct tizen_private *)ptr; +#define rightmost_zero(x) (~(x) & ((x) + 1)) + struct _tpl_wl_egl_display { tpl_gsource *disp_source; tpl_gthread *thread; @@ -92,6 +94,7 @@ typedef enum surf_message { ACQUIRABLE = 2, FORCE_FLUSH = 4, QUEUE_RESIZE = 8, + BUFFERS_FINALIZE = 16, } surf_message; struct _tpl_wl_egl_surface { @@ -128,6 +131,7 @@ struct _tpl_wl_egl_surface { tpl_list_t *buffers; int buffer_cnt; /* the number of using wl_egl_buffers */ tpl_gmutex_rec buffers_mutex; + int in_use; tpl_list_t *presentation_feedbacks; /* for tracing presentation feedbacks */ @@ -141,12 +145,19 @@ struct _tpl_wl_egl_surface { int fd; } presentation_sync; + struct { + tpl_gmutex mutex; + tpl_gcond cond; + int condition; /* store status of buffers in each bit */ + } status_sync; + tpl_gmutex surf_mutex; tpl_gcond surf_cond; surf_message sent_message; tpl_bool_t is_activated; + tpl_bool_t is_finalized; tpl_bool_t reset; /* TRUE if queue reseted by external */ tpl_bool_t need_to_enqueue; tpl_bool_t prerotation_capability; @@ -236,6 +247,9 @@ struct _tpl_wl_egl_buffer { buffer_status status; /* for tracing buffer status */ double changed_time; /* the time when buffer status changed */ + /* creation order between same tpl_wl_egl_surface */ + int order; + /* for damage region */ int num_rects; int *rects; @@ -387,11 +401,17 @@ static void _update_buffer_status(tpl_wl_egl_buffer_t *wl_egl_buffer, buffer_status status) { double current_time = _get_current_time(); + tpl_wl_egl_surface_t wl_egl_surface(wl_egl_buffer->wl_egl_surface); + int *condition = &wl_egl_surface->status_sync.condition; + tpl_bool_t is_removable = TPL_FALSE; + tpl_gmutex_lock(&wl_egl_surface->status_sync.mutex); switch (status) { case CREATED: + case CANCELED: case RELEASED: + is_removable = TPL_TRUE; case DEQUEUED: /* do nothing */ break; @@ -401,8 +421,15 @@ _update_buffer_status(tpl_wl_egl_buffer_t *wl_egl_buffer, buffer_status status) break; } + if (is_removable) + *condition &= ~wl_egl_buffer->order; + else + *condition |= wl_egl_buffer->order; + wl_egl_buffer->status = status; wl_egl_buffer->changed_time = current_time; + + tpl_gmutex_unlock(&wl_egl_surface->status_sync.mutex); } static void @@ -1941,7 +1968,9 @@ __tpl_wl_egl_surface_init(tpl_surface_t *surface) wl_egl_surface->reset = TPL_FALSE; wl_egl_surface->is_activated = TPL_FALSE; + wl_egl_surface->is_finalized = TPL_FALSE; wl_egl_surface->need_to_enqueue = TPL_TRUE; + wl_egl_surface->need_force_release = TPL_FALSE; wl_egl_surface->prerotation_capability = TPL_FALSE; wl_egl_surface->vblank_done = TPL_TRUE; wl_egl_surface->serial_updated = TPL_FALSE; @@ -1966,10 +1995,12 @@ __tpl_wl_egl_surface_init(tpl_surface_t *surface) wl_egl_surface->commit_sync.fd = -1; wl_egl_surface->presentation_sync.fd = -1; + wl_egl_surface->status_sync.condition = 0; wl_egl_surface->sent_message = NONE_MESSAGE; wl_egl_surface->buffers = __tpl_list_alloc(); + wl_egl_surface->in_use = 0; { struct tizen_private *tizen_private = wl_egl_tizen_get_tizen_private(wl_egl_window); @@ -2002,6 +2033,9 @@ __tpl_wl_egl_surface_init(tpl_surface_t *surface) tpl_gmutex_init(&wl_egl_surface->commit_sync.mutex); tpl_gmutex_init(&wl_egl_surface->presentation_sync.mutex); + tpl_gmutex_init(&wl_egl_surface->status_sync.mutex); + tpl_gcond_init(&wl_egl_surface->status_sync.cond); + tpl_gmutex_rec_init(&wl_egl_surface->buffers_mutex); tpl_gmutex_init(&wl_egl_surface->surf_mutex); @@ -2544,6 +2578,9 @@ __tpl_wl_egl_surface_fini(tpl_surface_t *surface) tpl_gmutex_clear(&wl_egl_surface->presentation_sync.mutex); tpl_gmutex_clear(&wl_egl_surface->perf_trace.mutex); + tpl_gcond_clear(&wl_egl_surface->status_sync.cond); + tpl_gmutex_clear(&wl_egl_surface->status_sync.mutex); + tpl_gcond_clear(&wl_egl_surface->surf_cond); tpl_gmutex_clear(&wl_egl_surface->surf_mutex); @@ -2763,8 +2800,6 @@ _wl_egl_buffer_create(tpl_wl_egl_surface_t *wl_egl_surface, wl_egl_buffer->bo_name = _get_tbm_surface_bo_name(tbm_surface); wl_egl_buffer->wl_egl_surface = wl_egl_surface; - _update_buffer_status(wl_egl_buffer, CREATED); - wl_egl_buffer->acquire_fence_fd = -1; wl_egl_buffer->commit_sync_fd = -1; wl_egl_buffer->presentation_sync_fd = -1; @@ -2780,9 +2815,13 @@ _wl_egl_buffer_create(tpl_wl_egl_surface_t *wl_egl_surface, tpl_gmutex_init(&wl_egl_buffer->mutex); tpl_gmutex_rec_lock(&wl_egl_surface->buffers_mutex); + wl_egl_buffer->order = rightmost_zero(wl_egl_surface->in_use); + wl_egl_surface->in_use |= wl_egl_buffer->order; __tpl_list_push_back(wl_egl_surface->buffers, (void *)wl_egl_buffer); tpl_gmutex_rec_unlock(&wl_egl_surface->buffers_mutex); + _update_buffer_status(wl_egl_buffer, CREATED); + TPL_INFO("[WL_EGL_BUFFER_CREATE]", "wl_egl_surface(%p) wl_egl_buffer(%p) tbm_surface(%p) bo(%d)", wl_egl_surface, wl_egl_buffer, tbm_surface, @@ -4034,6 +4073,7 @@ __cb_wl_egl_buffer_free(tpl_wl_egl_buffer_t *wl_egl_buffer) wl_egl_buffer->tbm_surface, wl_egl_buffer->bo_name); tpl_gmutex_rec_lock(&wl_egl_surface->buffers_mutex); + wl_egl_surface->in_use &= ~wl_egl_buffer->order; if (wl_egl_surface->buffers) { __tpl_list_remove_data(wl_egl_surface->buffers, (void *)wl_egl_buffer, TPL_FIRST, NULL);