• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #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