e_hwc_windows: support TDM_HWC_COMMIT_INTERVAL_VBLANK 36/246036/5
authorChangyeon Lee <cyeon.lee@samsung.com>
Tue, 27 Oct 2020 07:56:33 +0000 (16:56 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Tue, 27 Oct 2020 11:39:00 +0000 (20:39 +0900)
if tdm_backend set TDM_HWC_COMMIT_INTERVAL_VBLANK, enlightenment call
tdm_hwc_commit per vblank.

Change-Id: I34e8689aab1f463797c6eb2b9ee733f17ebc8c11

src/bin/e_hwc.h
src/bin/e_hwc_window.c
src/bin/e_hwc_windows.c
src/bin/e_hwc_windows.h

index 8e471bd..d085c07 100644 (file)
@@ -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 <tdm.h>
 #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;
 
index a5c6a9e..e2984d0 100644 (file)
@@ -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))
      {
index 2e987d1..5ae94c9 100644 (file)
@@ -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;
 }
index 59cad79..dd546b9 100644 (file)
@@ -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);