1 /*
2 * Copyright (c) 2021-2023 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 #include "pipeline/rs_main_thread.h"
16
17 #include <SkGraphics.h>
18 #include <securec.h>
19 #include "rs_trace.h"
20
21 #include "animation/rs_animation_fraction.h"
22 #include "command/rs_message_processor.h"
23 #include "delegate/rs_functional_delegate.h"
24
25 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
26 #include "pipeline/rs_base_render_node.h"
27 #include "pipeline/rs_base_render_util.h"
28 #include "pipeline/rs_cold_start_thread.h"
29 #include "pipeline/rs_divided_render_util.h"
30 #include "pipeline/rs_render_engine.h"
31 #include "pipeline/rs_render_service_visitor.h"
32 #include "pipeline/rs_root_render_node.h"
33 #include "pipeline/rs_surface_render_node.h"
34 #include "pipeline/rs_unmarshal_thread.h"
35 #include "pipeline/rs_uni_render_engine.h"
36 #include "pipeline/rs_uni_render_visitor.h"
37 #include "pipeline/rs_occlusion_config.h"
38 #include "platform/common/rs_log.h"
39 #include "platform/common/rs_innovation.h"
40 #include "platform/drawing/rs_vsync_client.h"
41 #include "property/rs_property_trace.h"
42 #include "property/rs_properties_painter.h"
43 #include "screen_manager/rs_screen_manager.h"
44 #include "socperf_client.h"
45 #include "transaction/rs_transaction_proxy.h"
46 #include "accessibility_config.h"
47 #include "rs_qos_thread.h"
48 #include "xcollie/watchdog.h"
49
50 #include "render_frame_trace.h"
51
52 using namespace FRAME_TRACE;
53 static const std::string RS_INTERVAL_NAME = "renderservice";
54
55 using namespace OHOS::AccessibilityConfig;
56 namespace OHOS {
57 namespace Rosen {
58 namespace {
59 constexpr uint32_t RUQUEST_VSYNC_NUMBER_LIMIT = 10;
60 constexpr uint64_t REFRESH_PERIOD = 16666667;
61 constexpr int32_t PERF_ANIMATION_REQUESTED_CODE = 10017;
62 constexpr int32_t PERF_MULTI_WINDOW_REQUESTED_CODE = 10026;
63 constexpr uint64_t PERF_PERIOD = 250000000;
64 constexpr uint64_t CLEAN_CACHE_FREQ = 60;
65 constexpr uint64_t SKIP_COMMAND_FREQ_LIMIT = 30;
66 constexpr uint64_t PERF_PERIOD_BLUR = 80000000;
67 constexpr uint64_t PERF_PERIOD_MULTI_WINDOW = 80000000;
68 constexpr uint32_t MULTI_WINDOW_PERF_START_NUM = 2;
69 constexpr uint32_t MULTI_WINDOW_PERF_END_NUM = 4;
70 const std::map<int, int32_t> BLUR_CNT_TO_BLUR_CODE {
71 { 1, 10021 },
72 { 2, 10022 },
73 { 3, 10023 },
74 };
75
Compare(const std::unique_ptr<RSTransactionData> & data1,const std::unique_ptr<RSTransactionData> & data2)76 bool Compare(const std::unique_ptr<RSTransactionData>& data1, const std::unique_ptr<RSTransactionData>& data2)
77 {
78 if (!data1 || !data2) {
79 RS_LOGW("Compare RSTransactionData: nullptr!");
80 return true;
81 }
82 return data1->GetIndex() < data2->GetIndex();
83 }
84
InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>> & source,std::vector<std::unique_ptr<RSTransactionData>> & target)85 void InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>>& source,
86 std::vector<std::unique_ptr<RSTransactionData>>& target)
87 {
88 target.insert(target.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.end()));
89 source.clear();
90 }
91 }
92
93 class AccessibilityObserver : public AccessibilityConfigObserver {
94 public:
95 AccessibilityObserver() = default;
OnConfigChanged(const CONFIG_ID id,const ConfigValue & value)96 void OnConfigChanged(const CONFIG_ID id, const ConfigValue &value) override
97 {
98 RS_LOGD("AccessibilityObserver OnConfigChanged");
99 ColorFilterMode mode = ColorFilterMode::COLOR_FILTER_END;
100 if (id == CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER) {
101 switch (value.daltonizationColorFilter) {
102 case Protanomaly:
103 mode = ColorFilterMode::DALTONIZATION_PROTANOMALY_MODE;
104 break;
105 case Deuteranomaly:
106 mode = ColorFilterMode::DALTONIZATION_DEUTERANOMALY_MODE;
107 break;
108 case Tritanomaly:
109 mode = ColorFilterMode::DALTONIZATION_TRITANOMALY_MODE;
110 break;
111 case Normal:
112 mode = ColorFilterMode::DALTONIZATION_NORMAL_MODE;
113 break;
114 default:
115 break;
116 }
117 RSBaseRenderEngine::SetColorFilterMode(mode);
118 } else if (id == CONFIG_ID::CONFIG_INVERT_COLOR) {
119 mode = value.invertColor ? ColorFilterMode::INVERT_COLOR_ENABLE_MODE :
120 ColorFilterMode::INVERT_COLOR_DISABLE_MODE;
121 RSBaseRenderEngine::SetColorFilterMode(mode);
122 } else {
123 RSBaseRenderEngine::SetHighContrast(value.highContrastText);
124 }
125 }
126 };
127
Instance()128 RSMainThread* RSMainThread::Instance()
129 {
130 static RSMainThread instance;
131 RSAnimationFraction::Init();
132 return &instance;
133 }
134
RSMainThread()135 RSMainThread::RSMainThread() : mainThreadId_(std::this_thread::get_id())
136 {
137 context_ = std::make_shared<RSContext>();
138 }
139
~RSMainThread()140 RSMainThread::~RSMainThread() noexcept
141 {
142 RemoveRSEventDetector();
143 RSInnovation::CloseInnovationSo();
144 }
145
Init()146 void RSMainThread::Init()
147 {
148 mainLoop_ = [&]() {
149 RS_LOGD("RsDebug mainLoop start");
150 PerfMultiWindow();
151 RenderFrameTrace::GetInstance().RenderStartFrameTrace(RS_INTERVAL_NAME);
152 SetRSEventDetectorLoopStartTag();
153 ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSMainThread::DoComposition");
154 ConsumeAndUpdateAllNodes();
155 WaitUntilUnmarshallingTaskFinished();
156 ProcessCommand();
157 Animate(timestamp_);
158 CheckColdStartMap();
159 CheckDelayedSwitchTask();
160 Render();
161 ReleaseAllNodesBuffer();
162 SendCommands();
163 ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
164 SetRSEventDetectorLoopFinishTag();
165 rsEventManager_.UpdateParam();
166 RS_LOGD("RsDebug mainLoop end");
167 };
168
169 if (isUniRender_) {
170 unmarshalBarrierTask_ = [this]() {
171 auto cachedTransactionData = RSUnmarshalThread::Instance().GetCachedTransactionData();
172 MergeToEffectiveTransactionDataMap(cachedTransactionData);
173 {
174 std::lock_guard<std::mutex> lock(unmarshalMutex_);
175 ++unmarshalFinishedCount_;
176 }
177 unmarshalTaskCond_.notify_all();
178 };
179 RSUnmarshalThread::Instance().Start();
180 }
181
182 runner_ = AppExecFwk::EventRunner::Create(false);
183 handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
184 int ret = HiviewDFX::Watchdog::GetInstance().AddThread("RenderService", handler_);
185 if (ret != 0) {
186 RS_LOGW("Add watchdog thread failed");
187 }
188 InitRSEventDetector();
189 sptr<VSyncConnection> conn = new VSyncConnection(rsVSyncDistributor_, "rs");
190 rsVSyncDistributor_->AddConnection(conn);
191 receiver_ = std::make_shared<VSyncReceiver>(conn, handler_);
192 receiver_->Init();
193 renderEngine_ = std::make_shared<RSRenderEngine>();
194 uniRenderEngine_ = std::make_shared<RSUniRenderEngine>();
195 RSBaseRenderEngine::Init();
196 #ifdef RS_ENABLE_GL
197 int cacheLimitsTimes = 2; // double skia Resource Cache Limits
198 auto grContext = RSBaseRenderEngine::GetRenderContext()->GetGrContext();
199 int maxResources = 0;
200 size_t maxResourcesSize = 0;
201 grContext->getResourceCacheLimits(&maxResources, &maxResourcesSize);
202 grContext->setResourceCacheLimits(cacheLimitsTimes * maxResources, cacheLimitsTimes * maxResourcesSize);
203 #endif
204 RSInnovation::OpenInnovationSo();
205 Occlusion::Region::InitDynamicLibraryFunction();
206
207 accessibilityObserver_ = std::make_shared<AccessibilityObserver>();
208 auto &config = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
209 config.InitializeContext();
210 config.SubscribeConfigObserver(CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER, accessibilityObserver_);
211 config.SubscribeConfigObserver(CONFIG_ID::CONFIG_INVERT_COLOR, accessibilityObserver_);
212 if (isUniRender_) {
213 config.SubscribeConfigObserver(CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT, accessibilityObserver_);
214 }
215
216 auto delegate = RSFunctionalDelegate::Create();
217 delegate->SetRepaintCallback([]() { RSMainThread::Instance()->RequestNextVSync(); });
218 RSOverdrawController::GetInstance().SetDelegate(delegate);
219 }
220
RsEventParamDump(std::string & dumpString)221 void RSMainThread::RsEventParamDump(std::string& dumpString)
222 {
223 rsEventManager_.DumpAllEventParam(dumpString);
224 }
225
RemoveRSEventDetector()226 void RSMainThread::RemoveRSEventDetector()
227 {
228 if (rsCompositionTimeoutDetector_ != nullptr) {
229 rsEventManager_.RemoveEvent(rsCompositionTimeoutDetector_->GetStringId());
230 }
231 }
232
InitRSEventDetector()233 void RSMainThread::InitRSEventDetector()
234 {
235 // default Threshold value of Timeout Event: 100ms
236 rsCompositionTimeoutDetector_ = RSBaseEventDetector::CreateRSTimeOutDetector(100, "RS_COMPOSITION_TIMEOUT");
237 if (rsCompositionTimeoutDetector_ != nullptr) {
238 rsEventManager_.AddEvent(rsCompositionTimeoutDetector_, 60000); // report Internal 1min:60s:60000ms
239 RS_LOGD("InitRSEventDetector finish");
240 }
241 }
242
SetRSEventDetectorLoopStartTag()243 void RSMainThread::SetRSEventDetectorLoopStartTag()
244 {
245 if (rsCompositionTimeoutDetector_ != nullptr) {
246 rsCompositionTimeoutDetector_->SetLoopStartTag();
247 }
248 }
249
SetRSEventDetectorLoopFinishTag()250 void RSMainThread::SetRSEventDetectorLoopFinishTag()
251 {
252 if (rsCompositionTimeoutDetector_ != nullptr) {
253 if (IfUseUniVisitor()) {
254 rsCompositionTimeoutDetector_->SetLoopFinishTag(
255 focusAppPid_, focusAppUid_, focusAppBundleName_, focusAppAbilityName_);
256 } else {
257 std::string defaultFocusAppInfo = "";
258 rsCompositionTimeoutDetector_->SetLoopFinishTag(
259 -1, -1, defaultFocusAppInfo, defaultFocusAppInfo);
260 }
261 }
262 }
263
SetFocusAppInfo(int32_t pid,int32_t uid,const std::string & bundleName,const std::string & abilityName)264 void RSMainThread::SetFocusAppInfo(
265 int32_t pid, int32_t uid, const std::string &bundleName, const std::string &abilityName)
266 {
267 focusAppPid_ = pid;
268 focusAppUid_ = uid;
269 focusAppBundleName_ = bundleName;
270 focusAppAbilityName_ = abilityName;
271 }
272
Start()273 void RSMainThread::Start()
274 {
275 if (runner_) {
276 runner_->Run();
277 }
278 }
279
ProcessCommand()280 void RSMainThread::ProcessCommand()
281 {
282 // To improve overall responsiveness, we make animations start on LAST frame instead of THIS frame.
283 // If last frame is too far away (earlier than 1 vsync from now), we use currentTimestamp_ - REFRESH_PERIOD as
284 // 'virtual' last frame timestamp.
285 if (timestamp_ - lastAnimateTimestamp_ > REFRESH_PERIOD) { // if last frame is earlier than 1 vsync from now
286 context_->currentTimestamp_ = timestamp_ - REFRESH_PERIOD;
287 } else {
288 context_->currentTimestamp_ = lastAnimateTimestamp_;
289 }
290 if (!isUniRender_) { // divided render for all
291 ProcessCommandForDividedRender();
292 return;
293 }
294 CheckBufferAvailableIfNeed();
295 // dynamic switch
296 if (useUniVisitor_) {
297 ProcessCommandForDividedRender();
298 ProcessCommandForUniRender();
299 } else {
300 ProcessCommandForUniRender();
301 ProcessCommandForDividedRender();
302 }
303 CheckUpdateSurfaceNodeIfNeed();
304 }
305
ProcessCommandForUniRender()306 void RSMainThread::ProcessCommandForUniRender()
307 {
308 TransactionDataMap transactionDataEffective;
309 std::string transactionFlags;
310 {
311 std::lock_guard<std::mutex> lock(transitionDataMutex_);
312
313 for (auto& elem: effectiveTransactionDataIndexMap_) {
314 auto& transactionVec = elem.second.second;
315 std::sort(transactionVec.begin(), transactionVec.end(), Compare);
316 }
317
318 for (auto& rsTransactionElem: effectiveTransactionDataIndexMap_) {
319 auto pid = rsTransactionElem.first;
320 auto& lastIndex = rsTransactionElem.second.first;
321 auto& transactionVec = rsTransactionElem.second.second;
322 auto iter = transactionVec.begin();
323 for (; iter != transactionVec.end(); ++iter) {
324 if ((*iter) == nullptr) {
325 continue;
326 }
327 auto curIndex = (*iter)->GetIndex();
328 if (curIndex == lastIndex + 1) {
329 ++lastIndex;
330 transactionFlags += ", [" + std::to_string(pid) + ", " + std::to_string(curIndex) + "]";
331 } else {
332 RS_LOGE("RSMainThread::ProcessCommandForUniRender wait curIndex:%llu, lastIndex:%llu, pid:%d",
333 curIndex, lastIndex, pid);
334 if (transactionDataLastWaitTime_[pid] == 0) {
335 transactionDataLastWaitTime_[pid] = timestamp_;
336 }
337 if ((timestamp_ - transactionDataLastWaitTime_[pid]) / REFRESH_PERIOD > SKIP_COMMAND_FREQ_LIMIT) {
338 transactionDataLastWaitTime_[pid] = 0;
339 lastIndex = curIndex;
340 transactionFlags += ", skip to[" + std::to_string(pid) + ", " + std::to_string(curIndex) + "]";
341 RS_LOGE("RSMainThread::ProcessCommandForUniRender skip to index:%llu, pid:%d", curIndex, pid);
342 continue;
343 }
344 break;
345 }
346 }
347 transactionDataEffective[pid].insert(transactionDataEffective[pid].end(),
348 std::make_move_iterator(transactionVec.begin()), std::make_move_iterator(iter));
349 transactionVec.erase(transactionVec.begin(), iter);
350 }
351 }
352 RS_TRACE_NAME("RSMainThread::ProcessCommandUni" + transactionFlags);
353 for (auto& rsTransactionElem: transactionDataEffective) {
354 for (auto& rsTransaction: rsTransactionElem.second) {
355 if (rsTransaction) {
356 context_->transactionTimestamp_ = rsTransaction->GetTimestamp();
357 rsTransaction->Process(*context_);
358 }
359 }
360 }
361 }
362
ProcessCommandForDividedRender()363 void RSMainThread::ProcessCommandForDividedRender()
364 {
365 const auto& nodeMap = context_->GetNodeMap();
366 RS_TRACE_BEGIN("RSMainThread::ProcessCommand");
367 {
368 std::lock_guard<std::mutex> lock(transitionDataMutex_);
369 if (!pendingEffectiveCommands_.empty()) {
370 effectiveCommands_.swap(pendingEffectiveCommands_);
371 }
372 if (!waitingBufferAvailable_ && !followVisitorCommands_.empty()) {
373 for (auto& [timestamp, commands] : followVisitorCommands_) {
374 effectiveCommands_[timestamp].insert(effectiveCommands_[timestamp].end(),
375 std::make_move_iterator(commands.begin()), std::make_move_iterator(commands.end()));
376 }
377 followVisitorCommands_.clear();
378 }
379 for (auto& [surfaceNodeId, commandMap] : cachedCommands_) {
380 auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(surfaceNodeId);
381 auto bufferTimestamp = bufferTimestamps_.find(surfaceNodeId);
382 std::map<uint64_t, std::vector<std::unique_ptr<RSCommand>>>::iterator effectIter;
383
384 if (!node || !node->IsOnTheTree() || bufferTimestamp == bufferTimestamps_.end() || useUniVisitor_) {
385 // If node has been destructed or is not on the tree or has no valid buffer,
386 // for all command cached in commandMap should be executed immediately
387 effectIter = commandMap.end();
388 } else {
389 uint64_t timestamp = bufferTimestamp->second;
390 effectIter = commandMap.upper_bound(timestamp);
391 }
392
393 for (auto it = commandMap.begin(); it != effectIter; it++) {
394 effectiveCommands_[it->first].insert(effectiveCommands_[it->first].end(),
395 std::make_move_iterator(it->second.begin()), std::make_move_iterator(it->second.end()));
396 }
397 commandMap.erase(commandMap.begin(), effectIter);
398 }
399 }
400 for (auto& [timestamp, commands] : effectiveCommands_) {
401 context_->transactionTimestamp_ = timestamp;
402 for (auto& command : commands) {
403 if (command) {
404 command->Process(*context_);
405 }
406 }
407 }
408 effectiveCommands_.clear();
409 RS_TRACE_END();
410 }
411
ConsumeAndUpdateAllNodes()412 void RSMainThread::ConsumeAndUpdateAllNodes()
413 {
414 RS_TRACE_NAME("RSMainThread::ConsumeAndUpdateAllNodes");
415 bool needRequestNextVsync = false;
416 bufferTimestamps_.clear();
417 const auto& nodeMap = GetContext().GetNodeMap();
418 nodeMap.TraverseSurfaceNodes(
419 [this, &needRequestNextVsync](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
420 if (surfaceNode == nullptr) {
421 return;
422 }
423
424 auto& surfaceHandler = static_cast<RSSurfaceHandler&>(*surfaceNode);
425 surfaceHandler.ResetCurrentFrameBufferConsumed();
426 if (RSBaseRenderUtil::ConsumeAndUpdateBuffer(surfaceHandler)) {
427 this->bufferTimestamps_[surfaceNode->GetId()] = static_cast<uint64_t>(surfaceNode->GetTimestamp());
428 }
429
430 // still have buffer(s) to consume.
431 if (surfaceHandler.GetAvailableBufferCount() > 0) {
432 needRequestNextVsync = true;
433 }
434 });
435
436 if (needRequestNextVsync) {
437 RequestNextVSync();
438 }
439 }
440
ReleaseAllNodesBuffer()441 void RSMainThread::ReleaseAllNodesBuffer()
442 {
443 RS_TRACE_NAME("RSMainThread::ReleaseAllNodesBuffer");
444 const auto& nodeMap = GetContext().GetNodeMap();
445 nodeMap.TraverseSurfaceNodes([](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
446 if (surfaceNode == nullptr) {
447 return;
448 }
449 // To avoid traverse surfaceNodeMap again, destroy cold start thread here
450 if ((!surfaceNode->IsOnTheTree() || !surfaceNode->ShouldPaint()) &&
451 RSColdStartManager::Instance().IsColdStartThreadRunning(surfaceNode->GetId())) {
452 surfaceNode->ClearCachedImage();
453 RSColdStartManager::Instance().StopColdStartThread(surfaceNode->GetId());
454 }
455 RSBaseRenderUtil::ReleaseBuffer(static_cast<RSSurfaceHandler&>(*surfaceNode));
456 });
457 }
458
WaitUtilUniRenderFinished()459 void RSMainThread::WaitUtilUniRenderFinished()
460 {
461 std::unique_lock<std::mutex> lock(uniRenderMutex_);
462 if (uniRenderFinished_) {
463 return;
464 }
465 uniRenderCond_.wait(lock, [this]() { return uniRenderFinished_; });
466 uniRenderFinished_ = false;
467 }
468
WaitUntilUnmarshallingTaskFinished()469 void RSMainThread::WaitUntilUnmarshallingTaskFinished()
470 {
471 if (!isUniRender_) {
472 return;
473 }
474 RS_TRACE_NAME("RSMainThread::WaitUntilUnmarshallingTaskFinished");
475 std::unique_lock<std::mutex> lock(unmarshalMutex_);
476 unmarshalTaskCond_.wait(lock, [this]() { return unmarshalFinishedCount_ > 0; });
477 --unmarshalFinishedCount_;
478 }
479
MergeToEffectiveTransactionDataMap(TransactionDataMap & cachedTransactionDataMap)480 void RSMainThread::MergeToEffectiveTransactionDataMap(TransactionDataMap& cachedTransactionDataMap)
481 {
482 std::lock_guard<std::mutex> lock(transitionDataMutex_);
483 for (auto& elem : cachedTransactionDataMap) {
484 auto pid = elem.first;
485 if (effectiveTransactionDataIndexMap_.count(pid) == 0) {
486 RS_LOGE("RSMainThread::MergeToEffectiveTransactionDataMap pid:%d not valid, skip it", pid);
487 continue;
488 }
489 InsertToEnd(elem.second, effectiveTransactionDataIndexMap_[pid].second);
490 }
491 cachedTransactionDataMap.clear();
492 }
493
NotifyUniRenderFinish()494 void RSMainThread::NotifyUniRenderFinish()
495 {
496 if (std::this_thread::get_id() != Id()) {
497 std::lock_guard<std::mutex> lock(uniRenderMutex_);
498 uniRenderFinished_ = true;
499 uniRenderCond_.notify_one();
500 } else {
501 uniRenderFinished_ = true;
502 }
503 }
504
IfUseUniVisitor() const505 bool RSMainThread::IfUseUniVisitor() const
506 {
507 return (useUniVisitor_ && !waitingUpdateSurfaceNode_) || (!useUniVisitor_ && waitingBufferAvailable_);
508 }
509
CheckBufferAvailableIfNeed()510 void RSMainThread::CheckBufferAvailableIfNeed()
511 {
512 if (!waitingBufferAvailable_) {
513 return;
514 }
515 const auto& nodeMap = GetContext().GetNodeMap();
516 bool allBufferAvailable = true;
517 for (auto& [id, surfaceNode] : nodeMap.surfaceNodeMap_) {
518 if (surfaceNode == nullptr || !surfaceNode->IsOnTheTree() || !surfaceNode->IsAppWindow() ||
519 !surfaceNode->ShouldPaint()) {
520 continue;
521 }
522 if (surfaceNode->GetBuffer() == nullptr) {
523 allBufferAvailable = false;
524 break;
525 }
526 }
527 waitingBufferAvailable_ = !allBufferAvailable;
528 if (!waitingBufferAvailable_ && renderModeChangeCallback_) {
529 renderModeChangeCallback_->OnRenderModeChanged(false);
530 // clear display surface buffer
531 ClearDisplayBuffer();
532 }
533 }
534
CheckUpdateSurfaceNodeIfNeed()535 void RSMainThread::CheckUpdateSurfaceNodeIfNeed()
536 {
537 if (!waitingUpdateSurfaceNode_) {
538 return;
539 }
540 const auto& nodeMap = GetContext().GetNodeMap();
541 bool allSurfaceNodeUpdated = true;
542 for (auto& [id, surfaceNode] : nodeMap.surfaceNodeMap_) {
543 if (!allSurfaceNodeUpdated) {
544 break;
545 }
546 if (surfaceNode == nullptr || !surfaceNode->IsOnTheTree() || !surfaceNode->IsAppWindow()) {
547 continue;
548 }
549 for (auto& child : surfaceNode->GetSortedChildren()) {
550 if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>() && child->IsOnTheTree()) {
551 allSurfaceNodeUpdated = false;
552 break;
553 }
554 }
555 surfaceNode->ResetSortedChildren();
556 }
557 waitingUpdateSurfaceNode_ = !allSurfaceNodeUpdated;
558 if (!waitingUpdateSurfaceNode_) {
559 for (auto& elem : applicationAgentMap_) {
560 if (elem.second != nullptr) {
561 elem.second->NotifyClearBufferCache();
562 }
563 }
564 if (renderModeChangeCallback_) {
565 renderModeChangeCallback_->OnRenderModeChanged(true);
566 }
567 // trigger global refresh
568 SetDirtyFlag();
569 }
570 }
571
Render()572 void RSMainThread::Render()
573 {
574 const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
575 if (rootNode == nullptr) {
576 RS_LOGE("RSMainThread::Render GetGlobalRootRenderNode fail");
577 return;
578 }
579 if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
580 RSPropertyTrace::GetInstance().RefreshNodeTraceInfo();
581 }
582 RS_LOGD("RSMainThread::Render isUni:%d", IfUseUniVisitor());
583
584 if (IfUseUniVisitor()) {
585 auto uniVisitor = std::make_shared<RSUniRenderVisitor>();
586 uniVisitor->SetAnimateState(doWindowAnimate_);
587 uniVisitor->SetDirtyFlag(isDirty_);
588 uniVisitor->SetFocusedWindowPid(focusAppPid_);
589 rootNode->Prepare(uniVisitor);
590 CalcOcclusion();
591 rootNode->Process(uniVisitor);
592 isDirty_ = false;
593 } else {
594 auto rsVisitor = std::make_shared<RSRenderServiceVisitor>();
595 rsVisitor->SetAnimateState(doWindowAnimate_);
596 rootNode->Prepare(rsVisitor);
597 CalcOcclusion();
598
599 bool doParallelComposition = false;
600 if (!rsVisitor->ShouldForceSerial() && RSInnovation::GetParallelCompositionEnabled()) {
601 doParallelComposition = DoParallelComposition(rootNode);
602 }
603 if (doParallelComposition) {
604 renderEngine_->ShrinkCachesIfNeeded();
605 return;
606 }
607 rootNode->Process(rsVisitor);
608 }
609
610 renderEngine_->ShrinkCachesIfNeeded();
611 PerfForBlurIfNeeded();
612 }
613
CalcOcclusion()614 void RSMainThread::CalcOcclusion()
615 {
616 if (doWindowAnimate_ && !useUniVisitor_) {
617 return;
618 }
619 const std::shared_ptr<RSBaseRenderNode> node = context_->GetGlobalRootRenderNode();
620 if (node == nullptr) {
621 RS_LOGE("RSMainThread::CalcOcclusion GetGlobalRootRenderNode fail");
622 return;
623 }
624 RSInnovation::UpdateOcclusionCullingSoEnabled();
625
626 std::vector<RSBaseRenderNode::SharedPtr> curAllSurfaces;
627 if (node->GetSortedChildren().size() == 1) {
628 auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(
629 node->GetSortedChildren().front());
630 if (displayNode) {
631 curAllSurfaces = displayNode->GetCurAllSurfaces();
632 }
633 } else {
634 node->CollectSurface(node, curAllSurfaces, IfUseUniVisitor());
635 }
636
637 // 1. Judge whether it is dirty
638 // Surface cnt changed or surface DstRectChanged or surface ZorderChanged
639 bool winDirty = (lastSurfaceCnt_ != curAllSurfaces.size() || isDirty_);
640 lastSurfaceCnt_ = curAllSurfaces.size();
641 if (!winDirty) {
642 for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
643 auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
644 if (surface == nullptr) {
645 continue;
646 }
647 if (surface->GetZorderChanged() || surface->GetDstRectChanged() ||
648 surface->IsOpaqueRegionChanged() ||
649 surface->GetAlphaChanged() || (IfUseUniVisitor() && surface->IsDirtyRegionUpdated())) {
650 winDirty = true;
651 }
652 surface->CleanDstRectChanged();
653 surface->CleanAlphaChanged();
654 }
655 }
656 if (!winDirty) {
657 return;
658 }
659
660 RS_TRACE_NAME("RSMainThread::CalcOcclusion");
661 // 2. Calc occlusion
662 Occlusion::Region curRegion;
663 VisibleData curVisVec;
664 std::map<uint32_t, bool> pidVisMap;
665 for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
666 auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
667 if (surface == nullptr || surface->GetDstRect().IsEmpty()) {
668 continue;
669 }
670 Occlusion::Rect rect;
671 if (!surface->GetOldDirtyInSurface().IsEmpty() && IfUseUniVisitor()) {
672 rect = Occlusion::Rect{surface->GetOldDirtyInSurface()};
673 } else {
674 rect = Occlusion::Rect{surface->GetDstRect()};
675 }
676 Occlusion::Region curSurface { rect };
677 // Current surface subtract current region, if result region is empty that means it's covered
678 Occlusion::Region subResult = curSurface.Sub(curRegion);
679 // Set result to SurfaceRenderNode and its children
680 surface->setQosCal(qosPidCal_);
681 surface->SetVisibleRegionRecursive(subResult, curVisVec, pidVisMap);
682
683 // when surface is in starting window stage, do not occlude other window surfaces
684 // fix grey block when directly open app (i.e. setting) from notification center
685 auto parentPtr = surface->GetParent().lock();
686 if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
687 auto surfaceParentPtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentPtr);
688 if (surfaceParentPtr->GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE &&
689 !surface->IsNotifyUIBufferAvailable()) {
690 continue;
691 }
692 }
693
694 // Current region need to merge current surface for next calculation(ignore alpha surface)
695 if (IfUseUniVisitor()) {
696 curRegion.OrSelf(surface->GetOpaqueRegion());
697 if (RSOcclusionConfig::GetInstance().IsDividerBar(surface->GetName())) {
698 curRegion.OrSelf(curSurface);
699 }
700 } else {
701 const uint8_t opacity = 255;
702 bool diff = (surface->GetDstRect().width_ > surface->GetBuffer()->GetWidth() ||
703 surface->GetDstRect().height_ > surface->GetBuffer()->GetHeight()) &&
704 surface->GetRenderProperties().GetFrameGravity() != Gravity::RESIZE &&
705 surface->GetRenderProperties().GetAlpha() != opacity;
706 if ((!surface->IsTransparent() && !diff) ||
707 RSOcclusionConfig::GetInstance().IsDividerBar(surface->GetName())) {
708 curRegion.OrSelf(curSurface);
709 }
710 }
711 }
712
713 // 3. Callback to WMS
714 CallbackToWMS(curVisVec);
715
716 // 4. Callback to QOS
717 CallbackToQOS(pidVisMap);
718 }
719
CheckQosVisChanged(std::map<uint32_t,bool> & pidVisMap)720 bool RSMainThread::CheckQosVisChanged(std::map<uint32_t, bool>& pidVisMap)
721 {
722 bool isVisibleChanged = pidVisMap.size() != lastPidVisMap_.size();
723 if (!isVisibleChanged) {
724 auto iterCur = pidVisMap.begin();
725 auto iterLast = lastPidVisMap_.begin();
726 for (; iterCur != pidVisMap.end(); iterCur++, iterLast++) {
727 if (iterCur->first != iterLast->first ||
728 iterCur->second != iterLast->second) {
729 isVisibleChanged = true;
730 break;
731 }
732 }
733 }
734
735 lastPidVisMap_.clear();
736 lastPidVisMap_.insert(pidVisMap.begin(), pidVisMap.end());
737 return isVisibleChanged;
738 }
739
CallbackToQOS(std::map<uint32_t,bool> & pidVisMap)740 void RSMainThread::CallbackToQOS(std::map<uint32_t, bool>& pidVisMap)
741 {
742 if (!RSInnovation::UpdateQosVsyncEnabled()) {
743 if (qosPidCal_) {
744 qosPidCal_ = false;
745 RSQosThread::ResetQosPid();
746 RSQosThread::GetInstance()->SetQosCal(qosPidCal_);
747 }
748 return;
749 }
750 qosPidCal_ = true;
751 RSQosThread::GetInstance()->SetQosCal(qosPidCal_);
752 if (!CheckQosVisChanged(pidVisMap)) {
753 return;
754 }
755 RS_TRACE_NAME("RSQosThread::OnRSVisibilityChangeCB");
756 RSQosThread::GetInstance()->OnRSVisibilityChangeCB(pidVisMap);
757 }
758
CallbackToWMS(VisibleData & curVisVec)759 void RSMainThread::CallbackToWMS(VisibleData& curVisVec)
760 {
761 // if visible surfaces changed callback to WMS:
762 // 1. curVisVec size changed
763 // 2. curVisVec content changed
764 bool visibleChanged = curVisVec.size() != lastVisVec_.size();
765 std::sort(curVisVec.begin(), curVisVec.end());
766 if (!visibleChanged) {
767 for (uint32_t i = 0; i < curVisVec.size(); i++) {
768 if (curVisVec[i] != lastVisVec_[i]) {
769 visibleChanged = true;
770 break;
771 }
772 }
773 }
774 if (visibleChanged) {
775 for (auto& listener : occlusionListeners_) {
776 listener->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(curVisVec));
777 }
778 }
779 lastVisVec_.clear();
780 std::copy(curVisVec.begin(), curVisVec.end(), std::back_inserter(lastVisVec_));
781 }
782
RequestNextVSync()783 void RSMainThread::RequestNextVSync()
784 {
785 RS_TRACE_FUNC();
786 VSyncReceiver::FrameCallback fcb = {
787 .userData_ = this,
788 .callback_ = [this](uint64_t timestamp, void* data) { OnVsync(timestamp, data); },
789 };
790 if (receiver_ != nullptr) {
791 requestNextVsyncNum_++;
792 if (requestNextVsyncNum_ > RUQUEST_VSYNC_NUMBER_LIMIT) {
793 RS_LOGW("RSMainThread::RequestNextVSync too many times:%d", requestNextVsyncNum_);
794 }
795 receiver_->RequestNextVSync(fcb);
796 }
797 }
798
OnVsync(uint64_t timestamp,void * data)799 void RSMainThread::OnVsync(uint64_t timestamp, void* data)
800 {
801 ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSMainThread::OnVsync");
802 timestamp_ = timestamp;
803 requestNextVsyncNum_ = 0;
804 if (isUniRender_) {
805 MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
806 RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
807 }
808 mainLoop_();
809 if (handler_) {
810 auto screenManager_ = CreateOrGetScreenManager();
811 if (screenManager_ != nullptr) {
812 PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
813 }
814 }
815 ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
816 }
817
Animate(uint64_t timestamp)818 void RSMainThread::Animate(uint64_t timestamp)
819 {
820 RS_TRACE_FUNC();
821
822 lastAnimateTimestamp_ = timestamp;
823
824 if (context_->animatingNodeList_.empty()) {
825 if (doWindowAnimate_ && RSInnovation::UpdateQosVsyncEnabled()) {
826 // Preventing Occlusion Calculation from Being Completed in Advance
827 RSQosThread::GetInstance()->OnRSVisibilityChangeCB(lastPidVisMap_);
828 }
829 doWindowAnimate_ = false;
830 return;
831 }
832
833 RS_LOGD("RSMainThread::Animate start, processing %d animating nodes", context_->animatingNodeList_.size());
834
835 bool curWinAnim = false;
836 bool needRequestNextVsync = false;
837 // iterate and animate all animating nodes, remove if animation finished
838 EraseIf(context_->animatingNodeList_,
839 [timestamp, &curWinAnim, &needRequestNextVsync](const auto& iter) -> bool {
840 auto node = iter.second.lock();
841 if (node == nullptr) {
842 RS_LOGD("RSMainThread::Animate removing expired animating node");
843 return true;
844 }
845 auto result = node->Animate(timestamp);
846 if (!result.first) {
847 RS_LOGD("RSMainThread::Animate removing finished animating node %" PRIu64, node->GetId());
848 }
849 needRequestNextVsync = needRequestNextVsync || result.second;
850 if (node->template IsInstanceOf<RSSurfaceRenderNode>()) {
851 curWinAnim = true;
852 }
853 return !result.first;
854 });
855
856 if (!doWindowAnimate_ && curWinAnim && RSInnovation::UpdateQosVsyncEnabled()) {
857 RSQosThread::ResetQosPid();
858 }
859 doWindowAnimate_ = curWinAnim;
860 RS_LOGD("RSMainThread::Animate end, %d animating nodes remains, has window animation: %d",
861 context_->animatingNodeList_.size(), curWinAnim);
862
863 if (needRequestNextVsync) {
864 RequestNextVSync();
865 }
866 PerfAfterAnim();
867 }
868
CheckDelayedSwitchTask()869 void RSMainThread::CheckDelayedSwitchTask()
870 {
871 if (switchDelayed_ && !doWindowAnimate_ && useUniVisitor_ != delayedTargetUniVisitor_ &&
872 !waitingBufferAvailable_ && !waitingUpdateSurfaceNode_) {
873 switchDelayed_ = false;
874 UpdateRenderMode(delayedTargetUniVisitor_.load());
875 }
876 }
877
UpdateRenderMode(bool useUniVisitor)878 void RSMainThread::UpdateRenderMode(bool useUniVisitor)
879 {
880 if (waitingBufferAvailable_ || waitingUpdateSurfaceNode_) {
881 RS_LOGE("RSMainThread::NotifyRenderModeChanged last update mode not finished, switch again");
882 }
883 useUniVisitor_.store(useUniVisitor);
884 waitingBufferAvailable_ = !useUniVisitor_;
885 waitingUpdateSurfaceNode_ = useUniVisitor_;
886 for (auto& elem : applicationAgentMap_) {
887 if (elem.second != nullptr) {
888 elem.second->OnRenderModeChanged(!useUniVisitor_);
889 }
890 }
891 }
892
CheckColdStartMap()893 void RSMainThread::CheckColdStartMap()
894 {
895 const auto& nodeMap = GetContext().GetNodeMap();
896 RSColdStartManager::Instance().CheckColdStartMap(nodeMap);
897 }
898
RecvRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)899 void RSMainThread::RecvRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
900 {
901 if (!rsTransactionData) {
902 return;
903 }
904 if (rsTransactionData->GetUniRender()) {
905 std::lock_guard<std::mutex> lock(transitionDataMutex_);
906 cachedTransactionDataMap_[rsTransactionData->GetSendingPid()].emplace_back(std::move(rsTransactionData));
907 } else {
908 ClassifyRSTransactionData(rsTransactionData);
909 }
910 RequestNextVSync();
911 }
912
ClassifyRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)913 void RSMainThread::ClassifyRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
914 {
915 const auto& nodeMap = context_->GetNodeMap();
916 std::lock_guard<std::mutex> lock(transitionDataMutex_);
917 std::unique_ptr<RSTransactionData> transactionData(std::move(rsTransactionData));
918 auto timestamp = transactionData->GetTimestamp();
919 RS_LOGD("RSMainThread::RecvRSTransactionData timestamp = %" PRIu64, timestamp);
920 for (auto& [nodeId, followType, command] : transactionData->GetPayload()) {
921 if (nodeId == 0 || followType == FollowType::NONE) {
922 pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
923 continue;
924 }
925 auto node = nodeMap.GetRenderNode(nodeId);
926 if (waitingBufferAvailable_ && node && followType == FollowType::FOLLOW_VISITOR) {
927 followVisitorCommands_[timestamp].emplace_back(std::move(command));
928 continue;
929 }
930 if (node && followType == FollowType::FOLLOW_TO_PARENT) {
931 auto parentNode = node->GetParent().lock();
932 if (parentNode) {
933 nodeId = parentNode->GetId();
934 } else {
935 pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
936 continue;
937 }
938 }
939 cachedCommands_[nodeId][timestamp].emplace_back(std::move(command));
940 }
941 }
942
PostTask(RSTaskMessage::RSTask task)943 void RSMainThread::PostTask(RSTaskMessage::RSTask task)
944 {
945 if (handler_) {
946 handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
947 }
948 }
949
PostSyncTask(RSTaskMessage::RSTask task)950 void RSMainThread::PostSyncTask(RSTaskMessage::RSTask task)
951 {
952 if (handler_) {
953 handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
954 }
955 }
956
RegisterApplicationAgent(uint32_t pid,sptr<IApplicationAgent> app)957 void RSMainThread::RegisterApplicationAgent(uint32_t pid, sptr<IApplicationAgent> app)
958 {
959 applicationAgentMap_.emplace(pid, app);
960 }
961
UnRegisterApplicationAgent(sptr<IApplicationAgent> app)962 void RSMainThread::UnRegisterApplicationAgent(sptr<IApplicationAgent> app)
963 {
964 EraseIf(applicationAgentMap_, [&app](const auto& iter) { return iter.second == app; });
965 }
966
NotifyRenderModeChanged(bool useUniVisitor)967 void RSMainThread::NotifyRenderModeChanged(bool useUniVisitor)
968 {
969 if (RSUniRenderJudgement::GetUniRenderEnabledType() != UniRenderEnabledType::UNI_RENDER_DYNAMIC_SWITCH) {
970 return;
971 }
972 if (useUniVisitor == useUniVisitor_) {
973 RS_LOGI("RSMainThread::NotifyRenderModeChanged useUniVisitor_:%d, not changed", useUniVisitor_.load());
974 return;
975 }
976 if (doWindowAnimate_) {
977 switchDelayed_ = true;
978 delayedTargetUniVisitor_ = useUniVisitor;
979 } else {
980 PostTask([useUniVisitor = useUniVisitor, this]() {
981 UpdateRenderMode(useUniVisitor);
982 });
983 }
984 }
985
QueryIfUseUniVisitor() const986 bool RSMainThread::QueryIfUseUniVisitor() const
987 {
988 RS_LOGI("RSMainThread::QueryIfUseUniVisitor useUniVisitor_:%d", useUniVisitor_.load());
989 return useUniVisitor_;
990 }
991
RegisterOcclusionChangeCallback(sptr<RSIOcclusionChangeCallback> callback)992 void RSMainThread::RegisterOcclusionChangeCallback(sptr<RSIOcclusionChangeCallback> callback)
993 {
994 occlusionListeners_.emplace_back(callback);
995 }
996
UnRegisterOcclusionChangeCallback(sptr<RSIOcclusionChangeCallback> callback)997 void RSMainThread::UnRegisterOcclusionChangeCallback(sptr<RSIOcclusionChangeCallback> callback)
998 {
999 auto iter = std::find(occlusionListeners_.begin(), occlusionListeners_.end(), callback);
1000 if (iter != occlusionListeners_.end()) {
1001 occlusionListeners_.erase(iter);
1002 }
1003 }
1004
CleanOcclusionListener()1005 void RSMainThread::CleanOcclusionListener()
1006 {
1007 occlusionListeners_.clear();
1008 }
1009
SetRenderModeChangeCallback(sptr<RSIRenderModeChangeCallback> callback)1010 void RSMainThread::SetRenderModeChangeCallback(sptr<RSIRenderModeChangeCallback> callback)
1011 {
1012 renderModeChangeCallback_ = callback;
1013 }
1014
SendCommands()1015 void RSMainThread::SendCommands()
1016 {
1017 RS_TRACE_FUNC();
1018 if (!RSMessageProcessor::Instance().HasTransaction()) {
1019 return;
1020 }
1021
1022 // dispatch messages to corresponding application
1023 auto transactionMapPtr = std::make_shared<std::unordered_map<uint32_t, RSTransactionData>>(
1024 RSMessageProcessor::Instance().GetAllTransactions());
1025 PostTask([this, transactionMapPtr]() {
1026 for (auto& transactionIter : *transactionMapPtr) {
1027 auto pid = transactionIter.first;
1028 auto appIter = applicationAgentMap_.find(pid);
1029 if (appIter == applicationAgentMap_.end()) {
1030 RS_LOGW(
1031 "RSMainThread::SendCommand no application agent registered as pid %d, this will cause memory leak!",
1032 pid);
1033 continue;
1034 }
1035 auto& app = appIter->second;
1036 auto transactionPtr = std::make_shared<RSTransactionData>(std::move(transactionIter.second));
1037 app->OnTransaction(transactionPtr);
1038 }
1039 });
1040 }
1041
QosStateDump(std::string & dumpString)1042 void RSMainThread::QosStateDump(std::string& dumpString)
1043 {
1044 if (RSQosThread::GetInstance()->GetQosCal()) {
1045 dumpString.append("QOS is enabled\n");
1046 } else {
1047 dumpString.append("QOS is disabled\n");
1048 }
1049 }
1050
RenderServiceTreeDump(std::string & dumpString)1051 void RSMainThread::RenderServiceTreeDump(std::string& dumpString)
1052 {
1053 dumpString.append("Animating Node: [");
1054 for (auto& [nodeId, _]: context_->animatingNodeList_) {
1055 dumpString.append(std::to_string(nodeId) + ", ");
1056 }
1057 dumpString.append("];\n");
1058 const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
1059 if (rootNode == nullptr) {
1060 dumpString.append("rootNode is null\n");
1061 return;
1062 }
1063 rootNode->DumpTree(0, dumpString);
1064 }
1065
DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)1066 bool RSMainThread::DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)
1067 {
1068 using CreateParallelSyncSignalFunc = void* (*)(uint32_t);
1069 using SignalCountDownFunc = void (*)(void*);
1070 using SignalAwaitFunc = void (*)(void*);
1071 using AssignTaskFunc = void (*)(std::function<void()>);
1072 using RemoveStoppedThreadsFunc = void (*)();
1073
1074 auto CreateParallelSyncSignal = (CreateParallelSyncSignalFunc)RSInnovation::_s_createParallelSyncSignal;
1075 auto SignalCountDown = (SignalCountDownFunc)RSInnovation::_s_signalCountDown;
1076 auto SignalAwait = (SignalAwaitFunc)RSInnovation::_s_signalAwait;
1077 auto AssignTask = (AssignTaskFunc)RSInnovation::_s_assignTask;
1078 auto RemoveStoppedThreads = (RemoveStoppedThreadsFunc)RSInnovation::_s_removeStoppedThreads;
1079
1080 void* syncSignal = (*CreateParallelSyncSignal)(rootNode->GetChildrenCount());
1081 if (!syncSignal) {
1082 return false;
1083 }
1084
1085 (*RemoveStoppedThreads)();
1086
1087 auto children = rootNode->GetSortedChildren();
1088 bool animate_ = doWindowAnimate_;
1089 for (auto it = children.rbegin(); it != children.rend(); it++) {
1090 auto child = *it;
1091 auto task = [&syncSignal, SignalCountDown, child, animate_]() {
1092 std::shared_ptr<RSNodeVisitor> visitor;
1093 auto rsVisitor = std::make_shared<RSRenderServiceVisitor>(true);
1094 rsVisitor->SetAnimateState(animate_);
1095 visitor = rsVisitor;
1096 child->Process(visitor);
1097 (*SignalCountDown)(syncSignal);
1098 };
1099 if (*it == *children.begin()) {
1100 task();
1101 } else {
1102 (*AssignTask)(task);
1103 }
1104 }
1105 (*SignalAwait)(syncSignal);
1106 ResetSortedChildren(rootNode);
1107 return true;
1108 }
1109
ResetSortedChildren(std::shared_ptr<RSBaseRenderNode> node)1110 void RSMainThread::ResetSortedChildren(std::shared_ptr<RSBaseRenderNode> node)
1111 {
1112 for (auto& child : node->GetSortedChildren()) {
1113 ResetSortedChildren(child);
1114 }
1115 node->ResetSortedChildren();
1116 }
1117
ClearTransactionDataPidInfo(pid_t remotePid)1118 void RSMainThread::ClearTransactionDataPidInfo(pid_t remotePid)
1119 {
1120 if (!isUniRender_) {
1121 return;
1122 }
1123 std::lock_guard<std::mutex> lock(transitionDataMutex_);
1124 if (effectiveTransactionDataIndexMap_.count(remotePid) > 0 &&
1125 !effectiveTransactionDataIndexMap_[remotePid].second.empty()) {
1126 RS_LOGD("RSMainThread::ClearTransactionDataPidInfo process:%d destroyed, skip commands", remotePid);
1127 }
1128 effectiveTransactionDataIndexMap_.erase(remotePid);
1129 transactionDataLastWaitTime_.erase(remotePid);
1130
1131 // clear cpu cache when process exit
1132 // CLEAN_CACHE_FREQ to prevent multiple cleanups in a short period of time
1133 if ((timestamp_ - lastCleanCacheTimestamp_) / REFRESH_PERIOD > CLEAN_CACHE_FREQ) {
1134 #ifdef RS_ENABLE_GL
1135 RS_LOGD("RSMainThread: clear cpu cache");
1136 auto grContext = RSBaseRenderEngine::GetRenderContext()->GetGrContext();
1137 grContext->flush();
1138 SkGraphics::PurgeAllCaches();
1139 grContext->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
1140 lastCleanCacheTimestamp_ = timestamp_;
1141 #endif
1142 }
1143 }
1144
AddTransactionDataPidInfo(pid_t remotePid)1145 void RSMainThread::AddTransactionDataPidInfo(pid_t remotePid)
1146 {
1147 if (!isUniRender_) {
1148 return;
1149 }
1150 std::lock_guard<std::mutex> lock(transitionDataMutex_);
1151 if (effectiveTransactionDataIndexMap_.count(remotePid) > 0) {
1152 RS_LOGW("RSMainThread::AddTransactionDataPidInfo remotePid:%d already exists", remotePid);
1153 }
1154 effectiveTransactionDataIndexMap_[remotePid].first = 0;
1155 }
1156
ClearDisplayBuffer()1157 void RSMainThread::ClearDisplayBuffer()
1158 {
1159 const std::shared_ptr<RSBaseRenderNode> node = context_->GetGlobalRootRenderNode();
1160 if (node == nullptr) {
1161 RS_LOGE("ClearDisplayBuffer get global root render node fail");
1162 return;
1163 }
1164 for (auto& child : node->GetSortedChildren()) {
1165 auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(child);
1166 if (displayNode == nullptr) {
1167 continue;
1168 }
1169 if (displayNode->GetRSSurface() != nullptr) {
1170 displayNode->GetRSSurface()->ResetBufferAge();
1171 }
1172 }
1173 }
1174
SetDirtyFlag()1175 void RSMainThread::SetDirtyFlag()
1176 {
1177 isDirty_ = true;
1178 }
1179
PerfAfterAnim()1180 void RSMainThread::PerfAfterAnim()
1181 {
1182 if (!IfUseUniVisitor()) {
1183 return;
1184 }
1185 if (!context_->animatingNodeList_.empty() && timestamp_ - prePerfTimestamp_ > PERF_PERIOD) {
1186 RS_LOGD("RSMainThread:: soc perf to render_service_animation");
1187 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(PERF_ANIMATION_REQUESTED_CODE, "");
1188 prePerfTimestamp_ = timestamp_;
1189 } else if (context_->animatingNodeList_.empty()) {
1190 RS_LOGD("RSMainThread:: soc perf off render_service_animation");
1191 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(PERF_ANIMATION_REQUESTED_CODE, false, "");
1192 prePerfTimestamp_ = 0;
1193 }
1194 }
ForceRefreshForUni()1195 void RSMainThread::ForceRefreshForUni()
1196 {
1197 if (isUniRender_) {
1198 PostTask([=]() {
1199 MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
1200 RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
1201 mainLoop_();
1202 });
1203 if (handler_) {
1204 auto screenManager_ = CreateOrGetScreenManager();
1205 if (screenManager_ != nullptr) {
1206 PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
1207 }
1208 }
1209 } else {
1210 RequestNextVSync();
1211 }
1212 }
1213
PerfForBlurIfNeeded()1214 void RSMainThread::PerfForBlurIfNeeded()
1215 {
1216 static int preBlurCnt = 0;
1217 int blurCnt = RSPropertiesPainter::GetAndResetBlurCnt();
1218 // clamp blurCnt to 0~3.
1219 blurCnt = std::clamp<int>(blurCnt, 0, 3);
1220 if (blurCnt != preBlurCnt && preBlurCnt != 0) {
1221 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(BLUR_CNT_TO_BLUR_CODE.at(preBlurCnt), false, "");
1222 preBlurCnt = 0;
1223 }
1224 if (blurCnt == 0) {
1225 return;
1226 }
1227 static uint64_t prePerfTimestamp = 0;
1228 if (timestamp_ - prePerfTimestamp > PERF_PERIOD_BLUR || blurCnt != preBlurCnt) {
1229 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(blurCnt), "");
1230 prePerfTimestamp = timestamp_;
1231 preBlurCnt = blurCnt;
1232 }
1233 }
1234
PerfMultiWindow()1235 void RSMainThread::PerfMultiWindow()
1236 {
1237 if (!isUniRender_) {
1238 return;
1239 }
1240 static uint64_t lastPerfTimestamp = 0;
1241 if (appWindowNum_ >= MULTI_WINDOW_PERF_START_NUM && appWindowNum_ <= MULTI_WINDOW_PERF_END_NUM
1242 && timestamp_ - lastPerfTimestamp > PERF_PERIOD_MULTI_WINDOW) {
1243 RS_LOGD("RSMainThread::PerfMultiWindow soc perf");
1244 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, "");
1245 lastPerfTimestamp = timestamp_;
1246 } else if ((appWindowNum_ < MULTI_WINDOW_PERF_START_NUM || appWindowNum_ > MULTI_WINDOW_PERF_END_NUM)
1247 && timestamp_ - lastPerfTimestamp < PERF_PERIOD_MULTI_WINDOW) {
1248 RS_LOGD("RSMainThread::PerfMultiWindow soc perf off");
1249 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(PERF_MULTI_WINDOW_REQUESTED_CODE, false, "");
1250 }
1251 }
1252
SetAppWindowNum(uint32_t num)1253 void RSMainThread::SetAppWindowNum(uint32_t num)
1254 {
1255 appWindowNum_ = num;
1256 }
1257 } // namespace Rosen
1258 } // namespace OHOS
1259