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