From 8ff75dd25b4ca65af2c364366838b21ef725064d Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Tue, 16 Jan 2024 14:35:01 +0900 Subject: [PATCH] tizen-core: Apply tizen-core to ecore idler Change-Id: I6bc79967c6f8d18dce0c5a930f90cd2c912d09c7 Signed-off-by: Changgyu Choi --- src/lib/ecore/ecore_idle_enterer.c | 20 ++- src/lib/ecore/ecore_idle_exiter.c | 19 ++- src/lib/ecore/ecore_idler.c | 35 +++++ src/lib/ecore/ecore_internal.h | 2 +- src/lib/ecore/meson.build | 3 +- src/lib/ecore/tizen-core/tcore.cc | 5 + src/lib/ecore/tizen-core/tcore.h | 3 + src/lib/ecore/tizen-core/tcore_idler.cc | 233 ++++++++++++++++++++++++++++++++ src/lib/ecore/tizen-core/tcore_idler.h | 36 +++++ 9 files changed, 352 insertions(+), 4 deletions(-) create mode 100644 src/lib/ecore/tizen-core/tcore_idler.cc create mode 100644 src/lib/ecore/tizen-core/tcore_idler.h diff --git a/src/lib/ecore/ecore_idle_enterer.c b/src/lib/ecore/ecore_idle_enterer.c index 9ce4716..d9cba6a 100644 --- a/src/lib/ecore/ecore_idle_enterer.c +++ b/src/lib/ecore/ecore_idle_enterer.c @@ -9,6 +9,10 @@ #include "Ecore.h" #include "ecore_private.h" +#ifdef USE_TIZEN_CORE +#include "tizen-core/tcore_idler.h" +#endif // USE_TIZEN_CORE + EFL_CALLBACKS_ARRAY_DEFINE(ecore_idle_enterer_callbacks, { EFL_LOOP_EVENT_IDLE_ENTER, _ecore_factorized_idle_process }, { EFL_EVENT_DEL, _ecore_factorized_idle_event_del }); @@ -18,6 +22,11 @@ EAPI Ecore_Idle_Enterer * ecore_idle_enterer_add(Ecore_Task_Cb func, const void *data) { +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return tcore_idle_enterer_add(func, data); +#endif // USE_TIZEN_CORE + return _ecore_factorized_idle_add(ecore_idle_enterer_callbacks(), func, data); } @@ -25,9 +34,13 @@ EAPI Ecore_Idle_Enterer * ecore_idle_enterer_before_add(Ecore_Task_Cb func, const void *data) { +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return tcore_idle_enterer_before_add(func, data); +#endif // USE_TIZEN_CORE + Ecore_Idle_Enterer *ie = NULL; ie = _ecore_factorized_idle_add(ecore_idle_enterer_callbacks(), func, data); - // This avoid us duplicating code and should only be slightly slower // due to a useless cycle of callback registration efl_event_callback_array_del(_mainloop_singleton, ecore_idle_enterer_callbacks(), ie); @@ -39,5 +52,10 @@ ecore_idle_enterer_before_add(Ecore_Task_Cb func, EAPI void * ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer) { +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return tcore_idle_enterer_del(idle_enterer); +#endif // USE_TIZEN_CORE + return _ecore_factorized_idle_del(idle_enterer); } diff --git a/src/lib/ecore/ecore_idle_exiter.c b/src/lib/ecore/ecore_idle_exiter.c index 9ca26c8..8ab655df 100644 --- a/src/lib/ecore/ecore_idle_exiter.c +++ b/src/lib/ecore/ecore_idle_exiter.c @@ -9,6 +9,10 @@ #include "Ecore.h" #include "ecore_private.h" +#ifdef USE_TIZEN_CORE +#include "tizen-core/tcore_idler.h" +#endif // USE_TIZEN_CORE + EFL_CALLBACKS_ARRAY_DEFINE(ecore_idle_exiter_callbacks, { EFL_LOOP_EVENT_IDLE_EXIT, _ecore_factorized_idle_process }, { EFL_EVENT_DEL, _ecore_factorized_idle_event_del }); @@ -17,11 +21,24 @@ EAPI Ecore_Idle_Exiter * ecore_idle_exiter_add(Ecore_Task_Cb func, const void *data) { - return _ecore_factorized_idle_add(ecore_idle_exiter_callbacks(), func, data); +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return tcore_idle_exiter_add(func, data); +#endif // USE_TIZEN_CORE + + Ecore_Idle_Exiter *ie = _ecore_factorized_idle_add( + ecore_idle_exiter_callbacks(), func, data); + + return ie; } EAPI void * ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter) { +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return tcore_idle_exiter_del(idle_exiter); +#endif // USE_TIZEN_CORE + return _ecore_factorized_idle_del(idle_exiter); } diff --git a/src/lib/ecore/ecore_idler.c b/src/lib/ecore/ecore_idler.c index ffd4579..091f898 100644 --- a/src/lib/ecore/ecore_idler.c +++ b/src/lib/ecore/ecore_idler.c @@ -9,6 +9,10 @@ #include "Ecore.h" #include "ecore_private.h" +#ifdef USE_TIZEN_CORE +#include "tizen-core/tcore_idler.h" +#endif // USE_TIZEN_CORE + struct _Ecore_Factorized_Idle { Ecore_Task_Cb func; @@ -23,12 +27,22 @@ struct _Ecore_Factorized_Idle void _ecore_factorized_idle_event_del(void *data, const Efl_Event *event EINA_UNUSED) { +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return; +#endif //USE_TIZEN_CORE + _ecore_factorized_idle_del(data); } void _ecore_factorized_idle_process(void *data, const Efl_Event *event EINA_UNUSED) { +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return; +#endif //USE_TIZEN_CORE + Ecore_Factorized_Idle *idler = data; idler->references++; @@ -49,6 +63,12 @@ _ecore_factorized_idle_del(Ecore_Idler *idler) void *data; if (!idler) return NULL; + +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return NULL; +#endif // USE_TIZEN_CORE + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); if (idler->references > 0) @@ -79,6 +99,11 @@ _ecore_factorized_idle_add(const Efl_Callback_Array_Item *desc, return NULL; } +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return NULL; +#endif // USE_TIZEN_CORE + if (!idler_mp) { idler_mp = eina_mempool_add("chained_mempool", "Ecore_Idle*", NULL, sizeof (Ecore_Factorized_Idle), 23); @@ -109,11 +134,21 @@ EAPI Ecore_Idler * ecore_idler_add(Ecore_Task_Cb func, const void *data) { +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return tcore_idler_add(func, data); +#endif // USE_TIZEN_CORE + return _ecore_factorized_idle_add(ecore_idler_callbacks(), func, data); } EAPI void * ecore_idler_del(Ecore_Idler *idler) { +#ifdef USE_TIZEN_CORE + if (tcore_ready()) + return tcore_idler_del(idler); +#endif // USE_TIZEN_CORE + return _ecore_factorized_idle_del(idler); } diff --git a/src/lib/ecore/ecore_internal.h b/src/lib/ecore/ecore_internal.h index 9f6e55e..b17ffc1 100644 --- a/src/lib/ecore/ecore_internal.h +++ b/src/lib/ecore/ecore_internal.h @@ -38,7 +38,7 @@ efl_model_list_value_get(Eina_List *childrens, { Eina_Value v = EINA_VALUE_EMPTY; Eina_List *l; - Eo *child; + void *child; if (eina_list_count(childrens) < start + count) return eina_value_error_init(EFL_MODEL_ERROR_INCORRECT_VALUE); diff --git a/src/lib/ecore/meson.build b/src/lib/ecore/meson.build index bccdff3..40ec5c1 100644 --- a/src/lib/ecore/meson.build +++ b/src/lib/ecore/meson.build @@ -210,7 +210,8 @@ if get_option('tizen-core') == true ecore_ext_deps += dependency('dlog') ecore_src += files([ 'tizen-core/tcore.cc', - 'tizen-core/tcore_events.cc' + 'tizen-core/tcore_events.cc', + 'tizen-core/tcore_idler.cc' ]) config_h.set('USE_TIZEN_CORE', '1') endif diff --git a/src/lib/ecore/tizen-core/tcore.cc b/src/lib/ecore/tizen-core/tcore.cc index 16e8208..93728df 100644 --- a/src/lib/ecore/tizen-core/tcore.cc +++ b/src/lib/ecore/tizen-core/tcore.cc @@ -4,6 +4,7 @@ #include #include "log_private.h" +#include "tcore_idler.h" namespace { @@ -47,6 +48,8 @@ class TCore { return tizen_core_get_glib_context(tizen_core_); } + tizen_core_h GetCore() const { return tizen_core_; } + private: bool disposed_ = true; bool ready_ = false; @@ -58,6 +61,8 @@ TCore core; } // namespace +tizen_core_h tcore_get_core(void) { return core.GetCore(); } + void* tcore_get_glib_context(void) { return core.GetGLibContext(); } bool tcore_ready(void) { return core.IsReady(); } diff --git a/src/lib/ecore/tizen-core/tcore.h b/src/lib/ecore/tizen-core/tcore.h index 562d057..a1fc6e7 100644 --- a/src/lib/ecore/tizen-core/tcore.h +++ b/src/lib/ecore/tizen-core/tcore.h @@ -2,11 +2,14 @@ #define _TCORE_H #include +#include #ifdef __cplusplus extern "C" { #endif +tizen_core_h tcore_get_core(void); + void *tcore_get_glib_context(void); bool tcore_ready(void); diff --git a/src/lib/ecore/tizen-core/tcore_idler.cc b/src/lib/ecore/tizen-core/tcore_idler.cc new file mode 100644 index 0000000..7971b38 --- /dev/null +++ b/src/lib/ecore/tizen-core/tcore_idler.cc @@ -0,0 +1,233 @@ +#undef EINA_SLSTR_INTERNAL +#define EINA_SLSTR_INTERNAL + +#include "tcore_idler.h" + +#include + +#include +#include +#include +#include + +#include "eina_internal.h" +#include "log_private.h" + +namespace { + +class IdlerManager { + public: + class IdleTask { + public: + IdleTask(Ecore_Task_Cb cb, const void* data) + : cb_(cb), data_(const_cast(data)) {} + + bool Do() { + if (!cb_) + return false; + + return static_cast(cb_(data_)); + } + + void* GetData() { return data_; } + + private: + Ecore_Task_Cb cb_; + void* data_; + }; + + IdlerManager() = default; + + ~IdlerManager() { Dispose(); } + + IdleTask* AddEnterer(std::unique_ptr task) { + return AddInternal(&enterers_, std::move(task)); + } + + IdleTask* AddIdler(std::unique_ptr task) { + return AddInternal(&idlers_, std::move(task)); + } + + IdleTask* AddExiter(std::unique_ptr task) { + return AddInternal(&exiters_, std::move(task)); + } + + IdleTask* AddBeforeEnterer(std::unique_ptr task) { + return AddInternal(&before_enterers_, std::move(task)); + } + + void* RemoveEnterer(IdleTask* task) { + void* data = RemoveInternal(&before_enterers_, task); + if (data != nullptr) + return data; + + return RemoveInternal(&enterers_, task); + } + + void* RemoveIdler(IdleTask* task) { return RemoveInternal(&idlers_, task); } + + void* RemoveExiter(IdleTask* task) { return RemoveInternal(&exiters_, task); } + + private: + void ProcessEnterer() { + std::unique_lock lock(GetMutex()); + before_enterers_.remove_if( + [](const std::unique_ptr& task) { return !task->Do(); }); + enterers_.remove_if( + [](const std::unique_ptr& task) { return !task->Do(); }); + + _ecore_throttle(); + } + + void ProcessIdler() { + std::unique_lock lock(GetMutex()); + idlers_.remove_if( + [](const std::unique_ptr& task) { return !task->Do(); }); + } + + void ProcessExiter() { + std::unique_lock lock(GetMutex()); + _ecore_animator_run_reset(); + eina_file_statgen_next(); + exiters_.remove_if( + [](const std::unique_ptr& task) { return !task->Do(); }); + + _ecore_animator_flush(); + eina_slstr_local_clear(); + } + + bool IdlerExist() const { + std::unique_lock lock(GetMutex()); + return !idlers_.empty(); + } + + IdleTask* AddInternal(std::list>* list, + std::unique_ptr task) { + std::unique_lock lock(mutex_); + Init(); + IdleTask* ret = task.get(); + list->push_front(std::move(task)); + return ret; + } + + void* RemoveInternal(std::list>* list, + IdleTask* task) { + std::unique_lock lock(mutex_); + auto it = std::find_if(list->begin(), list->end(), + [&](const std::unique_ptr& _task) { + return _task.get() == task; + }); + + if (it == list->end()) + return nullptr; + + void* data = (*it)->GetData(); + list->erase(it); + + if (before_enterers_.empty() && enterers_.empty() && idlers_.empty() && + exiters_.empty()) + Dispose(); + + return data; + } + + std::recursive_mutex& GetMutex() const { return mutex_; } + + static bool SourcePrepareCb(tizen_core_source_h source, int* timeout, + void* user_data) { + IdlerManager* manager = static_cast(user_data); + if (!manager->IdlerExist()) + *timeout = -1; + else + *timeout = 0; + return false; + } + + static bool SourceCheckCb(tizen_core_source_h source, void* user_data) { + auto* manager = static_cast(user_data); + manager->ProcessEnterer(); + if (!manager->IdlerExist()) return false; + return true; + } + + static bool SourceDispatchCb(tizen_core_source_h source, void* user_data) { + auto* manager = static_cast(user_data); + manager->ProcessIdler(); + manager->ProcessExiter(); + return true; + } + + void Init() { + std::unique_lock lock(GetMutex()); + if (!disposed_) return; + + tizen_core_source_create(&source_); + tizen_core_source_set_prepare_cb(source_, SourcePrepareCb, this); + tizen_core_source_set_check_cb(source_, SourceCheckCb, this); + tizen_core_source_set_dispatch_cb(source_, SourceDispatchCb, this); + tizen_core_add_source(tcore_get_core(), source_); + tizen_core_source_set_priority(source_, TIZEN_CORE_PRIORITY_HIGH_IDLE); + disposed_ = false; + } + + void Dispose() { + std::unique_lock lock(GetMutex()); + if (disposed_) return; + + if (source_) { + tizen_core_remove_source(tcore_get_core(), source_); + source_ = nullptr; + } + + disposed_ = true; + } + + private: + bool disposed_ = true; + mutable std::recursive_mutex mutex_; + std::list> before_enterers_; + std::list> enterers_; + std::list> idlers_; + std::list> exiters_; + tizen_core_source_h source_ = nullptr; +}; + +IdlerManager manager; + +} // namespace + +Ecore_Idler* tcore_idler_add(Ecore_Task_Cb func, const void* data) { + return reinterpret_cast( + manager.AddIdler(std::make_unique(func, data))); +} + +void* tcore_idler_del(Ecore_Idler* idler) { + return manager.RemoveIdler(reinterpret_cast(idler)); +} + +Ecore_Idle_Enterer* tcore_idle_enterer_add(Ecore_Task_Cb func, + const void* data) { + return reinterpret_cast( + manager.AddEnterer(std::make_unique(func, data))); +} + +Ecore_Idle_Enterer* tcore_idle_enterer_before_add(Ecore_Task_Cb func, + const void* data) { + return reinterpret_cast(manager.AddBeforeEnterer( + std::make_unique(func, data))); +} + +void* tcore_idle_enterer_del(Ecore_Idle_Enterer* idle_enterer) { + return manager.RemoveEnterer( + reinterpret_cast(idle_enterer)); +} + +Ecore_Idle_Exiter* tcore_idle_exiter_add(Ecore_Task_Cb func, const void* data) { + return reinterpret_cast( + manager.AddExiter(std::make_unique(func, data))); +} + +void* tcore_idle_exiter_del(Ecore_Idle_Exiter* idle_exiter) { + return manager.RemoveExiter( + reinterpret_cast(idle_exiter)); +} diff --git a/src/lib/ecore/tizen-core/tcore_idler.h b/src/lib/ecore/tizen-core/tcore_idler.h new file mode 100644 index 0000000..9655676 --- /dev/null +++ b/src/lib/ecore/tizen-core/tcore_idler.h @@ -0,0 +1,36 @@ +#ifndef _TCORE_IDLER_H +#define _TCORE_IDLER_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +#include "../Ecore.h" +#include "../ecore_private.h" + +#include "tcore.h" + +Ecore_Idler *tcore_idler_add(Ecore_Task_Cb func, const void *data); + +void *tcore_idler_del(Ecore_Idler *idler); + +Ecore_Idle_Enterer *tcore_idle_enterer_add(Ecore_Task_Cb func, + const void *data); + +Ecore_Idle_Enterer *tcore_idle_enterer_before_add(Ecore_Task_Cb func, + const void *data); + +void *tcore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer); + +Ecore_Idle_Exiter *tcore_idle_exiter_add(Ecore_Task_Cb func, const void *data); + +void *tcore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _TCORE_IDLER_H */ -- 2.7.4