• 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 <list>
18 #include "include/core/SkGraphics.h"
19 #include "memory/rs_memory_graphic.h"
20 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
21 #include <securec.h>
22 #include <stdint.h>
23 #include <string>
24 #include <unistd.h>
25 #include <malloc.h>
26 #ifdef NEW_SKIA
27 #include "include/gpu/GrDirectContext.h"
28 #else
29 #include "include/gpu/GrContext.h"
30 #include "include/gpu/GrGpuResource.h"
31 #endif
32 #include "rs_trace.h"
33 
34 #include "animation/rs_animation_fraction.h"
35 #include "command/rs_message_processor.h"
36 #include "common/rs_background_thread.h"
37 #include "delegate/rs_functional_delegate.h"
38 #include "memory/rs_memory_manager.h"
39 #include "memory/rs_memory_track.h"
40 #include "common/rs_common_def.h"
41 #include "common/rs_optional_trace.h"
42 #include "hgm_core.h"
43 #include "platform/ohos/rs_jank_stats.h"
44 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
45 #include "pipeline/rs_base_render_node.h"
46 #include "pipeline/rs_base_render_util.h"
47 #include "pipeline/rs_cold_start_thread.h"
48 #include "pipeline/rs_divided_render_util.h"
49 #include "pipeline/rs_frame_report.h"
50 #include "pipeline/rs_render_engine.h"
51 #include "pipeline/rs_render_service_visitor.h"
52 #include "pipeline/rs_root_render_node.h"
53 #include "pipeline/rs_hardware_thread.h"
54 #include "pipeline/rs_surface_render_node.h"
55 #include "pipeline/rs_unmarshal_thread.h"
56 #include "pipeline/rs_uni_render_engine.h"
57 #include "pipeline/rs_uni_render_visitor.h"
58 #include "pipeline/rs_uni_render_util.h"
59 #include "pipeline/rs_occlusion_config.h"
60 #include "platform/common/rs_log.h"
61 #include "platform/common/rs_innovation.h"
62 #include "platform/common/rs_system_properties.h"
63 #include "platform/drawing/rs_vsync_client.h"
64 #include "property/rs_property_trace.h"
65 #include "property/rs_properties_painter.h"
66 #ifdef NEW_RENDER_CONTEXT
67 #include "render_context/memory_handler.h"
68 #endif
69 #include "render/rs_pixel_map_util.h"
70 #include "screen_manager/rs_screen_manager.h"
71 #include "transaction/rs_transaction_proxy.h"
72 
73 #include "rs_qos_thread.h"
74 #include "xcollie/watchdog.h"
75 
76 #include "render_frame_trace.h"
77 
78 #if defined(ACCESSIBILITY_ENABLE)
79 #include "accessibility_config.h"
80 #endif
81 
82 #ifdef SOC_PERF_ENABLE
83 #include "socperf_client.h"
84 #endif
85 
86 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
87 #include "pipeline/driven_render/rs_driven_render_manager.h"
88 #endif
89 
90 #if defined(RS_ENABLE_RECORDING)
91 #include "benchmarks/rs_recording_thread.h"
92 #endif
93 
94 #include "scene_board_judgement.h"
95 #include "vsync_iconnection_token.h"
96 
97 using namespace FRAME_TRACE;
98 static const std::string RS_INTERVAL_NAME = "renderservice";
99 
100 #if defined(ACCESSIBILITY_ENABLE)
101 using namespace OHOS::AccessibilityConfig;
102 #endif
103 
104 namespace OHOS {
105 namespace Rosen {
106 namespace {
107 constexpr uint32_t REQUEST_VSYNC_NUMBER_LIMIT = 10;
108 constexpr uint64_t REFRESH_PERIOD = 16666667;
109 constexpr int32_t PERF_MULTI_WINDOW_REQUESTED_CODE = 10026;
110 constexpr int32_t FLUSH_SYNC_TRANSACTION_TIMEOUT = 100;
111 constexpr uint64_t PERF_PERIOD = 250000000;
112 constexpr uint64_t CLEAN_CACHE_FREQ = 60;
113 constexpr uint64_t SKIP_COMMAND_FREQ_LIMIT = 30;
114 constexpr uint64_t PERF_PERIOD_BLUR = 80000000;
115 constexpr const char* MEM_GPU_TYPE = "gpu";
116 constexpr uint64_t PERF_PERIOD_MULTI_WINDOW = 80000000;
117 constexpr uint32_t MULTI_WINDOW_PERF_START_NUM = 2;
118 constexpr uint32_t MULTI_WINDOW_PERF_END_NUM = 4;
119 constexpr uint32_t WAIT_FOR_RELEASED_BUFFER_TIMEOUT = 3000;
120 constexpr const char* WALLPAPER_VIEW = "WallpaperView";
121 #ifdef RS_ENABLE_GL
122 constexpr size_t DEFAULT_SKIA_CACHE_SIZE        = 96 * (1 << 20);
123 constexpr int DEFAULT_SKIA_CACHE_COUNT          = 2 * (1 << 12);
124 #endif
125 const std::map<int, int32_t> BLUR_CNT_TO_BLUR_CODE {
126     { 1, 10021 },
127     { 2, 10022 },
128     { 3, 10023 },
129 };
130 
Compare(const std::unique_ptr<RSTransactionData> & data1,const std::unique_ptr<RSTransactionData> & data2)131 bool Compare(const std::unique_ptr<RSTransactionData>& data1, const std::unique_ptr<RSTransactionData>& data2)
132 {
133     if (!data1 || !data2) {
134         RS_LOGW("Compare RSTransactionData: nullptr!");
135         return true;
136     }
137     return data1->GetIndex() < data2->GetIndex();
138 }
139 
InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>> & source,std::vector<std::unique_ptr<RSTransactionData>> & target)140 void InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>>& source,
141     std::vector<std::unique_ptr<RSTransactionData>>& target)
142 {
143     target.insert(target.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.end()));
144     source.clear();
145 }
146 
PerfRequest(int32_t perfRequestCode,bool onOffTag)147 void PerfRequest(int32_t perfRequestCode, bool onOffTag)
148 {
149 #ifdef SOC_PERF_ENABLE
150     OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(perfRequestCode, onOffTag, "");
151     RS_LOGD("RSMainThread::soc perf info [%d %d]", perfRequestCode, onOffTag);
152 #endif
153 }
154 }
155 
156 #if defined(ACCESSIBILITY_ENABLE)
157 class AccessibilityObserver : public AccessibilityConfigObserver {
158 public:
159     AccessibilityObserver() = default;
OnConfigChanged(const CONFIG_ID id,const ConfigValue & value)160     void OnConfigChanged(const CONFIG_ID id, const ConfigValue &value) override
161     {
162         RS_LOGD("AccessibilityObserver OnConfigChanged");
163         ColorFilterMode mode = ColorFilterMode::COLOR_FILTER_END;
164         if (id == CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER) {
165             switch (value.daltonizationColorFilter) {
166                 case Protanomaly:
167                     mode = ColorFilterMode::DALTONIZATION_PROTANOMALY_MODE;
168                     break;
169                 case Deuteranomaly:
170                     mode = ColorFilterMode::DALTONIZATION_DEUTERANOMALY_MODE;
171                     break;
172                 case Tritanomaly:
173                     mode = ColorFilterMode::DALTONIZATION_TRITANOMALY_MODE;
174                     break;
175                 case Normal:
176                     mode = ColorFilterMode::DALTONIZATION_NORMAL_MODE;
177                     break;
178                 default:
179                     break;
180             }
181             RSBaseRenderEngine::SetColorFilterMode(mode);
182         } else if (id == CONFIG_ID::CONFIG_INVERT_COLOR) {
183             mode = value.invertColor ? ColorFilterMode::INVERT_COLOR_ENABLE_MODE :
184                                         ColorFilterMode::INVERT_COLOR_DISABLE_MODE;
185             RSBaseRenderEngine::SetColorFilterMode(mode);
186         } else {
187             RSBaseRenderEngine::SetHighContrast(value.highContrastText);
188         }
189         RSMainThread::Instance()->PostTask([]() {
190             RSMainThread::Instance()->SetAccessibilityConfigChanged();
191             RSMainThread::Instance()->RequestNextVSync();
192         });
193     }
194 };
195 #endif
Instance()196 RSMainThread* RSMainThread::Instance()
197 {
198     static RSMainThread instance;
199     RSAnimationFraction::Init();
200     return &instance;
201 }
202 
RSMainThread()203 RSMainThread::RSMainThread() : mainThreadId_(std::this_thread::get_id())
204 {
205     context_ = std::make_shared<RSContext>();
206 }
207 
~RSMainThread()208 RSMainThread::~RSMainThread() noexcept
209 {
210     RemoveRSEventDetector();
211     RSInnovation::CloseInnovationSo();
212 }
213 
Init()214 void RSMainThread::Init()
215 {
216     mainLoop_ = [&]() {
217         RenderFrameStart();
218         PerfMultiWindow();
219         SetRSEventDetectorLoopStartTag();
220         ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSMainThread::DoComposition");
221         ConsumeAndUpdateAllNodes();
222         WaitUntilUnmarshallingTaskFinished();
223         ProcessCommand();
224         Animate(timestamp_);
225         CollectInfoForHardwareComposer();
226 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
227         CollectInfoForDrivenRender();
228 #endif
229         CheckColdStartMap();
230         Render();
231         InformHgmNodeInfo();
232         ReleaseAllNodesBuffer();
233         SendCommands();
234         activeAppsInProcess_.clear();
235         activeProcessNodeIds_.clear();
236         ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
237         SetRSEventDetectorLoopFinishTag();
238         rsEventManager_.UpdateParam();
239     };
240 #ifdef RS_ENABLE_RECORDING
241     RSRecordingThread::Instance().Start();
242 #endif
243     isUniRender_ = RSUniRenderJudgement::IsUniRender();
244     SetDeviceType();
245     RsFrameReport::GetInstance().Init();
246     if (isUniRender_) {
247         unmarshalBarrierTask_ = [this]() {
248             auto cachedTransactionData = RSUnmarshalThread::Instance().GetCachedTransactionData();
249             MergeToEffectiveTransactionDataMap(cachedTransactionData);
250             {
251                 std::lock_guard<std::mutex> lock(unmarshalMutex_);
252                 ++unmarshalFinishedCount_;
253             }
254             unmarshalTaskCond_.notify_all();
255         };
256         RSUnmarshalThread::Instance().Start();
257     }
258 
259     runner_ = AppExecFwk::EventRunner::Create(false);
260     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
261     int ret = HiviewDFX::Watchdog::GetInstance().AddThread("RenderService", handler_);
262     if (ret != 0) {
263         RS_LOGW("Add watchdog thread failed");
264     }
265     InitRSEventDetector();
266     sptr<VSyncIConnectionToken> token = new IRemoteStub<VSyncIConnectionToken>();
267     sptr<VSyncConnection> conn = new VSyncConnection(rsVSyncDistributor_, "rs", token->AsObject());
268     rsVSyncDistributor_->AddConnection(conn);
269     receiver_ = std::make_shared<VSyncReceiver>(conn, token->AsObject(), handler_);
270     receiver_->Init();
271     if (isUniRender_) {
272         uniRenderEngine_ = std::make_shared<RSUniRenderEngine>();
273         uniRenderEngine_->Init();
274     } else {
275         renderEngine_ = std::make_shared<RSRenderEngine>();
276         renderEngine_->Init();
277     }
278 #ifdef RS_ENABLE_GL
279     int cacheLimitsTimes = 3;
280 #ifndef USE_ROSEN_DRAWING
281 #ifdef NEW_RENDER_CONTEXT
282     auto grContext = isUniRender_? uniRenderEngine_->GetDrawingContext()->GetDrawingContext() :
283         renderEngine_->GetDrawingContext()->GetDrawingContext();
284 #else
285     auto grContext = isUniRender_? uniRenderEngine_->GetRenderContext()->GetGrContext() :
286         renderEngine_->GetRenderContext()->GetGrContext();
287 #endif
288     int maxResources = 0;
289     size_t maxResourcesSize = 0;
290     grContext->getResourceCacheLimits(&maxResources, &maxResourcesSize);
291     if (maxResourcesSize > 0) {
292         grContext->setResourceCacheLimits(cacheLimitsTimes * maxResources, cacheLimitsTimes *
293             std::fmin(maxResourcesSize, DEFAULT_SKIA_CACHE_SIZE));
294     } else {
295         grContext->setResourceCacheLimits(DEFAULT_SKIA_CACHE_COUNT, DEFAULT_SKIA_CACHE_SIZE);
296     }
297 #else
298     auto gpuContext = isUniRender_? uniRenderEngine_->GetRenderContext()->GetDrGPUContext() :
299         renderEngine_->GetRenderContext()->GetDrGPUContext();
300     if (gpuContext == nullptr) {
301         RS_LOGE("RSMainThread::Init gpuContext is nullptr!");
302         return;
303     }
304     int32_t maxResources = 0;
305     size_t maxResourcesSize = 0;
306     gpuContext->GetResourceCacheLimits(maxResources, maxResourcesSize);
307     if (maxResourcesSize > 0) {
308         gpuContext->SetResourceCacheLimits(cacheLimitsTimes * maxResources, cacheLimitsTimes * maxResourcesSize);
309     } else {
310         gpuContext->SetResourceCacheLimits(DEFAULT_SKIA_CACHE_COUNT, DEFAULT_SKIA_CACHE_SIZE);
311     }
312 #endif
313 #endif
314     RSInnovation::OpenInnovationSo();
315 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
316     RSDrivenRenderManager::InitInstance();
317 #endif
318 
319 #if defined(ACCESSIBILITY_ENABLE)
320     accessibilityObserver_ = std::make_shared<AccessibilityObserver>();
321     auto &config = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
322     config.InitializeContext();
323     config.SubscribeConfigObserver(CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER, accessibilityObserver_);
324     config.SubscribeConfigObserver(CONFIG_ID::CONFIG_INVERT_COLOR, accessibilityObserver_);
325     if (isUniRender_) {
326         config.SubscribeConfigObserver(CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT, accessibilityObserver_);
327     }
328 #endif
329 
330     auto delegate = RSFunctionalDelegate::Create();
331     delegate->SetRepaintCallback([]() { RSMainThread::Instance()->RequestNextVSync(); });
332     RSOverdrawController::GetInstance().SetDelegate(delegate);
333 
334     frameRateMgr_ = std::make_unique<HgmFrameRateManager>();
335 }
336 
RsEventParamDump(std::string & dumpString)337 void RSMainThread::RsEventParamDump(std::string& dumpString)
338 {
339     rsEventManager_.DumpAllEventParam(dumpString);
340 }
341 
RemoveRSEventDetector()342 void RSMainThread::RemoveRSEventDetector()
343 {
344     if (rsCompositionTimeoutDetector_ != nullptr) {
345         rsEventManager_.RemoveEvent(rsCompositionTimeoutDetector_->GetStringId());
346     }
347 }
348 
InitRSEventDetector()349 void RSMainThread::InitRSEventDetector()
350 {
351     // default Threshold value of Timeout Event: 100ms
352     rsCompositionTimeoutDetector_ = RSBaseEventDetector::CreateRSTimeOutDetector(100, "RS_COMPOSITION_TIMEOUT");
353     if (rsCompositionTimeoutDetector_ != nullptr) {
354         rsEventManager_.AddEvent(rsCompositionTimeoutDetector_, 60000); // report Internal 1min:60s:60000ms
355         RS_LOGD("InitRSEventDetector finish");
356     }
357 }
358 
SetDeviceType()359 void RSMainThread::SetDeviceType()
360 {
361     auto deviceTypeStr = system::GetParameter("const.product.devicetype", "pc");
362     if (deviceTypeStr == "pc") {
363         deviceType_ = DeviceType::PC;
364     } else if (deviceTypeStr == "tablet") {
365         deviceType_ = DeviceType::TABLET;
366     } else if (deviceTypeStr == "phone") {
367         deviceType_ = DeviceType::PHONE;
368     } else {
369         deviceType_ = DeviceType::OTHERS;
370     }
371 }
372 
SetIsCachedSurfaceUpdated(bool isCachedSurfaceUpdated)373 void RSMainThread::SetIsCachedSurfaceUpdated(bool isCachedSurfaceUpdated)
374 {
375     isCachedSurfaceUpdated_ = isCachedSurfaceUpdated;
376 }
377 
SetRSEventDetectorLoopStartTag()378 void RSMainThread::SetRSEventDetectorLoopStartTag()
379 {
380     if (rsCompositionTimeoutDetector_ != nullptr) {
381         rsCompositionTimeoutDetector_->SetLoopStartTag();
382     }
383 }
384 
SetRSEventDetectorLoopFinishTag()385 void RSMainThread::SetRSEventDetectorLoopFinishTag()
386 {
387     if (rsCompositionTimeoutDetector_ != nullptr) {
388         if (isUniRender_) {
389             rsCompositionTimeoutDetector_->SetLoopFinishTag(
390                 focusAppPid_, focusAppUid_, focusAppBundleName_, focusAppAbilityName_);
391         } else {
392             std::string defaultFocusAppInfo = "";
393             rsCompositionTimeoutDetector_->SetLoopFinishTag(
394                 -1, -1, defaultFocusAppInfo, defaultFocusAppInfo);
395         }
396     }
397 }
398 
SetFocusAppInfo(int32_t pid,int32_t uid,const std::string & bundleName,const std::string & abilityName,uint64_t focusNodeId)399 void RSMainThread::SetFocusAppInfo(
400     int32_t pid, int32_t uid, const std::string &bundleName, const std::string &abilityName, uint64_t focusNodeId)
401 {
402     focusAppPid_ = pid;
403     focusAppUid_ = uid;
404     focusAppBundleName_ = bundleName;
405     focusAppAbilityName_ = abilityName;
406     focusNodeId_ = focusNodeId;
407 }
408 
Start()409 void RSMainThread::Start()
410 {
411     if (runner_) {
412         runner_->Run();
413     }
414 }
415 
ProcessCommand()416 void RSMainThread::ProcessCommand()
417 {
418     // To improve overall responsiveness, we make animations start on LAST frame instead of THIS frame.
419     // If last frame is too far away (earlier than 1 vsync from now), we use currentTimestamp_ - REFRESH_PERIOD as
420     // 'virtual' last frame timestamp.
421     if (timestamp_ - lastAnimateTimestamp_ > REFRESH_PERIOD) { // if last frame is earlier than 1 vsync from now
422         context_->currentTimestamp_ = timestamp_ - REFRESH_PERIOD;
423     } else {
424         context_->currentTimestamp_ = lastAnimateTimestamp_;
425     }
426     if (isUniRender_) {
427         ProcessCommandForUniRender();
428     } else {
429         ProcessCommandForDividedRender();
430     }
431     if (RsFrameReport::GetInstance().GetEnable()) {
432         RsFrameReport::GetInstance().AnimateStart();
433     }
434 }
435 
CacheCommands()436 void RSMainThread::CacheCommands()
437 {
438     RS_OPTIONAL_TRACE_FUNC_BEGIN();
439     for (auto& skipTransactionData : cachedSkipTransactionDataMap_) {
440         pid_t pid = skipTransactionData.first;
441         RS_TRACE_NAME("cacheCmd pid: " + std::to_string(pid));
442         auto& skipTransactionDataVec = skipTransactionData.second;
443         cachedTransactionDataMap_[pid].insert(cachedTransactionDataMap_[pid].begin(),
444             std::make_move_iterator(skipTransactionDataVec.begin()),
445             std::make_move_iterator(skipTransactionDataVec.end()));
446     }
447     RS_OPTIONAL_TRACE_FUNC_END();
448 }
449 
CheckIfNodeIsBundle(std::shared_ptr<RSSurfaceRenderNode> node)450 void RSMainThread::CheckIfNodeIsBundle(std::shared_ptr<RSSurfaceRenderNode> node)
451 {
452     currentBundleName_ = node->GetBundleName();
453     if (node->GetName() == WALLPAPER_VIEW) {
454         noBundle_ = true;
455     }
456 }
457 
InformHgmNodeInfo()458 void RSMainThread::InformHgmNodeInfo()
459 {
460     auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
461     int32_t informResult = EXEC_SUCCESS;
462     if (currentBundleName_ != "") {
463         informResult = hgmCore.RefreshBundleName(currentBundleName_);
464     } else if (noBundle_) {
465         currentBundleName_ = "";
466         informResult = hgmCore.RefreshBundleName(currentBundleName_);
467         noBundle_ = false;
468     }
469     if (informResult != EXEC_SUCCESS) {
470         RS_LOGE("RSMainThread::InformHgmNodeInfo failed to refresh bundle name in hgm");
471     }
472 }
473 
GetCacheCmdSkippedNodes() const474 std::unordered_map<NodeId, bool> RSMainThread::GetCacheCmdSkippedNodes() const
475 {
476     return cacheCmdSkippedNodes_;
477 }
478 
CheckParallelSubThreadNodesStatus()479 void RSMainThread::CheckParallelSubThreadNodesStatus()
480 {
481     RS_OPTIONAL_TRACE_FUNC_BEGIN();
482     cacheCmdSkippedInfo_.clear();
483     cacheCmdSkippedNodes_.clear();
484     for (auto& node : subThreadNodes_) {
485         if (node == nullptr) {
486             RS_LOGE("RSMainThread::CheckParallelSubThreadNodesStatus sunThreadNode is nullptr!");
487             continue;
488         }
489         if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
490             RS_TRACE_NAME("node:[ " + node->GetName() + "]");
491             pid_t pid = 0;
492             if (node->IsAppWindow()) {
493                 pid = ExtractPid(node->GetId());
494             } else if (node->IsLeashWindow()) {
495                 for (auto& child : node->GetSortedChildren()) {
496                     auto surfaceNodePtr = child->ReinterpretCastTo<RSSurfaceRenderNode>();
497                     if (surfaceNodePtr && surfaceNodePtr->IsAppWindow()) {
498                         pid = ExtractPid(child->GetId());
499                         break;
500                     }
501                 }
502             }
503             cacheCmdSkippedNodes_[node->GetId()] = false;
504             if (pid == 0) {
505                 continue;
506             }
507             RS_LOGD("RSMainThread::CheckParallelSubThreadNodesStatus pid = %s, node name: %s, id: %llu",
508                 std::to_string(pid).c_str(), node->GetName().c_str(), node->GetId());
509             if (cacheCmdSkippedInfo_.count(pid) == 0) {
510                 cacheCmdSkippedInfo_[pid] = std::make_pair(std::vector<NodeId>{node->GetId()}, false);
511             } else {
512                 cacheCmdSkippedInfo_[pid].first.push_back(node->GetId());
513             }
514         }
515     }
516     RS_OPTIONAL_TRACE_FUNC_END();
517 }
518 
IsNeedSkip(NodeId instanceRootNodeId,pid_t pid)519 bool RSMainThread::IsNeedSkip(NodeId instanceRootNodeId, pid_t pid)
520 {
521     for (auto& cacheCmdSkipNodeId: cacheCmdSkippedInfo_[pid].first) {
522         if (cacheCmdSkipNodeId == instanceRootNodeId) {
523             return true;
524         }
525     }
526     return false;
527 }
528 
SkipCommandByNodeId(std::vector<std::unique_ptr<RSTransactionData>> & transactionVec,pid_t pid)529 void RSMainThread::SkipCommandByNodeId(std::vector<std::unique_ptr<RSTransactionData>>& transactionVec, pid_t pid)
530 {
531     if (cacheCmdSkippedInfo_.find(pid) == cacheCmdSkippedInfo_.end()) {
532         return;
533     }
534     std::vector<std::unique_ptr<RSTransactionData>> skipTransactionVec;
535     const auto& nodeMap = context_->GetNodeMap();
536     for (auto& transactionData: transactionVec) {
537         std::vector<std::tuple<NodeId, FollowType, std::unique_ptr<RSCommand>>> skipPayload;
538         std::vector<size_t> skipPayloadIndexVec;
539         auto& processPayload = transactionData->GetPayload();
540         for (size_t index = 0; index < processPayload.size(); ++index) {
541             auto& elem = processPayload[index];
542             if (std::get<2>(elem) == nullptr) { // check elem is valid
543                 continue;
544             }
545             NodeId nodeId = std::get<2>(elem)->GetNodeId();
546             auto node = nodeMap.GetRenderNode(nodeId);
547             if (node == nullptr) {
548                 continue;
549             }
550             NodeId instanceRootNodeId = node->GetInstanceRootNodeId();
551             if (IsNeedSkip(instanceRootNodeId, pid)) {
552                 skipPayload.emplace_back(std::move(elem));
553                 skipPayloadIndexVec.push_back(index);
554             }
555         }
556         if (!skipPayload.empty()) {
557             std::unique_ptr<RSTransactionData> skipTransactionData = std::make_unique<RSTransactionData>();
558             skipTransactionData->SetTimestamp(transactionData->GetTimestamp());
559             std::string ablityName = transactionData->GetAbilityName();
560             skipTransactionData->SetAbilityName(ablityName);
561             skipTransactionData->SetSendingPid(transactionData->GetSendingPid());
562             skipTransactionData->SetIndex(transactionData->GetIndex());
563             skipTransactionData->GetPayload() = std::move(skipPayload);
564             skipTransactionData->SetIsCached(true);
565             skipTransactionVec.emplace_back(std::move(skipTransactionData));
566         }
567         for (auto iter = skipPayloadIndexVec.rbegin(); iter != skipPayloadIndexVec.rend(); ++iter) {
568             processPayload.erase(processPayload.begin() + *iter);
569         }
570     }
571     if (!skipTransactionVec.empty()) {
572         cachedSkipTransactionDataMap_[pid] = std::move(skipTransactionVec);
573     }
574 }
575 
CheckAndUpdateTransactionIndex(std::shared_ptr<TransactionDataMap> & transactionDataEffective,std::string & transactionFlags)576 void RSMainThread::CheckAndUpdateTransactionIndex(std::shared_ptr<TransactionDataMap>& transactionDataEffective,
577     std::string& transactionFlags)
578 {
579     for (auto& rsTransactionElem: effectiveTransactionDataIndexMap_) {
580         auto pid = rsTransactionElem.first;
581         auto& lastIndex = rsTransactionElem.second.first;
582         auto& transactionVec = rsTransactionElem.second.second;
583         auto iter = transactionVec.begin();
584         for (; iter != transactionVec.end(); ++iter) {
585             if ((*iter) == nullptr) {
586                 continue;
587             }
588             if ((*iter)->GetIsCached()) {
589                 continue;
590             }
591             auto curIndex = (*iter)->GetIndex();
592             if (curIndex == lastIndex + 1) {
593                 if ((*iter)->GetTimestamp() >= timestamp_) {
594                     break;
595                 }
596                 ++lastIndex;
597                 transactionFlags += " [" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
598             } else {
599                 RS_LOGE("%s wait curIndex:%llu, lastIndex:%llu, pid:%d", __FUNCTION__, curIndex, lastIndex, pid);
600                 if (transactionDataLastWaitTime_[pid] == 0) {
601                     transactionDataLastWaitTime_[pid] = timestamp_;
602                 }
603                 if ((timestamp_ - transactionDataLastWaitTime_[pid]) / REFRESH_PERIOD > SKIP_COMMAND_FREQ_LIMIT) {
604                     transactionDataLastWaitTime_[pid] = 0;
605                     lastIndex = curIndex;
606                     transactionFlags += " skip to[" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
607                     RS_LOGE("%s skip to index:%llu, pid:%d", __FUNCTION__, curIndex, pid);
608                     continue;
609                 }
610                 break;
611             }
612         }
613         if (iter != transactionVec.begin()) {
614             (*transactionDataEffective)[pid].insert((*transactionDataEffective)[pid].end(),
615                 std::make_move_iterator(transactionVec.begin()), std::make_move_iterator(iter));
616             transactionVec.erase(transactionVec.begin(), iter);
617         }
618     }
619 }
620 
ProcessCommandForUniRender()621 void RSMainThread::ProcessCommandForUniRender()
622 {
623     ResetHardwareEnabledState();
624     std::shared_ptr<TransactionDataMap> transactionDataEffective = std::make_shared<TransactionDataMap>();
625     std::string transactionFlags;
626     if (RSSystemProperties::GetUIFirstEnabled() && RSSystemProperties::GetCacheCmdEnabled()) {
627         CheckParallelSubThreadNodesStatus();
628     }
629     {
630         std::lock_guard<std::mutex> lock(transitionDataMutex_);
631         cachedSkipTransactionDataMap_.clear();
632         for (auto& rsTransactionElem: effectiveTransactionDataIndexMap_) {
633             auto pid = rsTransactionElem.first;
634             auto& transactionVec = rsTransactionElem.second.second;
635             if (RSSystemProperties::GetUIFirstEnabled() && RSSystemProperties::GetCacheCmdEnabled()) {
636                 SkipCommandByNodeId(transactionVec, pid);
637             }
638             std::sort(transactionVec.begin(), transactionVec.end(), Compare);
639         }
640         if (RSSystemProperties::GetUIFirstEnabled() && RSSystemProperties::GetCacheCmdEnabled()) {
641             CacheCommands();
642         }
643         CheckAndUpdateTransactionIndex(transactionDataEffective, transactionFlags);
644     }
645     if (!transactionDataEffective->empty()) {
646         doDirectComposition_ = false;
647     }
648     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::ProcessCommandUni" + transactionFlags);
649     for (auto& rsTransactionElem: *transactionDataEffective) {
650         for (auto& rsTransaction: rsTransactionElem.second) {
651             if (rsTransaction) {
652                 if (rsTransaction->IsNeedSync() || syncTransactionData_.count(rsTransactionElem.first) > 0) {
653                     ProcessSyncRSTransactionData(rsTransaction, rsTransactionElem.first);
654                     continue;
655                 }
656                 ProcessRSTransactionData(rsTransaction, rsTransactionElem.first);
657             }
658         }
659     }
660     RSBackgroundThread::Instance().PostTask([ transactionDataEffective ] () {
661         RS_TRACE_NAME("RSMainThread::ProcessCommandForUniRender transactionDataEffective clear");
662         transactionDataEffective->clear();
663     });
664     RS_OPTIONAL_TRACE_END();
665 }
666 
ProcessCommandForDividedRender()667 void RSMainThread::ProcessCommandForDividedRender()
668 {
669     const auto& nodeMap = context_->GetNodeMap();
670     RS_TRACE_BEGIN("RSMainThread::ProcessCommand");
671     {
672         std::lock_guard<std::mutex> lock(transitionDataMutex_);
673         if (!pendingEffectiveCommands_.empty()) {
674             effectiveCommands_.swap(pendingEffectiveCommands_);
675         }
676         for (auto& [surfaceNodeId, commandMap] : cachedCommands_) {
677             auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(surfaceNodeId);
678             auto bufferTimestamp = bufferTimestamps_.find(surfaceNodeId);
679             std::map<uint64_t, std::vector<std::unique_ptr<RSCommand>>>::iterator effectIter;
680 
681             if (!node || !node->IsOnTheTree() || bufferTimestamp == bufferTimestamps_.end()) {
682                 // If node has been destructed or is not on the tree or has no valid buffer,
683                 // for all command cached in commandMap should be executed immediately
684                 effectIter = commandMap.end();
685             } else {
686                 uint64_t timestamp = bufferTimestamp->second;
687                 effectIter = commandMap.upper_bound(timestamp);
688             }
689 
690             for (auto it = commandMap.begin(); it != effectIter; it++) {
691                 effectiveCommands_[it->first].insert(effectiveCommands_[it->first].end(),
692                     std::make_move_iterator(it->second.begin()), std::make_move_iterator(it->second.end()));
693             }
694             commandMap.erase(commandMap.begin(), effectIter);
695         }
696     }
697     for (auto& [timestamp, commands] : effectiveCommands_) {
698         context_->transactionTimestamp_ = timestamp;
699         for (auto& command : commands) {
700             if (command) {
701                 command->Process(*context_);
702             }
703         }
704     }
705     effectiveCommands_.clear();
706     RS_TRACE_END();
707 }
708 
ProcessRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData,pid_t pid)709 void RSMainThread::ProcessRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData, pid_t pid)
710 {
711     context_->transactionTimestamp_ = rsTransactionData->GetTimestamp();
712     rsTransactionData->Process(*context_);
713     for (auto& [nodeId, followType, command] : rsTransactionData->GetPayload()) {
714         if (command != nullptr) {
715             AddActiveNodeId(pid, command->GetNodeId());
716         }
717     }
718 }
719 
ProcessSyncRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData,pid_t pid)720 void RSMainThread::ProcessSyncRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData, pid_t pid)
721 {
722     if (!rsTransactionData->IsNeedSync()) {
723         syncTransactionData_[pid].emplace_back(std::move(rsTransactionData));
724         return;
725     }
726 
727     if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
728         (syncTransactionData_.begin()->second.front()->GetSyncId() > rsTransactionData->GetSyncId())) {
729         ROSEN_LOGD("RSMainThread ProcessSyncRSTransactionData while syncId less GetCommandCount: %lu pid: %llu",
730             rsTransactionData->GetCommandCount(), rsTransactionData->GetSendingPid());
731         ProcessRSTransactionData(rsTransactionData, pid);
732         return;
733     }
734 
735     bool isNeedCloseSync = rsTransactionData->IsNeedCloseSync();
736     if (syncTransactionData_.empty()) {
737         if (handler_) {
738             auto task = [this]() {
739                 ROSEN_LOGD("RSMainThread ProcessAllSyncTransactionData timeout task");
740                 ProcessAllSyncTransactionData();
741             };
742             handler_->PostTask(task, "ProcessAllSyncTransactionsTimeoutTask", FLUSH_SYNC_TRANSACTION_TIMEOUT);
743         }
744     }
745     if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
746         (syncTransactionData_.begin()->second.front()->GetSyncId() != rsTransactionData->GetSyncId())) {
747         ProcessAllSyncTransactionData();
748     }
749     if (syncTransactionData_.count(pid) == 0) {
750         syncTransactionData_.insert({ pid, std::vector<std::unique_ptr<RSTransactionData>>() });
751     }
752     if (isNeedCloseSync) {
753         syncTransactionCount_ += rsTransactionData->GetSyncTransactionNum();
754     } else {
755         syncTransactionCount_ -= 1;
756     }
757     syncTransactionData_[pid].emplace_back(std::move(rsTransactionData));
758     if (syncTransactionCount_ == 0) {
759         ProcessAllSyncTransactionData();
760     }
761 }
762 
ProcessAllSyncTransactionData()763 void RSMainThread::ProcessAllSyncTransactionData()
764 {
765     for (auto& [pid, transactions] : syncTransactionData_) {
766         for (auto& transaction: transactions) {
767             ROSEN_LOGD("RSMainThread ProcessAllSyncTransactionData GetCommandCount: %lu pid: %llu",
768                 transaction->GetCommandCount(), pid);
769             ProcessRSTransactionData(transaction, pid);
770         }
771     }
772     syncTransactionData_.clear();
773     syncTransactionCount_ = 0;
774     RequestNextVSync();
775 }
776 
ConsumeAndUpdateAllNodes()777 void RSMainThread::ConsumeAndUpdateAllNodes()
778 {
779     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::ConsumeAndUpdateAllNodes");
780     bool needRequestNextVsync = false;
781     bufferTimestamps_.clear();
782     const auto& nodeMap = GetContext().GetNodeMap();
783     nodeMap.TraverseSurfaceNodes(
784         [this, &needRequestNextVsync](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
785         if (surfaceNode == nullptr) {
786             return;
787         }
788         auto& surfaceHandler = static_cast<RSSurfaceHandler&>(*surfaceNode);
789         surfaceHandler.ResetCurrentFrameBufferConsumed();
790         if (RSBaseRenderUtil::ConsumeAndUpdateBuffer(surfaceHandler)) {
791             this->bufferTimestamps_[surfaceNode->GetId()] = static_cast<uint64_t>(surfaceNode->GetTimestamp());
792             if (surfaceNode->IsCurrentFrameBufferConsumed()) {
793                 // collect surface view's pid to prevent wrong skip
794                 AddActiveNodeId(ExtractPid(surfaceNode->GetId()), surfaceNode->GetId());
795             }
796         }
797 
798         // still have buffer(s) to consume.
799         if (surfaceHandler.GetAvailableBufferCount() > 0) {
800             needRequestNextVsync = true;
801         }
802     });
803 
804     if (needRequestNextVsync) {
805         RequestNextVSync();
806     }
807     RS_OPTIONAL_TRACE_END();
808 }
809 
CollectInfoForHardwareComposer()810 void RSMainThread::CollectInfoForHardwareComposer()
811 {
812     if (!isUniRender_ || !RSSystemProperties::GetHardwareComposerEnabled()) {
813         return;
814     }
815     const auto& nodeMap = GetContext().GetNodeMap();
816     nodeMap.TraverseSurfaceNodes(
817         [this](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
818             if (surfaceNode == nullptr || !surfaceNode->IsOnTheTree()) {
819                 return;
820             }
821             if (surfaceNode->IsAppWindow()) {
822                 const auto& property = surfaceNode->GetRenderProperties();
823                 if (property.NeedFilter() || property.IsShadowValid()) {
824                     isHardwareForcedDisabled_ = true;
825                     return;
826                 }
827             }
828             auto& surfaceHandler = static_cast<RSSurfaceHandler&>(*surfaceNode);
829             if (surfaceHandler.IsCurrentFrameBufferConsumed()) {
830                 if (!surfaceNode->IsHardwareEnabledType() ||
831                     surfaceNode->GetSrcRect().IsEmpty() || surfaceNode->GetDstRect().IsEmpty()) {
832                     doDirectComposition_ = false;
833                 } else {
834                     isHardwareEnabledBufferUpdated_ = true;
835                 }
836             }
837 
838             if (surfaceNode->IsHardwareEnabledType() && surfaceNode->GetBuffer() != nullptr) {
839                 hardwareEnabledNodes_.emplace_back(surfaceNode);
840                 if (!surfaceNode->IsLastFrameHardwareEnabled()) {
841                     doDirectComposition_ = false;
842                 }
843             }
844         });
845 
846     if (doWindowAnimate_ || isHardwareForcedDisabled_) {
847         // setDirty for surfaceView if last frame is hardware enabled
848         for (auto& surfaceNode : hardwareEnabledNodes_) {
849             if (surfaceNode->IsLastFrameHardwareEnabled()) {
850                 surfaceNode->SetContentDirty();
851                 AddActiveNodeId(ExtractPid(surfaceNode->GetId()), surfaceNode->GetId());
852             }
853         }
854     }
855 }
856 
CollectInfoForDrivenRender()857 void RSMainThread::CollectInfoForDrivenRender()
858 {
859 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
860     hasDrivenNodeOnUniTree_ = false;
861     hasDrivenNodeMarkRender_ = false;
862     if (!isUniRender_ || !RSSystemProperties::GetHardwareComposerEnabled() ||
863         !RSDrivenRenderManager::GetInstance().GetDrivenRenderEnabled()) {
864         return;
865     }
866 
867     std::vector<std::shared_ptr<RSRenderNode>> drivenNodes;
868     std::vector<std::shared_ptr<RSRenderNode>> markRenderDrivenNodes;
869 
870     const auto& nodeMap = GetContext().GetNodeMap();
871     nodeMap.TraverseDrivenRenderNodes(
872         [&](const std::shared_ptr<RSRenderNode>& node) mutable {
873             if (node == nullptr || !node->IsOnTheTree()) {
874                 return;
875             }
876             drivenNodes.emplace_back(node);
877             if (node->GetPaintState()) {
878                 markRenderDrivenNodes.emplace_back(node);
879             }
880         });
881 
882     for (auto& node : drivenNodes) {
883         node->SetPaintState(false);
884         node->SetIsMarkDrivenRender(false);
885     }
886     if (!drivenNodes.empty()) {
887         hasDrivenNodeOnUniTree_ = true;
888     } else {
889         hasDrivenNodeOnUniTree_ = false;
890     }
891     if (markRenderDrivenNodes.size() == 1) { // only support 1 driven node
892         auto node = markRenderDrivenNodes.front();
893         node->SetIsMarkDrivenRender(true);
894         hasDrivenNodeMarkRender_ = true;
895     } else {
896         hasDrivenNodeMarkRender_ = false;
897     }
898 #endif
899 }
900 
NeedReleaseGpuResource(const RSRenderNodeMap & nodeMap)901 bool RSMainThread::NeedReleaseGpuResource(const RSRenderNodeMap& nodeMap)
902 {
903     bool needReleaseGpuResource = lastFrameHasFilter_;
904     bool currentFrameHasFilter = false;
905     auto residentSurfaceNodeMap = nodeMap.GetResidentSurfaceNodeMap();
906     for (const auto& [_, surfaceNode] : residentSurfaceNodeMap) {
907         if (!surfaceNode || !surfaceNode->IsOnTheTree()) {
908             continue;
909         }
910         // needReleaseGpuResource will be set true when all nodes don't need filter, otherwise false.
911         needReleaseGpuResource = needReleaseGpuResource &&
912             !(surfaceNode->GetRenderProperties().NeedFilter() || !(surfaceNode->GetChildrenNeedFilterRects().empty()));
913         // currentFrameHasFilter will be set true when one node needs filter, otherwise false.
914         currentFrameHasFilter = currentFrameHasFilter ||
915             surfaceNode->GetRenderProperties().NeedFilter() || !(surfaceNode->GetChildrenNeedFilterRects().empty());
916     }
917     lastFrameHasFilter_ = currentFrameHasFilter;
918     return needReleaseGpuResource;
919 }
920 
ReleaseAllNodesBuffer()921 void RSMainThread::ReleaseAllNodesBuffer()
922 {
923     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::ReleaseAllNodesBuffer");
924     const auto& nodeMap = GetContext().GetNodeMap();
925     nodeMap.TraverseSurfaceNodes([this](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
926         if (surfaceNode == nullptr) {
927             return;
928         }
929         // surfaceNode's buffer will be released in hardware thread if last frame enables hardware composer
930         if (surfaceNode->IsHardwareEnabledType()) {
931             if (surfaceNode->IsLastFrameHardwareEnabled()) {
932                 if (!surfaceNode->IsCurrentFrameHardwareEnabled()) {
933                     auto& surfaceHandler = static_cast<RSSurfaceHandler&>(*surfaceNode);
934                     auto preBuffer = surfaceHandler.GetPreBuffer();
935                     if (preBuffer.buffer != nullptr) {
936                         auto releaseTask = [buffer = preBuffer.buffer, consumer = surfaceHandler.GetConsumer(),
937                             fence = preBuffer.releaseFence]() mutable {
938                             auto ret = consumer->ReleaseBuffer(buffer, fence);
939                             if (ret != OHOS::SURFACE_ERROR_OK) {
940                                 RS_LOGW("surfaceHandler ReleaseBuffer failed(ret: %d)!", ret);
941                             }
942                         };
943                         preBuffer.Reset();
944                         RSHardwareThread::Instance().PostTask(releaseTask);
945                     }
946                 }
947                 surfaceNode->ResetCurrentFrameHardwareEnabledState();
948                 return;
949             }
950             surfaceNode->ResetCurrentFrameHardwareEnabledState();
951         }
952         // To avoid traverse surfaceNodeMap again, destroy cold start thread here
953         if ((!surfaceNode->IsOnTheTree() || !surfaceNode->ShouldPaint()) &&
954             RSColdStartManager::Instance().IsColdStartThreadRunning(surfaceNode->GetId())) {
955             if (RSColdStartManager::Instance().IsColdStartThreadIdle(surfaceNode->GetId())) {
956                 surfaceNode->ClearCachedImage();
957                 RSColdStartManager::Instance().StopColdStartThread(surfaceNode->GetId());
958             }
959         }
960         RSBaseRenderUtil::ReleaseBuffer(static_cast<RSSurfaceHandler&>(*surfaceNode));
961     });
962 #ifdef RS_ENABLE_GL
963     if (NeedReleaseGpuResource(nodeMap)) {
964         PostTask([this]() {
965 #ifndef USE_ROSEN_DRAWING
966 #ifdef NEW_RENDER_CONTEXT
967             MemoryManager::ReleaseUnlockGpuResource(GetRenderEngine()->GetDrawingContext()->GetDrawingContext());
968 #else
969             MemoryManager::ReleaseUnlockGpuResource(GetRenderEngine()->GetRenderContext()->GetGrContext());
970 #endif
971 #else
972             MemoryManager::ReleaseUnlockGpuResource(GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
973 #endif
974         });
975     }
976 #endif
977     RS_OPTIONAL_TRACE_END();
978 }
979 
WaitUtilUniRenderFinished()980 void RSMainThread::WaitUtilUniRenderFinished()
981 {
982     std::unique_lock<std::mutex> lock(uniRenderMutex_);
983     if (uniRenderFinished_) {
984         return;
985     }
986     uniRenderCond_.wait(lock, [this]() { return uniRenderFinished_; });
987     uniRenderFinished_ = false;
988 }
989 
WaitUntilDisplayNodeBufferReleased(RSDisplayRenderNode & node)990 bool RSMainThread::WaitUntilDisplayNodeBufferReleased(RSDisplayRenderNode& node)
991 {
992     std::unique_lock<std::mutex> lock(displayNodeBufferReleasedMutex_);
993     displayNodeBufferReleased_ = false; // prevent spurious wakeup of condition variable
994     if (node.GetConsumer()->QueryIfBufferAvailable()) {
995         return true;
996     }
997     return displayNodeBufferReleasedCond_.wait_until(lock, std::chrono::system_clock::now() +
998         std::chrono::milliseconds(WAIT_FOR_RELEASED_BUFFER_TIMEOUT), [this]() { return displayNodeBufferReleased_; });
999 }
1000 
WaitUtilDrivenRenderFinished()1001 void RSMainThread::WaitUtilDrivenRenderFinished()
1002 {
1003 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
1004     std::unique_lock<std::mutex> lock(drivenRenderMutex_);
1005     if (drivenRenderFinished_) {
1006         return;
1007     }
1008     drivenRenderCond_.wait(lock, [this]() { return drivenRenderFinished_; });
1009     drivenRenderFinished_ = false;
1010 #endif
1011 }
1012 
WaitUntilUnmarshallingTaskFinished()1013 void RSMainThread::WaitUntilUnmarshallingTaskFinished()
1014 {
1015     if (!isUniRender_) {
1016         return;
1017     }
1018     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::WaitUntilUnmarshallingTaskFinished");
1019     std::unique_lock<std::mutex> lock(unmarshalMutex_);
1020     unmarshalTaskCond_.wait(lock, [this]() { return unmarshalFinishedCount_ > 0; });
1021     --unmarshalFinishedCount_;
1022     RS_OPTIONAL_TRACE_END();
1023 }
1024 
MergeToEffectiveTransactionDataMap(TransactionDataMap & cachedTransactionDataMap)1025 void RSMainThread::MergeToEffectiveTransactionDataMap(TransactionDataMap& cachedTransactionDataMap)
1026 {
1027     std::lock_guard<std::mutex> lock(transitionDataMutex_);
1028     for (auto& elem : cachedTransactionDataMap) {
1029         auto pid = elem.first;
1030         if (effectiveTransactionDataIndexMap_.count(pid) == 0) {
1031             RS_LOGE("RSMainThread::MergeToEffectiveTransactionDataMap pid:%d not valid, skip it", pid);
1032             continue;
1033         }
1034         InsertToEnd(elem.second, effectiveTransactionDataIndexMap_[pid].second);
1035     }
1036     cachedTransactionDataMap.clear();
1037 }
1038 
NotifyUniRenderFinish()1039 void RSMainThread::NotifyUniRenderFinish()
1040 {
1041     if (std::this_thread::get_id() != Id()) {
1042         std::lock_guard<std::mutex> lock(uniRenderMutex_);
1043         uniRenderFinished_ = true;
1044         uniRenderCond_.notify_one();
1045     } else {
1046         uniRenderFinished_ = true;
1047     }
1048 }
1049 
NotifyDisplayNodeBufferReleased()1050 void RSMainThread::NotifyDisplayNodeBufferReleased()
1051 {
1052     RS_TRACE_NAME("RSMainThread::NotifyDisplayNodeBufferReleased");
1053     std::lock_guard<std::mutex> lock(displayNodeBufferReleasedMutex_);
1054     displayNodeBufferReleased_ = true;
1055     displayNodeBufferReleasedCond_.notify_one();
1056 }
1057 
NotifyDrivenRenderFinish()1058 void RSMainThread::NotifyDrivenRenderFinish()
1059 {
1060 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
1061     if (std::this_thread::get_id() != Id()) {
1062         std::lock_guard<std::mutex> lock(drivenRenderMutex_);
1063         drivenRenderFinished_ = true;
1064         drivenRenderCond_.notify_one();
1065     } else {
1066         drivenRenderFinished_ = true;
1067     }
1068 #endif
1069 }
1070 
ProcessHgmFrameRate(FrameRateRangeData data,uint64_t timestamp)1071 void RSMainThread::ProcessHgmFrameRate(FrameRateRangeData data, uint64_t timestamp)
1072 {
1073     // 0.[Planning]: The HGM logic here will be processed using sub-threads in the future.
1074 
1075     frameRateMgr_->Reset();
1076     // 1.[Planning]: Check and processing software vsync frame rate switching task for RS.
1077 
1078     // 2.Decision-making process for current frame.
1079     frameRateMgr_->UniProcessData(data);
1080 
1081     // 3.[Planning]: Post app and rs switch software vsync rate task.
1082 }
1083 
UniRender(std::shared_ptr<RSBaseRenderNode> rootNode)1084 void RSMainThread::UniRender(std::shared_ptr<RSBaseRenderNode> rootNode)
1085 {
1086     UpdateUIFirstSwitch();
1087     auto uniVisitor = std::make_shared<RSUniRenderVisitor>();
1088 #if defined(RS_ENABLE_DRIVEN_RENDER) && defined(RS_ENABLE_GL)
1089     uniVisitor->SetDrivenRenderFlag(hasDrivenNodeOnUniTree_, hasDrivenNodeMarkRender_);
1090 #endif
1091     uniVisitor->SetHardwareEnabledNodes(hardwareEnabledNodes_);
1092     uniVisitor->SetAppWindowNum(appWindowNum_);
1093     uniVisitor->SetProcessorRenderEngine(GetRenderEngine());
1094     ColorFilterMode colorFilterMode = renderEngine_->GetColorFilterMode();
1095     bool hasColorFilter = colorFilterMode >= ColorFilterMode::INVERT_COLOR_ENABLE_MODE &&
1096         colorFilterMode <= ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE;
1097     if (isHardwareForcedDisabled_ || rootNode->GetChildrenCount() > 1 || hasColorFilter) {
1098         // [PLANNING] GetChildrenCount > 1 indicates multi display, only Mirror Mode need be marked here
1099         // Mirror Mode reuses display node's buffer, so mark it and disable hardware composer in this case
1100         uniVisitor->MarkHardwareForcedDisabled();
1101         doDirectComposition_ = false;
1102     }
1103     bool needTraverseNodeTree = true;
1104     doDirectComposition_ = false;
1105     if (doDirectComposition_ && !isDirty_ && !isAccessibilityConfigChanged_ && !isCachedSurfaceUpdated_) {
1106         if (isHardwareEnabledBufferUpdated_) {
1107             needTraverseNodeTree = !uniVisitor->DoDirectComposition(rootNode);
1108         } else {
1109             RS_LOGI("RSMainThread::Render nothing to update");
1110             for (auto& node: hardwareEnabledNodes_) {
1111                 if (!node->IsHardwareForcedDisabled()) {
1112                     node->MarkCurrentFrameHardwareEnabled();
1113                 }
1114             }
1115             return;
1116         }
1117     }
1118     isCachedSurfaceUpdated_ = false;
1119     if (needTraverseNodeTree) {
1120         uniVisitor->SetAnimateState(doWindowAnimate_);
1121         uniVisitor->SetDirtyFlag(isDirty_ || isAccessibilityConfigChanged_);
1122         isAccessibilityConfigChanged_ = false;
1123         uniVisitor->SetFocusedNodeId(focusNodeId_);
1124         rootNode->Prepare(uniVisitor);
1125         ProcessHgmFrameRate(uniVisitor->GetFrameRateRangeData(), timestamp_);
1126         CalcOcclusion();
1127         bool doParallelComposition = RSInnovation::GetParallelCompositionEnabled(isUniRender_);
1128         if (doParallelComposition && rootNode->GetChildrenCount() > 1) {
1129             RS_LOGD("RSMainThread::Render multi-threads parallel composition begin.");
1130             doParallelComposition = uniVisitor->ParallelComposition(rootNode);
1131             if (doParallelComposition) {
1132                 RS_LOGD("RSMainThread::Render multi-threads parallel composition end.");
1133                 isDirty_ = false;
1134                 PerfForBlurIfNeeded();
1135                 return;
1136             }
1137         }
1138         if (IsUIFirstOn()) {
1139             auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(
1140                 rootNode->GetSortedChildren().front());
1141             std::list<std::shared_ptr<RSSurfaceRenderNode>> mainThreadNodes;
1142             std::list<std::shared_ptr<RSSurfaceRenderNode>> subThreadNodes;
1143             RSUniRenderUtil::AssignWindowNodes(displayNode, mainThreadNodes, subThreadNodes, focusNodeId_, deviceType_);
1144             const auto& nodeMap = context_->GetNodeMap();
1145             RSUniRenderUtil::ClearSurfaceIfNeed(nodeMap, displayNode, oldDisplayChildren_);
1146             uniVisitor->DrawSurfaceLayer(displayNode, subThreadNodes);
1147             RSUniRenderUtil::CacheSubThreadNodes(subThreadNodes_, subThreadNodes);
1148         }
1149         rootNode->Process(uniVisitor);
1150     }
1151     isDirty_ = false;
1152 }
1153 
Render()1154 void RSMainThread::Render()
1155 {
1156     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
1157     if (rootNode == nullptr) {
1158         RS_LOGE("RSMainThread::Render GetGlobalRootRenderNode fail");
1159         return;
1160     }
1161     if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
1162         RSPropertyTrace::GetInstance().RefreshNodeTraceInfo();
1163     }
1164 
1165     if (isUniRender_) {
1166         UniRender(rootNode);
1167     } else {
1168         auto rsVisitor = std::make_shared<RSRenderServiceVisitor>();
1169         rsVisitor->SetAnimateState(doWindowAnimate_);
1170         rootNode->Prepare(rsVisitor);
1171         CalcOcclusion();
1172 
1173         bool doParallelComposition = false;
1174         if (!rsVisitor->ShouldForceSerial() && RSInnovation::GetParallelCompositionEnabled(isUniRender_)) {
1175             doParallelComposition = DoParallelComposition(rootNode);
1176         }
1177         if (doParallelComposition) {
1178             renderEngine_->ShrinkCachesIfNeeded();
1179             return;
1180         }
1181         rootNode->Process(rsVisitor);
1182         renderEngine_->ShrinkCachesIfNeeded();
1183     }
1184 
1185     PerfForBlurIfNeeded();
1186 }
1187 
CheckSurfaceNeedProcess(OcclusionRectISet & occlusionSurfaces,std::shared_ptr<RSSurfaceRenderNode> curSurface)1188 bool RSMainThread::CheckSurfaceNeedProcess(OcclusionRectISet& occlusionSurfaces,
1189     std::shared_ptr<RSSurfaceRenderNode> curSurface)
1190 {
1191     bool needProcess = false;
1192     if (curSurface->IsFocusedNode(focusNodeId_)) {
1193         needProcess = true;
1194         if (!curSurface->HasContainerWindow() && !curSurface->IsTransparent() &&
1195             curSurface->GetName().find("hisearch") == std::string::npos) {
1196             occlusionSurfaces.insert(curSurface->GetDstRect());
1197         }
1198     } else {
1199         size_t beforeSize = occlusionSurfaces.size();
1200         occlusionSurfaces.insert(curSurface->GetDstRect());
1201         bool insertSuccess = occlusionSurfaces.size() > beforeSize ? true : false;
1202         if (insertSuccess) {
1203             needProcess = true;
1204             if (curSurface->IsTransparent() || curSurface->GetName().find("hisearch") != std::string::npos) {
1205                 auto iter = std::find_if(occlusionSurfaces.begin(), occlusionSurfaces.end(),
1206                     [&curSurface](RectI r) -> bool {return r == curSurface->GetDstRect();});
1207                 if (iter != occlusionSurfaces.end()) {
1208                     occlusionSurfaces.erase(iter);
1209                 }
1210             }
1211         }
1212     }
1213 
1214     if (needProcess) {
1215         CheckIfNodeIsBundle(curSurface);
1216     }
1217     return needProcess;
1218 }
1219 
CalcOcclusionImplementation(std::vector<RSBaseRenderNode::SharedPtr> & curAllSurfaces)1220 void RSMainThread::CalcOcclusionImplementation(std::vector<RSBaseRenderNode::SharedPtr>& curAllSurfaces)
1221 {
1222     Occlusion::Region accumulatedRegion;
1223     VisibleData curVisVec;
1224     OcclusionRectISet occlusionSurfaces;
1225     std::map<uint32_t, bool> pidVisMap;
1226     for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
1227         auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
1228         if (curSurface == nullptr || curSurface->GetDstRect().IsEmpty() || curSurface->IsLeashWindow()) {
1229             continue;
1230         }
1231         Occlusion::Rect occlusionRect;
1232         if (isUniRender_) {
1233             // In UniRender, CalcOcclusion should consider the shadow area of window
1234             occlusionRect = Occlusion::Rect {curSurface->GetOldDirtyInSurface()};
1235         } else {
1236             occlusionRect = Occlusion::Rect {curSurface->GetDstRect()};
1237         }
1238         RS_LOGD("RSMainThread::CalcOcclusionImplementation name: %s id: %llu rect: %s",
1239             curSurface->GetName().c_str(), curSurface->GetId(), occlusionRect.GetRectInfo().c_str());
1240         curSurface->setQosCal(qosPidCal_);
1241         if (CheckSurfaceNeedProcess(occlusionSurfaces, curSurface)) {
1242             Occlusion::Region curRegion { occlusionRect };
1243             Occlusion::Region subResult = curRegion.Sub(accumulatedRegion);
1244             curSurface->SetVisibleRegionRecursive(subResult, curVisVec, pidVisMap);
1245             // when surface is in starting window stage, do not occlude other window surfaces
1246             // fix grey block when directly open app (i.e. setting) from notification center
1247             auto parentPtr = curSurface->GetParent().lock();
1248             if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
1249                 auto surfaceParentPtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentPtr);
1250                 if (surfaceParentPtr->GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE &&
1251                     !curSurface->IsNotifyUIBufferAvailable()) {
1252                     continue;
1253                 }
1254             }
1255             if (isUniRender_) {
1256                 if (curSurface->GetName().find("hisearch") == std::string::npos) {
1257                     // When a surfacenode is in animation (i.e. 3d animation), its dstrect cannot be trusted, we treated
1258                     // it as a full transparent layer.
1259                     if (parentPtr != nullptr && parentPtr->IsInstanceOf<RSSurfaceRenderNode>()) {
1260                         auto surfaceParentPtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentPtr);
1261                         // leashwindow scaling is also means animation
1262                         if (surfaceParentPtr->IsLeashWindow() && surfaceParentPtr->IsScale()) {
1263                             curSurface->SetAnimateState();
1264                         }
1265                     }
1266                     if (!(curSurface->GetAnimateState())) {
1267                         accumulatedRegion.OrSelf(curSurface->GetOpaqueRegion());
1268                     } else {
1269                         curSurface->ResetAnimateState();
1270                     }
1271                 }
1272             } else {
1273                 bool diff = (curSurface->GetDstRect().width_ > curSurface->GetBuffer()->GetWidth() ||
1274                             curSurface->GetDstRect().height_ > curSurface->GetBuffer()->GetHeight()) &&
1275                             curSurface->GetRenderProperties().GetFrameGravity() != Gravity::RESIZE &&
1276                             ROSEN_EQ(curSurface->GetGlobalAlpha(), 1.0f);
1277                 if (!curSurface->IsTransparent() && !diff) {
1278                     accumulatedRegion.OrSelf(curRegion);
1279                 }
1280             }
1281         } else {
1282             curSurface->SetVisibleRegionRecursive({}, curVisVec, pidVisMap);
1283         }
1284     }
1285     // Callback to WMS and QOS
1286     CallbackToWMS(curVisVec);
1287     CallbackToQOS(pidVisMap);
1288 }
1289 
CalcOcclusion()1290 void RSMainThread::CalcOcclusion()
1291 {
1292     RS_TRACE_NAME("RSMainThread::CalcOcclusion");
1293     RS_LOGD("RSMainThread::CalcOcclusion animate:%d isUniRender:%d", doWindowAnimate_.load(), isUniRender_);
1294     if (doWindowAnimate_ && !isUniRender_) {
1295         return;
1296     }
1297     const std::shared_ptr<RSBaseRenderNode> node = context_->GetGlobalRootRenderNode();
1298     if (node == nullptr) {
1299         RS_LOGE("RSMainThread::CalcOcclusion GetGlobalRootRenderNode fail");
1300         return;
1301     }
1302     std::vector<RSBaseRenderNode::SharedPtr> curAllSurfaces;
1303     if (node->GetChildrenCount()== 1) {
1304         auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(
1305             node->GetSortedChildren().front());
1306         if (displayNode) {
1307             curAllSurfaces = displayNode->GetCurAllSurfaces();
1308         }
1309     } else {
1310         node->CollectSurface(node, curAllSurfaces, isUniRender_, false);
1311     }
1312     // Judge whether it is dirty
1313     // Surface cnt changed or surface DstRectChanged or surface ZorderChanged
1314     bool winDirty = (lastSurfaceCnt_ != curAllSurfaces.size() || isDirty_ ||
1315         lastFocusNodeId_ != focusNodeId_);
1316     lastSurfaceCnt_ = curAllSurfaces.size();
1317     lastFocusNodeId_ = focusNodeId_;
1318     if (!winDirty) {
1319         for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
1320             auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
1321             if (surface == nullptr || surface->IsLeashWindow()) {
1322                 continue;
1323             }
1324             if (surface->GetZorderChanged() || surface->GetDstRectChanged() ||
1325                 surface->IsOpaqueRegionChanged() ||
1326                 surface->GetAlphaChanged() || (isUniRender_ && surface->IsDirtyRegionUpdated())) {
1327                 winDirty = true;
1328             }
1329             surface->CleanDstRectChanged();
1330             surface->CleanAlphaChanged();
1331         }
1332     }
1333     if (!winDirty) {
1334         return;
1335     }
1336     CalcOcclusionImplementation(curAllSurfaces);
1337 }
1338 
CheckQosVisChanged(std::map<uint32_t,bool> & pidVisMap)1339 bool RSMainThread::CheckQosVisChanged(std::map<uint32_t, bool>& pidVisMap)
1340 {
1341     bool isVisibleChanged = pidVisMap.size() != lastPidVisMap_.size();
1342     if (!isVisibleChanged) {
1343         auto iterCur = pidVisMap.begin();
1344         auto iterLast = lastPidVisMap_.begin();
1345         for (; iterCur != pidVisMap.end(); iterCur++, iterLast++) {
1346             if (iterCur->first != iterLast->first ||
1347                 iterCur->second != iterLast->second) {
1348                 isVisibleChanged = true;
1349                 break;
1350             }
1351         }
1352     }
1353 
1354     lastPidVisMap_.clear();
1355     lastPidVisMap_.insert(pidVisMap.begin(), pidVisMap.end());
1356     return isVisibleChanged;
1357 }
1358 
CallbackToQOS(std::map<uint32_t,bool> & pidVisMap)1359 void RSMainThread::CallbackToQOS(std::map<uint32_t, bool>& pidVisMap)
1360 {
1361     if (!RSInnovation::UpdateQosVsyncEnabled()) {
1362         if (qosPidCal_) {
1363             qosPidCal_ = false;
1364             RSQosThread::ResetQosPid();
1365             RSQosThread::GetInstance()->SetQosCal(qosPidCal_);
1366         }
1367         return;
1368     }
1369     qosPidCal_ = true;
1370     RSQosThread::GetInstance()->SetQosCal(qosPidCal_);
1371     if (!CheckQosVisChanged(pidVisMap)) {
1372         return;
1373     }
1374     RS_TRACE_NAME("RSQosThread::OnRSVisibilityChangeCB");
1375     RSQosThread::GetInstance()->OnRSVisibilityChangeCB(pidVisMap);
1376 }
1377 
CallbackToWMS(VisibleData & curVisVec)1378 void RSMainThread::CallbackToWMS(VisibleData& curVisVec)
1379 {
1380     // if visible surfaces changed callback to WMS:
1381     // 1. curVisVec size changed
1382     // 2. curVisVec content changed
1383     bool visibleChanged = curVisVec.size() != lastVisVec_.size();
1384     std::sort(curVisVec.begin(), curVisVec.end());
1385     if (!visibleChanged) {
1386         for (uint32_t i = 0; i < curVisVec.size(); i++) {
1387             if (curVisVec[i] != lastVisVec_[i]) {
1388                 visibleChanged = true;
1389                 break;
1390             }
1391         }
1392     }
1393     if (visibleChanged) {
1394         std::lock_guard<std::mutex> lock(occlusionMutex_);
1395         for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
1396             if (it->second) {
1397                 RS_LOGD("RSMainThread::CallbackToWMS curVisVec size:%u", curVisVec.size());
1398                 it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(curVisVec));
1399             }
1400         }
1401     }
1402     lastVisVec_.clear();
1403     std::copy(curVisVec.begin(), curVisVec.end(), std::back_inserter(lastVisVec_));
1404 }
1405 
RequestNextVSync()1406 void RSMainThread::RequestNextVSync()
1407 {
1408     RS_OPTIONAL_TRACE_FUNC_BEGIN();
1409     VSyncReceiver::FrameCallback fcb = {
1410         .userData_ = this,
1411         .callback_ = [this](uint64_t timestamp, void* data) { OnVsync(timestamp, data); },
1412     };
1413     if (receiver_ != nullptr) {
1414         requestNextVsyncNum_++;
1415         if (requestNextVsyncNum_ > REQUEST_VSYNC_NUMBER_LIMIT) {
1416             RS_LOGW("RSMainThread::RequestNextVSync too many times:%d", requestNextVsyncNum_);
1417         }
1418         receiver_->RequestNextVSync(fcb);
1419     }
1420     RS_OPTIONAL_TRACE_FUNC_END();
1421 }
1422 
OnVsync(uint64_t timestamp,void * data)1423 void RSMainThread::OnVsync(uint64_t timestamp, void* data)
1424 {
1425     RS_OPTIONAL_TRACE_FUNC_BEGIN();
1426     RSJankStats::GetInstance().SetStartTime();
1427     timestamp_ = timestamp;
1428     curTime_ = static_cast<uint64_t>(
1429         std::chrono::duration_cast<std::chrono::nanoseconds>(
1430             std::chrono::steady_clock::now().time_since_epoch()).count());
1431     requestNextVsyncNum_ = 0;
1432     frameCount_++;
1433     if (isUniRender_) {
1434         MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
1435         RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
1436     }
1437     mainLoop_();
1438     auto screenManager_ = CreateOrGetScreenManager();
1439     if (screenManager_ != nullptr) {
1440         auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
1441         if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
1442             RSHardwareThread::Instance().PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
1443         } else {
1444             PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
1445         }
1446     }
1447     RSJankStats::GetInstance().SetEndTime();
1448     RS_OPTIONAL_TRACE_FUNC_END();
1449 }
1450 
Animate(uint64_t timestamp)1451 void RSMainThread::Animate(uint64_t timestamp)
1452 {
1453     RS_TRACE_FUNC();
1454     lastAnimateTimestamp_ = timestamp;
1455 
1456     if (context_->animatingNodeList_.empty()) {
1457         if (doWindowAnimate_ && RSInnovation::UpdateQosVsyncEnabled()) {
1458             // Preventing Occlusion Calculation from Being Completed in Advance
1459             RSQosThread::GetInstance()->OnRSVisibilityChangeCB(lastPidVisMap_);
1460         }
1461         doWindowAnimate_ = false;
1462         return;
1463     }
1464     doDirectComposition_ = false;
1465     bool curWinAnim = false;
1466     bool needRequestNextVsync = false;
1467     // iterate and animate all animating nodes, remove if animation finished
1468     EraseIf(context_->animatingNodeList_,
1469         [this, timestamp, &curWinAnim, &needRequestNextVsync](const auto& iter) -> bool {
1470         auto node = iter.second.lock();
1471         if (node == nullptr) {
1472             RS_LOGD("RSMainThread::Animate removing expired animating node");
1473             return true;
1474         }
1475         if (cacheCmdSkippedInfo_.count(ExtractPid(node->GetId())) > 0) {
1476             RS_LOGD("RSMainThread::Animate skip the cached node");
1477             return false;
1478         }
1479         if (node->IsOnTheTree()) {
1480             AddActiveNodeId(ExtractPid(node->GetId()), node->GetId());
1481         }
1482         auto [hasRunningAnimation, nodeNeedRequestNextVsync] = node->Animate(timestamp);
1483         if (!hasRunningAnimation) {
1484             RS_LOGD("RSMainThread::Animate removing finished animating node %" PRIu64, node->GetId());
1485         }
1486         // request vsync if: 1. node has running animation, or 2. transition animation just ended
1487         needRequestNextVsync = needRequestNextVsync || nodeNeedRequestNextVsync || (node.use_count() == 1);
1488         if (node->template IsInstanceOf<RSSurfaceRenderNode>() && hasRunningAnimation) {
1489             if (isUniRender_) {
1490                 auto surfacenode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
1491                 surfacenode->SetAnimateState();
1492             }
1493             curWinAnim = true;
1494         }
1495         return !hasRunningAnimation;
1496     });
1497     if (!doWindowAnimate_ && curWinAnim && RSInnovation::UpdateQosVsyncEnabled()) {
1498         RSQosThread::ResetQosPid();
1499     }
1500     doWindowAnimate_ = curWinAnim;
1501     RS_LOGD("RSMainThread::Animate end, %d animating nodes remains, has window animation: %d",
1502         context_->animatingNodeList_.size(), curWinAnim);
1503 
1504     if (needRequestNextVsync) {
1505         RequestNextVSync();
1506     }
1507     PerfAfterAnim(needRequestNextVsync);
1508 }
1509 
CheckColdStartMap()1510 void RSMainThread::CheckColdStartMap()
1511 {
1512     const auto& nodeMap = GetContext().GetNodeMap();
1513     RSColdStartManager::Instance().CheckColdStartMap(nodeMap);
1514 }
1515 
RecvRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)1516 void RSMainThread::RecvRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
1517 {
1518     if (!rsTransactionData) {
1519         return;
1520     }
1521     if (isUniRender_) {
1522         std::lock_guard<std::mutex> lock(transitionDataMutex_);
1523         cachedTransactionDataMap_[rsTransactionData->GetSendingPid()].emplace_back(std::move(rsTransactionData));
1524     } else {
1525         ClassifyRSTransactionData(rsTransactionData);
1526     }
1527     RequestNextVSync();
1528 }
1529 
ClassifyRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)1530 void RSMainThread::ClassifyRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
1531 {
1532     const auto& nodeMap = context_->GetNodeMap();
1533     std::lock_guard<std::mutex> lock(transitionDataMutex_);
1534     std::unique_ptr<RSTransactionData> transactionData(std::move(rsTransactionData));
1535     auto timestamp = transactionData->GetTimestamp();
1536     RS_LOGD("RSMainThread::RecvRSTransactionData timestamp = %" PRIu64, timestamp);
1537     for (auto& [nodeId, followType, command] : transactionData->GetPayload()) {
1538         if (nodeId == 0 || followType == FollowType::NONE) {
1539             pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
1540             continue;
1541         }
1542         auto node = nodeMap.GetRenderNode(nodeId);
1543         if (node && followType == FollowType::FOLLOW_TO_PARENT) {
1544             auto parentNode = node->GetParent().lock();
1545             if (parentNode) {
1546                 nodeId = parentNode->GetId();
1547             } else {
1548                 pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
1549                 continue;
1550             }
1551         }
1552         cachedCommands_[nodeId][timestamp].emplace_back(std::move(command));
1553     }
1554 }
1555 
PostTask(RSTaskMessage::RSTask task)1556 void RSMainThread::PostTask(RSTaskMessage::RSTask task)
1557 {
1558     if (handler_) {
1559         handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1560     }
1561 }
1562 
PostSyncTask(RSTaskMessage::RSTask task)1563 void RSMainThread::PostSyncTask(RSTaskMessage::RSTask task)
1564 {
1565     if (handler_) {
1566         handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1567     }
1568 }
1569 
RegisterApplicationAgent(uint32_t pid,sptr<IApplicationAgent> app)1570 void RSMainThread::RegisterApplicationAgent(uint32_t pid, sptr<IApplicationAgent> app)
1571 {
1572     applicationAgentMap_.emplace(pid, app);
1573 }
1574 
UnRegisterApplicationAgent(sptr<IApplicationAgent> app)1575 void RSMainThread::UnRegisterApplicationAgent(sptr<IApplicationAgent> app)
1576 {
1577     EraseIf(applicationAgentMap_, [&app](const auto& iter) { return iter.second == app; });
1578 }
1579 
RegisterOcclusionChangeCallback(pid_t pid,sptr<RSIOcclusionChangeCallback> callback)1580 void RSMainThread::RegisterOcclusionChangeCallback(pid_t pid, sptr<RSIOcclusionChangeCallback> callback)
1581 {
1582     std::lock_guard<std::mutex> lock(occlusionMutex_);
1583     occlusionListeners_[pid] = callback;
1584 }
1585 
UnRegisterOcclusionChangeCallback(pid_t pid)1586 void RSMainThread::UnRegisterOcclusionChangeCallback(pid_t pid)
1587 {
1588     std::lock_guard<std::mutex> lock(occlusionMutex_);
1589     occlusionListeners_.erase(pid);
1590 }
1591 
SendCommands()1592 void RSMainThread::SendCommands()
1593 {
1594     RS_OPTIONAL_TRACE_FUNC_BEGIN();
1595     RsFrameReport& fr = RsFrameReport::GetInstance();
1596     if (fr.GetEnable()) {
1597         fr.SendCommandsStart();
1598         fr.RenderEnd();
1599     }
1600     if (!RSMessageProcessor::Instance().HasTransaction()) {
1601         RS_OPTIONAL_TRACE_FUNC_END();
1602         return;
1603     }
1604 
1605     // dispatch messages to corresponding application
1606     auto transactionMapPtr = std::make_shared<std::unordered_map<uint32_t, std::shared_ptr<RSTransactionData>>>(
1607         RSMessageProcessor::Instance().GetAllTransactions());
1608     RSMessageProcessor::Instance().ReInitializeMovedMap();
1609     PostTask([this, transactionMapPtr]() {
1610         for (auto& transactionIter : *transactionMapPtr) {
1611             auto pid = transactionIter.first;
1612             auto appIter = applicationAgentMap_.find(pid);
1613             if (appIter == applicationAgentMap_.end()) {
1614                 RS_LOGW(
1615                     "RSMainThread::SendCommand no application agent registered as pid %d, this will cause memory leak!",
1616                     pid);
1617                 continue;
1618             }
1619             auto& app = appIter->second;
1620             auto transactionPtr = transactionIter.second;
1621             app->OnTransaction(transactionPtr);
1622         }
1623     });
1624     RS_OPTIONAL_TRACE_FUNC_END();
1625 }
1626 
QosStateDump(std::string & dumpString)1627 void RSMainThread::QosStateDump(std::string& dumpString)
1628 {
1629     if (RSQosThread::GetInstance()->GetQosCal()) {
1630         dumpString.append("QOS is enabled\n");
1631     } else {
1632         dumpString.append("QOS is disabled\n");
1633     }
1634 }
1635 
RenderServiceTreeDump(std::string & dumpString)1636 void RSMainThread::RenderServiceTreeDump(std::string& dumpString)
1637 {
1638     dumpString.append("Animating Node: [");
1639     for (auto& [nodeId, _]: context_->animatingNodeList_) {
1640         dumpString.append(std::to_string(nodeId) + ", ");
1641     }
1642     dumpString.append("];\n");
1643     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
1644     if (rootNode == nullptr) {
1645         dumpString.append("rootNode is null\n");
1646         return;
1647     }
1648     rootNode->DumpTree(0, dumpString);
1649 }
1650 
DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)1651 bool RSMainThread::DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)
1652 {
1653     using CreateParallelSyncSignalFunc = void* (*)(uint32_t);
1654     using SignalCountDownFunc = void (*)(void*);
1655     using SignalAwaitFunc = void (*)(void*);
1656     using AssignTaskFunc = void (*)(std::function<void()>);
1657     using RemoveStoppedThreadsFunc = void (*)();
1658 
1659     auto CreateParallelSyncSignal = (CreateParallelSyncSignalFunc)RSInnovation::_s_createParallelSyncSignal;
1660     auto SignalCountDown = (SignalCountDownFunc)RSInnovation::_s_signalCountDown;
1661     auto SignalAwait = (SignalAwaitFunc)RSInnovation::_s_signalAwait;
1662     auto AssignTask = (AssignTaskFunc)RSInnovation::_s_assignTask;
1663     auto RemoveStoppedThreads = (RemoveStoppedThreadsFunc)RSInnovation::_s_removeStoppedThreads;
1664 
1665     void* syncSignal = (*CreateParallelSyncSignal)(rootNode->GetChildrenCount());
1666     if (!syncSignal) {
1667         return false;
1668     }
1669 
1670     (*RemoveStoppedThreads)();
1671 
1672     auto children = rootNode->GetSortedChildren();
1673     bool animate_ = doWindowAnimate_;
1674     for (auto it = children.rbegin(); it != children.rend(); it++) {
1675         auto child = *it;
1676         auto task = [&syncSignal, SignalCountDown, child, animate_]() {
1677             std::shared_ptr<RSNodeVisitor> visitor;
1678             auto rsVisitor = std::make_shared<RSRenderServiceVisitor>(true);
1679             rsVisitor->SetAnimateState(animate_);
1680             visitor = rsVisitor;
1681             child->Process(visitor);
1682             (*SignalCountDown)(syncSignal);
1683         };
1684         if (*it == *children.begin()) {
1685             task();
1686         } else {
1687             (*AssignTask)(task);
1688         }
1689     }
1690     (*SignalAwait)(syncSignal);
1691     return true;
1692 }
1693 
ClearTransactionDataPidInfo(pid_t remotePid)1694 void RSMainThread::ClearTransactionDataPidInfo(pid_t remotePid)
1695 {
1696     if (!isUniRender_) {
1697         return;
1698     }
1699     std::lock_guard<std::mutex> lock(transitionDataMutex_);
1700     if (effectiveTransactionDataIndexMap_.count(remotePid) > 0 &&
1701         !effectiveTransactionDataIndexMap_[remotePid].second.empty()) {
1702         RS_LOGD("RSMainThread::ClearTransactionDataPidInfo process:%d destroyed, skip commands", remotePid);
1703     }
1704     effectiveTransactionDataIndexMap_.erase(remotePid);
1705     transactionDataLastWaitTime_.erase(remotePid);
1706 
1707     // clear cpu cache when process exit
1708     // CLEAN_CACHE_FREQ to prevent multiple cleanups in a short period of time
1709     if ((timestamp_ - lastCleanCacheTimestamp_) / REFRESH_PERIOD > CLEAN_CACHE_FREQ) {
1710 #ifdef RS_ENABLE_GL
1711         RS_LOGD("RSMainThread: clear cpu cache pid:%d", remotePid);
1712 #ifndef USE_ROSEN_DRAWING
1713 #ifdef NEW_RENDER_CONTEXT
1714         auto grContext = GetRenderEngine()->GetDrawingContext()->GetDrawingContext();
1715 #else
1716         auto grContext = GetRenderEngine()->GetRenderContext()->GetGrContext();
1717 #endif
1718         grContext->flush();
1719         SkGraphics::PurgeAllCaches(); // clear cpu cache
1720         if (!IsResidentProcess(remotePid)) {
1721             ReleaseExitSurfaceNodeAllGpuResource(grContext);
1722         } else {
1723             RS_LOGW("this pid:%d is resident process, no need release gpu resource", remotePid);
1724         }
1725 #ifdef NEW_SKIA
1726         grContext->flushAndSubmit(true);
1727 #else
1728         grContext->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
1729 #endif
1730 #else
1731         auto gpuContext = GetRenderEngine()->GetRenderContext()->GetDrGPUContext();
1732         if (gpuContext == nullptr) {
1733             return;
1734         }
1735         gpuContext->Flush();
1736         if (!IsResidentProcess(remotePid)) {
1737             ReleaseExitSurfaceNodeAllGpuResource(gpuContext);
1738         } else {
1739             RS_LOGW("this pid:%d is resident process, no need release gpu resource", remotePid);
1740         }
1741 #endif // USE_ROSEN_DRAWING
1742         lastCleanCacheTimestamp_ = timestamp_;
1743 #endif
1744     }
1745 }
1746 
IsResidentProcess(pid_t pid)1747 bool RSMainThread::IsResidentProcess(pid_t pid)
1748 {
1749     const auto& nodeMap = context_->GetNodeMap();
1750     return pid == ExtractPid(nodeMap.GetEntryViewNodeId()) || pid == ExtractPid(nodeMap.GetScreenLockWindowNodeId()) ||
1751         pid == ExtractPid(nodeMap.GetWallPaperViewNodeId());
1752 }
1753 
1754 #ifndef USE_ROSEN_DRAWING
1755 #ifdef NEW_SKIA
ReleaseExitSurfaceNodeAllGpuResource(GrDirectContext * grContext)1756 void RSMainThread::ReleaseExitSurfaceNodeAllGpuResource(GrDirectContext* grContext)
1757 #else
1758 void RSMainThread::ReleaseExitSurfaceNodeAllGpuResource(GrContext* grContext)
1759 #endif
1760 #else
1761 void RSMainThread::ReleaseExitSurfaceNodeAllGpuResource(Drawing::GPUContext* gpuContext)
1762 #endif
1763 {
1764     switch (RSSystemProperties::GetReleaseGpuResourceEnabled()) {
1765         case ReleaseGpuResourceType::WINDOW_HIDDEN:
1766         case ReleaseGpuResourceType::WINDOW_HIDDEN_AND_LAUCHER:
1767 #ifndef USE_ROSEN_DRAWING
1768             MemoryManager::ReleaseUnlockAndSafeCacheGpuResource(grContext);
1769 #else
1770             MemoryManager::ReleaseUnlockAndSafeCacheGpuResource(gpuContext);
1771 #endif
1772             break;
1773         default:
1774             break;
1775     }
1776 }
1777 
TrimMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString)1778 void RSMainThread::TrimMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString)
1779 {
1780 #ifdef RS_ENABLE_GL
1781     if (!RSUniRenderJudgement::IsUniRender()) {
1782         dumpString.append("\n---------------\nNot in UniRender and no resource can be released");
1783         return;
1784     }
1785     std::string type;
1786     argSets.erase(u"trimMem");
1787     if (!argSets.empty()) {
1788         type = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
1789     }
1790 #ifndef USE_ROSEN_DRAWING
1791 #ifdef NEW_RENDER_CONTEXT
1792     auto grContext = GetRenderEngine()->GetDrawingContext()->GetDrawingContext();
1793 #else
1794     auto grContext = GetRenderEngine()->GetRenderContext()->GetGrContext();
1795 #endif
1796     if (type.empty()) {
1797         grContext->flush();
1798         SkGraphics::PurgeAllCaches();
1799         grContext->freeGpuResources();
1800         grContext->purgeUnlockedResources(true);
1801 #ifdef NEW_RENDER_CONTEXT
1802         MemoryHandler::ClearShader();
1803 #else
1804         std::shared_ptr<RenderContext> rendercontext = std::make_shared<RenderContext>();
1805         rendercontext->CleanAllShaderCache();
1806 #endif
1807 #ifdef NEW_SKIA
1808         grContext->flushAndSubmit(true);
1809 #else
1810         grContext->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
1811 #endif
1812     } else if (type == "cpu") {
1813         grContext->flush();
1814         SkGraphics::PurgeAllCaches();
1815 #ifdef NEW_SKIA
1816         grContext->flushAndSubmit(true);
1817 #else
1818         grContext->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
1819 #endif
1820     } else if (type == "gpu") {
1821         grContext->flush();
1822         grContext->freeGpuResources();
1823 #ifdef NEW_SKIA
1824         grContext->flushAndSubmit(true);
1825 #else
1826         grContext->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
1827 #endif
1828     } else if (type == "uihidden") {
1829         grContext->flush();
1830         grContext->purgeUnlockedResources(true);
1831 #ifdef NEW_SKIA
1832         grContext->flushAndSubmit(true);
1833 #else
1834         grContext->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
1835 #endif
1836     } else if (type == "shader") {
1837 #ifdef NEW_RENDER_CONTEXT
1838         MemoryHandler::ClearShader();
1839 #else
1840         std::shared_ptr<RenderContext> rendercontext = std::make_shared<RenderContext>();
1841         rendercontext->CleanAllShaderCache();
1842 #endif
1843     } else if (type == "flushcache") {
1844         int ret = mallopt(M_FLUSH_THREAD_CACHE, 0);
1845         dumpString.append("flushcache " + std::to_string(ret) + "\n");
1846     } else {
1847         uint32_t pid = static_cast<uint32_t>(std::stoll(type));
1848         GrGpuResourceTag tag(pid, 0, 0, 0);
1849         MemoryManager::ReleaseAllGpuResource(grContext, tag);
1850     }
1851     dumpString.append("trimMem: " + type + "\n");
1852 #endif
1853 #else
1854     dumpString.append("No GPU in this device");
1855 #endif
1856 }
1857 
DumpMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString,std::string & type,int pid)1858 void RSMainThread::DumpMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString,
1859     std::string& type, int pid)
1860 {
1861 #ifdef RS_ENABLE_GL
1862     DfxString log;
1863 #ifndef USE_ROSEN_DRAWING
1864 #ifdef NEW_RENDER_CONTEXT
1865     auto grContext = GetRenderEngine()->GetDrawingContext()->GetDrawingContext();
1866 #else
1867     auto grContext = GetRenderEngine()->GetRenderContext()->GetGrContext();
1868 #endif
1869     if (pid != 0) {
1870         MemoryManager::DumpPidMemory(log, pid, grContext);
1871     } else {
1872         MemoryManager::DumpMemoryUsage(log, grContext, type);
1873     }
1874 #else
1875     auto gpuContext = GetRenderEngine()->GetRenderContext()->GetDrGPUContext();
1876     if (gpuContext != nullptr) {
1877         if (pid != 0) {
1878             MemoryManager::DumpPidMemory(log, pid, gpuContext);
1879         } else {
1880             MemoryManager::DumpMemoryUsage(log, gpuContext, type);
1881         }
1882     }
1883 #endif
1884     if (type.empty() || type == MEM_GPU_TYPE) {
1885         auto subThreadManager = RSSubThreadManager::Instance();
1886         if (subThreadManager) {
1887             subThreadManager->DumpMem(log);
1888         }
1889     }
1890     dumpString.append("dumpMem: " + type + "\n");
1891     dumpString.append(log.GetString());
1892 #else
1893     dumpString.append("No GPU in this device");
1894 #endif
1895 }
1896 
CountMem(int pid,MemoryGraphic & mem)1897 void RSMainThread::CountMem(int pid, MemoryGraphic& mem)
1898 {
1899 #ifdef RS_ENABLE_GL
1900 #ifndef USE_ROSEN_DRAWING
1901 #ifdef NEW_RENDER_CONTEXT
1902     mem = MemoryManager::CountPidMemory(pid, GetRenderEngine()->GetDrawingContext()->GetDrawingContext());
1903 #else
1904     mem = MemoryManager::CountPidMemory(pid, GetRenderEngine()->GetRenderContext()->GetGrContext());
1905 #endif
1906 #else
1907     mem = MemoryManager::CountPidMemory(pid, GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
1908 #endif
1909 #endif
1910 }
1911 
CountMem(std::vector<MemoryGraphic> & mems)1912 void RSMainThread::CountMem(std::vector<MemoryGraphic>& mems)
1913 {
1914 #ifdef RS_ENABLE_GL
1915     if (!context_) {
1916         RS_LOGE("RSMainThread::CountMem Context is nullptr");
1917         return;
1918     }
1919     const auto& nodeMap = context_->GetNodeMap();
1920     std::vector<pid_t> pids;
1921     nodeMap.TraverseSurfaceNodes([&pids] (const std::shared_ptr<RSSurfaceRenderNode>& node) {
1922         auto pid = ExtractPid(node->GetId());
1923         if (std::find(pids.begin(), pids.end(), pid) == pids.end()) {
1924             pids.emplace_back(pid);
1925         }
1926     });
1927 #ifndef USE_ROSEN_DRAWING
1928 #ifdef NEW_RENDER_CONTEXT
1929     MemoryManager::CountMemory(pids, GetRenderEngine()->GetDrawingContext()->GetDrawingContext(), mems);
1930 #else
1931     MemoryManager::CountMemory(pids, GetRenderEngine()->GetRenderContext()->GetGrContext(), mems);
1932 #endif
1933 #else
1934     MemoryManager::CountMemory(pids, GetRenderEngine()->GetRenderContext()->GetDrGPUContext(), mems);
1935 #endif
1936 #endif
1937 }
1938 
AddTransactionDataPidInfo(pid_t remotePid)1939 void RSMainThread::AddTransactionDataPidInfo(pid_t remotePid)
1940 {
1941     if (!isUniRender_) {
1942         return;
1943     }
1944     std::lock_guard<std::mutex> lock(transitionDataMutex_);
1945     if (effectiveTransactionDataIndexMap_.count(remotePid) > 0) {
1946         RS_LOGW("RSMainThread::AddTransactionDataPidInfo remotePid:%d already exists", remotePid);
1947     }
1948     effectiveTransactionDataIndexMap_[remotePid].first = 0;
1949 }
1950 
SetDirtyFlag()1951 void RSMainThread::SetDirtyFlag()
1952 {
1953     isDirty_ = true;
1954 }
1955 
SetAccessibilityConfigChanged()1956 void RSMainThread::SetAccessibilityConfigChanged()
1957 {
1958     isAccessibilityConfigChanged_ = true;
1959 }
1960 
PerfAfterAnim(bool needRequestNextVsync)1961 void RSMainThread::PerfAfterAnim(bool needRequestNextVsync)
1962 {
1963     if (!isUniRender_) {
1964         return;
1965     }
1966     if (needRequestNextVsync && timestamp_ - prePerfTimestamp_ > PERF_PERIOD) {
1967         RS_LOGD("RSMainThread:: soc perf to render_service_animation");
1968         prePerfTimestamp_ = timestamp_;
1969     } else if (!needRequestNextVsync && prePerfTimestamp_) {
1970         RS_LOGD("RSMainThread:: soc perf off render_service_animation");
1971         prePerfTimestamp_ = 0;
1972     }
1973 }
1974 
ForceRefreshForUni()1975 void RSMainThread::ForceRefreshForUni()
1976 {
1977     if (isUniRender_) {
1978         PostTask([=]() {
1979             MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
1980             RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
1981             auto now = std::chrono::duration_cast<std::chrono::nanoseconds>(
1982                 std::chrono::steady_clock::now().time_since_epoch()).count();
1983             timestamp_ = timestamp_ + (now - curTime_);
1984             curTime_ = now;
1985             RS_TRACE_NAME("RSMainThread::ForceRefreshForUni timestamp:" + std::to_string(timestamp_));
1986             mainLoop_();
1987         });
1988         auto screenManager_ = CreateOrGetScreenManager();
1989         if (screenManager_ != nullptr) {
1990             auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
1991             if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
1992                 RSHardwareThread::Instance().PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
1993             } else {
1994                 PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
1995             }
1996         }
1997     } else {
1998         RequestNextVSync();
1999     }
2000 }
2001 
PerfForBlurIfNeeded()2002 void RSMainThread::PerfForBlurIfNeeded()
2003 {
2004     static int preBlurCnt = 0;
2005     int blurCnt = RSPropertiesPainter::GetAndResetBlurCnt();
2006     // clamp blurCnt to 0~3.
2007     blurCnt = std::clamp<int>(blurCnt, 0, 3);
2008     if (blurCnt != preBlurCnt && preBlurCnt != 0) {
2009         PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(preBlurCnt), false);
2010         preBlurCnt = 0;
2011     }
2012     if (blurCnt == 0) {
2013         return;
2014     }
2015     static uint64_t prePerfTimestamp = 0;
2016     if (timestamp_ - prePerfTimestamp > PERF_PERIOD_BLUR || blurCnt != preBlurCnt) {
2017         PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(blurCnt), true);
2018         prePerfTimestamp = timestamp_;
2019         preBlurCnt = blurCnt;
2020     }
2021 }
2022 
PerfMultiWindow()2023 void RSMainThread::PerfMultiWindow()
2024 {
2025     if (!isUniRender_) {
2026         return;
2027     }
2028     static uint64_t lastPerfTimestamp = 0;
2029     if (appWindowNum_ >= MULTI_WINDOW_PERF_START_NUM && appWindowNum_ <= MULTI_WINDOW_PERF_END_NUM
2030         && timestamp_ - lastPerfTimestamp > PERF_PERIOD_MULTI_WINDOW) {
2031         RS_LOGD("RSMainThread::PerfMultiWindow soc perf");
2032         PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, true);
2033         lastPerfTimestamp = timestamp_;
2034     } else if ((appWindowNum_ < MULTI_WINDOW_PERF_START_NUM || appWindowNum_ > MULTI_WINDOW_PERF_END_NUM)
2035         && timestamp_ - lastPerfTimestamp < PERF_PERIOD_MULTI_WINDOW) {
2036         RS_LOGD("RSMainThread::PerfMultiWindow soc perf off");
2037         PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, false);
2038     }
2039 }
2040 
RenderFrameStart()2041 void RSMainThread::RenderFrameStart()
2042 {
2043     if (RsFrameReport::GetInstance().GetEnable()) {
2044         RsFrameReport::GetInstance().RenderStart();
2045     }
2046     RenderFrameTrace::GetInstance().RenderStartFrameTrace(RS_INTERVAL_NAME);
2047 }
2048 
SetAppWindowNum(uint32_t num)2049 void RSMainThread::SetAppWindowNum(uint32_t num)
2050 {
2051     appWindowNum_ = num;
2052 }
2053 
AddActiveNodeId(pid_t pid,NodeId id)2054 void RSMainThread::AddActiveNodeId(pid_t pid, NodeId id)
2055 {
2056     if (id == 0) {
2057         activeAppsInProcess_[pid].emplace(INVALID_NODEID);
2058         return;
2059     }
2060     auto node = RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode(id);
2061     if (node == nullptr) {
2062         return;
2063     }
2064     // root nodeid should be updated before check
2065     if (!node->IsOnTheTree()) {
2066         return;
2067     }
2068     if (auto parentPtr = node->GetParent().lock()) {
2069         auto rootNodeId = node->GetInstanceRootNodeId();
2070         activeAppsInProcess_[pid].emplace(rootNodeId);
2071         activeProcessNodeIds_[rootNodeId].emplace(id);
2072     }
2073 }
2074 
ResetHardwareEnabledState()2075 void RSMainThread::ResetHardwareEnabledState()
2076 {
2077     doDirectComposition_ = RSSystemProperties::GetHardwareComposerEnabled();
2078     isHardwareEnabledBufferUpdated_ = false;
2079     hardwareEnabledNodes_.clear();
2080     isHardwareForcedDisabled_ = false;
2081 }
2082 
ShowWatermark(const std::shared_ptr<Media::PixelMap> & watermarkImg,bool isShow)2083 void RSMainThread::ShowWatermark(const std::shared_ptr<Media::PixelMap> &watermarkImg, bool isShow)
2084 {
2085     std::lock_guard<std::mutex> lock(watermarkMutex_);
2086     isShow_ = isShow;
2087     if (isShow_) {
2088 #ifndef USE_ROSEN_DRAWING
2089         watermarkImg_ = RSPixelMapUtil::ExtractSkImage(std::move(watermarkImg));
2090 #else
2091         watermarkImg_ = RSPixelMapUtil::ExtractDrawingImage(std::move(watermarkImg));
2092 #endif
2093     } else {
2094         watermarkImg_ = nullptr;
2095     }
2096     SetDirtyFlag();
2097     RequestNextVSync();
2098 }
2099 
2100 #ifndef USE_ROSEN_DRAWING
GetWatermarkImg()2101 sk_sp<SkImage> RSMainThread::GetWatermarkImg()
2102 #else
2103 std::shared_ptr<Drawing::Image> RSMainThread::GetWatermarkImg()
2104 #endif
2105 {
2106     return watermarkImg_;
2107 }
2108 
GetWatermarkFlag()2109 bool RSMainThread::GetWatermarkFlag()
2110 {
2111     return isShow_;
2112 }
2113 
IsSingleDisplay()2114 bool RSMainThread::IsSingleDisplay()
2115 {
2116     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
2117     if (rootNode == nullptr) {
2118         RS_LOGE("RSMainThread::IsSingleDisplay GetGlobalRootRenderNode fail");
2119         return false;
2120     }
2121     return rootNode->GetChildrenCount() == 1;
2122 }
2123 
2124 const uint32_t UIFIRST_MINIMUM_NODE_NUMBER = 20;
UpdateUIFirstSwitch()2125 void RSMainThread::UpdateUIFirstSwitch()
2126 {
2127     if (deviceType_ == DeviceType::PHONE) {
2128         isUiFirstOn_ = (RSSystemProperties::GetUIFirstEnabled() && IsSingleDisplay());
2129         return;
2130     }
2131     isUiFirstOn_ = false;
2132     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
2133     if (rootNode && IsSingleDisplay()) {
2134         auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(
2135             rootNode->GetSortedChildren().front());
2136         if (displayNode) {
2137             uint32_t childrenCount = 0;
2138             if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
2139                 std::vector<RSBaseRenderNode::SharedPtr> curAllSurfacesVec;
2140                 displayNode->CollectSurface(displayNode, curAllSurfacesVec, true, true);
2141                 childrenCount = curAllSurfacesVec.size();
2142             } else {
2143                 childrenCount = displayNode->GetChildrenCount();
2144             }
2145             isUiFirstOn_ = RSSystemProperties::GetUIFirstEnabled() &&
2146                 (childrenCount >= UIFIRST_MINIMUM_NODE_NUMBER);
2147         }
2148     }
2149 }
2150 
IsUIFirstOn() const2151 bool RSMainThread::IsUIFirstOn() const
2152 {
2153     return isUiFirstOn_;
2154 }
2155 } // namespace Rosen
2156 } // namespace OHOS
2157