• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 
16 #define EGL_EGLEXT_PROTOTYPES
17 
18 #include "pipeline/rs_main_thread.h"
19 
20 #include <algorithm>
21 #include <cstdint>
22 #include <list>
23 #include <malloc.h>
24 #include <securec.h>
25 #include <stdint.h>
26 #include <string>
27 #include <unistd.h>
28 
29 #include "benchmarks/file_utils.h"
30 #include "delegate/rs_functional_delegate.h"
31 #include "hgm_core.h"
32 #include "hgm_energy_consumption_policy.h"
33 #include "hgm_frame_rate_manager.h"
34 #include "include/core/SkGraphics.h"
35 #include "include/gpu/GrDirectContext.h"
36 #include "mem_mgr_client.h"
37 #include "render_frame_trace.h"
38 #include "rs_frame_report.h"
39 #include "rs_profiler.h"
40 #include "rs_trace.h"
41 #include "scene_board_judgement.h"
42 #include "vsync_iconnection_token.h"
43 #include "xcollie/watchdog.h"
44 
45 #include "animation/rs_animation_fraction.h"
46 #include "command/rs_animation_command.h"
47 #include "command/rs_message_processor.h"
48 #include "command/rs_node_command.h"
49 #include "common/rs_background_thread.h"
50 #include "common/rs_common_def.h"
51 #include "common/rs_optional_trace.h"
52 #include "drawable/rs_canvas_drawing_render_node_drawable.h"
53 #include "info_collection/rs_gpu_dirty_region_collection.h"
54 #include "luminance/rs_luminance_control.h"
55 #include "memory/rs_memory_graphic.h"
56 #include "memory/rs_memory_manager.h"
57 #include "memory/rs_memory_track.h"
58 #include "metadata_helper.h"
59 #include "params/rs_surface_render_params.h"
60 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
61 #include "pipeline/round_corner_display/rs_rcd_render_manager.h"
62 #include "pipeline/round_corner_display/rs_round_corner_display.h"
63 #include "pipeline/rs_base_render_node.h"
64 #include "pipeline/rs_base_render_util.h"
65 #include "pipeline/rs_canvas_drawing_render_node.h"
66 #include "pipeline/rs_divided_render_util.h"
67 #include "pipeline/rs_hardware_thread.h"
68 #include "pipeline/rs_occlusion_config.h"
69 #include "pipeline/rs_processor_factory.h"
70 #include "pipeline/rs_render_engine.h"
71 #include "pipeline/rs_render_service_visitor.h"
72 #include "pipeline/rs_root_render_node.h"
73 #include "pipeline/rs_surface_buffer_callback_manager.h"
74 #include "pipeline/rs_surface_render_node.h"
75 #include "pipeline/rs_task_dispatcher.h"
76 #include "pipeline/rs_ui_capture_task_parallel.h"
77 #include "pipeline/rs_uni_render_engine.h"
78 #include "pipeline/rs_uni_render_thread.h"
79 #include "pipeline/rs_uni_render_util.h"
80 #include "pipeline/rs_uni_render_visitor.h"
81 #include "pipeline/rs_unmarshal_thread.h"
82 #include "pipeline/rs_render_node_gc.h"
83 #include "pipeline/rs_uifirst_manager.h"
84 #include "pipeline/sk_resource_manager.h"
85 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
86 #include "pipeline/pointer_render/rs_pointer_render_manager.h"
87 #endif
88 #include "platform/common/rs_innovation.h"
89 #include "platform/common/rs_log.h"
90 #include "platform/common/rs_system_properties.h"
91 #include "platform/drawing/rs_vsync_client.h"
92 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
93 #include "platform/ohos/rs_jank_stats.h"
94 #include "property/rs_point_light_manager.h"
95 #include "property/rs_properties_painter.h"
96 #include "property/rs_property_trace.h"
97 #include "render/rs_image_cache.h"
98 #include "render/rs_pixel_map_util.h"
99 #include "render/rs_typeface_cache.h"
100 #include "screen_manager/rs_screen_manager.h"
101 #include "transaction/rs_transaction_proxy.h"
102 
103 #ifdef RS_ENABLE_GL
104 #include "GLES3/gl3.h"
105 #include "EGL/egl.h"
106 #include "EGL/eglext.h"
107 #endif
108 
109 #ifdef RS_ENABLE_PARALLEL_UPLOAD
110 #include "rs_upload_resource_thread.h"
111 #endif
112 
113 #ifdef NEW_RENDER_CONTEXT
114 #include "render_context/memory_handler.h"
115 #endif
116 
117 #if defined(ACCESSIBILITY_ENABLE)
118 #include "accessibility_config.h"
119 #endif
120 
121 #ifdef SOC_PERF_ENABLE
122 #include "socperf_client.h"
123 #endif
124 
125 #if defined(RS_ENABLE_CHIPSET_VSYNC)
126 #include "chipset_vsync_impl.h"
127 #endif
128 #ifdef RES_SCHED_ENABLE
129 #include "system_ability_definition.h"
130 #include "if_system_ability_manager.h"
131 #include <iservice_registry.h>
132 #endif
133 
134 using namespace FRAME_TRACE;
135 static const std::string RS_INTERVAL_NAME = "renderservice";
136 
137 #if defined(ACCESSIBILITY_ENABLE)
138 using namespace OHOS::AccessibilityConfig;
139 #endif
140 
141 namespace OHOS {
142 namespace Rosen {
143 namespace {
144 constexpr uint32_t REQUEST_VSYNC_NUMBER_LIMIT = 10;
145 constexpr uint64_t REFRESH_PERIOD = 16666667;
146 constexpr int32_t PERF_MULTI_WINDOW_REQUESTED_CODE = 10026;
147 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
148 constexpr uint64_t PERF_PERIOD = 250000000;
149 constexpr uint64_t CLEAN_CACHE_FREQ = 60;
150 constexpr uint64_t SKIP_COMMAND_FREQ_LIMIT = 30;
151 constexpr uint64_t PERF_PERIOD_BLUR = 1000000000;
152 constexpr uint64_t PERF_PERIOD_BLUR_TIMEOUT = 80000000;
153 constexpr uint64_t MAX_DYNAMIC_STATUS_TIME = 5000000000;
154 constexpr uint64_t MAX_SYSTEM_SCENE_STATUS_TIME = 800000000;
155 constexpr uint64_t PERF_PERIOD_MULTI_WINDOW = 80000000;
156 constexpr uint32_t MULTI_WINDOW_PERF_START_NUM = 2;
157 constexpr uint32_t MULTI_WINDOW_PERF_END_NUM = 4;
158 constexpr uint32_t TIME_OF_EIGHT_FRAMES = 8000;
159 constexpr uint32_t TIME_OF_THE_FRAMES = 1000;
160 constexpr uint32_t WAIT_FOR_RELEASED_BUFFER_TIMEOUT = 3000;
161 constexpr uint32_t WAIT_FOR_HARDWARE_THREAD_TASK_TIMEOUT = 3000;
162 constexpr uint32_t WAIT_FOR_SURFACE_CAPTURE_PROCESS_TIMEOUT = 1000;
163 constexpr uint32_t WATCHDOG_TIMEVAL = 5000;
164 constexpr uint32_t HARDWARE_THREAD_TASK_NUM = 2;
165 constexpr int32_t SIMI_VISIBLE_RATE = 2;
166 constexpr int32_t DEFAULT_RATE = 1;
167 constexpr int32_t INVISBLE_WINDOW_RATE = 10;
168 constexpr int32_t MAX_CAPTURE_COUNT = 5;
169 constexpr int32_t SYSTEM_ANIMATED_SCENES_RATE = 2;
170 constexpr uint32_t WAIT_FOR_MEM_MGR_SERVICE = 100;
171 constexpr uint32_t DELAY_TIME_FOR_ACE_BOUNDARY_UPDATE = 100; // ms
172 constexpr uint32_t CAL_NODE_PREFERRED_FPS_LIMIT = 50;
173 constexpr uint32_t EVENT_SET_HARDWARE_UTIL = 100004;
174 constexpr float DEFAULT_HDR_RATIO = 1.0f;
175 constexpr float REFERENCE_WHITE = 203.0f;
176 constexpr float CAMERA_WHITE_MIN = 500.0f;
177 constexpr float CAMERA_WHITE_MAX = 510.0f;
178 constexpr float CAMERA_HDR_RATIO = 2.5f;
179 constexpr float HDR_WHITE = 1000.0f;
180 constexpr float DEFAULT_SCALER = HDR_WHITE / REFERENCE_WHITE;
181 constexpr float GAMMA2_2 = 2.2f;
182 constexpr const char* WALLPAPER_VIEW = "WallpaperView";
183 constexpr const char* CLEAR_GPU_CACHE = "ClearGpuCache";
184 constexpr const char* MEM_MGR = "MemMgr";
185 constexpr const char* DESKTOP_NAME_FOR_ROTATION = "SCBDesktop";
186 const std::string PERF_FOR_BLUR_IF_NEEDED_TASK_NAME = "PerfForBlurIfNeeded";
187 constexpr const char* CAPTURE_WINDOW_NAME = "CapsuleWindow";
188 constexpr const char* HIDE_NOTCH_STATUS = "persist.sys.graphic.hideNotch.status";
189 constexpr const char* DEFAULT_SURFACE_NODE_NAME = "DefaultSurfaceNodeName";
190 #ifdef RS_ENABLE_GL
191 constexpr size_t DEFAULT_SKIA_CACHE_SIZE        = 96 * (1 << 20);
192 constexpr int DEFAULT_SKIA_CACHE_COUNT          = 2 * (1 << 12);
193 #endif
194 #if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
195 constexpr const char* MEM_GPU_TYPE = "gpu";
196 #endif
197 const std::map<int, int32_t> BLUR_CNT_TO_BLUR_CODE {
198     { 1, 10021 },
199     { 2, 10022 },
200     { 3, 10023 },
201 };
202 
Compare(const std::unique_ptr<RSTransactionData> & data1,const std::unique_ptr<RSTransactionData> & data2)203 bool Compare(const std::unique_ptr<RSTransactionData>& data1, const std::unique_ptr<RSTransactionData>& data2)
204 {
205     if (!data1 || !data2) {
206         RS_LOGW("Compare RSTransactionData: nullptr!");
207         return true;
208     }
209     return data1->GetIndex() < data2->GetIndex();
210 }
211 
InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>> & source,std::vector<std::unique_ptr<RSTransactionData>> & target)212 void InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>>& source,
213     std::vector<std::unique_ptr<RSTransactionData>>& target)
214 {
215     target.insert(target.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.end()));
216     source.clear();
217 }
218 
PerfRequest(int32_t perfRequestCode,bool onOffTag)219 void PerfRequest(int32_t perfRequestCode, bool onOffTag)
220 {
221 #ifdef SOC_PERF_ENABLE
222     OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(perfRequestCode, onOffTag, "");
223     RS_LOGD("RSMainThread::soc perf info [%{public}d %{public}d]", perfRequestCode, onOffTag);
224 #endif
225 }
226 
DoScreenRcdTask(std::shared_ptr<RSProcessor> & processor,std::unique_ptr<RcdInfo> & rcdInfo,const ScreenInfo & screenInfo)227 void DoScreenRcdTask(std::shared_ptr<RSProcessor>& processor, std::unique_ptr<RcdInfo>& rcdInfo,
228     const ScreenInfo& screenInfo)
229 {
230     if (screenInfo.state != ScreenState::HDI_OUTPUT_ENABLE) {
231         RS_LOGD("DoScreenRcdTask is not at HDI_OUPUT mode");
232         return;
233     }
234     if (RSSingleton<RoundCornerDisplay>::GetInstance().GetRcdEnable()) {
235         RSSingleton<RoundCornerDisplay>::GetInstance().RunHardwareTask(
236             [&processor, &rcdInfo]() {
237                 auto hardInfo = RSSingleton<RoundCornerDisplay>::GetInstance().GetHardwareInfo();
238                 rcdInfo->processInfo = {processor, hardInfo.topLayer, hardInfo.bottomLayer,
239                     hardInfo.resourceChanged};
240                 RSRcdRenderManager::GetInstance().DoProcessRenderMainThreadTask(rcdInfo->processInfo);
241             }
242         );
243     }
244 }
245 
CalScaler(const float & maxContentLightLevel)246 float CalScaler(const float& maxContentLightLevel)
247 {
248     if (ROSEN_EQ(maxContentLightLevel, REFERENCE_WHITE)) {
249         return DEFAULT_HDR_RATIO;
250     } else if (ROSEN_GE(maxContentLightLevel, CAMERA_WHITE_MIN) && ROSEN_LE(maxContentLightLevel, CAMERA_WHITE_MAX)) {
251         return CAMERA_HDR_RATIO;
252     } else if (ROSEN_LE(maxContentLightLevel, HDR_WHITE)) {
253         return HDR_WHITE / REFERENCE_WHITE;
254     } else {
255         return maxContentLightLevel / REFERENCE_WHITE;
256     }
257 }
258 
UpdateSurfaceNodeNit(const sptr<SurfaceBuffer> & surfaceBuffer,RSSurfaceRenderNode & surfaceNode,bool isHdrSurface)259 void UpdateSurfaceNodeNit(const sptr<SurfaceBuffer>& surfaceBuffer, RSSurfaceRenderNode& surfaceNode, bool isHdrSurface)
260 {
261     std::shared_ptr<RSDisplayRenderNode> ancestor = nullptr;
262     auto displayLock = surfaceNode.GetAncestorDisplayNode().lock();
263     if (displayLock != nullptr) {
264         ancestor = displayLock->ReinterpretCastTo<RSDisplayRenderNode>();
265     }
266     if (ancestor == nullptr) {
267         RS_LOGD("RSMainThread UpdateSurfaceNodeNit GetAncestorDisplayNode() return nullptr");
268         return;
269     }
270     auto screenId = ancestor->GetScreenId();
271 
272     if (!isHdrSurface) {
273         surfaceNode.SetBrightnessRatio(RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0));
274         return;
275     }
276 
277     using namespace HDI::Display::Graphic::Common::V1_0;
278     std::vector<uint8_t> hdrStaticMetadataVec;
279     if (MetadataHelper::GetHDRStaticMetadata(surfaceBuffer, hdrStaticMetadataVec) != GSERROR_OK) {
280         RS_LOGE("MetadataHelper GetHDRStaticMetadata failed");
281         return;
282     }
283     float scaler = DEFAULT_SCALER;
284     if (hdrStaticMetadataVec.size() != sizeof(HdrStaticMetadata) || hdrStaticMetadataVec.data() == nullptr) {
285         RS_LOGD("hdrStaticMetadataVec is invalid");
286     } else {
287         const auto& data = *reinterpret_cast<HdrStaticMetadata*>(hdrStaticMetadataVec.data());
288         scaler = CalScaler(data.cta861.maxContentLightLevel);
289     }
290 
291     auto& rsLuminance = RSLuminanceControl::Get();
292     float sdrNits = rsLuminance.GetSdrDisplayNits(screenId);
293     float displayNits = rsLuminance.GetDisplayNits(screenId);
294 
295     float layerNits = std::clamp(sdrNits * scaler, sdrNits, displayNits);
296     surfaceNode.SetDisplayNit(layerNits);
297     surfaceNode.SetSdrNit(sdrNits);
298     if (ROSEN_LNE(displayNits, 0.0f)) {
299         surfaceNode.SetBrightnessRatio(DEFAULT_HDR_RATIO);
300     } else {
301         surfaceNode.SetBrightnessRatio(std::pow(layerNits / displayNits, 1.0f / GAMMA2_2)); // gamma 2.2
302     }
303 }
304 
305 std::string g_dumpStr = "";
306 std::mutex g_dumpMutex;
307 std::condition_variable g_dumpCond_;
308 }
309 
310 #if defined(ACCESSIBILITY_ENABLE)
311 class AccessibilityObserver : public AccessibilityConfigObserver {
312 public:
313     AccessibilityObserver() = default;
OnConfigChanged(const CONFIG_ID id,const ConfigValue & value)314     void OnConfigChanged(const CONFIG_ID id, const ConfigValue &value) override
315     {
316         ColorFilterMode mode = ColorFilterMode::COLOR_FILTER_END;
317         if (id == CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER) {
318             RS_LOGI("RSAccessibility DALTONIZATION_COLOR_FILTER: %{public}d",
319                 static_cast<int>(value.daltonizationColorFilter));
320             switch (value.daltonizationColorFilter) {
321                 case Protanomaly:
322                     mode = ColorFilterMode::DALTONIZATION_PROTANOMALY_MODE;
323                     break;
324                 case Deuteranomaly:
325                     mode = ColorFilterMode::DALTONIZATION_DEUTERANOMALY_MODE;
326                     break;
327                 case Tritanomaly:
328                     mode = ColorFilterMode::DALTONIZATION_TRITANOMALY_MODE;
329                     break;
330                 case Normal:
331                     mode = ColorFilterMode::DALTONIZATION_NORMAL_MODE;
332                     break;
333                 default:
334                     break;
335             }
336             RSBaseRenderEngine::SetColorFilterMode(mode);
337         } else if (id == CONFIG_ID::CONFIG_INVERT_COLOR) {
338             RS_LOGI("RSAccessibility INVERT_COLOR: %{public}d", static_cast<int>(value.invertColor));
339             mode = value.invertColor ? ColorFilterMode::INVERT_COLOR_ENABLE_MODE :
340                                         ColorFilterMode::INVERT_COLOR_DISABLE_MODE;
341             RSBaseRenderEngine::SetColorFilterMode(mode);
342         } else if (id == CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT) {
343             RS_LOGI("RSAccessibility HIGH_CONTRAST_TEXT: %{public}d", static_cast<int>(value.highContrastText));
344             RSBaseRenderEngine::SetHighContrast(value.highContrastText);
345         } else {
346             RS_LOGW("RSAccessibility configId: %{public}d is not supported yet.", id);
347         }
348         RSMainThread::Instance()->PostTask([]() {
349             RSMainThread::Instance()->SetAccessibilityConfigChanged();
350             RSMainThread::Instance()->RequestNextVSync();
351         });
352     }
353 };
354 #endif
WaitUntilUploadTextureTaskFinished(bool isUniRender)355 static inline void WaitUntilUploadTextureTaskFinished(bool isUniRender)
356 {
357 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_PARALLEL_UPLOAD)
358 #if defined(NEW_SKIA) && defined(RS_ENABLE_UNI_RENDER)
359     if (isUniRender) {
360         RSUploadResourceThread::Instance().OnProcessBegin();
361     }
362     return;
363 #endif
364 #endif
365 }
366 
CheckIsHdrSurface(const RSSurfaceRenderNode & surfaceNode)367 bool RSMainThread::CheckIsHdrSurface(const RSSurfaceRenderNode& surfaceNode)
368 {
369     if (!surfaceNode.IsOnTheTree()) {
370         return false;
371     }
372     const auto& surfaceBuffer = surfaceNode.GetRSSurfaceHandler()->GetBuffer();
373     if (surfaceBuffer == nullptr) {
374         return false;
375     }
376     if (surfaceBuffer->GetFormat() != GRAPHIC_PIXEL_FMT_YCBCR_P010 &&
377         surfaceBuffer->GetFormat() != GRAPHIC_PIXEL_FMT_YCRCB_P010) {
378         return false;
379     }
380     using namespace HDI::Display::Graphic::Common::V1_0;
381     CM_ColorSpaceInfo colorSpaceInfo;
382     if (MetadataHelper::GetColorSpaceInfo(surfaceBuffer, colorSpaceInfo) == GSERROR_OK) {
383         if (colorSpaceInfo.transfunc == TRANSFUNC_PQ || colorSpaceInfo.transfunc == TRANSFUNC_HLG) {
384             return true;
385         }
386     }
387     return false;
388 }
389 
Instance()390 RSMainThread* RSMainThread::Instance()
391 {
392     static RSMainThread instance;
393     RSAnimationFraction::Init();
394     return &instance;
395 }
396 
RSMainThread()397 RSMainThread::RSMainThread() : mainThreadId_(std::this_thread::get_id()),
398     rsParallelType_(RSSystemParameters::GetRsParallelType())
399 {
400     context_ = std::make_shared<RSContext>();
401     context_->Initialize();
402 }
403 
~RSMainThread()404 RSMainThread::~RSMainThread() noexcept
405 {
406     RSNodeCommandHelper::SetCommitDumpNodeTreeProcessor(nullptr);
407     RemoveRSEventDetector();
408     RSInnovation::CloseInnovationSo();
409     if (rsAppStateListener_) {
410         Memory::MemMgrClient::GetInstance().UnsubscribeAppState(*rsAppStateListener_);
411     }
412 }
413 
DvsyncCheckRequestNextVsync()414 void RSMainThread::DvsyncCheckRequestNextVsync()
415 {
416     bool needAnimate = false;
417     if (needRequestNextVsyncAnimate_) {
418         rsVSyncDistributor_->MarkRSAnimate();
419         needAnimate = true;
420     } else {
421         rsVSyncDistributor_->UnmarkRSAnimate();
422     }
423     if (needAnimate || rsVSyncDistributor_->HasPendingUIRNV()) {
424         RequestNextVSync("animate", timestamp_);
425     }
426 }
427 
Init()428 void RSMainThread::Init()
429 {
430     mainLoop_ = [&]() {
431         RS_PROFILER_ON_FRAME_BEGIN();
432         if (isUniRender_ && !renderThreadParams_) {
433             // fill the params, and sync to render thread later
434             renderThreadParams_ = std::make_unique<RSRenderThreadParams>();
435         }
436         RenderFrameStart(timestamp_);
437         RSRenderNodeGC::Instance().SetGCTaskEnable(true);
438 #if defined(RS_ENABLE_UNI_RENDER)
439         WaitUntilSurfaceCapProcFinished();
440 #endif
441         PerfMultiWindow();
442         SetRSEventDetectorLoopStartTag();
443         ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSMainThread::DoComposition: " + std::to_string(curTime_));
444         RS_LOGI("DoComposition start time:%{public}" PRIu64, curTime_);
445         ConsumeAndUpdateAllNodes();
446         WaitUntilUnmarshallingTaskFinished();
447         ProcessCommand();
448         Animate(timestamp_);
449         DvsyncCheckRequestNextVsync();
450         CollectInfoForHardwareComposer();
451         RSUifirstManager::Instance().PrepareCurrentFrameEvent();
452         ProcessHgmFrameRate(timestamp_);
453         RS_PROFILER_ON_RENDER_BEGIN();
454         // may mark rsnotrendering
455         Render(); // now render is traverse tree to prepare
456         RS_PROFILER_ON_RENDER_END();
457         OnUniRenderDraw();
458         UIExtensionNodesTraverseAndCallback();
459         InformHgmNodeInfo();
460         if (!isUniRender_) {
461             ReleaseAllNodesBuffer();
462         }
463         SendCommands();
464         {
465             std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
466             context_->activeNodesInRoot_.clear();
467         }
468         ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
469         SetRSEventDetectorLoopFinishTag();
470         rsEventManager_.UpdateParam();
471         ResetAnimateNodeFlag();
472         SKResourceManager::Instance().ReleaseResource();
473         // release batched node from render tree (enabled by default, can be disabled in RSSystemProperties)
474         RSRenderNodeGC::Instance().ReleaseFromTree();
475         // release node memory
476         RSRenderNodeGC::Instance().ReleaseNodeMemory();
477         if (!isUniRender_) {
478             RSRenderNodeGC::Instance().ReleaseDrawableMemory();
479         }
480         if (!RSImageCache::Instance().CheckUniqueIdIsEmpty()) {
481             static std::function<void()> task = []() -> void {
482                 RSImageCache::Instance().ReleaseUniqueIdList();
483             };
484             RSBackgroundThread::Instance().PostTask(task);
485         }
486 #ifdef RS_ENABLE_PARALLEL_UPLOAD
487         RSUploadResourceThread::Instance().OnRenderEnd();
488 #endif
489         RSTypefaceCache::Instance().HandleDelayDestroyQueue();
490 #if defined(RS_ENABLE_CHIPSET_VSYNC)
491         ConnectChipsetVsyncSer();
492 #endif
493         RS_LOGI("DoComposition end time:%{public}" PRIu64, curTime_);
494         RS_PROFILER_ON_FRAME_END();
495     };
496     static std::function<void (std::shared_ptr<Drawing::Image> image)> holdDrawingImagefunc =
497         [] (std::shared_ptr<Drawing::Image> image) -> void {
498             if (image) {
499                 SKResourceManager::Instance().HoldResource(image);
500             }
501         };
502     Drawing::DrawOpItem::SetBaseCallback(holdDrawingImagefunc);
503     static std::function<std::shared_ptr<Drawing::Typeface> (uint64_t)> customTypefaceQueryfunc =
504         [] (uint64_t globalUniqueId) -> std::shared_ptr<Drawing::Typeface> {
505             return RSTypefaceCache::Instance().GetDrawingTypefaceCache(globalUniqueId);
506         };
507     Drawing::DrawOpItem::SetTypefaceQueryCallBack(customTypefaceQueryfunc);
508     {
509         using namespace std::placeholders;
510         RSNodeCommandHelper::SetCommitDumpNodeTreeProcessor(
511             std::bind(&RSMainThread::OnCommitDumpClientNodeTree, this, _1, _2, _3, _4));
512     }
513 
514     isUniRender_ = RSUniRenderJudgement::IsUniRender();
515     SetDeviceType();
516     qosPidCal_ = deviceType_ == DeviceType::PC;
517     isFoldScreenDevice_ = RSSystemProperties::IsFoldScreenFlag();
518     auto taskDispatchFunc = [](const RSTaskDispatcher::RSTask& task, bool isSyncTask = false) {
519         RSMainThread::Instance()->PostTask(task);
520     };
521     context_->SetTaskRunner(taskDispatchFunc);
522     if (isUniRender_) {
523         auto rtTaskDispatchFunc = [](const RSTaskDispatcher::RSTask& task) {
524             RSUniRenderThread::Instance().PostRTTask(task);
525         };
526         context_->SetRTTaskRunner(rtTaskDispatchFunc);
527     }
528     context_->SetVsyncRequestFunc([]() {
529         RSMainThread::Instance()->RequestNextVSync();
530         RSMainThread::Instance()->SetDirtyFlag();
531     });
532     RSTaskDispatcher::GetInstance().RegisterTaskDispatchFunc(gettid(), taskDispatchFunc);
533     RsFrameReport::GetInstance().Init();
534     RSSystemProperties::WatchSystemProperty(HIDE_NOTCH_STATUS, OnHideNotchStatusCallback, nullptr);
535     if (isUniRender_) {
536         unmarshalBarrierTask_ = [this]() {
537             auto cachedTransactionData = RSUnmarshalThread::Instance().GetCachedTransactionData();
538             MergeToEffectiveTransactionDataMap(cachedTransactionData);
539             {
540                 std::lock_guard<std::mutex> lock(unmarshalMutex_);
541                 ++unmarshalFinishedCount_;
542             }
543             unmarshalTaskCond_.notify_all();
544         };
545         RSUnmarshalThread::Instance().Start();
546     }
547     Drawing::DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback(
548         RSSurfaceBufferCallbackManager::Instance().GetSurfaceBufferOpItemCallback());
549 
550     RSSurfaceBufferCallbackManager::Instance().SetRunPolicy([](auto task) {
551         RSHardwareThread::Instance().PostTask(task);
552     });
553 
554     runner_ = AppExecFwk::EventRunner::Create(false);
555     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
556     int ret = HiviewDFX::Watchdog::GetInstance().AddThread("RenderService", handler_, WATCHDOG_TIMEVAL);
557     if (ret != 0) {
558         RS_LOGW("Add watchdog thread failed");
559     }
560 #ifdef RES_SCHED_ENABLE
561     SubScribeSystemAbility();
562 #endif
563     InitRSEventDetector();
564     sptr<VSyncIConnectionToken> token = new IRemoteStub<VSyncIConnectionToken>();
565     sptr<VSyncConnection> conn = new VSyncConnection(rsVSyncDistributor_, "rs", token->AsObject());
566     rsFrameRateLinker_ = std::make_shared<RSRenderFrameRateLinker>();
567     conn->id_ = rsFrameRateLinker_->GetId();
568     rsVSyncDistributor_->AddConnection(conn);
569     receiver_ = std::make_shared<VSyncReceiver>(conn, token->AsObject(), handler_, "rs");
570     receiver_->Init();
571     if (!isUniRender_) {
572         renderEngine_ = std::make_shared<RSRenderEngine>();
573         renderEngine_->Init();
574     }
575     auto PostTaskProxy = [](RSTaskMessage::RSTask task, const std::string& name, int64_t delayTime,
576         AppExecFwk::EventQueue::Priority priority) {
577         RSMainThread::Instance()->PostTask(task, name, delayTime, priority);
578     };
579     RSRenderNodeGC::Instance().SetMainTask(PostTaskProxy);
580     auto GCNotifyTaskProxy = [](bool isEnable) {
581         RSRenderNodeGC::Instance().SetGCTaskEnable(isEnable);
582     };
583     conn->SetGCNotifyTask(GCNotifyTaskProxy);
584 #ifdef RS_ENABLE_GL
585     /* move to render thread ? */
586     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
587         int cacheLimitsTimes = 3;
588 #ifdef NEW_RENDER_CONTEXT
589         auto gpuContext = isUniRender_? uniRenderEngine_->GetDrawingContext()->GetDrawingContext() :
590             renderEngine_->GetDrawingContext()->GetDrawingContext();
591 #else
592         auto gpuContext = isUniRender_? GetRenderEngine()->GetRenderContext()->GetDrGPUContext() :
593             renderEngine_->GetRenderContext()->GetDrGPUContext();
594 #endif
595         if (gpuContext == nullptr) {
596             RS_LOGE("RSMainThread::Init gpuContext is nullptr!");
597             return;
598         }
599         int32_t maxResources = 0;
600         size_t maxResourcesSize = 0;
601         gpuContext->GetResourceCacheLimits(&maxResources, &maxResourcesSize);
602         if (maxResourcesSize > 0) {
603             gpuContext->SetResourceCacheLimits(cacheLimitsTimes * maxResources, cacheLimitsTimes *
604                 std::fmin(maxResourcesSize, DEFAULT_SKIA_CACHE_SIZE));
605         } else {
606             gpuContext->SetResourceCacheLimits(DEFAULT_SKIA_CACHE_COUNT, DEFAULT_SKIA_CACHE_SIZE);
607         }
608     }
609 #endif // RS_ENABLE_GL
610     RSInnovation::OpenInnovationSo();
611 #if defined(RS_ENABLE_UNI_RENDER)
612     /* move to render thread ? */
613     RSBackgroundThread::Instance().InitRenderContext(GetRenderEngine()->GetRenderContext().get());
614 #endif
615 
616     RSRcdRenderManager::InitInstance();
617 
618 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
619 #if defined (RS_ENABLE_VK)
620     RSPointerRenderManager::InitInstance(GetRenderEngine()->GetVkImageManager());
621 #endif
622 
623 #if defined (RS_ENABLE_GL) && defined (RS_ENABLE_EGLIMAGE)
624     RSPointerRenderManager::InitInstance(GetRenderEngine()->GetEglImageManager());
625 #endif
626 #endif
627 
628 #if defined(ROSEN_OHOS) && defined(RS_ENABLE_PARALLEL_UPLOAD)
629     if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
630 #if defined(NEW_SKIA) && defined(RS_ENABLE_UNI_RENDER)
631         RSUploadResourceThread::Instance().InitRenderContext(GetRenderEngine()->GetRenderContext().get());
632 #endif
633     }
634 #endif
635 
636 #if defined(ACCESSIBILITY_ENABLE)
637     accessibilityObserver_ = std::make_shared<AccessibilityObserver>();
638     auto &config = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
639     config.InitializeContext();
640     config.SubscribeConfigObserver(CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER, accessibilityObserver_);
641     config.SubscribeConfigObserver(CONFIG_ID::CONFIG_INVERT_COLOR, accessibilityObserver_);
642     if (isUniRender_) {
643         config.SubscribeConfigObserver(CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT, accessibilityObserver_);
644     }
645 #endif
646 
647     auto delegate = RSFunctionalDelegate::Create();
648     delegate->SetRepaintCallback([this]() {
649         bool isOverDrawEnabled = RSOverdrawController::GetInstance().IsEnabled();
650         PostTask([this, isOverDrawEnabled]() {
651             SetDirtyFlag();
652             isOverDrawEnabledOfCurFrame_ = isOverDrawEnabled;
653             RequestNextVSync("OverDrawUpdate");
654         });
655     });
656     RSOverdrawController::GetInstance().SetDelegate(delegate);
657 
658     frameRateMgr_ = OHOS::Rosen::HgmCore::Instance().GetFrameRateMgr();
659     if (frameRateMgr_ != nullptr) {
660         frameRateMgr_->SetForceUpdateCallback([this](bool idleTimerExpired, bool forceUpdate) {
661             RSMainThread::Instance()->PostTask([this, idleTimerExpired, forceUpdate]() {
662                 RS_TRACE_NAME_FMT("RSMainThread::TimerExpiredCallback Run idleTimerExpiredFlag: %s  forceUpdateFlag: %s",
663                     idleTimerExpired? "True":"False", forceUpdate? "True": "False");
664                 RSMainThread::Instance()->SetForceUpdateUniRenderFlag(forceUpdate);
665                 RSMainThread::Instance()->SetIdleTimerExpiredFlag(idleTimerExpired);
666                 RS_TRACE_NAME_FMT("DVSyncIsOn: %d", this->rsVSyncDistributor_->IsDVsyncOn());
667                 RSMainThread::Instance()->RequestNextVSync("ltpoForceUpdate");
668             });
669         });
670         frameRateMgr_->Init(rsVSyncController_, appVSyncController_, vsyncGenerator_);
671     }
672     SubscribeAppState();
673     PrintCurrentStatus();
674     RSLuminanceControl::Get().Init();
675     if (deviceType_ == DeviceType::PHONE || deviceType_ == DeviceType::TABLET) {
676         MemoryManager::InitMemoryLimit(GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
677     }
678 }
679 
RsEventParamDump(std::string & dumpString)680 void RSMainThread::RsEventParamDump(std::string& dumpString)
681 {
682     rsEventManager_.DumpAllEventParam(dumpString);
683 }
684 
RemoveRSEventDetector()685 void RSMainThread::RemoveRSEventDetector()
686 {
687     if (rsCompositionTimeoutDetector_ != nullptr) {
688         rsEventManager_.RemoveEvent(rsCompositionTimeoutDetector_->GetStringId());
689     }
690 }
691 
InitRSEventDetector()692 void RSMainThread::InitRSEventDetector()
693 {
694     // default Threshold value of Timeout Event: 100ms
695     rsCompositionTimeoutDetector_ = RSBaseEventDetector::CreateRSTimeOutDetector(100, "RS_COMPOSITION_TIMEOUT");
696     if (rsCompositionTimeoutDetector_ != nullptr) {
697         rsEventManager_.AddEvent(rsCompositionTimeoutDetector_, 60000); // report Internal 1min:60s:60000ms
698         RS_LOGD("InitRSEventDetector finish");
699     }
700 }
701 
SetDeviceType()702 void RSMainThread::SetDeviceType()
703 {
704     auto deviceTypeStr = system::GetParameter("const.product.devicetype", "pc");
705     if (deviceTypeStr == "pc" || deviceTypeStr == "2in1") {
706         deviceType_ = DeviceType::PC;
707     } else if (deviceTypeStr == "tablet") {
708         deviceType_ = DeviceType::TABLET;
709     } else if (deviceTypeStr == "phone") {
710         deviceType_ = DeviceType::PHONE;
711     } else {
712         deviceType_ = DeviceType::OTHERS;
713     }
714 }
715 
GetDeviceType() const716 DeviceType RSMainThread::GetDeviceType() const
717 {
718     return deviceType_;
719 }
720 
GetFocusNodeId() const721 uint64_t RSMainThread::GetFocusNodeId() const
722 {
723     return focusNodeId_;
724 }
725 
GetFocusLeashWindowId() const726 uint64_t RSMainThread::GetFocusLeashWindowId() const
727 {
728     return focusLeashWindowId_;
729 }
730 
SetFocusLeashWindowId()731 void RSMainThread::SetFocusLeashWindowId()
732 {
733     const auto& nodeMap = context_->GetNodeMap();
734     auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(focusNodeId_));
735     if (node != nullptr) {
736         auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node->GetParent().lock());
737         if (node->IsAppWindow() && parent && parent->IsLeashWindow()) {
738             focusLeashWindowId_ = parent->GetId();
739         }
740     }
741 }
742 
SetIsCachedSurfaceUpdated(bool isCachedSurfaceUpdated)743 void RSMainThread::SetIsCachedSurfaceUpdated(bool isCachedSurfaceUpdated)
744 {
745     isCachedSurfaceUpdated_ = isCachedSurfaceUpdated;
746 }
747 
SetRSEventDetectorLoopStartTag()748 void RSMainThread::SetRSEventDetectorLoopStartTag()
749 {
750     if (rsCompositionTimeoutDetector_ != nullptr) {
751         rsCompositionTimeoutDetector_->SetLoopStartTag();
752     }
753 }
754 
SetRSEventDetectorLoopFinishTag()755 void RSMainThread::SetRSEventDetectorLoopFinishTag()
756 {
757     if (rsCompositionTimeoutDetector_ != nullptr) {
758         if (isUniRender_) {
759             rsCompositionTimeoutDetector_->SetLoopFinishTag(
760                 focusAppPid_, focusAppUid_, focusAppBundleName_, focusAppAbilityName_);
761         } else {
762             std::string defaultFocusAppInfo = "";
763             rsCompositionTimeoutDetector_->SetLoopFinishTag(
764                 -1, -1, defaultFocusAppInfo, defaultFocusAppInfo);
765         }
766     }
767 }
768 
SetFocusAppInfo(int32_t pid,int32_t uid,const std::string & bundleName,const std::string & abilityName,uint64_t focusNodeId)769 void RSMainThread::SetFocusAppInfo(
770     int32_t pid, int32_t uid, const std::string& bundleName, const std::string& abilityName, uint64_t focusNodeId)
771 {
772     focusAppPid_ = pid;
773     focusAppUid_ = uid;
774     focusAppBundleName_ = bundleName;
775     focusAppAbilityName_ = abilityName;
776     UpdateFocusNodeId(focusNodeId);
777 }
778 
UpdateFocusNodeId(NodeId focusNodeId)779 void RSMainThread::UpdateFocusNodeId(NodeId focusNodeId)
780 {
781     if (focusNodeId_ == focusNodeId || focusNodeId == INVALID_NODEID) {
782         return;
783     }
784     UpdateNeedDrawFocusChange(focusNodeId_);
785     UpdateNeedDrawFocusChange(focusNodeId);
786     focusNodeId_ = focusNodeId;
787 }
788 
UpdateNeedDrawFocusChange(NodeId id)789 void RSMainThread::UpdateNeedDrawFocusChange(NodeId id)
790 {
791     const auto& nodeMap = context_->GetNodeMap();
792     auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(id));
793     // while nodeMap can't find node, return instantly
794     if (!node) {
795         return;
796     }
797     auto parentNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node->GetParent().lock());
798     // while node's parent isn't LEASH_WINDOW_NODE, itselt need SetNeedDrawFocusChange
799     if (!parentNode || parentNode->GetSurfaceNodeType() != RSSurfaceNodeType::LEASH_WINDOW_NODE) {
800         node->SetNeedDrawFocusChange(true);
801         return;
802     }
803     // while node's parent is LEASH_WINDOW_NODE, parent need SetNeedDrawFocusChange
804     parentNode->SetNeedDrawFocusChange(true);
805 }
806 
Start()807 void RSMainThread::Start()
808 {
809     if (runner_) {
810         runner_->Run();
811     }
812 }
813 
ProcessCommand()814 void RSMainThread::ProcessCommand()
815 {
816     RSUnmarshalThread::Instance().ClearTransactionDataStatistics();
817 
818     // To improve overall responsiveness, we make animations start on LAST frame instead of THIS frame.
819     // If last frame is too far away (earlier than 1 vsync from now), we use currentTimestamp_ - REFRESH_PERIOD as
820     // 'virtual' last frame timestamp.
821     if (timestamp_ - lastAnimateTimestamp_ > REFRESH_PERIOD) { // if last frame is earlier than 1 vsync from now
822         context_->currentTimestamp_ = timestamp_ - REFRESH_PERIOD;
823     } else {
824         context_->currentTimestamp_ = lastAnimateTimestamp_;
825     }
826     RS_PROFILER_ON_PROCESS_COMMAND();
827     if (isUniRender_) {
828         ProcessCommandForUniRender();
829     } else {
830         ProcessCommandForDividedRender();
831     }
832     switch(context_->purgeType_) {
833         case RSContext::PurgeType::GENTLY:
834             isUniRender_ ? RSUniRenderThread::Instance().ClearMemoryCache(context_->clearMoment_, false) :
835                 ClearMemoryCache(context_->clearMoment_, false);
836                 isNeedResetClearMemoryTask_ = true;
837             break;
838         case RSContext::PurgeType::STRONGLY:
839             isUniRender_ ? RSUniRenderThread::Instance().ClearMemoryCache(context_->clearMoment_, true) :
840                 ClearMemoryCache(context_->clearMoment_, true);
841                 isNeedResetClearMemoryTask_ = true;
842             break;
843         default:
844             break;
845     }
846     context_->purgeType_ = RSContext::PurgeType::NONE;
847     if (RsFrameReport::GetInstance().GetEnable()) {
848         RsFrameReport::GetInstance().AnimateStart();
849     }
850 }
851 
PrintCurrentStatus()852 void RSMainThread::PrintCurrentStatus()
853 {
854     std::string gpuType = "";
855     switch (OHOS::Rosen::RSSystemProperties::GetGpuApiType()) {
856         case OHOS::Rosen::GpuApiType::OPENGL:
857             gpuType = "opengl";
858             break;
859         case OHOS::Rosen::GpuApiType::VULKAN:
860             gpuType = "vulkan";
861             break;
862         case OHOS::Rosen::GpuApiType::DDGR:
863             gpuType = "ddgr";
864             break;
865         default:
866             break;
867     }
868     RS_LOGI("[Drawing] Version: Non-released");
869     RS_LOGE("RSMainThread::PrintCurrentStatus:  drawing is opened, gpu type is %{public}s", gpuType.c_str());
870 }
871 
SubScribeSystemAbility()872 void RSMainThread::SubScribeSystemAbility()
873 {
874     RS_LOGI("%{public}s", __func__);
875     sptr<ISystemAbilityManager> systemAbilityManager =
876         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
877     if (!systemAbilityManager) {
878         RS_LOGE("%{public}s failed to get system ability manager client", __func__);
879         return;
880     }
881     std::string threadName = "RSMainThread";
882     std::string strUid = std::to_string(getuid());
883     std::string strPid = std::to_string(getpid());
884     std::string strTid = std::to_string(gettid());
885 
886     saStatusChangeListener_ = new (std::nothrow)VSyncSystemAbilityListener(threadName, strUid, strPid, strTid);
887     if (saStatusChangeListener_ == nullptr) {
888         RS_LOGE("RSMainThread::SubScribeSystemAbility new VSyncSystemAbilityListener failed");
889         return;
890     }
891     int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, saStatusChangeListener_);
892     if (ret != ERR_OK) {
893         RS_LOGE("%{public}s subscribe system ability %{public}d failed.", __func__, RES_SCHED_SYS_ABILITY_ID);
894         saStatusChangeListener_ = nullptr;
895     }
896 }
897 
CacheCommands()898 void RSMainThread::CacheCommands()
899 {
900     RS_OPTIONAL_TRACE_FUNC();
901     for (auto& skipTransactionData : cachedSkipTransactionDataMap_) {
902         pid_t pid = skipTransactionData.first;
903         RS_TRACE_NAME("cacheCmd pid: " + std::to_string(pid));
904         auto& skipTransactionDataVec = skipTransactionData.second;
905         cachedTransactionDataMap_[pid].insert(cachedTransactionDataMap_[pid].begin(),
906             std::make_move_iterator(skipTransactionDataVec.begin()),
907             std::make_move_iterator(skipTransactionDataVec.end()));
908         skipTransactionDataVec.clear();
909     }
910 }
911 
CheckIfNodeIsBundle(std::shared_ptr<RSSurfaceRenderNode> node)912 void RSMainThread::CheckIfNodeIsBundle(std::shared_ptr<RSSurfaceRenderNode> node)
913 {
914     currentBundleName_ = node->GetBundleName();
915     if (node->GetName() == WALLPAPER_VIEW) {
916         noBundle_ = true;
917     }
918 }
919 
InformHgmNodeInfo()920 void RSMainThread::InformHgmNodeInfo()
921 {
922     auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
923     int32_t informResult = EXEC_SUCCESS;
924     if (currentBundleName_ != "") {
925         informResult = hgmCore.RefreshBundleName(currentBundleName_);
926     } else if (noBundle_) {
927         currentBundleName_ = "";
928         informResult = hgmCore.RefreshBundleName(currentBundleName_);
929         noBundle_ = false;
930     }
931     if (informResult != EXEC_SUCCESS) {
932         RS_LOGE("RSMainThread::InformHgmNodeInfo failed to refresh bundle name in hgm");
933     }
934 }
935 
GetCacheCmdSkippedNodes() const936 const std::unordered_map<NodeId, bool>& RSMainThread::GetCacheCmdSkippedNodes() const
937 {
938     return cacheCmdSkippedNodes_;
939 }
940 
CheckParallelSubThreadNodesStatus()941 bool RSMainThread::CheckParallelSubThreadNodesStatus()
942 {
943     RS_OPTIONAL_TRACE_FUNC();
944     cacheCmdSkippedInfo_.clear();
945     cacheCmdSkippedNodes_.clear();
946     if (subThreadNodes_.empty() &&
947         (deviceType_ != DeviceType::PC || (leashWindowCount_ > 0 && isUiFirstOn_ == false))) {
948         if (!isUniRender_) {
949             RSSubThreadManager::Instance()->ResetSubThreadGrContext(); // planning: move to prepare
950         }
951         return false;
952     }
953     for (auto& node : subThreadNodes_) {
954         if (node == nullptr) {
955             RS_LOGE("RSMainThread::CheckParallelSubThreadNodesStatus sunThreadNode is nullptr!");
956             continue;
957         }
958         if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
959             RS_TRACE_NAME("node:[ " + node->GetName() + "]");
960             pid_t pid = 0;
961             if (node->IsAppWindow()) {
962                 pid = ExtractPid(node->GetId());
963             } else if (node->IsLeashWindow()) {
964                 for (auto& child : *node->GetSortedChildren()) {
965                     auto surfaceNodePtr = child->ReinterpretCastTo<RSSurfaceRenderNode>();
966                     if (surfaceNodePtr && surfaceNodePtr->IsAppWindow()) {
967                         pid = ExtractPid(child->GetId());
968                         break;
969                     }
970                 }
971             }
972             cacheCmdSkippedNodes_[node->GetId()] = false;
973             if (pid == 0) {
974                 continue;
975             }
976             RS_LOGD("RSMainThread::CheckParallelSubThreadNodesStatus pid = %{public}s, node name: %{public}s,"
977                 "id: %{public}" PRIu64 "", std::to_string(pid).c_str(), node->GetName().c_str(), node->GetId());
978             auto it = cacheCmdSkippedInfo_.find(pid);
979             if (it == cacheCmdSkippedInfo_.end()) {
980                 cacheCmdSkippedInfo_.emplace(pid, std::make_pair(std::vector<NodeId>{node->GetId()}, false));
981             } else {
982                 it->second.first.push_back(node->GetId());
983             }
984             if (!node->HasAbilityComponent()) {
985                 continue;
986             }
987             for (auto& nodeId : node->GetAbilityNodeIds()) {
988                 pid_t abilityNodePid = ExtractPid(nodeId);
989                 it = cacheCmdSkippedInfo_.find(abilityNodePid);
990                 if (it == cacheCmdSkippedInfo_.end()) {
991                     cacheCmdSkippedInfo_.emplace(abilityNodePid,
992                         std::make_pair(std::vector<NodeId>{node->GetId()}, true));
993                 } else {
994                     it->second.first.push_back(node->GetId());
995                 }
996             }
997         }
998     }
999     if (!cacheCmdSkippedNodes_.empty()) {
1000         return true;
1001     }
1002     if (!isUiFirstOn_) {
1003         // clear subThreadNodes_ when UIFirst off and none of subThreadNodes_ is in the state of doing
1004         subThreadNodes_.clear();
1005     }
1006     return false;
1007 }
1008 
IsNeedSkip(NodeId instanceRootNodeId,pid_t pid)1009 bool RSMainThread::IsNeedSkip(NodeId instanceRootNodeId, pid_t pid)
1010 {
1011     return std::any_of(cacheCmdSkippedInfo_[pid].first.begin(), cacheCmdSkippedInfo_[pid].first.end(),
1012         [instanceRootNodeId](const auto& cacheCmdSkipNodeId) {
1013             return cacheCmdSkipNodeId == instanceRootNodeId;
1014         });
1015 }
1016 
SkipCommandByNodeId(std::vector<std::unique_ptr<RSTransactionData>> & transactionVec,pid_t pid)1017 void RSMainThread::SkipCommandByNodeId(std::vector<std::unique_ptr<RSTransactionData>>& transactionVec, pid_t pid)
1018 {
1019     if (cacheCmdSkippedInfo_.find(pid) == cacheCmdSkippedInfo_.end()) {
1020         return;
1021     }
1022     std::vector<std::unique_ptr<RSTransactionData>> skipTransactionVec;
1023     const auto& nodeMap = context_->GetNodeMap();
1024     for (auto& transactionData: transactionVec) {
1025         std::vector<std::tuple<NodeId, FollowType, std::unique_ptr<RSCommand>>> skipPayload;
1026         std::vector<size_t> skipPayloadIndexVec;
1027         auto& processPayload = transactionData->GetPayload();
1028         for (size_t index = 0; index < processPayload.size(); ++index) {
1029             auto& elem = processPayload[index];
1030             if (std::get<2>(elem) == nullptr) { // check elem is valid
1031                 continue;
1032             }
1033             NodeId nodeId = std::get<2>(elem)->GetNodeId();
1034             auto node = nodeMap.GetRenderNode(nodeId);
1035             if (node == nullptr) {
1036                 continue;
1037             }
1038             NodeId firstLevelNodeId = node->GetFirstLevelNodeId();
1039             if (IsNeedSkip(firstLevelNodeId, pid)) {
1040                 skipPayload.emplace_back(std::move(elem));
1041                 skipPayloadIndexVec.push_back(index);
1042             }
1043         }
1044         if (!skipPayload.empty()) {
1045             std::unique_ptr<RSTransactionData> skipTransactionData = std::make_unique<RSTransactionData>();
1046             skipTransactionData->SetTimestamp(transactionData->GetTimestamp());
1047             std::string ablityName = transactionData->GetAbilityName();
1048             skipTransactionData->SetAbilityName(ablityName);
1049             skipTransactionData->SetSendingPid(transactionData->GetSendingPid());
1050             skipTransactionData->SetIndex(transactionData->GetIndex());
1051             skipTransactionData->GetPayload() = std::move(skipPayload);
1052             skipTransactionData->SetIsCached(true);
1053             skipTransactionVec.emplace_back(std::move(skipTransactionData));
1054         }
1055         for (auto iter = skipPayloadIndexVec.rbegin(); iter != skipPayloadIndexVec.rend(); ++iter) {
1056             processPayload.erase(processPayload.begin() + *iter);
1057         }
1058     }
1059     if (!skipTransactionVec.empty()) {
1060         cachedSkipTransactionDataMap_[pid] = std::move(skipTransactionVec);
1061     }
1062 }
1063 
RequestNextVsyncForCachedCommand(std::string & transactionFlags,pid_t pid,uint64_t curIndex)1064 void RSMainThread::RequestNextVsyncForCachedCommand(std::string& transactionFlags, pid_t pid, uint64_t curIndex)
1065 {
1066 #ifdef ROSEN_EMULATOR
1067     transactionFlags += " cache [" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
1068     RequestNextVSync();
1069 #else
1070     transactionFlags += " cache (" + std::to_string(pid) + "," + std::to_string(curIndex) + ")";
1071     RS_TRACE_NAME("RSMainThread::CheckAndUpdateTransactionIndex Trigger NextVsync");
1072     if (rsVSyncDistributor_->IsUiDvsyncOn()) {
1073         RequestNextVSync("fromRsMainCommand", timestamp_);
1074     } else {
1075         RequestNextVSync();
1076     }
1077 #endif
1078 }
1079 
CheckAndUpdateTransactionIndex(std::shared_ptr<TransactionDataMap> & transactionDataEffective,std::string & transactionFlags)1080 void RSMainThread::CheckAndUpdateTransactionIndex(std::shared_ptr<TransactionDataMap>& transactionDataEffective,
1081     std::string& transactionFlags)
1082 {
1083     for (auto& rsTransactionElem: effectiveTransactionDataIndexMap_) {
1084         auto pid = rsTransactionElem.first;
1085         auto& lastIndex = rsTransactionElem.second.first;
1086         auto& transactionVec = rsTransactionElem.second.second;
1087         auto iter = transactionVec.begin();
1088         for (; iter != transactionVec.end(); ++iter) {
1089             if ((*iter) == nullptr) {
1090                 continue;
1091             }
1092             if ((*iter)->GetIsCached()) {
1093                 continue;
1094             }
1095             auto curIndex = (*iter)->GetIndex();
1096             if (curIndex == lastIndex + 1) {
1097                 if ((*iter)->GetTimestamp() + static_cast<uint64_t>(rsVSyncDistributor_->GetUiCommandDelayTime())
1098                     >= timestamp_) {
1099                     RequestNextVsyncForCachedCommand(transactionFlags, pid, curIndex);
1100                     break;
1101                 }
1102                 ++lastIndex;
1103                 transactionFlags += " [" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
1104             } else {
1105                 RS_LOGE("%{public}s wait curIndex:%{public}" PRIu64 ", lastIndex:%{public}" PRIu64 ", pid:%{public}d",
1106                     __FUNCTION__, curIndex, lastIndex, pid);
1107                 if (transactionDataLastWaitTime_[pid] == 0) {
1108                     transactionDataLastWaitTime_[pid] = timestamp_;
1109                 }
1110                 if ((timestamp_ - transactionDataLastWaitTime_[pid]) / REFRESH_PERIOD > SKIP_COMMAND_FREQ_LIMIT) {
1111                     transactionDataLastWaitTime_[pid] = 0;
1112                     lastIndex = curIndex;
1113                     transactionFlags += " skip to[" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
1114                     RS_LOGE("%{public}s skip to index:%{public}" PRIu64 ", pid:%{public}d",
1115                         __FUNCTION__, curIndex, pid);
1116                     continue;
1117                 }
1118                 break;
1119             }
1120         }
1121         if (iter != transactionVec.begin()) {
1122             (*transactionDataEffective)[pid].insert((*transactionDataEffective)[pid].end(),
1123                 std::make_move_iterator(transactionVec.begin()), std::make_move_iterator(iter));
1124             transactionVec.erase(transactionVec.begin(), iter);
1125         }
1126     }
1127 }
1128 
ProcessCommandForUniRender()1129 void RSMainThread::ProcessCommandForUniRender()
1130 {
1131     std::shared_ptr<TransactionDataMap> transactionDataEffective = std::make_shared<TransactionDataMap>();
1132     std::string transactionFlags;
1133     bool isNeedCacheCmd = CheckParallelSubThreadNodesStatus();
1134     {
1135         std::lock_guard<std::mutex> lock(transitionDataMutex_);
1136         cachedSkipTransactionDataMap_.clear();
1137         for (auto& rsTransactionElem: effectiveTransactionDataIndexMap_) {
1138             auto& transactionVec = rsTransactionElem.second.second;
1139             if (isNeedCacheCmd) {
1140                 auto pid = rsTransactionElem.first;
1141                 SkipCommandByNodeId(transactionVec, pid);
1142             }
1143             std::sort(transactionVec.begin(), transactionVec.end(), Compare);
1144         }
1145         if (isNeedCacheCmd) {
1146             CacheCommands();
1147         }
1148         CheckAndUpdateTransactionIndex(transactionDataEffective, transactionFlags);
1149     }
1150     if (!transactionDataEffective->empty()) {
1151         doDirectComposition_ = false;
1152         RS_OPTIONAL_TRACE_NAME_FMT("rs debug: %s transactionDataEffective not empty", __func__);
1153     }
1154     RS_TRACE_NAME("RSMainThread::ProcessCommandUni" + transactionFlags);
1155     transactionFlags_ = transactionFlags;
1156     for (auto& rsTransactionElem: *transactionDataEffective) {
1157         for (auto& rsTransaction: rsTransactionElem.second) {
1158             if (rsTransaction) {
1159                 if (rsTransaction->IsNeedSync() || syncTransactionData_.count(rsTransactionElem.first) > 0) {
1160                     ProcessSyncRSTransactionData(rsTransaction, rsTransactionElem.first);
1161                     continue;
1162                 }
1163                 ProcessRSTransactionData(rsTransaction, rsTransactionElem.first);
1164             }
1165         }
1166     }
1167     if (!transactionDataEffective->empty()) {
1168         RSBackgroundThread::Instance().PostTask([ transactionDataEffective ] () {
1169             RS_TRACE_NAME("RSMainThread::ProcessCommandForUniRender transactionDataEffective clear");
1170             transactionDataEffective->clear();
1171         });
1172     }
1173 }
1174 
ProcessCommandForDividedRender()1175 void RSMainThread::ProcessCommandForDividedRender()
1176 {
1177     const auto& nodeMap = context_->GetNodeMap();
1178     RS_TRACE_BEGIN("RSMainThread::ProcessCommand");
1179     {
1180         std::lock_guard<std::mutex> lock(transitionDataMutex_);
1181         if (!pendingEffectiveCommands_.empty()) {
1182             effectiveCommands_.swap(pendingEffectiveCommands_);
1183         }
1184         for (auto& [surfaceNodeId, commandMap] : cachedCommands_) {
1185             auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(surfaceNodeId);
1186             auto bufferTimestamp = dividedRenderbufferTimestamps_.find(surfaceNodeId);
1187             std::map<uint64_t, std::vector<std::unique_ptr<RSCommand>>>::iterator effectIter;
1188 
1189             if (!node || !node->IsOnTheTree() || bufferTimestamp == dividedRenderbufferTimestamps_.end()) {
1190                 // If node has been destructed or is not on the tree or has no valid buffer,
1191                 // for all command cached in commandMap should be executed immediately
1192                 effectIter = commandMap.end();
1193             } else {
1194                 uint64_t timestamp = bufferTimestamp->second;
1195                 effectIter = commandMap.upper_bound(timestamp);
1196             }
1197 
1198             for (auto it = commandMap.begin(); it != effectIter; it++) {
1199                 effectiveCommands_[it->first].insert(effectiveCommands_[it->first].end(),
1200                     std::make_move_iterator(it->second.begin()), std::make_move_iterator(it->second.end()));
1201             }
1202             commandMap.erase(commandMap.begin(), effectIter);
1203         }
1204     }
1205     for (auto& [timestamp, commands] : effectiveCommands_) {
1206         context_->transactionTimestamp_ = timestamp;
1207         for (auto& command : commands) {
1208             if (command) {
1209                 command->Process(*context_);
1210             }
1211         }
1212     }
1213     effectiveCommands_.clear();
1214     RS_TRACE_END();
1215 }
1216 
ProcessRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData,pid_t pid)1217 void RSMainThread::ProcessRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData, pid_t pid)
1218 {
1219     context_->transactionTimestamp_ = rsTransactionData->GetTimestamp();
1220     rsTransactionData->Process(*context_);
1221 }
1222 
StartSyncTransactionFallbackTask(std::unique_ptr<RSTransactionData> & rsTransactionData)1223 void RSMainThread::StartSyncTransactionFallbackTask(std::unique_ptr<RSTransactionData>& rsTransactionData)
1224 {
1225     if (handler_) {
1226         auto task = [this, syncId = rsTransactionData->GetSyncId()]() {
1227             if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
1228                     syncTransactionData_.begin()->second.front()->GetSyncId() != syncId) {
1229                 return;
1230             }
1231             ROSEN_LOGD("RSMainThread ProcessAllSyncTransactionData timeout task");
1232             ProcessAllSyncTransactionData();
1233         };
1234         handler_->PostTask(
1235             task, "ProcessAllSyncTransactionsTimeoutTask", RSSystemProperties::GetSyncTransactionWaitDelay());
1236     }
1237 }
1238 
ProcessSyncTransactionCount(std::unique_ptr<RSTransactionData> & rsTransactionData)1239 void RSMainThread::ProcessSyncTransactionCount(std::unique_ptr<RSTransactionData>& rsTransactionData)
1240 {
1241     auto sendingPid = rsTransactionData->GetSendingPid();
1242     auto parentPid = rsTransactionData->GetParentPid();
1243     subSyncTransactionCounts_[sendingPid] += rsTransactionData->GetSyncTransactionNum();
1244     if (subSyncTransactionCounts_[sendingPid] == 0) {
1245         subSyncTransactionCounts_.erase(sendingPid);
1246     }
1247     if (!rsTransactionData->IsNeedCloseSync()) {
1248         subSyncTransactionCounts_[parentPid]--;
1249         if (subSyncTransactionCounts_[parentPid] == 0) {
1250             subSyncTransactionCounts_.erase(parentPid);
1251         }
1252     }
1253     ROSEN_LOGD("RSMainThread::ProcessSyncTransactionCount isNeedCloseSync:%{public}d syncId:%{public}" PRIu64 ""
1254                " parentPid:%{public}d syncNum:%{public}d subSyncTransactionCounts_.size:%{public}zd",
1255         rsTransactionData->IsNeedCloseSync(), rsTransactionData->GetSyncId(), parentPid,
1256         rsTransactionData->GetSyncTransactionNum(), subSyncTransactionCounts_.size());
1257 }
1258 
ProcessSyncRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData,pid_t pid)1259 void RSMainThread::ProcessSyncRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData, pid_t pid)
1260 {
1261     if (!rsTransactionData->IsNeedSync()) {
1262         syncTransactionData_[pid].emplace_back(std::move(rsTransactionData));
1263         return;
1264     }
1265 
1266     if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
1267         (syncTransactionData_.begin()->second.front()->GetSyncId() > rsTransactionData->GetSyncId())) {
1268         ROSEN_LOGD("RSMainThread ProcessSyncRSTransactionData while syncId less GetCommandCount: %{public}lu"
1269             "pid: %{public}d", rsTransactionData->GetCommandCount(), rsTransactionData->GetSendingPid());
1270         ProcessRSTransactionData(rsTransactionData, pid);
1271         return;
1272     }
1273 
1274     if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
1275         (syncTransactionData_.begin()->second.front()->GetSyncId() != rsTransactionData->GetSyncId())) {
1276         ProcessAllSyncTransactionData();
1277     }
1278     if (syncTransactionData_.empty()) {
1279         StartSyncTransactionFallbackTask(rsTransactionData);
1280     }
1281     if (syncTransactionData_.count(pid) == 0) {
1282         syncTransactionData_.insert({ pid, std::vector<std::unique_ptr<RSTransactionData>>() });
1283     }
1284     ProcessSyncTransactionCount(rsTransactionData);
1285     syncTransactionData_[pid].emplace_back(std::move(rsTransactionData));
1286     if (subSyncTransactionCounts_.empty()) {
1287         ROSEN_LOGD("SyncTransaction sucess");
1288         ProcessAllSyncTransactionData();
1289     }
1290 }
1291 
ProcessAllSyncTransactionData()1292 void RSMainThread::ProcessAllSyncTransactionData()
1293 {
1294     RS_TRACE_NAME("RSMainThread::ProcessAllSyncTransactionData");
1295     for (auto& [pid, transactions] : syncTransactionData_) {
1296         for (auto& transaction: transactions) {
1297             ROSEN_LOGD("RSMainThread ProcessAllSyncTransactionData GetCommandCount: %{public}lu pid: %{public}d",
1298                 transaction->GetCommandCount(), pid);
1299             ProcessRSTransactionData(transaction, pid);
1300         }
1301     }
1302     syncTransactionData_.clear();
1303     subSyncTransactionCounts_.clear();
1304     RequestNextVSync();
1305 }
1306 
ConsumeAndUpdateAllNodes()1307 void RSMainThread::ConsumeAndUpdateAllNodes()
1308 {
1309     ResetHardwareEnabledState(isUniRender_);
1310     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::ConsumeAndUpdateAllNodes");
1311     bool needRequestNextVsync = false;
1312     bool hasHdrVideo = false;
1313     if (!isUniRender_) {
1314         dividedRenderbufferTimestamps_.clear();
1315     }
1316     const auto& nodeMap = GetContext().GetNodeMap();
1317     nodeMap.TraverseSurfaceNodes(
1318         [this, &needRequestNextVsync, &hasHdrVideo](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
1319         if (surfaceNode == nullptr) {
1320             return;
1321         }
1322 
1323         surfaceNode->ResetAnimateState();
1324         surfaceNode->ResetRotateState();
1325         surfaceNode->ResetSpecialLayerChangedFlag();
1326         // Reset BasicGeoTrans info at the beginning of cmd process
1327         if (surfaceNode->IsLeashOrMainWindow()) {
1328             surfaceNode->ResetIsOnlyBasicGeoTransform();
1329         }
1330         if (surfaceNode->GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
1331             surfaceNode->SetContentDirty(); // screen recording capsule force mark dirty
1332         }
1333         if (surfaceNode->IsHardwareEnabledType()
1334             && CheckSubThreadNodeStatusIsDoing(surfaceNode->GetInstanceRootNodeId())) {
1335             RS_LOGD("SubThread is processing %{public}s, skip acquire buffer", surfaceNode->GetName().c_str());
1336             return;
1337         }
1338         auto surfaceHandler = surfaceNode->GetMutableRSSurfaceHandler();
1339         if (frameRateMgr_ != nullptr && surfaceHandler->GetAvailableBufferCount() > 0) {
1340             auto surfaceNodeName = surfaceNode->GetName().empty() ? DEFAULT_SURFACE_NODE_NAME : surfaceNode->GetName();
1341             frameRateMgr_->UpdateSurfaceTime(surfaceNodeName, timestamp_, ExtractPid(surfaceNode->GetId()));
1342         }
1343         surfaceHandler->ResetCurrentFrameBufferConsumed();
1344         if (RSBaseRenderUtil::ConsumeAndUpdateBuffer(*surfaceHandler, timestamp_)) {
1345             if (!isUniRender_) {
1346                 this->dividedRenderbufferTimestamps_[surfaceNode->GetId()] =
1347                     static_cast<uint64_t>(surfaceHandler->GetTimestamp());
1348             }
1349             if (surfaceHandler->IsCurrentFrameBufferConsumed() && surfaceNode->IsHardwareEnabledType()) {
1350                 GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(surfaceNode->GetId(),
1351                     surfaceNode->GetName(), surfaceHandler->GetDamageRegion());
1352             }
1353             if (surfaceHandler->IsCurrentFrameBufferConsumed() && !surfaceNode->IsHardwareEnabledType()) {
1354                 surfaceNode->SetContentDirty();
1355                 doDirectComposition_ = false;
1356                 RS_OPTIONAL_TRACE_NAME_FMT(
1357                     "rs debug: name %s, id %" PRIu64", buffer consumed and not HardwareEnabledType",
1358                     surfaceNode->GetName().c_str(), surfaceNode->GetId());
1359             }
1360             if (isUniRender_ && surfaceHandler->IsCurrentFrameBufferConsumed()) {
1361                 RSBaseRenderUtil::SetScalingMode(*surfaceNode);
1362                 auto buffer = surfaceHandler->GetBuffer();
1363                 auto preBuffer = surfaceHandler->GetPreBuffer();
1364                 surfaceNode->UpdateBufferInfo(buffer,
1365                     surfaceHandler->GetDamageRegion(), surfaceHandler->GetAcquireFence(), preBuffer);
1366                 if (surfaceHandler->GetBufferSizeChanged() || surfaceHandler->GetBufferTransformTypeChanged()) {
1367                     surfaceNode->SetContentDirty();
1368                     doDirectComposition_ = false;
1369                     surfaceHandler->SetBufferTransformTypeChanged(false);
1370                     RS_OPTIONAL_TRACE_NAME_FMT("rs debug: name %s, id %" PRIu64", surfaceNode buffer size changed",
1371                         surfaceNode->GetName().c_str(), surfaceNode->GetId());
1372                     RS_LOGI("ConsumeAndUpdateAllNodes name:%{public}s id:%{public}" PRIu64" buffer size changed, "
1373                         "buffer:[%{public}d, %{public}d], preBuffer:[%{public}d, %{public}d]",
1374                         surfaceNode->GetName().c_str(), surfaceNode->GetId(),
1375                         buffer ? buffer->GetSurfaceBufferWidth() : 0, buffer ? buffer->GetSurfaceBufferHeight() : 0,
1376                         preBuffer ? preBuffer->GetSurfaceBufferWidth() : 0,
1377                         preBuffer ? preBuffer->GetSurfaceBufferHeight() : 0);
1378                 }
1379             }
1380             if (deviceType_ == DeviceType::PC && isUiFirstOn_ && surfaceHandler->IsCurrentFrameBufferConsumed()
1381                 && surfaceNode->IsHardwareEnabledType() && surfaceNode->IsHardwareForcedDisabledByFilter()) {
1382                     RS_OPTIONAL_TRACE_NAME(surfaceNode->GetName() +
1383                         " SetContentDirty for UIFirst assigning to subthread");
1384                     surfaceNode->SetContentDirty();
1385                     doDirectComposition_ = false;
1386                     RS_OPTIONAL_TRACE_NAME_FMT("rs debug: name %s, id %" PRIu64", pc uifirst on",
1387                         surfaceNode->GetName().c_str(), surfaceNode->GetId());
1388             }
1389         }
1390 #ifdef RS_ENABLE_VK
1391         if ((RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
1392             RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) && RSSystemProperties::GetDrmEnabled() &&
1393             deviceType_ != DeviceType::PC && (surfaceHandler->GetBufferUsage() & BUFFER_USAGE_PROTECTED)) {
1394             if (!surfaceNode->GetProtectedLayer()) {
1395                 surfaceNode->SetProtectedLayer(true);
1396             }
1397             const auto& instanceNode = surfaceNode->GetInstanceRootNode();
1398             if (instanceNode && instanceNode->IsOnTheTree()) {
1399                 hasProtectedLayer_ = true;
1400             }
1401         }
1402 #endif
1403         // still have buffer(s) to consume.
1404         if (surfaceHandler->GetAvailableBufferCount() > 0) {
1405             needRequestNextVsync = true;
1406         }
1407         if (!hasHdrVideo) {
1408             hasHdrVideo = CheckIsHdrSurface(*surfaceNode);
1409         }
1410         if ((*surfaceNode).GetRSSurfaceHandler() == nullptr) {
1411             RS_LOGE("surfaceNode.GetRSSurfaceHandler is NULL");
1412             return;
1413         }
1414         UpdateSurfaceNodeNit((*surfaceNode).GetRSSurfaceHandler()->GetBuffer(),
1415             *surfaceNode, CheckIsHdrSurface(*surfaceNode));
1416     });
1417     RSLuminanceControl::Get().SetHdrStatus(0, hasHdrVideo, HDR_TYPE::VIDEO);
1418     if (needRequestNextVsync) {
1419         RequestNextVSync();
1420     }
1421     RS_OPTIONAL_TRACE_END();
1422 }
1423 
CheckSubThreadNodeStatusIsDoing(NodeId appNodeId) const1424 bool RSMainThread::CheckSubThreadNodeStatusIsDoing(NodeId appNodeId) const
1425 {
1426     for (auto& node : subThreadNodes_) {
1427         if (node == nullptr) {
1428             continue;
1429         }
1430         if (node->GetCacheSurfaceProcessedStatus() != CacheProcessStatus::DOING) {
1431             continue;
1432         }
1433         if (node->GetId() == appNodeId) {
1434             return true;
1435         }
1436         for (auto& child : *node->GetSortedChildren()) {
1437             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1438             if (surfaceNode && surfaceNode->GetId() == appNodeId) {
1439                 return true;
1440             }
1441         }
1442     }
1443     return false;
1444 }
1445 
CollectInfoForHardwareComposer()1446 void RSMainThread::CollectInfoForHardwareComposer()
1447 {
1448     if (!isUniRender_) {
1449         return;
1450     }
1451     CheckIfHardwareForcedDisabled();
1452     if (!pendingUiCaptureTasks_.empty()) {
1453         RS_OPTIONAL_TRACE_NAME("rs debug: uiCapture SetDoDirectComposition false");
1454         doDirectComposition_ = false;
1455     }
1456     const auto& nodeMap = GetContext().GetNodeMap();
1457     nodeMap.TraverseSurfaceNodes(
1458         [this, &nodeMap](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
1459             if (surfaceNode == nullptr) {
1460                 return;
1461             }
1462             auto surfaceHandler = surfaceNode->GetMutableRSSurfaceHandler();
1463             if (surfaceHandler->GetBuffer() != nullptr) {
1464                 selfDrawingNodes_.emplace_back(surfaceNode);
1465                 selfDrawables_.emplace_back(surfaceNode->GetRenderDrawable());
1466             }
1467 
1468             if (!surfaceNode->GetDoDirectComposition()) {
1469                 doDirectComposition_ = false;
1470                 RS_OPTIONAL_TRACE_NAME_FMT("rs debug: name %s, id %" PRIu64", node GetDoDirectComposition is false",
1471                     surfaceNode->GetName().c_str(), surfaceNode->GetId());
1472                 surfaceNode->SetDoDirectComposition(true);
1473             }
1474 
1475             if (!surfaceNode->IsOnTheTree()) {
1476                 if (surfaceHandler->IsCurrentFrameBufferConsumed()) {
1477                     surfaceNode->UpdateHardwareDisabledState(true);
1478                     doDirectComposition_ = false;
1479                     RS_OPTIONAL_TRACE_NAME_FMT("rs debug: name %s, id %" PRIu64", node not on the tree "
1480                         "and buffer consumed", surfaceNode->GetName().c_str(), surfaceNode->GetId());
1481                 }
1482                 return;
1483             }
1484 
1485             if (surfaceNode->IsLeashWindow() && surfaceNode->GetForceUIFirstChanged()) {
1486                 forceUIFirstChanged_ = true;
1487                 surfaceNode->SetForceUIFirstChanged(false);
1488             }
1489 
1490             if (!surfaceNode->IsHardwareEnabledType()) {
1491                 return;
1492             }
1493 
1494             // if hwc node is set on the tree this frame, mark its parent app node to be prepared
1495             auto appNodeId = surfaceNode->GetInstanceRootNodeId();
1496             if (surfaceNode->IsNewOnTree()) {
1497                 context_->AddActiveNode(nodeMap.GetRenderNode(appNodeId));
1498             }
1499 
1500             if (surfaceHandler->GetBuffer() != nullptr) {
1501                 // collect hwc nodes vector, used for display node skip and direct composition cases
1502                 surfaceNode->SetIsLastFrameHwcEnabled(!surfaceNode->IsHardwareForcedDisabled());
1503                 hardwareEnabledNodes_.emplace_back(surfaceNode);
1504                 hardwareEnabledDrwawables_.emplace_back(surfaceNode->GetRenderDrawable());
1505             }
1506 
1507             // set content dirty for hwc node if needed
1508             if (isHardwareForcedDisabled_) {
1509                 // buffer updated or hwc -> gpu
1510                 if (surfaceHandler->IsCurrentFrameBufferConsumed() || surfaceNode->GetIsLastFrameHwcEnabled()) {
1511                     surfaceNode->SetContentDirty();
1512                 }
1513             } else if (!surfaceNode->GetIsLastFrameHwcEnabled()) { // gpu -> hwc
1514                 if (surfaceHandler->IsCurrentFrameBufferConsumed()) {
1515                     surfaceNode->SetContentDirty();
1516                     doDirectComposition_ = false;
1517                     RS_OPTIONAL_TRACE_NAME_FMT(
1518                         "rs debug: name %s, id %" PRIu64", isLastFrameHwcEnabled not enabled and buffer consumed",
1519                         surfaceNode->GetName().c_str(), surfaceNode->GetId());
1520                 } else {
1521                     if (surfaceNode->GetAncoForceDoDirect()) {
1522                         surfaceNode->SetContentDirty();
1523                     }
1524                     surfaceNode->SetHwcDelayDirtyFlag(true);
1525                 }
1526             } else { // hwc -> hwc
1527                 // self-drawing node don't set content dirty when gpu -> hwc
1528                 // so first frame in hwc -> hwc, should set content dirty
1529                 if (surfaceNode->GetHwcDelayDirtyFlag()) {
1530                     surfaceNode->SetContentDirty();
1531                     surfaceNode->SetHwcDelayDirtyFlag(false);
1532                     doDirectComposition_ = false;
1533                     RS_OPTIONAL_TRACE_NAME_FMT("rs debug: name %s, id %" PRIu64", HwcDelayDirtyFlag is true",
1534                         surfaceNode->GetName().c_str(), surfaceNode->GetId());
1535                 }
1536             }
1537 
1538             if (surfaceHandler->IsCurrentFrameBufferConsumed()) {
1539                 isHardwareEnabledBufferUpdated_ = true;
1540             }
1541         });
1542 }
1543 
IsLastFrameUIFirstEnabled(NodeId appNodeId) const1544 bool RSMainThread::IsLastFrameUIFirstEnabled(NodeId appNodeId) const
1545 {
1546     for (auto& node : subThreadNodes_) {
1547         if (node == nullptr) {
1548             continue;
1549         }
1550         if (node->IsAppWindow()) {
1551             if (node->GetId() == appNodeId) {
1552                 return true;
1553             }
1554         } else {
1555             for (auto& child : *node->GetSortedChildren()) {
1556                 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1557                 if (surfaceNode && surfaceNode->IsAppWindow() && surfaceNode->GetId() == appNodeId) {
1558                     return true;
1559                 }
1560             }
1561         }
1562     }
1563     return false;
1564 }
1565 
CheckIfHardwareForcedDisabled()1566 void RSMainThread::CheckIfHardwareForcedDisabled()
1567 {
1568     ColorFilterMode colorFilterMode = renderEngine_->GetColorFilterMode();
1569     bool hasColorFilter = colorFilterMode >= ColorFilterMode::INVERT_COLOR_ENABLE_MODE &&
1570         colorFilterMode <= ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE;
1571     std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
1572     if (rootNode == nullptr) {
1573         RS_LOGE("RSMainThread::CheckIfHardwareForcedDisabled rootNode is nullptr");
1574         return;
1575     }
1576     bool isMultiDisplay = rootNode->GetChildrenCount() > 1;
1577 
1578     // check all children of global root node, and only disable hardware composer
1579     // in case node's composite type is UNI_RENDER_EXPAND_COMPOSITE or Wired projection
1580     const auto& children = rootNode->GetChildren();
1581     auto itr = std::find_if(children->begin(), children->end(), [](const std::shared_ptr<RSRenderNode>& child) -> bool {
1582             if (child == nullptr) {
1583                 return false;
1584             }
1585             if (child->GetType() != RSRenderNodeType::DISPLAY_NODE) {
1586                 return false;
1587             }
1588             auto displayNodeSp = std::static_pointer_cast<RSDisplayRenderNode>(child);
1589             if (displayNodeSp->GetMirrorSource().lock()) {
1590                 // wired projection case
1591                 return displayNodeSp->GetCompositeType() == RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE;
1592             }
1593             return displayNodeSp->GetCompositeType() == RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE;
1594     });
1595 
1596     bool isExpandScreenOrWiredProjectionCase = itr != children->end();
1597     bool enableHwcForMirrorMode = RSSystemProperties::GetHardwareComposerEnabledForMirrorMode();
1598     // [PLANNING] GetChildrenCount > 1 indicates multi display, only Mirror Mode need be marked here
1599     // Mirror Mode reuses display node's buffer, so mark it and disable hardware composer in this case
1600     isHardwareForcedDisabled_ = isHardwareForcedDisabled_ || doWindowAnimate_ ||
1601         (isMultiDisplay && (isExpandScreenOrWiredProjectionCase || !enableHwcForMirrorMode) && !hasProtectedLayer_) ||
1602         hasColorFilter;
1603     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug global: CheckIfHardwareForcedDisabled isHardwareForcedDisabled_:%d "
1604         "doWindowAnimate_:%d isMultiDisplay:%d hasColorFilter:%d",
1605         isHardwareForcedDisabled_, doWindowAnimate_.load(), isMultiDisplay, hasColorFilter);
1606 
1607     if (isMultiDisplay && !isHardwareForcedDisabled_) {
1608         // Disable direct composition when hardware composer is enabled for virtual screen
1609         doDirectComposition_ = false;
1610     }
1611 }
1612 
ReleaseAllNodesBuffer()1613 void RSMainThread::ReleaseAllNodesBuffer()
1614 {
1615     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::ReleaseAllNodesBuffer");
1616     const auto& nodeMap = GetContext().GetNodeMap();
1617     nodeMap.TraverseSurfaceNodes([this](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
1618         if (surfaceNode == nullptr) {
1619             return;
1620         }
1621         auto surfaceHandler = surfaceNode->GetMutableRSSurfaceHandler();
1622         // surfaceNode's buffer will be released in hardware thread if last frame enables hardware composer
1623         if (surfaceNode->IsHardwareEnabledType()) {
1624             if (surfaceNode->IsLastFrameHardwareEnabled()) {
1625                 if (!surfaceNode->IsCurrentFrameHardwareEnabled()) {
1626                     auto preBuffer = surfaceHandler->GetPreBuffer();
1627                     if (preBuffer != nullptr) {
1628                         auto releaseTask = [buffer = preBuffer, consumer = surfaceHandler->GetConsumer(),
1629                             fence = surfaceHandler->GetPreBufferReleaseFence()]() mutable {
1630                             auto ret = consumer->ReleaseBuffer(buffer, fence);
1631                             if (ret != OHOS::SURFACE_ERROR_OK) {
1632                                 RS_LOGD("surfaceHandler ReleaseBuffer failed(ret: %{public}d)!", ret);
1633                             }
1634                         };
1635                         surfaceHandler->ResetPreBuffer();
1636                         RSHardwareThread::Instance().PostTask(releaseTask);
1637                     }
1638                 }
1639                 surfaceNode->ResetCurrentFrameHardwareEnabledState();
1640                 return;
1641             }
1642             surfaceNode->ResetCurrentFrameHardwareEnabledState();
1643         }
1644         RSBaseRenderUtil::ReleaseBuffer(*surfaceHandler);
1645     });
1646     RS_OPTIONAL_TRACE_END();
1647 }
1648 
GetRefreshRate() const1649 uint32_t RSMainThread::GetRefreshRate() const
1650 {
1651     auto screenManager = CreateOrGetScreenManager();
1652     if (!screenManager) {
1653         RS_LOGE("RSMainThread::GetRefreshRate screenManager is nullptr");
1654         return STANDARD_REFRESH_RATE;
1655     }
1656     uint32_t refreshRate = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(
1657         screenManager->GetDefaultScreenId());
1658     if (refreshRate == 0) {
1659         RS_LOGE("RSMainThread::GetRefreshRate refreshRate is invalid");
1660         return STANDARD_REFRESH_RATE;
1661     }
1662     return refreshRate;
1663 }
1664 
GetDynamicRefreshRate() const1665 uint32_t RSMainThread::GetDynamicRefreshRate() const
1666 {
1667     uint32_t refreshRate = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(displayNodeScreenId_);
1668     if (refreshRate == 0) {
1669         RS_LOGE("RSMainThread::GetDynamicRefreshRate refreshRate is invalid");
1670         return STANDARD_REFRESH_RATE;
1671     }
1672     return refreshRate;
1673 }
1674 
ClearMemoryCache(ClearMemoryMoment moment,bool deeply,pid_t pid)1675 void RSMainThread::ClearMemoryCache(ClearMemoryMoment moment, bool deeply, pid_t pid)
1676 {
1677     if (!RSSystemProperties::GetReleaseResourceEnabled()) {
1678         return;
1679     }
1680     this->clearMemoryFinished_ = false;
1681     this->clearMemDeeply_ = this->clearMemDeeply_ || deeply;
1682     this->SetClearMoment(moment);
1683     this->exitedPidSet_.emplace(pid);
1684     auto task =
1685         [this, moment, deeply]() {
1686             auto grContext = GetRenderEngine()->GetRenderContext()->GetDrGPUContext();
1687             if (!grContext) {
1688                 return;
1689             }
1690             RS_LOGD("Clear memory cache %{public}d", this->GetClearMoment());
1691             RS_TRACE_NAME_FMT("Clear memory cache, cause the moment [%d] happen", this->GetClearMoment());
1692             SKResourceManager::Instance().ReleaseResource();
1693             grContext->Flush();
1694             SkGraphics::PurgeAllCaches(); // clear cpu cache
1695             auto pid = *(this->exitedPidSet_.begin());
1696             if (this->exitedPidSet_.size() == 1 && pid == -1) {  // no exited app, just clear scratch resource
1697                 if (deeply || this->deviceType_ != DeviceType::PHONE) {
1698                     MemoryManager::ReleaseUnlockAndSafeCacheGpuResource(grContext);
1699                 } else {
1700                     MemoryManager::ReleaseUnlockGpuResource(grContext);
1701                 }
1702             } else {
1703                 MemoryManager::ReleaseUnlockGpuResource(grContext, this->exitedPidSet_);
1704             }
1705             grContext->FlushAndSubmit(true);
1706             this->clearMemoryFinished_ = true;
1707             this->exitedPidSet_.clear();
1708             this->clearMemDeeply_ = false;
1709             this->SetClearMoment(ClearMemoryMoment::NO_CLEAR);
1710         };
1711     auto refreshRate = GetRefreshRate();
1712     if (refreshRate > 0) {
1713         if (!isUniRender_ || rsParallelType_ == RsParallelType::RS_PARALLEL_TYPE_SINGLE_THREAD) {
1714             PostTask(task, CLEAR_GPU_CACHE,
1715                 (this->deviceType_ == DeviceType::PHONE ? TIME_OF_EIGHT_FRAMES : TIME_OF_THE_FRAMES) / refreshRate,
1716                 AppExecFwk::EventQueue::Priority::HIGH);
1717         } else {
1718             RSUniRenderThread::Instance().PostTask(task, CLEAR_GPU_CACHE,
1719                 (this->deviceType_ == DeviceType::PHONE ? TIME_OF_EIGHT_FRAMES : TIME_OF_THE_FRAMES) / refreshRate,
1720                 AppExecFwk::EventQueue::Priority::HIGH);
1721         }
1722     }
1723 }
1724 
WaitUtilUniRenderFinished()1725 void RSMainThread::WaitUtilUniRenderFinished()
1726 {
1727     std::unique_lock<std::mutex> lock(uniRenderMutex_);
1728     if (uniRenderFinished_) {
1729         return;
1730     }
1731     RS_TRACE_NAME("RSMainThread::WaitUtilUniRenderFinished");
1732     uniRenderCond_.wait(lock, [this]() { return uniRenderFinished_; });
1733     uniRenderFinished_ = false;
1734 }
1735 
WaitUntilUnmarshallingTaskFinished()1736 void RSMainThread::WaitUntilUnmarshallingTaskFinished()
1737 {
1738     if (!isUniRender_) {
1739         return;
1740     }
1741     if (!needWaitUnmarshalFinished_) {
1742         /* if needWaitUnmarshalFinished_ is false, it means UnmarshallingTask is finished, no need to wait.
1743          * reset needWaitUnmarshalFinished_ to true, maybe it need to wait next time.
1744          */
1745         needWaitUnmarshalFinished_ = true;
1746         return;
1747     }
1748     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::WaitUntilUnmarshallingTaskFinished");
1749     std::unique_lock<std::mutex> lock(unmarshalMutex_);
1750     unmarshalTaskCond_.wait(lock, [this]() { return unmarshalFinishedCount_ > 0; });
1751     --unmarshalFinishedCount_;
1752     RS_OPTIONAL_TRACE_END();
1753 }
1754 
MergeToEffectiveTransactionDataMap(TransactionDataMap & cachedTransactionDataMap)1755 void RSMainThread::MergeToEffectiveTransactionDataMap(TransactionDataMap& cachedTransactionDataMap)
1756 {
1757     std::lock_guard<std::mutex> lock(transitionDataMutex_);
1758     for (auto& elem : cachedTransactionDataMap) {
1759         auto pid = elem.first;
1760         if (effectiveTransactionDataIndexMap_.count(pid) == 0) {
1761             RS_LOGE("RSMainThread::MergeToEffectiveTransactionDataMap pid:%{public}d not valid, skip it", pid);
1762             continue;
1763         }
1764         InsertToEnd(elem.second, effectiveTransactionDataIndexMap_[pid].second);
1765     }
1766     cachedTransactionDataMap.clear();
1767 }
1768 
NotifyUniRenderFinish()1769 void RSMainThread::NotifyUniRenderFinish()
1770 {
1771     if (std::this_thread::get_id() != Id()) {
1772         std::lock_guard<std::mutex> lock(uniRenderMutex_);
1773         uniRenderFinished_ = true;
1774         uniRenderCond_.notify_one();
1775     } else {
1776         uniRenderFinished_ = true;
1777     }
1778 }
1779 
OnHideNotchStatusCallback(const char * key,const char * value,void * context)1780 void RSMainThread::OnHideNotchStatusCallback(const char *key, const char *value, void *context)
1781 {
1782     if (strcmp(key, HIDE_NOTCH_STATUS) != 0) {
1783         return;
1784     }
1785     RSMainThread::Instance()->RequestNextVSync();
1786 }
1787 
NotifySurfaceCapProcFinish()1788 void RSMainThread::NotifySurfaceCapProcFinish()
1789 {
1790     RS_TRACE_NAME("RSMainThread::NotifySurfaceCapProcFinish");
1791     std::lock_guard<std::mutex> lock(surfaceCapProcMutex_);
1792     surfaceCapProcFinished_ = true;
1793     surfaceCapProcTaskCond_.notify_one();
1794 }
1795 
WaitUntilSurfaceCapProcFinished()1796 void RSMainThread::WaitUntilSurfaceCapProcFinished()
1797 {
1798     if (GetDeviceType() != DeviceType::PHONE) {
1799         return;
1800     }
1801     std::unique_lock<std::mutex> lock(surfaceCapProcMutex_);
1802     if (surfaceCapProcFinished_) {
1803         return;
1804     }
1805     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::WaitUntilSurfaceCapProcFinished");
1806     surfaceCapProcTaskCond_.wait_until(lock, std::chrono::system_clock::now() +
1807         std::chrono::milliseconds(WAIT_FOR_SURFACE_CAPTURE_PROCESS_TIMEOUT),
1808         [this]() { return surfaceCapProcFinished_; });
1809     RS_OPTIONAL_TRACE_END();
1810 }
1811 
SetSurfaceCapProcFinished(bool flag)1812 void RSMainThread::SetSurfaceCapProcFinished(bool flag)
1813 {
1814     std::lock_guard<std::mutex> lock(surfaceCapProcMutex_);
1815     surfaceCapProcFinished_ = flag;
1816 }
1817 
IsRequestedNextVSync()1818 bool RSMainThread::IsRequestedNextVSync()
1819 {
1820     if (receiver_ != nullptr) {
1821         return receiver_->IsRequestedNextVSync();
1822     }
1823     return false;
1824 }
1825 
ProcessHgmFrameRate(uint64_t timestamp)1826 void RSMainThread::ProcessHgmFrameRate(uint64_t timestamp)
1827 {
1828     RS_TRACE_FUNC();
1829     if (rsFrameRateLinker_ != nullptr) {
1830         rsCurrRange_.type_ = RS_ANIMATION_FRAME_RATE_TYPE;
1831         HgmEnergyConsumptionPolicy::Instance().GetAnimationIdleFps(rsCurrRange_);
1832         rsFrameRateLinker_->SetExpectedRange(rsCurrRange_);
1833         RS_TRACE_NAME_FMT("rsCurrRange = (%d, %d, %d)", rsCurrRange_.min_, rsCurrRange_.max_, rsCurrRange_.preferred_);
1834     }
1835     if (!frameRateMgr_ || !rsVSyncDistributor_) {
1836         return;
1837     }
1838     DvsyncInfo info;
1839     info.isRsDvsyncOn = rsVSyncDistributor_->IsDVsyncOn();
1840     info.isUiDvsyncOn =  rsVSyncDistributor_->IsUiDvsyncOn();
1841     auto rsRate = rsVSyncDistributor_->GetRefreshRate();
1842     // Check and processing refresh rate task.
1843     frameRateMgr_->ProcessPendingRefreshRate(timestamp, rsRate, info);
1844 
1845     // hgm warning: use IsLtpo instead after GetDisplaySupportedModes ready
1846     if (frameRateMgr_->GetCurScreenStrategyId().find("LTPO") == std::string::npos) {
1847         frameRateMgr_->UniProcessDataForLtps(idleTimerExpiredFlag_);
1848     } else {
1849         auto appFrameLinkers = GetContext().GetFrameRateLinkerMap().Get();
1850         frameRateMgr_->UniProcessDataForLtpo(timestamp, rsFrameRateLinker_, appFrameLinkers,
1851             idleTimerExpiredFlag_, info);
1852     }
1853 }
1854 
GetParallelCompositionEnabled()1855 bool RSMainThread::GetParallelCompositionEnabled()
1856 {
1857     return doParallelComposition_;
1858 }
1859 
SetFrameIsRender(bool isRender)1860 void RSMainThread::SetFrameIsRender(bool isRender)
1861 {
1862     if (rsVSyncDistributor_ != nullptr) {
1863         rsVSyncDistributor_->SetFrameIsRender(isRender);
1864     }
1865 }
1866 
WaitUntilUploadTextureTaskFinishedForGL()1867 void RSMainThread::WaitUntilUploadTextureTaskFinishedForGL()
1868 {
1869     if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
1870         WaitUntilUploadTextureTaskFinished(isUniRender_);
1871     }
1872 }
1873 
AddUiCaptureTask(NodeId id,std::function<void ()> task)1874 void RSMainThread::AddUiCaptureTask(NodeId id, std::function<void()> task)
1875 {
1876     pendingUiCaptureTasks_.emplace_back(id, task);
1877     if (!IsRequestedNextVSync()) {
1878         RequestNextVSync();
1879     }
1880 }
1881 
PrepareUiCaptureTasks(std::shared_ptr<RSUniRenderVisitor> uniVisitor)1882 void RSMainThread::PrepareUiCaptureTasks(std::shared_ptr<RSUniRenderVisitor> uniVisitor)
1883 {
1884     const auto& nodeMap = context_->GetNodeMap();
1885     for (auto [id, captureTask]: pendingUiCaptureTasks_) {
1886         auto node = nodeMap.GetRenderNode(id);
1887         if (!node) {
1888             RS_LOGW("RSMainThread::PrepareUiCaptureTasks node is nullptr");
1889         } else if (!node->IsOnTheTree() || node->IsDirty() || node->IsSubTreeDirty()) {
1890             node->PrepareSelfNodeForApplyModifiers();
1891         }
1892         uiCaptureTasks_.emplace(id, captureTask);
1893     }
1894     pendingUiCaptureTasks_.clear();
1895 }
1896 
ProcessUiCaptureTasks()1897 void RSMainThread::ProcessUiCaptureTasks()
1898 {
1899     while (!uiCaptureTasks_.empty()) {
1900         if (RSUiCaptureTaskParallel::GetCaptureCount() >= MAX_CAPTURE_COUNT) {
1901             return;
1902         }
1903         auto captureTask = std::get<1>(uiCaptureTasks_.front());
1904         uiCaptureTasks_.pop();
1905         captureTask();
1906     }
1907 }
1908 
UniRender(std::shared_ptr<RSBaseRenderNode> rootNode)1909 void RSMainThread::UniRender(std::shared_ptr<RSBaseRenderNode> rootNode)
1910 {
1911     if (isAccessibilityConfigChanged_) {
1912         RSUniRenderVisitor::ClearRenderGroupCache();
1913     }
1914     UpdateUIFirstSwitch();
1915     UpdateRogSizeIfNeeded();
1916     UpdateAceDebugBoundaryEnabled();
1917     auto uniVisitor = std::make_shared<RSUniRenderVisitor>();
1918     uniVisitor->SetHardwareEnabledNodes(hardwareEnabledNodes_);
1919     uniVisitor->SetAppWindowNum(appWindowNum_);
1920     uniVisitor->SetProcessorRenderEngine(GetRenderEngine());
1921     uniVisitor->SetForceUpdateFlag(forceUpdateUniRenderFlag_);
1922 
1923     if (isHardwareForcedDisabled_) {
1924         uniVisitor->MarkHardwareForcedDisabled();
1925         doDirectComposition_ = false;
1926         RS_OPTIONAL_TRACE_NAME_FMT("rs debug: %s HardwareForcedDisabled is true", __func__);
1927     }
1928     bool needTraverseNodeTree = true;
1929     needDrawFrame_ = true;
1930     if (doDirectComposition_ && !isDirty_ && !isAccessibilityConfigChanged_
1931         && !isCachedSurfaceUpdated_) {
1932         if (isHardwareEnabledBufferUpdated_) {
1933             needTraverseNodeTree = !DoDirectComposition(rootNode, !isLastFrameDirectComposition_);
1934         } else if (forceUpdateUniRenderFlag_) {
1935             RS_TRACE_NAME("RSMainThread::UniRender ForceUpdateUniRender");
1936         } else if (!pendingUiCaptureTasks_.empty()) {
1937             RS_LOGD("RSMainThread::Render pendingUiCaptureTasks_ not empty");
1938         } else {
1939             needDrawFrame_ = false;
1940             RS_LOGD("RSMainThread::Render nothing to update");
1941             RS_TRACE_NAME("RSMainThread::UniRender nothing to update");
1942             RSMainThread::Instance()->SetSkipJankAnimatorFrame(true);
1943             for (auto& node: hardwareEnabledNodes_) {
1944                 if (!node->IsHardwareForcedDisabled()) {
1945                     node->MarkCurrentFrameHardwareEnabled();
1946                 }
1947             }
1948             WaitUntilUploadTextureTaskFinishedForGL();
1949             return;
1950         }
1951     }
1952 
1953     isCachedSurfaceUpdated_ = false;
1954     if (needTraverseNodeTree) {
1955         RSUniRenderThread::Instance().PostTask([ids = context_->GetMutableNodeMap().GetAndClearPurgeableNodeIds()] {
1956             RSUniRenderThread::Instance().ResetClearMemoryTask(std::move(ids));
1957         });
1958         RSUifirstManager::Instance().ProcessForceUpdateNode();
1959         doDirectComposition_ = false;
1960         uniVisitor->SetAnimateState(doWindowAnimate_);
1961         uniVisitor->SetDirtyFlag(isDirty_ || isAccessibilityConfigChanged_ || forceUIFirstChanged_);
1962         forceUIFirstChanged_ = false;
1963         isFirstFrameOfPartialRender_ = (!isPartialRenderEnabledOfLastFrame_ || isRegionDebugEnabledOfLastFrame_) &&
1964             uniVisitor->GetIsPartialRenderEnabled() && !uniVisitor->GetIsRegionDebugEnabled();
1965         SetFocusLeashWindowId();
1966         uniVisitor->SetFocusedNodeId(focusNodeId_, focusLeashWindowId_);
1967         if (RSSystemProperties::GetQuickPrepareEnabled()) {
1968             //planning:the QuickPrepare will be replaced by Prepare
1969             rootNode->QuickPrepare(uniVisitor);
1970             uniVisitor->SurfaceOcclusionCallbackToWMS();
1971         } else {
1972             rootNode->Prepare(uniVisitor);
1973         }
1974         renderThreadParams_->selfDrawables_ = std::move(selfDrawables_);
1975         renderThreadParams_->hardwareEnabledTypeDrawables_ = std::move(hardwareEnabledDrwawables_);
1976         renderThreadParams_->isOverDrawEnabled_ = isOverDrawEnabledOfCurFrame_;
1977         isAccessibilityConfigChanged_ = false;
1978         isCurtainScreenUsingStatusChanged_ = false;
1979         RSPointLightManager::Instance()->PrepareLight();
1980         vsyncControlEnabled_ = (deviceType_ == DeviceType::PC) && RSSystemParameters::GetVSyncControlEnabled();
1981         systemAnimatedScenesEnabled_ = RSSystemParameters::GetSystemAnimatedScenesEnabled();
1982         if (!RSSystemProperties::GetQuickPrepareEnabled()) {
1983             CalcOcclusion();
1984         }
1985         if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
1986             WaitUntilUploadTextureTaskFinished(isUniRender_);
1987         }
1988         if (false) { // planning: move to prepare
1989             auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(
1990                 rootNode->GetFirstChild());
1991             std::list<std::shared_ptr<RSSurfaceRenderNode>> mainThreadNodes;
1992             std::list<std::shared_ptr<RSSurfaceRenderNode>> subThreadNodes;
1993             RSUniRenderUtil::AssignWindowNodes(displayNode, mainThreadNodes, subThreadNodes);
1994             const auto& nodeMap = context_->GetNodeMap();
1995             RSUniRenderUtil::ClearSurfaceIfNeed(nodeMap, displayNode, oldDisplayChildren_, deviceType_);
1996             RSUniRenderUtil::CacheSubThreadNodes(subThreadNodes_, subThreadNodes);
1997         }
1998         lastWatermarkFlag_ = watermarkFlag_;
1999         isPartialRenderEnabledOfLastFrame_ = uniVisitor->GetIsPartialRenderEnabled();
2000         isRegionDebugEnabledOfLastFrame_ = uniVisitor->GetIsRegionDebugEnabled();
2001         isOverDrawEnabledOfLastFrame_ = isOverDrawEnabledOfCurFrame_;
2002         // set params used in render thread
2003         uniVisitor->SetUniRenderThreadParam(renderThreadParams_);
2004     } else if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
2005         WaitUntilUploadTextureTaskFinished(isUniRender_);
2006     }
2007     PrepareUiCaptureTasks(uniVisitor);
2008     screenPowerOnChanged_ = false;
2009     forceUpdateUniRenderFlag_ = false;
2010     idleTimerExpiredFlag_ = false;
2011 }
2012 
DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode,bool waitForRT)2013 bool RSMainThread::DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode, bool waitForRT)
2014 {
2015     auto children = rootNode->GetChildren();
2016     if (children->empty()) {
2017         return false;
2018     }
2019     RS_TRACE_NAME("DoDirectComposition");
2020     RS_LOGI("DoDirectComposition time:%{public}" PRIu64, curTime_);
2021     auto displayNode = RSRenderNode::ReinterpretCast<RSDisplayRenderNode>(children->front());
2022     if (!displayNode ||
2023         displayNode->GetCompositeType() != RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE) {
2024         RS_LOGE("RSMainThread::DoDirectComposition displayNode state error");
2025         return false;
2026     }
2027     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
2028     if (screenManager == nullptr) {
2029         RS_LOGE("RSMainThread::DoDirectComposition screenManager is nullptr");
2030         return false;
2031     }
2032     auto screenInfo = screenManager->QueryScreenInfo(displayNode->GetScreenId());
2033     if (screenInfo.state != ScreenState::HDI_OUTPUT_ENABLE) {
2034         RS_LOGE("RSMainThread::DoDirectComposition: ScreenState error!");
2035         return false;
2036     }
2037     auto processor = RSProcessorFactory::CreateProcessor(displayNode->GetCompositeType());
2038     auto renderEngine = GetRenderEngine();
2039     if (processor == nullptr || renderEngine == nullptr) {
2040         RS_LOGE("RSMainThread::DoDirectComposition: RSProcessor or renderEngine is null!");
2041         return false;
2042     }
2043 
2044     if (!processor->Init(*displayNode, displayNode->GetDisplayOffsetX(), displayNode->GetDisplayOffsetY(),
2045         INVALID_SCREEN_ID, renderEngine)) {
2046         RS_LOGE("RSMainThread::DoDirectComposition: processor init failed!");
2047         return false;
2048     }
2049 
2050     if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
2051         RS_LOGW("RSMainThread::DoDirectComposition: hardwareThread task has too many to Execute");
2052     }
2053     for (auto& surfaceNode : hardwareEnabledNodes_) {
2054         auto surfaceHandler = surfaceNode->GetRSSurfaceHandler();
2055         if (!surfaceNode->IsHardwareForcedDisabled()) {
2056             auto params = static_cast<RSSurfaceRenderParams*>(surfaceNode->GetStagingRenderParams().get());
2057             if (!surfaceHandler->IsCurrentFrameBufferConsumed() && params->GetPreBuffer() != nullptr) {
2058                 params->SetPreBuffer(nullptr);
2059                 surfaceNode->AddToPendingSyncList();
2060             }
2061             processor->CreateLayer(*surfaceNode, *params);
2062             // buffer is synced to directComposition
2063             params->SetBufferSynced(true);
2064         }
2065     }
2066     RSUifirstManager::Instance().CreateUIFirstLayer(processor);
2067     auto rcdInfo = std::make_unique<RcdInfo>();
2068     DoScreenRcdTask(processor, rcdInfo, screenInfo);
2069     if (waitForRT) {
2070         RSUniRenderThread::Instance().PostSyncTask([processor, displayNode]() {
2071             RS_TRACE_NAME("DoDirectComposition PostProcess");
2072             auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
2073             hgmCore.SetDirectCompositionFlag(true);
2074             processor->ProcessDisplaySurface(*displayNode);
2075             processor->PostProcess();
2076         });
2077     } else {
2078         auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
2079         hgmCore.SetDirectCompositionFlag(true);
2080         processor->ProcessDisplaySurface(*displayNode);
2081         processor->PostProcess();
2082     }
2083 
2084     RS_LOGD("RSMainThread::DoDirectComposition end");
2085     return true;
2086 }
2087 
GetDesktopPidForRotationScene() const2088 pid_t RSMainThread::GetDesktopPidForRotationScene() const
2089 {
2090     return desktopPidForRotationScene_;
2091 }
2092 
Render()2093 void RSMainThread::Render()
2094 {
2095     if (RSSystemParameters::GetRenderStop()) {
2096         return;
2097     }
2098     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
2099     if (rootNode == nullptr) {
2100         if (RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
2101             WaitUntilUploadTextureTaskFinished(isUniRender_);
2102         }
2103         RS_LOGE("RSMainThread::Render GetGlobalRootRenderNode fail");
2104         return;
2105     }
2106     if (isUniRender_) {
2107         auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
2108         renderThreadParams_->SetTimestamp(hgmCore.GetCurrentTimestamp());
2109         renderThreadParams_->SetRequestNextVsyncFlag(needRequestNextVsyncAnimate_);
2110         renderThreadParams_->SetPendingScreenRefreshRate(hgmCore.GetPendingScreenRefreshRate());
2111         renderThreadParams_->SetPendingConstraintRelativeTime(hgmCore.GetPendingConstraintRelativeTime());
2112         renderThreadParams_->SetForceCommitLayer(isHardwareEnabledBufferUpdated_ || forceUpdateUniRenderFlag_);
2113         renderThreadParams_->SetOcclusionEnabled(RSSystemProperties::GetOcclusionEnabled());
2114         renderThreadParams_->SetCacheEnabledForRotation(RSSystemProperties::GetCacheEnabledForRotation());
2115         renderThreadParams_->SetUIFirstCurrentFrameCanSkipFirstWait(
2116             RSUifirstManager::Instance().GetCurrentFrameSkipFirstWait());
2117     }
2118     if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
2119         RSPropertyTrace::GetInstance().RefreshNodeTraceInfo();
2120     }
2121     if (focusAppBundleName_.find(DESKTOP_NAME_FOR_ROTATION) != std::string::npos) {
2122         desktopPidForRotationScene_ = focusAppPid_;
2123     }
2124     int dumpTreeCount = RSSystemParameters::GetDumpRSTreeCount();
2125     if (UNLIKELY(dumpTreeCount)) {
2126         RS_TRACE_NAME("dump rstree");
2127         RenderServiceTreeDump(g_dumpStr);
2128         RSSystemParameters::SetDumpRSTreeCount(dumpTreeCount - 1);
2129     }
2130     if (isUniRender_) {
2131         renderThreadParams_->SetWatermark(watermarkFlag_, watermarkImg_);
2132         renderThreadParams_->SetCurtainScreenUsingStatus(isCurtainScreenOn_);
2133         UniRender(rootNode);
2134         frameCount_++;
2135     } else {
2136         auto rsVisitor = std::make_shared<RSRenderServiceVisitor>();
2137         rsVisitor->SetAnimateState(doWindowAnimate_);
2138         rootNode->Prepare(rsVisitor);
2139         CalcOcclusion();
2140         bool doParallelComposition = false;
2141         if (!rsVisitor->ShouldForceSerial() && RSInnovation::GetParallelCompositionEnabled(isUniRender_)) {
2142             doParallelComposition = DoParallelComposition(rootNode);
2143         }
2144         if (doParallelComposition) {
2145             renderEngine_->ShrinkCachesIfNeeded();
2146             return;
2147         }
2148         rootNode->Process(rsVisitor);
2149         renderEngine_->ShrinkCachesIfNeeded();
2150     }
2151     if (!isUniRender_) {
2152         CallbackDrawContextStatusToWMS();
2153         CheckSystemSceneStatus();
2154         PerfForBlurIfNeeded();
2155     }
2156     UpdateLuminance();
2157 }
2158 
OnUniRenderDraw()2159 void RSMainThread::OnUniRenderDraw()
2160 {
2161     if (!isUniRender_) {
2162         return;
2163     }
2164 
2165     if (!doDirectComposition_ && needDrawFrame_) {
2166         renderThreadParams_->SetContext(context_);
2167         renderThreadParams_->SetDiscardJankFrames(GetDiscardJankFrames());
2168         drawFrame_.SetRenderThreadParams(renderThreadParams_);
2169         drawFrame_.PostAndWait();
2170         return;
2171     }
2172     // To remove ClearMemoryTask for first frame of doDirectComposition or if needed
2173     if ((doDirectComposition_ && !isLastFrameDirectComposition_) || isNeedResetClearMemoryTask_ || !needDrawFrame_) {
2174         RSUniRenderThread::Instance().PostTask([ids = context_->GetMutableNodeMap().GetAndClearPurgeableNodeIds()] {
2175             RSUniRenderThread::Instance().ResetClearMemoryTask(std::move(ids), true);
2176         });
2177         isNeedResetClearMemoryTask_ = false;
2178     }
2179 
2180     UpdateDisplayNodeScreenId();
2181     RsFrameReport& fr = RsFrameReport::GetInstance();
2182     if (fr.GetEnable()) {
2183         fr.RSRenderEnd();
2184     }
2185 }
2186 
CheckSystemSceneStatus()2187 void RSMainThread::CheckSystemSceneStatus()
2188 {
2189     std::lock_guard<std::mutex> lock(systemAnimatedScenesMutex_);
2190     uint64_t curTime = static_cast<uint64_t>(
2191         std::chrono::duration_cast<std::chrono::nanoseconds>(
2192             std::chrono::steady_clock::now().time_since_epoch()).count());
2193     while (!systemAnimatedScenesList_.empty()) {
2194         if (curTime - static_cast<uint64_t>(systemAnimatedScenesList_.front().second) > MAX_SYSTEM_SCENE_STATUS_TIME) {
2195             systemAnimatedScenesList_.pop_front();
2196         } else {
2197             break;
2198         }
2199     }
2200     while (!threeFingerScenesList_.empty()) {
2201         if (curTime - static_cast<uint64_t>(threeFingerScenesList_.front().second) > MAX_SYSTEM_SCENE_STATUS_TIME) {
2202             threeFingerScenesList_.pop_front();
2203         } else {
2204             break;
2205         }
2206     }
2207 }
2208 
CallbackDrawContextStatusToWMS(bool isUniRender)2209 void RSMainThread::CallbackDrawContextStatusToWMS(bool isUniRender)
2210 {
2211     auto& curDrawStatusVec = isUniRender ? RSUniRenderThread::Instance().GetDrawStatusVec() : curDrawStatusVec_;
2212     auto timestamp = isUniRender ? RSUniRenderThread::Instance().GetCurrentTimestamp() : timestamp_;
2213     VisibleData drawStatusVec;
2214     for (auto dynamicNodeId : curDrawStatusVec) {
2215         if (lastDrawStatusMap_.find(dynamicNodeId) == lastDrawStatusMap_.end()) {
2216             drawStatusVec.emplace_back(std::make_pair(dynamicNodeId,
2217                 WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_DYNAMIC_STATUS));
2218             RS_OPTIONAL_TRACE_NAME_FMT("%s nodeId[%" PRIu64 "] status[%d]",
2219                 __func__, dynamicNodeId, WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_DYNAMIC_STATUS);
2220         }
2221         lastDrawStatusMap_[dynamicNodeId] = timestamp;
2222     }
2223     auto drawStatusIter = lastDrawStatusMap_.begin();
2224     while (drawStatusIter != lastDrawStatusMap_.end()) {
2225         if (timestamp - drawStatusIter->second > MAX_DYNAMIC_STATUS_TIME) {
2226             drawStatusVec.emplace_back(std::make_pair(drawStatusIter->first,
2227                 WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_STATIC_STATUS));
2228             RS_OPTIONAL_TRACE_NAME_FMT("%s nodeId[%" PRIu64 "] status[%d]",
2229                 __func__, drawStatusIter->first, WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_STATIC_STATUS);
2230             auto tmpIter = drawStatusIter++;
2231             lastDrawStatusMap_.erase(tmpIter);
2232         } else {
2233             drawStatusIter++;
2234         }
2235     }
2236     curDrawStatusVec.clear();
2237     if (!drawStatusVec.empty()) {
2238         std::lock_guard<std::mutex> lock(occlusionMutex_);
2239         for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
2240             if (it->second) {
2241                 it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(drawStatusVec));
2242             }
2243         }
2244     }
2245 }
2246 
CheckSurfaceNeedProcess(OcclusionRectISet & occlusionSurfaces,std::shared_ptr<RSSurfaceRenderNode> curSurface)2247 bool RSMainThread::CheckSurfaceNeedProcess(OcclusionRectISet& occlusionSurfaces,
2248     std::shared_ptr<RSSurfaceRenderNode> curSurface)
2249 {
2250     bool needProcess = false;
2251     if (curSurface->IsFocusedNode(focusNodeId_)) {
2252         needProcess = true;
2253         if (!curSurface->HasContainerWindow() && !curSurface->IsTransparent() &&
2254             !curSurface->HasWindowCorner() &&
2255             !curSurface->GetAnimateState() && // when node animating (i.e. 3d animation), the region cannot be trusted
2256             curSurface->GetName().find("hisearch") == std::string::npos) {
2257             occlusionSurfaces.insert({curSurface->GetId(), curSurface->GetDstRect()});
2258         }
2259     } else {
2260         size_t beforeSize = occlusionSurfaces.size();
2261         occlusionSurfaces.insert({curSurface->GetId(), curSurface->GetDstRect()});
2262         bool insertSuccess = occlusionSurfaces.size() > beforeSize ? true : false;
2263         if (insertSuccess) {
2264             needProcess = true;
2265             if (curSurface->IsTransparent() ||
2266                 curSurface->HasWindowCorner() ||
2267                 curSurface->GetAnimateState() || // when node animating(i.e. 3d animation), the region cannot be trusted
2268                 curSurface->GetName().find("hisearch") != std::string::npos) {
2269                 auto iter = std::find_if(occlusionSurfaces.begin(), occlusionSurfaces.end(),
2270                     [&curSurface](const auto& r) -> bool {return r.second == curSurface->GetDstRect();});
2271                 if (iter != occlusionSurfaces.end()) {
2272                     occlusionSurfaces.erase(iter);
2273                 }
2274             }
2275         }
2276     }
2277 
2278     if (needProcess) {
2279         CheckIfNodeIsBundle(curSurface);
2280     }
2281     return needProcess;
2282 }
2283 
GetRegionVisibleLevel(const Occlusion::Region & curRegion,const Occlusion::Region & visibleRegion)2284 RSVisibleLevel RSMainThread::GetRegionVisibleLevel(const Occlusion::Region& curRegion,
2285     const Occlusion::Region& visibleRegion)
2286 {
2287     if (visibleRegion.IsEmpty()) {
2288         return RSVisibleLevel::RS_INVISIBLE;
2289     } else if (visibleRegion.Area() == curRegion.Area()) {
2290         return RSVisibleLevel::RS_ALL_VISIBLE;
2291     } else if (static_cast<uint>(visibleRegion.Area()) <
2292         (static_cast<uint>(curRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
2293         return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
2294     }
2295     return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
2296 }
2297 
CalcSurfaceNodeVisibleRegion(const std::shared_ptr<RSDisplayRenderNode> & displayNode,const std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedRegion,Occlusion::Region & curRegion,Occlusion::Region & totalRegion)2298 RSVisibleLevel RSMainThread::CalcSurfaceNodeVisibleRegion(const std::shared_ptr<RSDisplayRenderNode>& displayNode,
2299     const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2300     Occlusion::Region& accumulatedRegion, Occlusion::Region& curRegion, Occlusion::Region& totalRegion)
2301 {
2302     if (!surfaceNode) {
2303         return RSVisibleLevel::RS_INVISIBLE;
2304     }
2305 
2306     if (!isUniRender_) {
2307         if (displayNode) {
2308             surfaceNode->SetDstRect(displayNode->GetSurfaceDstRect(surfaceNode->GetId()));
2309         }
2310     }
2311 
2312     Occlusion::Rect occlusionRect = surfaceNode->GetSurfaceOcclusionRect(isUniRender_);
2313     curRegion = Occlusion::Region { occlusionRect };
2314     Occlusion::Region subRegion = curRegion.Sub(accumulatedRegion);
2315 
2316     RSVisibleLevel visibleLevel = GetRegionVisibleLevel(curRegion, subRegion);
2317 
2318     if (!isUniRender_) {
2319         Occlusion::Region visSurface = surfaceNode->GetVisibleRegion();
2320         totalRegion = subRegion.Or(visSurface);
2321     } else {
2322         totalRegion = subRegion;
2323     }
2324 
2325     return visibleLevel;
2326 }
2327 
CalcOcclusionImplementation(const std::shared_ptr<RSDisplayRenderNode> & displayNode,std::vector<RSBaseRenderNode::SharedPtr> & curAllSurfaces,VisibleData & dstCurVisVec,std::map<NodeId,RSVisibleLevel> & dstVisMapForVsyncRate)2328 void RSMainThread::CalcOcclusionImplementation(const std::shared_ptr<RSDisplayRenderNode>& displayNode,
2329     std::vector<RSBaseRenderNode::SharedPtr>& curAllSurfaces, VisibleData& dstCurVisVec,
2330     std::map<NodeId, RSVisibleLevel>& dstVisMapForVsyncRate)
2331 {
2332     Occlusion::Region accumulatedRegion;
2333     VisibleData curVisVec;
2334     OcclusionRectISet occlusionSurfaces;
2335     std::map<NodeId, RSVisibleLevel> visMapForVsyncRate;
2336     bool hasFilterCacheOcclusion = false;
2337     bool filterCacheOcclusionEnabled = RSSystemParameters::GetFilterCacheOcculusionEnabled();
2338 
2339     auto calculator = [this, &displayNode, &occlusionSurfaces, &accumulatedRegion, &curVisVec, &visMapForVsyncRate,
2340         &hasFilterCacheOcclusion, filterCacheOcclusionEnabled] (std::shared_ptr<RSSurfaceRenderNode>& curSurface,
2341         bool needSetVisibleRegion) {
2342         curSurface->setQosCal(vsyncControlEnabled_);
2343         if (!CheckSurfaceNeedProcess(occlusionSurfaces, curSurface)) {
2344             curSurface->SetVisibleRegionRecursive({}, curVisVec, visMapForVsyncRate);
2345             return;
2346         }
2347 
2348         Occlusion::Region curRegion {};
2349         Occlusion::Region totalRegion {};
2350         auto visibleLevel =
2351             CalcSurfaceNodeVisibleRegion(displayNode, curSurface, accumulatedRegion, curRegion, totalRegion);
2352 
2353         curSurface->SetVisibleRegionRecursive(totalRegion, curVisVec, visMapForVsyncRate, needSetVisibleRegion,
2354             visibleLevel, !systemAnimatedScenesList_.empty());
2355         curSurface->AccumulateOcclusionRegion(
2356             accumulatedRegion, curRegion, hasFilterCacheOcclusion, isUniRender_, filterCacheOcclusionEnabled);
2357     };
2358 
2359     for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
2360         auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2361         if (curSurface && !curSurface->IsLeashWindow()) {
2362             curSurface->SetOcclusionInSpecificScenes(deviceType_ == DeviceType::PC && !threeFingerScenesList_.empty());
2363             calculator(curSurface, true);
2364         }
2365     }
2366 
2367     // if there are valid filter cache occlusion, recalculate surfacenode visibleregionforcallback for WMS/QOS callback
2368     if (hasFilterCacheOcclusion && isUniRender_) {
2369         curVisVec.clear();
2370         visMapForVsyncRate.clear();
2371         occlusionSurfaces.clear();
2372         accumulatedRegion = {};
2373         for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
2374             auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2375             if (curSurface && !curSurface->IsLeashWindow()) {
2376                 calculator(curSurface, false);
2377             }
2378         }
2379     }
2380 
2381     dstCurVisVec.insert(dstCurVisVec.end(), curVisVec.begin(), curVisVec.end());
2382     dstVisMapForVsyncRate.insert(visMapForVsyncRate.begin(), visMapForVsyncRate.end());
2383 }
2384 
CalcOcclusion()2385 void RSMainThread::CalcOcclusion()
2386 {
2387     RS_OPTIONAL_TRACE_NAME("RSMainThread::CalcOcclusion");
2388     RS_LOGD("RSMainThread::CalcOcclusion animate:%{public}d isUniRender:%{public}d",
2389         doWindowAnimate_.load(), isUniRender_);
2390     if (doWindowAnimate_ && !isUniRender_) {
2391         return;
2392     }
2393     const std::shared_ptr<RSBaseRenderNode> node = context_->GetGlobalRootRenderNode();
2394     if (node == nullptr) {
2395         RS_LOGE("RSMainThread::CalcOcclusion GetGlobalRootRenderNode fail");
2396         return;
2397     }
2398     std::map<RSDisplayRenderNode::SharedPtr, std::vector<RSBaseRenderNode::SharedPtr>> curAllSurfacesInDisplay;
2399     std::vector<RSBaseRenderNode::SharedPtr> curAllSurfaces;
2400     for (const auto& child : *node->GetSortedChildren()) {
2401         auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(child);
2402         if (displayNode) {
2403             const auto& surfaces = displayNode->GetCurAllSurfaces();
2404             curAllSurfacesInDisplay[displayNode] = surfaces;
2405             curAllSurfaces.insert(curAllSurfaces.end(), surfaces.begin(), surfaces.end());
2406         }
2407     }
2408 
2409     if (node->GetChildrenCount()== 1) {
2410         auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(node->GetFirstChild());
2411         if (displayNode) {
2412             curAllSurfaces = displayNode->GetCurAllSurfaces();
2413         }
2414     } else {
2415         node->CollectSurface(node, curAllSurfaces, isUniRender_, false);
2416     }
2417     // Judge whether it is dirty
2418     // Surface cnt changed or surface DstRectChanged or surface ZorderChanged
2419     std::vector<NodeId> curSurfaceIds;
2420     curSurfaceIds.reserve(curAllSurfaces.size());
2421     for (auto it = curAllSurfaces.begin(); it != curAllSurfaces.end(); ++it) {
2422         auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2423         if (surface == nullptr) {
2424             continue;
2425         }
2426         curSurfaceIds.emplace_back(surface->GetId());
2427     }
2428     bool winDirty = (isDirty_ || lastFocusNodeId_ != focusNodeId_ || lastSurfaceIds_ != curSurfaceIds);
2429     lastSurfaceIds_ = std::move(curSurfaceIds);
2430     lastFocusNodeId_ = focusNodeId_;
2431     if (!winDirty) {
2432         for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
2433             auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2434             if (surface == nullptr || surface->IsLeashWindow()) {
2435                 continue;
2436             }
2437             if (surface->GetZorderChanged() || surface->GetDstRectChanged() ||
2438                 surface->IsOpaqueRegionChanged() ||
2439                 surface->GetAlphaChanged() || (isUniRender_ && surface->IsDirtyRegionUpdated())) {
2440                 winDirty = true;
2441             } else if (RSSystemParameters::GetFilterCacheOcculusionEnabled() &&
2442                 surface->IsTransparent() && surface->IsFilterCacheStatusChanged()) {
2443                 // When current frame's filter cache is valid or last frame's occlusion use filter cache as opaque
2444                 // The occlusion needs to be recalculated
2445                 winDirty = true;
2446             }
2447             surface->CleanDstRectChanged();
2448             surface->CleanAlphaChanged();
2449             surface->CleanOpaqueRegionChanged();
2450             surface->CleanDirtyRegionUpdated();
2451         }
2452     }
2453     if (!winDirty && !(systemAnimatedScenesList_.empty() && isReduceVSyncBySystemAnimatedScenes_)) {
2454         if (SurfaceOcclusionCallBackIfOnTreeStateChanged()) {
2455             SurfaceOcclusionCallback();
2456         }
2457         return;
2458     }
2459     isReduceVSyncBySystemAnimatedScenes_ = false;
2460     VisibleData dstCurVisVec;
2461     std::map<NodeId, RSVisibleLevel> dstVisMapForVsyncRate;
2462     for (auto& surfaces : curAllSurfacesInDisplay) {
2463         CalcOcclusionImplementation(surfaces.first, surfaces.second, dstCurVisVec, dstVisMapForVsyncRate);
2464     }
2465 
2466     // Callback to WMS and QOS
2467     CallbackToWMS(dstCurVisVec);
2468     SetVSyncRateByVisibleLevel(dstVisMapForVsyncRate, curAllSurfaces);
2469     // Callback for registered self drawing surfacenode
2470     SurfaceOcclusionCallback();
2471 }
2472 
CheckSurfaceVisChanged(std::map<NodeId,RSVisibleLevel> & visMapForVsyncRate,std::vector<RSBaseRenderNode::SharedPtr> & curAllSurfaces)2473 bool RSMainThread::CheckSurfaceVisChanged(std::map<NodeId, RSVisibleLevel>& visMapForVsyncRate,
2474     std::vector<RSBaseRenderNode::SharedPtr>& curAllSurfaces)
2475 {
2476     if (!systemAnimatedScenesList_.empty()) {
2477         visMapForVsyncRate.clear();
2478         for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
2479             auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2480             if (curSurface == nullptr || curSurface->GetDstRect().IsEmpty() || curSurface->IsLeashWindow()) {
2481                 continue;
2482             }
2483             visMapForVsyncRate[curSurface->GetId()] = RSVisibleLevel::RS_SYSTEM_ANIMATE_SCENE;
2484         }
2485         isReduceVSyncBySystemAnimatedScenes_ = true;
2486     }
2487     bool isVisibleChanged = visMapForVsyncRate.size() != visMapForVsyncRate.size();
2488     if (!isVisibleChanged) {
2489         auto iterCur = visMapForVsyncRate.begin();
2490         auto iterLast = lastVisMapForVsyncRate_.begin();
2491         for (; iterCur != visMapForVsyncRate.end(); iterCur++, iterLast++) {
2492             if (iterCur->first != iterLast->first ||
2493                 iterCur->second != iterLast->second) {
2494                 isVisibleChanged = true;
2495                 break;
2496             }
2497         }
2498     }
2499 
2500     if (isVisibleChanged) {
2501         lastVisMapForVsyncRate_ = visMapForVsyncRate;
2502     }
2503     return isVisibleChanged;
2504 }
2505 
SetVSyncRateByVisibleLevel(std::map<NodeId,RSVisibleLevel> & visMapForVsyncRate,std::vector<RSBaseRenderNode::SharedPtr> & curAllSurfaces)2506 void RSMainThread::SetVSyncRateByVisibleLevel(std::map<NodeId, RSVisibleLevel>& visMapForVsyncRate,
2507     std::vector<RSBaseRenderNode::SharedPtr>& curAllSurfaces)
2508 {
2509     if (!vsyncControlEnabled_ || !CheckSurfaceVisChanged(visMapForVsyncRate, curAllSurfaces) ||
2510         appVSyncDistributor_ == nullptr) {
2511         return;
2512     }
2513     RS_TRACE_NAME_FMT("%s visMapForVsyncRateSize[%lu]", __func__, visMapForVsyncRate.size());
2514     for (auto iter:visMapForVsyncRate) {
2515         if (iter.second == RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE) {
2516             appVSyncDistributor_->SetQosVSyncRate(iter.first, SIMI_VISIBLE_RATE);
2517         } else if (iter.second == RSVisibleLevel::RS_SYSTEM_ANIMATE_SCENE) {
2518             appVSyncDistributor_->SetQosVSyncRate(iter.first, SYSTEM_ANIMATED_SCENES_RATE, true);
2519         } else if (iter.second == RSVisibleLevel::RS_INVISIBLE) {
2520             appVSyncDistributor_->SetQosVSyncRate(iter.first, INVISBLE_WINDOW_RATE);
2521         } else {
2522             appVSyncDistributor_->SetQosVSyncRate(iter.first, DEFAULT_RATE);
2523         }
2524     }
2525 }
2526 
2527 
CallbackToWMS(VisibleData & curVisVec)2528 void RSMainThread::CallbackToWMS(VisibleData& curVisVec)
2529 {
2530     // if visible surfaces changed callback to WMS:
2531     // 1. curVisVec size changed
2532     // 2. curVisVec content changed
2533     bool visibleChanged = curVisVec.size() != lastVisVec_.size();
2534     std::sort(curVisVec.begin(), curVisVec.end());
2535     if (!visibleChanged) {
2536         for (uint32_t i = 0; i < curVisVec.size(); i++) {
2537             if ((curVisVec[i].first != lastVisVec_[i].first) || (curVisVec[i].second != lastVisVec_[i].second)) {
2538                 visibleChanged = true;
2539                 break;
2540             }
2541         }
2542     }
2543     if (visibleChanged) {
2544         std::lock_guard<std::mutex> lock(occlusionMutex_);
2545         for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
2546             if (it->second) {
2547                 it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(curVisVec));
2548             }
2549         }
2550     }
2551     lastVisVec_.clear();
2552     std::swap(lastVisVec_, curVisVec);
2553 }
2554 
SurfaceOcclusionCallback()2555 void RSMainThread::SurfaceOcclusionCallback()
2556 {
2557     const auto& nodeMap = context_->GetNodeMap();
2558     for (auto &listener : surfaceOcclusionListeners_) {
2559         if (savedAppWindowNode_.find(listener.first) == savedAppWindowNode_.end()) {
2560             auto node = nodeMap.GetRenderNode(listener.first);
2561             if (!node || !node->IsOnTheTree()) {
2562                 RS_LOGW("RSMainThread::SurfaceOcclusionCallback cannot find surfacenode %{public}"
2563                     PRIu64 ".", listener.first);
2564                 continue;
2565             }
2566             auto appWindowNodeId = node->GetInstanceRootNodeId();
2567             if (appWindowNodeId == INVALID_NODEID) {
2568                 RS_LOGW("RSMainThread::SurfaceOcclusionCallback surfacenode %{public}"
2569                     PRIu64 " cannot find app window node.", listener.first);
2570                 continue;
2571             }
2572             auto surfaceNode = node->ReinterpretCastTo<RSSurfaceRenderNode>();
2573             auto appWindowNode =
2574                 RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
2575             if (!surfaceNode || !appWindowNode) {
2576                 RS_LOGW("RSMainThread::SurfaceOcclusionCallback ReinterpretCastTo fail.");
2577                 continue;
2578             }
2579             savedAppWindowNode_[listener.first] = std::make_pair(surfaceNode, appWindowNode);
2580         }
2581         uint8_t level = 0;
2582         float visibleAreaRatio = 0.0f;
2583         bool isOnTheTree = savedAppWindowNode_[listener.first].first->IsOnTheTree();
2584         if (isOnTheTree) {
2585             const auto& property = savedAppWindowNode_[listener.first].second->GetRenderProperties();
2586             auto dstRect = property.GetBoundsGeometry()->GetAbsRect();
2587             if (dstRect.IsEmpty()) {
2588                 continue;
2589             }
2590             visibleAreaRatio = static_cast<float>(savedAppWindowNode_[listener.first].second->
2591                 GetVisibleRegion().Area()) / static_cast<float>(dstRect.GetWidth() * dstRect.GetHeight());
2592             auto& partitionVector = std::get<2>(listener.second); // get tuple 2 partition points vector
2593             bool vectorEmpty = partitionVector.empty();
2594             if (vectorEmpty && (visibleAreaRatio > 0.0f)) {
2595                 level = 1;
2596             } else if (!vectorEmpty && ROSEN_EQ(visibleAreaRatio, 1.0f)) {
2597                 level = partitionVector.size();
2598             } else if (!vectorEmpty && (visibleAreaRatio > 0.0f)) {
2599                 for (const auto &point : partitionVector) {
2600                     if (visibleAreaRatio > point) {
2601                         level += 1;
2602                         continue;
2603                     }
2604                     break;
2605                 }
2606             }
2607         }
2608         auto& savedLevel = std::get<3>(listener.second); // tuple 3, check visible is changed
2609         if (savedLevel != level) {
2610             RS_LOGD("RSMainThread::SurfaceOcclusionCallback surfacenode: %{public}" PRIu64 ".", listener.first);
2611             savedLevel = level;
2612             if (isOnTheTree) {
2613                 std::get<1>(listener.second)->OnSurfaceOcclusionVisibleChanged(visibleAreaRatio);
2614             }
2615         }
2616     }
2617 }
2618 
WaitHardwareThreadTaskExecute()2619 bool RSMainThread::WaitHardwareThreadTaskExecute()
2620 {
2621     std::unique_lock<std::mutex> lock(hardwareThreadTaskMutex_);
2622     return hardwareThreadTaskCond_.wait_until(lock, std::chrono::system_clock::now() +
2623         std::chrono::milliseconds(WAIT_FOR_HARDWARE_THREAD_TASK_TIMEOUT),
2624         []() { return RSHardwareThread::Instance().GetunExecuteTaskNum() <= HARDWARE_THREAD_TASK_NUM; });
2625 }
2626 
NotifyHardwareThreadCanExecuteTask()2627 void RSMainThread::NotifyHardwareThreadCanExecuteTask()
2628 {
2629     RS_TRACE_NAME("RSMainThread::NotifyHardwareThreadCanExecuteTask");
2630     std::lock_guard<std::mutex> lock(hardwareThreadTaskMutex_);
2631     hardwareThreadTaskCond_.notify_one();
2632 }
2633 
RequestNextVSync(const std::string & fromWhom,int64_t lastVSyncTS)2634 void RSMainThread::RequestNextVSync(const std::string& fromWhom, int64_t lastVSyncTS)
2635 {
2636     RS_OPTIONAL_TRACE_FUNC();
2637     VSyncReceiver::FrameCallback fcb = {
2638         .userData_ = this,
2639         .callbackWithId_ = [this](uint64_t timestamp, uint64_t frameCount, void* data) {
2640                 OnVsync(timestamp, frameCount, data);
2641             },
2642     };
2643     if (receiver_ != nullptr) {
2644         requestNextVsyncNum_++;
2645         if (requestNextVsyncNum_ > REQUEST_VSYNC_NUMBER_LIMIT) {
2646             RS_LOGD("RSMainThread::RequestNextVSync too many times:%{public}d", requestNextVsyncNum_.load());
2647         }
2648         receiver_->RequestNextVSync(fcb, fromWhom, lastVSyncTS);
2649     }
2650 }
2651 
ProcessScreenHotPlugEvents()2652 void RSMainThread::ProcessScreenHotPlugEvents()
2653 {
2654     auto screenManager_ = CreateOrGetScreenManager();
2655     if (!screenManager_) {
2656         return;
2657     }
2658 
2659     if (!screenManager_->TrySimpleProcessHotPlugEvents()) {
2660         auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
2661         if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
2662             RSHardwareThread::Instance().PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
2663         } else {
2664             PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
2665         }
2666     }
2667 }
2668 
OnVsync(uint64_t timestamp,uint64_t frameCount,void * data)2669 void RSMainThread::OnVsync(uint64_t timestamp, uint64_t frameCount, void* data)
2670 {
2671     isOnVsync_.store(true);
2672     const int64_t onVsyncStartTime = GetCurrentSystimeMs();
2673     const int64_t onVsyncStartTimeSteady = GetCurrentSteadyTimeMs();
2674     const float onVsyncStartTimeSteadyFloat = GetCurrentSteadyTimeMsFloat();
2675     RSJankStatsOnVsyncStart(onVsyncStartTime, onVsyncStartTimeSteady, onVsyncStartTimeSteadyFloat);
2676     timestamp_ = timestamp;
2677     curTime_ = static_cast<uint64_t>(
2678         std::chrono::duration_cast<std::chrono::nanoseconds>(
2679             std::chrono::steady_clock::now().time_since_epoch()).count());
2680     RS_PROFILER_PATCH_TIME(timestamp_);
2681     RS_PROFILER_PATCH_TIME(curTime_);
2682     requestNextVsyncNum_ = 0;
2683     vsyncId_ = frameCount;
2684     frameCount_++;
2685     if (isUniRender_) {
2686         MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
2687         if (RSUnmarshalThread::Instance().CachedTransactionDataEmpty()) {
2688             // set needWaitUnmarshalFinished_ to false, it means mainLoop do not wait unmarshalBarrierTask_
2689             needWaitUnmarshalFinished_ = false;
2690         } else {
2691             RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
2692         }
2693     }
2694     mainLoop_();
2695 #if defined(RS_ENABLE_CHIPSET_VSYNC)
2696     SetVsyncInfo(timestamp);
2697 #endif
2698     ProcessScreenHotPlugEvents();
2699     RSJankStatsOnVsyncEnd(onVsyncStartTime, onVsyncStartTimeSteady, onVsyncStartTimeSteadyFloat);
2700     isOnVsync_.store(false);
2701 }
2702 
RSJankStatsOnVsyncStart(int64_t onVsyncStartTime,int64_t onVsyncStartTimeSteady,float onVsyncStartTimeSteadyFloat)2703 void RSMainThread::RSJankStatsOnVsyncStart(int64_t onVsyncStartTime, int64_t onVsyncStartTimeSteady,
2704                                            float onVsyncStartTimeSteadyFloat)
2705 {
2706     if (isUniRender_) {
2707         if (!renderThreadParams_) {
2708             // fill the params, and sync to render thread later
2709             renderThreadParams_ = std::make_unique<RSRenderThreadParams>();
2710         }
2711         renderThreadParams_->SetIsUniRenderAndOnVsync(true);
2712         renderThreadParams_->SetOnVsyncStartTime(onVsyncStartTime);
2713         renderThreadParams_->SetOnVsyncStartTimeSteady(onVsyncStartTimeSteady);
2714         renderThreadParams_->SetOnVsyncStartTimeSteadyFloat(onVsyncStartTimeSteadyFloat);
2715         SetSkipJankAnimatorFrame(false);
2716     }
2717 }
2718 
GetSelfDrawingNodes() const2719 const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& RSMainThread::GetSelfDrawingNodes() const
2720 {
2721     return selfDrawingNodes_;
2722 }
2723 
GetSelfDrawables() const2724 const std::vector<DrawableV2::RSRenderNodeDrawableAdapter::SharedPtr>& RSMainThread::GetSelfDrawables() const
2725 {
2726     return selfDrawables_;
2727 }
2728 
RSJankStatsOnVsyncEnd(int64_t onVsyncStartTime,int64_t onVsyncStartTimeSteady,float onVsyncStartTimeSteadyFloat)2729 void RSMainThread::RSJankStatsOnVsyncEnd(int64_t onVsyncStartTime, int64_t onVsyncStartTimeSteady,
2730                                          float onVsyncStartTimeSteadyFloat)
2731 {
2732     if (isUniRender_ && doDirectComposition_) {
2733         const JankDurationParams rsParams = { .timeStart_ = onVsyncStartTime,
2734                                               .timeStartSteady_ = onVsyncStartTimeSteady,
2735                                               .timeStartSteadyFloat_ = onVsyncStartTimeSteadyFloat,
2736                                               .timeEnd_ = GetCurrentSystimeMs(),
2737                                               .timeEndSteady_ = GetCurrentSteadyTimeMs(),
2738                                               .timeEndSteadyFloat_ = GetCurrentSteadyTimeMsFloat(),
2739                                               .refreshRate_ = GetDynamicRefreshRate(),
2740                                               .discardJankFrames_ = GetDiscardJankFrames(),
2741                                               .skipJankAnimatorFrame_ = GetSkipJankAnimatorFrame() };
2742         drawFrame_.PostDirectCompositionJankStats(rsParams);
2743     }
2744     if (isUniRender_) {
2745         SetDiscardJankFrames(false);
2746     }
2747 }
2748 
2749 #if defined(RS_ENABLE_CHIPSET_VSYNC)
ConnectChipsetVsyncSer()2750 void RSMainThread::ConnectChipsetVsyncSer()
2751 {
2752     if (initVsyncServiceFlag_ && (OHOS::Camera::ChipsetVsyncImpl::Instance().InitChipsetVsyncImpl() == -1)) {
2753         initVsyncServiceFlag_ = true;
2754     } else {
2755         initVsyncServiceFlag_ = false;
2756     }
2757 }
2758 #endif
2759 
2760 #if defined(RS_ENABLE_CHIPSET_VSYNC)
SetVsyncInfo(uint64_t timestamp)2761 void RSMainThread::SetVsyncInfo(uint64_t timestamp)
2762 {
2763     int64_t vsyncPeriod = 0;
2764     if (receiver_) {
2765         receiver_->GetVSyncPeriod(vsyncPeriod);
2766     }
2767     OHOS::Camera::ChipsetVsyncImpl::Instance().SetVsyncImpl(timestamp, vsyncPeriod);
2768     RS_LOGD("UpdateVsyncTime = %{public}lld, period = %{public}lld",
2769         static_cast<long long>(timestamp), static_cast<long long>(vsyncPeriod));
2770 }
2771 #endif
2772 
Animate(uint64_t timestamp)2773 void RSMainThread::Animate(uint64_t timestamp)
2774 {
2775     RS_TRACE_FUNC();
2776     lastAnimateTimestamp_ = timestamp;
2777     rsCurrRange_.Reset();
2778     needRequestNextVsyncAnimate_ = false;
2779 
2780     if (context_->animatingNodeList_.empty()) {
2781         doWindowAnimate_ = false;
2782         context_->SetRequestedNextVsyncAnimate(false);
2783         return;
2784     }
2785     UpdateAnimateNodeFlag();
2786     doDirectComposition_ = false;
2787     RS_OPTIONAL_TRACE_NAME_FMT("rs debug: %s doDirectComposition false", __func__);
2788     bool curWinAnim = false;
2789     bool needRequestNextVsync = false;
2790     // isCalculateAnimationValue is embedded modify for stat animate frame drop
2791     bool isCalculateAnimationValue = false;
2792     bool isRateDeciderEnabled = (context_->animatingNodeList_.size() <= CAL_NODE_PREFERRED_FPS_LIMIT);
2793     bool isDisplaySyncEnabled = true;
2794     int64_t period = 0;
2795     if (receiver_) {
2796         receiver_->GetVSyncPeriod(period);
2797     }
2798     RSRenderAnimation::isCalcAnimateVelocity_ = isRateDeciderEnabled;
2799     uint32_t totalAnimationSize = 0;
2800     uint32_t animatingNodeSize = context_->animatingNodeList_.size();
2801     bool needPrintAnimationDFX = false;
2802     std::set<pid_t> animationPids;
2803     if (IsTagEnabled(HITRACE_TAG_GRAPHIC_AGP)) {
2804         auto screenManager = CreateOrGetScreenManager();
2805         needPrintAnimationDFX = screenManager != nullptr && screenManager->IsAllScreensPowerOff();
2806     }
2807     // iterate and animate all animating nodes, remove if animation finished
2808     EraseIf(context_->animatingNodeList_,
2809         [this, timestamp, period, isDisplaySyncEnabled, isRateDeciderEnabled, &totalAnimationSize,
2810         &curWinAnim, &needRequestNextVsync, &isCalculateAnimationValue, &needPrintAnimationDFX,
2811         &animationPids](const auto& iter) -> bool {
2812         auto node = iter.second.lock();
2813         if (node == nullptr) {
2814             RS_LOGD("RSMainThread::Animate removing expired animating node");
2815             return true;
2816         }
2817         if (cacheCmdSkippedInfo_.count(ExtractPid(node->GetId())) > 0) {
2818             rsCurrRange_.Merge(node->animationManager_.GetDecideFrameRateRange());
2819             RS_LOGD("RSMainThread::Animate skip the cached node");
2820             return false;
2821         }
2822         totalAnimationSize += node->animationManager_.GetAnimationsSize();
2823         auto frameRateGetFunc = [this](const RSPropertyUnit unit, float velocity) -> int32_t {
2824             if (frameRateMgr_ != nullptr) {
2825                 return frameRateMgr_->GetExpectedFrameRate(unit, velocity);
2826             }
2827             return 0;
2828         };
2829         node->animationManager_.SetRateDeciderEnable(isRateDeciderEnabled, frameRateGetFunc);
2830         auto [hasRunningAnimation, nodeNeedRequestNextVsync, nodeCalculateAnimationValue] =
2831             node->Animate(timestamp, period, isDisplaySyncEnabled);
2832         if (!hasRunningAnimation) {
2833             node->InActivateDisplaySync();
2834             RS_LOGD("RSMainThread::Animate removing finished animating node %{public}" PRIu64, node->GetId());
2835         } else {
2836             node->UpdateDisplaySyncRange();
2837             rsCurrRange_.Merge(node->animationManager_.GetDecideFrameRateRange());
2838         }
2839         // request vsync if: 1. node has running animation, or 2. transition animation just ended
2840         needRequestNextVsync = needRequestNextVsync || nodeNeedRequestNextVsync || (node.use_count() == 1);
2841         isCalculateAnimationValue = isCalculateAnimationValue || nodeCalculateAnimationValue;
2842         if (node->template IsInstanceOf<RSSurfaceRenderNode>() && hasRunningAnimation) {
2843             if (isUniRender_) {
2844                 auto surfacenode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
2845                 surfacenode->SetAnimateState();
2846             }
2847             curWinAnim = true;
2848         }
2849         if (needPrintAnimationDFX && needRequestNextVsync && node->animationManager_.GetAnimationsSize() > 0) {
2850             animationPids.insert(node->animationManager_.GetAnimationPid());
2851         }
2852         return !hasRunningAnimation;
2853     });
2854     if (needPrintAnimationDFX && needRequestNextVsync && animationPids.size() > 0) {
2855         std::string pidList;
2856         for (const auto& pid : animationPids) {
2857             pidList += "[" + std::to_string(pid) + "]";
2858         }
2859         RS_TRACE_NAME_FMT("Animate from pid %s", pidList.c_str());
2860     }
2861 
2862     RS_TRACE_NAME_FMT("Animate [nodeSize, totalAnimationSize] is [%lu, %lu]", animatingNodeSize, totalAnimationSize);
2863     if (!isCalculateAnimationValue && needRequestNextVsync) {
2864         RS_TRACE_NAME("Animation running empty");
2865     }
2866 
2867     doWindowAnimate_ = curWinAnim;
2868     RS_LOGD("RSMainThread::Animate end, animating nodes remains, has window animation: %{public}d", curWinAnim);
2869 
2870     if (needRequestNextVsync) {
2871         HgmEnergyConsumptionPolicy::Instance().StatisticAnimationTime(timestamp / NS_PER_MS);
2872         if (!rsVSyncDistributor_->IsDVsyncOn()) {
2873             RequestNextVSync("animate", timestamp_);
2874         } else {
2875             needRequestNextVsyncAnimate_ = true;  // set the member variable instead of directly calling rnv
2876             RS_TRACE_NAME("rs_RequestNextVSync");
2877         }
2878     } else if (isUniRender_) {
2879         renderThreadParams_->SetImplicitAnimationEnd(true);
2880     }
2881     context_->SetRequestedNextVsyncAnimate(needRequestNextVsync);
2882 
2883     PerfAfterAnim(needRequestNextVsync);
2884 }
2885 
UpdateAceDebugBoundaryEnabled()2886 void RSMainThread::UpdateAceDebugBoundaryEnabled()
2887 {
2888     if (!isOverDrawEnabledOfCurFrame_) {
2889         return;
2890     }
2891     bool isAceDebugBoundaryEnabled = RSSystemProperties::GetAceDebugBoundaryEnabled();
2892     if (isAceDebugBoundaryEnabledOfLastFrame_ && !isAceDebugBoundaryEnabled) {
2893         if (!hasPostUpdateAceDebugBoundaryTask_) {
2894             PostTask(
2895                 [isAceDebugBoundaryEnabled, this]() {
2896                     SetDirtyFlag();
2897                     RequestNextVSync();
2898                     isAceDebugBoundaryEnabledOfLastFrame_ = isAceDebugBoundaryEnabled;
2899                     hasPostUpdateAceDebugBoundaryTask_ = false;
2900                 },
2901                 "UpdateAceBoundaryEnabledTask", DELAY_TIME_FOR_ACE_BOUNDARY_UPDATE);
2902             hasPostUpdateAceDebugBoundaryTask_ = true;
2903         }
2904         renderThreadParams_->isAceDebugBoundaryEnabled_ = true;
2905     } else {
2906         if (hasPostUpdateAceDebugBoundaryTask_) {
2907             handler_->RemoveTask("UpdateAceBoundaryEnabledTask");
2908             hasPostUpdateAceDebugBoundaryTask_ = false;
2909         }
2910         renderThreadParams_->isAceDebugBoundaryEnabled_ = isAceDebugBoundaryEnabled;
2911         isAceDebugBoundaryEnabledOfLastFrame_ = isAceDebugBoundaryEnabled;
2912     }
2913 }
2914 
IsNeedProcessBySingleFrameComposer(std::unique_ptr<RSTransactionData> & rsTransactionData)2915 bool RSMainThread::IsNeedProcessBySingleFrameComposer(std::unique_ptr<RSTransactionData>& rsTransactionData)
2916 {
2917     if (!isUniRender_ || !rsTransactionData) {
2918         return false;
2919     }
2920 
2921     if (!RSSingleFrameComposer::IsShouldProcessByIpcThread(rsTransactionData->GetSendingPid()) &&
2922         !RSSystemProperties::GetSingleFrameComposerEnabled()) {
2923         return false;
2924     }
2925 
2926     // animation node will call RequestNextVsync() in mainLoop_, here we simply ignore animation scenario
2927     if (!context_->animatingNodeList_.empty()) {
2928         return false;
2929     }
2930 
2931     // ignore mult-window scenario
2932     auto currentVisibleLeashWindowCount = context_->GetNodeMap().GetVisibleLeashWindowCount();
2933     if (currentVisibleLeashWindowCount >= MULTI_WINDOW_PERF_START_NUM) {
2934         return false;
2935     }
2936 
2937     return true;
2938 }
2939 
ProcessDataBySingleFrameComposer(std::unique_ptr<RSTransactionData> & rsTransactionData)2940 void RSMainThread::ProcessDataBySingleFrameComposer(std::unique_ptr<RSTransactionData>& rsTransactionData)
2941 {
2942     if (!rsTransactionData || !isUniRender_) {
2943         return;
2944     }
2945 
2946     if (RSSystemProperties::GetSingleFrameComposerEnabled()) {
2947         RSSingleFrameComposer::SetSingleFrameFlag(std::this_thread::get_id());
2948         context_->transactionTimestamp_ = rsTransactionData->GetTimestamp();
2949         rsTransactionData->ProcessBySingleFrameComposer(*context_);
2950     }
2951 
2952     RecvAndProcessRSTransactionDataImmediately(rsTransactionData);
2953 }
2954 
RecvAndProcessRSTransactionDataImmediately(std::unique_ptr<RSTransactionData> & rsTransactionData)2955 void RSMainThread::RecvAndProcessRSTransactionDataImmediately(std::unique_ptr<RSTransactionData>& rsTransactionData)
2956 {
2957     if (!rsTransactionData || !isUniRender_) {
2958         return;
2959     }
2960     RS_TRACE_NAME("ProcessBySingleFrameComposer");
2961     {
2962         std::lock_guard<std::mutex> lock(transitionDataMutex_);
2963         cachedTransactionDataMap_[rsTransactionData->GetSendingPid()].emplace_back(std::move(rsTransactionData));
2964     }
2965     ForceRefreshForUni();
2966 }
2967 
RecvRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)2968 void RSMainThread::RecvRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
2969 {
2970     if (!rsTransactionData) {
2971         return;
2972     }
2973     if (isUniRender_) {
2974         std::lock_guard<std::mutex> lock(transitionDataMutex_);
2975         cachedTransactionDataMap_[rsTransactionData->GetSendingPid()].emplace_back(std::move(rsTransactionData));
2976     } else {
2977         ClassifyRSTransactionData(rsTransactionData);
2978     }
2979     RequestNextVSync();
2980 }
2981 
ClassifyRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)2982 void RSMainThread::ClassifyRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
2983 {
2984     const auto& nodeMap = context_->GetNodeMap();
2985     std::lock_guard<std::mutex> lock(transitionDataMutex_);
2986     std::unique_ptr<RSTransactionData> transactionData(std::move(rsTransactionData));
2987     auto timestamp = transactionData->GetTimestamp();
2988     RS_LOGD("RSMainThread::RecvRSTransactionData timestamp = %{public}" PRIu64, timestamp);
2989     for (auto& [nodeId, followType, command] : transactionData->GetPayload()) {
2990         if (nodeId == 0 || followType == FollowType::NONE) {
2991             pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
2992             continue;
2993         }
2994         auto node = nodeMap.GetRenderNode(nodeId);
2995         if (node && followType == FollowType::FOLLOW_TO_PARENT) {
2996             auto parentNode = node->GetParent().lock();
2997             if (parentNode) {
2998                 nodeId = parentNode->GetId();
2999             } else {
3000                 pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
3001                 continue;
3002             }
3003         }
3004         cachedCommands_[nodeId][timestamp].emplace_back(std::move(command));
3005     }
3006 }
3007 
PostTask(RSTaskMessage::RSTask task)3008 void RSMainThread::PostTask(RSTaskMessage::RSTask task)
3009 {
3010     if (handler_) {
3011         handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
3012     }
3013 }
3014 
PostTask(RSTaskMessage::RSTask task,const std::string & name,int64_t delayTime,AppExecFwk::EventQueue::Priority priority)3015 void RSMainThread::PostTask(RSTaskMessage::RSTask task, const std::string& name, int64_t delayTime,
3016     AppExecFwk::EventQueue::Priority priority)
3017 {
3018     if (handler_) {
3019         handler_->PostTask(task, name, delayTime, priority);
3020     }
3021 }
3022 
RemoveTask(const std::string & name)3023 void RSMainThread::RemoveTask(const std::string& name)
3024 {
3025     if (handler_) {
3026         handler_->RemoveTask(name);
3027     }
3028 }
3029 
PostSyncTask(RSTaskMessage::RSTask task)3030 void RSMainThread::PostSyncTask(RSTaskMessage::RSTask task)
3031 {
3032     if (handler_) {
3033         handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
3034     }
3035 }
3036 
IsIdle() const3037 bool RSMainThread::IsIdle() const
3038 {
3039     return handler_ ? handler_->IsIdle() : false;
3040 }
3041 
RegisterApplicationAgent(uint32_t pid,sptr<IApplicationAgent> app)3042 void RSMainThread::RegisterApplicationAgent(uint32_t pid, sptr<IApplicationAgent> app)
3043 {
3044     applicationAgentMap_.emplace(pid, app);
3045 }
3046 
UnRegisterApplicationAgent(sptr<IApplicationAgent> app)3047 void RSMainThread::UnRegisterApplicationAgent(sptr<IApplicationAgent> app)
3048 {
3049     EraseIf(applicationAgentMap_,
3050         [&app](const auto& iter) { return iter.second && app && iter.second->AsObject() == app->AsObject(); });
3051 }
3052 
RegisterOcclusionChangeCallback(pid_t pid,sptr<RSIOcclusionChangeCallback> callback)3053 void RSMainThread::RegisterOcclusionChangeCallback(pid_t pid, sptr<RSIOcclusionChangeCallback> callback)
3054 {
3055     std::lock_guard<std::mutex> lock(occlusionMutex_);
3056     occlusionListeners_[pid] = callback;
3057 }
3058 
UnRegisterOcclusionChangeCallback(pid_t pid)3059 void RSMainThread::UnRegisterOcclusionChangeCallback(pid_t pid)
3060 {
3061     std::lock_guard<std::mutex> lock(occlusionMutex_);
3062     occlusionListeners_.erase(pid);
3063 }
3064 
RegisterSurfaceOcclusionChangeCallback(NodeId id,pid_t pid,sptr<RSISurfaceOcclusionChangeCallback> callback,std::vector<float> & partitionPoints)3065 void RSMainThread::RegisterSurfaceOcclusionChangeCallback(
3066     NodeId id, pid_t pid, sptr<RSISurfaceOcclusionChangeCallback> callback, std::vector<float>& partitionPoints)
3067 {
3068     std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
3069     uint8_t level = 1;
3070     if (!partitionPoints.empty()) {
3071         level = partitionPoints.size();
3072     }
3073     surfaceOcclusionListeners_[id] = std::make_tuple(pid, callback, partitionPoints, level);
3074 }
3075 
UnRegisterSurfaceOcclusionChangeCallback(NodeId id)3076 void RSMainThread::UnRegisterSurfaceOcclusionChangeCallback(NodeId id)
3077 {
3078     std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
3079     surfaceOcclusionListeners_.erase(id);
3080     savedAppWindowNode_.erase(id);
3081 }
3082 
ClearSurfaceOcclusionChangeCallback(pid_t pid)3083 void RSMainThread::ClearSurfaceOcclusionChangeCallback(pid_t pid)
3084 {
3085     std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
3086     for (auto it = surfaceOcclusionListeners_.begin(); it != surfaceOcclusionListeners_.end();) {
3087         if (std::get<0>(it->second) == pid) {
3088             if (savedAppWindowNode_.find(it->first) != savedAppWindowNode_.end()) {
3089                 savedAppWindowNode_.erase(it->first);
3090             }
3091             surfaceOcclusionListeners_.erase(it++);
3092         } else {
3093             it++;
3094         }
3095     }
3096 }
3097 
SurfaceOcclusionChangeCallback(VisibleData & dstCurVisVec)3098 void RSMainThread::SurfaceOcclusionChangeCallback(VisibleData& dstCurVisVec)
3099 {
3100     std::lock_guard<std::mutex> lock(occlusionMutex_);
3101     for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
3102         if (it->second) {
3103             it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(dstCurVisVec));
3104         }
3105     }
3106 }
3107 
SurfaceOcclusionCallBackIfOnTreeStateChanged()3108 bool RSMainThread::SurfaceOcclusionCallBackIfOnTreeStateChanged()
3109 {
3110     std::vector<NodeId> registeredSurfaceOnTree;
3111     for (auto it = savedAppWindowNode_.begin(); it != savedAppWindowNode_.end(); ++it) {
3112         if (it->second.first->IsOnTheTree()) {
3113             registeredSurfaceOnTree.push_back(it->first);
3114         }
3115     }
3116     if (lastRegisteredSurfaceOnTree_ != registeredSurfaceOnTree) {
3117         lastRegisteredSurfaceOnTree_ = registeredSurfaceOnTree;
3118         return true;
3119     }
3120     return false;
3121 }
3122 
SendCommands()3123 void RSMainThread::SendCommands()
3124 {
3125     RS_OPTIONAL_TRACE_FUNC();
3126     RsFrameReport& fr = RsFrameReport::GetInstance();
3127     if (fr.GetEnable()) {
3128         fr.SendCommandsStart();
3129         fr.RenderEnd();
3130     }
3131     if (!context_->needSyncFinishAnimationList_.empty()) {
3132         for (const auto [nodeId, animationId] : context_->needSyncFinishAnimationList_) {
3133             RS_LOGI("RSMainThread::SendCommands sync finish animation node is %{public}" PRIu64 ","
3134                 " animation is %{public}" PRIu64, nodeId, animationId);
3135             std::unique_ptr<RSCommand> command =
3136                 std::make_unique<RSAnimationCallback>(nodeId, animationId, FINISHED);
3137             RSMessageProcessor::Instance().AddUIMessage(ExtractPid(animationId), std::move(command));
3138         }
3139         context_->needSyncFinishAnimationList_.clear();
3140     }
3141     if (!RSMessageProcessor::Instance().HasTransaction()) {
3142         return;
3143     }
3144 
3145     // dispatch messages to corresponding application
3146     auto transactionMapPtr = std::make_shared<std::unordered_map<uint32_t, std::shared_ptr<RSTransactionData>>>(
3147         RSMessageProcessor::Instance().GetAllTransactions());
3148     PostTask([this, transactionMapPtr]() {
3149         std::string dfxString;
3150         for (const auto& transactionIter : *transactionMapPtr) {
3151             auto pid = transactionIter.first;
3152             auto appIter = applicationAgentMap_.find(pid);
3153             if (appIter == applicationAgentMap_.end()) {
3154                 RS_LOGW("RSMainThread::SendCommand no application agent registered as pid %{public}d,"
3155                     "this will cause memory leak!", pid);
3156                 continue;
3157             }
3158             auto& app = appIter->second;
3159             auto transactionPtr = transactionIter.second;
3160             if (transactionPtr != nullptr) {
3161                 dfxString += "[pid:" + std::to_string(pid) + ",cmdIndex:" + std::to_string(transactionPtr->GetIndex())
3162                     + ",cmdCount:" + std::to_string(transactionPtr->GetCommandCount()) + "]";
3163             }
3164             app->OnTransaction(transactionPtr);
3165         }
3166         RS_LOGI("RSMainThread::SendCommand to %{public}s", dfxString.c_str());
3167         RS_TRACE_NAME_FMT("RSMainThread::SendCommand to %s", dfxString.c_str());
3168     });
3169 }
3170 
RenderServiceTreeDump(std::string & dumpString,bool forceDumpSingleFrame)3171 void RSMainThread::RenderServiceTreeDump(std::string& dumpString, bool forceDumpSingleFrame)
3172 {
3173     if (LIKELY(forceDumpSingleFrame)) {
3174         RS_TRACE_NAME("GetDumpTree");
3175         dumpString.append("-- RS transactionFlags: " + transactionFlags_ + "\n");
3176         dumpString.append("-- current timeStamp: " + std::to_string(timestamp_) + "\n");
3177         dumpString.append("-- vsyncId: " + std::to_string(vsyncId_) + "\n");
3178         dumpString.append("Animating Node: [");
3179         for (auto& [nodeId, _]: context_->animatingNodeList_) {
3180             dumpString.append(std::to_string(nodeId) + ", ");
3181         }
3182         dumpString.append("];\n");
3183         const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3184         if (rootNode == nullptr) {
3185             dumpString.append("rootNode is null\n");
3186             return;
3187         }
3188         rootNode->DumpTree(0, dumpString);
3189 
3190         dumpString += "\n====================================\n";
3191         RSUniRenderThread::Instance().RenderServiceTreeDump(dumpString);
3192     } else {
3193         dumpString += g_dumpStr;
3194         g_dumpStr = "";
3195     }
3196 }
3197 
SendClientDumpNodeTreeCommands(uint32_t taskId)3198 void RSMainThread::SendClientDumpNodeTreeCommands(uint32_t taskId)
3199 {
3200     RS_TRACE_NAME_FMT("DumpClientNodeTree start task[%u]", taskId);
3201     std::unique_lock<std::mutex> lock(nodeTreeDumpMutex_);
3202     if (nodeTreeDumpTasks_.find(taskId) != nodeTreeDumpTasks_.end()) {
3203         RS_LOGW("SendClientDumpNodeTreeCommands task[%{public}u] duplicate", taskId);
3204         return;
3205     }
3206 
3207     std::unordered_map<pid_t, std::vector<NodeId>> topNodes;
3208     if (const auto& rootNode = context_->GetGlobalRootRenderNode()) {
3209         for (const auto& displayNode : *rootNode->GetSortedChildren()) {
3210             for (const auto& node : *displayNode->GetSortedChildren()) {
3211                 NodeId id = node->GetId();
3212                 topNodes[ExtractPid(id)].push_back(id);
3213             }
3214         }
3215     }
3216     context_->GetNodeMap().TraversalNodes([this, &topNodes] (const std::shared_ptr<RSBaseRenderNode>& node) {
3217         if (node->IsOnTheTree() && node->GetType() == RSRenderNodeType::ROOT_NODE) {
3218             if (auto parent = node->GetParent().lock()) {
3219                 NodeId id = parent->GetId();
3220                 topNodes[ExtractPid(id)].push_back(id);
3221             }
3222             NodeId id = node->GetId();
3223             topNodes[ExtractPid(id)].push_back(id);
3224         }
3225     });
3226 
3227     auto& task = nodeTreeDumpTasks_[taskId];
3228     for (const auto& [pid, nodeIds] : topNodes) {
3229         auto iter = applicationAgentMap_.find(pid);
3230         if (iter == applicationAgentMap_.end() || !iter->second) {
3231             continue;
3232         }
3233         auto transactionData = std::make_shared<RSTransactionData>();
3234         for (auto id : nodeIds) {
3235             auto command = std::make_unique<RSDumpClientNodeTree>(id, pid, taskId);
3236             transactionData->AddCommand(std::move(command), id, FollowType::NONE);
3237             task.count++;
3238             RS_TRACE_NAME_FMT("DumpClientNodeTree add task[%u] pid[%u] node[%" PRIu64 "]",
3239                 taskId, pid, id);
3240             RS_LOGI("SendClientDumpNodeTreeCommands add task[%{public}u] pid[%u] node[%" PRIu64 "]",
3241                 taskId, pid, id);
3242         }
3243         iter->second->OnTransaction(transactionData);
3244     }
3245     RS_LOGI("SendClientDumpNodeTreeCommands send task[%{public}u] count[%{public}zu]",
3246         taskId, task.count);
3247 }
3248 
CollectClientNodeTreeResult(uint32_t taskId,std::string & dumpString,size_t timeout)3249 void RSMainThread::CollectClientNodeTreeResult(uint32_t taskId, std::string& dumpString, size_t timeout)
3250 {
3251     std::unique_lock<std::mutex> lock(nodeTreeDumpMutex_);
3252     {
3253         RS_TRACE_NAME_FMT("DumpClientNodeTree wait task[%u]", taskId);
3254         nodeTreeDumpCondVar_.wait_for(lock, std::chrono::milliseconds(timeout), [this, taskId] () {
3255             const auto& task = nodeTreeDumpTasks_[taskId];
3256             return task.completionCount == task.count;
3257         });
3258     }
3259 
3260     const auto& task = nodeTreeDumpTasks_[taskId];
3261     size_t completed = task.completionCount;
3262     RS_TRACE_NAME_FMT("DumpClientNodeTree end task[%u] completionCount[%zu]", taskId, completed);
3263     dumpString += "\n-- ClientNodeTreeDump: ";
3264     for (const auto& [pid, data] : task.data) {
3265         dumpString += "\n| pid[";
3266         dumpString += std::to_string(pid);
3267         dumpString += "]";
3268         if (data) {
3269             dumpString += "\n";
3270             dumpString += data.value();
3271         }
3272     }
3273     nodeTreeDumpTasks_.erase(taskId);
3274 
3275     RS_LOGI("CollectClientNodeTreeResult task[%{public}u] completionCount[%{public}zu]",
3276         taskId, completed);
3277 }
3278 
OnCommitDumpClientNodeTree(NodeId nodeId,pid_t pid,uint32_t taskId,const std::string & result)3279 void RSMainThread::OnCommitDumpClientNodeTree(NodeId nodeId, pid_t pid, uint32_t taskId, const std::string& result)
3280 {
3281     RS_TRACE_NAME_FMT("DumpClientNodeTree collected task[%u] dataSize[%zu] pid[%d]",
3282         taskId, result.size(), pid);
3283     {
3284         std::unique_lock<std::mutex> lock(nodeTreeDumpMutex_);
3285         auto iter = nodeTreeDumpTasks_.find(taskId);
3286         if (iter == nodeTreeDumpTasks_.end()) {
3287             RS_LOGW("OnDumpClientNodeTree task[%{public}u] not found for pid[%d]", taskId, pid);
3288             return;
3289         }
3290 
3291         iter->second.completionCount++;
3292         auto& data = iter->second.data[pid];
3293         if (data) {
3294             data->append("\n");
3295             data->append(result);
3296         } else {
3297             data = result;
3298         }
3299     }
3300     nodeTreeDumpCondVar_.notify_all();
3301 
3302     RS_LOGI("OnDumpClientNodeTree task[%{public}u] dataSize[%{public}zu] pid[%d]",
3303         taskId, result.size(), pid);
3304 }
3305 
3306 
DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)3307 bool RSMainThread::DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)
3308 {
3309     using CreateParallelSyncSignalFunc = void* (*)(uint32_t);
3310     using SignalCountDownFunc = void (*)(void*);
3311     using SignalAwaitFunc = void (*)(void*);
3312     using AssignTaskFunc = void (*)(std::function<void()>);
3313     using RemoveStoppedThreadsFunc = void (*)();
3314 
3315     auto CreateParallelSyncSignal = (CreateParallelSyncSignalFunc)RSInnovation::_s_createParallelSyncSignal;
3316     auto SignalCountDown = (SignalCountDownFunc)RSInnovation::_s_signalCountDown;
3317     auto SignalAwait = (SignalAwaitFunc)RSInnovation::_s_signalAwait;
3318     auto AssignTask = (AssignTaskFunc)RSInnovation::_s_assignTask;
3319     auto RemoveStoppedThreads = (RemoveStoppedThreadsFunc)RSInnovation::_s_removeStoppedThreads;
3320 
3321     void* syncSignal = (*CreateParallelSyncSignal)(rootNode->GetChildrenCount());
3322     if (!syncSignal) {
3323         return false;
3324     }
3325 
3326     (*RemoveStoppedThreads)();
3327 
3328     auto children = *rootNode->GetSortedChildren();
3329     bool animate_ = doWindowAnimate_;
3330     for (auto it = children.rbegin(); it != children.rend(); it++) {
3331         auto child = *it;
3332         auto task = [&syncSignal, SignalCountDown, child, animate_]() {
3333             std::shared_ptr<RSNodeVisitor> visitor;
3334             auto rsVisitor = std::make_shared<RSRenderServiceVisitor>(true);
3335             rsVisitor->SetAnimateState(animate_);
3336             visitor = rsVisitor;
3337             child->Process(visitor);
3338             (*SignalCountDown)(syncSignal);
3339         };
3340         if (*it == *children.begin()) {
3341             task();
3342         } else {
3343             (*AssignTask)(task);
3344         }
3345     }
3346     (*SignalAwait)(syncSignal);
3347     return true;
3348 }
3349 
ClearTransactionDataPidInfo(pid_t remotePid)3350 void RSMainThread::ClearTransactionDataPidInfo(pid_t remotePid)
3351 {
3352     if (!isUniRender_) {
3353         return;
3354     }
3355     std::lock_guard<std::mutex> lock(transitionDataMutex_);
3356     auto it = effectiveTransactionDataIndexMap_.find(remotePid);
3357     if (it != effectiveTransactionDataIndexMap_.end()) {
3358         if (!it->second.second.empty()) {
3359             RS_LOGD("RSMainThread::ClearTransactionDataPidInfo process:%{public}d destroyed, skip commands", remotePid);
3360         }
3361         effectiveTransactionDataIndexMap_.erase(it);
3362     }
3363     transactionDataLastWaitTime_.erase(remotePid);
3364 
3365     // clear cpu cache when process exit
3366     // CLEAN_CACHE_FREQ to prevent multiple cleanups in a short period of time
3367     if (remotePid != lastCleanCachePid_ ||
3368         ((timestamp_ - lastCleanCacheTimestamp_) / REFRESH_PERIOD) > CLEAN_CACHE_FREQ) {
3369 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
3370         RS_LOGD("RSMainThread: clear cpu cache pid:%{public}d", remotePid);
3371         if (!IsResidentProcess(remotePid)) {
3372             if (isUniRender_) {
3373                 RSUniRenderThread::Instance().ClearMemoryCache(ClearMemoryMoment::PROCESS_EXIT, true, remotePid);
3374                 isNeedResetClearMemoryTask_ = true;
3375             } else {
3376                 ClearMemoryCache(ClearMemoryMoment::PROCESS_EXIT, true);
3377             }
3378             lastCleanCacheTimestamp_ = timestamp_;
3379             lastCleanCachePid_ = remotePid;
3380         }
3381 #endif
3382     }
3383 }
3384 
IsResidentProcess(pid_t pid) const3385 bool RSMainThread::IsResidentProcess(pid_t pid) const
3386 {
3387     return pid == ExtractPid(context_->GetNodeMap().GetEntryViewNodeId());
3388 }
3389 
TrimMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString)3390 void RSMainThread::TrimMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString)
3391 {
3392 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
3393     if (!RSUniRenderJudgement::IsUniRender()) {
3394         dumpString.append("\n---------------\nNot in UniRender and no resource can be released");
3395         return;
3396     }
3397     std::string type;
3398     argSets.erase(u"trimMem");
3399     if (!argSets.empty()) {
3400         type = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
3401     }
3402     RSUniRenderThread::Instance().TrimMem(dumpString, type);
3403 #endif
3404 }
3405 
DumpMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString,std::string & type,pid_t pid)3406 void RSMainThread::DumpMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString,
3407     std::string& type, pid_t pid)
3408 {
3409 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
3410     DfxString log;
3411     if (pid != 0) {
3412         RSUniRenderThread::Instance().PostSyncTask([&log, pid] {
3413             RS_TRACE_NAME_FMT("Dumping memory of pid[%d]", pid);
3414             MemoryManager::DumpPidMemory(log, pid,
3415                 RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
3416         });
3417     } else {
3418         MemoryManager::DumpMemoryUsage(log, type);
3419     }
3420     if (type.empty() || type == MEM_GPU_TYPE) {
3421         auto subThreadManager = RSSubThreadManager::Instance();
3422         if (subThreadManager) {
3423             subThreadManager->DumpMem(log);
3424         }
3425     }
3426     dumpString.append("dumpMem: " + type + "\n");
3427     dumpString.append(log.GetString());
3428 #else
3429     dumpString.append("No GPU in this device");
3430 #endif
3431 }
3432 
CountMem(int pid,MemoryGraphic & mem)3433 void RSMainThread::CountMem(int pid, MemoryGraphic& mem)
3434 {
3435 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
3436     RSUniRenderThread::Instance().PostSyncTask([&mem, pid] {
3437         RS_TRACE_NAME_FMT("Counting memory of pid[%d]", pid);
3438         mem = MemoryManager::CountPidMemory(pid,
3439             RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
3440     });
3441 #endif
3442 }
3443 
CountMem(std::vector<MemoryGraphic> & mems)3444 void RSMainThread::CountMem(std::vector<MemoryGraphic>& mems)
3445 {
3446 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
3447     if (!context_) {
3448         RS_LOGE("RSMainThread::CountMem Context is nullptr");
3449         return;
3450     }
3451     const auto& nodeMap = context_->GetNodeMap();
3452     std::vector<pid_t> pids;
3453     nodeMap.TraverseSurfaceNodes([&pids] (const std::shared_ptr<RSSurfaceRenderNode>& node) {
3454         auto pid = ExtractPid(node->GetId());
3455         if (std::find(pids.begin(), pids.end(), pid) == pids.end()) {
3456             pids.emplace_back(pid);
3457         }
3458     });
3459     RSUniRenderThread::Instance().PostSyncTask([&mems, &pids] {
3460         MemoryManager::CountMemory(pids,
3461             RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetDrGPUContext(), mems);
3462     });
3463 #endif
3464 }
3465 
AddTransactionDataPidInfo(pid_t remotePid)3466 void RSMainThread::AddTransactionDataPidInfo(pid_t remotePid)
3467 {
3468     if (!isUniRender_) {
3469         return;
3470     }
3471     std::lock_guard<std::mutex> lock(transitionDataMutex_);
3472     auto it = effectiveTransactionDataIndexMap_.find(remotePid);
3473     if (it != effectiveTransactionDataIndexMap_.end()) {
3474         RS_LOGW("RSMainThread::AddTransactionDataPidInfo remotePid:%{public}d already exists", remotePid);
3475         it->second.first = 0;
3476     } else {
3477         effectiveTransactionDataIndexMap_.emplace(remotePid,
3478             std::make_pair(0, std::vector<std::unique_ptr<RSTransactionData>>()));;
3479     }
3480 }
3481 
SetDirtyFlag(bool isDirty)3482 void RSMainThread::SetDirtyFlag(bool isDirty)
3483 {
3484     isDirty_ = isDirty;
3485 }
3486 
GetDirtyFlag()3487 bool RSMainThread::GetDirtyFlag()
3488 {
3489     return isDirty_;
3490 }
3491 
SetScreenPowerOnChanged(bool val)3492 void RSMainThread::SetScreenPowerOnChanged(bool val)
3493 {
3494     screenPowerOnChanged_ = val;
3495 }
3496 
GetScreenPowerOnChanged() const3497 bool RSMainThread::GetScreenPowerOnChanged() const
3498 {
3499     return screenPowerOnChanged_;
3500 }
3501 
SetNoNeedToPostTask(bool noNeedToPostTask)3502 void RSMainThread::SetNoNeedToPostTask(bool noNeedToPostTask)
3503 {
3504     noNeedToPostTask_ = noNeedToPostTask;
3505 }
3506 
GetNoNeedToPostTask()3507 bool RSMainThread::GetNoNeedToPostTask()
3508 {
3509     return noNeedToPostTask_.load();
3510 }
3511 
SetAccessibilityConfigChanged()3512 void RSMainThread::SetAccessibilityConfigChanged()
3513 {
3514     isAccessibilityConfigChanged_ = true;
3515 }
3516 
IsAccessibilityConfigChanged() const3517 bool RSMainThread::IsAccessibilityConfigChanged() const
3518 {
3519     return isAccessibilityConfigChanged_;
3520 }
3521 
IsCurtainScreenUsingStatusChanged() const3522 bool RSMainThread::IsCurtainScreenUsingStatusChanged() const
3523 {
3524     return isCurtainScreenUsingStatusChanged_;
3525 }
3526 
PerfAfterAnim(bool needRequestNextVsync)3527 void RSMainThread::PerfAfterAnim(bool needRequestNextVsync)
3528 {
3529     if (!isUniRender_) {
3530         return;
3531     }
3532     if (needRequestNextVsync && timestamp_ - prePerfTimestamp_ > PERF_PERIOD) {
3533         RS_LOGD("RSMainThread:: soc perf to render_service_animation");
3534         prePerfTimestamp_ = timestamp_;
3535     } else if (!needRequestNextVsync && prePerfTimestamp_) {
3536         RS_LOGD("RSMainThread:: soc perf off render_service_animation");
3537         prePerfTimestamp_ = 0;
3538     }
3539 }
3540 
ForceRefreshForUni()3541 void RSMainThread::ForceRefreshForUni()
3542 {
3543     if (isUniRender_) {
3544         PostTask([=]() {
3545             MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
3546             RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
3547             auto now = std::chrono::duration_cast<std::chrono::nanoseconds>(
3548                 std::chrono::steady_clock::now().time_since_epoch()).count();
3549             RS_PROFILER_PATCH_TIME(now);
3550             timestamp_ = timestamp_ + (now - curTime_);
3551             curTime_ = now;
3552             RS_TRACE_NAME("RSMainThread::ForceRefreshForUni timestamp:" + std::to_string(timestamp_));
3553             mainLoop_();
3554         });
3555         auto screenManager_ = CreateOrGetScreenManager();
3556         if (screenManager_ != nullptr) {
3557             auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
3558             if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
3559                 RSHardwareThread::Instance().PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
3560             } else {
3561                 PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
3562             }
3563         }
3564     } else {
3565         RequestNextVSync();
3566     }
3567 }
3568 
PerfForBlurIfNeeded()3569 void RSMainThread::PerfForBlurIfNeeded()
3570 {
3571     handler_->RemoveTask(PERF_FOR_BLUR_IF_NEEDED_TASK_NAME);
3572     static uint64_t prePerfTimestamp = 0;
3573     static int preBlurCnt = 0;
3574     static int cnt = 0;
3575 
3576     auto task = [this]() {
3577         if (preBlurCnt == 0) {
3578             return;
3579         }
3580         auto now = std::chrono::steady_clock::now().time_since_epoch();
3581         auto timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
3582         RS_OPTIONAL_TRACE_NAME_FMT("PerfForBlurIfNeeded now[%ld] timestamp[%ld] preBlurCnt[%d]",
3583             std::chrono::steady_clock::now().time_since_epoch(), timestamp, preBlurCnt);
3584         if (static_cast<uint64_t>(timestamp) - prePerfTimestamp > PERF_PERIOD_BLUR_TIMEOUT && preBlurCnt != 0) {
3585             PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(preBlurCnt), false);
3586             prePerfTimestamp = 0;
3587             preBlurCnt = 0;
3588         }
3589     };
3590     // delay 100ms
3591     handler_->PostTask(task, PERF_FOR_BLUR_IF_NEEDED_TASK_NAME, 100);
3592     int blurCnt = RSPropertiesPainter::GetAndResetBlurCnt();
3593     // clamp blurCnt to 0~3.
3594     blurCnt = std::clamp<int>(blurCnt, 0, 3);
3595     if (blurCnt < preBlurCnt) {
3596         cnt++;
3597     } else {
3598         cnt = 0;
3599     }
3600     // if blurCnt > preBlurCnt, than change perf code;
3601     // if blurCnt < preBlurCnt 10 times continuously, than change perf code.
3602     bool cntIsMatch = blurCnt > preBlurCnt || cnt > 10;
3603     if (cntIsMatch && preBlurCnt != 0) {
3604         RS_OPTIONAL_TRACE_NAME_FMT("PerfForBlurIfNeeded Perf close, preBlurCnt[%d] blurCnt[%ld]", preBlurCnt, blurCnt);
3605         PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(preBlurCnt), false);
3606         preBlurCnt = blurCnt == 0 ? 0 : preBlurCnt;
3607     }
3608     if (blurCnt == 0) {
3609         return;
3610     }
3611     if (timestamp_ - prePerfTimestamp > PERF_PERIOD_BLUR || cntIsMatch) {
3612         RS_OPTIONAL_TRACE_NAME_FMT("PerfForBlurIfNeeded PerfRequest, preBlurCnt[%d] blurCnt[%ld]", preBlurCnt, blurCnt);
3613         PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(blurCnt), true);
3614         prePerfTimestamp = timestamp_;
3615         preBlurCnt = blurCnt;
3616     }
3617 }
3618 
PerfMultiWindow()3619 void RSMainThread::PerfMultiWindow()
3620 {
3621     if (!isUniRender_) {
3622         return;
3623     }
3624     static uint64_t lastPerfTimestamp = 0;
3625     if (appWindowNum_ >= MULTI_WINDOW_PERF_START_NUM && appWindowNum_ <= MULTI_WINDOW_PERF_END_NUM
3626         && timestamp_ - lastPerfTimestamp > PERF_PERIOD_MULTI_WINDOW) {
3627         RS_LOGD("RSMainThread::PerfMultiWindow soc perf");
3628         PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, true);
3629         lastPerfTimestamp = timestamp_;
3630     } else if ((appWindowNum_ < MULTI_WINDOW_PERF_START_NUM || appWindowNum_ > MULTI_WINDOW_PERF_END_NUM)
3631         && timestamp_ - lastPerfTimestamp < PERF_PERIOD_MULTI_WINDOW) {
3632         RS_LOGD("RSMainThread::PerfMultiWindow soc perf off");
3633         PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, false);
3634     }
3635 }
3636 
RenderFrameStart(uint64_t timestamp)3637 void RSMainThread::RenderFrameStart(uint64_t timestamp)
3638 {
3639     if (RsFrameReport::GetInstance().GetEnable()) {
3640         RsFrameReport::GetInstance().RenderStart(timestamp);
3641     }
3642     RenderFrameTrace::GetInstance().RenderStartFrameTrace(RS_INTERVAL_NAME);
3643     int hardwareTid = RSHardwareThread::Instance().GetHardwareTid();
3644     if (hardwareTid_ != hardwareTid) {
3645         hardwareTid_ = hardwareTid;
3646         RsFrameReport::GetInstance().SetFrameParam(EVENT_SET_HARDWARE_UTIL, 0, 0, hardwareTid_);
3647     }
3648 }
3649 
SetAppWindowNum(uint32_t num)3650 void RSMainThread::SetAppWindowNum(uint32_t num)
3651 {
3652     appWindowNum_ = num;
3653 }
3654 
SetSystemAnimatedScenes(SystemAnimatedScenes systemAnimatedScenes)3655 bool RSMainThread::SetSystemAnimatedScenes(SystemAnimatedScenes systemAnimatedScenes)
3656 {
3657     RS_OPTIONAL_TRACE_NAME_FMT("%s systemAnimatedScenes[%u] systemAnimatedScenes_[%u] threeFingerScenesListSize[%d] "
3658         "systemAnimatedScenesListSize_[%d]", __func__, systemAnimatedScenes,
3659         systemAnimatedScenes_, threeFingerScenesList_.size(), systemAnimatedScenesList_.size());
3660     if (systemAnimatedScenes < SystemAnimatedScenes::ENTER_MISSION_CENTER ||
3661             systemAnimatedScenes > SystemAnimatedScenes::OTHERS) {
3662         RS_LOGD("RSMainThread::SetSystemAnimatedScenes Out of range.");
3663         return false;
3664     }
3665     systemAnimatedScenes_ = systemAnimatedScenes;
3666     if (!systemAnimatedScenesEnabled_) {
3667         return true;
3668     }
3669     {
3670         std::lock_guard<std::mutex> lock(systemAnimatedScenesMutex_);
3671         if (systemAnimatedScenes == SystemAnimatedScenes::OTHERS) {
3672             if (!threeFingerScenesList_.empty()) {
3673                 threeFingerScenesList_.pop_front();
3674             }
3675             if (!systemAnimatedScenesList_.empty()) {
3676                 systemAnimatedScenesList_.pop_front();
3677             }
3678         } else {
3679             uint64_t curTime = static_cast<uint64_t>(
3680                 std::chrono::duration_cast<std::chrono::nanoseconds>(
3681                     std::chrono::steady_clock::now().time_since_epoch()).count());
3682             if (systemAnimatedScenes == SystemAnimatedScenes::ENTER_TFS_WINDOW ||
3683                 systemAnimatedScenes == SystemAnimatedScenes::EXIT_TFU_WINDOW ||
3684                 systemAnimatedScenes == SystemAnimatedScenes::ENTER_WIND_CLEAR ||
3685                 systemAnimatedScenes == SystemAnimatedScenes::ENTER_WIND_RECOVER) {
3686                 threeFingerScenesList_.push_back(std::make_pair(systemAnimatedScenes, curTime));
3687             }
3688             if (systemAnimatedScenes != SystemAnimatedScenes::APPEAR_MISSION_CENTER) {
3689                 systemAnimatedScenesList_.push_back(std::make_pair(systemAnimatedScenes, curTime));
3690             }
3691         }
3692     }
3693     return true;
3694 }
3695 
GetSystemAnimatedScenes()3696 SystemAnimatedScenes RSMainThread::GetSystemAnimatedScenes()
3697 {
3698     return systemAnimatedScenes_;
3699 }
3700 
CheckNodeHasToBePreparedByPid(NodeId nodeId,bool isClassifyByRoot)3701 bool RSMainThread::CheckNodeHasToBePreparedByPid(NodeId nodeId, bool isClassifyByRoot)
3702 {
3703     std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
3704     if (context_->activeNodesInRoot_.empty() || nodeId == INVALID_NODEID) {
3705         return false;
3706     }
3707     if (!isClassifyByRoot) {
3708         // Match by PID
3709         auto pid = ExtractPid(nodeId);
3710         return std::any_of(context_->activeNodesInRoot_.begin(), context_->activeNodesInRoot_.end(),
3711             [pid](const auto& iter) { return ExtractPid(iter.first) == pid; });
3712     } else {
3713         return context_->activeNodesInRoot_.count(nodeId);
3714     }
3715 }
3716 
IsDrawingGroupChanged(const RSRenderNode & cacheRootNode) const3717 bool RSMainThread::IsDrawingGroupChanged(const RSRenderNode& cacheRootNode) const
3718 {
3719     std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
3720     auto iter = context_->activeNodesInRoot_.find(cacheRootNode.GetInstanceRootNodeId());
3721     if (iter != context_->activeNodesInRoot_.end()) {
3722         const auto& activeNodeIds = iter->second;
3723         // do not need to check cacheroot node itself
3724         // in case of tree change, parent node would set content dirty and reject before
3725         auto cacheRootId = cacheRootNode.GetId();
3726         auto groupNodeIds = cacheRootNode.GetVisitedCacheRootIds();
3727         for (auto [id, subNode] : activeNodeIds) {
3728             auto node = subNode.lock();
3729             if (node == nullptr || id == cacheRootId) {
3730                 continue;
3731             }
3732             if (groupNodeIds.find(node->GetDrawingCacheRootId()) != groupNodeIds.end()) {
3733                 return true;
3734             }
3735         }
3736     }
3737     return false;
3738 }
3739 
CheckAndUpdateInstanceContentStaticStatus(std::shared_ptr<RSSurfaceRenderNode> instanceNode) const3740 void RSMainThread::CheckAndUpdateInstanceContentStaticStatus(std::shared_ptr<RSSurfaceRenderNode> instanceNode) const
3741 {
3742     if (instanceNode == nullptr) {
3743         RS_LOGE("CheckAndUpdateInstanceContentStaticStatus instanceNode invalid.");
3744         return ;
3745     }
3746     std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
3747     auto iter = context_->activeNodesInRoot_.find(instanceNode->GetId());
3748     if (iter != context_->activeNodesInRoot_.end()) {
3749         instanceNode->UpdateSurfaceCacheContentStatic(iter->second);
3750     } else {
3751         instanceNode->UpdateSurfaceCacheContentStatic();
3752     }
3753 }
3754 
ResetHardwareEnabledState(bool isUniRender)3755 void RSMainThread::ResetHardwareEnabledState(bool isUniRender)
3756 {
3757     if (isUniRender) {
3758         isHardwareForcedDisabled_ = !RSSystemProperties::GetHardwareComposerEnabled();
3759         isLastFrameDirectComposition_ = doDirectComposition_;
3760         doDirectComposition_ = !isHardwareForcedDisabled_;
3761         isHardwareEnabledBufferUpdated_ = false;
3762         hasProtectedLayer_ = false;
3763         hardwareEnabledNodes_.clear();
3764         hardwareEnabledDrwawables_.clear();
3765         selfDrawingNodes_.clear();
3766         selfDrawables_.clear();
3767     }
3768 }
3769 
IsHardwareEnabledNodesNeedSync()3770 bool RSMainThread::IsHardwareEnabledNodesNeedSync()
3771 {
3772     bool needSync = false;
3773     for (const auto& node : hardwareEnabledNodes_) {
3774         if (node != nullptr && ((!doDirectComposition_ && node->GetStagingRenderParams() != nullptr &&
3775             node->GetStagingRenderParams()->NeedSync()) ||
3776             (doDirectComposition_ && !node->IsHardwareForcedDisabled()))) {
3777             needSync = true;
3778             break;
3779         }
3780     }
3781     RS_TRACE_NAME_FMT("%s %u", __func__, needSync);
3782     RS_LOGD("%{public}s %{public}u", __func__, needSync);
3783 
3784     return needSync;
3785 }
3786 
IsOcclusionNodesNeedSync(NodeId id,bool useCurWindow)3787 bool RSMainThread::IsOcclusionNodesNeedSync(NodeId id, bool useCurWindow)
3788 {
3789     auto nodePtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
3790         GetContext().GetNodeMap().GetRenderNode(id));
3791     if (nodePtr == nullptr) {
3792         return false;
3793     }
3794 
3795     if (useCurWindow == false) {
3796         auto parentNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr->GetParent().lock());
3797         if (parentNode && parentNode->IsLeashWindow() && parentNode->ShouldPaint()) {
3798             nodePtr = parentNode;
3799         }
3800     }
3801 
3802     if (nodePtr->GetIsFullChildrenListValid() == false) {
3803         nodePtr->PrepareSelfNodeForApplyModifiers();
3804         return true;
3805     }
3806 
3807     bool needSync = false;
3808     if (nodePtr->IsLeashWindow()) {
3809         auto children = nodePtr->GetSortedChildren();
3810         for (auto child : *children) {
3811             auto childSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
3812             if (childSurfaceNode && childSurfaceNode->IsMainWindowType() &&
3813                 childSurfaceNode->GetVisibleRegion().IsEmpty()) {
3814                 childSurfaceNode->PrepareSelfNodeForApplyModifiers();
3815                 needSync = true;
3816             }
3817         }
3818     } else if (nodePtr->IsMainWindowType() && nodePtr->GetVisibleRegion().IsEmpty()) {
3819         nodePtr->PrepareSelfNodeForApplyModifiers();
3820         needSync = true;
3821     }
3822 
3823     return needSync;
3824 }
3825 
ShowWatermark(const std::shared_ptr<Media::PixelMap> & watermarkImg,bool flag)3826 void RSMainThread::ShowWatermark(const std::shared_ptr<Media::PixelMap> &watermarkImg, bool flag)
3827 {
3828     std::lock_guard<std::mutex> lock(watermarkMutex_);
3829     auto screenManager_ = CreateOrGetScreenManager();
3830     if (flag && screenManager_) {
3831         auto screenInfo = screenManager_->QueryDefaultScreenInfo();
3832         constexpr int32_t maxScale = 2;
3833         if (screenInfo.id != INVALID_SCREEN_ID && watermarkImg &&
3834             (watermarkImg->GetWidth() > maxScale * static_cast<int32_t>(screenInfo.width) ||
3835             watermarkImg->GetHeight() > maxScale * static_cast<int32_t>(screenInfo.height))) {
3836             RS_LOGE("RSMainThread::ShowWatermark width %{public}" PRId32" or height %{public}" PRId32" has reached"
3837                 " the maximum limit!", watermarkImg->GetWidth(), watermarkImg->GetHeight());
3838             return;
3839         }
3840     }
3841 
3842     watermarkFlag_ = flag;
3843     if (flag) {
3844         watermarkImg_ = RSPixelMapUtil::ExtractDrawingImage(std::move(watermarkImg));
3845     } else {
3846         watermarkImg_ = nullptr;
3847     }
3848     SetDirtyFlag();
3849     RequestNextVSync();
3850 }
3851 
GetWatermarkImg()3852 std::shared_ptr<Drawing::Image> RSMainThread::GetWatermarkImg()
3853 {
3854     return watermarkImg_;
3855 }
3856 
GetWatermarkFlag()3857 bool RSMainThread::GetWatermarkFlag()
3858 {
3859     return watermarkFlag_;
3860 }
3861 
IsSingleDisplay()3862 bool RSMainThread::IsSingleDisplay()
3863 {
3864     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3865     if (rootNode == nullptr) {
3866         RS_LOGE("RSMainThread::IsSingleDisplay GetGlobalRootRenderNode fail");
3867         return false;
3868     }
3869     return rootNode->GetChildrenCount() == 1;
3870 }
3871 
HasMirrorDisplay() const3872 bool RSMainThread::HasMirrorDisplay() const
3873 {
3874     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3875     if (rootNode == nullptr || rootNode->GetChildrenCount() <= 1) {
3876         return false;
3877     }
3878 
3879     for (auto& child : *rootNode->GetSortedChildren()) {
3880         if (!child || !child->IsInstanceOf<RSDisplayRenderNode>()) {
3881             continue;
3882         }
3883         auto displayNode = child->ReinterpretCastTo<RSDisplayRenderNode>();
3884         if (!displayNode) {
3885             continue;
3886         }
3887         if (auto mirroredNode = displayNode->GetMirrorSource().lock()) {
3888             return true;
3889         }
3890     }
3891     return false;
3892 }
3893 
UpdateRogSizeIfNeeded()3894 void RSMainThread::UpdateRogSizeIfNeeded()
3895 {
3896     if (!RSSystemProperties::IsPhoneType() || RSSystemProperties::IsFoldScreenFlag()) {
3897         return;
3898     }
3899     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3900     if (!rootNode) {
3901         return;
3902     }
3903     auto child = rootNode->GetFirstChild();
3904     if (child != nullptr && child->IsInstanceOf<RSDisplayRenderNode>()) {
3905         auto displayNode = child->ReinterpretCastTo<RSDisplayRenderNode>();
3906         if (displayNode == nullptr) {
3907             return;
3908         }
3909         auto screenManager_ = CreateOrGetScreenManager();
3910         if (screenManager_ == nullptr) {
3911             return;
3912         }
3913         screenManager_->SetRogScreenResolution(
3914             displayNode->GetScreenId(), displayNode->GetRogWidth(), displayNode->GetRogHeight());
3915     }
3916 }
3917 
UpdateDisplayNodeScreenId()3918 void RSMainThread::UpdateDisplayNodeScreenId()
3919 {
3920     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3921     if (!rootNode) {
3922         RS_LOGE("RSMainThread::UpdateDisplayNodeScreenId rootNode is nullptr");
3923         return;
3924     }
3925     auto child = rootNode->GetFirstChild();
3926     if (child != nullptr && child->IsInstanceOf<RSDisplayRenderNode>()) {
3927         auto displayNode = child->ReinterpretCastTo<RSDisplayRenderNode>();
3928         if (displayNode) {
3929             displayNodeScreenId_ = displayNode->GetScreenId();
3930         }
3931     }
3932 }
3933 
3934 const uint32_t UIFIRST_MINIMUM_NODE_NUMBER = 4; // minimum window number(4) for enabling UIFirst
3935 const uint32_t FOLD_DEVICE_SCREEN_NUMBER = 2; // alt device has two screens
3936 
UpdateUIFirstSwitch()3937 void RSMainThread::UpdateUIFirstSwitch()
3938 {
3939     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3940     if (!rootNode) {
3941         RSUifirstManager::Instance().SetUiFirstSwitch(isUiFirstOn_);
3942         return;
3943     }
3944     auto firstChildren = rootNode->GetFirstChild();
3945     if (!firstChildren) {
3946         RSUifirstManager::Instance().SetUiFirstSwitch(isUiFirstOn_);
3947         return;
3948     }
3949     auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(firstChildren);
3950     if (!displayNode) {
3951         RSUifirstManager::Instance().SetUiFirstSwitch(isUiFirstOn_);
3952         return;
3953     }
3954     if (deviceType_ != DeviceType::PC) {
3955         if (hasProtectedLayer_) {
3956             isUiFirstOn_ = false;
3957         } else {
3958             isUiFirstOn_ = RSSystemProperties::GetUIFirstEnabled();
3959         }
3960         RSUifirstManager::Instance().SetUiFirstSwitch(isUiFirstOn_);
3961         return;
3962     }
3963     isUiFirstOn_ = false;
3964     if (IsSingleDisplay() || HasMirrorDisplay()) {
3965         uint32_t LeashWindowCount = 0;
3966         displayNode->CollectSurfaceForUIFirstSwitch(LeashWindowCount, UIFIRST_MINIMUM_NODE_NUMBER);
3967         isUiFirstOn_ = RSSystemProperties::GetUIFirstEnabled() && LeashWindowCount >=  UIFIRST_MINIMUM_NODE_NUMBER;
3968     }
3969     RSUifirstManager::Instance().SetUiFirstSwitch(isUiFirstOn_);
3970 }
3971 
IsUIFirstOn() const3972 bool RSMainThread::IsUIFirstOn() const
3973 {
3974     return isUiFirstOn_;
3975 }
3976 
UpdateAnimateNodeFlag()3977 void RSMainThread::UpdateAnimateNodeFlag()
3978 {
3979     if (!context_) {
3980         return;
3981     }
3982     context_->curFrameAnimatingNodeList_.insert(context_->animatingNodeList_.begin(),
3983         context_->animatingNodeList_.end());
3984     for (auto& item : context_->curFrameAnimatingNodeList_) {
3985         auto node = item.second.lock();
3986         if (node) {
3987             node->SetCurFrameHasAnimation(true);
3988         }
3989     }
3990 }
3991 
ResetAnimateNodeFlag()3992 void RSMainThread::ResetAnimateNodeFlag()
3993 {
3994     if (!context_) {
3995         return;
3996     }
3997     for (auto& item : context_->curFrameAnimatingNodeList_) {
3998         auto node = item.second.lock();
3999         if (node) {
4000             node->SetCurFrameHasAnimation(false);
4001         }
4002     }
4003     context_->curFrameAnimatingNodeList_.clear();
4004 }
4005 
ReleaseSurface()4006 void RSMainThread::ReleaseSurface()
4007 {
4008     std::lock_guard<std::mutex> lock(mutex_);
4009     while (tmpSurfaces_.size() > 0) {
4010         auto tmp = tmpSurfaces_.front();
4011         tmpSurfaces_.pop();
4012         tmp = nullptr;
4013     }
4014 }
4015 
AddToReleaseQueue(std::shared_ptr<Drawing::Surface> && surface)4016 void RSMainThread::AddToReleaseQueue(std::shared_ptr<Drawing::Surface>&& surface)
4017 {
4018     std::lock_guard<std::mutex> lock(mutex_);
4019     tmpSurfaces_.push(std::move(surface));
4020 }
4021 
GetAppMemoryInMB(float & cpuMemSize,float & gpuMemSize)4022 void RSMainThread::GetAppMemoryInMB(float& cpuMemSize, float& gpuMemSize)
4023 {
4024     RSUniRenderThread::Instance().PostSyncTask([&cpuMemSize, &gpuMemSize] {
4025         gpuMemSize = MemoryManager::GetAppGpuMemoryInMB(
4026             RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
4027         cpuMemSize = MemoryTrack::Instance().GetAppMemorySizeInMB();
4028     });
4029 }
4030 
SubscribeAppState()4031 void RSMainThread::SubscribeAppState()
4032 {
4033     PostTask(
4034         [this]() {
4035             rsAppStateListener_ = std::make_shared<RSAppStateListener>();
4036             if (Memory::MemMgrClient::GetInstance().SubscribeAppState(*rsAppStateListener_) != -1) {
4037                 RS_LOGD("Subscribe MemMgr Success");
4038                 subscribeFailCount_ = 0;
4039                 return;
4040             } else {
4041                 RS_LOGE("Subscribe Failed, try again");
4042                 subscribeFailCount_++;
4043                 if (subscribeFailCount_ < 10) { // The maximum number of failures is 10
4044                     SubscribeAppState();
4045                 } else {
4046                     RS_LOGE("Subscribe Failed 10 times, exiting");
4047                 }
4048             }
4049         },
4050         MEM_MGR, WAIT_FOR_MEM_MGR_SERVICE);
4051 }
4052 
HandleOnTrim(Memory::SystemMemoryLevel level)4053 void RSMainThread::HandleOnTrim(Memory::SystemMemoryLevel level)
4054 {
4055     if (handler_) {
4056         handler_->PostTask(
4057             [level, this]() {
4058                 RS_LOGD("Enter level:%{public}d, OnTrim Success", level);
4059                 RS_TRACE_NAME_FMT("System is low memory, HandleOnTrim Enter level:%d", level);
4060                 switch (level) {
4061                     case Memory::SystemMemoryLevel::MEMORY_LEVEL_CRITICAL:
4062                         if (isUniRender_) {
4063                             RSUniRenderThread::Instance().ClearMemoryCache(ClearMemoryMoment::LOW_MEMORY, true);
4064                             isNeedResetClearMemoryTask_ = true;
4065                         } else {
4066                             ClearMemoryCache(ClearMemoryMoment::LOW_MEMORY, true);
4067                         }
4068                         break;
4069                     case Memory::SystemMemoryLevel::MEMORY_LEVEL_LOW:
4070                     case Memory::SystemMemoryLevel::MEMORY_LEVEL_MODERATE:
4071                     case Memory::SystemMemoryLevel::MEMORY_LEVEL_PURGEABLE:
4072                         break;
4073                     default:
4074                         break;
4075                 }
4076             },
4077             AppExecFwk::EventQueue::Priority::IDLE);
4078     }
4079 }
4080 
SetCurtainScreenUsingStatus(bool isCurtainScreenOn)4081 void RSMainThread::SetCurtainScreenUsingStatus(bool isCurtainScreenOn)
4082 {
4083     if (isCurtainScreenOn_ == isCurtainScreenOn) {
4084         RS_LOGD("RSMainThread::SetCurtainScreenUsingStatus: curtain screen status not change");
4085         return;
4086     }
4087     RSUifirstManager::Instance().SetUseDmaBuffer(!isCurtainScreenOn);
4088     isCurtainScreenOn_ = isCurtainScreenOn;
4089     isCurtainScreenUsingStatusChanged_ = true;
4090     SetDirtyFlag();
4091     RequestNextVSync();
4092     RS_LOGD("RSMainThread::SetCurtainScreenUsingStatus %{public}d", isCurtainScreenOn);
4093 }
4094 
SetLuminanceChangingStatus(bool isLuminanceChanged)4095 void RSMainThread::SetLuminanceChangingStatus(bool isLuminanceChanged)
4096 {
4097     isLuminanceChanged_.store(isLuminanceChanged);
4098 }
4099 
ExchangeLuminanceChangingStatus()4100 bool RSMainThread::ExchangeLuminanceChangingStatus()
4101 {
4102     bool expectChanged = true;
4103     if (!isLuminanceChanged_.compare_exchange_weak(expectChanged, false)) {
4104         return false;
4105     }
4106     RS_LOGD("RSMainThread::ExchangeLuminanceChangingStatus changed");
4107     return true;
4108 }
4109 
IsCurtainScreenOn() const4110 bool RSMainThread::IsCurtainScreenOn() const
4111 {
4112     return isCurtainScreenOn_;
4113 }
4114 
GetCurrentSystimeMs() const4115 int64_t RSMainThread::GetCurrentSystimeMs() const
4116 {
4117     auto curTime = std::chrono::system_clock::now().time_since_epoch();
4118     int64_t curSysTime = std::chrono::duration_cast<std::chrono::milliseconds>(curTime).count();
4119     return curSysTime;
4120 }
4121 
GetCurrentSteadyTimeMs() const4122 int64_t RSMainThread::GetCurrentSteadyTimeMs() const
4123 {
4124     auto curTime = std::chrono::steady_clock::now().time_since_epoch();
4125     int64_t curSteadyTime = std::chrono::duration_cast<std::chrono::milliseconds>(curTime).count();
4126     return curSteadyTime;
4127 }
4128 
GetCurrentSteadyTimeMsFloat() const4129 float RSMainThread::GetCurrentSteadyTimeMsFloat() const
4130 {
4131     auto curTime = std::chrono::steady_clock::now().time_since_epoch();
4132     int64_t curSteadyTimeUs = std::chrono::duration_cast<std::chrono::microseconds>(curTime).count();
4133     float curSteadyTime = curSteadyTimeUs / MS_TO_US;
4134     return curSteadyTime;
4135 }
4136 
UpdateLuminance()4137 void RSMainThread::UpdateLuminance()
4138 {
4139     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
4140     if (rootNode == nullptr) {
4141         return;
4142     }
4143     bool isNeedRefreshAll{false};
4144     if (auto screenManager = CreateOrGetScreenManager()) {
4145         auto& rsLuminance = RSLuminanceControl::Get();
4146         for (const auto& child : *rootNode->GetSortedChildren()) {
4147             auto displayNode = RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(child);
4148             if (displayNode == nullptr) {
4149                 continue;
4150             }
4151 
4152             auto screenId = displayNode->GetScreenId();
4153             if (rsLuminance.IsDimmingOn(screenId)) {
4154                 rsLuminance.DimmingIncrease(screenId);
4155                 isNeedRefreshAll = true;
4156             }
4157             if (rsLuminance.IsNeedUpdateLuminance(screenId)) {
4158                 uint32_t newLevel = rsLuminance.GetNewHdrLuminance(screenId);
4159                 screenManager->SetScreenBacklight(screenId, newLevel);
4160                 rsLuminance.SetNowHdrLuminance(screenId, newLevel);
4161             }
4162         }
4163     }
4164     if (isNeedRefreshAll) {
4165         SetLuminanceChangingStatus(true);
4166         SetDirtyFlag();
4167         RequestNextVSync();
4168     }
4169 }
4170 
RegisterUIExtensionCallback(pid_t pid,uint64_t userId,sptr<RSIUIExtensionCallback> callback)4171 void RSMainThread::RegisterUIExtensionCallback(pid_t pid, uint64_t userId, sptr<RSIUIExtensionCallback> callback)
4172 {
4173     std::lock_guard<std::mutex> lock(uiExtensionMutex_);
4174     RS_LOGI("RSMainThread::RegisterUIExtensionCallback for User: %{public}" PRIu64 " PID: %{public}d.", userId, pid);
4175     uiExtensionListenners_[pid] = std::pair<uint64_t, sptr<RSIUIExtensionCallback>>(userId, callback);
4176 }
4177 
UnRegisterUIExtensionCallback(pid_t pid)4178 void RSMainThread::UnRegisterUIExtensionCallback(pid_t pid)
4179 {
4180     std::lock_guard<std::mutex> lock(uiExtensionMutex_);
4181     RS_LOGI("RSMainThread::UnRegisterUIExtensionCallback for PID: %{public}d.", pid);
4182     uiExtensionListenners_.erase(pid);
4183 }
4184 
SetAncoForceDoDirect(bool direct)4185 void RSMainThread::SetAncoForceDoDirect(bool direct)
4186 {
4187     RS_LOGI("RSMainThread::SetAncoForceDoDirect %{public}d.", direct);
4188     RSSurfaceRenderNode::SetAncoForceDoDirect(direct);
4189 }
4190 
UIExtensionNodesTraverseAndCallback()4191 void RSMainThread::UIExtensionNodesTraverseAndCallback()
4192 {
4193     std::lock_guard<std::mutex> lock(uiExtensionMutex_);
4194     RSUniRenderUtil::UIExtensionFindAndTraverseAncestor(context_->GetNodeMap(), uiExtensionCallbackData_);
4195     if (CheckUIExtensionCallbackDataChanged()) {
4196         RS_OPTIONAL_TRACE_NAME_FMT("RSMainThread::UIExtensionNodesTraverseAndCallback data size: [%lu]",
4197             uiExtensionCallbackData_.size());
4198         for (const auto& item : uiExtensionListenners_) {
4199             auto userId = item.second.first;
4200             auto callback = item.second.second;
4201             if (callback) {
4202                 callback->OnUIExtension(std::make_shared<RSUIExtensionData>(uiExtensionCallbackData_), userId);
4203             }
4204         }
4205     }
4206     lastFrameUIExtensionDataEmpty_ = uiExtensionCallbackData_.empty();
4207     uiExtensionCallbackData_.clear();
4208 }
4209 
CheckUIExtensionCallbackDataChanged() const4210 bool RSMainThread::CheckUIExtensionCallbackDataChanged() const
4211 {
4212     // empty for two consecutive frames, callback can be skipped.
4213     if (uiExtensionCallbackData_.empty()) {
4214         return !lastFrameUIExtensionDataEmpty_;
4215     }
4216     // layout of host node was not changed, callback can be skipped.
4217     const auto& nodeMap = context_->GetNodeMap();
4218     for (const auto& data : uiExtensionCallbackData_) {
4219         auto hostNode = nodeMap.GetRenderNode(data.first);
4220         if (hostNode != nullptr && !hostNode->LastFrameSubTreeSkipped()) {
4221             return true;
4222         }
4223     }
4224     RS_OPTIONAL_TRACE_NAME("RSMainThread::CheckUIExtensionCallbackDataChanged, all host nodes were not changed.");
4225     return false;
4226 }
4227 
SetHardwareTaskNum(uint32_t num)4228 void RSMainThread::SetHardwareTaskNum(uint32_t num)
4229 {
4230     rsVSyncDistributor_->SetHardwareTaskNum(num);
4231 }
4232 } // namespace Rosen
4233 } // namespace OHOS
4234