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)
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)
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;
+}
#ifdef E_TYPEDEFS
typedef struct _E_Hwc E_Hwc;
+typedef struct _E_Hwc_Sync_Callback E_Hwc_Sync_Callback;
#define HWC_NAME_LEN 64
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
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;
Ecore_Timer *commit_handler_timer;
Eina_List *wins_commit_data_list;
+
+ Eina_List *sync_callback_list;
};
E_API extern int E_EVENT_HWC_ACTIVE;
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
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)
{
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)
{
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);
/* 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: