99#include " flutter/shell/platform/tizen/flutter_tizen_engine.h"
1010#include " flutter/shell/platform/tizen/logger.h"
1111
12- static const int kMessageQuit = -1 ;
13- static const int kMessageRequestVblank = 0 ;
14-
1512namespace flutter {
1613
17- typedef struct {
14+ namespace {
15+
16+ constexpr int kMessageQuit = -1 ;
17+ constexpr int kMessageRequestVblank = 0 ;
18+
19+ struct Message {
1820 Eina_Thread_Queue_Msg head;
1921 int event;
2022 intptr_t baton;
21- } Msg ;
23+ };
2224
23- TizenVsyncWaiter::TizenVsyncWaiter (FlutterTizenEngine* engine)
24- : engine_(engine) {
25- vblank_thread_ = ecore_thread_feedback_run (RequestVblankLoop, nullptr ,
26- nullptr , nullptr , this , EINA_TRUE);
25+ } // namespace
26+
27+ TizenVsyncWaiter::TizenVsyncWaiter (FlutterTizenEngine* engine) {
28+ tdm_client_ = std::make_shared<TdmClient>(engine);
29+
30+ vblank_thread_ = ecore_thread_feedback_run (RunVblankLoop, nullptr , nullptr ,
31+ nullptr , this , EINA_TRUE);
2732}
2833
2934TizenVsyncWaiter::~TizenVsyncWaiter () {
30- if ( tdm_client_) {
31- tdm_client_-> OnEngineStop ();
32- }
33- Send ( kMessageQuit , 0 );
35+ tdm_client_. reset ();
36+
37+ SendMessage ( kMessageQuit , 0 );
38+
3439 if (vblank_thread_) {
3540 ecore_thread_cancel (vblank_thread_);
3641 vblank_thread_ = nullptr ;
3742 }
3843}
3944
40- void TizenVsyncWaiter::SetTdmClient (TdmClient* tdm_client) {
41- tdm_client_ = tdm_client;
42- }
43-
4445void TizenVsyncWaiter::AsyncWaitForVsync (intptr_t baton) {
45- Send (kMessageRequestVblank , baton);
46+ SendMessage (kMessageRequestVblank , baton);
4647}
4748
48- void TizenVsyncWaiter::Send (int event, intptr_t baton) {
49+ void TizenVsyncWaiter::SendMessage (int event, intptr_t baton) {
4950 if (!vblank_thread_ || ecore_thread_check (vblank_thread_)) {
5051 FT_LOG (Error) << " Invalid vblank thread." ;
5152 return ;
@@ -56,104 +57,83 @@ void TizenVsyncWaiter::Send(int event, intptr_t baton) {
5657 return ;
5758 }
5859
59- Msg* msg;
6060 void * ref;
61- msg = static_cast <Msg *>(
62- eina_thread_queue_send (vblank_thread_queue_, sizeof (Msg ), &ref));
63- msg ->event = event;
64- msg ->baton = baton;
61+ Message* message = static_cast <Message *>(
62+ eina_thread_queue_send (vblank_thread_queue_, sizeof (Message ), &ref));
63+ message ->event = event;
64+ message ->baton = baton;
6565 eina_thread_queue_send_done (vblank_thread_queue_, ref);
6666}
6767
68- void TizenVsyncWaiter::RequestVblankLoop (void * data, Ecore_Thread* thread) {
69- TizenVsyncWaiter* tizen_vsync_waiter =
70- reinterpret_cast <TizenVsyncWaiter*>(data);
71- TdmClient tdm_client (tizen_vsync_waiter->engine_ );
72- tizen_vsync_waiter->SetTdmClient (&tdm_client);
73- if (!tdm_client.IsValid ()) {
68+ void TizenVsyncWaiter::RunVblankLoop (void * data, Ecore_Thread* thread) {
69+ auto * self = reinterpret_cast <TizenVsyncWaiter*>(data);
70+
71+ std::weak_ptr<TdmClient> tdm_client = self->tdm_client_ ;
72+ if (!tdm_client.lock ()->IsValid ()) {
7473 FT_LOG (Error) << " Invalid tdm_client." ;
7574 ecore_thread_cancel (thread);
7675 return ;
7776 }
77+
7878 Eina_Thread_Queue* vblank_thread_queue = eina_thread_queue_new ();
7979 if (!vblank_thread_queue) {
8080 FT_LOG (Error) << " Invalid vblank thread queue." ;
8181 ecore_thread_cancel (thread);
8282 return ;
8383 }
84+ self->vblank_thread_queue_ = vblank_thread_queue;
8485
85- tizen_vsync_waiter->vblank_thread_queue_ = vblank_thread_queue;
8686 while (!ecore_thread_check (thread)) {
8787 void * ref;
88- Msg* msg;
89- msg = static_cast <Msg*>( eina_thread_queue_wait (vblank_thread_queue, &ref));
90- if (msg ) {
88+ Message* message = static_cast <Message*>(
89+ eina_thread_queue_wait (vblank_thread_queue, &ref));
90+ if (message-> event == kMessageQuit ) {
9191 eina_thread_queue_wait_done (vblank_thread_queue, ref);
92- } else {
93- FT_LOG (Error) << " Received a null message." ;
94- continue ;
92+ break ;
9593 }
96- if (msg->event == kMessageQuit ) {
94+ intptr_t baton = message->baton ;
95+ eina_thread_queue_wait_done (vblank_thread_queue, ref);
96+
97+ if (tdm_client.expired ()) {
9798 break ;
9899 }
99- tdm_client.WaitVblank (msg-> baton );
100+ tdm_client.lock ()-> AwaitVblank ( baton);
100101 }
102+
101103 if (vblank_thread_queue) {
102104 eina_thread_queue_free (vblank_thread_queue);
103105 }
104106}
105107
106108TdmClient::TdmClient (FlutterTizenEngine* engine) {
107- if (!CreateTdm ()) {
108- FT_LOG (Error) << " CreateTdm() failed." ;
109- }
110- engine_ = engine;
111- }
112-
113- TdmClient::~TdmClient () {
114- DestroyTdm ();
115- }
116-
117- void TdmClient::OnEngineStop () {
118- std::lock_guard<std::mutex> lock (engine_mutex_);
119- engine_ = nullptr ;
120- }
121-
122- void TdmClient::WaitVblank (intptr_t baton) {
123- baton_ = baton;
124- tdm_error error = tdm_client_vblank_wait (vblank_, 1 , VblankCallback, this );
125- if (error != TDM_ERROR_NONE) {
126- FT_LOG (Error) << " tdm_client_vblank_wait() failed." ;
127- return ;
128- }
129- tdm_client_handle_events (client_);
130- }
131-
132- bool TdmClient::CreateTdm () {
133109 tdm_error ret;
134110 client_ = tdm_client_create (&ret);
135- if (ret != TDM_ERROR_NONE && client_ != NULL ) {
111+ if (ret != TDM_ERROR_NONE) {
136112 FT_LOG (Error) << " Failed to create a TDM client." ;
137- return false ;
113+ return ;
138114 }
139115
140116 output_ = tdm_client_get_output (client_, const_cast <char *>(" default" ), &ret);
141- if (ret != TDM_ERROR_NONE && output_ != NULL ) {
117+ if (ret != TDM_ERROR_NONE) {
142118 FT_LOG (Error) << " Could not obtain the default client output." ;
143- return false ;
119+ return ;
144120 }
145121
146122 vblank_ = tdm_client_output_create_vblank (output_, &ret);
147- if (ret != TDM_ERROR_NONE && vblank_ != NULL ) {
123+ if (ret != TDM_ERROR_NONE) {
148124 FT_LOG (Error) << " Failed to create a vblank object." ;
149- return false ;
125+ return ;
150126 }
151-
152127 tdm_client_vblank_set_enable_fake (vblank_, 1 );
153- return true ;
128+
129+ engine_ = engine;
154130}
155131
156- void TdmClient::DestroyTdm () {
132+ TdmClient::~TdmClient () {
133+ {
134+ std::lock_guard<std::mutex> lock (engine_mutex_);
135+ engine_ = nullptr ;
136+ }
157137 if (vblank_) {
158138 tdm_client_vblank_destroy (vblank_);
159139 vblank_ = nullptr ;
@@ -165,6 +145,16 @@ void TdmClient::DestroyTdm() {
165145 }
166146}
167147
148+ void TdmClient::AwaitVblank (intptr_t baton) {
149+ baton_ = baton;
150+ tdm_error ret = tdm_client_vblank_wait (vblank_, 1 , VblankCallback, this );
151+ if (ret != TDM_ERROR_NONE) {
152+ FT_LOG (Error) << " tdm_client_vblank_wait failed with error: " << ret;
153+ return ;
154+ }
155+ tdm_client_handle_events (client_);
156+ }
157+
168158bool TdmClient::IsValid () {
169159 return vblank_ && client_;
170160}
@@ -175,14 +165,15 @@ void TdmClient::VblankCallback(tdm_client_vblank* vblank,
175165 unsigned int tv_sec,
176166 unsigned int tv_usec,
177167 void * user_data) {
178- TdmClient* client = reinterpret_cast <TdmClient*>(user_data);
179- FT_ASSERT (client != nullptr );
180- std::lock_guard<std::mutex> lock (client->engine_mutex_ );
181- if (client->engine_ ) {
168+ auto * self = reinterpret_cast <TdmClient*>(user_data);
169+ FT_ASSERT (self != nullptr );
170+
171+ std::lock_guard<std::mutex> lock (self->engine_mutex_ );
172+ if (self->engine_ ) {
182173 uint64_t frame_start_time_nanos = tv_sec * 1e9 + tv_usec * 1e3 ;
183174 uint64_t frame_target_time_nanos = 16.6 * 1e6 + frame_start_time_nanos;
184- client ->engine_ ->OnVsync (client ->baton_ , frame_start_time_nanos,
185- frame_target_time_nanos);
175+ self ->engine_ ->OnVsync (self ->baton_ , frame_start_time_nanos,
176+ frame_target_time_nanos);
186177 }
187178}
188179
0 commit comments