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