e_hwc_windows: add e_hwc_sync_callback_add/del 53/244753/6
authorChangyeon Lee <cyeon.lee@samsung.com>
Wed, 23 Sep 2020 11:18:54 +0000 (20:18 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Thu, 24 Sep 2020 08:33:44 +0000 (17:33 +0900)
Change-Id: Id04883574406ddc642b2e068479202ffccbb5958

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

index 2e25e178e232175c811c519e99a6e5613555d95a..b84501cf309da8665762119b0ad265ec1b5ad365 100644 (file)
@@ -439,6 +439,8 @@ fail:
 EINTERN void
 e_hwc_del(E_Hwc *hwc)
 {
+   E_Hwc_Sync_Callback *sync_callback;
+
    if (!hwc) return;
 
    if (e_hwc_policy_get(hwc) == E_HWC_POLICY_WINDOWS)
@@ -449,6 +451,9 @@ e_hwc_del(E_Hwc *hwc)
 
    e_comp_wl_buffer_reference(&hwc->pp_buffer_ref, NULL);
 
+   EINA_LIST_FREE(hwc->sync_callback_list, sync_callback)
+     sync_callback->hwc = NULL;
+
    _e_hwc_ee_deinit(hwc);
 
    if (hwc->commit_fence_fd >= 0)
@@ -841,3 +846,54 @@ e_client_hwc_visible_skip_set(E_Client *ec, Eina_Bool skip)
 
    return EINA_TRUE;
 }
+
+E_API E_Hwc_Sync_Callback *
+e_hwc_sync_callback_add(E_Hwc *hwc, E_Hwc_Sync_Done_Cb cb, void *data)
+{
+   E_Hwc_Sync_Callback *sync_callback;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(hwc->hwc_policy == E_HWC_POLICY_WINDOWS, NULL);
+
+   sync_callback = E_NEW(E_Hwc_Sync_Callback, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(sync_callback, NULL);
+
+   sync_callback->hwc = hwc;
+   sync_callback->cb = cb;
+   sync_callback->data = data;
+
+   hwc->sync_callback_list = eina_list_append(hwc->sync_callback_list, sync_callback);
+
+   return sync_callback;
+}
+
+E_API void
+e_hwc_sync_callback_del(E_Hwc_Sync_Callback *sync_callback)
+{
+   EINA_SAFETY_ON_NULL_RETURN(sync_callback);
+
+   if (sync_callback->hwc)
+     {
+        sync_callback->hwc->sync_callback_list =
+           eina_list_remove(sync_callback->hwc->sync_callback_list, sync_callback);
+     }
+
+   E_FREE(sync_callback);
+}
+
+EINTERN Eina_Bool
+e_hwc_sync_callback_call(E_Hwc_Sync_Callback *sync_callback)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(sync_callback, EINA_FALSE);
+
+   if (sync_callback->done) return EINA_TRUE;
+
+   sync_callback->done = EINA_TRUE;
+
+   if (!sync_callback->cb) return EINA_TRUE;
+
+   /* it is possible callback is freed in callback */
+   sync_callback->cb(sync_callback->data, sync_callback->hwc);
+
+   return EINA_TRUE;
+}
index 7890bbf6d8902c4d2e3c42cb0cbd4102e29c975a..8e471bdd68cc31c5fb69aea45b233b91805d601f 100644 (file)
@@ -1,6 +1,7 @@
 #ifdef E_TYPEDEFS
 
 typedef struct _E_Hwc     E_Hwc;
+typedef struct _E_Hwc_Sync_Callback E_Hwc_Sync_Callback;
 
 #define HWC_NAME_LEN 64
 
@@ -54,6 +55,8 @@ typedef struct _hwc_prop {
 typedef Eina_Bool (*E_Hwc_Intercept_Hook_Cb)(void *data, E_Hwc *hwc);
 typedef struct _E_Hwc_Intercept_Hook E_Hwc_Intercept_Hook;
 
+typedef void (*E_Hwc_Sync_Done_Cb)(void *data, E_Hwc *hwc);
+
 #else
 #ifndef E_HWC_H
 #define E_HWC_H
@@ -69,6 +72,14 @@ struct _E_Hwc_Intercept_Hook
    unsigned char               delete_me : 1;
 };
 
+struct _E_Hwc_Sync_Callback
+{
+   E_Hwc                      *hwc;
+   void                       *data;
+   E_Hwc_Sync_Done_Cb          cb;
+   Eina_Bool                   done;
+};
+
 struct _E_Hwc
 {
    E_Output            *output;
@@ -147,6 +158,8 @@ struct _E_Hwc
    Ecore_Timer         *commit_handler_timer;
 
    Eina_List           *wins_commit_data_list;
+
+   Eina_List           *sync_callback_list;
 };
 
 E_API extern int E_EVENT_HWC_ACTIVE;
@@ -186,5 +199,11 @@ E_API Eina_Bool               e_client_hwc_property_set(E_Client *ec, unsigned i
 E_API Eina_Bool               e_client_hwc_on_plane(E_Client *ec);
 E_API Eina_Bool               e_client_hwc_visible_skip_set(E_Client *ec, Eina_Bool skip);
 
+EINTERN Eina_Bool             e_hwc_sync_callback_call(E_Hwc_Sync_Callback *sync_callback);
+
+/* Once callback of E_Hwc_Sync_Callback is called, E_Hwc_Sync_Callback should be destroyed */
+E_API E_Hwc_Sync_Callback    *e_hwc_sync_callback_add(E_Hwc *hwc, E_Hwc_Sync_Done_Cb cb, void *data);
+E_API void                    e_hwc_sync_callback_del(E_Hwc_Sync_Callback *sync_callback);
+
 #endif
 #endif
index 2d37285047cd869612cf595e480fc3140458bbc7..fd199ea03cfacd2141fa94860140b534d5fbc732 100644 (file)
@@ -3069,6 +3069,16 @@ pp_fail:
    return EINA_FALSE;
 }
 
+static void
+_e_hwc_windows_sync_callback_call(E_Hwc *hwc)
+{
+   E_Hwc_Sync_Callback *sync_callback;
+   Eina_List *l, *ll;
+
+   EINA_LIST_FOREACH_SAFE(hwc->sync_callback_list, l, ll, sync_callback)
+     e_hwc_sync_callback_call(sync_callback);
+}
+
 EINTERN Eina_Bool
 e_hwc_windows_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode)
 {
@@ -3087,22 +3097,22 @@ e_hwc_windows_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode)
    if (hwc->primary_output)
      {
         if (!_e_hwc_windows_changes_update(hwc))
-          return EINA_TRUE;
+          goto update_done;
      }
    else
      {
         if (!_e_hwc_windows_external_changes_update(hwc, display_mode))
-          return EINA_TRUE;
+          goto update_done;
      }
 
    if (output->fake_config)
      {
         _e_hwc_windows_offscreen_commit(hwc);
-        return EINA_TRUE;
+        goto update_done;
      }
 
    if (!_e_hwc_windows_evaluate(hwc, display_mode))
