From 885e8bc7e202ccc53d2d48b03e2286237a0dbde2 Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Thu, 22 Sep 2022 12:38:38 +0900 Subject: [PATCH 1/4] Remove extra threading from TizenVsyncWaiter --- shell/platform/tizen/tizen_vsync_waiter.cc | 126 +++------------------ shell/platform/tizen/tizen_vsync_waiter.h | 29 +---- 2 files changed, 18 insertions(+), 137 deletions(-) diff --git a/shell/platform/tizen/tizen_vsync_waiter.cc b/shell/platform/tizen/tizen_vsync_waiter.cc index 0906cae1e9fe9..0621aa3138e69 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.cc +++ b/shell/platform/tizen/tizen_vsync_waiter.cc @@ -4,108 +4,13 @@ #include "tizen_vsync_waiter.h" -#include - #include "flutter/shell/platform/tizen/flutter_tizen_engine.h" #include "flutter/shell/platform/tizen/logger.h" namespace flutter { -namespace { - -constexpr int kMessageQuit = -1; -constexpr int kMessageRequestVblank = 0; - -struct Message { - Eina_Thread_Queue_Msg head; - int event; - intptr_t baton; -}; - -} // namespace - -TizenVsyncWaiter::TizenVsyncWaiter(FlutterTizenEngine* engine) { - tdm_client_ = std::make_shared(engine); - - vblank_thread_ = ecore_thread_feedback_run(RunVblankLoop, nullptr, nullptr, - nullptr, this, EINA_TRUE); -} - -TizenVsyncWaiter::~TizenVsyncWaiter() { - tdm_client_.reset(); - - SendMessage(kMessageQuit, 0); - - if (vblank_thread_) { - ecore_thread_cancel(vblank_thread_); - vblank_thread_ = nullptr; - } -} - -void TizenVsyncWaiter::AsyncWaitForVsync(intptr_t baton) { - SendMessage(kMessageRequestVblank, baton); -} - -void TizenVsyncWaiter::SendMessage(int event, intptr_t baton) { - if (!vblank_thread_ || ecore_thread_check(vblank_thread_)) { - FT_LOG(Error) << "Invalid vblank thread."; - return; - } - - if (!vblank_thread_queue_) { - FT_LOG(Error) << "Invalid vblank thread queue."; - return; - } - - void* ref; - Message* message = static_cast( - eina_thread_queue_send(vblank_thread_queue_, sizeof(Message), &ref)); - message->event = event; - message->baton = baton; - eina_thread_queue_send_done(vblank_thread_queue_, ref); -} - -void TizenVsyncWaiter::RunVblankLoop(void* data, Ecore_Thread* thread) { - auto* self = reinterpret_cast(data); - - std::weak_ptr tdm_client = self->tdm_client_; - if (!tdm_client.lock()->IsValid()) { - FT_LOG(Error) << "Invalid tdm_client."; - ecore_thread_cancel(thread); - return; - } - - Eina_Thread_Queue* vblank_thread_queue = eina_thread_queue_new(); - if (!vblank_thread_queue) { - FT_LOG(Error) << "Invalid vblank thread queue."; - ecore_thread_cancel(thread); - return; - } - self->vblank_thread_queue_ = vblank_thread_queue; - - while (!ecore_thread_check(thread)) { - void* ref; - Message* message = static_cast( - eina_thread_queue_wait(vblank_thread_queue, &ref)); - if (message->event == kMessageQuit) { - eina_thread_queue_wait_done(vblank_thread_queue, ref); - break; - } - intptr_t baton = message->baton; - eina_thread_queue_wait_done(vblank_thread_queue, ref); - - if (tdm_client.expired()) { - break; - } - tdm_client.lock()->AwaitVblank(baton); - } - - if (vblank_thread_queue) { - eina_thread_queue_free(vblank_thread_queue); - } -} - -TdmClient::TdmClient(FlutterTizenEngine* engine) { +TizenVsyncWaiter::TizenVsyncWaiter(FlutterTizenEngine* engine) + : engine_(engine) { tdm_error ret; client_ = tdm_client_create(&ret); if (ret != TDM_ERROR_NONE) { @@ -125,27 +30,28 @@ TdmClient::TdmClient(FlutterTizenEngine* engine) { return; } tdm_client_vblank_set_enable_fake(vblank_, 1); - - engine_ = engine; } -TdmClient::~TdmClient() { +TizenVsyncWaiter::~TizenVsyncWaiter() { { std::lock_guard lock(engine_mutex_); engine_ = nullptr; } + if (vblank_) { tdm_client_vblank_destroy(vblank_); vblank_ = nullptr; } + output_ = nullptr; + if (client_) { tdm_client_destroy(client_); client_ = nullptr; } } -void TdmClient::AwaitVblank(intptr_t baton) { +void TizenVsyncWaiter::AsyncWaitForVsync(intptr_t baton) { baton_ = baton; tdm_error ret = tdm_client_vblank_wait(vblank_, 1, VblankCallback, this); if (ret != TDM_ERROR_NONE) { @@ -155,17 +61,13 @@ void TdmClient::AwaitVblank(intptr_t baton) { tdm_client_handle_events(client_); } -bool TdmClient::IsValid() { - return vblank_ && client_; -} - -void TdmClient::VblankCallback(tdm_client_vblank* vblank, - tdm_error error, - unsigned int sequence, - unsigned int tv_sec, - unsigned int tv_usec, - void* user_data) { - auto* self = reinterpret_cast(user_data); +void TizenVsyncWaiter::VblankCallback(tdm_client_vblank* vblank, + tdm_error error, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void* user_data) { + auto* self = reinterpret_cast(user_data); FT_ASSERT(self != nullptr); std::lock_guard lock(self->engine_mutex_); diff --git a/shell/platform/tizen/tizen_vsync_waiter.h b/shell/platform/tizen/tizen_vsync_waiter.h index acb164b049019..1d98d9c63dc2a 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.h +++ b/shell/platform/tizen/tizen_vsync_waiter.h @@ -5,25 +5,21 @@ #ifndef EMBEDDER_TIZEN_VSYNC_WAITER_H_ #define EMBEDDER_TIZEN_VSYNC_WAITER_H_ -#include #include #include #include -#include "flutter/shell/platform/embedder/embedder.h" - namespace flutter { class FlutterTizenEngine; -class TdmClient { +class TizenVsyncWaiter { public: - TdmClient(FlutterTizenEngine* engine); - virtual ~TdmClient(); + TizenVsyncWaiter(FlutterTizenEngine* engine); + virtual ~TizenVsyncWaiter(); - bool IsValid(); - void AwaitVblank(intptr_t baton); + void AsyncWaitForVsync(intptr_t baton); private: static void VblankCallback(tdm_client_vblank* vblank, @@ -43,23 +39,6 @@ class TdmClient { intptr_t baton_ = 0; }; -class TizenVsyncWaiter { - public: - TizenVsyncWaiter(FlutterTizenEngine* engine); - virtual ~TizenVsyncWaiter(); - - void AsyncWaitForVsync(intptr_t baton); - - private: - void SendMessage(int event, intptr_t baton); - - static void RunVblankLoop(void* data, Ecore_Thread* thread); - - std::shared_ptr tdm_client_; - Ecore_Thread* vblank_thread_ = nullptr; - Eina_Thread_Queue* vblank_thread_queue_ = nullptr; -}; - } // namespace flutter #endif // EMBEDDER_TIZEN_VSYNC_WAITER_H_ From ef8fd0d4e667fb5a72b4efb9a089545e5a02b76a Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Thu, 22 Sep 2022 17:25:15 +0900 Subject: [PATCH 2/4] Revert "Remove extra threading from TizenVsyncWaiter" This reverts commit 885e8bc7e202ccc53d2d48b03e2286237a0dbde2. --- shell/platform/tizen/tizen_vsync_waiter.cc | 126 ++++++++++++++++++--- shell/platform/tizen/tizen_vsync_waiter.h | 29 ++++- 2 files changed, 137 insertions(+), 18 deletions(-) diff --git a/shell/platform/tizen/tizen_vsync_waiter.cc b/shell/platform/tizen/tizen_vsync_waiter.cc index 0621aa3138e69..0906cae1e9fe9 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.cc +++ b/shell/platform/tizen/tizen_vsync_waiter.cc @@ -4,13 +4,108 @@ #include "tizen_vsync_waiter.h" +#include + #include "flutter/shell/platform/tizen/flutter_tizen_engine.h" #include "flutter/shell/platform/tizen/logger.h" namespace flutter { -TizenVsyncWaiter::TizenVsyncWaiter(FlutterTizenEngine* engine) - : engine_(engine) { +namespace { + +constexpr int kMessageQuit = -1; +constexpr int kMessageRequestVblank = 0; + +struct Message { + Eina_Thread_Queue_Msg head; + int event; + intptr_t baton; +}; + +} // namespace + +TizenVsyncWaiter::TizenVsyncWaiter(FlutterTizenEngine* engine) { + tdm_client_ = std::make_shared(engine); + + vblank_thread_ = ecore_thread_feedback_run(RunVblankLoop, nullptr, nullptr, + nullptr, this, EINA_TRUE); +} + +TizenVsyncWaiter::~TizenVsyncWaiter() { + tdm_client_.reset(); + + SendMessage(kMessageQuit, 0); + + if (vblank_thread_) { + ecore_thread_cancel(vblank_thread_); + vblank_thread_ = nullptr; + } +} + +void TizenVsyncWaiter::AsyncWaitForVsync(intptr_t baton) { + SendMessage(kMessageRequestVblank, baton); +} + +void TizenVsyncWaiter::SendMessage(int event, intptr_t baton) { + if (!vblank_thread_ || ecore_thread_check(vblank_thread_)) { + FT_LOG(Error) << "Invalid vblank thread."; + return; + } + + if (!vblank_thread_queue_) { + FT_LOG(Error) << "Invalid vblank thread queue."; + return; + } + + void* ref; + Message* message = static_cast( + eina_thread_queue_send(vblank_thread_queue_, sizeof(Message), &ref)); + message->event = event; + message->baton = baton; + eina_thread_queue_send_done(vblank_thread_queue_, ref); +} + +void TizenVsyncWaiter::RunVblankLoop(void* data, Ecore_Thread* thread) { + auto* self = reinterpret_cast(data); + + std::weak_ptr tdm_client = self->tdm_client_; + if (!tdm_client.lock()->IsValid()) { + FT_LOG(Error) << "Invalid tdm_client."; + ecore_thread_cancel(thread); + return; + } + + Eina_Thread_Queue* vblank_thread_queue = eina_thread_queue_new(); + if (!vblank_thread_queue) { + FT_LOG(Error) << "Invalid vblank thread queue."; + ecore_thread_cancel(thread); + return; + } + self->vblank_thread_queue_ = vblank_thread_queue; + + while (!ecore_thread_check(thread)) { + void* ref; + Message* message = static_cast( + eina_thread_queue_wait(vblank_thread_queue, &ref)); + if (message->event == kMessageQuit) { + eina_thread_queue_wait_done(vblank_thread_queue, ref); + break; + } + intptr_t baton = message->baton; + eina_thread_queue_wait_done(vblank_thread_queue, ref); + + if (tdm_client.expired()) { + break; + } + tdm_client.lock()->AwaitVblank(baton); + } + + if (vblank_thread_queue) { + eina_thread_queue_free(vblank_thread_queue); + } +} + +TdmClient::TdmClient(FlutterTizenEngine* engine) { tdm_error ret; client_ = tdm_client_create(&ret); if (ret != TDM_ERROR_NONE) { @@ -30,28 +125,27 @@ TizenVsyncWaiter::TizenVsyncWaiter(FlutterTizenEngine* engine) return; } tdm_client_vblank_set_enable_fake(vblank_, 1); + + engine_ = engine; } -TizenVsyncWaiter::~TizenVsyncWaiter() { +TdmClient::~TdmClient() { { std::lock_guard lock(engine_mutex_); engine_ = nullptr; } - if (vblank_) { tdm_client_vblank_destroy(vblank_); vblank_ = nullptr; } - output_ = nullptr; - if (client_) { tdm_client_destroy(client_); client_ = nullptr; } } -void TizenVsyncWaiter::AsyncWaitForVsync(intptr_t baton) { +void TdmClient::AwaitVblank(intptr_t baton) { baton_ = baton; tdm_error ret = tdm_client_vblank_wait(vblank_, 1, VblankCallback, this); if (ret != TDM_ERROR_NONE) { @@ -61,13 +155,17 @@ void TizenVsyncWaiter::AsyncWaitForVsync(intptr_t baton) { tdm_client_handle_events(client_); } -void TizenVsyncWaiter::VblankCallback(tdm_client_vblank* vblank, - tdm_error error, - unsigned int sequence, - unsigned int tv_sec, - unsigned int tv_usec, - void* user_data) { - auto* self = reinterpret_cast(user_data); +bool TdmClient::IsValid() { + return vblank_ && client_; +} + +void TdmClient::VblankCallback(tdm_client_vblank* vblank, + tdm_error error, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void* user_data) { + auto* self = reinterpret_cast(user_data); FT_ASSERT(self != nullptr); std::lock_guard lock(self->engine_mutex_); diff --git a/shell/platform/tizen/tizen_vsync_waiter.h b/shell/platform/tizen/tizen_vsync_waiter.h index 1d98d9c63dc2a..acb164b049019 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.h +++ b/shell/platform/tizen/tizen_vsync_waiter.h @@ -5,21 +5,25 @@ #ifndef EMBEDDER_TIZEN_VSYNC_WAITER_H_ #define EMBEDDER_TIZEN_VSYNC_WAITER_H_ +#include #include #include #include +#include "flutter/shell/platform/embedder/embedder.h" + namespace flutter { class FlutterTizenEngine; -class TizenVsyncWaiter { +class TdmClient { public: - TizenVsyncWaiter(FlutterTizenEngine* engine); - virtual ~TizenVsyncWaiter(); + TdmClient(FlutterTizenEngine* engine); + virtual ~TdmClient(); - void AsyncWaitForVsync(intptr_t baton); + bool IsValid(); + void AwaitVblank(intptr_t baton); private: static void VblankCallback(tdm_client_vblank* vblank, @@ -39,6 +43,23 @@ class TizenVsyncWaiter { intptr_t baton_ = 0; }; +class TizenVsyncWaiter { + public: + TizenVsyncWaiter(FlutterTizenEngine* engine); + virtual ~TizenVsyncWaiter(); + + void AsyncWaitForVsync(intptr_t baton); + + private: + void SendMessage(int event, intptr_t baton); + + static void RunVblankLoop(void* data, Ecore_Thread* thread); + + std::shared_ptr tdm_client_; + Ecore_Thread* vblank_thread_ = nullptr; + Eina_Thread_Queue* vblank_thread_queue_ = nullptr; +}; + } // namespace flutter #endif // EMBEDDER_TIZEN_VSYNC_WAITER_H_ From 538b5dadca0866cb0cdc86814f066f72e5c38390 Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Thu, 22 Sep 2022 18:13:22 +0900 Subject: [PATCH 3/4] Make tdm_client local to RunVblankLoop --- shell/platform/tizen/tizen_vsync_waiter.cc | 38 ++++++++++------------ shell/platform/tizen/tizen_vsync_waiter.h | 7 ++-- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/shell/platform/tizen/tizen_vsync_waiter.cc b/shell/platform/tizen/tizen_vsync_waiter.cc index 0906cae1e9fe9..afb59f05b514f 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.cc +++ b/shell/platform/tizen/tizen_vsync_waiter.cc @@ -24,18 +24,17 @@ struct Message { } // namespace -TizenVsyncWaiter::TizenVsyncWaiter(FlutterTizenEngine* engine) { - tdm_client_ = std::make_shared(engine); - +TizenVsyncWaiter::TizenVsyncWaiter(FlutterTizenEngine* engine) + : engine_(engine) { vblank_thread_ = ecore_thread_feedback_run(RunVblankLoop, nullptr, nullptr, nullptr, this, EINA_TRUE); } TizenVsyncWaiter::~TizenVsyncWaiter() { - tdm_client_.reset(); - + if (tdm_client_) { + tdm_client_->OnEngineStop(); + } SendMessage(kMessageQuit, 0); - if (vblank_thread_) { ecore_thread_cancel(vblank_thread_); vblank_thread_ = nullptr; @@ -68,8 +67,9 @@ void TizenVsyncWaiter::SendMessage(int event, intptr_t baton) { void TizenVsyncWaiter::RunVblankLoop(void* data, Ecore_Thread* thread) { auto* self = reinterpret_cast(data); - std::weak_ptr tdm_client = self->tdm_client_; - if (!tdm_client.lock()->IsValid()) { + TdmClient tdm_client(self->engine_); + self->SetTdmClient(&tdm_client); + if (!tdm_client.IsValid()) { FT_LOG(Error) << "Invalid tdm_client."; ecore_thread_cancel(thread); return; @@ -94,10 +94,7 @@ void TizenVsyncWaiter::RunVblankLoop(void* data, Ecore_Thread* thread) { intptr_t baton = message->baton; eina_thread_queue_wait_done(vblank_thread_queue, ref); - if (tdm_client.expired()) { - break; - } - tdm_client.lock()->AwaitVblank(baton); + tdm_client.AwaitVblank(baton); } if (vblank_thread_queue) { @@ -130,10 +127,6 @@ TdmClient::TdmClient(FlutterTizenEngine* engine) { } TdmClient::~TdmClient() { - { - std::lock_guard lock(engine_mutex_); - engine_ = nullptr; - } if (vblank_) { tdm_client_vblank_destroy(vblank_); vblank_ = nullptr; @@ -145,6 +138,15 @@ TdmClient::~TdmClient() { } } +bool TdmClient::IsValid() { + return vblank_ && client_; +} + +void TdmClient::OnEngineStop() { + std::lock_guard lock(engine_mutex_); + engine_ = nullptr; +} + void TdmClient::AwaitVblank(intptr_t baton) { baton_ = baton; tdm_error ret = tdm_client_vblank_wait(vblank_, 1, VblankCallback, this); @@ -155,10 +157,6 @@ void TdmClient::AwaitVblank(intptr_t baton) { tdm_client_handle_events(client_); } -bool TdmClient::IsValid() { - return vblank_ && client_; -} - void TdmClient::VblankCallback(tdm_client_vblank* vblank, tdm_error error, unsigned int sequence, diff --git a/shell/platform/tizen/tizen_vsync_waiter.h b/shell/platform/tizen/tizen_vsync_waiter.h index acb164b049019..44eb4e31b2a5e 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.h +++ b/shell/platform/tizen/tizen_vsync_waiter.h @@ -8,7 +8,6 @@ #include #include -#include #include #include "flutter/shell/platform/embedder/embedder.h" @@ -23,6 +22,7 @@ class TdmClient { virtual ~TdmClient(); bool IsValid(); + void OnEngineStop(); void AwaitVblank(intptr_t baton); private: @@ -53,9 +53,12 @@ class TizenVsyncWaiter { private: void SendMessage(int event, intptr_t baton); + void SetTdmClient(TdmClient* tdm_client) { tdm_client_ = tdm_client; } + static void RunVblankLoop(void* data, Ecore_Thread* thread); - std::shared_ptr tdm_client_; + FlutterTizenEngine* engine_ = nullptr; + TdmClient* tdm_client_ = nullptr; Ecore_Thread* vblank_thread_ = nullptr; Eina_Thread_Queue* vblank_thread_queue_ = nullptr; }; From e97c1fac83cc1b545a7398f65a3d113c2902d8a4 Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Fri, 23 Sep 2022 17:51:50 +0900 Subject: [PATCH 4/4] Make tdm_client_ into a share_ptr again --- shell/platform/tizen/tizen_vsync_waiter.cc | 21 ++++++++++++--------- shell/platform/tizen/tizen_vsync_waiter.h | 6 ++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/shell/platform/tizen/tizen_vsync_waiter.cc b/shell/platform/tizen/tizen_vsync_waiter.cc index afb59f05b514f..e321759614d02 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.cc +++ b/shell/platform/tizen/tizen_vsync_waiter.cc @@ -24,17 +24,18 @@ struct Message { } // namespace -TizenVsyncWaiter::TizenVsyncWaiter(FlutterTizenEngine* engine) - : engine_(engine) { +TizenVsyncWaiter::TizenVsyncWaiter(FlutterTizenEngine* engine) { + tdm_client_ = std::make_shared(engine); + vblank_thread_ = ecore_thread_feedback_run(RunVblankLoop, nullptr, nullptr, nullptr, this, EINA_TRUE); } TizenVsyncWaiter::~TizenVsyncWaiter() { - if (tdm_client_) { - tdm_client_->OnEngineStop(); - } + tdm_client_->OnEngineStop(); + SendMessage(kMessageQuit, 0); + if (vblank_thread_) { ecore_thread_cancel(vblank_thread_); vblank_thread_ = nullptr; @@ -67,9 +68,8 @@ void TizenVsyncWaiter::SendMessage(int event, intptr_t baton) { void TizenVsyncWaiter::RunVblankLoop(void* data, Ecore_Thread* thread) { auto* self = reinterpret_cast(data); - TdmClient tdm_client(self->engine_); - self->SetTdmClient(&tdm_client); - if (!tdm_client.IsValid()) { + std::weak_ptr tdm_client = self->tdm_client_; + if (!tdm_client.lock()->IsValid()) { FT_LOG(Error) << "Invalid tdm_client."; ecore_thread_cancel(thread); return; @@ -94,7 +94,10 @@ void TizenVsyncWaiter::RunVblankLoop(void* data, Ecore_Thread* thread) { intptr_t baton = message->baton; eina_thread_queue_wait_done(vblank_thread_queue, ref); - tdm_client.AwaitVblank(baton); + if (tdm_client.expired()) { + break; + } + tdm_client.lock()->AwaitVblank(baton); } if (vblank_thread_queue) { diff --git a/shell/platform/tizen/tizen_vsync_waiter.h b/shell/platform/tizen/tizen_vsync_waiter.h index 44eb4e31b2a5e..627fc6f02051b 100644 --- a/shell/platform/tizen/tizen_vsync_waiter.h +++ b/shell/platform/tizen/tizen_vsync_waiter.h @@ -8,6 +8,7 @@ #include #include +#include #include #include "flutter/shell/platform/embedder/embedder.h" @@ -53,12 +54,9 @@ class TizenVsyncWaiter { private: void SendMessage(int event, intptr_t baton); - void SetTdmClient(TdmClient* tdm_client) { tdm_client_ = tdm_client; } - static void RunVblankLoop(void* data, Ecore_Thread* thread); - FlutterTizenEngine* engine_ = nullptr; - TdmClient* tdm_client_ = nullptr; + std::shared_ptr tdm_client_; Ecore_Thread* vblank_thread_ = nullptr; Eina_Thread_Queue* vblank_thread_queue_ = nullptr; };