• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         std::lock_guard<std::mutex> lock(occlusionMutex_);
776         for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
777             if (it->second) {
778                 RS_LOGD("RSMainThread::CallbackToWMS curVisVec size:%u", curVisVec.size());
779                 it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(curVisVec));
780             }
781         }
782     }
783     lastVisVec_.clear();
784     std::copy(curVisVec.begin(), curVisVec.end(), std::back_inserter(lastVisVec_));
785 }
786 
RequestNextVSync()787 void RSMainThread::RequestNextVSync()
788 {
789     RS_TRACE_FUNC();
790     VSyncReceiver::FrameCallback fcb = {
791         .userData_ = this,
792         .callback_ = [this](uint64_t timestamp, void* data) { OnVsync(timestamp, data); },
793     };
794     if (receiver_ != nullptr) {
795         requestNextVsyncNum_++;
796         if (requestNextVsyncNum_ > RUQUEST_VSYNC_NUMBER_LIMIT) {
797             RS_LOGW("RSMainThread::RequestNextVSync too many times:%d", requestNextVsyncNum_);
798         }
799         receiver_->RequestNextVSync(fcb);
800     }
801 }
802 
OnVsync(uint64_t timestamp,void * data)803 void RSMainThread::OnVsync(uint64_t timestamp, void* data)
804 {
805     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSMainThread::OnVsync");
806     timestamp_ = timestamp;
807     requestNextVsyncNum_ = 0;
808     if (isUniRender_) {
809         MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
810         RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
811     }
812     mainLoop_();
813     if (handler_) {
814         auto screenManager_ = CreateOrGetScreenManager();
815         if (screenManager_ != nullptr) {
816             PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
817         }
818     }
819     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
820 }
821 
Animate(uint64_t timestamp)822 void RSMainThread::Animate(uint64_t timestamp)
823 {
824     RS_TRACE_FUNC();
825 
826     lastAnimateTimestamp_ = timestamp;
827 
828     if (context_->animatingNodeList_.empty()) {
829         if (doWindowAnimate_ && RSInnovation::UpdateQosVsyncEnabled()) {
830             // Preventing Occlusion Calculation from Being Completed in Advance
831             RSQosThread::GetInstance()->OnRSVisibilityChangeCB(lastPidVisMap_);
832         }
833         doWindowAnimate_ = false;
834         return;
835     }
836 
837     RS_LOGD("RSMainThread::Animate start, processing %d animating nodes", context_->animatingNodeList_.size());
838 
839     bool curWinAnim = false;
840     bool needRequestNextVsync = false;
841     // iterate and animate all animating nodes, remove if animation finished
842     EraseIf(context_->animatingNodeList_,
843         [timestamp, &curWinAnim, &needRequestNextVsync](const auto& iter) -> bool {
844         auto node = iter.second.lock();
845         if (node == nullptr) {
846             RS_LOGD("RSMainThread::Animate removing expired animating node");
847             return true;
848         }
849         auto result = node->Animate(timestamp);
850         if (!result.first) {
851             RS_LOGD("RSMainThread::Animate removing finished animating node %" PRIu64, node->GetId());
852         }
853         needRequestNextVsync = needRequestNextVsync || result.second;
854         if (node->template IsInstanceOf<RSSurfaceRenderNode>()) {
855             curWinAnim = true;
856         }
857         return !result.first;
858     });
859 
860     if (!doWindowAnimate_ && curWinAnim && RSInnovation::UpdateQosVsyncEnabled()) {
861         RSQosThread::ResetQosPid();
862     }
863     doWindowAnimate_ = curWinAnim;
864     RS_LOGD("RSMainThread::Animate end, %d animating nodes remains, has window animation: %d",
865         context_->animatingNodeList_.size(), curWinAnim);
866 
867     if (needRequestNextVsync) {
868         RequestNextVSync();
869     }
870     PerfAfterAnim();
871 }
872 
CheckDelayedSwitchTask()873 void RSMainThread::CheckDelayedSwitchTask()
874 {
875     if (switchDelayed_ && !doWindowAnimate_ && useUniVisitor_ != delayedTargetUniVisitor_ &&
876         !waitingBufferAvailable_ && !waitingUpdateSurfaceNode_) {
877         switchDelayed_ = false;
878         UpdateRenderMode(delayedTargetUniVisitor_.load());
879     }
880 }
881 
UpdateRenderMode(bool useUniVisitor)882 void RSMainThread::UpdateRenderMode(bool useUniVisitor)
883 {
884     if (waitingBufferAvailable_ || waitingUpdateSurfaceNode_) {
885         RS_LOGE("RSMainThread::NotifyRenderModeChanged last update mode not finished, switch again");
886     }
887     useUniVisitor_.store(useUniVisitor);
888     waitingBufferAvailable_ = !useUniVisitor_;
889     waitingUpdateSurfaceNode_ = useUniVisitor_;
890     for (auto& elem : applicationAgentMap_) {
891         if (elem.second != nullptr) {
892             elem.second->OnRenderModeChanged(!useUniVisitor_);
893         }
894     }
895 }
896 
CheckColdStartMap()897 void RSMainThread::CheckColdStartMap()
898 {
899     const auto& nodeMap = GetContext().GetNodeMap();
900     RSColdStartManager::Instance().CheckColdStartMap(nodeMap);
901 }
902 
RecvRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)903 void RSMainThread::RecvRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
904 {
905     if (!rsTransactionData) {
906         return;
907     }
908     if (rsTransactionData->GetUniRender()) {
909         std::lock_guard<std::mutex> lock(transitionDataMutex_);
910         cachedTransactionDataMap_[rsTransactionData->GetSendingPid()].emplace_back(std::move(rsTransactionData));
911     } else {
912         ClassifyRSTransactionData(rsTransactionData);
913     }
914     RequestNextVSync();
915 }
916 
ClassifyRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)917 void RSMainThread::ClassifyRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
918 {
919     const auto& nodeMap = context_->GetNodeMap();
920     std::lock_guard<std::mutex> lock(transitionDataMutex_);
921     std::unique_ptr<RSTransactionData> transactionData(std::move(rsTransactionData));
922     auto timestamp = transactionData->GetTimestamp();
923     RS_LOGD("RSMainThread::RecvRSTransactionData timestamp = %" PRIu64, timestamp);
924     for (auto& [nodeId, followType, command] : transactionData->GetPayload()) {
925         if (nodeId == 0 || followType == FollowType::NONE) {
926             pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
927             continue;
928         }
929         auto node = nodeMap.GetRenderNode(nodeId);
930         if (waitingBufferAvailable_ && node && followType == FollowType::FOLLOW_VISITOR) {
931             followVisitorCommands_[timestamp].emplace_back(std::move(command));
932             continue;
933         }
934         if (node && followType == FollowType::FOLLOW_TO_PARENT) {
935             auto parentNode = node->GetParent().lock();
936             if (parentNode) {
937                 nodeId = parentNode->GetId();
938             } else {
939                 pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
940                 continue;
941             }
942         }
943         cachedCommands_[nodeId][timestamp].emplace_back(std::move(command));
944     }
945 }
946 
PostTask(RSTaskMessage::RSTask task)947 void RSMainThread::PostTask(RSTaskMessage::RSTask task)
948 {
949     if (handler_) {
950         handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
951     }
952 }
953 
PostSyncTask(RSTaskMessage::RSTask task)954 void RSMainThread::PostSyncTask(RSTaskMessage::RSTask task)
955 {
956     if (handler_) {
957         handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
958     }
959 }
960 
RegisterApplicationAgent(uint32_t pid,sptr<IApplicationAgent> app)961 void RSMainThread::RegisterApplicationAgent(uint32_t pid, sptr<IApplicationAgent> app)
962 {
963     applicationAgentMap_.emplace(pid, app);
964 }
965 
UnRegisterApplicationAgent(sptr<IApplicationAgent> app)966 void RSMainThread::UnRegisterApplicationAgent(sptr<IApplicationAgent> app)
967 {
968     EraseIf(applicationAgentMap_, [&app](const auto& iter) { return iter.second == app; });
969 }
970 
NotifyRenderModeChanged(bool useUniVisitor)971 void RSMainThread::NotifyRenderModeChanged(bool useUniVisitor)
972 {
973     if (RSUniRenderJudgement::GetUniRenderEnabledType() != UniRenderEnabledType::UNI_RENDER_DYNAMIC_SWITCH) {
974         return;
975     }
976     if (useUniVisitor == useUniVisitor_) {
977         RS_LOGI("RSMainThread::NotifyRenderModeChanged useUniVisitor_:%d, not changed", useUniVisitor_.load());
978         return;
979     }
980     if (doWindowAnimate_) {
981         switchDelayed_ = true;
982         delayedTargetUniVisitor_ = useUniVisitor;
983     } else {
984         PostTask([useUniVisitor = useUniVisitor, this]() {
985             UpdateRenderMode(useUniVisitor);
986         });
987     }
988 }
989 
QueryIfUseUniVisitor() const990 bool RSMainThread::QueryIfUseUniVisitor() const
991 {
992     RS_LOGI("RSMainThread::QueryIfUseUniVisitor useUniVisitor_:%d", useUniVisitor_.load());
993     return useUniVisitor_;
994 }
995 
RegisterOcclusionChangeCallback(pid_t pid,sptr<RSIOcclusionChangeCallback> callback)996 void RSMainThread::RegisterOcclusionChangeCallback(pid_t pid, sptr<RSIOcclusionChangeCallback> callback)
997 {
998     std::lock_guard<std::mutex> lock(occlusionMutex_);
999     occlusionListeners_[pid] = callback;
1000 }
1001 
UnRegisterOcclusionChangeCallback(pid_t pid)1002 void RSMainThread::UnRegisterOcclusionChangeCallback(pid_t pid)
1003 {
1004     std::lock_guard<std::mutex> lock(occlusionMutex_);
1005     occlusionListeners_.erase(pid);
1006 }
1007 
SetRenderModeChangeCallback(sptr<RSIRenderModeChangeCallback> callback)1008 void RSMainThread::SetRenderModeChangeCallback(sptr<RSIRenderModeChangeCallback> callback)
1009 {
1010     renderModeChangeCallback_ = callback;
1011 }
1012 
SendCommands()1013 void RSMainThread::SendCommands()
1014 {
1015     RS_TRACE_FUNC();
1016     if (!RSMessageProcessor::Instance().HasTransaction()) {
1017         return;
1018     }
1019 
1020     // dispatch messages to corresponding application
1021     auto transactionMapPtr = std::make_shared<std::unordered_map<uint32_t, RSTransactionData>>(
1022         RSMessageProcessor::Instance().GetAllTransactions());
1023     PostTask([this, transactionMapPtr]() {
1024         for (auto& transactionIter : *transactionMapPtr) {
1025             auto pid = transactionIter.first;
1026             auto appIter = applicationAgentMap_.find(pid);
1027             if (appIter == applicationAgentMap_.end()) {
1028                 RS_LOGW(
1029                     "RSMainThread::SendCommand no application agent registered as pid %d, this will cause memory leak!",
1030                     pid);
1031                 continue;
1032             }
1033             auto& app = appIter->second;
1034             auto transactionPtr = std::make_shared<RSTransactionData>(std::move(transactionIter.second));
1035             app->OnTransaction(transactionPtr);
1036         }
1037     });
1038 }
1039 
QosStateDump(std::string & dumpString)1040 void RSMainThread::QosStateDump(std::string& dumpString)
1041 {
1042     if (RSQosThread::GetInstance()->GetQosCal()) {
1043         dumpString.append("QOS is enabled\n");
1044     } else {
1045         dumpString.append("QOS is disabled\n");
1046     }
1047 }
1048 
RenderServiceTreeDump(std::string & dumpString)1049 void RSMainThread::RenderServiceTreeDump(std::string& dumpString)
1050 {
1051     dumpString.append("Animating Node: [");
1052     for (auto& [nodeId, _]: context_->animatingNodeList_) {
1053         dumpString.append(std::to_string(nodeId) + ", ");
1054     }
1055     dumpString.append("];\n");
1056     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
1057     if (rootNode == nullptr) {
1058         dumpString.append("rootNode is null\n");
1059         return;
1060     }
1061     rootNode->DumpTree(0, dumpString);
1062 }
1063 
DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)1064 bool RSMainThread::DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)
1065 {
1066     using CreateParallelSyncSignalFunc = void* (*)(uint32_t);
1067     using SignalCountDownFunc = void (*)(void*);
1068     using SignalAwaitFunc = void (*)(void*);
1069     using AssignTaskFunc = void (*)(std::function<void()>);
1070     using RemoveStoppedThreadsFunc = void (*)();
1071 
1072     auto CreateParallelSyncSignal = (CreateParallelSyncSignalFunc)RSInnovation::_s_createParallelSyncSignal;
1073     auto SignalCountDown = (SignalCountDownFunc)RSInnovation::_s_signalCountDown;
1074     auto SignalAwait = (SignalAwaitFunc)RSInnovation::_s_signalAwait;
1075     auto AssignTask = (AssignTaskFunc)RSInnovation::_s_assignTask;
1076     auto RemoveStoppedThreads = (RemoveStoppedThreadsFunc)RSInnovation::_s_removeStoppedThreads;
1077 
1078     void* syncSignal = (*CreateParallelSyncSignal)(rootNode->GetChildrenCount());
1079     if (!syncSignal) {
1080         return false;
1081     }
1082 
1083     (*RemoveStoppedThreads)();
1084 
1085     auto children = rootNode->GetSortedChildren();
1086     bool animate_ = doWindowAnimate_;
1087     for (auto it = children.rbegin(); it != children.rend(); it++) {
1088         auto child = *it;
1089         auto task = [&syncSignal, SignalCountDown, child, animate_]() {
1090             std::shared_ptr<RSNodeVisitor> visitor;
1091             auto rsVisitor = std::make_shared<RSRenderServiceVisitor>(true);
1092             rsVisitor->SetAnimateState(animate_);
1093             visitor = rsVisitor;
1094             child->Process(visitor);
1095             (*SignalCountDown)(syncSignal);
1096         };
1097         if (*it == *children.begin()) {
1098             task();
1099         } else {
1100             (*AssignTask)(task);
1101         }
1102     }
1103     (*SignalAwait)(syncSignal);
1104     ResetSortedChildren(rootNode);
1105     return true;
1106 }
1107 
ResetSortedChildren(std::shared_ptr<RSBaseRenderNode> node)1108 void RSMainThread::ResetSortedChildren(std::shared_ptr<RSBaseRenderNode> node)
1109 {
1110     for (auto& child : node->GetSortedChildren()) {
1111         ResetSortedChildren(child);
1112     }
1113     node->ResetSortedChildren();
1114 }
1115 
ClearTransactionDataPidInfo(pid_t remotePid)1116 void RSMainThread::ClearTransactionDataPidInfo(pid_t remotePid)
1117 {
1118     if (!isUniRender_) {
1119         return;
1120     }
1121     std::lock_guard<std::mutex> lock(transitionDataMutex_);
1122     if (effectiveTransactionDataIndexMap_.count(remotePid) > 0 &&
1123         !effectiveTransactionDataIndexMap_[remotePid].second.empty()) {
1124         RS_LOGD("RSMainThread::ClearTransactionDataPidInfo process:%d destroyed, skip commands", remotePid);
1125     }
1126     effectiveTransactionDataIndexMap_.erase(remotePid);
1127     transactionDataLastWaitTime_.erase(remotePid);
1128 
1129     // clear cpu cache when process exit
1130     // CLEAN_CACHE_FREQ to prevent multiple cleanups in a short period of time
1131     if ((timestamp_ - lastCleanCacheTimestamp_) / REFRESH_PERIOD > CLEAN_CACHE_FREQ) {
1132 #ifdef RS_ENABLE_GL
1133         RS_LOGD("RSMainThread: clear cpu cache");
1134         auto grContext = RSBaseRenderEngine::GetRenderContext()->GetGrContext();
1135         grContext->flush();
1136         SkGraphics::PurgeAllCaches();
1137         grContext->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
1138         lastCleanCacheTimestamp_ = timestamp_;
1139 #endif
1140     }
1141 }
1142 
AddTransactionDataPidInfo(pid_t remotePid)1143 void RSMainThread::AddTransactionDataPidInfo(pid_t remotePid)
1144 {
1145     if (!isUniRender_) {
1146         return;
1147     }
1148     std::lock_guard<std::mutex> lock(transitionDataMutex_);
1149     if (effectiveTransactionDataIndexMap_.count(remotePid) > 0) {
1150         RS_LOGW("RSMainThread::AddTransactionDataPidInfo remotePid:%d already exists", remotePid);
1151     }
1152     effectiveTransactionDataIndexMap_[remotePid].first = 0;
1153 }
1154 
ClearDisplayBuffer()1155 void RSMainThread::ClearDisplayBuffer()
1156 {
1157     const std::shared_ptr<RSBaseRenderNode> node = context_->GetGlobalRootRenderNode();
1158     if (node == nullptr) {
1159         RS_LOGE("ClearDisplayBuffer get global root render node fail");
1160         return;
1161     }
1162     for (auto& child : node->GetSortedChildren()) {
1163         auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(child);
1164         if (displayNode == nullptr) {
1165             continue;
1166         }
1167         if (displayNode->GetRSSurface() != nullptr) {
1168             displayNode->GetRSSurface()->ResetBufferAge();
1169         }
1170     }
1171 }
1172 
SetDirtyFlag()1173 void RSMainThread::SetDirtyFlag()
1174 {
1175     isDirty_ = true;
1176 }
1177 
PerfAfterAnim()1178 void RSMainThread::PerfAfterAnim()
1179 {
1180     if (!IfUseUniVisitor()) {
1181         return;
1182     }
1183     if (!context_->animatingNodeList_.empty() && timestamp_ - prePerfTimestamp_ > PERF_PERIOD) {
1184         RS_LOGD("RSMainThread:: soc perf to render_service_animation");
1185         OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(PERF_ANIMATION_REQUESTED_CODE, "");
1186         prePerfTimestamp_ = timestamp_;
1187     } else if (context_->animatingNodeList_.empty()) {
1188         RS_LOGD("RSMainThread:: soc perf off render_service_animation");
1189         OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(PERF_ANIMATION_REQUESTED_CODE, false, "");
1190         prePerfTimestamp_ = 0;
1191     }
1192 }
ForceRefreshForUni()1193 void RSMainThread::ForceRefreshForUni()
1194 {
1195     if (isUniRender_) {
1196         PostTask([=]() {
1197             MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
1198             RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
1199             mainLoop_();
1200         });
1201         if (handler_) {
1202             auto screenManager_ = CreateOrGetScreenManager();
1203             if (screenManager_ != nullptr) {
1204                 PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
1205             }
1206         }
1207     } else {
1208         RequestNextVSync();
1209     }
1210 }
1211 
PerfForBlurIfNeeded()1212 void RSMainThread::PerfForBlurIfNeeded()
1213 {
1214     static int preBlurCnt = 0;
1215     int blurCnt = RSPropertiesPainter::GetAndResetBlurCnt();
1216     // clamp blurCnt to 0~3.
1217     blurCnt = std::clamp<int>(blurCnt, 0, 3);
1218     if (blurCnt != preBlurCnt && preBlurCnt != 0) {
1219         OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(BLUR_CNT_TO_BLUR_CODE.at(preBlurCnt), false, "");
1220         preBlurCnt = 0;
1221     }
1222     if (blurCnt == 0) {
1223         return;
1224     }
1225     static uint64_t prePerfTimestamp = 0;
1226     if (timestamp_ - prePerfTimestamp > PERF_PERIOD_BLUR || blurCnt != preBlurCnt) {
1227         OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(blurCnt), "");
1228         prePerfTimestamp = timestamp_;
1229         preBlurCnt = blurCnt;
1230     }
1231 }
1232 
PerfMultiWindow()1233 void RSMainThread::PerfMultiWindow()
1234 {
1235     if (!isUniRender_) {
1236         return;
1237     }
1238     static uint64_t lastPerfTimestamp = 0;
1239     if (appWindowNum_ >= MULTI_WINDOW_PERF_START_NUM && appWindowNum_ <= MULTI_WINDOW_PERF_END_NUM
1240         && timestamp_ - lastPerfTimestamp > PERF_PERIOD_MULTI_WINDOW) {
1241         RS_LOGD("RSMainThread::PerfMultiWindow soc perf");
1242         OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, "");
1243         lastPerfTimestamp = timestamp_;
1244     } else if ((appWindowNum_ < MULTI_WINDOW_PERF_START_NUM || appWindowNum_ > MULTI_WINDOW_PERF_END_NUM)
1245         && timestamp_ - lastPerfTimestamp < PERF_PERIOD_MULTI_WINDOW) {
1246         RS_LOGD("RSMainThread::PerfMultiWindow soc perf off");
1247         OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(PERF_MULTI_WINDOW_REQUESTED_CODE, false, "");
1248     }
1249 }
1250 
SetAppWindowNum(uint32_t num)1251 void RSMainThread::SetAppWindowNum(uint32_t num)
1252 {
1253     appWindowNum_ = num;
1254 }
1255 } // namespace Rosen
1256 } // namespace OHOS
1257