-     return EINA_TRUE;
+     goto re_evaluate;
 
    if (hwc->pp_set)
      {
@@ -3113,17 +3123,17 @@ e_hwc_windows_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode)
    if (hwc->hwc_mode != E_HWC_MODE_FULL)
      {
         if (!_e_hwc_windows_target_buffer_prepared(hwc))
-          return EINA_TRUE;
+          goto re_evaluate;
      }
 
    if (output->dpms == E_OUTPUT_DPMS_OFF)
      {
         _e_hwc_windows_offscreen_commit(hwc);
-        return EINA_TRUE;
+        goto update_done;
      }
 
    if (!(wins_commit_data = _e_hwc_windows_commit_data_acquire(hwc)))
-     return EINA_TRUE;
+     goto update_done;
 
    EHWSTRACE("!!!!!!!! HWC Commit !!!!!!!!", NULL, hwc);
    _e_hwc_windows_update_fps(hwc);
@@ -3158,6 +3168,13 @@ e_hwc_windows_commit(E_Hwc *hwc, E_Output_Display_Mode display_mode)
    /* send tizen_hwc_commit feedback committed */
    e_comp_wl_tizen_hwc_committed();
 
+update_done:
+   if (!hwc->transition)
+     _e_hwc_windows_sync_callback_call(hwc);
+
+   return EINA_TRUE;
+
+re_evaluate:
    return EINA_TRUE;
 
 fail: