• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ui/rs_ui_director.h"
17 
18 #include "rs_trace.h"
19 #include "sandbox_utils.h"
20 
21 #include "animation/rs_animation_trace_utils.h"
22 #include "command/rs_message_processor.h"
23 #include "command/rs_node_command.h"
24 #include "hyper_graphic_manager/core/utils/hgm_command.h"
25 #include "modifier/rs_modifier_manager.h"
26 #include "modifier/rs_modifier_manager_map.h"
27 #include "pipeline/rs_node_map.h"
28 #include "pipeline/rs_render_thread.h"
29 #include "platform/common/rs_log.h"
30 #include "rs_frame_report.h"
31 #include "transaction/rs_application_agent_impl.h"
32 #include "transaction/rs_interfaces.h"
33 #include "transaction/rs_transaction.h"
34 #include "transaction/rs_transaction_proxy.h"
35 #include "feature/hyper_graphic_manager/rs_frame_rate_policy.h"
36 #include "ui/rs_root_node.h"
37 #include "ui/rs_surface_extractor.h"
38 #include "ui/rs_surface_node.h"
39 #include "ui/rs_ui_context.h"
40 #include "ui/rs_ui_context_manager.h"
41 
42 #ifdef _WIN32
43 #include <windows.h>
44 #define gettid GetCurrentThreadId
45 #endif
46 
47 #ifdef __APPLE__
48 #define gettid getpid
49 #endif
50 
51 #ifdef __gnu_linux__
52 #include <sys/types.h>
53 #include <sys/syscall.h>
54 #define gettid []() -> int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); }
55 #endif
56 
57 namespace OHOS {
58 namespace Rosen {
59 std::function<void()> RSUIDirector::requestVsyncCallback_ = nullptr;
60 static std::mutex g_vsyncCallbackMutex;
61 static std::once_flag g_initDumpNodeTreeProcessorFlag;
62 
Create()63 std::shared_ptr<RSUIDirector> RSUIDirector::Create()
64 {
65     return std::shared_ptr<RSUIDirector>(new RSUIDirector());
66 }
67 
~RSUIDirector()68 RSUIDirector::~RSUIDirector()
69 {
70     Destroy();
71 }
72 
Init(bool shouldCreateRenderThread,bool isMultiInstance)73 void RSUIDirector::Init(bool shouldCreateRenderThread, bool isMultiInstance)
74 {
75     AnimationCommandHelper::SetAnimationCallbackProcessor(AnimationCallbackProcessor);
76     std::call_once(g_initDumpNodeTreeProcessorFlag,
77         []() { RSNodeCommandHelper::SetDumpNodeTreeProcessor(RSUIDirector::DumpNodeTreeProcessor); });
78     if (isMultiInstance) {
79         rsUIContext_ = RSUIContextManager::MutableInstance().CreateRSUIContext();
80     }
81 
82     isUniRenderEnabled_ = RSSystemProperties::GetUniRenderEnabled();
83     if (shouldCreateRenderThread && !isUniRenderEnabled_) {
84         auto renderThreadClient = RSIRenderClient::CreateRenderThreadClient();
85         if (rsUIContext_ != nullptr) {
86             auto transaction = rsUIContext_->GetRSTransaction();
87             if (transaction != nullptr) {
88                 transaction->SetRenderThreadClient(renderThreadClient);
89             }
90         } else {
91             auto transactionProxy = RSTransactionProxy::GetInstance();
92             if (transactionProxy != nullptr) {
93                 transactionProxy->SetRenderThreadClient(renderThreadClient);
94             }
95         }
96 
97         RsFrameReport::GetInstance().Init();
98         if (!cacheDir_.empty()) {
99             RSRenderThread::Instance().SetCacheDir(cacheDir_);
100         }
101         RSRenderThread::Instance().Start();
102     } else {
103         // force fallback animaiions send to RS if no render thread
104         RSNodeMap::Instance().GetAnimationFallbackNode()->isRenderServiceNode_ = true; // ToDo
105     }
106     if (!cacheDir_.empty()) {
107         RSRenderThread::Instance().SetCacheDir(cacheDir_);
108     }
109     if (auto rsApplicationAgent = RSApplicationAgentImpl::Instance()) {
110         rsApplicationAgent->RegisterRSApplicationAgent();
111     }
112 
113     GoForeground();
114     RSInterpolator::Init();
115 }
116 
SetFlushEmptyCallback(FlushEmptyCallback flushEmptyCallback)117 void RSUIDirector::SetFlushEmptyCallback(FlushEmptyCallback flushEmptyCallback)
118 {
119     if (rsUIContext_) {
120         auto transaction = rsUIContext_->GetRSTransaction();
121         if (transaction != nullptr) {
122             transaction->SetFlushEmptyCallback(flushEmptyCallback);
123         }
124     } else {
125         auto transactionProxy = RSTransactionProxy::GetInstance();
126         if (transactionProxy != nullptr) {
127             transactionProxy->SetFlushEmptyCallback(flushEmptyCallback);
128         }
129     }
130 }
131 
StartTextureExport()132 void RSUIDirector::StartTextureExport()
133 {
134     isUniRenderEnabled_ = RSSystemProperties::GetUniRenderEnabled();
135     if (isUniRenderEnabled_) {
136         auto renderThreadClient = RSIRenderClient::CreateRenderThreadClient();
137         if (rsUIContext_) {
138             auto transaction = rsUIContext_->GetRSTransaction();
139             if (transaction != nullptr) {
140                 transaction->SetRenderThreadClient(renderThreadClient);
141             }
142         } else {
143             auto transactionProxy = RSTransactionProxy::GetInstance();
144             if (transactionProxy != nullptr) {
145                 transactionProxy->SetRenderThreadClient(renderThreadClient);
146             }
147         }
148         RSRenderThread::Instance().Start();
149     }
150     RSRenderThread::Instance().UpdateWindowStatus(true);
151 }
152 
GoForeground(bool isTextureExport)153 void RSUIDirector::GoForeground(bool isTextureExport)
154 {
155     ROSEN_LOGD("RSUIDirector::GoForeground");
156     if (!isActive_) {
157         if (!isUniRenderEnabled_ || isTextureExport) {
158             RSRenderThread::Instance().UpdateWindowStatus(true);
159         }
160         isActive_ = true;
161         auto node = rsUIContext_ ? rsUIContext_->GetNodeMap().GetNode<RSRootNode>(root_)
162                                  : RSNodeMap::Instance().GetNode<RSRootNode>(root_);
163         if (node) {
164             node->SetEnableRender(true);
165         }
166         auto surfaceNode = surfaceNode_.lock();
167         if (surfaceNode) {
168             surfaceNode->MarkUIHidden(false);
169             surfaceNode->SetAbilityState(RSSurfaceNodeAbilityState::FOREGROUND);
170         }
171     }
172 }
173 
GoBackground(bool isTextureExport)174 void RSUIDirector::GoBackground(bool isTextureExport)
175 {
176     ROSEN_LOGD("RSUIDirector::GoBackground");
177     if (isActive_) {
178         if (!isUniRenderEnabled_ || isTextureExport) {
179             RSRenderThread::Instance().UpdateWindowStatus(false);
180         }
181         isActive_ = false;
182         auto node = rsUIContext_ ? rsUIContext_->GetNodeMap().GetNode<RSRootNode>(root_)
183                                  : RSNodeMap::Instance().GetNode<RSRootNode>(root_);
184         if (node) {
185             node->SetEnableRender(false);
186         }
187         auto surfaceNode = surfaceNode_.lock();
188         if (surfaceNode) {
189             surfaceNode->MarkUIHidden(true);
190             surfaceNode->SetAbilityState(RSSurfaceNodeAbilityState::BACKGROUND);
191         }
192         if (isTextureExport || isUniRenderEnabled_) {
193             return;
194         }
195         // clean bufferQueue cache
196         RSRenderThread::Instance().PostTask([surfaceNode]() {
197             if (surfaceNode != nullptr) {
198                 std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode);
199                 if (rsSurface == nullptr) {
200                     ROSEN_LOGE("rsSurface is nullptr");
201                     return;
202                 }
203                 rsSurface->ClearBuffer();
204             }
205         });
206 #if defined(ACE_ENABLE_GL) || defined(ACE_ENABLE_VK)
207         RSRenderThread::Instance().PostTask([this]() {
208             auto renderContext = RSRenderThread::Instance().GetRenderContext();
209             if (renderContext != nullptr) {
210 #ifndef ROSEN_CROSS_PLATFORM
211                 renderContext->ClearRedundantResources();
212 #endif
213             }
214         });
215 #endif
216     }
217 }
218 
Destroy(bool isTextureExport)219 void RSUIDirector::Destroy(bool isTextureExport)
220 {
221     if (root_ != 0) {
222         if (!isUniRenderEnabled_ || isTextureExport) {
223             auto node = rsUIContext_ ? rsUIContext_->GetNodeMap().GetNode<RSRootNode>(root_)
224                                  : RSNodeMap::Instance().GetNode<RSRootNode>(root_);
225             if (node) {
226                 node->RemoveFromTree();
227             }
228         }
229         root_ = 0;
230     }
231     GoBackground(isTextureExport);
232     SendMessages();
233     if (rsUIContext_ != nullptr) {
234         RSUIContextManager::MutableInstance().DestroyContext(rsUIContext_->GetToken());
235         rsUIContext_ = nullptr;
236     }
237     std::unique_lock<std::mutex> lock(uiTaskRunnersVisitorMutex_);
238     uiTaskRunners_.erase(this); // to del
239 }
240 
SetRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode)241 void RSUIDirector::SetRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode)
242 {
243     surfaceNode_ = surfaceNode;
244     AttachSurface();
245 }
246 
SetAbilityBGAlpha(uint8_t alpha)247 void RSUIDirector::SetAbilityBGAlpha(uint8_t alpha)
248 {
249     auto node = surfaceNode_.lock();
250     if (!node) {
251         ROSEN_LOGI("RSUIDirector::SetAbilityBGAlpha, surfaceNode_ is nullptr");
252         return;
253     }
254     node->SetAbilityBGAlpha(alpha);
255 }
256 
SetRTRenderForced(bool isRenderForced)257 void RSUIDirector::SetRTRenderForced(bool isRenderForced)
258 {
259     RSRenderThread::Instance().SetRTRenderForced(isRenderForced);
260 }
261 
SetContainerWindow(bool hasContainerWindow,RRect rrect)262 void RSUIDirector::SetContainerWindow(bool hasContainerWindow, RRect rrect)
263 {
264     auto node = surfaceNode_.lock();
265     if (!node) {
266         ROSEN_LOGI("RSUIDirector::SetContainerWindow, surfaceNode_ is nullptr");
267         return;
268     }
269     node->SetContainerWindow(hasContainerWindow, rrect);
270 }
271 
SetRoot(NodeId root)272 void RSUIDirector::SetRoot(NodeId root)
273 {
274     if (root_ == root) {
275         ROSEN_LOGW("RSUIDirector::SetRoot, root_ is not change");
276         return;
277     }
278     root_ = root;
279     AttachSurface();
280 }
281 
AttachSurface()282 void RSUIDirector::AttachSurface()
283 {
284     auto node = rsUIContext_ ? rsUIContext_->GetNodeMap().GetNode<RSRootNode>(root_)
285                                  : RSNodeMap::Instance().GetNode<RSRootNode>(root_);
286     auto surfaceNode = surfaceNode_.lock();
287     if (node != nullptr && surfaceNode != nullptr) {
288         node->AttachRSSurfaceNode(surfaceNode);
289         ROSEN_LOGD("RSUIDirector::AttachSurface [%{public}" PRIu64, surfaceNode->GetId());
290     } else {
291         ROSEN_LOGD("RSUIDirector::AttachSurface not ready");
292     }
293 }
294 
SetAppFreeze(bool isAppFreeze)295 void RSUIDirector::SetAppFreeze(bool isAppFreeze)
296 {
297     auto surfaceNode = surfaceNode_.lock();
298     if (surfaceNode != nullptr) {
299         surfaceNode->SetFreeze(isAppFreeze);
300     }
301 }
302 
SetRequestVsyncCallback(const std::function<void ()> & callback)303 void RSUIDirector::SetRequestVsyncCallback(const std::function<void()>& callback)
304 {
305     std::unique_lock<std::mutex> lock(g_vsyncCallbackMutex);
306     requestVsyncCallback_ = callback;
307 }
308 
SetTimeStamp(uint64_t timeStamp,const std::string & abilityName)309 void RSUIDirector::SetTimeStamp(uint64_t timeStamp, const std::string& abilityName)
310 {
311     timeStamp_ = timeStamp;
312     abilityName_ = abilityName;
313 }
314 
SetCacheDir(const std::string & cacheFilePath)315 void RSUIDirector::SetCacheDir(const std::string& cacheFilePath)
316 {
317     cacheDir_ = cacheFilePath;
318 }
319 
FlushAnimation(uint64_t timeStamp,int64_t vsyncPeriod)320 bool RSUIDirector::FlushAnimation(uint64_t timeStamp, int64_t vsyncPeriod)
321 {
322     auto modifierManager = rsUIContext_ ? rsUIContext_->GetRSModifierManager()
323                                         : RSModifierManagerMap::Instance()->GetModifierManager(gettid());
324     if (modifierManager != nullptr) {
325         modifierManager->SetDisplaySyncEnable(true);
326         modifierManager->SetFrameRateGetFunc(
327             [](const RSPropertyUnit unit, float velocity, int32_t area, int length) -> int32_t {
328                 return RSFrameRatePolicy::GetInstance()->GetExpectedFrameRate(unit, velocity);
329             }
330         );
331         return modifierManager->Animate(timeStamp, vsyncPeriod);
332     }
333     return false;
334 }
335 
HasFirstFrameAnimation()336 bool RSUIDirector::HasFirstFrameAnimation()
337 {
338     auto modifierManager = rsUIContext_ ? rsUIContext_->GetRSModifierManager()
339                                         : RSModifierManagerMap::Instance()->GetModifierManager(gettid());
340     if (modifierManager != nullptr) {
341         return modifierManager->GetAndResetFirstFrameAnimationState();
342     }
343     return false;
344 }
345 
FlushAnimationStartTime(uint64_t timeStamp)346 void RSUIDirector::FlushAnimationStartTime(uint64_t timeStamp)
347 {
348     auto modifierManager = rsUIContext_ ? rsUIContext_->GetRSModifierManager()
349                                         : RSModifierManagerMap::Instance()->GetModifierManager(gettid());
350     if (modifierManager != nullptr) {
351         modifierManager->FlushStartAnimation(timeStamp);
352     }
353 }
354 
FlushModifier()355 void RSUIDirector::FlushModifier()
356 {
357     auto modifierManager = rsUIContext_ ? rsUIContext_->GetRSModifierManager()
358                                         : RSModifierManagerMap::Instance()->GetModifierManager(gettid());
359     if (modifierManager == nullptr) {
360         return;
361     }
362 
363     modifierManager->Draw();
364     // post animation finish callback(s) to task queue
365     RSUIDirector::RecvMessages();
366 }
367 
HasUIRunningAnimation()368 bool RSUIDirector::HasUIRunningAnimation()
369 {
370     auto modifierManager = rsUIContext_ ? rsUIContext_->GetRSModifierManager()
371                                         : RSModifierManagerMap::Instance()->GetModifierManager(gettid());
372     if (modifierManager != nullptr) {
373         return modifierManager->HasUIRunningAnimation();
374     }
375     return false;
376 }
377 
SetUITaskRunner(const TaskRunner & uiTaskRunner,int32_t instanceId,bool useMultiInstance)378 void RSUIDirector::SetUITaskRunner(const TaskRunner& uiTaskRunner, int32_t instanceId, bool useMultiInstance)
379 {
380     if (!useMultiInstance) {
381         std::unique_lock<std::mutex> lock(uiTaskRunnersVisitorMutex_);
382         instanceId_ = instanceId;
383         uiTaskRunners_[this] = uiTaskRunner;
384         if (!isHgmConfigChangeCallbackReg_) {
385             RSFrameRatePolicy::GetInstance()->RegisterHgmConfigChangeCallback();
386             isHgmConfigChangeCallbackReg_ = true;
387         }
388         return;
389     }
390 
391     if (rsUIContext_ == nullptr) {
392         ROSEN_LOGD("multi-instance, RSUIDirector::SetUITaskRunner, rsUIContext_ is null!");
393         return;
394     }
395     if (!isHgmConfigChangeCallbackReg_) {
396         RSFrameRatePolicy::GetInstance()->RegisterHgmConfigChangeCallback();
397         isHgmConfigChangeCallbackReg_ = true;
398     }
399 }
400 
SendMessages()401 void RSUIDirector::SendMessages()
402 {
403     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "SendCommands");
404     if (rsUIContext_) {
405         auto transaction = rsUIContext_->GetRSTransaction();
406         if (transaction != nullptr) {
407             transaction->FlushImplicitTransaction(timeStamp_, abilityName_);
408             index_ = transaction->GetTransactionDataIndex();
409         } else {
410             RS_LOGE_LIMIT(__func__, __line__, "RSUIDirector::SendMessages failed, transaction is nullptr");
411         }
412     } else {
413         auto transactionProxy = RSTransactionProxy::GetInstance();
414         if (transactionProxy != nullptr) {
415             transactionProxy->FlushImplicitTransaction(timeStamp_, abilityName_);
416             index_ = transactionProxy->GetTransactionDataIndex();
417         } else {
418             RS_LOGE_LIMIT(__func__, __line__, "RSUIDirector::SendMessages failed, transactionProxy is nullptr");
419         }
420     }
421     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
422 }
423 
GetIndex() const424 uint32_t RSUIDirector::GetIndex() const
425 {
426     return index_;
427 }
428 
GetRSUIContext() const429 std::shared_ptr<RSUIContext> RSUIDirector::GetRSUIContext() const
430 {
431     return rsUIContext_;
432 }
433 
RecvMessages()434 void RSUIDirector::RecvMessages()
435 {
436     if (GetRealPid() == -1) {
437         return;
438     }
439     static const uint32_t pid = static_cast<uint32_t>(GetRealPid());
440     if (!RSMessageProcessor::Instance().HasTransaction(pid)) {
441         return;
442     }
443     auto transactionDataPtr = RSMessageProcessor::Instance().GetTransaction(pid);
444     RecvMessages(transactionDataPtr);
445 }
446 
RecvMessages(std::shared_ptr<RSTransactionData> cmds,bool useMultiInstance)447 void RSUIDirector::RecvMessages(std::shared_ptr<RSTransactionData> cmds, bool useMultiInstance)
448 {
449     if (cmds == nullptr || cmds->IsEmpty()) {
450         return;
451     }
452     ROSEN_LOGD("ProcessMessages begin");
453     RSUIDirector::ProcessMessages(cmds, useMultiInstance);
454 }
455 
ProcessMessages(std::shared_ptr<RSTransactionData> cmds)456 void RSUIDirector::ProcessMessages(std::shared_ptr<RSTransactionData> cmds)
457 {
458     // message ID for correspondence UI thread and IPC thread
459     static uint32_t messageId = 0;
460     std::map<int32_t, std::vector<std::unique_ptr<RSCommand>>> m;
461     for (auto &[id, _, cmd] : cmds->GetPayload()) {
462         NodeId realId = (id == 0 && cmd) ? cmd->GetNodeId() : id;
463         int32_t instanceId = RSNodeMap::Instance().GetNodeInstanceId(realId); // ToDo
464         if (instanceId == INSTANCE_ID_UNDEFINED) {
465             instanceId = RSNodeMap::Instance().GetInstanceIdForReleasedNode(realId); // ToDo
466         }
467         m[instanceId].push_back(std::move(cmd));
468     }
469     auto msgId = ++messageId;
470     RS_TRACE_NAME_FMT("RSUIDirector::ProcessMessages Post [messageId:%lu,cmdIndex:%llu,cmdCount:%lu]",
471         msgId, cmds->GetIndex(), cmds->GetCommandCount());
472     auto counter = std::make_shared<std::atomic_size_t>(m.size());
473     for (auto &[instanceId, commands] : m) {
474         ROSEN_LOGI("Post messageId:%{public}d, cmdCount:%{public}lu, instanceId:%{public}d", msgId,
475             static_cast<unsigned long>(commands.size()), instanceId);
476         PostTask(
477             [cmds = std::make_shared<std::vector<std::unique_ptr<RSCommand>>>(std::move(commands)),
478                 counter, msgId, tempInstanceId = instanceId] {
479                 RS_TRACE_NAME_FMT("RSUIDirector::ProcessMessages Process messageId:%lu", msgId);
480                 ROSEN_LOGI("Process messageId:%{public}d, cmdCount:%{public}lu, instanceId:%{public}d",
481                     msgId, static_cast<unsigned long>(cmds->size()), tempInstanceId);
482                 for (auto &cmd : *cmds) {
483                     RSContext context; // RSCommand->process() needs it
484                     cmd->Process(context);
485                 }
486                 if (counter->fetch_sub(1) == 1) {
487                     std::unique_lock<std::mutex> lock(g_vsyncCallbackMutex);
488                     if (requestVsyncCallback_ != nullptr) {
489                         requestVsyncCallback_();
490                     } else {
491                         RSTransaction::FlushImplicitTransaction();
492                     }
493                     ROSEN_LOGD("ProcessMessages end");
494                 }
495             }, instanceId);
496     }
497 }
498 
ProcessMessages(std::shared_ptr<RSTransactionData> cmds,bool useMultiInstance)499 void RSUIDirector::ProcessMessages(std::shared_ptr<RSTransactionData> cmds, bool useMultiInstance)
500 {
501     if (!useMultiInstance) {
502         ProcessMessages(cmds);
503         return;
504     }
505     static uint32_t messageId = 0;
506     std::map<uint64_t, std::vector<std::unique_ptr<RSCommand>>> cmdMap;
507     for (auto& [id, _, cmd] : cmds->GetPayload()) {
508         uint64_t token = cmd->GetToken();
509         cmdMap[token].push_back(std::move(cmd));
510     }
511     auto msgId = ++messageId;
512     RS_TRACE_NAME_FMT("RSUIDirector::ProcessMessages Post [messageId:%lu,cmdIndex:%llu,cmdCount:%lu]",
513         msgId, cmds->GetIndex(), cmds->GetCommandCount());
514     auto counter = std::make_shared<std::atomic_size_t>(cmdMap.size());
515     for (auto& [token, commands] : cmdMap) {
516         ROSEN_LOGI("Post messageId:%{public}d, cmdCount:%{public}lu, token:%{public}" PRIu64, msgId,
517             static_cast<unsigned long>(commands.size()), token);
518         auto rsUICtx = RSUIContextManager::Instance().GetRSUIContext(token);
519         if (rsUICtx == nullptr) {
520             ROSEN_LOGI("RSUIDirector::ProcessMessages, can not get rsUIContext with token:%{public}" PRIu64 "", token);
521             return;
522         }
523         rsUICtx->PostTask([cmds = std::make_shared<std::vector<std::unique_ptr<RSCommand>>>(std::move(commands)),
524                               counter, msgId, tempToken = token, &rsUICtx] {
525             RS_TRACE_NAME_FMT("RSUIDirector::ProcessMessages Process messageId:%lu", msgId);
526             ROSEN_LOGI("Process messageId:%{public}d, cmdCount:%{public}lu, token:%{public}" PRIu64, msgId,
527                 static_cast<unsigned long>(cmds->size()), tempToken);
528             for (auto& cmd : *cmds) {
529                 RSContext context; // RSCommand->process() needs it
530                 cmd->Process(context);
531             }
532             if (counter->fetch_sub(1) == 1) {
533                 std::unique_lock<std::mutex> lock(g_vsyncCallbackMutex);
534                 if (requestVsyncCallback_ != nullptr) {
535                     requestVsyncCallback_();
536                 } else {
537                     rsUICtx->GetRSTransaction()->FlushImplicitTransaction();
538                 }
539                 ROSEN_LOGD("ProcessMessages end");
540             }
541         });
542     }
543 }
544 
AnimationCallbackProcessor(NodeId nodeId,AnimationId animId,uint64_t token,AnimationCallbackEvent event)545 void RSUIDirector::AnimationCallbackProcessor(NodeId nodeId, AnimationId animId, uint64_t token,
546     AnimationCallbackEvent event)
547 {
548     RSAnimationTraceUtils::GetInstance().addAnimationFinishTrace(
549         "Animation FinishCallback Processor", nodeId, animId, false);
550     auto rsUIContext = RSUIContextManager::Instance().GetRSUIContext(token);
551     // try find the node by nodeId
552     if (auto nodePtr = rsUIContext ? rsUIContext->GetNodeMap().GetNode<RSNode>(nodeId)
553                                    : RSNodeMap::Instance().GetNode<RSNode>(nodeId)) {
554         if (!nodePtr->AnimationCallback(animId, event)) {
555             ROSEN_LOGE("RSUIDirector::AnimationCallbackProcessor, could not find animation %{public}" PRIu64 ""
556                 "on node %{public}" PRIu64, animId, nodeId);
557         }
558         return;
559     }
560 
561     // if node not found, try rsUIContext
562     if (rsUIContext && rsUIContext->AnimationCallback(animId, event)) {
563         ROSEN_LOGD("multi-instance, RSUIDirector::AnimationCallbackProcessor, found animation %{public}" PRIu64
564                    " on fallback node.", animId);
565         return;
566     }
567     // if node not found, try fallback node
568     auto& fallbackNode = RSNodeMap::Instance().GetAnimationFallbackNode(); // ToDo
569     if (fallbackNode && fallbackNode->AnimationCallback(animId, event)) {
570         ROSEN_LOGD("RSUIDirector::AnimationCallbackProcessor, found animation %{public}" PRIu64 " on fallback node.",
571             animId);
572     } else {
573         ROSEN_LOGE("RSUIDirector::AnimationCallbackProcessor, could not find animation %{public}" PRIu64 " on"
574             " fallback node.", animId);
575     }
576 }
577 
DumpNodeTreeProcessor(NodeId nodeId,pid_t pid,uint32_t taskId)578 void RSUIDirector::DumpNodeTreeProcessor(NodeId nodeId, pid_t pid, uint32_t taskId)
579 {
580     RS_TRACE_NAME_FMT("DumpClientNodeTree dump task[%u] node[%" PRIu64 "]", taskId, nodeId);
581     ROSEN_LOGI("DumpNodeTreeProcessor task[%{public}u] node[%" PRIu64 "]", taskId, nodeId);
582 
583     std::string out;
584     // use for dump transactionFlags [pid,index] in client tree dump
585     int32_t instanceId = RSNodeMap::Instance().GetNodeInstanceId(nodeId); // DFX ToDo
586     {
587         std::unique_lock<std::mutex> lock(uiTaskRunnersVisitorMutex_);
588         for (const auto &[director, taskRunner] : uiTaskRunners_) {
589             if (director->instanceId_ == instanceId) {
590                 out.append("transactionFlags:[ ").append(std::to_string(pid).append(", ")
591                     .append(std::to_string(director->index_)).append("]\r"));
592                 break;
593             }
594         }
595     }
596 
597     if (auto node = RSNodeMap::Instance().GetNode(nodeId)) { // DFX ToDo
598         constexpr int TOP_LEVEL_DEPTH = 1;
599         node->DumpTree(TOP_LEVEL_DEPTH, out);
600     }
601 
602     auto transactionProxy = RSTransactionProxy::GetInstance(); // planing
603     if (transactionProxy != nullptr) {
604         std::unique_ptr<RSCommand> command = std::make_unique<RSCommitDumpClientNodeTree>(
605             nodeId, getpid(), taskId, out);
606         transactionProxy->AddCommand(command, true);
607         RSTransaction::FlushImplicitTransaction();
608     }
609 }
610 
PostFrameRateTask(const std::function<void ()> & task,bool useMultiInstance)611 void RSUIDirector::PostFrameRateTask(const std::function<void()>& task, bool useMultiInstance)
612 {
613     if (!useMultiInstance) {
614         PostTask(task);
615         return;
616     }
617     auto ctx = RSUIContextManager::Instance().GetRandomUITaskRunnerCtx();
618     if (ctx == nullptr) {
619         ROSEN_LOGD("multi-instance RSUIDirector::PostFrameRateTask, no taskRunner exists");
620         return;
621     }
622     ctx->PostTask(task);
623 }
624 
PostTask(const std::function<void ()> & task,int32_t instanceId)625 void RSUIDirector::PostTask(const std::function<void()>& task, int32_t instanceId)
626 {
627     PostDelayTask(task, 0, instanceId);
628 }
629 
PostDelayTask(const std::function<void ()> & task,uint32_t delay,int32_t instanceId)630 void RSUIDirector::PostDelayTask(const std::function<void()>& task, uint32_t delay, int32_t instanceId)
631 {
632     std::unique_lock<std::mutex> lock(uiTaskRunnersVisitorMutex_);
633     for (const auto &[director, taskRunner] : uiTaskRunners_) {
634         if (director->instanceId_ != instanceId) {
635             continue;
636         }
637         ROSEN_LOGD("RSUIDirector::PostTask instanceId=%{public}d success", instanceId);
638         taskRunner(task, delay);
639         return;
640     }
641     if (instanceId != INSTANCE_ID_UNDEFINED) {
642         ROSEN_LOGW("RSUIDirector::PostTask instanceId=%{public}d not found", instanceId);
643     }
644     for (const auto &[_, taskRunner] : uiTaskRunners_) {
645         ROSEN_LOGD("RSUIDirector::PostTask success");
646         taskRunner(task, delay);
647         return;
648     }
649 }
650 
GetCurrentRefreshRateMode()651 int32_t RSUIDirector::GetCurrentRefreshRateMode()
652 {
653     return RSFrameRatePolicy::GetInstance()->GetRefreshRateModeName();
654 }
655 
GetAnimateExpectedRate() const656 int32_t RSUIDirector::GetAnimateExpectedRate() const
657 {
658     int32_t animateRate = 0;
659     auto modifierManager = RSModifierManagerMap::Instance()->GetModifierManager(gettid());
660     if (modifierManager != nullptr) {
661         auto& range = modifierManager->GetFrameRateRange();
662         if (range.IsValid()) {
663             animateRate = range.preferred_;
664         }
665     }
666     return animateRate;
667 }
668 } // namespace Rosen
669 } // namespace OHOS
670