From 024fa5848480cd2dbb84c47e4b6bee0f5af1d00e Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Tue, 27 Oct 2020 16:56:33 +0900 Subject: [PATCH] e_hwc_windows: support TDM_HWC_COMMIT_INTERVAL_VBLANK if tdm_backend set TDM_HWC_COMMIT_INTERVAL_VBLANK, enlightenment call tdm_hwc_commit per vblank. Change-Id: I34e8689aab1f463797c6eb2b9ee733f17ebc8c11 --- src/bin/e_hwc.h | 2 +- src/bin/e_hwc_window.c | 12 ++-- src/bin/e_hwc_windows.c | 186 +++++++++++++++++++++++++++++++++++------------- src/bin/e_hwc_windows.h | 5 ++ 4 files changed, 148 insertions(+), 57 deletions(-) diff --git a/src/bin/e_hwc.h b/src/bin/e_hwc.h index 8e471bd..d085c07 100644 --- a/src/bin/e_hwc.h +++ b/src/bin/e_hwc.h @@ -61,6 +61,7 @@ typedef void (*E_Hwc_Sync_Done_Cb)(void *data, E_Hwc *hwc); #ifndef E_HWC_H #define E_HWC_H +#include #include "e_hwc_window.h" struct _E_Hwc_Intercept_Hook @@ -155,7 +156,6 @@ struct _E_Hwc Eina_Bool tdm_hwc_fence; int commit_fence_fd; - Ecore_Timer *commit_handler_timer; Eina_List *wins_commit_data_list; diff --git a/src/bin/e_hwc_window.c b/src/bin/e_hwc_window.c index a5c6a9e..e2984d0 100644 --- a/src/bin/e_hwc_window.c +++ b/src/bin/e_hwc_window.c @@ -1467,12 +1467,12 @@ e_hwc_window_commit_data_acquire(E_Hwc_Window *hwc_window) e_hwc_window_buffer_set(&commit_data->buffer, NULL, NULL); } - EHWTRACE("COM ts:%10p ------- {%25s}, state:%s, zpos:%d, deleted:%s", + EHWTRACE("COM data:%p ts:%p ------- {%25s}, state:%s, zpos:%d", hwc_window->ec, hwc_window->hwc, hwc_window, - commit_data->buffer.tsurface, + commit_data, commit_data->buffer.tsurface, e_hwc_window_name_get(hwc_window), e_hwc_window_state_string_get(hwc_window->state), - hwc_window->zpos, (hwc_window->is_deleted ? "yes" : "no")); + hwc_window->zpos); commit_data->hwc_window = hwc_window; e_object_ref(E_OBJECT(hwc_window)); @@ -1564,11 +1564,11 @@ e_hwc_window_commit_data_release(E_Hwc_Window *hwc_window, E_Hwc_Window_Commit_D tsurface = commit_data->buffer.tsurface; queue = commit_data->buffer.queue; - EHWTRACE("DON ts:%10p ------- {%25s}, state:%s, zpos:%d, deleted:%s (Window)", + EHWTRACE("DON data:%p ts:%p ------- {%25s}, state:%s, zpos:%d", hwc_window->ec, hwc_window->hwc, hwc_window, - tsurface, e_hwc_window_name_get(hwc_window), + commit_data, tsurface, e_hwc_window_name_get(hwc_window), e_hwc_window_state_string_get(hwc_window->state), - hwc_window->zpos, (hwc_window->is_deleted ? "yes" : "no")); + hwc_window->zpos); if (e_hwc_window_is_cursor(hwc_window)) { diff --git a/src/bin/e_hwc_windows.c b/src/bin/e_hwc_windows.c index 2e987d1..5ae94c9 100644 --- a/src/bin/e_hwc_windows.c +++ b/src/bin/e_hwc_windows.c @@ -77,7 +77,8 @@ static uint64_t ehws_comp_buffer_info_key; #define EHWS_BUFFER_COMP_INFO_KEY (unsigned long)(&ehws_comp_buffer_info_key) static Eina_Bool _e_hwc_windows_target_window_queue_set(E_Hwc_Window_Target *target_hwc_window); -static void _e_hwc_windows_wait_commit_set(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_commit_data, Eina_Bool set); +static void _e_hwc_windows_wait_commit_set(E_Hwc *hwc, Eina_Bool set); +static void _e_hwc_windows_commit_handler_timer_set(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_commit_data, Eina_Bool set); static E_Comp_Wl_Buffer * _e_hwc_windows_comp_wl_buffer_get(E_Hwc_Window *hwc_window) @@ -299,7 +300,11 @@ _e_hwc_windows_commit_data_release(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_c e_hwc_window_presentation_time_feedback_present(hwc_window, sequence, tv_sec, tv_usec); if (e_hwc_window_is_video(hwc_window) && hwc_window->ec) - e_client_video_commit_data_release(hwc_window->ec, sequence, tv_sec, tv_usec); + { + if ((!wins_commit_data->use_vblank_handler) || + (wins_commit_data->use_vblank_handler && !wins_commit_data->vblank_done)) + e_client_video_commit_data_release(hwc_window->ec, sequence, tv_sec, tv_usec); + } if (!e_hwc_window_commit_data_release(hwc_window, commit_data)) continue; } @@ -307,9 +312,67 @@ _e_hwc_windows_commit_data_release(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_c wins_commit_data->commit_data_list = eina_list_free(wins_commit_data->commit_data_list); hwc->wins_commit_data_list = eina_list_remove(hwc->wins_commit_data_list, wins_commit_data); + + _e_hwc_windows_commit_handler_timer_set(hwc, wins_commit_data, EINA_FALSE); free(wins_commit_data); } +static void +_e_hwc_windows_commit_handler(tdm_hwc *thwc, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data) +{ + E_Hwc_Windows_Commit_Data *wins_commit_data = (E_Hwc_Windows_Commit_Data *)user_data; + E_Hwc *hwc; + + EINA_SAFETY_ON_NULL_RETURN(wins_commit_data); + + hwc = wins_commit_data->hwc; + EINA_SAFETY_ON_NULL_RETURN(hwc); + + EHWSTRACE("!!!!!!!! HWC Commit Handler !!!!!!!!", NULL, hwc); + + /* 'wait_commit' is mechanism to make 'fetch and commit' no more than one time per a frame; + * a 'page flip' happened so it's time to allow to make 'fetch and commit' for the e_output */ + if (!wins_commit_data->use_vblank_handler) + _e_hwc_windows_wait_commit_set(hwc, EINA_FALSE); + + _e_hwc_windows_commit_data_release(hwc, wins_commit_data, sequence, tv_sec, tv_usec); +} + +static Eina_Bool +_e_hwc_windows_commit_handler_timeout(void *data) +{ + E_Hwc_Windows_Commit_Data *wins_commit_data = (E_Hwc_Windows_Commit_Data *)data; + + if (!wins_commit_data) return ECORE_CALLBACK_CANCEL; + + EHWSERR("Timeout wait commit", wins_commit_data->hwc); + + wins_commit_data->commit_handler_timer = NULL; + + _e_hwc_windows_commit_handler(wins_commit_data->hwc->thwc, 0, 0, 0, wins_commit_data); + + return ECORE_CALLBACK_CANCEL; +} + +static void +_e_hwc_windows_commit_handler_timer_set(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_commit_data, Eina_Bool set) +{ + if (!e_comp->commit_handler_timer.use) return; + + if (wins_commit_data->commit_handler_timer) + { + ecore_timer_del(wins_commit_data->commit_handler_timer); + wins_commit_data->commit_handler_timer = NULL; + } + + if (set) + wins_commit_data->commit_handler_timer = ecore_timer_add(e_comp->commit_handler_timer.interval, + _e_hwc_windows_commit_handler_timeout, + wins_commit_data); +} + static E_Hwc_Windows_Commit_Data * _e_hwc_windows_commit_data_acquire(E_Hwc *hwc) { @@ -355,28 +418,6 @@ _e_hwc_windows_commit_data_acquire(E_Hwc *hwc) } static void -_e_hwc_windows_commit_handler(tdm_hwc *thwc, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data) -{ - E_Hwc_Windows_Commit_Data *wins_commit_data = (E_Hwc_Windows_Commit_Data *)user_data; - E_Hwc *hwc; - - EINA_SAFETY_ON_NULL_RETURN(wins_commit_data); - - hwc = wins_commit_data->hwc; - EINA_SAFETY_ON_NULL_RETURN(hwc); - - EHWSTRACE("!!!!!!!! HWC Commit Handler !!!!!!!!", NULL, hwc); - - /* 'wait_commit' is mechanism to make 'fetch and commit' no more than one time per a frame; - * a 'page flip' happened so it's time to allow to make 'fetch and commit' for the e_output */ - _e_hwc_windows_wait_commit_set(hwc, wins_commit_data, EINA_FALSE); - - _e_hwc_windows_commit_data_release(hwc, wins_commit_data, sequence, tv_sec, tv_usec); -} - -static void _e_hwc_windows_offscreen_commit(E_Hwc *hwc) { E_Hwc_Window *hwc_window = NULL; @@ -1568,42 +1609,46 @@ _e_hwc_windows_pp_info_set(E_Hwc *hwc, tbm_surface_h src, tbm_surface_h dst, return EINA_TRUE; } -static Eina_Bool -_e_hwc_windows_commit_handler_timeout(void *data) +static void +_e_hwc_windows_vblank_handler(tdm_output *output, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data) { - E_Hwc_Windows_Commit_Data *wins_commit_data = (E_Hwc_Windows_Commit_Data *)data; + E_Hwc *hwc = (E_Hwc *)user_data; + E_Hwc_Windows_Commit_Data *wins_commit_data = NULL; + E_Hwc_Window_Commit_Data *commit_data; + Eina_List *l; - if (!wins_commit_data) return ECORE_CALLBACK_CANCEL; + EINA_SAFETY_ON_NULL_RETURN(hwc); - EHWSERR("Timeout wait commit", wins_commit_data->hwc); + EHWSTRACE("!!!!!!!! HWC Vblank Handler!!!!!!!!", NULL, hwc); - wins_commit_data->hwc->wait_commit = EINA_FALSE; - wins_commit_data->hwc->commit_handler_timer = NULL; + _e_hwc_windows_wait_commit_set(hwc, EINA_FALSE); - _e_hwc_windows_commit_handler(wins_commit_data->hwc->thwc, 0, 0, 0, wins_commit_data); + if (!eina_list_count(hwc->wins_commit_data_list)) return; - return ECORE_CALLBACK_CANCEL; -} + wins_commit_data = eina_list_last_data_get(hwc->wins_commit_data_list); + EINA_SAFETY_ON_NULL_RETURN(wins_commit_data); -static void -_e_hwc_windows_wait_commit_set(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_commit_data, Eina_Bool set) -{ - if (hwc->wait_commit == set) return; + if (!wins_commit_data->use_vblank_handler) return; - if (e_comp->commit_handler_timer.use) + EINA_LIST_FOREACH(wins_commit_data->commit_data_list, l, commit_data) { - if (hwc->commit_handler_timer) - { - ecore_timer_del(hwc->commit_handler_timer); - hwc->commit_handler_timer = NULL; - } + if (!commit_data) continue; + if (!commit_data->hwc_window) continue; - if (set) - hwc->commit_handler_timer = ecore_timer_add(e_comp->commit_handler_timer.interval, - _e_hwc_windows_commit_handler_timeout, - wins_commit_data); + if (e_hwc_window_is_video(commit_data->hwc_window) && commit_data->hwc_window->ec) + e_client_video_commit_data_release(commit_data->hwc_window->ec, sequence, tv_sec, tv_usec); } + wins_commit_data->vblank_done = EINA_TRUE; +} + +static void +_e_hwc_windows_wait_commit_set(E_Hwc *hwc, Eina_Bool set) +{ + if (hwc->wait_commit == set) return; + hwc->wait_commit = set; } @@ -3079,6 +3124,44 @@ _e_hwc_windows_sync_callback_call(E_Hwc *hwc) e_hwc_sync_callback_call(sync_callback); } +static tdm_hwc_commit_interval +_e_hwc_windows_commit_interval_get(E_Hwc *hwc) +{ + tdm_error terror; + tdm_hwc_commit_interval interval = TDM_HWC_COMMIT_INTERVAL_NONE; + + terror = tdm_hwc_get_commit_interval(hwc->thwc, &interval); + if (terror != TDM_ERROR_NONE) + return TDM_HWC_COMMIT_INTERVAL_NONE; + + return interval; +} + +static void +_e_hwc_windows_commit_interval_update(E_Hwc *hwc, E_Hwc_Windows_Commit_Data *wins_commit_data) +{ + tdm_hwc_commit_interval interval = TDM_HWC_COMMIT_INTERVAL_NONE; + tdm_error terror = TDM_ERROR_NONE; + + if (!hwc->wait_commit) return; + + interval = _e_hwc_windows_commit_interval_get(hwc); + if (interval == TDM_HWC_COMMIT_INTERVAL_VBLANK) + { + terror = tdm_output_wait_vblank(hwc->output->toutput, 1, 0, _e_hwc_windows_vblank_handler, + (void *)hwc); + if (terror != TDM_ERROR_NONE) + { + EHWSERR("fail to tdm_output_wait_vblank", hwc); + return; + } + + wins_commit_data->use_vblank_handler = EINA_TRUE; + + EHWSTRACE("!!!!!!!! HWC Vblank !!!!!!!!", NULL, hwc); + } +} + EINTERN Eina_Bool e_hwc_windows_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode) { @@ -3138,8 +3221,9 @@ e_hwc_windows_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode) EHWSTRACE("!!!!!!!! HWC Commit !!!!!!!!", NULL, hwc); _e_hwc_windows_update_fps(hwc); - _e_hwc_windows_wait_commit_set(hwc, wins_commit_data, EINA_TRUE); + _e_hwc_windows_wait_commit_set(hwc, EINA_TRUE); + _e_hwc_windows_commit_handler_timer_set(hwc, wins_commit_data, EINA_TRUE); hwc->wins_commit_data_list = eina_list_append(hwc->wins_commit_data_list, wins_commit_data); error = tdm_hwc_commit(hwc->thwc, 0, _e_hwc_windows_commit_handler, wins_commit_data); @@ -3150,6 +3234,8 @@ e_hwc_windows_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode) goto fail; } + _e_hwc_windows_commit_interval_update(hwc, wins_commit_data); + if (e_hwc_windows_fence_enabled_get(hwc)) { error = tdm_hwc_get_commit_fence(hwc->thwc, &commit_fence_fd); @@ -3180,7 +3266,7 @@ re_evaluate: fail: /* send tizen_hwc_commit feedback discarded */ e_comp_wl_tizen_hwc_discarded(); - _e_hwc_windows_wait_commit_set(hwc, wins_commit_data, EINA_FALSE); + _e_hwc_windows_wait_commit_set(hwc, EINA_FALSE); return EINA_FALSE; } diff --git a/src/bin/e_hwc_windows.h b/src/bin/e_hwc_windows.h index 59cad79..dd546b9 100644 --- a/src/bin/e_hwc_windows.h +++ b/src/bin/e_hwc_windows.h @@ -24,6 +24,11 @@ struct _E_Hwc_Windows_Commit_Data { E_Hwc_Window_Commit_Data *target_commit_data; Eina_List *commit_data_list; E_Hwc *hwc; + + Ecore_Timer *commit_handler_timer; + + Eina_Bool use_vblank_handler; + Eina_Bool vblank_done; }; EINTERN Eina_Bool e_hwc_windows_init(void); -- 2.7.4