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 #define EGL_EGLEXT_PROTOTYPES
16 #include "pipeline/rs_main_thread.h"
17
18 #include <list>
19 #include <algorithm>
20 #include "hgm_core.h"
21 #include "include/core/SkGraphics.h"
22 #include "memory/rs_memory_graphic.h"
23 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
24 #include <securec.h>
25 #include <stdint.h>
26 #include <string>
27 #include <unistd.h>
28 #include <malloc.h>
29 #ifdef RS_ENABLE_GL
30 #include "GLES3/gl3.h"
31 #include "EGL/egl.h"
32 #include "EGL/eglext.h"
33 #endif
34 #include "include/gpu/GrDirectContext.h"
35 #include "rs_trace.h"
36
37 #include "animation/rs_animation_fraction.h"
38 #include "benchmarks/file_utils.h"
39 #include "command/rs_message_processor.h"
40 #include "common/rs_background_thread.h"
41 #ifdef RS_ENABLE_PARALLEL_UPLOAD
42 #include "rs_upload_resource_thread.h"
43 #endif
44 #include "delegate/rs_functional_delegate.h"
45 #include "memory/rs_memory_manager.h"
46 #include "memory/rs_memory_track.h"
47 #include "common/rs_common_def.h"
48 #include "common/rs_optional_trace.h"
49 #include "hgm_core.h"
50 #include "hgm_frame_rate_manager.h"
51 #include "platform/ohos/rs_jank_stats.h"
52 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
53 #include "pipeline/rs_base_render_node.h"
54 #include "pipeline/rs_base_render_util.h"
55 #include "pipeline/rs_divided_render_util.h"
56 #include "pipeline/rs_frame_report.h"
57 #include "pipeline/rs_render_engine.h"
58 #include "pipeline/rs_render_service_visitor.h"
59 #include "pipeline/rs_root_render_node.h"
60 #include "pipeline/rs_hardware_thread.h"
61 #include "pipeline/rs_surface_render_node.h"
62 #include "pipeline/rs_task_dispatcher.h"
63 #include "pipeline/rs_unmarshal_thread.h"
64 #include "pipeline/rs_uni_render_engine.h"
65 #include "pipeline/rs_uni_render_visitor.h"
66 #include "pipeline/rs_uni_render_util.h"
67 #include "pipeline/rs_occlusion_config.h"
68 #include "pipeline/sk_resource_manager.h"
69 #include "platform/common/rs_log.h"
70 #include "platform/common/rs_innovation.h"
71 #include "platform/common/rs_system_properties.h"
72 #include "platform/drawing/rs_vsync_client.h"
73 #include "property/rs_property_trace.h"
74 #include "property/rs_properties_painter.h"
75 #include "property/rs_point_light_manager.h"
76 #ifdef NEW_RENDER_CONTEXT
77 #include "render_context/memory_handler.h"
78 #endif
79 #include "render/rs_pixel_map_util.h"
80 #include "screen_manager/rs_screen_manager.h"
81 #include "transaction/rs_transaction_proxy.h"
82
83 #include "rs_qos_thread.h"
84 #include "xcollie/watchdog.h"
85
86 #include "render_frame_trace.h"
87
88 #if defined(ACCESSIBILITY_ENABLE)
89 #include "accessibility_config.h"
90 #endif
91
92 #ifdef SOC_PERF_ENABLE
93 #include "socperf_client.h"
94 #endif
95
96 #if defined(RS_ENABLE_DRIVEN_RENDER)
97 #include "pipeline/driven_render/rs_driven_render_manager.h"
98 #endif
99
100 #include "pipeline/round_corner_display/rs_rcd_render_manager.h"
101 #include "scene_board_judgement.h"
102 #include "vsync_iconnection_token.h"
103
104 #include "mem_mgr_client.h"
105
106 using namespace FRAME_TRACE;
107 static const std::string RS_INTERVAL_NAME = "renderservice";
108
109 #if defined(ACCESSIBILITY_ENABLE)
110 using namespace OHOS::AccessibilityConfig;
111 #endif
112
113 namespace OHOS {
114 namespace Rosen {
115 namespace {
116 constexpr uint32_t REQUEST_VSYNC_NUMBER_LIMIT = 10;
117 constexpr uint64_t REFRESH_PERIOD = 16666667;
118 constexpr int32_t PERF_MULTI_WINDOW_REQUESTED_CODE = 10026;
119 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
120 constexpr uint64_t PERF_PERIOD = 250000000;
121 constexpr uint64_t CLEAN_CACHE_FREQ = 60;
122 constexpr uint64_t SKIP_COMMAND_FREQ_LIMIT = 30;
123 constexpr uint64_t PERF_PERIOD_BLUR = 1000000000;
124 constexpr uint64_t PERF_PERIOD_BLUR_TIMEOUT = 80000000;
125 constexpr uint64_t MAX_DYNAMIC_STATUS_TIME = 5000000000;
126 constexpr uint64_t MAX_SYSTEM_SCENE_STATUS_TIME = 800000000;
127 constexpr uint64_t PERF_PERIOD_MULTI_WINDOW = 80000000;
128 constexpr uint32_t MULTI_WINDOW_PERF_START_NUM = 2;
129 constexpr uint32_t MULTI_WINDOW_PERF_END_NUM = 4;
130 constexpr uint32_t TIME_OF_EIGHT_FRAMES = 8000;
131 constexpr uint32_t TIME_OF_THE_FRAMES = 1000;
132 constexpr uint32_t WAIT_FOR_RELEASED_BUFFER_TIMEOUT = 3000;
133 constexpr uint32_t WAIT_FOR_HARDWARE_THREAD_TASK_TIMEOUT = 3000;
134 constexpr uint32_t WAIT_FOR_SURFACE_CAPTURE_PROCESS_TIMEOUT = 1000;
135 constexpr uint32_t WATCHDOG_TIMEVAL = 5000;
136 constexpr uint32_t HARDWARE_THREAD_TASK_NUM = 2;
137 constexpr int32_t SIMI_VISIBLE_RATE = 2;
138 constexpr int32_t DEFAULT_RATE = 1;
139 constexpr int32_t INVISBLE_WINDOW_RATE = 10;
140 constexpr int32_t SYSTEM_ANIMATED_SECNES_RATE = 2;
141 constexpr int32_t MAX_MULTI_INSTANCE_PID_COUNT = 1;
142 constexpr uint32_t WAIT_FOR_MEM_MGR_SERVICE = 100;
143 constexpr uint32_t CAL_NODE_PREFERRED_FPS_LIMIT = 50;
144 constexpr uint32_t EVENT_SET_HARDWARE_UTIL = 100004;
145 constexpr const char* WALLPAPER_VIEW = "WallpaperView";
146 constexpr const char* CLEAR_GPU_CACHE = "ClearGpuCache";
147 constexpr const char* MEM_MGR = "MemMgr";
148 constexpr const char* DESKTOP_NAME_FOR_ROTATION = "SCBDesktop";
149 #ifdef RS_ENABLE_GL
150 constexpr size_t DEFAULT_SKIA_CACHE_SIZE = 96 * (1 << 20);
151 constexpr int DEFAULT_SKIA_CACHE_COUNT = 2 * (1 << 12);
152 #endif
153 #if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
154 constexpr const char* MEM_GPU_TYPE = "gpu";
155 #endif
156 const std::map<int, int32_t> BLUR_CNT_TO_BLUR_CODE {
157 { 1, 10021 },
158 { 2, 10022 },
159 { 3, 10023 },
160 };
161
Compare(const std::unique_ptr<RSTransactionData> & data1,const std::unique_ptr<RSTransactionData> & data2)162 bool Compare(const std::unique_ptr<RSTransactionData>& data1, const std::unique_ptr<RSTransactionData>& data2)
163 {
164 if (!data1 || !data2) {
165 RS_LOGW("Compare RSTransactionData: nullptr!");
166 return true;
167 }
168 return data1->GetIndex() < data2->GetIndex();
169 }
170
InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>> & source,std::vector<std::unique_ptr<RSTransactionData>> & target)171 void InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>>& source,
172 std::vector<std::unique_ptr<RSTransactionData>>& target)
173 {
174 target.insert(target.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.end()));
175 source.clear();
176 }
177
PerfRequest(int32_t perfRequestCode,bool onOffTag)178 void PerfRequest(int32_t perfRequestCode, bool onOffTag)
179 {
180 #ifdef SOC_PERF_ENABLE
181 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(perfRequestCode, onOffTag, "");
182 RS_LOGD("RSMainThread::soc perf info [%{public}d %{public}d]", perfRequestCode, onOffTag);
183 #endif
184 }
185 }
186
187 #if defined(ACCESSIBILITY_ENABLE)
188 class AccessibilityObserver : public AccessibilityConfigObserver {
189 public:
190 AccessibilityObserver() = default;
OnConfigChanged(const CONFIG_ID id,const ConfigValue & value)191 void OnConfigChanged(const CONFIG_ID id, const ConfigValue &value) override
192 {
193 RS_LOGD("AccessibilityObserver OnConfigChanged configId: %{public}d", id);
194 ColorFilterMode mode = ColorFilterMode::COLOR_FILTER_END;
195 if (id == CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER) {
196 switch (value.daltonizationColorFilter) {
197 case Protanomaly:
198 mode = ColorFilterMode::DALTONIZATION_PROTANOMALY_MODE;
199 break;
200 case Deuteranomaly:
201 mode = ColorFilterMode::DALTONIZATION_DEUTERANOMALY_MODE;
202 break;
203 case Tritanomaly:
204 mode = ColorFilterMode::DALTONIZATION_TRITANOMALY_MODE;
205 break;
206 case Normal:
207 mode = ColorFilterMode::DALTONIZATION_NORMAL_MODE;
208 break;
209 default:
210 break;
211 }
212 RSBaseRenderEngine::SetColorFilterMode(mode);
213 } else if (id == CONFIG_ID::CONFIG_INVERT_COLOR) {
214 mode = value.invertColor ? ColorFilterMode::INVERT_COLOR_ENABLE_MODE :
215 ColorFilterMode::INVERT_COLOR_DISABLE_MODE;
216 RSBaseRenderEngine::SetColorFilterMode(mode);
217 } else if (id == CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT) {
218 RSBaseRenderEngine::SetHighContrast(value.highContrastText);
219 } else {
220 RS_LOGW("AccessibilityObserver configId: %{public}d is not supported yet.", id);
221 }
222 RSMainThread::Instance()->PostTask([]() {
223 RSMainThread::Instance()->SetAccessibilityConfigChanged();
224 RSMainThread::Instance()->RequestNextVSync();
225 });
226 }
227 };
228 #endif
WaitUntilUploadTextureTaskFinished(bool isUniRender)229 static inline void WaitUntilUploadTextureTaskFinished(bool isUniRender)
230 {
231 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_PARALLEL_UPLOAD)
232 #if defined(NEW_SKIA) && defined(RS_ENABLE_UNI_RENDER)
233 if (isUniRender) {
234 RSUploadResourceThread::Instance().OnProcessBegin();
235 }
236 return;
237 #endif
238 #endif
239 }
240
Instance()241 RSMainThread* RSMainThread::Instance()
242 {
243 static RSMainThread instance;
244 RSAnimationFraction::Init();
245 return &instance;
246 }
247
RSMainThread()248 RSMainThread::RSMainThread() : mainThreadId_(std::this_thread::get_id())
249 {
250 context_ = std::make_shared<RSContext>();
251 context_->Initialize();
252 }
253
~RSMainThread()254 RSMainThread::~RSMainThread() noexcept
255 {
256 RemoveRSEventDetector();
257 RSInnovation::CloseInnovationSo();
258 if (rsAppStateListener_) {
259 Memory::MemMgrClient::GetInstance().UnsubscribeAppState(*rsAppStateListener_);
260 }
261 }
262
Init()263 void RSMainThread::Init()
264 {
265 mainLoop_ = [&]() {
266 mainLooping_.store(true);
267 RenderFrameStart(timestamp_);
268 #if defined(RS_ENABLE_UNI_RENDER)
269 WaitUntilSurfaceCapProcFinished();
270 #endif
271 PerfMultiWindow();
272 SetRSEventDetectorLoopStartTag();
273 ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSMainThread::DoComposition");
274 ConsumeAndUpdateAllNodes();
275 WaitUntilUnmarshallingTaskFinished();
276 ProcessCommand();
277 Animate(timestamp_);
278 ApplyModifiers();
279 CollectInfoForHardwareComposer();
280 ProcessHgmFrameRate(timestamp_);
281 #if defined(RS_ENABLE_DRIVEN_RENDER)
282 CollectInfoForDrivenRender();
283 #endif
284 Render();
285 InformHgmNodeInfo();
286 ReleaseAllNodesBuffer();
287 auto subThreadManager = RSSubThreadManager::Instance();
288 subThreadManager->SubmitFilterSubThreadTask();
289 SendCommands();
290 {
291 std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
292 context_->activeNodesInRoot_.clear();
293 }
294 ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
295 SetRSEventDetectorLoopFinishTag();
296 rsEventManager_.UpdateParam();
297 SKResourceManager::Instance().ReleaseResource();
298 #ifdef RS_ENABLE_PARALLEL_UPLOAD
299 RSUploadResourceThread::Instance().OnRenderEnd();
300 #endif
301 mainLooping_.store(false);
302 };
303 static std::function<void (std::shared_ptr<Drawing::Image> image)> holdDrawingImagefunc =
304 [] (std::shared_ptr<Drawing::Image> image) -> void {
305 if (image) {
306 SKResourceManager::Instance().HoldResource(image);
307 }
308 };
309 Drawing::DrawOpItem::SetBaseCallback(holdDrawingImagefunc);
310
311 isUniRender_ = RSUniRenderJudgement::IsUniRender();
312 SetDeviceType();
313 qosPidCal_ = deviceType_ == DeviceType::PC;
314 isFoldScreenDevice_ = system::GetParameter("const.window.foldscreen.type", "") == "true";
315 auto taskDispatchFunc = [](const RSTaskDispatcher::RSTask& task, bool isSyncTask = false) {
316 RSMainThread::Instance()->PostTask(task);
317 };
318 context_->SetTaskRunner(taskDispatchFunc);
319 context_->SetVsyncRequestFunc([]() {
320 RSMainThread::Instance()->RequestNextVSync();
321 RSMainThread::Instance()->SetDirtyFlag();
322 });
323 RSTaskDispatcher::GetInstance().RegisterTaskDispatchFunc(gettid(), taskDispatchFunc);
324 RsFrameReport::GetInstance().Init();
325 if (isUniRender_) {
326 unmarshalBarrierTask_ = [this]() {
327 auto cachedTransactionData = RSUnmarshalThread::Instance().GetCachedTransactionData();
328 MergeToEffectiveTransactionDataMap(cachedTransactionData);
329 {
330 std::lock_guard<std::mutex> lock(unmarshalMutex_);
331 ++unmarshalFinishedCount_;
332 }
333 unmarshalTaskCond_.notify_all();
334 };
335 RSUnmarshalThread::Instance().Start();
336 }
337
338 runner_ = AppExecFwk::EventRunner::Create(false);
339 handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
340 int ret = HiviewDFX::Watchdog::GetInstance().AddThread("RenderService", handler_, WATCHDOG_TIMEVAL);
341 if (ret != 0) {
342 RS_LOGW("Add watchdog thread failed");
343 }
344 InitRSEventDetector();
345 sptr<VSyncIConnectionToken> token = new IRemoteStub<VSyncIConnectionToken>();
346 sptr<VSyncConnection> conn = new VSyncConnection(rsVSyncDistributor_, "rs", token->AsObject());
347 rsFrameRateLinker_ = std::make_shared<RSRenderFrameRateLinker>();
348 conn->id_ = rsFrameRateLinker_->GetId();
349 rsVSyncDistributor_->AddConnection(conn);
350 receiver_ = std::make_shared<VSyncReceiver>(conn, token->AsObject(), handler_);
351 receiver_->Init();
352 if (isUniRender_) {
353 uniRenderEngine_ = std::make_shared<RSUniRenderEngine>();
354 uniRenderEngine_->Init();
355 } else {
356 renderEngine_ = std::make_shared<RSRenderEngine>();
357 renderEngine_->Init();
358 }
359 #ifdef RS_ENABLE_GL
360 if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
361 int cacheLimitsTimes = ((system::GetParameter("const.product.devicetype", "") == "ALT") ||
362 deviceType_ == DeviceType::PC) ? 6 : 3;
363 #ifndef USE_ROSEN_DRAWING
364 #ifdef NEW_RENDER_CONTEXT
365 auto grContext = isUniRender_? uniRenderEngine_->GetDrawingContext()->GetDrawingContext() :
366 renderEngine_->GetDrawingContext()->GetDrawingContext();
367 #else
368 auto grContext = isUniRender_? uniRenderEngine_->GetRenderContext()->GetGrContext() :
369 renderEngine_->GetRenderContext()->GetGrContext();
370 #endif
371 int maxResources = 0;
372 size_t maxResourcesSize = 0;
373 grContext->getResourceCacheLimits(&maxResources, &maxResourcesSize);
374 if (maxResourcesSize > 0) {
375 grContext->setResourceCacheLimits(cacheLimitsTimes * maxResources, cacheLimitsTimes *
376 std::fmin(maxResourcesSize, DEFAULT_SKIA_CACHE_SIZE));
377 } else {
378 grContext->setResourceCacheLimits(DEFAULT_SKIA_CACHE_COUNT, DEFAULT_SKIA_CACHE_SIZE);
379 }
380 #else
381 #ifdef NEW_RENDER_CONTEXT
382 auto gpuContext = isUniRender_? uniRenderEngine_->GetDrawingContext()->GetDrawingContext() :
383 renderEngine_->GetDrawingContext()->GetDrawingContext();
384 #else
385 auto gpuContext = isUniRender_? uniRenderEngine_->GetRenderContext()->GetDrGPUContext() :
386 renderEngine_->GetRenderContext()->GetDrGPUContext();
387 #endif
388 if (gpuContext == nullptr) {
389 RS_LOGE("RSMainThread::Init gpuContext is nullptr!");
390 return;
391 }
392 int32_t maxResources = 0;
393 size_t maxResourcesSize = 0;
394 gpuContext->GetResourceCacheLimits(&maxResources, &maxResourcesSize);
395 if (maxResourcesSize > 0) {
396 gpuContext->SetResourceCacheLimits(cacheLimitsTimes * maxResources, cacheLimitsTimes *
397 std::fmin(maxResourcesSize, DEFAULT_SKIA_CACHE_SIZE));
398 } else {
399 gpuContext->SetResourceCacheLimits(DEFAULT_SKIA_CACHE_COUNT, DEFAULT_SKIA_CACHE_SIZE);
400 }
401 #endif // USE_ROSEN_DRAWING
402 }
403 #endif // RS_ENABLE_GL
404 RSInnovation::OpenInnovationSo();
405 #if defined(RS_ENABLE_DRIVEN_RENDER)
406 RSDrivenRenderManager::InitInstance();
407 RSBackgroundThread::Instance().InitRenderContext(GetRenderEngine()->GetRenderContext().get());
408 #endif
409
410 RSRcdRenderManager::InitInstance();
411
412 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_PARALLEL_UPLOAD)
413 if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
414 #if defined(NEW_SKIA) && defined(RS_ENABLE_UNI_RENDER)
415 RSUploadResourceThread::Instance().InitRenderContext(GetRenderEngine()->GetRenderContext().get());
416 #endif
417 }
418 #endif
419
420 #if defined(ACCESSIBILITY_ENABLE)
421 accessibilityObserver_ = std::make_shared<AccessibilityObserver>();
422 auto &config = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
423 config.InitializeContext();
424 config.SubscribeConfigObserver(CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER, accessibilityObserver_);
425 config.SubscribeConfigObserver(CONFIG_ID::CONFIG_INVERT_COLOR, accessibilityObserver_);
426 if (isUniRender_) {
427 config.SubscribeConfigObserver(CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT, accessibilityObserver_);
428 }
429 #endif
430
431 auto delegate = RSFunctionalDelegate::Create();
432 delegate->SetRepaintCallback([]() { RSMainThread::Instance()->RequestNextVSync(); });
433 RSOverdrawController::GetInstance().SetDelegate(delegate);
434
435 frameRateMgr_ = OHOS::Rosen::HgmCore::Instance().GetFrameRateMgr();
436 frameRateMgr_->SetForceUpdateCallback([](bool idleTimerExpired, bool forceUpdate) {
437 RSMainThread::Instance()->PostTask([idleTimerExpired, forceUpdate]() {
438 RS_TRACE_NAME_FMT("RSMainThread::TimerExpiredCallback Run idleTimerExpiredFlag: %s forceUpdateFlag: %s",
439 idleTimerExpired? "True":"False", forceUpdate? "True": "False");
440 RSMainThread::Instance()->SetForceUpdateUniRenderFlag(forceUpdate);
441 RSMainThread::Instance()->SetIdleTimerExpiredFlag(idleTimerExpired);
442 RSMainThread::Instance()->RequestNextVSync();
443 });
444 });
445 frameRateMgr_->Init(rsVSyncController_, appVSyncController_, vsyncGenerator_);
446 SubscribeAppState();
447 PrintCurrentStatus();
448 }
449
RsEventParamDump(std::string & dumpString)450 void RSMainThread::RsEventParamDump(std::string& dumpString)
451 {
452 rsEventManager_.DumpAllEventParam(dumpString);
453 }
454
RemoveRSEventDetector()455 void RSMainThread::RemoveRSEventDetector()
456 {
457 if (rsCompositionTimeoutDetector_ != nullptr) {
458 rsEventManager_.RemoveEvent(rsCompositionTimeoutDetector_->GetStringId());
459 }
460 }
461
InitRSEventDetector()462 void RSMainThread::InitRSEventDetector()
463 {
464 // default Threshold value of Timeout Event: 100ms
465 rsCompositionTimeoutDetector_ = RSBaseEventDetector::CreateRSTimeOutDetector(100, "RS_COMPOSITION_TIMEOUT");
466 if (rsCompositionTimeoutDetector_ != nullptr) {
467 rsEventManager_.AddEvent(rsCompositionTimeoutDetector_, 60000); // report Internal 1min:60s:60000ms
468 RS_LOGD("InitRSEventDetector finish");
469 }
470 }
471
SetDeviceType()472 void RSMainThread::SetDeviceType()
473 {
474 auto deviceTypeStr = system::GetParameter("const.product.devicetype", "pc");
475 if (deviceTypeStr == "pc" || deviceTypeStr == "2in1") {
476 deviceType_ = DeviceType::PC;
477 } else if (deviceTypeStr == "tablet") {
478 deviceType_ = DeviceType::TABLET;
479 } else if (deviceTypeStr == "phone") {
480 deviceType_ = DeviceType::PHONE;
481 } else {
482 deviceType_ = DeviceType::OTHERS;
483 }
484 }
485
GetDeviceType() const486 DeviceType RSMainThread::GetDeviceType() const
487 {
488 return deviceType_;
489 }
490
GetFocusNodeId() const491 uint64_t RSMainThread::GetFocusNodeId() const
492 {
493 return focusNodeId_;
494 }
495
GetFocusLeashWindowId() const496 uint64_t RSMainThread::GetFocusLeashWindowId() const
497 {
498 return focusLeashWindowId_;
499 }
500
SetFocusLeashWindowId()501 void RSMainThread::SetFocusLeashWindowId()
502 {
503 const auto& nodeMap = context_->GetNodeMap();
504 auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(focusNodeId_));
505 if (node != nullptr) {
506 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node->GetParent().lock());
507 if (node->IsAppWindow() && parent && parent->IsLeashWindow()) {
508 focusLeashWindowId_ = parent->GetId();
509 }
510 }
511 }
512
SetIsCachedSurfaceUpdated(bool isCachedSurfaceUpdated)513 void RSMainThread::SetIsCachedSurfaceUpdated(bool isCachedSurfaceUpdated)
514 {
515 isCachedSurfaceUpdated_ = isCachedSurfaceUpdated;
516 }
517
SetRSEventDetectorLoopStartTag()518 void RSMainThread::SetRSEventDetectorLoopStartTag()
519 {
520 if (rsCompositionTimeoutDetector_ != nullptr) {
521 rsCompositionTimeoutDetector_->SetLoopStartTag();
522 }
523 }
524
SetRSEventDetectorLoopFinishTag()525 void RSMainThread::SetRSEventDetectorLoopFinishTag()
526 {
527 if (rsCompositionTimeoutDetector_ != nullptr) {
528 if (isUniRender_) {
529 rsCompositionTimeoutDetector_->SetLoopFinishTag(
530 focusAppPid_, focusAppUid_, focusAppBundleName_, focusAppAbilityName_);
531 } else {
532 std::string defaultFocusAppInfo = "";
533 rsCompositionTimeoutDetector_->SetLoopFinishTag(
534 -1, -1, defaultFocusAppInfo, defaultFocusAppInfo);
535 }
536 }
537 }
538
SetFocusAppInfo(int32_t pid,int32_t uid,const std::string & bundleName,const std::string & abilityName,uint64_t focusNodeId)539 void RSMainThread::SetFocusAppInfo(
540 int32_t pid, int32_t uid, const std::string &bundleName, const std::string &abilityName, uint64_t focusNodeId)
541 {
542 focusAppPid_ = pid;
543 focusAppUid_ = uid;
544 focusAppBundleName_ = bundleName;
545 focusAppAbilityName_ = abilityName;
546 focusNodeId_ = focusNodeId;
547 }
548
GetFocusAppBundleName() const549 std::string RSMainThread::GetFocusAppBundleName() const
550 {
551 return focusAppBundleName_;
552 }
553
Start()554 void RSMainThread::Start()
555 {
556 if (runner_) {
557 runner_->Run();
558 }
559 }
560
ProcessCommand()561 void RSMainThread::ProcessCommand()
562 {
563 // To improve overall responsiveness, we make animations start on LAST frame instead of THIS frame.
564 // If last frame is too far away (earlier than 1 vsync from now), we use currentTimestamp_ - REFRESH_PERIOD as
565 // 'virtual' last frame timestamp.
566 if (timestamp_ - lastAnimateTimestamp_ > REFRESH_PERIOD) { // if last frame is earlier than 1 vsync from now
567 context_->currentTimestamp_ = timestamp_ - REFRESH_PERIOD;
568 } else {
569 context_->currentTimestamp_ = lastAnimateTimestamp_;
570 }
571 if (isUniRender_) {
572 ProcessCommandForUniRender();
573 } else {
574 ProcessCommandForDividedRender();
575 }
576 switch (context_->purgeType_) {
577 case RSContext::PurgeType::GENTLY:
578 ClearMemoryCache(context_->clearMoment_, false);
579 break;
580 case RSContext::PurgeType::STRONGLY:
581 ClearMemoryCache(context_->clearMoment_, true);
582 break;
583 default:
584 break;
585 }
586 context_->purgeType_ = RSContext::PurgeType::NONE;
587 if (RsFrameReport::GetInstance().GetEnable()) {
588 RsFrameReport::GetInstance().AnimateStart();
589 }
590 }
591
PrintCurrentStatus()592 void RSMainThread::PrintCurrentStatus()
593 {
594 #ifndef USE_ROSEN_DRAWING
595 RS_LOGE("RSMainThread::PrintCurrentStatus: drawing is closed");
596 #else
597 std::string gpuType = "";
598 switch (OHOS::Rosen::RSSystemProperties::GetGpuApiType()) {
599 case OHOS::Rosen::GpuApiType::OPENGL:
600 gpuType = "opengl";
601 break;
602 case OHOS::Rosen::GpuApiType::VULKAN:
603 gpuType = "vulkan";
604 break;
605 case OHOS::Rosen::GpuApiType::DDGR:
606 gpuType = "ddgr";
607 break;
608 default:
609 break;
610 }
611 RS_LOGI("[Drawing] Version: Non-released");
612 RS_LOGE("RSMainThread::PrintCurrentStatus: drawing is opened, gpu type is %{public}s", gpuType.c_str());
613 #endif
614 }
615
CacheCommands()616 void RSMainThread::CacheCommands()
617 {
618 RS_OPTIONAL_TRACE_FUNC();
619 for (auto& skipTransactionData : cachedSkipTransactionDataMap_) {
620 pid_t pid = skipTransactionData.first;
621 RS_TRACE_NAME("cacheCmd pid: " + std::to_string(pid));
622 auto& skipTransactionDataVec = skipTransactionData.second;
623 cachedTransactionDataMap_[pid].insert(cachedTransactionDataMap_[pid].begin(),
624 std::make_move_iterator(skipTransactionDataVec.begin()),
625 std::make_move_iterator(skipTransactionDataVec.end()));
626 }
627 }
628
CheckIfNodeIsBundle(std::shared_ptr<RSSurfaceRenderNode> node)629 void RSMainThread::CheckIfNodeIsBundle(std::shared_ptr<RSSurfaceRenderNode> node)
630 {
631 currentBundleName_ = node->GetBundleName();
632 if (node->GetName() == WALLPAPER_VIEW) {
633 noBundle_ = true;
634 }
635 }
636
InformHgmNodeInfo()637 void RSMainThread::InformHgmNodeInfo()
638 {
639 auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
640 int32_t informResult = EXEC_SUCCESS;
641 if (currentBundleName_ != "") {
642 informResult = hgmCore.RefreshBundleName(currentBundleName_);
643 } else if (noBundle_) {
644 currentBundleName_ = "";
645 informResult = hgmCore.RefreshBundleName(currentBundleName_);
646 noBundle_ = false;
647 }
648 if (informResult != EXEC_SUCCESS) {
649 RS_LOGE("RSMainThread::InformHgmNodeInfo failed to refresh bundle name in hgm");
650 }
651 }
652
GetCacheCmdSkippedNodes() const653 std::unordered_map<NodeId, bool> RSMainThread::GetCacheCmdSkippedNodes() const
654 {
655 return cacheCmdSkippedNodes_;
656 }
657
CheckParallelSubThreadNodesStatus()658 bool RSMainThread::CheckParallelSubThreadNodesStatus()
659 {
660 RS_OPTIONAL_TRACE_FUNC();
661 cacheCmdSkippedInfo_.clear();
662 cacheCmdSkippedNodes_.clear();
663 if (subThreadNodes_.empty() &&
664 (deviceType_ == DeviceType::PHONE || (LeashWindowCount_ > 0 && isUiFirstOn_ == false))) {
665 RSSubThreadManager::Instance()->ResetSubThreadGrContext();
666 return false;
667 }
668 for (auto& node : subThreadNodes_) {
669 if (node == nullptr) {
670 RS_LOGE("RSMainThread::CheckParallelSubThreadNodesStatus sunThreadNode is nullptr!");
671 continue;
672 }
673 if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
674 RS_TRACE_NAME("node:[ " + node->GetName() + "]");
675 pid_t pid = 0;
676 if (node->IsAppWindow()) {
677 pid = ExtractPid(node->GetId());
678 } else if (node->IsLeashWindow()) {
679 for (auto& child : *node->GetSortedChildren()) {
680 auto surfaceNodePtr = child->ReinterpretCastTo<RSSurfaceRenderNode>();
681 if (surfaceNodePtr && surfaceNodePtr->IsAppWindow()) {
682 pid = ExtractPid(child->GetId());
683 break;
684 }
685 }
686 }
687 cacheCmdSkippedNodes_[node->GetId()] = false;
688 if (pid == 0) {
689 continue;
690 }
691 RS_LOGD("RSMainThread::CheckParallelSubThreadNodesStatus pid = %{public}s, node name: %{public}s,"
692 "id: %{public}" PRIu64 "", std::to_string(pid).c_str(), node->GetName().c_str(), node->GetId());
693 if (cacheCmdSkippedInfo_.count(pid) == 0) {
694 cacheCmdSkippedInfo_[pid] = std::make_pair(std::vector<NodeId>{node->GetId()}, false);
695 } else {
696 cacheCmdSkippedInfo_[pid].first.push_back(node->GetId());
697 }
698 if (!node->HasAbilityComponent()) {
699 continue;
700 }
701 for (auto& nodeId : node->GetAbilityNodeIds()) {
702 pid_t abilityNodePid = ExtractPid(nodeId);
703 if (cacheCmdSkippedInfo_.count(abilityNodePid) == 0) {
704 cacheCmdSkippedInfo_[abilityNodePid] = std::make_pair(std::vector<NodeId>{node->GetId()}, true);
705 } else {
706 cacheCmdSkippedInfo_[abilityNodePid].first.push_back(node->GetId());
707 }
708 }
709 }
710 }
711 if (!cacheCmdSkippedNodes_.empty()) {
712 return true;
713 }
714 if (!isUiFirstOn_) {
715 // clear subThreadNodes_ when UIFirst off and none of subThreadNodes_ is in the state of doing
716 subThreadNodes_.clear();
717 }
718 return false;
719 }
720
IsNeedSkip(NodeId instanceRootNodeId,pid_t pid)721 bool RSMainThread::IsNeedSkip(NodeId instanceRootNodeId, pid_t pid)
722 {
723 return std::any_of(cacheCmdSkippedInfo_[pid].first.begin(), cacheCmdSkippedInfo_[pid].first.end(),
724 [instanceRootNodeId](const auto& cacheCmdSkipNodeId) {
725 return cacheCmdSkipNodeId == instanceRootNodeId;
726 });
727 }
728
SkipCommandByNodeId(std::vector<std::unique_ptr<RSTransactionData>> & transactionVec,pid_t pid)729 void RSMainThread::SkipCommandByNodeId(std::vector<std::unique_ptr<RSTransactionData>>& transactionVec, pid_t pid)
730 {
731 if (cacheCmdSkippedInfo_.find(pid) == cacheCmdSkippedInfo_.end()) {
732 return;
733 }
734 std::vector<std::unique_ptr<RSTransactionData>> skipTransactionVec;
735 const auto& nodeMap = context_->GetNodeMap();
736 for (auto& transactionData: transactionVec) {
737 std::vector<std::tuple<NodeId, FollowType, std::unique_ptr<RSCommand>>> skipPayload;
738 std::vector<size_t> skipPayloadIndexVec;
739 auto& processPayload = transactionData->GetPayload();
740 for (size_t index = 0; index < processPayload.size(); ++index) {
741 auto& elem = processPayload[index];
742 if (std::get<2>(elem) == nullptr) { // check elem is valid
743 continue;
744 }
745 NodeId nodeId = std::get<2>(elem)->GetNodeId();
746 auto node = nodeMap.GetRenderNode(nodeId);
747 if (node == nullptr) {
748 continue;
749 }
750 NodeId firstLevelNodeId = node->GetFirstLevelNodeId();
751 if (IsNeedSkip(firstLevelNodeId, pid)) {
752 skipPayload.emplace_back(std::move(elem));
753 skipPayloadIndexVec.push_back(index);
754 }
755 }
756 if (!skipPayload.empty()) {
757 std::unique_ptr<RSTransactionData> skipTransactionData = std::make_unique<RSTransactionData>();
758 skipTransactionData->SetTimestamp(transactionData->GetTimestamp());
759 std::string ablityName = transactionData->GetAbilityName();
760 skipTransactionData->SetAbilityName(ablityName);
761 skipTransactionData->SetSendingPid(transactionData->GetSendingPid());
762 skipTransactionData->SetIndex(transactionData->GetIndex());
763 skipTransactionData->GetPayload() = std::move(skipPayload);
764 skipTransactionData->SetIsCached(true);
765 skipTransactionVec.emplace_back(std::move(skipTransactionData));
766 }
767 for (auto iter = skipPayloadIndexVec.rbegin(); iter != skipPayloadIndexVec.rend(); ++iter) {
768 processPayload.erase(processPayload.begin() + *iter);
769 }
770 }
771 if (!skipTransactionVec.empty()) {
772 cachedSkipTransactionDataMap_[pid] = std::move(skipTransactionVec);
773 }
774 }
775
CheckAndUpdateTransactionIndex(std::shared_ptr<TransactionDataMap> & transactionDataEffective,std::string & transactionFlags)776 void RSMainThread::CheckAndUpdateTransactionIndex(std::shared_ptr<TransactionDataMap>& transactionDataEffective,
777 std::string& transactionFlags)
778 {
779 for (auto& rsTransactionElem: effectiveTransactionDataIndexMap_) {
780 auto pid = rsTransactionElem.first;
781 auto& lastIndex = rsTransactionElem.second.first;
782 auto& transactionVec = rsTransactionElem.second.second;
783 auto iter = transactionVec.begin();
784 for (; iter != transactionVec.end(); ++iter) {
785 if ((*iter) == nullptr) {
786 continue;
787 }
788 if ((*iter)->GetIsCached()) {
789 continue;
790 }
791 auto curIndex = (*iter)->GetIndex();
792 if (curIndex == lastIndex + 1) {
793 if ((*iter)->GetTimestamp() >= timestamp_) {
794 break;
795 }
796 ++lastIndex;
797 transactionFlags += " [" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
798 } else {
799 RS_LOGE("%{public}s wait curIndex:%{public}" PRIu64 ", lastIndex:%{public}" PRIu64 ", pid:%{public}d",
800 __FUNCTION__, curIndex, lastIndex, pid);
801 if (transactionDataLastWaitTime_[pid] == 0) {
802 transactionDataLastWaitTime_[pid] = timestamp_;
803 }
804 if ((timestamp_ - transactionDataLastWaitTime_[pid]) / REFRESH_PERIOD > SKIP_COMMAND_FREQ_LIMIT) {
805 transactionDataLastWaitTime_[pid] = 0;
806 lastIndex = curIndex;
807 transactionFlags += " skip to[" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
808 RS_LOGE("%{public}s skip to index:%{public}" PRIu64 ", pid:%{public}d",
809 __FUNCTION__, curIndex, pid);
810 continue;
811 }
812 break;
813 }
814 }
815 if (iter != transactionVec.begin()) {
816 (*transactionDataEffective)[pid].insert((*transactionDataEffective)[pid].end(),
817 std::make_move_iterator(transactionVec.begin()), std::make_move_iterator(iter));
818 transactionVec.erase(transactionVec.begin(), iter);
819 }
820 }
821 }
822
ProcessCommandForUniRender()823 void RSMainThread::ProcessCommandForUniRender()
824 {
825 std::shared_ptr<TransactionDataMap> transactionDataEffective = std::make_shared<TransactionDataMap>();
826 std::string transactionFlags;
827 bool isNeedCacheCmd = CheckParallelSubThreadNodesStatus();
828 {
829 std::lock_guard<std::mutex> lock(transitionDataMutex_);
830 cachedSkipTransactionDataMap_.clear();
831 for (auto& rsTransactionElem: effectiveTransactionDataIndexMap_) {
832 auto& transactionVec = rsTransactionElem.second.second;
833 if (isNeedCacheCmd) {
834 auto pid = rsTransactionElem.first;
835 SkipCommandByNodeId(transactionVec, pid);
836 }
837 std::sort(transactionVec.begin(), transactionVec.end(), Compare);
838 }
839 if (isNeedCacheCmd) {
840 CacheCommands();
841 }
842 CheckAndUpdateTransactionIndex(transactionDataEffective, transactionFlags);
843 }
844 if (!transactionDataEffective->empty()) {
845 doDirectComposition_ = false;
846 }
847 RS_TRACE_NAME("RSMainThread::ProcessCommandUni" + transactionFlags);
848 for (auto& rsTransactionElem: *transactionDataEffective) {
849 for (auto& rsTransaction: rsTransactionElem.second) {
850 if (rsTransaction) {
851 if (rsTransaction->IsNeedSync() || syncTransactionData_.count(rsTransactionElem.first) > 0) {
852 ProcessSyncRSTransactionData(rsTransaction, rsTransactionElem.first);
853 continue;
854 }
855 ProcessRSTransactionData(rsTransaction, rsTransactionElem.first);
856 }
857 }
858 }
859 RSBackgroundThread::Instance().PostTask([ transactionDataEffective ] () {
860 RS_TRACE_NAME("RSMainThread::ProcessCommandForUniRender transactionDataEffective clear");
861 transactionDataEffective->clear();
862 });
863 }
864
ProcessCommandForDividedRender()865 void RSMainThread::ProcessCommandForDividedRender()
866 {
867 const auto& nodeMap = context_->GetNodeMap();
868 RS_TRACE_BEGIN("RSMainThread::ProcessCommand");
869 {
870 std::lock_guard<std::mutex> lock(transitionDataMutex_);
871 if (!pendingEffectiveCommands_.empty()) {
872 effectiveCommands_.swap(pendingEffectiveCommands_);
873 }
874 for (auto& [surfaceNodeId, commandMap] : cachedCommands_) {
875 auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(surfaceNodeId);
876 auto bufferTimestamp = bufferTimestamps_.find(surfaceNodeId);
877 std::map<uint64_t, std::vector<std::unique_ptr<RSCommand>>>::iterator effectIter;
878
879 if (!node || !node->IsOnTheTree() || bufferTimestamp == bufferTimestamps_.end()) {
880 // If node has been destructed or is not on the tree or has no valid buffer,
881 // for all command cached in commandMap should be executed immediately
882 effectIter = commandMap.end();
883 } else {
884 uint64_t timestamp = bufferTimestamp->second;
885 effectIter = commandMap.upper_bound(timestamp);
886 }
887
888 for (auto it = commandMap.begin(); it != effectIter; it++) {
889 effectiveCommands_[it->first].insert(effectiveCommands_[it->first].end(),
890 std::make_move_iterator(it->second.begin()), std::make_move_iterator(it->second.end()));
891 }
892 commandMap.erase(commandMap.begin(), effectIter);
893 }
894 }
895 for (auto& [timestamp, commands] : effectiveCommands_) {
896 context_->transactionTimestamp_ = timestamp;
897 for (auto& command : commands) {
898 if (command) {
899 command->Process(*context_);
900 }
901 }
902 }
903 effectiveCommands_.clear();
904 RS_TRACE_END();
905 }
906
ProcessRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData,pid_t pid)907 void RSMainThread::ProcessRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData, pid_t pid)
908 {
909 context_->transactionTimestamp_ = rsTransactionData->GetTimestamp();
910 rsTransactionData->Process(*context_);
911 }
912
ProcessSyncRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData,pid_t pid)913 void RSMainThread::ProcessSyncRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData, pid_t pid)
914 {
915 if (!rsTransactionData->IsNeedSync()) {
916 syncTransactionData_[pid].emplace_back(std::move(rsTransactionData));
917 return;
918 }
919
920 if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
921 (syncTransactionData_.begin()->second.front()->GetSyncId() > rsTransactionData->GetSyncId())) {
922 ROSEN_LOGD("RSMainThread ProcessSyncRSTransactionData while syncId less GetCommandCount: %{public}lu"
923 "pid: %{public}d", rsTransactionData->GetCommandCount(), rsTransactionData->GetSendingPid());
924 ProcessRSTransactionData(rsTransactionData, pid);
925 return;
926 }
927
928 bool isNeedCloseSync = rsTransactionData->IsNeedCloseSync();
929 if (syncTransactionData_.empty()) {
930 if (handler_) {
931 auto task = [this, syncId = rsTransactionData->GetSyncId()]() {
932 if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
933 syncTransactionData_.begin()->second.front()->GetSyncId() != syncId) {
934 return;
935 }
936 ROSEN_LOGD("RSMainThread ProcessAllSyncTransactionData timeout task");
937 ProcessAllSyncTransactionData();
938 };
939 handler_->PostTask(task, "ProcessAllSyncTransactionsTimeoutTask",
940 RSSystemProperties::GetSyncTransactionWaitDelay());
941 }
942 }
943 if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
944 (syncTransactionData_.begin()->second.front()->GetSyncId() != rsTransactionData->GetSyncId())) {
945 ProcessAllSyncTransactionData();
946 }
947 if (syncTransactionData_.count(pid) == 0) {
948 syncTransactionData_.insert({ pid, std::vector<std::unique_ptr<RSTransactionData>>() });
949 }
950 if (isNeedCloseSync) {
951 syncTransactionCount_ += rsTransactionData->GetSyncTransactionNum();
952 } else {
953 syncTransactionCount_ -= 1;
954 }
955 syncTransactionData_[pid].emplace_back(std::move(rsTransactionData));
956 if (syncTransactionCount_ == 0) {
957 ProcessAllSyncTransactionData();
958 }
959 }
960
ProcessAllSyncTransactionData()961 void RSMainThread::ProcessAllSyncTransactionData()
962 {
963 for (auto& [pid, transactions] : syncTransactionData_) {
964 for (auto& transaction: transactions) {
965 ROSEN_LOGD("RSMainThread ProcessAllSyncTransactionData GetCommandCount: %{public}lu pid: %{public}d",
966 transaction->GetCommandCount(), pid);
967 ProcessRSTransactionData(transaction, pid);
968 }
969 }
970 syncTransactionData_.clear();
971 syncTransactionCount_ = 0;
972 RequestNextVSync();
973 }
974
ConsumeAndUpdateAllNodes()975 void RSMainThread::ConsumeAndUpdateAllNodes()
976 {
977 if (isUniRender_) {
978 ResetHardwareEnabledState();
979 }
980 RS_OPTIONAL_TRACE_BEGIN("RSMainThread::ConsumeAndUpdateAllNodes");
981 bool needRequestNextVsync = false;
982 bufferTimestamps_.clear();
983 const auto& nodeMap = GetContext().GetNodeMap();
984 nodeMap.TraverseSurfaceNodes(
985 [this, &needRequestNextVsync](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
986 if (surfaceNode == nullptr) {
987 return;
988 }
989 surfaceNode->ResetAnimateState();
990 // Reset BasicGeoTrans info at the beginning of cmd process
991 if (surfaceNode->IsMainWindowType() || surfaceNode->IsLeashWindow()) {
992 surfaceNode->ResetIsOnlyBasicGeoTransform();
993 }
994 if (surfaceNode->IsHardwareEnabledType()
995 && CheckSubThreadNodeStatusIsDoing(surfaceNode->GetInstanceRootNodeId())) {
996 RS_LOGD("SubThread is processing %{public}s, skip acquire buffer", surfaceNode->GetName().c_str());
997 return;
998 }
999 auto& surfaceHandler = static_cast<RSSurfaceHandler&>(*surfaceNode);
1000 surfaceHandler.ResetCurrentFrameBufferConsumed();
1001 if (RSBaseRenderUtil::ConsumeAndUpdateBuffer(surfaceHandler)) {
1002 this->bufferTimestamps_[surfaceNode->GetId()] = static_cast<uint64_t>(surfaceNode->GetTimestamp());
1003 if (surfaceNode->IsCurrentFrameBufferConsumed() && !surfaceNode->IsHardwareEnabledType()) {
1004 surfaceNode->SetContentDirty();
1005 doDirectComposition_ = false;
1006 }
1007 if (deviceType_ == DeviceType::PC && isUiFirstOn_ && surfaceNode->IsCurrentFrameBufferConsumed()
1008 && surfaceNode->IsHardwareEnabledType() && surfaceNode->IsHardwareForcedDisabledByFilter()) {
1009 RS_OPTIONAL_TRACE_NAME(surfaceNode->GetName() +
1010 " SetContentDirty for UIFirst assigning to subthread");
1011 surfaceNode->SetContentDirty();
1012 doDirectComposition_ = false;
1013 }
1014 }
1015
1016 // still have buffer(s) to consume.
1017 if (surfaceHandler.GetAvailableBufferCount() > 0) {
1018 needRequestNextVsync = true;
1019 }
1020 });
1021
1022 if (needRequestNextVsync) {
1023 RequestNextVSync();
1024 }
1025 RS_OPTIONAL_TRACE_END();
1026 }
1027
CheckSubThreadNodeStatusIsDoing(NodeId appNodeId) const1028 bool RSMainThread::CheckSubThreadNodeStatusIsDoing(NodeId appNodeId) const
1029 {
1030 for (auto& node : subThreadNodes_) {
1031 if (node->GetCacheSurfaceProcessedStatus() != CacheProcessStatus::DOING) {
1032 continue;
1033 }
1034 if (node->GetId() == appNodeId) {
1035 return true;
1036 }
1037 for (auto& child : *node->GetSortedChildren()) {
1038 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1039 if (surfaceNode && surfaceNode->GetId() == appNodeId) {
1040 return true;
1041 }
1042 }
1043 }
1044 return false;
1045 }
1046
CollectInfoForHardwareComposer()1047 void RSMainThread::CollectInfoForHardwareComposer()
1048 {
1049 if (!isUniRender_) {
1050 return;
1051 }
1052 CheckIfHardwareForcedDisabled();
1053 const auto& nodeMap = GetContext().GetNodeMap();
1054 nodeMap.TraverseSurfaceNodes(
1055 [this, &nodeMap](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
1056 if (surfaceNode == nullptr || !surfaceNode->IsOnTheTree()) {
1057 return;
1058 }
1059 if (surfaceNode->IsLeashWindow() && surfaceNode->GetForceUIFirstChanged()) {
1060 forceUIFirstChanged_ = true;
1061 surfaceNode->SetForceUIFirstChanged(false);
1062 }
1063 if (surfaceNode->GetBuffer() != nullptr) {
1064 selfDrawingNodes_.emplace_back(surfaceNode);
1065 }
1066 if (!surfaceNode->IsHardwareEnabledType()) {
1067 return;
1068 }
1069
1070 if (surfaceNode->GetName().find("RosenWeb") != std::string::npos) {
1071 RS_TRACE_NAME_FMT("find RosenWeb");
1072 rsCurrRange_ = {OLED_120_HZ, OLED_120_HZ, OLED_120_HZ};
1073 }
1074
1075 // if hwc node is set on the tree this frame, mark its parent app node to be prepared
1076 auto appNodeId = surfaceNode->GetInstanceRootNodeId();
1077 if (surfaceNode->IsNewOnTree()) {
1078 context_->AddActiveNode(nodeMap.GetRenderNode(appNodeId));
1079 }
1080
1081 if (surfaceNode->GetBuffer() != nullptr) {
1082 // collect hwc nodes vector, used for display node skip and direct composition cases
1083 hardwareEnabledNodes_.emplace_back(surfaceNode);
1084 }
1085
1086 // set content dirty for hwc node if needed
1087 if (isHardwareForcedDisabled_) {
1088 // buffer updated or hwc -> gpu
1089 if (surfaceNode->IsCurrentFrameBufferConsumed() || surfaceNode->IsLastFrameHardwareEnabled()) {
1090 surfaceNode->SetContentDirty();
1091 }
1092 } else if (!surfaceNode->IsLastFrameHardwareEnabled()) { // gpu -> hwc
1093 if (!IsLastFrameUIFirstEnabled(appNodeId)) {
1094 if (surfaceNode->IsCurrentFrameBufferConsumed()) {
1095 surfaceNode->SetContentDirty();
1096 doDirectComposition_ = false;
1097 } else {
1098 surfaceNode->SetHwcDelayDirtyFlag(true);
1099 }
1100 } else {
1101 doDirectComposition_ = false;
1102 }
1103 } else { // hwc -> hwc
1104 // self-drawing node don't set content dirty when gpu -> hwc
1105 // so first frame in hwc -> hwc, should set content dirty
1106 if (surfaceNode->GetHwcDelayDirtyFlag()) {
1107 surfaceNode->SetContentDirty();
1108 surfaceNode->SetHwcDelayDirtyFlag(false);
1109 doDirectComposition_ = false;
1110 }
1111 }
1112
1113 if (surfaceNode->IsCurrentFrameBufferConsumed()) {
1114 isHardwareEnabledBufferUpdated_ = true;
1115 }
1116 });
1117 }
1118
IsLastFrameUIFirstEnabled(NodeId appNodeId) const1119 bool RSMainThread::IsLastFrameUIFirstEnabled(NodeId appNodeId) const
1120 {
1121 for (auto& node : subThreadNodes_) {
1122 if (node->IsAppWindow()) {
1123 if (node->GetId() == appNodeId) {
1124 return true;
1125 }
1126 } else {
1127 for (auto& child : *node->GetSortedChildren()) {
1128 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1129 if (surfaceNode && surfaceNode->IsAppWindow() && surfaceNode->GetId() == appNodeId) {
1130 return true;
1131 }
1132 }
1133 }
1134 }
1135 return false;
1136 }
1137
CheckIfHardwareForcedDisabled()1138 void RSMainThread::CheckIfHardwareForcedDisabled()
1139 {
1140 ColorFilterMode colorFilterMode = renderEngine_->GetColorFilterMode();
1141 bool hasColorFilter = colorFilterMode >= ColorFilterMode::INVERT_COLOR_ENABLE_MODE &&
1142 colorFilterMode <= ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE;
1143 std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
1144 bool isMultiDisplay = rootNode && rootNode->GetChildrenCount() > 1;
1145
1146 // [PLANNING] GetChildrenCount > 1 indicates multi display, only Mirror Mode need be marked here
1147 // Mirror Mode reuses display node's buffer, so mark it and disable hardware composer in this case
1148 isHardwareForcedDisabled_ = isHardwareForcedDisabled_ || doWindowAnimate_ || isMultiDisplay || hasColorFilter;
1149 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: CheckIfHardwareForcedDisabled isHardwareForcedDisabled_:%d "
1150 "doWindowAnimate_:%d isMultiDisplay:%d hasColorFilter:%d",
1151 isHardwareForcedDisabled_, doWindowAnimate_.load(), isMultiDisplay, hasColorFilter);
1152 }
1153
CollectInfoForDrivenRender()1154 void RSMainThread::CollectInfoForDrivenRender()
1155 {
1156 #if defined(RS_ENABLE_DRIVEN_RENDER)
1157 hasDrivenNodeOnUniTree_ = false;
1158 hasDrivenNodeMarkRender_ = false;
1159 if (!isUniRender_ || !RSSystemProperties::GetHardwareComposerEnabled() ||
1160 !RSDrivenRenderManager::GetInstance().GetDrivenRenderEnabled()) {
1161 return;
1162 }
1163
1164 std::vector<std::shared_ptr<RSRenderNode>> drivenNodes;
1165 std::vector<std::shared_ptr<RSRenderNode>> markRenderDrivenNodes;
1166
1167 const auto& nodeMap = GetContext().GetNodeMap();
1168 nodeMap.TraverseDrivenRenderNodes(
1169 [&](const std::shared_ptr<RSRenderNode>& node) mutable {
1170 if (node == nullptr || !node->IsOnTheTree()) {
1171 return;
1172 }
1173 drivenNodes.emplace_back(node);
1174 if (node->GetPaintState()) {
1175 markRenderDrivenNodes.emplace_back(node);
1176 }
1177 });
1178
1179 for (auto& node : drivenNodes) {
1180 node->SetPaintState(false);
1181 node->SetIsMarkDrivenRender(false);
1182 }
1183 if (!drivenNodes.empty()) {
1184 hasDrivenNodeOnUniTree_ = true;
1185 } else {
1186 hasDrivenNodeOnUniTree_ = false;
1187 }
1188 if (markRenderDrivenNodes.size() == 1) { // only support 1 driven node
1189 auto node = markRenderDrivenNodes.front();
1190 node->SetIsMarkDrivenRender(true);
1191 hasDrivenNodeMarkRender_ = true;
1192 } else {
1193 hasDrivenNodeMarkRender_ = false;
1194 }
1195 #endif
1196 }
1197
ReleaseAllNodesBuffer()1198 void RSMainThread::ReleaseAllNodesBuffer()
1199 {
1200 RS_OPTIONAL_TRACE_BEGIN("RSMainThread::ReleaseAllNodesBuffer");
1201 const auto& nodeMap = GetContext().GetNodeMap();
1202 nodeMap.TraverseSurfaceNodes([this](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
1203 if (surfaceNode == nullptr) {
1204 return;
1205 }
1206 // surfaceNode's buffer will be released in hardware thread if last frame enables hardware composer
1207 if (surfaceNode->IsHardwareEnabledType()) {
1208 if (surfaceNode->IsLastFrameHardwareEnabled()) {
1209 if (!surfaceNode->IsCurrentFrameHardwareEnabled()) {
1210 auto& surfaceHandler = static_cast<RSSurfaceHandler&>(*surfaceNode);
1211 auto& preBuffer = surfaceHandler.GetPreBuffer();
1212 if (preBuffer.buffer != nullptr) {
1213 auto releaseTask = [buffer = preBuffer.buffer, consumer = surfaceHandler.GetConsumer(),
1214 fence = preBuffer.releaseFence]() mutable {
1215 auto ret = consumer->ReleaseBuffer(buffer, fence);
1216 if (ret != OHOS::SURFACE_ERROR_OK) {
1217 RS_LOGD("surfaceHandler ReleaseBuffer failed(ret: %{public}d)!", ret);
1218 }
1219 };
1220 preBuffer.Reset();
1221 RSHardwareThread::Instance().PostTask(releaseTask);
1222 }
1223 }
1224 surfaceNode->ResetCurrentFrameHardwareEnabledState();
1225 return;
1226 }
1227 surfaceNode->ResetCurrentFrameHardwareEnabledState();
1228 }
1229 RSBaseRenderUtil::ReleaseBuffer(static_cast<RSSurfaceHandler&>(*surfaceNode));
1230 });
1231 RS_OPTIONAL_TRACE_END();
1232 }
1233
GetRefreshRate() const1234 uint32_t RSMainThread::GetRefreshRate() const
1235 {
1236 auto screenManager = CreateOrGetScreenManager();
1237 if (!screenManager) {
1238 RS_LOGE("RSMainThread::GetRefreshRate screenManager is nullptr");
1239 return 60; // The default refreshrate is 60
1240 }
1241 return OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(screenManager->GetDefaultScreenId());
1242 }
1243
ClearMemoryCache(ClearMemoryMoment moment,bool deeply)1244 void RSMainThread::ClearMemoryCache(ClearMemoryMoment moment, bool deeply)
1245 {
1246 if (!RSSystemProperties::GetReleaseResourceEnabled()) {
1247 return;
1248 }
1249 this->clearMemoryFinished_ = false;
1250 this->clearMemDeeply_ = this->clearMemDeeply_ || deeply;
1251 this->SetClearMoment(moment);
1252 PostTask(
1253 [this, moment, deeply]() {
1254 #ifndef USE_ROSEN_DRAWING
1255 #ifdef NEW_RENDER_CONTEXT
1256 auto grContext = GetRenderEngine()->GetDrawingContext()->GetDrawingContext();
1257 #else
1258 auto grContext = GetRenderEngine()->GetRenderContext()->GetGrContext();
1259 #endif
1260 if (!grContext) {
1261 return;
1262 }
1263 RS_LOGD("Clear memory cache %{public}d", this->GetClearMoment());
1264 RS_TRACE_NAME_FMT("Clear memory cache, cause the moment [%d] happen", this->GetClearMoment());
1265 SKResourceManager::Instance().ReleaseResource();
1266 grContext->flush();
1267 SkGraphics::PurgeAllCaches(); // clear cpu cache
1268 if (deeply || this->deviceType_ != DeviceType::PHONE) {
1269 MemoryManager::ReleaseUnlockAndSafeCacheGpuResource(grContext);
1270 } else {
1271 MemoryManager::ReleaseUnlockGpuResource(grContext);
1272 }
1273 grContext->flushAndSubmit(true);
1274 #else
1275 auto grContext = GetRenderEngine()->GetRenderContext()->GetDrGPUContext();
1276 if (!grContext) {
1277 return;
1278 }
1279 RS_LOGD("Clear memory cache %{public}d", this->GetClearMoment());
1280 RS_TRACE_NAME_FMT("Clear memory cache, cause the moment [%d] happen", this->GetClearMoment());
1281 SKResourceManager::Instance().ReleaseResource();
1282 grContext->Flush();
1283 SkGraphics::PurgeAllCaches(); // clear cpu cache
1284 if (deeply || this->deviceType_ != DeviceType::PHONE) {
1285 MemoryManager::ReleaseUnlockAndSafeCacheGpuResource(grContext);
1286 } else {
1287 MemoryManager::ReleaseUnlockGpuResource(grContext);
1288 }
1289 grContext->FlushAndSubmit(true);
1290 #endif
1291 this->clearMemoryFinished_ = true;
1292 this->clearMemDeeply_ = false;
1293 this->SetClearMoment(ClearMemoryMoment::NO_CLEAR);
1294 },
1295 CLEAR_GPU_CACHE, (this->deviceType_ == DeviceType::PHONE ? TIME_OF_EIGHT_FRAMES : TIME_OF_THE_FRAMES)
1296 / GetRefreshRate());
1297 }
1298
WaitUtilUniRenderFinished()1299 void RSMainThread::WaitUtilUniRenderFinished()
1300 {
1301 std::unique_lock<std::mutex> lock(uniRenderMutex_);
1302 if (uniRenderFinished_) {
1303 return;
1304 }
1305 RS_TRACE_NAME("RSMainThread::WaitUtilUniRenderFinished");
1306 uniRenderCond_.wait(lock, [this]() { return uniRenderFinished_; });
1307 uniRenderFinished_ = false;
1308 }
1309
WaitUntilDisplayNodeBufferReleased(RSDisplayRenderNode & node)1310 bool RSMainThread::WaitUntilDisplayNodeBufferReleased(RSDisplayRenderNode& node)
1311 {
1312 std::unique_lock<std::mutex> lock(displayNodeBufferReleasedMutex_);
1313 displayNodeBufferReleased_ = false; // prevent spurious wakeup of condition variable
1314 if (node.GetConsumer()->QueryIfBufferAvailable()) {
1315 return true;
1316 }
1317 return displayNodeBufferReleasedCond_.wait_until(lock, std::chrono::system_clock::now() +
1318 std::chrono::milliseconds(WAIT_FOR_RELEASED_BUFFER_TIMEOUT), [this]() { return displayNodeBufferReleased_; });
1319 }
1320
WaitUtilDrivenRenderFinished()1321 void RSMainThread::WaitUtilDrivenRenderFinished()
1322 {
1323 #if defined(RS_ENABLE_DRIVEN_RENDER)
1324 std::unique_lock<std::mutex> lock(drivenRenderMutex_);
1325 if (drivenRenderFinished_) {
1326 return;
1327 }
1328 drivenRenderCond_.wait(lock, [this]() { return drivenRenderFinished_; });
1329 drivenRenderFinished_ = false;
1330 #endif
1331 }
1332
WaitUntilUnmarshallingTaskFinished()1333 void RSMainThread::WaitUntilUnmarshallingTaskFinished()
1334 {
1335 if (!isUniRender_) {
1336 return;
1337 }
1338 RS_OPTIONAL_TRACE_BEGIN("RSMainThread::WaitUntilUnmarshallingTaskFinished");
1339 std::unique_lock<std::mutex> lock(unmarshalMutex_);
1340 unmarshalTaskCond_.wait(lock, [this]() { return unmarshalFinishedCount_ > 0; });
1341 --unmarshalFinishedCount_;
1342 RS_OPTIONAL_TRACE_END();
1343 }
1344
MergeToEffectiveTransactionDataMap(TransactionDataMap & cachedTransactionDataMap)1345 void RSMainThread::MergeToEffectiveTransactionDataMap(TransactionDataMap& cachedTransactionDataMap)
1346 {
1347 std::lock_guard<std::mutex> lock(transitionDataMutex_);
1348 for (auto& elem : cachedTransactionDataMap) {
1349 auto pid = elem.first;
1350 if (effectiveTransactionDataIndexMap_.count(pid) == 0) {
1351 RS_LOGE("RSMainThread::MergeToEffectiveTransactionDataMap pid:%{public}d not valid, skip it", pid);
1352 continue;
1353 }
1354 InsertToEnd(elem.second, effectiveTransactionDataIndexMap_[pid].second);
1355 }
1356 cachedTransactionDataMap.clear();
1357 }
1358
NotifyUniRenderFinish()1359 void RSMainThread::NotifyUniRenderFinish()
1360 {
1361 if (std::this_thread::get_id() != Id()) {
1362 std::lock_guard<std::mutex> lock(uniRenderMutex_);
1363 uniRenderFinished_ = true;
1364 uniRenderCond_.notify_one();
1365 } else {
1366 uniRenderFinished_ = true;
1367 }
1368 }
1369
NotifyDisplayNodeBufferReleased()1370 void RSMainThread::NotifyDisplayNodeBufferReleased()
1371 {
1372 RS_TRACE_NAME("RSMainThread::NotifyDisplayNodeBufferReleased");
1373 std::lock_guard<std::mutex> lock(displayNodeBufferReleasedMutex_);
1374 displayNodeBufferReleased_ = true;
1375 displayNodeBufferReleasedCond_.notify_one();
1376 }
1377
NotifySurfaceCapProcFinish()1378 void RSMainThread::NotifySurfaceCapProcFinish()
1379 {
1380 RS_TRACE_NAME("RSMainThread::NotifySurfaceCapProcFinish");
1381 std::lock_guard<std::mutex> lock(surfaceCapProcMutex_);
1382 surfaceCapProcFinished_ = true;
1383 surfaceCapProcTaskCond_.notify_one();
1384 }
1385
WaitUntilSurfaceCapProcFinished()1386 void RSMainThread::WaitUntilSurfaceCapProcFinished()
1387 {
1388 if (GetDeviceType() != DeviceType::PHONE) {
1389 return;
1390 }
1391 std::unique_lock<std::mutex> lock(surfaceCapProcMutex_);
1392 if (surfaceCapProcFinished_) {
1393 return;
1394 }
1395 RS_OPTIONAL_TRACE_BEGIN("RSMainThread::WaitUntilSurfaceCapProcFinished");
1396 surfaceCapProcTaskCond_.wait_until(lock, std::chrono::system_clock::now() +
1397 std::chrono::milliseconds(WAIT_FOR_SURFACE_CAPTURE_PROCESS_TIMEOUT),
1398 [this]() { return surfaceCapProcFinished_; });
1399 RS_OPTIONAL_TRACE_END();
1400 }
1401
SetSurfaceCapProcFinished(bool flag)1402 void RSMainThread::SetSurfaceCapProcFinished(bool flag)
1403 {
1404 std::lock_guard<std::mutex> lock(surfaceCapProcMutex_);
1405 surfaceCapProcFinished_ = flag;
1406 }
1407
NotifyDrivenRenderFinish()1408 void RSMainThread::NotifyDrivenRenderFinish()
1409 {
1410 #if defined(RS_ENABLE_DRIVEN_RENDER)
1411 if (std::this_thread::get_id() != Id()) {
1412 std::lock_guard<std::mutex> lock(drivenRenderMutex_);
1413 drivenRenderFinished_ = true;
1414 drivenRenderCond_.notify_one();
1415 } else {
1416 drivenRenderFinished_ = true;
1417 }
1418 #endif
1419 }
1420
ProcessHgmFrameRate(uint64_t timestamp)1421 void RSMainThread::ProcessHgmFrameRate(uint64_t timestamp)
1422 {
1423 RS_TRACE_FUNC();
1424 if (rsFrameRateLinker_ != nullptr) {
1425 rsFrameRateLinker_->SetExpectedRange(rsCurrRange_);
1426 RS_TRACE_NAME_FMT("rsCurrRange = (%d, %d, %d)", rsCurrRange_.min_, rsCurrRange_.max_, rsCurrRange_.preferred_);
1427 }
1428 // Check and processing refresh rate task.
1429 auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
1430 hgmCore.SetTimestamp(timestamp);
1431 auto pendingRefreshRate = frameRateMgr_->GetPendingRefreshRate();
1432 if (pendingRefreshRate != nullptr) {
1433 hgmCore.SetPendingScreenRefreshRate(*pendingRefreshRate);
1434 frameRateMgr_->ResetPendingRefreshRate();
1435 RS_TRACE_NAME_FMT("RSMainThread::ProcessHgmFrameRate pendingRefreshRate: %d", *pendingRefreshRate);
1436 }
1437
1438 // hgm warning: use IsLtpo instead after GetDisplaySupportedModes ready
1439 if (frameRateMgr_->GetCurScreenStrategyId().find("LTPO") == std::string::npos) {
1440 frameRateMgr_->UniProcessDataForLtps(idleTimerExpiredFlag_);
1441 } else {
1442 auto appFrameLinkers = GetContext().GetFrameRateLinkerMap().Get();
1443 frameRateMgr_->UniProcessDataForLtpo(timestamp, rsFrameRateLinker_, appFrameLinkers, idleTimerExpiredFlag_);
1444 }
1445 }
1446
GetParallelCompositionEnabled()1447 bool RSMainThread::GetParallelCompositionEnabled()
1448 {
1449 return doParallelComposition_;
1450 }
1451
ColorPickerRequestVsyncIfNeed()1452 void RSMainThread::ColorPickerRequestVsyncIfNeed()
1453 {
1454 if (colorPickerForceRequestVsync_) {
1455 colorPickerRequestFrameNum_--;
1456 if (colorPickerRequestFrameNum_ > 0) {
1457 RSMainThread::Instance()->SetNoNeedToPostTask(false);
1458 RSMainThread::Instance()->SetDirtyFlag();
1459 RequestNextVSync();
1460 } else {
1461 // The last frame reset to 15, then to request next 15 frames if need
1462 colorPickerRequestFrameNum_ = 15;
1463 RSMainThread::Instance()->SetNoNeedToPostTask(true);
1464 colorPickerForceRequestVsync_ = false;
1465 }
1466 } else {
1467 RSMainThread::Instance()->SetNoNeedToPostTask(false);
1468 }
1469 }
1470
WaitUntilUploadTextureTaskFinishedForGL()1471 void RSMainThread::WaitUntilUploadTextureTaskFinishedForGL()
1472 {
1473 if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
1474 WaitUntilUploadTextureTaskFinished(isUniRender_);
1475 }
1476 }
1477
UniRender(std::shared_ptr<RSBaseRenderNode> rootNode)1478 void RSMainThread::UniRender(std::shared_ptr<RSBaseRenderNode> rootNode)
1479 {
1480 if (isAccessibilityConfigChanged_) {
1481 RSUniRenderVisitor::ClearRenderGroupCache();
1482 }
1483 UpdateUIFirstSwitch();
1484 UpdateRogSizeIfNeeded();
1485 auto uniVisitor = std::make_shared<RSUniRenderVisitor>();
1486 #if defined(RS_ENABLE_DRIVEN_RENDER)
1487 uniVisitor->SetDrivenRenderFlag(hasDrivenNodeOnUniTree_, hasDrivenNodeMarkRender_);
1488 #endif
1489 uniVisitor->SetHardwareEnabledNodes(hardwareEnabledNodes_);
1490 uniVisitor->SetAppWindowNum(appWindowNum_);
1491 uniVisitor->SetProcessorRenderEngine(GetRenderEngine());
1492 uniVisitor->SetForceUpdateFlag(forceUpdateUniRenderFlag_);
1493
1494 if (isHardwareForcedDisabled_) {
1495 uniVisitor->MarkHardwareForcedDisabled();
1496 doDirectComposition_ = false;
1497 }
1498 bool needTraverseNodeTree = true;
1499 if (doDirectComposition_ && !isDirty_ && !isAccessibilityConfigChanged_
1500 && !isCachedSurfaceUpdated_) {
1501 if (isHardwareEnabledBufferUpdated_) {
1502 needTraverseNodeTree = !uniVisitor->DoDirectComposition(rootNode);
1503 } else if (forceUpdateUniRenderFlag_) {
1504 RS_TRACE_NAME("RSMainThread::UniRender ForceUpdateUniRender");
1505 } else if (colorPickerForceRequestVsync_) {
1506 RS_TRACE_NAME("RSMainThread::UniRender ColorPickerForceRequestVsync");
1507 RSMainThread::Instance()->SetNoNeedToPostTask(false);
1508 RSMainThread::Instance()->SetDirtyFlag();
1509 RequestNextVSync();
1510 return;
1511 } else {
1512 RS_LOGD("RSMainThread::Render nothing to update");
1513 for (auto& node: hardwareEnabledNodes_) {
1514 if (!node->IsHardwareForcedDisabled()) {
1515 node->MarkCurrentFrameHardwareEnabled();
1516 }
1517 }
1518 WaitUntilUploadTextureTaskFinishedForGL();
1519 return;
1520 }
1521 }
1522
1523 ColorPickerRequestVsyncIfNeed();
1524
1525 isCachedSurfaceUpdated_ = false;
1526 if (needTraverseNodeTree) {
1527 uniVisitor->SetAnimateState(doWindowAnimate_);
1528 uniVisitor->SetDirtyFlag(isDirty_ || isAccessibilityConfigChanged_ || forceUIFirstChanged_);
1529 forceUIFirstChanged_ = false;
1530 isAccessibilityConfigChanged_ = false;
1531 SetFocusLeashWindowId();
1532 uniVisitor->SetFocusedNodeId(focusNodeId_, focusLeashWindowId_);
1533 rootNode->Prepare(uniVisitor);
1534 RSPointLightManager::Instance()->PrepareLight();
1535 vsyncControlEnabled_ = (deviceType_ == DeviceType::PC) && RSSystemParameters::GetVSyncControlEnabled();
1536 systemAnimatedScenesEnabled_ = RSSystemParameters::GetSystemAnimatedScenesEnabled();
1537 CalcOcclusion();
1538 doParallelComposition_ = RSInnovation::GetParallelCompositionEnabled(isUniRender_) &&
1539 rootNode->GetChildrenCount() > 1;
1540 if (doParallelComposition_) {
1541 RS_LOGD("RSMainThread::Render multi-threads parallel composition begin.");
1542 if (uniVisitor->ParallelComposition(rootNode)) {
1543 RS_LOGD("RSMainThread::Render multi-threads parallel composition end.");
1544 isDirty_ = false;
1545 if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
1546 WaitUntilUploadTextureTaskFinished(isUniRender_);
1547 }
1548 return;
1549 }
1550 }
1551 if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
1552 WaitUntilUploadTextureTaskFinished(isUniRender_);
1553 }
1554 if (IsUIFirstOn()) {
1555 auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(
1556 rootNode->GetFirstChild());
1557 std::list<std::shared_ptr<RSSurfaceRenderNode>> mainThreadNodes;
1558 std::list<std::shared_ptr<RSSurfaceRenderNode>> subThreadNodes;
1559 RSUniRenderUtil::AssignWindowNodes(displayNode, mainThreadNodes, subThreadNodes);
1560 const auto& nodeMap = context_->GetNodeMap();
1561 RSUniRenderUtil::ClearSurfaceIfNeed(nodeMap, displayNode, oldDisplayChildren_, deviceType_);
1562 uniVisitor->DrawSurfaceLayer(displayNode, subThreadNodes);
1563 RSUniRenderUtil::CacheSubThreadNodes(subThreadNodes_, subThreadNodes);
1564 }
1565 rootNode->Process(uniVisitor);
1566 } else if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
1567 WaitUntilUploadTextureTaskFinished(isUniRender_);
1568 }
1569 isDirty_ = false;
1570 forceUpdateUniRenderFlag_ = false;
1571 idleTimerExpiredFlag_ = false;
1572 }
1573
GetDesktopPidForRotationScene() const1574 pid_t RSMainThread::GetDesktopPidForRotationScene() const
1575 {
1576 return desktopPidForRotationScene_;
1577 }
1578
Render()1579 void RSMainThread::Render()
1580 {
1581 const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
1582 if (rootNode == nullptr) {
1583 if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
1584 WaitUntilUploadTextureTaskFinished(isUniRender_);
1585 }
1586 RS_LOGE("RSMainThread::Render GetGlobalRootRenderNode fail");
1587 return;
1588 }
1589 if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
1590 RSPropertyTrace::GetInstance().RefreshNodeTraceInfo();
1591 }
1592 if (focusAppBundleName_.find(DESKTOP_NAME_FOR_ROTATION) != std::string::npos) {
1593 desktopPidForRotationScene_ = focusAppPid_;
1594 }
1595 if (RSSystemProperties::GetDumpRSTreeCount()) {
1596 std::string rsTreeStr;
1597 RenderServiceTreeDump(rsTreeStr);
1598 RS_TRACE_NAME("WriteDumpTree");
1599 std::string dumpFilePath = "/data/RSTree";
1600 if (access(dumpFilePath.c_str(), F_OK) != 0) {
1601 constexpr int directoryPermission = 0755; // drwxr-xr-x
1602 mkdir(dumpFilePath.c_str(), directoryPermission);
1603 }
1604 dumpFilePath += "/rsTree_" + std::to_string(frameCount_) + ".txt";
1605 OHOS::Rosen::Benchmarks::WriteStringToFile(rsTreeStr, dumpFilePath);
1606 RSSystemProperties::SetDumpRSTreeCount(RSSystemProperties::GetDumpRSTreeCount() - 1);
1607 }
1608 if (isUniRender_) {
1609 UniRender(rootNode);
1610 } else {
1611 auto rsVisitor = std::make_shared<RSRenderServiceVisitor>();
1612 rsVisitor->SetAnimateState(doWindowAnimate_);
1613 rootNode->Prepare(rsVisitor);
1614 CalcOcclusion();
1615 bool doParallelComposition = false;
1616 if (!rsVisitor->ShouldForceSerial() && RSInnovation::GetParallelCompositionEnabled(isUniRender_)) {
1617 doParallelComposition = DoParallelComposition(rootNode);
1618 }
1619 if (doParallelComposition) {
1620 renderEngine_->ShrinkCachesIfNeeded();
1621 return;
1622 }
1623 rootNode->Process(rsVisitor);
1624 renderEngine_->ShrinkCachesIfNeeded();
1625 }
1626 CallbackDrawContextStatusToWMS();
1627 CheckSystemSceneStatus();
1628 PerfForBlurIfNeeded();
1629 }
1630
CheckSystemSceneStatus()1631 void RSMainThread::CheckSystemSceneStatus()
1632 {
1633 std::lock_guard<std::mutex> lock(systemAnimatedScenesMutex_);
1634 uint64_t curTime = static_cast<uint64_t>(
1635 std::chrono::duration_cast<std::chrono::nanoseconds>(
1636 std::chrono::steady_clock::now().time_since_epoch()).count());
1637 while (!systemAnimatedScenesList_.empty()) {
1638 if (curTime - systemAnimatedScenesList_.front().second > MAX_SYSTEM_SCENE_STATUS_TIME) {
1639 systemAnimatedScenesList_.pop_front();
1640 } else {
1641 break;
1642 }
1643 }
1644 while (!threeFingerScenesList_.empty()) {
1645 if (curTime - threeFingerScenesList_.front().second > MAX_SYSTEM_SCENE_STATUS_TIME) {
1646 threeFingerScenesList_.pop_front();
1647 } else {
1648 break;
1649 }
1650 }
1651 }
1652
CallbackDrawContextStatusToWMS()1653 void RSMainThread::CallbackDrawContextStatusToWMS()
1654 {
1655 VisibleData drawStatusVec;
1656 for (auto dynamicNodeId : curDrawStatusVec_) {
1657 if (lastDrawStatusMap_.find(dynamicNodeId) == lastDrawStatusMap_.end()) {
1658 drawStatusVec.emplace_back(std::make_pair(dynamicNodeId,
1659 WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_DYNAMIC_STATUS));
1660 RS_OPTIONAL_TRACE_NAME_FMT("%s nodeId[%" PRIu64 "] status[%d]",
1661 __func__, dynamicNodeId, WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_DYNAMIC_STATUS);
1662 }
1663 lastDrawStatusMap_[dynamicNodeId] = timestamp_;
1664 }
1665 auto drawStatusIter = lastDrawStatusMap_.begin();
1666 while (drawStatusIter != lastDrawStatusMap_.end()) {
1667 if (timestamp_ - drawStatusIter->second > MAX_DYNAMIC_STATUS_TIME) {
1668 drawStatusVec.emplace_back(std::make_pair(drawStatusIter->first,
1669 WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_STATIC_STATUS));
1670 RS_OPTIONAL_TRACE_NAME_FMT("%s nodeId[%" PRIu64 "] status[%d]",
1671 __func__, drawStatusIter->first, WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_STATIC_STATUS);
1672 auto tmpIter = drawStatusIter++;
1673 lastDrawStatusMap_.erase(tmpIter);
1674 } else {
1675 drawStatusIter++;
1676 }
1677 }
1678 curDrawStatusVec_.clear();
1679 if (!drawStatusVec.empty()) {
1680 std::lock_guard<std::mutex> lock(occlusionMutex_);
1681 for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
1682 if (it->second) {
1683 it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(drawStatusVec));
1684 }
1685 }
1686 }
1687 }
1688
CheckSurfaceNeedProcess(OcclusionRectISet & occlusionSurfaces,std::shared_ptr<RSSurfaceRenderNode> curSurface)1689 bool RSMainThread::CheckSurfaceNeedProcess(OcclusionRectISet& occlusionSurfaces,
1690 std::shared_ptr<RSSurfaceRenderNode> curSurface)
1691 {
1692 bool needProcess = false;
1693 if (curSurface->IsFocusedNode(focusNodeId_)) {
1694 needProcess = true;
1695 if (!curSurface->HasContainerWindow() && !curSurface->IsTransparent() &&
1696 !curSurface->HasWindowCorner() &&
1697 !curSurface->GetAnimateState() && // when node animating (i.e. 3d animation), the region cannot be trusted
1698 curSurface->GetName().find("hisearch") == std::string::npos) {
1699 occlusionSurfaces.insert(curSurface->GetDstRect());
1700 }
1701 } else {
1702 size_t beforeSize = occlusionSurfaces.size();
1703 occlusionSurfaces.insert(curSurface->GetDstRect());
1704 bool insertSuccess = occlusionSurfaces.size() > beforeSize ? true : false;
1705 if (insertSuccess) {
1706 needProcess = true;
1707 if (curSurface->IsTransparent() ||
1708 curSurface->HasWindowCorner() ||
1709 curSurface->GetAnimateState() || // when node animating(i.e. 3d animation), the region cannot be trusted
1710 curSurface->GetName().find("hisearch") != std::string::npos) {
1711 auto iter = std::find_if(occlusionSurfaces.begin(), occlusionSurfaces.end(),
1712 [&curSurface](RectI r) -> bool {return r == curSurface->GetDstRect();});
1713 if (iter != occlusionSurfaces.end()) {
1714 occlusionSurfaces.erase(iter);
1715 }
1716 }
1717 }
1718 }
1719
1720 if (needProcess) {
1721 CheckIfNodeIsBundle(curSurface);
1722 }
1723 return needProcess;
1724 }
1725
GetRegionVisibleLevel(const Occlusion::Region & curRegion,const Occlusion::Region & visibleRegion)1726 RSVisibleLevel RSMainThread::GetRegionVisibleLevel(const Occlusion::Region& curRegion,
1727 const Occlusion::Region& visibleRegion)
1728 {
1729 if (visibleRegion.IsEmpty()) {
1730 return RSVisibleLevel::RS_INVISIBLE;
1731 } else if (visibleRegion.Area() == curRegion.Area()) {
1732 return RSVisibleLevel::RS_ALL_VISIBLE;
1733 } else if (static_cast<uint>(visibleRegion.Area()) <
1734 (static_cast<uint>(curRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
1735 return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
1736 }
1737 return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
1738 }
1739
CalcOcclusionImplementation(std::vector<RSBaseRenderNode::SharedPtr> & curAllSurfaces,VisibleData & dstCurVisVec,std::map<uint32_t,RSVisibleLevel> & dstPidVisMap)1740 void RSMainThread::CalcOcclusionImplementation(std::vector<RSBaseRenderNode::SharedPtr>& curAllSurfaces,
1741 VisibleData& dstCurVisVec, std::map<uint32_t, RSVisibleLevel>& dstPidVisMap)
1742 {
1743 Occlusion::Region accumulatedRegion;
1744 VisibleData curVisVec;
1745 OcclusionRectISet occlusionSurfaces;
1746 std::map<uint32_t, RSVisibleLevel> pidVisMap;
1747 bool hasFilterCacheOcclusion = false;
1748 bool filterCacheOcclusionEnabled = RSSystemParameters::GetFilterCacheOcculusionEnabled();
1749 for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
1750 auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
1751 if (curSurface == nullptr || curSurface->IsLeashWindow()) {
1752 continue;
1753 }
1754 curSurface->SetOcclusionInSpecificScenes(deviceType_ == DeviceType::PC && !threeFingerScenesList_.empty());
1755 Occlusion::Rect occlusionRect = curSurface->GetSurfaceOcclusionRect(isUniRender_);
1756 curSurface->setQosCal(vsyncControlEnabled_);
1757 if (CheckSurfaceNeedProcess(occlusionSurfaces, curSurface)) {
1758 Occlusion::Region curRegion { occlusionRect };
1759 Occlusion::Region subResult = curRegion.Sub(accumulatedRegion);
1760 RSVisibleLevel visibleLevel = GetRegionVisibleLevel(curRegion, subResult);
1761 RS_LOGD("%{public}s nodeId[%{public}" PRIu64 "] visibleLevel[%{public}d]",
1762 __func__, curSurface->GetId(), visibleLevel);
1763 curSurface->SetVisibleRegionRecursive(subResult, curVisVec, pidVisMap, true, visibleLevel,
1764 !systemAnimatedScenesList_.empty());
1765 curSurface->AccumulateOcclusionRegion(accumulatedRegion, curRegion, hasFilterCacheOcclusion, isUniRender_,
1766 filterCacheOcclusionEnabled);
1767 } else {
1768 curSurface->SetVisibleRegionRecursive({}, curVisVec, pidVisMap);
1769 RS_LOGD("%{public}s nodeId[%{public}" PRIu64 "] visibleLevel[%{public}d]",
1770 __func__, curSurface->GetId(), RSVisibleLevel::RS_INVISIBLE);
1771 }
1772 }
1773
1774 // if there are valid filter cache occlusion, recalculate surfacenode visibleregionforcallback for WMS/QOS callback
1775 if (hasFilterCacheOcclusion && isUniRender_) {
1776 curVisVec.clear();
1777 pidVisMap.clear();
1778 occlusionSurfaces.clear();
1779 accumulatedRegion = {};
1780 for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
1781 auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
1782 if (curSurface == nullptr || curSurface->IsLeashWindow()) {
1783 continue;
1784 }
1785 Occlusion::Rect occlusionRect = curSurface->GetSurfaceOcclusionRect(isUniRender_);
1786 curSurface->setQosCal(vsyncControlEnabled_);
1787 if (CheckSurfaceNeedProcess(occlusionSurfaces, curSurface)) {
1788 Occlusion::Region curRegion { occlusionRect };
1789 Occlusion::Region subResult = curRegion.Sub(accumulatedRegion);
1790 RSVisibleLevel visibleLevel = GetRegionVisibleLevel(curRegion, subResult);
1791 curSurface->SetVisibleRegionRecursive(subResult, curVisVec, pidVisMap, false, visibleLevel,
1792 !systemAnimatedScenesList_.empty());
1793 curSurface->AccumulateOcclusionRegion(accumulatedRegion, curRegion, hasFilterCacheOcclusion,
1794 isUniRender_, false);
1795 } else {
1796 curSurface->SetVisibleRegionRecursive({}, curVisVec, pidVisMap, false);
1797 }
1798 }
1799 }
1800
1801 dstCurVisVec.insert(dstCurVisVec.end(), curVisVec.begin(), curVisVec.end());
1802 dstPidVisMap.insert(pidVisMap.begin(), pidVisMap.end());
1803 }
1804
CalcOcclusion()1805 void RSMainThread::CalcOcclusion()
1806 {
1807 RS_OPTIONAL_TRACE_NAME("RSMainThread::CalcOcclusion");
1808 RS_LOGD("RSMainThread::CalcOcclusion animate:%{public}d isUniRender:%{public}d",
1809 doWindowAnimate_.load(), isUniRender_);
1810 if (doWindowAnimate_ && !isUniRender_) {
1811 return;
1812 }
1813 const std::shared_ptr<RSBaseRenderNode> node = context_->GetGlobalRootRenderNode();
1814 if (node == nullptr) {
1815 RS_LOGE("RSMainThread::CalcOcclusion GetGlobalRootRenderNode fail");
1816 return;
1817 }
1818 std::map<NodeId, std::vector<RSBaseRenderNode::SharedPtr>> curAllSurfacesInDisplay;
1819 std::vector<RSBaseRenderNode::SharedPtr> curAllSurfaces;
1820 for (const auto& child : *node->GetSortedChildren()) {
1821 auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(child);
1822 if (displayNode) {
1823 const auto& surfaces = displayNode->GetCurAllSurfaces();
1824 curAllSurfacesInDisplay[displayNode->GetNodeId()] = surfaces;
1825 curAllSurfaces.insert(curAllSurfaces.end(), surfaces.begin(), surfaces.end());
1826 }
1827 }
1828
1829 if (node->GetChildrenCount()== 1) {
1830 auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(node->GetFirstChild());
1831 if (displayNode) {
1832 curAllSurfaces = displayNode->GetCurAllSurfaces();
1833 }
1834 } else {
1835 node->CollectSurface(node, curAllSurfaces, isUniRender_, false);
1836 }
1837 // Judge whether it is dirty
1838 // Surface cnt changed or surface DstRectChanged or surface ZorderChanged
1839 std::vector<NodeId> curSurfaceIds;
1840 curSurfaceIds.reserve(curAllSurfaces.size());
1841 for (auto it = curAllSurfaces.begin(); it != curAllSurfaces.end(); ++it) {
1842 auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
1843 if (surface == nullptr) {
1844 continue;
1845 }
1846 curSurfaceIds.emplace_back(surface->GetId());
1847 }
1848 bool winDirty = (lastSurfaceIds_ != curSurfaceIds || isDirty_ ||
1849 lastFocusNodeId_ != focusNodeId_);
1850 lastSurfaceIds_ = std::move(curSurfaceIds);
1851 lastFocusNodeId_ = focusNodeId_;
1852 if (!winDirty) {
1853 for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
1854 auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
1855 if (surface == nullptr || surface->IsLeashWindow()) {
1856 continue;
1857 }
1858 if (surface->GetZorderChanged() || surface->GetDstRectChanged() ||
1859 surface->IsOpaqueRegionChanged() ||
1860 surface->GetAlphaChanged() || (isUniRender_ && surface->IsDirtyRegionUpdated())) {
1861 winDirty = true;
1862 } else if (RSSystemParameters::GetFilterCacheOcculusionEnabled() &&
1863 surface->IsTransparent() && surface->IsFilterCacheStatusChanged()) {
1864 // When current frame's filter cache is valid or last frame's occlusion use filter cache as opaque
1865 // The occlusion needs to be recalculated
1866 winDirty = true;
1867 }
1868 surface->CleanDstRectChanged();
1869 surface->CleanAlphaChanged();
1870 surface->CleanOpaqueRegionChanged();
1871 surface->CleanDirtyRegionUpdated();
1872 }
1873 }
1874 if (!winDirty && !(systemAnimatedScenesList_.empty() && isReduceVSyncBySystemAnimatedScenes_)) {
1875 if (SurfaceOcclusionCallBackIfOnTreeStateChanged()) {
1876 SurfaceOcclusionCallback();
1877 }
1878 return;
1879 }
1880 isReduceVSyncBySystemAnimatedScenes_ = false;
1881 VisibleData dstCurVisVec;
1882 std::map<uint32_t, RSVisibleLevel> dstPidVisMap;
1883 for (auto& surfaces : curAllSurfacesInDisplay) {
1884 CalcOcclusionImplementation(surfaces.second, dstCurVisVec, dstPidVisMap);
1885 }
1886
1887 // Callback to WMS and QOS
1888 CallbackToWMS(dstCurVisVec);
1889 SetVSyncRateByVisibleLevel(dstPidVisMap, curAllSurfaces);
1890 // Callback for registered self drawing surfacenode
1891 SurfaceOcclusionCallback();
1892 }
1893
SetMultiInstancePidVSyncRate(std::map<uint32_t,RSVisibleLevel> & pidVisMap,std::vector<RSBaseRenderNode::SharedPtr> & curAllSurfaces)1894 void RSMainThread::SetMultiInstancePidVSyncRate(std::map<uint32_t, RSVisibleLevel>& pidVisMap,
1895 std::vector<RSBaseRenderNode::SharedPtr>& curAllSurfaces)
1896 {
1897 std::map<uint32_t, int> multiInstancePidMap;
1898 for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
1899 auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
1900 if (curSurface == nullptr || curSurface->GetDstRect().IsEmpty() || curSurface->IsLeashWindow()) {
1901 continue;
1902 }
1903 uint32_t tmpPid = ExtractPid(curSurface->GetId());
1904 multiInstancePidMap[tmpPid]++;
1905 }
1906 for (auto& iter : multiInstancePidMap) {
1907 if (iter.second > MAX_MULTI_INSTANCE_PID_COUNT) {
1908 pidVisMap[iter.first] = RSVisibleLevel::RS_ALL_VISIBLE;
1909 }
1910 }
1911 }
1912
CheckSurfaceVisChanged(std::map<uint32_t,RSVisibleLevel> & pidVisMap,std::vector<RSBaseRenderNode::SharedPtr> & curAllSurfaces)1913 bool RSMainThread::CheckSurfaceVisChanged(std::map<uint32_t, RSVisibleLevel>& pidVisMap,
1914 std::vector<RSBaseRenderNode::SharedPtr>& curAllSurfaces)
1915 {
1916 if (!systemAnimatedScenesList_.empty()) {
1917 pidVisMap.clear();
1918 for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
1919 auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
1920 if (curSurface == nullptr || curSurface->GetDstRect().IsEmpty() || curSurface->IsLeashWindow()) {
1921 continue;
1922 }
1923 uint32_t tmpPid = ExtractPid(curSurface->GetId());
1924 pidVisMap[tmpPid] = RSVisibleLevel::RS_SYSTEM_ANIMATE_SCENE;
1925 }
1926 isReduceVSyncBySystemAnimatedScenes_ = true;
1927 } else {
1928 SetMultiInstancePidVSyncRate(pidVisMap, curAllSurfaces);
1929 }
1930 bool isVisibleChanged = pidVisMap.size() != lastPidVisMap_.size();
1931 if (!isVisibleChanged) {
1932 auto iterCur = pidVisMap.begin();
1933 auto iterLast = lastPidVisMap_.begin();
1934 for (; iterCur != pidVisMap.end(); iterCur++, iterLast++) {
1935 if (iterCur->first != iterLast->first ||
1936 iterCur->second != iterLast->second) {
1937 isVisibleChanged = true;
1938 break;
1939 }
1940 }
1941 }
1942
1943 if (isVisibleChanged) {
1944 lastPidVisMap_ = pidVisMap;
1945 }
1946 return isVisibleChanged;
1947 }
1948
SetVSyncRateByVisibleLevel(std::map<uint32_t,RSVisibleLevel> & pidVisMap,std::vector<RSBaseRenderNode::SharedPtr> & curAllSurfaces)1949 void RSMainThread::SetVSyncRateByVisibleLevel(std::map<uint32_t, RSVisibleLevel>& pidVisMap,
1950 std::vector<RSBaseRenderNode::SharedPtr>& curAllSurfaces)
1951 {
1952 if (!vsyncControlEnabled_ || !CheckSurfaceVisChanged(pidVisMap, curAllSurfaces) ||
1953 appVSyncDistributor_ == nullptr) {
1954 return;
1955 }
1956 RS_TRACE_NAME_FMT("%s pidVisMapSize[%lu]", __func__, pidVisMap.size());
1957 for (auto iter:pidVisMap) {
1958 if (iter.second == RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE) {
1959 appVSyncDistributor_->SetQosVSyncRate(iter.first, SIMI_VISIBLE_RATE);
1960 } else if (iter.second == RSVisibleLevel::RS_SYSTEM_ANIMATE_SCENE) {
1961 appVSyncDistributor_->SetQosVSyncRate(iter.first, SYSTEM_ANIMATED_SECNES_RATE);
1962 } else if (iter.second == RSVisibleLevel::RS_INVISIBLE) {
1963 appVSyncDistributor_->SetQosVSyncRate(iter.first, INVISBLE_WINDOW_RATE);
1964 } else {
1965 appVSyncDistributor_->SetQosVSyncRate(iter.first, DEFAULT_RATE);
1966 }
1967 }
1968 }
1969
CallbackToWMS(VisibleData & curVisVec)1970 void RSMainThread::CallbackToWMS(VisibleData& curVisVec)
1971 {
1972 // if visible surfaces changed callback to WMS:
1973 // 1. curVisVec size changed
1974 // 2. curVisVec content changed
1975 bool visibleChanged = curVisVec.size() != lastVisVec_.size();
1976 std::sort(curVisVec.begin(), curVisVec.end());
1977 if (!visibleChanged) {
1978 for (uint32_t i = 0; i < curVisVec.size(); i++) {
1979 if ((curVisVec[i].first != lastVisVec_[i].first) || (curVisVec[i].second != lastVisVec_[i].second)) {
1980 visibleChanged = true;
1981 break;
1982 }
1983 }
1984 }
1985 if (visibleChanged) {
1986 std::lock_guard<std::mutex> lock(occlusionMutex_);
1987 for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
1988 if (it->second) {
1989 it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(curVisVec));
1990 }
1991 }
1992 }
1993 lastVisVec_.clear();
1994 std::swap(lastVisVec_, curVisVec);
1995 }
1996
SurfaceOcclusionCallback()1997 void RSMainThread::SurfaceOcclusionCallback()
1998 {
1999 const auto& nodeMap = context_->GetNodeMap();
2000 for (auto &listener : surfaceOcclusionListeners_) {
2001 if (savedAppWindowNode_.find(listener.first) == savedAppWindowNode_.end()) {
2002 auto node = nodeMap.GetRenderNode(listener.first);
2003 if (!node || !node->IsOnTheTree()) {
2004 RS_LOGW("RSMainThread::SurfaceOcclusionCallback cannot find surfacenode %{public}"
2005 PRIu64 ".", listener.first);
2006 continue;
2007 }
2008 auto appWindowNodeId = node->GetInstanceRootNodeId();
2009 if (appWindowNodeId == INVALID_NODEID) {
2010 RS_LOGW("RSMainThread::SurfaceOcclusionCallback surfacenode %{public}"
2011 PRIu64 " cannot find app window node.", listener.first);
2012 continue;
2013 }
2014 auto surfaceNode = node->ReinterpretCastTo<RSSurfaceRenderNode>();
2015 auto appWindowNode = nodeMap.GetRenderNode(appWindowNodeId)->ReinterpretCastTo<RSSurfaceRenderNode>();
2016 if (!surfaceNode || !appWindowNode) {
2017 RS_LOGW("RSMainThread::SurfaceOcclusionCallback ReinterpretCastTo fail.");
2018 continue;
2019 }
2020 savedAppWindowNode_[listener.first] = std::make_pair(surfaceNode, appWindowNode);
2021 }
2022 uint8_t level = 0;
2023 float visibleAreaRatio = 0.0f;
2024 bool isOnTheTree = savedAppWindowNode_[listener.first].first->IsOnTheTree();
2025 if (isOnTheTree) {
2026 const auto& property = savedAppWindowNode_[listener.first].first->GetRenderProperties();
2027 auto dstRect = property.GetBoundsGeometry()->GetAbsRect();
2028 if (dstRect.IsEmpty()) {
2029 continue;
2030 }
2031 visibleAreaRatio = static_cast<float>(savedAppWindowNode_[listener.first].second->
2032 GetVisibleRegionForCallBack().IntersectArea(dstRect)) /
2033 static_cast<float>(dstRect.GetWidth() * dstRect.GetHeight());
2034 auto& partitionVector = std::get<2>(listener.second); // get tuple 2 partition points vector
2035 bool vectorEmpty = partitionVector.empty();
2036 if (vectorEmpty && (visibleAreaRatio > 0.0f)) {
2037 level = 1;
2038 } else if (!vectorEmpty && ROSEN_EQ(visibleAreaRatio, 1.0f)) {
2039 level = partitionVector.size();
2040 } else if (!vectorEmpty && (visibleAreaRatio > 0.0f)) {
2041 for (const auto &point : partitionVector) {
2042 if (visibleAreaRatio > point) {
2043 level += 1;
2044 continue;
2045 }
2046 break;
2047 }
2048 }
2049 }
2050 auto& savedLevel = std::get<3>(listener.second); // tuple 3, check visible is changed
2051 if (savedLevel != level) {
2052 RS_LOGD("RSMainThread::SurfaceOcclusionCallback surfacenode: %{public}" PRIu64 ".", listener.first);
2053 savedLevel = level;
2054 if (isOnTheTree) {
2055 std::get<1>(listener.second)->OnSurfaceOcclusionVisibleChanged(visibleAreaRatio);
2056 }
2057 }
2058 }
2059 }
2060
WaitHardwareThreadTaskExcute()2061 bool RSMainThread::WaitHardwareThreadTaskExcute()
2062 {
2063 std::unique_lock<std::mutex> lock(hardwareThreadTaskMutex_);
2064 return hardwareThreadTaskCond_.wait_until(lock, std::chrono::system_clock::now() +
2065 std::chrono::milliseconds(WAIT_FOR_HARDWARE_THREAD_TASK_TIMEOUT),
2066 []() { return RSHardwareThread::Instance().GetunExcuteTaskNum() <= HARDWARE_THREAD_TASK_NUM; });
2067 }
2068
NotifyHardwareThreadCanExcuteTask()2069 void RSMainThread::NotifyHardwareThreadCanExcuteTask()
2070 {
2071 RS_TRACE_NAME("RSMainThread::NotifyHardwareThreadCanExcuteTask");
2072 std::lock_guard<std::mutex> lock(hardwareThreadTaskMutex_);
2073 hardwareThreadTaskCond_.notify_one();
2074 }
2075
RequestNextVSync()2076 void RSMainThread::RequestNextVSync()
2077 {
2078 RS_OPTIONAL_TRACE_FUNC();
2079 VSyncReceiver::FrameCallback fcb = {
2080 .userData_ = this,
2081 .callback_ = [this](uint64_t timestamp, void* data) { OnVsync(timestamp, data); },
2082 };
2083 if (receiver_ != nullptr) {
2084 requestNextVsyncNum_++;
2085 if (requestNextVsyncNum_ > REQUEST_VSYNC_NUMBER_LIMIT) {
2086 RS_LOGW("RSMainThread::RequestNextVSync too many times:%{public}d", requestNextVsyncNum_);
2087 }
2088 receiver_->RequestNextVSync(fcb);
2089 }
2090 }
2091
OnVsync(uint64_t timestamp,void * data)2092 void RSMainThread::OnVsync(uint64_t timestamp, void* data)
2093 {
2094 RSJankStats::GetInstance().SetStartTime();
2095 SetDiscardJankFrames(false);
2096 timestamp_ = timestamp;
2097 curTime_ = static_cast<uint64_t>(
2098 std::chrono::duration_cast<std::chrono::nanoseconds>(
2099 std::chrono::steady_clock::now().time_since_epoch()).count());
2100 requestNextVsyncNum_ = 0;
2101 frameCount_++;
2102 if (isUniRender_) {
2103 MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
2104 RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
2105 }
2106 mainLoop_();
2107 auto screenManager_ = CreateOrGetScreenManager();
2108 if (screenManager_ != nullptr) {
2109 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
2110 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
2111 RSHardwareThread::Instance().PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
2112 } else {
2113 PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
2114 }
2115 }
2116 RSJankStats::GetInstance().SetEndTime(GetDiscardJankFrames());
2117 }
2118
Animate(uint64_t timestamp)2119 void RSMainThread::Animate(uint64_t timestamp)
2120 {
2121 RS_TRACE_FUNC();
2122 lastAnimateTimestamp_ = timestamp;
2123 rsCurrRange_.Reset();
2124
2125 if (context_->animatingNodeList_.empty()) {
2126 if (doWindowAnimate_ && RSInnovation::UpdateQosVsyncEnabled()) {
2127 // Preventing Occlusion Calculation from Being Completed in Advance
2128 RSQosThread::GetInstance()->OnRSVisibilityChangeCB(lastPidVisMap_);
2129 }
2130 doWindowAnimate_ = false;
2131 return;
2132 }
2133 doDirectComposition_ = false;
2134 bool curWinAnim = false;
2135 bool needRequestNextVsync = false;
2136 // isCalculateAnimationValue is embedded modify for stat animate frame drop
2137 bool isCalculateAnimationValue = false;
2138 bool isRateDeciderEnabled = (context_->animatingNodeList_.size() <= CAL_NODE_PREFERRED_FPS_LIMIT);
2139 bool isDisplaySyncEnabled =
2140 HgmCore::Instance().GetCurrentRefreshRateMode() == HGM_REFRESHRATE_MODE_AUTO ? true : false;
2141 int64_t period = 0;
2142 if (receiver_) {
2143 receiver_->GetVSyncPeriod(period);
2144 }
2145 RSRenderAnimation::isCalcAnimateVelocity_ = isRateDeciderEnabled;
2146 uint32_t totalAnimationSize = 0;
2147 uint32_t animatingNodeSize = context_->animatingNodeList_.size();
2148 // iterate and animate all animating nodes, remove if animation finished
2149 EraseIf(context_->animatingNodeList_,
2150 [this, timestamp, period, isDisplaySyncEnabled, isRateDeciderEnabled, &totalAnimationSize,
2151 &curWinAnim, &needRequestNextVsync, &isCalculateAnimationValue](const auto& iter) -> bool {
2152 auto node = iter.second.lock();
2153 if (node == nullptr) {
2154 RS_LOGD("RSMainThread::Animate removing expired animating node");
2155 return true;
2156 }
2157 if (cacheCmdSkippedInfo_.count(ExtractPid(node->GetId())) > 0) {
2158 rsCurrRange_.Merge(node->animationManager_.GetDecideFrameRateRange());
2159 RS_LOGD("RSMainThread::Animate skip the cached node");
2160 return false;
2161 }
2162 totalAnimationSize += node->animationManager_.GetAnimationsSize();
2163 auto frameRateGetFunc = [this](const RSPropertyUnit unit, float velocity) -> int32_t {
2164 return frameRateMgr_->GetExpectedFrameRate(unit, velocity);
2165 };
2166 node->animationManager_.SetRateDeciderEnable(isRateDeciderEnabled, frameRateGetFunc);
2167 auto [hasRunningAnimation, nodeNeedRequestNextVsync, nodeCalculateAnimationValue] =
2168 node->Animate(timestamp, period, isDisplaySyncEnabled);
2169 if (!hasRunningAnimation) {
2170 node->InActivateDisplaySync();
2171 RS_LOGD("RSMainThread::Animate removing finished animating node %{public}" PRIu64, node->GetId());
2172 } else {
2173 node->UpdateDisplaySyncRange();
2174 rsCurrRange_.Merge(node->animationManager_.GetDecideFrameRateRange());
2175 }
2176 // request vsync if: 1. node has running animation, or 2. transition animation just ended
2177 needRequestNextVsync = needRequestNextVsync || nodeNeedRequestNextVsync || (node.use_count() == 1);
2178 isCalculateAnimationValue = isCalculateAnimationValue || nodeCalculateAnimationValue;
2179 if (node->template IsInstanceOf<RSSurfaceRenderNode>() && hasRunningAnimation) {
2180 if (isUniRender_) {
2181 auto surfacenode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
2182 surfacenode->SetAnimateState();
2183 }
2184 curWinAnim = true;
2185 }
2186 return !hasRunningAnimation;
2187 });
2188 RS_TRACE_NAME_FMT("Animate [nodeSize, totalAnimationSize] is [%lu, %lu]", animatingNodeSize, totalAnimationSize);
2189 if (!doWindowAnimate_ && curWinAnim && RSInnovation::UpdateQosVsyncEnabled()) {
2190 RSQosThread::ResetQosPid();
2191 }
2192 if (!isCalculateAnimationValue && needRequestNextVsync) {
2193 RS_TRACE_NAME("Animation running empty");
2194 }
2195
2196 doWindowAnimate_ = curWinAnim;
2197 RS_LOGD("RSMainThread::Animate end, animating nodes remains, has window animation: %{public}d", curWinAnim);
2198
2199 if (needRequestNextVsync) {
2200 RequestNextVSync();
2201 }
2202 PerfAfterAnim(needRequestNextVsync);
2203 }
2204
ProcessDataBySingleFrameComposer(std::unique_ptr<RSTransactionData> & rsTransactionData)2205 void RSMainThread::ProcessDataBySingleFrameComposer(std::unique_ptr<RSTransactionData>& rsTransactionData)
2206 {
2207 if (!rsTransactionData || !RSSystemProperties::GetSingleFrameComposerEnabled() ||
2208 !RSSingleFrameComposer::IsShouldProcessByIpcThread(rsTransactionData->GetSendingPid())) {
2209 return;
2210 }
2211
2212 RSSingleFrameComposer::SetSingleFrameFlag(std::this_thread::get_id());
2213 if (isUniRender_) {
2214 context_->transactionTimestamp_ = rsTransactionData->GetTimestamp();
2215 rsTransactionData->ProcessBySingleFrameComposer(*context_);
2216 }
2217 }
2218
RecvRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)2219 void RSMainThread::RecvRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
2220 {
2221 if (!rsTransactionData) {
2222 return;
2223 }
2224 if (isUniRender_) {
2225 std::lock_guard<std::mutex> lock(transitionDataMutex_);
2226 cachedTransactionDataMap_[rsTransactionData->GetSendingPid()].emplace_back(std::move(rsTransactionData));
2227 } else {
2228 ClassifyRSTransactionData(rsTransactionData);
2229 }
2230 RequestNextVSync();
2231 }
2232
ClassifyRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)2233 void RSMainThread::ClassifyRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
2234 {
2235 const auto& nodeMap = context_->GetNodeMap();
2236 std::lock_guard<std::mutex> lock(transitionDataMutex_);
2237 std::unique_ptr<RSTransactionData> transactionData(std::move(rsTransactionData));
2238 auto timestamp = transactionData->GetTimestamp();
2239 RS_LOGD("RSMainThread::RecvRSTransactionData timestamp = %{public}" PRIu64, timestamp);
2240 for (auto& [nodeId, followType, command] : transactionData->GetPayload()) {
2241 if (nodeId == 0 || followType == FollowType::NONE) {
2242 pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
2243 continue;
2244 }
2245 auto node = nodeMap.GetRenderNode(nodeId);
2246 if (node && followType == FollowType::FOLLOW_TO_PARENT) {
2247 auto parentNode = node->GetParent().lock();
2248 if (parentNode) {
2249 nodeId = parentNode->GetId();
2250 } else {
2251 pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
2252 continue;
2253 }
2254 }
2255 cachedCommands_[nodeId][timestamp].emplace_back(std::move(command));
2256 }
2257 }
2258
PostTask(RSTaskMessage::RSTask task)2259 void RSMainThread::PostTask(RSTaskMessage::RSTask task)
2260 {
2261 if (handler_) {
2262 handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
2263 }
2264 }
2265
PostTask(RSTaskMessage::RSTask task,const std::string & name,int64_t delayTime,AppExecFwk::EventQueue::Priority priority)2266 void RSMainThread::PostTask(RSTaskMessage::RSTask task, const std::string& name, int64_t delayTime,
2267 AppExecFwk::EventQueue::Priority priority)
2268 {
2269 if (handler_) {
2270 handler_->PostTask(task, name, delayTime, priority);
2271 }
2272 }
2273
RemoveTask(const std::string & name)2274 void RSMainThread::RemoveTask(const std::string& name)
2275 {
2276 if (handler_) {
2277 handler_->RemoveTask(name);
2278 }
2279 }
2280
PostSyncTask(RSTaskMessage::RSTask task)2281 void RSMainThread::PostSyncTask(RSTaskMessage::RSTask task)
2282 {
2283 if (handler_) {
2284 handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
2285 }
2286 }
2287
IsIdle() const2288 bool RSMainThread::IsIdle() const
2289 {
2290 return handler_ ? handler_->IsIdle() : false;
2291 }
2292
RegisterApplicationAgent(uint32_t pid,sptr<IApplicationAgent> app)2293 void RSMainThread::RegisterApplicationAgent(uint32_t pid, sptr<IApplicationAgent> app)
2294 {
2295 applicationAgentMap_.emplace(pid, app);
2296 }
2297
UnRegisterApplicationAgent(sptr<IApplicationAgent> app)2298 void RSMainThread::UnRegisterApplicationAgent(sptr<IApplicationAgent> app)
2299 {
2300 EraseIf(applicationAgentMap_,
2301 [&app](const auto& iter) { return iter.second && app && iter.second->AsObject() == app->AsObject(); });
2302 }
2303
RegisterOcclusionChangeCallback(pid_t pid,sptr<RSIOcclusionChangeCallback> callback)2304 void RSMainThread::RegisterOcclusionChangeCallback(pid_t pid, sptr<RSIOcclusionChangeCallback> callback)
2305 {
2306 std::lock_guard<std::mutex> lock(occlusionMutex_);
2307 occlusionListeners_[pid] = callback;
2308 }
2309
UnRegisterOcclusionChangeCallback(pid_t pid)2310 void RSMainThread::UnRegisterOcclusionChangeCallback(pid_t pid)
2311 {
2312 std::lock_guard<std::mutex> lock(occlusionMutex_);
2313 occlusionListeners_.erase(pid);
2314 }
2315
RegisterSurfaceOcclusionChangeCallback(NodeId id,pid_t pid,sptr<RSISurfaceOcclusionChangeCallback> callback,std::vector<float> & partitionPoints)2316 void RSMainThread::RegisterSurfaceOcclusionChangeCallback(
2317 NodeId id, pid_t pid, sptr<RSISurfaceOcclusionChangeCallback> callback, std::vector<float>& partitionPoints)
2318 {
2319 std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
2320 uint8_t level = 1;
2321 if (!partitionPoints.empty()) {
2322 level = partitionPoints.size();
2323 }
2324 surfaceOcclusionListeners_[id] = std::make_tuple(pid, callback, partitionPoints, level);
2325 }
2326
UnRegisterSurfaceOcclusionChangeCallback(NodeId id)2327 void RSMainThread::UnRegisterSurfaceOcclusionChangeCallback(NodeId id)
2328 {
2329 std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
2330 surfaceOcclusionListeners_.erase(id);
2331 savedAppWindowNode_.erase(id);
2332 }
2333
ClearSurfaceOcclusionChangeCallback(pid_t pid)2334 void RSMainThread::ClearSurfaceOcclusionChangeCallback(pid_t pid)
2335 {
2336 std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
2337 for (auto it = surfaceOcclusionListeners_.begin(); it != surfaceOcclusionListeners_.end();) {
2338 if (std::get<0>(it->second) == pid) {
2339 if (savedAppWindowNode_.find(it->first) != savedAppWindowNode_.end()) {
2340 savedAppWindowNode_.erase(it->first);
2341 }
2342 surfaceOcclusionListeners_.erase(it++);
2343 } else {
2344 it++;
2345 }
2346 }
2347 }
2348
SurfaceOcclusionCallBackIfOnTreeStateChanged()2349 bool RSMainThread::SurfaceOcclusionCallBackIfOnTreeStateChanged()
2350 {
2351 std::vector<NodeId> registeredSurfaceOnTree;
2352 for (auto it = savedAppWindowNode_.begin(); it != savedAppWindowNode_.end(); ++it) {
2353 if (it->second.first->IsOnTheTree()) {
2354 registeredSurfaceOnTree.push_back(it->first);
2355 }
2356 }
2357 if (lastRegisteredSurfaceOnTree_ != registeredSurfaceOnTree) {
2358 lastRegisteredSurfaceOnTree_ = registeredSurfaceOnTree;
2359 return true;
2360 }
2361 return false;
2362 }
2363
SendCommands()2364 void RSMainThread::SendCommands()
2365 {
2366 RS_OPTIONAL_TRACE_FUNC();
2367 RsFrameReport& fr = RsFrameReport::GetInstance();
2368 if (fr.GetEnable()) {
2369 fr.SendCommandsStart();
2370 fr.RenderEnd();
2371 }
2372 if (!RSMessageProcessor::Instance().HasTransaction()) {
2373 return;
2374 }
2375
2376 // dispatch messages to corresponding application
2377 auto transactionMapPtr = std::make_shared<std::unordered_map<uint32_t, std::shared_ptr<RSTransactionData>>>(
2378 RSMessageProcessor::Instance().GetAllTransactions());
2379 RSMessageProcessor::Instance().ReInitializeMovedMap();
2380 PostTask([this, transactionMapPtr]() {
2381 for (const auto& transactionIter : *transactionMapPtr) {
2382 auto pid = transactionIter.first;
2383 auto appIter = applicationAgentMap_.find(pid);
2384 if (appIter == applicationAgentMap_.end()) {
2385 RS_LOGW("RSMainThread::SendCommand no application agent registered as pid %{public}d,"
2386 "this will cause memory leak!", pid);
2387 continue;
2388 }
2389 auto& app = appIter->second;
2390 auto transactionPtr = transactionIter.second;
2391 app->OnTransaction(transactionPtr);
2392 }
2393 });
2394 }
2395
QosStateDump(std::string & dumpString)2396 void RSMainThread::QosStateDump(std::string& dumpString)
2397 {
2398 if (RSQosThread::GetInstance()->GetQosCal()) {
2399 dumpString.append("QOS is enabled\n");
2400 } else {
2401 dumpString.append("QOS is disabled\n");
2402 }
2403 }
2404
RenderServiceTreeDump(std::string & dumpString)2405 void RSMainThread::RenderServiceTreeDump(std::string& dumpString)
2406 {
2407 RS_TRACE_NAME("GetDumpTree");
2408 dumpString.append("Animating Node: [");
2409 for (auto& [nodeId, _]: context_->animatingNodeList_) {
2410 dumpString.append(std::to_string(nodeId) + ", ");
2411 }
2412 dumpString.append("];\n");
2413 const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
2414 if (rootNode == nullptr) {
2415 dumpString.append("rootNode is null\n");
2416 return;
2417 }
2418 rootNode->DumpTree(0, dumpString);
2419 }
2420
DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)2421 bool RSMainThread::DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)
2422 {
2423 using CreateParallelSyncSignalFunc = void* (*)(uint32_t);
2424 using SignalCountDownFunc = void (*)(void*);
2425 using SignalAwaitFunc = void (*)(void*);
2426 using AssignTaskFunc = void (*)(std::function<void()>);
2427 using RemoveStoppedThreadsFunc = void (*)();
2428
2429 auto CreateParallelSyncSignal = (CreateParallelSyncSignalFunc)RSInnovation::_s_createParallelSyncSignal;
2430 auto SignalCountDown = (SignalCountDownFunc)RSInnovation::_s_signalCountDown;
2431 auto SignalAwait = (SignalAwaitFunc)RSInnovation::_s_signalAwait;
2432 auto AssignTask = (AssignTaskFunc)RSInnovation::_s_assignTask;
2433 auto RemoveStoppedThreads = (RemoveStoppedThreadsFunc)RSInnovation::_s_removeStoppedThreads;
2434
2435 void* syncSignal = (*CreateParallelSyncSignal)(rootNode->GetChildrenCount());
2436 if (!syncSignal) {
2437 return false;
2438 }
2439
2440 (*RemoveStoppedThreads)();
2441
2442 auto children = *rootNode->GetSortedChildren();
2443 bool animate_ = doWindowAnimate_;
2444 for (auto it = children.rbegin(); it != children.rend(); it++) {
2445 auto child = *it;
2446 auto task = [&syncSignal, SignalCountDown, child, animate_]() {
2447 std::shared_ptr<RSNodeVisitor> visitor;
2448 auto rsVisitor = std::make_shared<RSRenderServiceVisitor>(true);
2449 rsVisitor->SetAnimateState(animate_);
2450 visitor = rsVisitor;
2451 child->Process(visitor);
2452 (*SignalCountDown)(syncSignal);
2453 };
2454 if (*it == *children.begin()) {
2455 task();
2456 } else {
2457 (*AssignTask)(task);
2458 }
2459 }
2460 (*SignalAwait)(syncSignal);
2461 return true;
2462 }
2463
ClearTransactionDataPidInfo(pid_t remotePid)2464 void RSMainThread::ClearTransactionDataPidInfo(pid_t remotePid)
2465 {
2466 if (!isUniRender_) {
2467 return;
2468 }
2469 std::lock_guard<std::mutex> lock(transitionDataMutex_);
2470 if (effectiveTransactionDataIndexMap_.count(remotePid) > 0 &&
2471 !effectiveTransactionDataIndexMap_[remotePid].second.empty()) {
2472 RS_LOGD("RSMainThread::ClearTransactionDataPidInfo process:%{public}d destroyed, skip commands", remotePid);
2473 }
2474 effectiveTransactionDataIndexMap_.erase(remotePid);
2475 transactionDataLastWaitTime_.erase(remotePid);
2476
2477 // clear cpu cache when process exit
2478 // CLEAN_CACHE_FREQ to prevent multiple cleanups in a short period of time
2479 if ((timestamp_ - lastCleanCacheTimestamp_) / REFRESH_PERIOD > CLEAN_CACHE_FREQ) {
2480 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2481 RS_LOGD("RSMainThread: clear cpu cache pid:%{public}d", remotePid);
2482 if (!IsResidentProcess(remotePid)) {
2483 ClearMemoryCache(ClearMemoryMoment::PROCESS_EXIT, true);
2484 }
2485 lastCleanCacheTimestamp_ = timestamp_;
2486 #endif
2487 }
2488 }
2489
IsResidentProcess(pid_t pid) const2490 bool RSMainThread::IsResidentProcess(pid_t pid) const
2491 {
2492 return pid == ExtractPid(context_->GetNodeMap().GetEntryViewNodeId());
2493 }
2494
TrimMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString)2495 void RSMainThread::TrimMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString)
2496 {
2497 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2498 if (!RSUniRenderJudgement::IsUniRender()) {
2499 dumpString.append("\n---------------\nNot in UniRender and no resource can be released");
2500 return;
2501 }
2502 std::string type;
2503 argSets.erase(u"trimMem");
2504 if (!argSets.empty()) {
2505 type = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
2506 }
2507 #ifndef USE_ROSEN_DRAWING
2508 #ifdef NEW_RENDER_CONTEXT
2509 auto grContext = GetRenderEngine()->GetDrawingContext()->GetDrawingContext();
2510 #else
2511 auto grContext = GetRenderEngine()->GetRenderContext()->GetGrContext();
2512 #endif
2513 if (type.empty()) {
2514 grContext->flush();
2515 SkGraphics::PurgeAllCaches();
2516 grContext->freeGpuResources();
2517 grContext->purgeUnlockedResources(true);
2518 #ifdef NEW_RENDER_CONTEXT
2519 MemoryHandler::ClearShader();
2520 #else
2521 std::shared_ptr<RenderContext> rendercontext = std::make_shared<RenderContext>();
2522 rendercontext->CleanAllShaderCache();
2523 #endif
2524 grContext->flushAndSubmit(true);
2525 } else if (type == "cpu") {
2526 grContext->flush();
2527 SkGraphics::PurgeAllCaches();
2528 grContext->flushAndSubmit(true);
2529 } else if (type == "gpu") {
2530 grContext->flush();
2531 grContext->freeGpuResources();
2532 grContext->flushAndSubmit(true);
2533 } else if (type == "uihidden") {
2534 grContext->flush();
2535 grContext->purgeUnlockAndSafeCacheGpuResources();
2536 grContext->flushAndSubmit(true);
2537 } else if (type == "shader") {
2538 #ifdef NEW_RENDER_CONTEXT
2539 MemoryHandler::ClearShader();
2540 #else
2541 std::shared_ptr<RenderContext> rendercontext = std::make_shared<RenderContext>();
2542 rendercontext->CleanAllShaderCache();
2543 #endif
2544 } else if (type == "flushcache") {
2545 int ret = mallopt(M_FLUSH_THREAD_CACHE, 0);
2546 dumpString.append("flushcache " + std::to_string(ret) + "\n");
2547 } else {
2548 uint32_t pid = static_cast<uint32_t>(std::stoll(type));
2549 GrGpuResourceTag tag(pid, 0, 0, 0);
2550 MemoryManager::ReleaseAllGpuResource(grContext, tag);
2551 }
2552 dumpString.append("trimMem: " + type + "\n");
2553 #else
2554 #ifdef NEW_RENDER_CONTEXT
2555 auto gpuContext = GetRenderEngine()->GetDrawingContext()->GetDrawingContext();
2556 #else
2557 auto gpuContext = GetRenderEngine()->GetRenderContext()->GetDrGPUContext();
2558 #endif
2559 if (type.empty()) {
2560 gpuContext->Flush();
2561 SkGraphics::PurgeAllCaches();
2562 gpuContext->FreeGpuResources();
2563 gpuContext->PurgeUnlockedResources(true);
2564 #ifdef NEW_RENDER_CONTEXT
2565 MemoryHandler::ClearShader();
2566 #else
2567 std::shared_ptr<RenderContext> rendercontext = std::make_shared<RenderContext>();
2568 rendercontext->CleanAllShaderCache();
2569 #endif
2570 gpuContext->FlushAndSubmit(true);
2571 } else if (type == "cpu") {
2572 gpuContext->Flush();
2573 SkGraphics::PurgeAllCaches();
2574 gpuContext->FlushAndSubmit(true);
2575 } else if (type == "gpu") {
2576 gpuContext->Flush();
2577 gpuContext->FreeGpuResources();
2578 gpuContext->FlushAndSubmit(true);
2579 } else if (type == "uihidden") {
2580 gpuContext->Flush();
2581 gpuContext->PurgeUnlockAndSafeCacheGpuResources();
2582 gpuContext->FlushAndSubmit(true);
2583 } else if (type == "shader") {
2584 #ifdef NEW_RENDER_CONTEXT
2585 MemoryHandler::ClearShader();
2586 #else
2587 std::shared_ptr<RenderContext> rendercontext = std::make_shared<RenderContext>();
2588 rendercontext->CleanAllShaderCache();
2589 #endif
2590 } else if (type == "flushcache") {
2591 int ret = mallopt(M_FLUSH_THREAD_CACHE, 0);
2592 dumpString.append("flushcache " + std::to_string(ret) + "\n");
2593 } else {
2594 uint32_t pid = static_cast<uint32_t>(std::stoll(type));
2595 Drawing::GPUResourceTag tag(pid, 0, 0, 0);
2596 MemoryManager::ReleaseAllGpuResource(gpuContext, tag);
2597 }
2598 dumpString.append("trimMem: " + type + "\n");
2599 #endif
2600 #endif
2601 }
2602
DumpNode(std::string & result,uint64_t nodeId) const2603 void RSMainThread::DumpNode(std::string& result, uint64_t nodeId) const
2604 {
2605 const auto& nodeMap = context_->GetNodeMap();
2606 auto node = nodeMap.GetRenderNode<RSRenderNode>(nodeId);
2607 if (!node) {
2608 result.append("have no this node");
2609 return;
2610 }
2611 DfxString log;
2612 node->DumpNodeInfo(log);
2613 result.append(log.GetString());
2614 }
2615
DumpMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString,std::string & type,int pid)2616 void RSMainThread::DumpMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString,
2617 std::string& type, int pid)
2618 {
2619 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2620 DfxString log;
2621 #ifndef USE_ROSEN_DRAWING
2622 #ifdef NEW_RENDER_CONTEXT
2623 auto grContext = GetRenderEngine()->GetDrawingContext()->GetDrawingContext();
2624 #else
2625 auto grContext = GetRenderEngine()->GetRenderContext()->GetGrContext();
2626 #endif
2627 if (pid != 0) {
2628 MemoryManager::DumpPidMemory(log, pid, grContext);
2629 } else {
2630 MemoryManager::DumpMemoryUsage(log, grContext, type);
2631 }
2632 #else
2633 auto gpuContext = GetRenderEngine()->GetRenderContext()->GetDrGPUContext();
2634 if (gpuContext != nullptr) {
2635 if (pid != 0) {
2636 MemoryManager::DumpPidMemory(log, pid, gpuContext);
2637 } else {
2638 MemoryManager::DumpMemoryUsage(log, gpuContext, type);
2639 }
2640 }
2641 #endif
2642 if (type.empty() || type == MEM_GPU_TYPE) {
2643 auto subThreadManager = RSSubThreadManager::Instance();
2644 if (subThreadManager) {
2645 subThreadManager->DumpMem(log);
2646 }
2647 }
2648 dumpString.append("dumpMem: " + type + "\n");
2649 dumpString.append(log.GetString());
2650 #else
2651 dumpString.append("No GPU in this device");
2652 #endif
2653 }
2654
CountMem(int pid,MemoryGraphic & mem)2655 void RSMainThread::CountMem(int pid, MemoryGraphic& mem)
2656 {
2657 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2658 #ifndef USE_ROSEN_DRAWING
2659 #ifdef NEW_RENDER_CONTEXT
2660 mem = MemoryManager::CountPidMemory(pid, GetRenderEngine()->GetDrawingContext()->GetDrawingContext());
2661 mem += MemoryManager::CountSubMemory(pid, GetRenderEngine()->GetDrawingContext()->GetDrawingContext());
2662 #else
2663 mem = MemoryManager::CountPidMemory(pid, GetRenderEngine()->GetRenderContext()->GetGrContext());
2664 mem += MemoryManager::CountSubMemory(pid, GetRenderEngine()->GetRenderContext()->GetGrContext());
2665 #endif
2666 #else
2667 mem = MemoryManager::CountPidMemory(pid, GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
2668 mem += MemoryManager::CountSubMemory(pid, GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
2669 #endif
2670 #endif
2671 }
2672
CountMem(std::vector<MemoryGraphic> & mems)2673 void RSMainThread::CountMem(std::vector<MemoryGraphic>& mems)
2674 {
2675 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
2676 if (!context_) {
2677 RS_LOGE("RSMainThread::CountMem Context is nullptr");
2678 return;
2679 }
2680 const auto& nodeMap = context_->GetNodeMap();
2681 std::vector<pid_t> pids;
2682 nodeMap.TraverseSurfaceNodes([&pids] (const std::shared_ptr<RSSurfaceRenderNode>& node) {
2683 auto pid = ExtractPid(node->GetId());
2684 if (std::find(pids.begin(), pids.end(), pid) == pids.end()) {
2685 pids.emplace_back(pid);
2686 }
2687 });
2688 #ifndef USE_ROSEN_DRAWING
2689 #ifdef NEW_RENDER_CONTEXT
2690 MemoryManager::CountMemory(pids, GetRenderEngine()->GetDrawingContext()->GetDrawingContext(), mems);
2691 #else
2692 MemoryManager::CountMemory(pids, GetRenderEngine()->GetRenderContext()->GetGrContext(), mems);
2693 #endif
2694 #else
2695 MemoryManager::CountMemory(pids, GetRenderEngine()->GetRenderContext()->GetDrGPUContext(), mems);
2696 #endif
2697 #endif
2698 }
2699
AddTransactionDataPidInfo(pid_t remotePid)2700 void RSMainThread::AddTransactionDataPidInfo(pid_t remotePid)
2701 {
2702 if (!isUniRender_) {
2703 return;
2704 }
2705 std::lock_guard<std::mutex> lock(transitionDataMutex_);
2706 if (effectiveTransactionDataIndexMap_.count(remotePid) > 0) {
2707 RS_LOGW("RSMainThread::AddTransactionDataPidInfo remotePid:%{public}d already exists", remotePid);
2708 }
2709 effectiveTransactionDataIndexMap_[remotePid].first = 0;
2710 }
2711
SetDirtyFlag()2712 void RSMainThread::SetDirtyFlag()
2713 {
2714 isDirty_ = true;
2715 }
2716
SetColorPickerForceRequestVsync(bool colorPickerForceRequestVsync)2717 void RSMainThread::SetColorPickerForceRequestVsync(bool colorPickerForceRequestVsync)
2718 {
2719 colorPickerForceRequestVsync_ = colorPickerForceRequestVsync;
2720 }
2721
SetNoNeedToPostTask(bool noNeedToPostTask)2722 void RSMainThread::SetNoNeedToPostTask(bool noNeedToPostTask)
2723 {
2724 noNeedToPostTask_ = noNeedToPostTask;
2725 }
2726
GetNoNeedToPostTask()2727 bool RSMainThread::GetNoNeedToPostTask()
2728 {
2729 return noNeedToPostTask_.load();
2730 }
2731
SetAccessibilityConfigChanged()2732 void RSMainThread::SetAccessibilityConfigChanged()
2733 {
2734 isAccessibilityConfigChanged_ = true;
2735 }
2736
PerfAfterAnim(bool needRequestNextVsync)2737 void RSMainThread::PerfAfterAnim(bool needRequestNextVsync)
2738 {
2739 if (!isUniRender_) {
2740 return;
2741 }
2742 if (needRequestNextVsync && timestamp_ - prePerfTimestamp_ > PERF_PERIOD) {
2743 RS_LOGD("RSMainThread:: soc perf to render_service_animation");
2744 prePerfTimestamp_ = timestamp_;
2745 } else if (!needRequestNextVsync && prePerfTimestamp_) {
2746 RS_LOGD("RSMainThread:: soc perf off render_service_animation");
2747 prePerfTimestamp_ = 0;
2748 }
2749 }
2750
ForceRefreshForUni()2751 void RSMainThread::ForceRefreshForUni()
2752 {
2753 if (isUniRender_) {
2754 PostTask([=]() {
2755 MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
2756 RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
2757 auto now = std::chrono::duration_cast<std::chrono::nanoseconds>(
2758 std::chrono::steady_clock::now().time_since_epoch()).count();
2759 timestamp_ = timestamp_ + (now - curTime_);
2760 curTime_ = now;
2761 RS_TRACE_NAME("RSMainThread::ForceRefreshForUni timestamp:" + std::to_string(timestamp_));
2762 mainLoop_();
2763 });
2764 auto screenManager_ = CreateOrGetScreenManager();
2765 if (screenManager_ != nullptr) {
2766 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
2767 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
2768 RSHardwareThread::Instance().PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
2769 } else {
2770 PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
2771 }
2772 }
2773 } else {
2774 RequestNextVSync();
2775 }
2776 }
2777
PerfForBlurIfNeeded()2778 void RSMainThread::PerfForBlurIfNeeded()
2779 {
2780 handler_->RemoveTask("PerfForBlurIfNeeded");
2781 static uint64_t prePerfTimestamp = 0;
2782 static int preBlurCnt = 0;
2783 auto task = [this]() {
2784 if (timestamp_ - prePerfTimestamp > PERF_PERIOD_BLUR_TIMEOUT && preBlurCnt != 0) {
2785 PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(preBlurCnt), false);
2786 prePerfTimestamp = 0;
2787 preBlurCnt = 0;
2788 }
2789 };
2790 // delay 100ms
2791 handler_->PostTask(task, "PerfForBlurIfNeeded", 100);
2792 int blurCnt = RSPropertiesPainter::GetAndResetBlurCnt();
2793 // clamp blurCnt to 0~3.
2794 blurCnt = std::clamp<int>(blurCnt, 0, 3);
2795 if ((blurCnt > preBlurCnt || blurCnt == 0) && preBlurCnt != 0) {
2796 PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(preBlurCnt), false);
2797 preBlurCnt = 0;
2798 }
2799 if (blurCnt == 0) {
2800 return;
2801 }
2802 if (timestamp_ - prePerfTimestamp > PERF_PERIOD_BLUR || blurCnt > preBlurCnt) {
2803 PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(blurCnt), true);
2804 prePerfTimestamp = timestamp_;
2805 preBlurCnt = blurCnt;
2806 }
2807 }
2808
PerfMultiWindow()2809 void RSMainThread::PerfMultiWindow()
2810 {
2811 if (!isUniRender_) {
2812 return;
2813 }
2814 static uint64_t lastPerfTimestamp = 0;
2815 if (appWindowNum_ >= MULTI_WINDOW_PERF_START_NUM && appWindowNum_ <= MULTI_WINDOW_PERF_END_NUM
2816 && timestamp_ - lastPerfTimestamp > PERF_PERIOD_MULTI_WINDOW) {
2817 RS_LOGD("RSMainThread::PerfMultiWindow soc perf");
2818 PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, true);
2819 lastPerfTimestamp = timestamp_;
2820 } else if ((appWindowNum_ < MULTI_WINDOW_PERF_START_NUM || appWindowNum_ > MULTI_WINDOW_PERF_END_NUM)
2821 && timestamp_ - lastPerfTimestamp < PERF_PERIOD_MULTI_WINDOW) {
2822 RS_LOGD("RSMainThread::PerfMultiWindow soc perf off");
2823 PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, false);
2824 }
2825 }
2826
RenderFrameStart(uint64_t timestamp)2827 void RSMainThread::RenderFrameStart(uint64_t timestamp)
2828 {
2829 if (RsFrameReport::GetInstance().GetEnable()) {
2830 RsFrameReport::GetInstance().RenderStart(timestamp);
2831 }
2832 RenderFrameTrace::GetInstance().RenderStartFrameTrace(RS_INTERVAL_NAME);
2833 int hardwareTid = RSHardwareThread::Instance().GetHardwareTid();
2834 if (hardwareTid_ != hardwareTid) {
2835 hardwareTid_ = hardwareTid;
2836 RsFrameReport::GetInstance().SetFrameParam(EVENT_SET_HARDWARE_UTIL, 0, 0, hardwareTid_);
2837 }
2838 }
2839
SetAppWindowNum(uint32_t num)2840 void RSMainThread::SetAppWindowNum(uint32_t num)
2841 {
2842 appWindowNum_ = num;
2843 }
2844
SetSystemAnimatedScenes(SystemAnimatedScenes systemAnimatedScenes)2845 bool RSMainThread::SetSystemAnimatedScenes(SystemAnimatedScenes systemAnimatedScenes)
2846 {
2847 RS_OPTIONAL_TRACE_NAME_FMT("%s systemAnimatedScenes[%u] systemAnimatedScenes_[%u] threeFingerScenesListSize[%d] "
2848 "systemAnimatedScenesListSize_[%d]", __func__, systemAnimatedScenes,
2849 systemAnimatedScenes_, threeFingerScenesList_.size(), systemAnimatedScenesList_.size());
2850 if (systemAnimatedScenes < SystemAnimatedScenes::ENTER_MISSION_CENTER ||
2851 systemAnimatedScenes > SystemAnimatedScenes::OTHERS) {
2852 RS_LOGD("RSMainThread::SetSystemAnimatedScenes Out of range.");
2853 return false;
2854 }
2855 systemAnimatedScenes_ = systemAnimatedScenes;
2856 if (!systemAnimatedScenesEnabled_) {
2857 return true;
2858 }
2859 {
2860 std::lock_guard<std::mutex> lock(systemAnimatedScenesMutex_);
2861 if (systemAnimatedScenes == SystemAnimatedScenes::OTHERS) {
2862 if (!threeFingerScenesList_.empty()) {
2863 threeFingerScenesList_.pop_front();
2864 }
2865 if (!systemAnimatedScenesList_.empty()) {
2866 systemAnimatedScenesList_.pop_front();
2867 }
2868 } else {
2869 uint64_t curTime = static_cast<uint64_t>(
2870 std::chrono::duration_cast<std::chrono::nanoseconds>(
2871 std::chrono::steady_clock::now().time_since_epoch()).count());
2872 if (systemAnimatedScenes == SystemAnimatedScenes::ENTER_TFS_WINDOW ||
2873 systemAnimatedScenes == SystemAnimatedScenes::EXIT_TFU_WINDOW ||
2874 systemAnimatedScenes == SystemAnimatedScenes::ENTER_WIND_CLEAR ||
2875 systemAnimatedScenes == SystemAnimatedScenes::ENTER_WIND_RECOVER) {
2876 threeFingerScenesList_.push_back(std::make_pair(systemAnimatedScenes, curTime));
2877 }
2878 if (systemAnimatedScenes != SystemAnimatedScenes::APPEAR_MISSION_CENTER) {
2879 systemAnimatedScenesList_.push_back(std::make_pair(systemAnimatedScenes, curTime));
2880 }
2881 }
2882 }
2883 return true;
2884 }
2885
GetSystemAnimatedScenes()2886 SystemAnimatedScenes RSMainThread::GetSystemAnimatedScenes()
2887 {
2888 return systemAnimatedScenes_;
2889 }
2890
CheckNodeHasToBePreparedByPid(NodeId nodeId,bool isClassifyByRoot)2891 bool RSMainThread::CheckNodeHasToBePreparedByPid(NodeId nodeId, bool isClassifyByRoot)
2892 {
2893 if (context_->activeNodesInRoot_.empty() || nodeId == INVALID_NODEID) {
2894 return false;
2895 }
2896 if (!isClassifyByRoot) {
2897 // Match by PID
2898 auto pid = ExtractPid(nodeId);
2899 return std::any_of(context_->activeNodesInRoot_.begin(), context_->activeNodesInRoot_.end(),
2900 [pid](const auto& iter) { return ExtractPid(iter.first) == pid; });
2901 } else {
2902 std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
2903 return context_->activeNodesInRoot_.count(nodeId);
2904 }
2905 }
2906
IsDrawingGroupChanged(RSRenderNode & cacheRootNode) const2907 bool RSMainThread::IsDrawingGroupChanged(RSRenderNode& cacheRootNode) const
2908 {
2909 auto iter = context_->activeNodesInRoot_.find(cacheRootNode.GetInstanceRootNodeId());
2910 if (iter != context_->activeNodesInRoot_.end()) {
2911 const auto& activeNodeIds = iter->second;
2912 // do not need to check cacheroot node itself
2913 // in case of tree change, parent node would set content dirty and reject before
2914 auto cacheRootId = cacheRootNode.GetId();
2915 auto groupNodeIds = cacheRootNode.GetVisitedCacheRootIds();
2916 for (auto [id, subNode] : activeNodeIds) {
2917 auto node = subNode.lock();
2918 if (node == nullptr || id == cacheRootId) {
2919 continue;
2920 }
2921 if (groupNodeIds.find(node->GetDrawingCacheRootId()) != groupNodeIds.end()) {
2922 return true;
2923 }
2924 }
2925 }
2926 return false;
2927 }
2928
CheckAndUpdateInstanceContentStaticStatus(std::shared_ptr<RSSurfaceRenderNode> instanceNode) const2929 void RSMainThread::CheckAndUpdateInstanceContentStaticStatus(std::shared_ptr<RSSurfaceRenderNode> instanceNode) const
2930 {
2931 if (instanceNode == nullptr) {
2932 RS_LOGE("CheckAndUpdateInstanceContentStaticStatus instanceNode invalid.");
2933 return ;
2934 }
2935 auto iter = context_->activeNodesInRoot_.find(instanceNode->GetId());
2936 if (iter != context_->activeNodesInRoot_.end()) {
2937 instanceNode->UpdateSurfaceCacheContentStatic(iter->second);
2938 } else {
2939 instanceNode->UpdateSurfaceCacheContentStatic({});
2940 }
2941 }
2942
ApplyModifiers()2943 void RSMainThread::ApplyModifiers()
2944 {
2945 std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
2946 if (context_->activeNodesInRoot_.empty()) {
2947 return;
2948 }
2949 RS_TRACE_NAME_FMT("ApplyModifiers (PropertyDrawableEnable %s)",
2950 RSSystemProperties::GetPropertyDrawableEnable() ? "TRUE" : "FALSE");
2951 std::unordered_map<NodeId, std::shared_ptr<RSRenderNode>> nodesThatNeedsRegenerateChildren;
2952 for (const auto& [root, nodeSet] : context_->activeNodesInRoot_) {
2953 for (const auto& [id, nodePtr] : nodeSet) {
2954 auto node = nodePtr.lock();
2955 if (node == nullptr) {
2956 continue;
2957 }
2958 if (!node->isFullChildrenListValid_ || !node->isChildrenSorted_) {
2959 nodesThatNeedsRegenerateChildren.emplace(node->id_, node);
2960 }
2961 // apply modifiers, if z-order not changed, skip
2962 if (!node->ApplyModifiers()) {
2963 continue;
2964 }
2965 if (auto parent = node->GetParent().lock()) {
2966 parent->isChildrenSorted_ = false;
2967 nodesThatNeedsRegenerateChildren.emplace(parent->id_, parent);
2968 }
2969 }
2970 }
2971 // Update the full children list of the nodes that need it
2972 nodesThatNeedsRegenerateChildren.emplace(0, context_->globalRootRenderNode_);
2973 for (auto& [id, node] : nodesThatNeedsRegenerateChildren) {
2974 node->UpdateFullChildrenListIfNeeded();
2975 }
2976 }
2977
ResetHardwareEnabledState()2978 void RSMainThread::ResetHardwareEnabledState()
2979 {
2980 isHardwareForcedDisabled_ = !RSSystemProperties::GetHardwareComposerEnabled();
2981 doDirectComposition_ = !isHardwareForcedDisabled_;
2982 isHardwareEnabledBufferUpdated_ = false;
2983 hardwareEnabledNodes_.clear();
2984 selfDrawingNodes_.clear();
2985 }
2986
GetSelfDrawingNodes() const2987 const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& RSMainThread::GetSelfDrawingNodes() const
2988 {
2989 return selfDrawingNodes_;
2990 }
2991
ShowWatermark(const std::shared_ptr<Media::PixelMap> & watermarkImg,bool isShow)2992 void RSMainThread::ShowWatermark(const std::shared_ptr<Media::PixelMap> &watermarkImg, bool isShow)
2993 {
2994 std::lock_guard<std::mutex> lock(watermarkMutex_);
2995 isShow_ = isShow;
2996 if (isShow_) {
2997 #ifndef USE_ROSEN_DRAWING
2998 watermarkImg_ = RSPixelMapUtil::ExtractSkImage(std::move(watermarkImg));
2999 #else
3000 watermarkImg_ = RSPixelMapUtil::ExtractDrawingImage(std::move(watermarkImg));
3001 #endif
3002 } else {
3003 watermarkImg_ = nullptr;
3004 }
3005 SetDirtyFlag();
3006 RequestNextVSync();
3007 }
3008
3009 #ifndef USE_ROSEN_DRAWING
GetWatermarkImg()3010 sk_sp<SkImage> RSMainThread::GetWatermarkImg()
3011 #else
3012 std::shared_ptr<Drawing::Image> RSMainThread::GetWatermarkImg()
3013 #endif
3014 {
3015 return watermarkImg_;
3016 }
3017
GetWatermarkFlag()3018 bool RSMainThread::GetWatermarkFlag()
3019 {
3020 return isShow_;
3021 }
3022
IsSingleDisplay()3023 bool RSMainThread::IsSingleDisplay()
3024 {
3025 const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3026 if (rootNode == nullptr) {
3027 RS_LOGE("RSMainThread::IsSingleDisplay GetGlobalRootRenderNode fail");
3028 return false;
3029 }
3030 return rootNode->GetChildrenCount() == 1;
3031 }
3032
UpdateRogSizeIfNeeded()3033 void RSMainThread::UpdateRogSizeIfNeeded()
3034 {
3035 if (!RSSystemProperties::IsPhoneType() || RSSystemProperties::IsFoldScreenFlag()) {
3036 return;
3037 }
3038 const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3039 if (!rootNode) {
3040 return;
3041 }
3042 auto child = rootNode->GetFirstChild();
3043 if (child != nullptr && child->IsInstanceOf<RSDisplayRenderNode>()) {
3044 auto displayNode = child->ReinterpretCastTo<RSDisplayRenderNode>();
3045 if (displayNode) {
3046 auto screenManager_ = CreateOrGetScreenManager();
3047 screenManager_->SetRogScreenResolution(
3048 displayNode->GetScreenId(), displayNode->GetRogWidth(), displayNode->GetRogHeight());
3049 }
3050 }
3051 }
3052
3053 const uint32_t UIFIRST_MINIMUM_NODE_NUMBER = 4; // minimum window number(4) for enabling UIFirst
3054 const uint32_t FOLD_DEVICE_SCREEN_NUMBER = 2; // alt device has two screens
3055
UpdateUIFirstSwitch()3056 void RSMainThread::UpdateUIFirstSwitch()
3057 {
3058 const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3059 if (!rootNode) {
3060 return;
3061 }
3062 auto firstChildren = rootNode->GetFirstChild();
3063 if (!firstChildren) {
3064 return;
3065 }
3066 auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(firstChildren);
3067 if (!displayNode) {
3068 return;
3069 }
3070 auto screenManager_ = CreateOrGetScreenManager();
3071 uint32_t actualScreensNum = screenManager_->GetActualScreensNum();
3072 if (deviceType_ == DeviceType::PHONE) {
3073 if (isFoldScreenDevice_) {
3074 isUiFirstOn_ = (RSSystemProperties::GetUIFirstEnabled() && actualScreensNum == FOLD_DEVICE_SCREEN_NUMBER);
3075 } else {
3076 isUiFirstOn_ = (RSSystemProperties::GetUIFirstEnabled() && actualScreensNum == 1);
3077 }
3078 return;
3079 }
3080 isUiFirstOn_ = false;
3081 if (IsSingleDisplay()) {
3082 uint32_t LeashWindowCount = 0;
3083 displayNode->CollectSurfaceForUIFirstSwitch(LeashWindowCount, UIFIRST_MINIMUM_NODE_NUMBER);
3084 isUiFirstOn_ = RSSystemProperties::GetUIFirstEnabled() && LeashWindowCount >= UIFIRST_MINIMUM_NODE_NUMBER;
3085 }
3086 }
3087
IsUIFirstOn() const3088 bool RSMainThread::IsUIFirstOn() const
3089 {
3090 return isUiFirstOn_;
3091 }
3092
ReleaseSurface()3093 void RSMainThread::ReleaseSurface()
3094 {
3095 std::lock_guard<std::mutex> lock(mutex_);
3096 while (tmpSurfaces_.size() > 0) {
3097 auto tmp = tmpSurfaces_.front();
3098 tmpSurfaces_.pop();
3099 tmp = nullptr;
3100 }
3101 }
3102
3103 #ifndef USE_ROSEN_DRAWING
AddToReleaseQueue(sk_sp<SkSurface> && surface)3104 void RSMainThread::AddToReleaseQueue(sk_sp<SkSurface>&& surface)
3105 #else
3106 void RSMainThread::AddToReleaseQueue(std::shared_ptr<Drawing::Surface>&& surface)
3107 #endif
3108 {
3109 std::lock_guard<std::mutex> lock(mutex_);
3110 tmpSurfaces_.push(std::move(surface));
3111 }
3112
GetAppMemoryInMB(float & cpuMemSize,float & gpuMemSize)3113 void RSMainThread::GetAppMemoryInMB(float& cpuMemSize, float& gpuMemSize)
3114 {
3115 PostSyncTask([&cpuMemSize, &gpuMemSize, this]() {
3116 #ifndef USE_ROSEN_DRAWING
3117 #ifdef NEW_RENDER_CONTEXT
3118 gpuMemSize = MemoryManager::GetAppGpuMemoryInMB(GetRenderEngine()->GetDrawingContext()->GetDrawingContext());
3119 #else
3120 gpuMemSize = MemoryManager::GetAppGpuMemoryInMB(GetRenderEngine()->GetRenderContext()->GetGrContext());
3121 #endif
3122 #else
3123 gpuMemSize = MemoryManager::GetAppGpuMemoryInMB(GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
3124 #endif
3125 cpuMemSize = MemoryTrack::Instance().GetAppMemorySizeInMB();
3126 });
3127 }
3128
SubscribeAppState()3129 void RSMainThread::SubscribeAppState()
3130 {
3131 PostTask(
3132 [this]() {
3133 rsAppStateListener_ = std::make_shared<RSAppStateListener>();
3134 if (Memory::MemMgrClient::GetInstance().SubscribeAppState(*rsAppStateListener_) != -1) {
3135 RS_LOGD("Subscribe MemMgr Success");
3136 subscribeFailCount_ = 0;
3137 return;
3138 } else {
3139 RS_LOGE("Subscribe Failed, try again");
3140 subscribeFailCount_++;
3141 if (subscribeFailCount_ < 10) { // The maximum number of failures is 10
3142 SubscribeAppState();
3143 } else {
3144 RS_LOGE("Subscribe Failed 10 times, exiting");
3145 }
3146 }
3147 },
3148 MEM_MGR, WAIT_FOR_MEM_MGR_SERVICE);
3149 }
3150
HandleOnTrim(Memory::SystemMemoryLevel level)3151 void RSMainThread::HandleOnTrim(Memory::SystemMemoryLevel level)
3152 {
3153 if (handler_) {
3154 handler_->PostTask(
3155 [level, this]() {
3156 RS_LOGD("Enter level:%{public}d, OnTrim Success", level);
3157 RS_TRACE_NAME_FMT("System is low memory, HandleOnTrim Enter level:%d", level);
3158 switch (level) {
3159 case Memory::SystemMemoryLevel::MEMORY_LEVEL_CRITICAL:
3160 ClearMemoryCache(ClearMemoryMoment::LOW_MEMORY, true);
3161 break;
3162 case Memory::SystemMemoryLevel::MEMORY_LEVEL_LOW:
3163 case Memory::SystemMemoryLevel::MEMORY_LEVEL_MODERATE:
3164 case Memory::SystemMemoryLevel::MEMORY_LEVEL_PURGEABLE:
3165 break;
3166 default:
3167 break;
3168 }
3169 },
3170 AppExecFwk::EventQueue::Priority::IDLE);
3171 }
3172 }
3173
3174 } // namespace Rosen
3175 } // namespace OHOS
3176