• 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         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