• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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/main_thread/rs_main_thread.h"
19 
20 #include <algorithm>
21 #include <cstdint>
22 #include <list>
23 #include <malloc.h>
24 #include <parameters.h>
25 #include <securec.h>
26 #include <stdint.h>
27 #include <string>
28 #include <unistd.h>
29 
30 #include "app_mgr_client.h"
31 #include "delegate/rs_functional_delegate.h"
32 #include "hgm_energy_consumption_policy.h"
33 #include "hgm_frame_rate_manager.h"
34 #include "include/core/SkGraphics.h"
35 #include "mem_mgr_client.h"
36 #include "render_frame_trace.h"
37 #include "rs_frame_report.h"
38 #include "rs_profiler.h"
39 #include "rs_trace.h"
40 #include "hisysevent.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_display_node_command.h"
48 #include "command/rs_message_processor.h"
49 #include "command/rs_node_command.h"
50 #include "common/rs_background_thread.h"
51 #include "common/rs_common_def.h"
52 #include "common/rs_optional_trace.h"
53 #include "dirty_region/rs_gpu_dirty_collector.h"
54 #include "display_engine/rs_color_temperature.h"
55 #include "display_engine/rs_luminance_control.h"
56 #include "drawable/rs_canvas_drawing_render_node_drawable.h"
57 #include "feature/drm/rs_drm_util.h"
58 #include "feature/hdr/rs_hdr_util.h"
59 #include "feature/lpp/lpp_video_handler.h"
60 #include "feature/anco_manager/rs_anco_manager.h"
61 #include "feature/opinc/rs_opinc_manager.h"
62 #include "feature/uifirst/rs_uifirst_manager.h"
63 #ifdef RS_ENABLE_OVERLAY_DISPLAY
64 #include "feature/overlay_display/rs_overlay_display_manager.h"
65 #endif
66 #include "feature/hpae/rs_hpae_manager.h"
67 #include "gfx/performance/rs_perfmonitor_reporter.h"
68 #include "graphic_feature_param_manager.h"
69 #include "info_collection/rs_gpu_dirty_region_collection.h"
70 #include "memory/rs_memory_graphic.h"
71 #include "memory/rs_memory_manager.h"
72 #include "memory/rs_memory_track.h"
73 #include "metadata_helper.h"
74 #include "monitor/self_drawing_node_monitor.h"
75 #include "params/rs_surface_render_params.h"
76 #include "pipeline/rs_base_render_node.h"
77 #include "pipeline/render_thread/rs_base_render_util.h"
78 #include "pipeline/rs_canvas_drawing_render_node.h"
79 #include "pipeline/render_thread/rs_divided_render_util.h"
80 #include "pipeline/hardware_thread/rs_hardware_thread.h"
81 #include "pipeline/hardware_thread/rs_realtime_refresh_rate_manager.h"
82 #include "pipeline/rs_occlusion_config.h"
83 #include "pipeline/rs_pointer_window_manager.h"
84 #include "pipeline/rs_processor_factory.h"
85 #include "pipeline/render_thread/rs_render_engine.h"
86 #include "pipeline/main_thread/rs_render_service_visitor.h"
87 #include "pipeline/rs_logical_display_render_node.h"
88 #include "pipeline/rs_root_render_node.h"
89 #include "pipeline/rs_surface_buffer_callback_manager.h"
90 #include "pipeline/rs_surface_render_node.h"
91 #include "pipeline/rs_task_dispatcher.h"
92 #include "pipeline/rs_unmarshal_task_manager.h"
93 #include "rs_frame_rate_vote.h"
94 #include "singleton.h"
95 #ifdef RS_ENABLE_VK
96 #include "pipeline/rs_vk_pipeline_config.h"
97 #endif
98 #include "pipeline/rs_render_node_gc.h"
99 #include "pipeline/sk_resource_manager.h"
100 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
101 #include "pipeline/magic_pointer_render/rs_magic_pointer_render_manager.h"
102 #endif
103 #include "platform/common/rs_innovation.h"
104 #include "platform/common/rs_log.h"
105 #include "platform/common/rs_system_properties.h"
106 #include "platform/drawing/rs_vsync_client.h"
107 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
108 #include "platform/ohos/rs_jank_stats.h"
109 #include "property/rs_point_light_manager.h"
110 #include "property/rs_properties_painter.h"
111 #include "property/rs_property_trace.h"
112 #include "render/rs_image_cache.h"
113 #include "render/rs_pixel_map_util.h"
114 #include "render/rs_typeface_cache.h"
115 #include "screen_manager/rs_screen_manager.h"
116 #include "transaction/rs_transaction_metric_collector.h"
117 #include "transaction/rs_transaction_proxy.h"
118 #include "transaction/rs_unmarshal_thread.h"
119 
120 #ifdef RS_ENABLE_GPU
121 #include "feature/capture/rs_ui_capture_task_parallel.h"
122 #include "feature/capture/rs_ui_capture_solo_task_parallel.h"
123 #include "feature/uifirst/rs_sub_thread_manager.h"
124 #include "feature/round_corner_display/rs_rcd_surface_render_node.h"
125 #include "feature/round_corner_display/rs_round_corner_display_manager.h"
126 #include "pipeline/render_thread/rs_uni_render_engine.h"
127 #include "pipeline/render_thread/rs_uni_render_thread.h"
128 #include "pipeline/render_thread/rs_uni_render_util.h"
129 #include "pipeline/main_thread/rs_uni_render_visitor.h"
130 #endif
131 
132 #ifdef RS_ENABLE_GL
133 #include "GLES3/gl3.h"
134 #include "EGL/egl.h"
135 #include "EGL/eglext.h"
136 #endif
137 
138 #if defined(ACCESSIBILITY_ENABLE)
139 #include "accessibility_config.h"
140 #endif
141 
142 #ifdef SOC_PERF_ENABLE
143 #include "socperf_client.h"
144 #endif
145 
146 #if defined(RS_ENABLE_CHIPSET_VSYNC)
147 #include "rs_chipset_vsync.h"
148 #endif
149 #ifdef RES_SCHED_ENABLE
150 #include "system_ability_definition.h"
151 #include "if_system_ability_manager.h"
152 #include <iservice_registry.h>
153 #include "ressched_event_listener.h"
154 #endif
155 
156 // cpu boost
157 #include "c/ffrt_cpu_boost.h"
158 // blur predict
159 #include "rs_frame_blur_predict.h"
160 #include "rs_frame_deadline_predict.h"
161 #include "feature_cfg/feature_param/extend_feature/mem_param.h"
162 #include "feature/hetero_hdr/rs_hdr_manager.h"
163 
164 #include "feature_cfg/graphic_feature_param_manager.h"
165 #include "feature_cfg/feature_param/feature_param.h"
166 
167 using namespace FRAME_TRACE;
168 static const std::string RS_INTERVAL_NAME = "renderservice";
169 
170 #if defined(ACCESSIBILITY_ENABLE)
171 using namespace OHOS::AccessibilityConfig;
172 #endif
173 
174 #undef LOG_TAG
175 #define LOG_TAG "RSMainThread"
176 
177 namespace OHOS {
178 namespace Rosen {
179 namespace {
180 constexpr uint32_t VSYNC_LOG_ENABLED_TIMES_THRESHOLD = 500;
181 constexpr uint32_t VSYNC_LOG_ENABLED_STEP_TIMES = 100;
182 constexpr uint32_t REQUEST_VSYNC_NUMBER_LIMIT = 20;
183 constexpr uint64_t REFRESH_PERIOD = 16666667;
184 constexpr int32_t PERF_MULTI_WINDOW_REQUESTED_CODE = 10026;
185 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
186 constexpr uint64_t PERF_PERIOD = 250000000;
187 constexpr uint64_t CLEAN_CACHE_FREQ = 60;
188 constexpr uint64_t SKIP_COMMAND_FREQ_LIMIT = 30;
189 constexpr uint64_t PERF_PERIOD_BLUR = 1000000000;
190 constexpr uint64_t PERF_PERIOD_BLUR_TIMEOUT = 80000000;
191 constexpr uint64_t MAX_DYNAMIC_STATUS_TIME = 5000000000;
192 constexpr uint64_t MAX_SYSTEM_SCENE_STATUS_TIME = 800000000;
193 constexpr uint64_t PERF_PERIOD_MULTI_WINDOW = 80000000;
194 constexpr uint32_t MULTI_WINDOW_PERF_START_NUM = 2;
195 constexpr uint32_t MULTI_WINDOW_PERF_END_NUM = 4;
196 constexpr uint32_t TIME_OF_CAPTURE_TASK_REMAIN = 500;
197 constexpr uint32_t TIME_OF_EIGHT_FRAMES = 8000;
198 constexpr uint32_t TIME_OF_THE_FRAMES = 1000;
199 constexpr uint32_t WAIT_FOR_RELEASED_BUFFER_TIMEOUT = 3000;
200 constexpr uint32_t WAIT_FOR_HARDWARE_THREAD_TASK_TIMEOUT = 3000;
201 constexpr uint32_t WAIT_FOR_SURFACE_CAPTURE_PROCESS_TIMEOUT = 1000;
202 constexpr uint32_t WAIT_FOR_UNMARSHAL_THREAD_TASK_TIMEOUT = 4000;
203 constexpr uint32_t WATCHDOG_TIMEVAL = 5000;
204 constexpr uint32_t HARDWARE_THREAD_TASK_NUM = 2;
205 constexpr uint32_t NODE_DUMP_STRING_LEN = 8;
206 constexpr int32_t SIMI_VISIBLE_RATE = 2;
207 constexpr int32_t DEFAULT_RATE = 1;
208 constexpr int32_t INVISBLE_WINDOW_RATE = 10;
209 constexpr int32_t MAX_CAPTURE_COUNT = 5;
210 constexpr int32_t SYSTEM_ANIMATED_SCENES_RATE = 2;
211 constexpr uint32_t CAL_NODE_PREFERRED_FPS_LIMIT = 50;
212 constexpr uint32_t EVENT_SET_HARDWARE_UTIL = 100004;
213 constexpr uint32_t EVENT_NAME_MAX_LENGTH = 50;
214 constexpr uint32_t HIGH_32BIT = 32;
215 constexpr uint64_t PERIOD_MAX_OFFSET = 1000000; // 1ms
216 constexpr uint64_t FASTCOMPOSE_OFFSET = 300000; // 300us
217 constexpr const char* WALLPAPER_VIEW = "WallpaperView";
218 constexpr const char* CLEAR_GPU_CACHE = "ClearGpuCache";
219 constexpr const char* DESKTOP_NAME_FOR_ROTATION = "SCBDesktop";
220 const std::string PERF_FOR_BLUR_IF_NEEDED_TASK_NAME = "PerfForBlurIfNeeded";
221 constexpr const char* CAPTURE_WINDOW_NAME = "CapsuleWindow";
222 constexpr const char* HIDE_NOTCH_STATUS = "persist.sys.graphic.hideNotch.status";
223 constexpr const char* DRAWING_CACHE_DFX = "rosen.drawingCache.enabledDfx";
224 constexpr const char* DEFAULT_SURFACE_NODE_NAME = "DefaultSurfaceNodeName";
225 constexpr const char* ENABLE_DEBUG_FMT_TRACE = "sys.graphic.openTestModeTrace";
226 constexpr uint64_t ONE_SECOND_TIMESTAMP = 1e9;
227 constexpr int SKIP_FIRST_FRAME_DRAWING_NUM = 1;
228 constexpr uint32_t MAX_ANIMATED_SCENES_NUM = 0xFFFF;
229 constexpr size_t MAX_SURFACE_OCCLUSION_LISTENERS_SIZE = std::numeric_limits<uint16_t>::max();
230 constexpr uint32_t MAX_DROP_FRAME_PID_LIST_SIZE = 1024;
231 
232 #ifdef RS_ENABLE_GL
233 constexpr size_t DEFAULT_SKIA_CACHE_SIZE        = 96 * (1 << 20);
234 constexpr int DEFAULT_SKIA_CACHE_COUNT          = 2 * (1 << 12);
235 #endif
236 #if (defined RS_ENABLE_GL) || (defined RS_ENABLE_VK)
237 constexpr const char* MEM_GPU_TYPE = "gpu";
238 #endif
239 constexpr size_t MEMUNIT_RATE = 1024;
240 constexpr size_t MAX_GPU_CONTEXT_CACHE_SIZE = 1024 * MEMUNIT_RATE * MEMUNIT_RATE;   // 1G
241 constexpr uint32_t REQUEST_VSYNC_DUMP_NUMBER = 100;
242 const std::string DVSYNC_NOTIFY_UNMARSHAL_TASK_NAME = "DVSyncNotifyUnmarshalTask";
243 const std::map<int, int32_t> BLUR_CNT_TO_BLUR_CODE {
244     { 1, 10021 },
245     { 2, 10022 },
246     { 3, 10023 },
247 };
248 
SystemTime()249 static int64_t SystemTime()
250 {
251     timespec t = {};
252     clock_gettime(CLOCK_MONOTONIC, &t);
253     return int64_t(t.tv_sec) * 1000000000LL + t.tv_nsec; // 1000000000ns == 1s
254 }
255 
Compare(const std::unique_ptr<RSTransactionData> & data1,const std::unique_ptr<RSTransactionData> & data2)256 bool Compare(const std::unique_ptr<RSTransactionData>& data1, const std::unique_ptr<RSTransactionData>& data2)
257 {
258     if (!data1 || !data2) {
259         RS_LOGW("Compare RSTransactionData: nullptr!");
260         return true;
261     }
262     return data1->GetIndex() < data2->GetIndex();
263 }
264 
InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>> & source,std::vector<std::unique_ptr<RSTransactionData>> & target)265 void InsertToEnd(std::vector<std::unique_ptr<RSTransactionData>>& source,
266     std::vector<std::unique_ptr<RSTransactionData>>& target)
267 {
268     target.insert(target.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.end()));
269     source.clear();
270 }
271 
PerfRequest(int32_t perfRequestCode,bool onOffTag)272 void PerfRequest(int32_t perfRequestCode, bool onOffTag)
273 {
274 #ifdef SOC_PERF_ENABLE
275     OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequestEx(perfRequestCode, onOffTag, "");
276     RS_LOGD("soc perf info [%{public}d %{public}d]", perfRequestCode, onOffTag);
277 #endif
278 }
279 
280 #ifdef RS_ENABLE_GPU
281 // rcd node will be handled by RS tree in OH 6.0 rcd refactoring, should remove this later
DoScreenRcdTask(RSScreenRenderNode & screenNode,std::shared_ptr<RSProcessor> & processor)282 void DoScreenRcdTask(RSScreenRenderNode& screenNode, std::shared_ptr<RSProcessor> &processor)
283 {
284     if (processor == nullptr) {
285         RS_LOGD("DoScreenRcdTask has no processor");
286         return;
287     }
288     auto screenInfo =
289         static_cast<RSScreenRenderParams *>(screenNode.GetStagingRenderParams().get())->GetScreenInfo();
290     if (screenInfo.state != ScreenState::HDI_OUTPUT_ENABLE) {
291         RS_LOGD("DoScreenRcdTask is not at HDI_OUPUT mode");
292         return;
293     }
294     auto hardInfo = RSSingleton<RoundCornerDisplayManager>::GetInstance().GetHardwareInfo(screenNode.GetId());
295         auto rcdNodeTop = std::static_pointer_cast<RSRcdSurfaceRenderNode>(screenNode.GetRcdSurfaceNodeTop());
296     if (rcdNodeTop) {
297         rcdNodeTop->DoProcessRenderMainThreadTask(hardInfo.resourceChanged, processor);
298     } else {
299         RS_LOGD("Top rcdnode is null");
300     }
301     auto rcdNodeBottom = std::static_pointer_cast<RSRcdSurfaceRenderNode>(screenNode.GetRcdSurfaceNodeBottom());
302     if (rcdNodeBottom) {
303         rcdNodeBottom->DoProcessRenderMainThreadTask(hardInfo.resourceChanged, processor);
304     } else {
305         RS_LOGD("Bottom rcdnode is null");
306     }
307 }
308 #endif
309 
310 class RSEventDumper : public AppExecFwk::Dumper {
311 public:
Dump(const std::string & message)312     void Dump(const std::string &message) override
313     {
314         dumpString.append(message);
315     }
316 
GetTag()317     std::string GetTag() override
318     {
319         return std::string("RSEventDumper");
320     }
321 
GetOutput() const322     std::string GetOutput() const
323     {
324         return dumpString;
325     }
326 private:
327     std::string dumpString = "";
328 };
329 
330 std::string g_dumpStr = "";
331 std::mutex g_dumpMutex;
332 std::condition_variable g_dumpCond_;
333 }
334 
335 #if defined(ACCESSIBILITY_ENABLE)
336 class AccessibilityObserver : public AccessibilityConfigObserver {
337 public:
338     AccessibilityObserver() = default;
OnConfigChanged(const CONFIG_ID id,const ConfigValue & value)339     void OnConfigChanged(const CONFIG_ID id, const ConfigValue &value) override
340     {
341         ColorFilterMode mode = ColorFilterMode::COLOR_FILTER_END;
342         if (id == CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER) {
343             if (!AccessibilityParam::IsColorCorrectionEnabled()) {
344                 RS_LOGE("RSAccessibility ColorCorrectionEnabled is not supported");
345                 return;
346             }
347 
348             RS_LOGI("RSAccessibility DALTONIZATION_COLOR_FILTER: %{public}d",
349                 static_cast<int>(value.daltonizationColorFilter));
350             switch (value.daltonizationColorFilter) {
351                 case Protanomaly:
352                     mode = ColorFilterMode::DALTONIZATION_PROTANOMALY_MODE;
353                     break;
354                 case Deuteranomaly:
355                     mode = ColorFilterMode::DALTONIZATION_DEUTERANOMALY_MODE;
356                     break;
357                 case Tritanomaly:
358                     mode = ColorFilterMode::DALTONIZATION_TRITANOMALY_MODE;
359                     break;
360                 case Normal:
361                     mode = ColorFilterMode::DALTONIZATION_NORMAL_MODE;
362                     break;
363                 default:
364                     break;
365             }
366             RSBaseRenderEngine::SetColorFilterMode(mode);
367         } else if (id == CONFIG_ID::CONFIG_INVERT_COLOR) {
368             if (!AccessibilityParam::IsColorReverseEnabled()) {
369                 RS_LOGE("RSAccessibility ColorReverseEnabled is not supported");
370                 return;
371             }
372 
373             RS_LOGI("RSAccessibility INVERT_COLOR: %{public}d", static_cast<int>(value.invertColor));
374             mode = value.invertColor ? ColorFilterMode::INVERT_COLOR_ENABLE_MODE :
375                                         ColorFilterMode::INVERT_COLOR_DISABLE_MODE;
376             RSBaseRenderEngine::SetColorFilterMode(mode);
377         } else if (id == CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT) {
378             if (!AccessibilityParam::IsHighContrastEnabled()) {
379                 RS_LOGE("RSAccessibility HighContrastEnabled is not supported");
380                 return;
381             }
382 
383             RS_LOGI("RSAccessibility HIGH_CONTRAST: %{public}d", static_cast<int>(value.highContrastText));
384             RSBaseRenderEngine::SetHighContrast(value.highContrastText);
385         } else {
386             RS_LOGW("RSAccessibility configId: %{public}d is not supported yet.", id);
387         }
388         RSMainThread::Instance()->PostTask([]() {
389             RSMainThread::Instance()->SetAccessibilityConfigChanged();
390             RSMainThread::Instance()->RequestNextVSync();
391         });
392     }
393 };
394 #endif
395 
Instance()396 RSMainThread* RSMainThread::Instance()
397 {
398     static RSMainThread instance;
399     return &instance;
400 }
401 
RSMainThread()402 RSMainThread::RSMainThread() : rsParallelType_(RSSystemParameters::GetRsParallelType()),
403     mainThreadId_(std::this_thread::get_id())
404 {
405     context_ = std::make_shared<RSContext>();
406     context_->Initialize();
407 }
408 
~RSMainThread()409 RSMainThread::~RSMainThread() noexcept
410 {
411     RSNodeCommandHelper::SetCommitDumpNodeTreeProcessor(nullptr);
412     RemoveRSEventDetector();
413     RSInnovation::CloseInnovationSo();
414 #if defined(RS_ENABLE_CHIPSET_VSYNC)
415     RsChipsetVsync::Instance().CloseLibrary();
416 #endif
417     if (rsAppStateListener_) {
418         Memory::MemMgrClient::GetInstance().UnsubscribeAppState(*rsAppStateListener_);
419     }
420 }
421 
TraverseCanvasDrawingNodesNotOnTree()422 void RSMainThread::TraverseCanvasDrawingNodesNotOnTree()
423 {
424     const auto& nodeMap = context_->GetNodeMap();
425     nodeMap.TraverseCanvasDrawingNodes([](const std::shared_ptr<RSCanvasDrawingRenderNode>& canvasDrawingNode) {
426         if (canvasDrawingNode == nullptr) {
427             return;
428         }
429         canvasDrawingNode->ContentStyleSlotUpdate();
430     });
431 }
432 
Init()433 void RSMainThread::Init()
434 {
435     mainLoop_ = [&]() {
436         RS_PROFILER_ON_FRAME_BEGIN(timestamp_);
437         if (isUniRender_ && !renderThreadParams_) {
438 #ifdef RS_ENABLE_GPU
439             // fill the params, and sync to render thread later
440             renderThreadParams_ = std::make_unique<RSRenderThreadParams>();
441 #endif
442         }
443         RenderFrameStart(timestamp_);
444         RSRenderNodeGC::Instance().SetGCTaskEnable(true);
445         PerfMultiWindow();
446         SetRSEventDetectorLoopStartTag();
447         ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "RSMainThread::DoComposition: " + std::to_string(curTime_));
448         ConsumeAndUpdateAllNodes();
449         ClearNeedDropframePidList();
450         WaitUntilUnmarshallingTaskFinished();
451         ProcessCommand();
452         RsFrameBlurPredict::GetInstance().AdjustCurrentFrameDrawLargeAreaBlurFrequencyPredictively();
453         UpdateSubSurfaceCnt();
454         Animate(timestamp_);
455         CollectInfoForHardwareComposer();
456 #ifdef RS_ENABLE_GPU
457         RSUifirstManager::Instance().PrepareCurrentFrameEvent();
458 #endif
459         ProcessHgmFrameRate(timestamp_);
460         RS_PROFILER_ON_RENDER_BEGIN();
461         // cpu boost feature start
462         ffrt_cpu_boost_start(CPUBOOST_START_POINT);
463         // may mark rsnotrendering
464         Render(); // now render is traverse tree to prepare
465         RsFrameBlurPredict::GetInstance().UpdateCurrentFrameDrawLargeAreaBlurFrequencyPrecisely();
466         // cpu boost feature end
467         ffrt_cpu_boost_end(CPUBOOST_START_POINT);
468         TraverseCanvasDrawingNodesNotOnTree();
469         RS_PROFILER_ON_RENDER_END();
470         OnUniRenderDraw();
471         UIExtensionNodesTraverseAndCallback();
472         if (!isUniRender_) {
473             RSMainThread::GPUCompositonCacheGuard guard;
474             ReleaseAllNodesBuffer();
475         }
476         SendCommands();
477         {
478             std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
479             context_->activeNodesInRoot_.clear();
480         }
481         ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
482         SetRSEventDetectorLoopFinishTag();
483         rsEventManager_.UpdateParam();
484         ResetAnimateNodeFlag();
485         SKResourceManager::Instance().ReleaseResource();
486         // release batched node from render tree (enabled by default, can be disabled in RSSystemProperties)
487         RSRenderNodeGC::Instance().ReleaseFromTree();
488         // release node memory
489         RSRenderNodeGC::Instance().ReleaseNodeMemory();
490         if (!isUniRender_) {
491             RSRenderNodeGC::Instance().ReleaseDrawableMemory();
492         }
493         if (!RSImageCache::Instance().CheckUniqueIdIsEmpty()) {
494             static std::function<void()> task = []() -> void {
495                 RSImageCache::Instance().ReleaseUniqueIdList();
496             };
497             RSBackgroundThread::Instance().PostTask(task);
498         }
499         RSTypefaceCache::Instance().HandleDelayDestroyQueue();
500 #if defined(RS_ENABLE_CHIPSET_VSYNC)
501         ConnectChipsetVsyncSer();
502 #endif
503 #ifdef RS_ENABLE_VK
504         if (needCreateVkPipeline_) {
505             needCreateVkPipeline_ = false;
506             RSBackgroundThread::Instance().PostTask([]() {
507                 Rosen::RDC::RDCConfig rdcConfig;
508                 rdcConfig.LoadAndAnalyze(std::string(Rosen::RDC::CONFIG_XML_FILE));
509             });
510         }
511 #endif
512 
513         RS_PROFILER_ON_FRAME_END();
514     };
515     static std::function<void (std::shared_ptr<Drawing::Image> image)> holdDrawingImagefunc =
516         [] (std::shared_ptr<Drawing::Image> image) -> void {
517             if (image) {
518                 SKResourceManager::Instance().HoldResource(image);
519             }
520         };
521     Drawing::DrawOpItem::SetBaseCallback(holdDrawingImagefunc);
522     static std::function<std::shared_ptr<Drawing::Typeface> (uint64_t)> customTypefaceQueryfunc =
523         [] (uint64_t globalUniqueId) -> std::shared_ptr<Drawing::Typeface> {
524             return RSTypefaceCache::Instance().GetDrawingTypefaceCache(globalUniqueId);
525         };
526     Drawing::DrawOpItem::SetTypefaceQueryCallBack(customTypefaceQueryfunc);
527     {
528         using namespace std::placeholders;
529         RSNodeCommandHelper::SetCommitDumpNodeTreeProcessor(
530             std::bind(&RSMainThread::OnCommitDumpClientNodeTree, this, _1, _2, _3, _4));
531     }
532     Drawing::DrawSurfaceBufferOpItem::RegisterSurfaceBufferCallback({
533         .OnFinish = RSSurfaceBufferCallbackManager::Instance().GetOnFinishCb(),
534         .OnAfterAcquireBuffer = RSSurfaceBufferCallbackManager::Instance().GetOnAfterAcquireBufferCb(),
535     });
536     RSSurfaceBufferCallbackManager::Instance().SetIsUniRender(true);
537 #ifdef RS_ENABLE_GPU
538     RSSurfaceBufferCallbackManager::Instance().SetRunPolicy([](auto task) {
539         RSHardwareThread::Instance().PostTask(task);
540     });
541 #endif
542     RSSurfaceBufferCallbackManager::Instance().SetVSyncFuncs({
543         .requestNextVsync = []() {
544             RSMainThread::Instance()->RequestNextVSync();
545         },
546         .isRequestedNextVSync = []() {
547             return RSMainThread::Instance()->IsRequestedNextVSync();
548         },
549     });
550 
551     isUniRender_ = RSUniRenderJudgement::IsUniRender();
552     SetDeviceType();
553     isFoldScreenDevice_ = RSSystemProperties::IsFoldScreenFlag();
554     auto taskDispatchFunc = [](const RSTaskDispatcher::RSTask& task, bool isSyncTask = false) {
555         RSMainThread::Instance()->PostTask(task);
556     };
557     context_->SetTaskRunner(taskDispatchFunc);
558     rsVsyncRateReduceManager_.Init(appVSyncDistributor_);
559     if (isUniRender_) {
560 #ifdef RS_ENABLE_GPU
561         auto rtTaskDispatchFunc = [](const RSTaskDispatcher::RSTask& task) {
562             RSUniRenderThread::Instance().PostRTTask(task);
563         };
564         context_->SetRTTaskRunner(rtTaskDispatchFunc);
565 #endif
566     }
567     context_->SetVsyncRequestFunc([]() {
568         RSMainThread::Instance()->RequestNextVSync();
569         RSMainThread::Instance()->SetDirtyFlag();
570     });
571     RSTaskDispatcher::GetInstance().RegisterTaskDispatchFunc(gettid(), taskDispatchFunc);
572     RsFrameReport::GetInstance().Init();
573     RSUniHwcPrevalidateUtil::GetInstance().Init();
574     RSSystemProperties::WatchSystemProperty(HIDE_NOTCH_STATUS, OnHideNotchStatusCallback, nullptr);
575     RSSystemProperties::WatchSystemProperty(DRAWING_CACHE_DFX, OnDrawingCacheDfxSwitchCallback, nullptr);
576     if (isUniRender_) {
577 #ifdef RS_ENABLE_GPU
578         unmarshalBarrierTask_ = [this]() {
579             auto cachedTransactionData = RSUnmarshalThread::Instance().GetCachedTransactionData();
580             MergeToEffectiveTransactionDataMap(cachedTransactionData);
581             {
582                 std::lock_guard<std::mutex> lock(unmarshalMutex_);
583                 ++unmarshalFinishedCount_;
584                 waitForDVSyncFrame_.store(false);
585             }
586             unmarshalTaskCond_.notify_all();
587         };
588         RSUnmarshalThread::Instance().Start();
589 #endif
590     }
591 
592     RS_LOGI("thread init");
593     runner_ = AppExecFwk::EventRunner::Create(false);
594     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
595     uint32_t timeForWatchDog = WATCHDOG_TIMEVAL;
596     int ret = HiviewDFX::Watchdog::GetInstance().AddThread("RenderService", handler_, timeForWatchDog);
597     if (ret != 0) {
598         RS_LOGW("Add watchdog thread failed");
599     }
600 #ifdef RES_SCHED_ENABLE
601     SubScribeSystemAbility();
602 #endif
603     InitRSEventDetector();
604     RS_LOGI("VSync init");
605     sptr<VSyncIConnectionToken> token = new IRemoteStub<VSyncIConnectionToken>();
606     sptr<VSyncConnection> conn = new VSyncConnection(rsVSyncDistributor_, "rs", token->AsObject());
607     conn->id_ = hgmContext_.GetRSFrameRateLinker()->GetId();
608     rsVSyncDistributor_->AddConnection(conn);
609     receiver_ = std::make_shared<VSyncReceiver>(conn, token->AsObject(), handler_, "rs");
610     receiver_->Init();
611     if (!isUniRender_) {
612         renderEngine_ = std::make_shared<RSRenderEngine>();
613         renderEngine_->Init();
614     }
615     RSOpincManager::Instance().SetOPIncSwitch(OPIncParam::IsOPIncEnable());
616     RSUifirstManager::Instance().ReadUIFirstCcmParam();
617     auto PostTaskProxy = [](RSTaskMessage::RSTask task, const std::string& name, int64_t delayTime,
618         AppExecFwk::EventQueue::Priority priority) {
619         RSMainThread::Instance()->PostTask(task, name, delayTime, priority);
620     };
621     RSRenderNodeGC::Instance().SetMainTask(PostTaskProxy);
622     auto GCNotifyTaskProxy = [](bool isEnable) {
623         RSRenderNodeGC::Instance().SetGCTaskEnable(isEnable);
624     };
625     conn->SetGCNotifyTask(GCNotifyTaskProxy);
626     RSScreenRenderNode::SetReleaseTask([](ScreenId id) {
627         auto screenManager = CreateOrGetScreenManager();
628         if (screenManager == nullptr) {
629             RS_LOGE("ReleaseScreenDmaBuffer: screenManager is nullptr");
630             return;
631         }
632         screenManager->ReleaseScreenDmaBuffer(id);
633     });
634     RSLogicalDisplayRenderNode::SetScreenStatusNotifyTask([](bool status) {
635         sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
636         if (screenManager == nullptr) {
637             RS_LOGE("RSMainThread::Init screenManager is nullptr");
638             return;
639         }
640         screenManager->SetScreenSwitchStatus(status);
641     });
642 #ifdef RS_ENABLE_GL
643     /* move to render thread ? */
644     if (RSSystemProperties::GetGpuApiType() == GpuApiType::OPENGL) {
645         int cacheLimitsTimes = 3;
646         auto gpuContext = isUniRender_? GetRenderEngine()->GetRenderContext()->GetDrGPUContext() :
647             renderEngine_->GetRenderContext()->GetDrGPUContext();
648         if (gpuContext == nullptr) {
649             RS_LOGE("Init gpuContext is nullptr!");
650             return;
651         }
652         int32_t maxResources = 0;
653         size_t maxResourcesSize = 0;
654         gpuContext->GetResourceCacheLimits(&maxResources, &maxResourcesSize);
655         if (maxResourcesSize > 0) {
656             gpuContext->SetResourceCacheLimits(cacheLimitsTimes * maxResources, cacheLimitsTimes *
657                 std::fmin(maxResourcesSize, DEFAULT_SKIA_CACHE_SIZE));
658         } else {
659             gpuContext->SetResourceCacheLimits(DEFAULT_SKIA_CACHE_COUNT, DEFAULT_SKIA_CACHE_SIZE);
660         }
661     }
662 #endif // RS_ENABLE_GL
663     RS_LOGI("OpenInnovationSo");
664     RSInnovation::OpenInnovationSo();
665 #if defined(RS_ENABLE_CHIPSET_VSYNC)
666     RsChipsetVsync::Instance().LoadLibrary();
667 #endif
668 #if defined(RS_ENABLE_UNI_RENDER)
669     RS_LOGI("InitRenderContext");
670     /* move to render thread ? */
671     RSBackgroundThread::Instance().InitRenderContext(GetRenderEngine()->GetRenderContext().get());
672 #endif
673 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
674 #if defined (RS_ENABLE_GL) && defined (RS_ENABLE_EGLIMAGE) || defined (RS_ENABLE_VK)
675     RSMagicPointerRenderManager::InitInstance(GetRenderEngine()->GetImageManager());
676 #endif
677 #endif
678 
679 #if defined(ACCESSIBILITY_ENABLE)
680     RS_LOGI("AccessibilityConfig init");
681     accessibilityObserver_ = std::make_shared<AccessibilityObserver>();
682     auto &config = OHOS::AccessibilityConfig::AccessibilityConfig::GetInstance();
683     config.InitializeContext();
684     config.SubscribeConfigObserver(CONFIG_ID::CONFIG_DALTONIZATION_COLOR_FILTER, accessibilityObserver_);
685     config.SubscribeConfigObserver(CONFIG_ID::CONFIG_INVERT_COLOR, accessibilityObserver_);
686     if (isUniRender_) {
687         config.SubscribeConfigObserver(CONFIG_ID::CONFIG_HIGH_CONTRAST_TEXT, accessibilityObserver_);
688     }
689 #endif
690     RegisterScreenNodeListener();
691     auto delegate = RSFunctionalDelegate::Create();
692     delegate->SetRepaintCallback([this]() {
693         bool isOverDrawEnabled = RSOverdrawController::GetInstance().IsEnabled();
694         PostTask([this, isOverDrawEnabled]() {
695             SetDirtyFlag();
696             isOverDrawEnabledOfCurFrame_ = isOverDrawEnabled;
697             RequestNextVSync("OverDrawUpdate");
698         });
699     });
700     RSAnimationFraction::Init();
701     RS_LOGI("RSOverdrawController init");
702     RSOverdrawController::GetInstance().SetDelegate(delegate);
703 
704     RS_LOGI("HgmTaskHandleThread init");
705     hgmContext_.InitHgmTaskHandleThread(
706         rsVSyncController_, appVSyncController_, vsyncGenerator_, appVSyncDistributor_);
707     SubscribeAppState();
708     PrintCurrentStatus();
709     RS_LOGI("UpdateGpuContextCacheSize");
710     UpdateGpuContextCacheSize();
711     RS_LOGI("RSLuminanceControl init");
712     RSLuminanceControl::Get().Init();
713     RS_LOGI("RSColorTemperature init");
714     RSColorTemperature::Get().Init();
715     // used to force refresh screen when cct is updated
716     std::function<void()> refreshFunc = []() {
717         RSMainThread::Instance()->SetDirtyFlag();
718         RSMainThread::Instance()->RequestNextVSync();
719     };
720     RSColorTemperature::Get().RegisterRefresh(std::move(refreshFunc));
721 #ifdef RS_ENABLE_GPU
722     MemoryManager::InitMemoryLimit();
723     MemoryManager::SetGpuMemoryLimit(GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
724 #endif
725     RSSystemProperties::WatchSystemProperty(ENABLE_DEBUG_FMT_TRACE, OnFmtTraceSwitchCallback, nullptr);
726 }
727 
GetFrontBufferDesiredPresentTimeStamp(const sptr<IConsumerSurface> & consumer,int64_t & desiredPresentTimeStamp)728 void RSMainThread::GetFrontBufferDesiredPresentTimeStamp(
729     const sptr<IConsumerSurface>& consumer, int64_t& desiredPresentTimeStamp)
730 {
731     if (consumer == nullptr) {
732         desiredPresentTimeStamp = 0;
733         return;
734     }
735     bool isAutoTimeStamp = false;
736     int64_t fronDesiredPresentTimeStamp = 0;
737     if (consumer->GetFrontDesiredPresentTimeStamp(fronDesiredPresentTimeStamp, isAutoTimeStamp) !=
738         GSError::GSERROR_OK || fronDesiredPresentTimeStamp <= 0 || isAutoTimeStamp) {
739         desiredPresentTimeStamp = 0;
740         return;
741     }
742 
743     const uint64_t tmp = static_cast<uint64_t>(fronDesiredPresentTimeStamp);
744     if (tmp <= vsyncRsTimestamp_.load() ||
745         (tmp > ONE_SECOND_TIMESTAMP && tmp - ONE_SECOND_TIMESTAMP > vsyncRsTimestamp_.load())) {
746         desiredPresentTimeStamp = 0;
747         return;
748     }
749     // vsyncRsTimestamp_ < fronDesiredPresentTimeStamp <= vsyncRsTimestamp_ + 1s
750     desiredPresentTimeStamp = fronDesiredPresentTimeStamp;
751 }
752 
NotifyUnmarshalTask(int64_t uiTimestamp)753 void RSMainThread::NotifyUnmarshalTask(int64_t uiTimestamp)
754 {
755     if (isUniRender_ && rsVSyncDistributor_->IsUiDvsyncOn() && static_cast<uint64_t>(uiTimestamp) +
756         static_cast<uint64_t>(rsVSyncDistributor_->GetUiCommandDelayTime()) >= vsyncRsTimestamp_.load()
757         && waitForDVSyncFrame_.load()) {
758         auto cachedTransactionData = RSUnmarshalThread::Instance().GetCachedTransactionData();
759         MergeToEffectiveTransactionDataMap(cachedTransactionData);
760         {
761             std::lock_guard<std::mutex> lock(unmarshalMutex_);
762             ++unmarshalFinishedCount_;
763             waitForDVSyncFrame_.store(false);
764             RSUnmarshalThread::Instance().RemoveTask(DVSYNC_NOTIFY_UNMARSHAL_TASK_NAME);
765         }
766         unmarshalTaskCond_.notify_all();
767     }
768 }
769 
UpdateGpuContextCacheSize()770 void RSMainThread::UpdateGpuContextCacheSize()
771 {
772 #ifdef RS_ENABLE_GPU
773     auto gpuContext = isUniRender_? GetRenderEngine()->GetRenderContext()->GetDrGPUContext() :
774         renderEngine_->GetRenderContext()->GetDrGPUContext();
775     if (gpuContext == nullptr) {
776         RS_LOGE("UpdateGpuContextCacheSize gpuContext is nullptr!");
777         return;
778     }
779     auto screenManager = CreateOrGetScreenManager();
780     if (!screenManager) {
781         RS_LOGE("UpdateGpuContextCacheSize screenManager is nullptr");
782         return;
783     }
784     size_t cacheLimitsResourceSize = 0;
785     size_t maxResourcesSize = 0;
786     int32_t maxResources = 0;
787     gpuContext->GetResourceCacheLimits(&maxResources, &maxResourcesSize);
788     auto maxScreenInfo = screenManager->GetActualScreenMaxResolution();
789     constexpr size_t baseResourceSize = 500;    // 500 M memory is baseline
790     constexpr int32_t baseResolution = 3427200; // 3427200 is base resolution
791     float actualScale = maxScreenInfo.phyWidth * maxScreenInfo.phyHeight * 1.0f / baseResolution;
792     cacheLimitsResourceSize = baseResourceSize * actualScale
793         * MEMUNIT_RATE * MEMUNIT_RATE; // adjust by actual Resolution
794     cacheLimitsResourceSize = cacheLimitsResourceSize > MAX_GPU_CONTEXT_CACHE_SIZE ?
795         MAX_GPU_CONTEXT_CACHE_SIZE : cacheLimitsResourceSize;
796     if (cacheLimitsResourceSize > maxResourcesSize) {
797         gpuContext->SetResourceCacheLimits(maxResources, cacheLimitsResourceSize);
798     }
799     static int systemCacheLimitResourceSize = MEMParam::GetRSCacheLimitsResourceSize();
800     RS_LOGD("systemCacheLimitResourceSize: %{public}d", systemCacheLimitResourceSize);
801     if (systemCacheLimitResourceSize > 0) {
802         gpuContext->SetResourceCacheLimits(maxResources, systemCacheLimitResourceSize);
803     }
804 
805     auto purgeableMaxCount = RSSystemParameters::GetPurgeableResourceLimit();
806     gpuContext->SetPurgeableResourceLimit(purgeableMaxCount);
807 #endif
808 }
809 
InitVulkanErrorCallback(Drawing::GPUContext * gpuContext)810 void RSMainThread::InitVulkanErrorCallback(Drawing::GPUContext* gpuContext)
811 {
812     if (gpuContext == nullptr) {
813         RS_LOGE("InitVulkanErrorCallback gpuContext is nullptr");
814         return;
815     }
816 
817     gpuContext->RegisterVulkanErrorCallback([this]() {
818         RS_LOGE("FocusLeashWindowName:[%{public}s]", this->focusLeashWindowName_.c_str());
819 
820         char appWindowName[EVENT_NAME_MAX_LENGTH];
821         char focusLeashWindowName[EVENT_NAME_MAX_LENGTH];
822         char extinfodefault[EVENT_NAME_MAX_LENGTH] = "ext_info_default";
823 
824         auto cpyresult = strcpy_s(appWindowName, EVENT_NAME_MAX_LENGTH, appWindowName_.c_str());
825         if (cpyresult != 0) {
826             RS_LOGE("Copy appWindowName_ error, AppWindowName:%{public}s", appWindowName_.c_str());
827         }
828         cpyresult = strcpy_s(focusLeashWindowName, EVENT_NAME_MAX_LENGTH, focusLeashWindowName_.c_str());
829         if (cpyresult != 0) {
830             RS_LOGE("Copy focusLeashWindowName error, focusLeashWindowName:%{public}s", focusLeashWindowName_.c_str());
831         }
832 
833         HiSysEventParam pPID = { .name = "PID", .t = HISYSEVENT_UINT32, .v = { .ui32 = appPid_ }, .arraySize = 0 };
834 
835         HiSysEventParam pAppNodeId = {
836             .name = "AppNodeId", .t = HISYSEVENT_UINT64, .v = { .ui64 = appWindowId_ }, .arraySize = 0
837         };
838 
839         HiSysEventParam pAppNodeName = {
840             .name = "AppNodeName", .t = HISYSEVENT_STRING, .v = { .s = appWindowName }, .arraySize = 0
841         };
842 
843         HiSysEventParam pLeashWindowId = {
844             .name = "LeashWindowId", .t = HISYSEVENT_UINT64, .v = { .ui64 = focusLeashWindowId_ }, .arraySize = 0
845         };
846 
847         HiSysEventParam pLeashWindowName = {
848             .name = "LeashWindowName", .t = HISYSEVENT_STRING, .v = { .s = focusLeashWindowName }, .arraySize = 0
849         };
850 
851         HiSysEventParam pExtInfo = {
852             .name = "ExtInfo", .t = HISYSEVENT_STRING, .v = { .s = extinfodefault }, .arraySize = 0
853         };
854 
855         HiSysEventParam paramsHebcFault[] = { pPID, pAppNodeId, pAppNodeName, pLeashWindowId, pLeashWindowName,
856             pExtInfo };
857 
858         int ret = OH_HiSysEvent_Write("GRAPHIC", "RS_VULKAN_ERROR", HISYSEVENT_FAULT, paramsHebcFault,
859             sizeof(paramsHebcFault) / sizeof(paramsHebcFault[0]));
860         if (ret == 0) {
861             RS_LOGE("Successed to rs_vulkan_error fault event.");
862         } else {
863             RS_LOGE("Faild to upload rs_vulkan_error event, ret = %{public}d", ret);
864         }
865     });
866 }
867 
RsEventParamDump(std::string & dumpString)868 void RSMainThread::RsEventParamDump(std::string& dumpString)
869 {
870     rsEventManager_.DumpAllEventParam(dumpString);
871 }
872 
RemoveRSEventDetector()873 void RSMainThread::RemoveRSEventDetector()
874 {
875     if (rsCompositionTimeoutDetector_ != nullptr) {
876         rsEventManager_.RemoveEvent(rsCompositionTimeoutDetector_->GetStringId());
877     }
878 }
879 
InitRSEventDetector()880 void RSMainThread::InitRSEventDetector()
881 {
882     // default Threshold value of Timeout Event: 100ms
883     rsCompositionTimeoutDetector_ = RSBaseEventDetector::CreateRSTimeOutDetector(100, "RS_COMPOSITION_TIMEOUT");
884     if (rsCompositionTimeoutDetector_ != nullptr) {
885         rsEventManager_.AddEvent(rsCompositionTimeoutDetector_, 60000); // report Internal 1min:60s:60000ms
886         RS_LOGD("InitRSEventDetector finish");
887     }
888 }
889 
SetDeviceType()890 void RSMainThread::SetDeviceType()
891 {
892     auto deviceTypeStr = system::GetParameter("const.product.devicetype", "pc");
893     if (deviceTypeStr == "pc" || deviceTypeStr == "2in1") {
894         deviceType_ = DeviceType::PC;
895     } else if (deviceTypeStr == "tablet") {
896         deviceType_ = DeviceType::TABLET;
897     } else if (deviceTypeStr == "phone") {
898         deviceType_ = DeviceType::PHONE;
899     } else {
900         deviceType_ = DeviceType::OTHERS;
901     }
902 }
903 
GetDeviceType() const904 DeviceType RSMainThread::GetDeviceType() const
905 {
906     return deviceType_;
907 }
908 
GetFocusNodeId() const909 uint64_t RSMainThread::GetFocusNodeId() const
910 {
911     return focusNodeId_;
912 }
913 
GetFocusLeashWindowId() const914 uint64_t RSMainThread::GetFocusLeashWindowId() const
915 {
916     return focusLeashWindowId_;
917 }
918 
SetFocusLeashWindowId()919 void RSMainThread::SetFocusLeashWindowId()
920 {
921     const auto& nodeMap = context_->GetNodeMap();
922     auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(focusNodeId_));
923     if (node != nullptr) {
924         auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node->GetParent().lock());
925         if (node->IsAppWindow() && parent && parent->IsLeashWindow()) {
926             focusLeashWindowId_ = parent->GetId();
927             focusLeashWindowName_ = parent->GetName();
928             appWindowId_ = node->GetId();
929             appWindowName_ = node->GetName();
930             appPid_ = appWindowId_ >> HIGH_32BIT;
931         }
932     }
933 }
934 
SetIsCachedSurfaceUpdated(bool isCachedSurfaceUpdated)935 void RSMainThread::SetIsCachedSurfaceUpdated(bool isCachedSurfaceUpdated)
936 {
937     isCachedSurfaceUpdated_ = isCachedSurfaceUpdated;
938 }
939 
SetRSEventDetectorLoopStartTag()940 void RSMainThread::SetRSEventDetectorLoopStartTag()
941 {
942     if (rsCompositionTimeoutDetector_ != nullptr) {
943         rsCompositionTimeoutDetector_->SetLoopStartTag();
944     }
945 }
946 
SetRSEventDetectorLoopFinishTag()947 void RSMainThread::SetRSEventDetectorLoopFinishTag()
948 {
949     if (rsCompositionTimeoutDetector_ != nullptr) {
950         if (isUniRender_) {
951 #ifdef RS_ENABLE_GPU
952             rsCompositionTimeoutDetector_->SetLoopFinishTag(
953                 focusAppPid_, focusAppUid_, focusAppBundleName_, focusAppAbilityName_);
954 #endif
955         } else {
956             std::string defaultFocusAppInfo = "";
957             rsCompositionTimeoutDetector_->SetLoopFinishTag(
958                 -1, -1, defaultFocusAppInfo, defaultFocusAppInfo);
959         }
960     }
961 }
962 
SetFocusAppInfo(const FocusAppInfo & info)963 void RSMainThread::SetFocusAppInfo(const FocusAppInfo& info)
964 {
965     focusAppPid_ = info.pid;
966     focusAppUid_ = info.uid;
967     focusAppBundleName_ = info.bundleName;
968     focusAppAbilityName_ = info.abilityName;
969     UpdateFocusNodeId(info.focusNodeId);
970     RSPerfMonitorReporter::GetInstance().SetFocusAppInfo(info.bundleName.c_str());
971 }
972 
UpdateFocusNodeId(NodeId focusNodeId)973 void RSMainThread::UpdateFocusNodeId(NodeId focusNodeId)
974 {
975     if (focusNodeId_ == focusNodeId || focusNodeId == INVALID_NODEID) {
976         return;
977     }
978     UpdateNeedDrawFocusChange(focusNodeId_);
979     UpdateNeedDrawFocusChange(focusNodeId);
980     focusNodeId_ = focusNodeId;
981 }
982 
UpdateNeedDrawFocusChange(NodeId id)983 void RSMainThread::UpdateNeedDrawFocusChange(NodeId id)
984 {
985     const auto& nodeMap = context_->GetNodeMap();
986     auto node = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(id));
987     // while nodeMap can't find node, return instantly
988     if (!node) {
989         return;
990     }
991     auto parentNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node->GetParent().lock());
992     // while node's parent isn't LEASH_WINDOW_NODE, itselt need SetNeedDrawFocusChange
993     if (!parentNode || parentNode->GetSurfaceNodeType() != RSSurfaceNodeType::LEASH_WINDOW_NODE) {
994         node->SetNeedDrawFocusChange(true);
995         return;
996     }
997     // while node's parent is LEASH_WINDOW_NODE, parent need SetNeedDrawFocusChange
998     parentNode->SetNeedDrawFocusChange(true);
999 }
1000 
Start()1001 void RSMainThread::Start()
1002 {
1003     if (runner_) {
1004         runner_->Run();
1005     }
1006     isRunning_ = true;
1007 }
1008 
ProcessCommand()1009 void RSMainThread::ProcessCommand()
1010 {
1011     RSUnmarshalThread::Instance().ClearTransactionDataStatistics();
1012 
1013     // To improve overall responsiveness, we make animations start on LAST frame instead of THIS frame.
1014     // If last frame is too far away (earlier than 1 vsync from now), we use currentTimestamp_ - REFRESH_PERIOD as
1015     // 'virtual' last frame timestamp.
1016     if (timestamp_ - lastAnimateTimestamp_ > REFRESH_PERIOD) { // if last frame is earlier than 1 vsync from now
1017         context_->currentTimestamp_ = timestamp_ - REFRESH_PERIOD;
1018     } else {
1019         context_->currentTimestamp_ = lastAnimateTimestamp_;
1020     }
1021     RS_PROFILER_ON_PROCESS_COMMAND();
1022     if (isUniRender_) {
1023 #ifdef RS_ENABLE_GPU
1024         ProcessCommandForUniRender();
1025 #endif
1026     } else {
1027         ProcessCommandForDividedRender();
1028     }
1029 #ifdef RS_ENABLE_GPU
1030     switch(context_->purgeType_) {
1031         case RSContext::PurgeType::GENTLY:
1032             isUniRender_ ? RSUniRenderThread::Instance().ClearMemoryCache(context_->clearMoment_, false) :
1033                 ClearMemoryCache(context_->clearMoment_, false);
1034                 isNeedResetClearMemoryTask_ = true;
1035             break;
1036         case RSContext::PurgeType::STRONGLY:
1037             isUniRender_ ? RSUniRenderThread::Instance().ClearMemoryCache(context_->clearMoment_, true) :
1038                 ClearMemoryCache(context_->clearMoment_, true);
1039                 isNeedResetClearMemoryTask_ = true;
1040             break;
1041         default:
1042             break;
1043     }
1044 #endif
1045     context_->purgeType_ = RSContext::PurgeType::NONE;
1046 }
1047 
UpdateSubSurfaceCnt()1048 void RSMainThread::UpdateSubSurfaceCnt()
1049 {
1050     auto& updateInfo = context_->subSurfaceCntUpdateInfo_;
1051     if (updateInfo.empty()) {
1052         return;
1053     }
1054     RS_TRACE_NAME_FMT("UpdateSubSurfaceCnt size: %zu", updateInfo.size());
1055     const auto& nodeMap = context_->GetNodeMap();
1056     for (auto& iter : updateInfo) {
1057         if (iter.curParentId_ != INVALID_NODEID) {
1058             if (auto curParent = nodeMap.GetRenderNode(iter.curParentId_)) {
1059                 curParent->UpdateSubSurfaceCnt(iter.updateCnt_);
1060             }
1061         }
1062         if (iter.preParentId_ != INVALID_NODEID) {
1063             if (auto preParent = nodeMap.GetRenderNode(iter.preParentId_)) {
1064                 preParent->UpdateSubSurfaceCnt(-iter.updateCnt_);
1065             }
1066         }
1067     }
1068     context_->subSurfaceCntUpdateInfo_.clear();
1069 }
1070 
PrintCurrentStatus()1071 void RSMainThread::PrintCurrentStatus()
1072 {
1073 #ifdef RS_ENABLE_GPU
1074     std::string gpuType = "";
1075     switch (RSSystemProperties::GetGpuApiType()) {
1076         case GpuApiType::OPENGL:
1077             gpuType = "opengl";
1078             break;
1079         case GpuApiType::VULKAN:
1080             gpuType = "vulkan";
1081             break;
1082         case GpuApiType::DDGR:
1083             gpuType = "ddgr";
1084             break;
1085         default:
1086             break;
1087     }
1088     RS_LOGI("[Drawing] Version: Non-released");
1089     RS_LOGE("PrintCurrentStatus: drawing is opened, gpu type is %{public}s", gpuType.c_str());
1090 #endif
1091 }
1092 
SubScribeSystemAbility()1093 void RSMainThread::SubScribeSystemAbility()
1094 {
1095     RS_LOGI("%{public}s", __func__);
1096     sptr<ISystemAbilityManager> systemAbilityManager =
1097         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1098     if (!systemAbilityManager) {
1099         RS_LOGE("%{public}s failed to get system ability manager client", __func__);
1100         return;
1101     }
1102     std::string threadName = "RSMainThread";
1103     std::string strUid = std::to_string(getuid());
1104     std::string strPid = std::to_string(getpid());
1105     std::string strTid = std::to_string(gettid());
1106 
1107     saStatusChangeListener_ = new (std::nothrow)VSyncSystemAbilityListener(threadName, strUid, strPid, strTid);
1108     if (saStatusChangeListener_ == nullptr) {
1109         RS_LOGE("SubScribeSystemAbility new VSyncSystemAbilityListener failed");
1110         return;
1111     }
1112     int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, saStatusChangeListener_);
1113     if (ret != ERR_OK) {
1114         RS_LOGE("%{public}s subscribe system ability %{public}d failed.", __func__, RES_SCHED_SYS_ABILITY_ID);
1115         saStatusChangeListener_ = nullptr;
1116     }
1117 }
1118 
CacheCommands()1119 void RSMainThread::CacheCommands()
1120 {
1121     RS_OPTIONAL_TRACE_FUNC();
1122     for (auto& skipTransactionData : cachedSkipTransactionDataMap_) {
1123         pid_t pid = skipTransactionData.first;
1124         RS_TRACE_NAME("cacheCmd pid: " + std::to_string(pid));
1125         auto& skipTransactionDataVec = skipTransactionData.second;
1126         cachedTransactionDataMap_[pid].insert(cachedTransactionDataMap_[pid].begin(),
1127             std::make_move_iterator(skipTransactionDataVec.begin()),
1128             std::make_move_iterator(skipTransactionDataVec.end()));
1129         skipTransactionDataVec.clear();
1130     }
1131 }
1132 
GetCacheCmdSkippedNodes() const1133 const std::unordered_map<NodeId, bool>& RSMainThread::GetCacheCmdSkippedNodes() const
1134 {
1135     return cacheCmdSkippedNodes_;
1136 }
1137 
CheckParallelSubThreadNodesStatus()1138 bool RSMainThread::CheckParallelSubThreadNodesStatus()
1139 {
1140     RS_OPTIONAL_TRACE_FUNC();
1141     cacheCmdSkippedInfo_.clear();
1142     cacheCmdSkippedNodes_.clear();
1143     if (subThreadNodes_.empty() &&
1144         (RSUifirstManager::Instance().GetUiFirstType() != UiFirstCcmType::MULTI
1145             || (leashWindowCount_ > 0 && !RSUifirstManager::Instance().GetUiFirstSwitch()))) {
1146 #ifdef RS_ENABLE_GPU
1147         if (!isUniRender_) {
1148             RSSubThreadManager::Instance()->ResetSubThreadGrContext(); // planning: move to prepare
1149         }
1150 #endif
1151         return false;
1152     }
1153     for (auto& node : subThreadNodes_) {
1154         if (node == nullptr) {
1155             RS_LOGE("CheckParallelSubThreadNodesStatus sunThreadNode is nullptr!");
1156             continue;
1157         }
1158         if (node->GetCacheSurfaceProcessedStatus() == CacheProcessStatus::DOING) {
1159             RS_TRACE_NAME("node:[ " + node->GetName() + "]");
1160             pid_t pid = 0;
1161             if (node->IsAppWindow()) {
1162                 pid = ExtractPid(node->GetId());
1163             } else if (node->IsLeashWindow()) {
1164                 for (auto& child : *node->GetSortedChildren()) {
1165                     auto surfaceNodePtr = child->ReinterpretCastTo<RSSurfaceRenderNode>();
1166                     if (surfaceNodePtr && surfaceNodePtr->IsAppWindow()) {
1167                         pid = ExtractPid(child->GetId());
1168                         break;
1169                     }
1170                 }
1171             }
1172             cacheCmdSkippedNodes_[node->GetId()] = false;
1173             if (pid == 0) {
1174                 continue;
1175             }
1176             RS_LOGD("CheckParallelSubThreadNodesStatus pid = %{public}s, node name: %{public}s,"
1177                 "id: %{public}" PRIu64 "", std::to_string(pid).c_str(), node->GetName().c_str(), node->GetId());
1178             auto it = cacheCmdSkippedInfo_.find(pid);
1179             if (it == cacheCmdSkippedInfo_.end()) {
1180                 cacheCmdSkippedInfo_.emplace(pid, std::make_pair(std::vector<NodeId>{node->GetId()}, false));
1181             } else {
1182                 it->second.first.push_back(node->GetId());
1183             }
1184             if (!node->HasAbilityComponent()) {
1185                 continue;
1186             }
1187             for (auto& nodeId : node->GetAbilityNodeIds()) {
1188                 pid_t abilityNodePid = ExtractPid(nodeId);
1189                 it = cacheCmdSkippedInfo_.find(abilityNodePid);
1190                 if (it == cacheCmdSkippedInfo_.end()) {
1191                     cacheCmdSkippedInfo_.emplace(abilityNodePid,
1192                         std::make_pair(std::vector<NodeId>{node->GetId()}, true));
1193                 } else {
1194                     it->second.first.push_back(node->GetId());
1195                 }
1196             }
1197         }
1198     }
1199     if (!cacheCmdSkippedNodes_.empty()) {
1200         return true;
1201     }
1202     if (!RSUifirstManager::Instance().GetUiFirstSwitch()) {
1203         // clear subThreadNodes_ when UIFirst off and none of subThreadNodes_ is in the state of doing
1204         subThreadNodes_.clear();
1205     }
1206     return false;
1207 }
1208 
IsNeedSkip(NodeId instanceRootNodeId,pid_t pid)1209 bool RSMainThread::IsNeedSkip(NodeId instanceRootNodeId, pid_t pid)
1210 {
1211     return std::any_of(cacheCmdSkippedInfo_[pid].first.begin(), cacheCmdSkippedInfo_[pid].first.end(),
1212         [instanceRootNodeId](const auto& cacheCmdSkipNodeId) {
1213             return cacheCmdSkipNodeId == instanceRootNodeId;
1214         });
1215 }
1216 
SkipCommandByNodeId(std::vector<std::unique_ptr<RSTransactionData>> & transactionVec,pid_t pid)1217 void RSMainThread::SkipCommandByNodeId(std::vector<std::unique_ptr<RSTransactionData>>& transactionVec, pid_t pid)
1218 {
1219     if (cacheCmdSkippedInfo_.find(pid) == cacheCmdSkippedInfo_.end()) {
1220         return;
1221     }
1222     std::vector<std::unique_ptr<RSTransactionData>> skipTransactionVec;
1223     const auto& nodeMap = context_->GetNodeMap();
1224     for (auto& transactionData: transactionVec) {
1225         std::vector<std::tuple<NodeId, FollowType, std::unique_ptr<RSCommand>>> skipPayload;
1226         std::vector<size_t> skipPayloadIndexVec;
1227         auto& processPayload = transactionData->GetPayload();
1228         for (size_t index = 0; index < processPayload.size(); ++index) {
1229             auto& elem = processPayload[index];
1230             if (std::get<2>(elem) == nullptr) { // check elem is valid
1231                 continue;
1232             }
1233             NodeId nodeId = std::get<2>(elem)->GetNodeId();
1234             auto node = nodeMap.GetRenderNode(nodeId);
1235             if (node == nullptr) {
1236                 continue;
1237             }
1238             NodeId firstLevelNodeId = node->GetFirstLevelNodeId();
1239             if (IsNeedSkip(firstLevelNodeId, pid)) {
1240                 skipPayload.emplace_back(std::move(elem));
1241                 skipPayloadIndexVec.push_back(index);
1242             }
1243         }
1244         if (!skipPayload.empty()) {
1245             std::unique_ptr<RSTransactionData> skipTransactionData = std::make_unique<RSTransactionData>();
1246             skipTransactionData->SetTimestamp(transactionData->GetTimestamp());
1247             std::string ablityName = transactionData->GetAbilityName();
1248             skipTransactionData->SetAbilityName(ablityName);
1249             skipTransactionData->SetSendingPid(transactionData->GetSendingPid());
1250             skipTransactionData->SetIndex(transactionData->GetIndex());
1251             skipTransactionData->GetPayload() = std::move(skipPayload);
1252             skipTransactionData->SetIsCached(true);
1253             skipTransactionVec.emplace_back(std::move(skipTransactionData));
1254         }
1255         for (auto iter = skipPayloadIndexVec.rbegin(); iter != skipPayloadIndexVec.rend(); ++iter) {
1256             processPayload.erase(processPayload.begin() + *iter);
1257         }
1258     }
1259     if (!skipTransactionVec.empty()) {
1260         cachedSkipTransactionDataMap_[pid] = std::move(skipTransactionVec);
1261     }
1262 }
1263 
RequestNextVsyncForCachedCommand(std::string & transactionFlags,pid_t pid,uint64_t curIndex)1264 void RSMainThread::RequestNextVsyncForCachedCommand(std::string& transactionFlags, pid_t pid, uint64_t curIndex)
1265 {
1266 #ifdef ROSEN_EMULATOR
1267     transactionFlags += " cache [" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
1268     RequestNextVSync();
1269 #else
1270     transactionFlags += " cache (" + std::to_string(pid) + "," + std::to_string(curIndex) + ")";
1271     RS_TRACE_NAME("RSMainThread::CheckAndUpdateTransactionIndex Trigger NextVsync");
1272     if (rsVSyncDistributor_->IsUiDvsyncOn()) {
1273         RequestNextVSync("fromRsMainCommand", 0);
1274     } else {
1275         RequestNextVSync("UI", 0);
1276     }
1277 #endif
1278 }
1279 
NeedConsumeMultiCommand(int32_t & dvsyncPid)1280 bool RSMainThread::NeedConsumeMultiCommand(int32_t& dvsyncPid)
1281 {
1282     bool needUpdateDVSyncTime = rsVSyncDistributor_->NeedUpdateVSyncTime(dvsyncPid);
1283     uint64_t lastUpdateTime = static_cast<uint64_t>(rsVSyncDistributor_->GetLastUpdateTime());
1284     if (needUpdateDVSyncTime) {
1285         RS_TRACE_NAME("lastUpdateTime:" + std::to_string(lastUpdateTime));
1286         if (lastUpdateTime + static_cast<uint64_t>(rsVSyncDistributor_->GetUiCommandDelayTime()) < timestamp_) {
1287             RS_TRACE_NAME("needConsume:true");
1288             return true;
1289         }
1290     }
1291     return false;
1292 }
1293 
NeedConsumeDVSyncCommand(uint32_t & endIndex,std::vector<std::unique_ptr<RSTransactionData>> & transactionVec)1294 bool RSMainThread::NeedConsumeDVSyncCommand(uint32_t& endIndex,
1295     std::vector<std::unique_ptr<RSTransactionData>>& transactionVec)
1296 {
1297     uint64_t lastTime = 0;
1298     for (auto it = transactionVec.begin(); it != transactionVec.end(); ++it) {
1299         uint64_t curTime = (*it)->GetTimestamp();
1300         if (curTime < lastTime) {
1301             endIndex = (*it)->GetIndex();
1302             rsVSyncDistributor_->SetVSyncTimeUpdated();
1303             RS_TRACE_NAME("isDVSyncConsume:true");
1304             return true;
1305         }
1306         lastTime = curTime;
1307     }
1308     return false;
1309 }
1310 
CheckAndUpdateTransactionIndex(std::shared_ptr<TransactionDataMap> & transactionDataEffective,std::string & transactionFlags)1311 void RSMainThread::CheckAndUpdateTransactionIndex(std::shared_ptr<TransactionDataMap>& transactionDataEffective,
1312     std::string& transactionFlags)
1313 {
1314     int32_t dvsyncPid = 0;
1315     bool needConsume = NeedConsumeMultiCommand(dvsyncPid);
1316     for (auto& rsTransactionElem: effectiveTransactionDataIndexMap_) {
1317         auto pid = rsTransactionElem.first;
1318         auto& lastIndex = rsTransactionElem.second.first;
1319         auto& transactionVec = rsTransactionElem.second.second;
1320         auto iter = transactionVec.begin();
1321         uint32_t endIndex = 0;
1322         bool isDVSyncConsume = false;
1323         if (needConsume && pid == dvsyncPid) {
1324             isDVSyncConsume = NeedConsumeDVSyncCommand(endIndex, transactionVec);
1325         }
1326         for (; iter != transactionVec.end(); ++iter) {
1327             if ((*iter) == nullptr) {
1328                 continue;
1329             }
1330             if ((*iter)->GetIsCached()) {
1331                 continue;
1332             }
1333             auto curIndex = (*iter)->GetIndex();
1334             RS_PROFILER_REPLAY_FIX_TRINDEX(curIndex, lastIndex);
1335             if (curIndex == lastIndex + 1) {
1336                 if ((*iter)->GetTimestamp() + static_cast<uint64_t>(rsVSyncDistributor_->GetUiCommandDelayTime()) +
1337                     rsVSyncDistributor_->GetRsDelayTime(pid)
1338                     >= timestamp_ && (!isDVSyncConsume || curIndex > endIndex)) {
1339                     RequestNextVsyncForCachedCommand(transactionFlags, pid, curIndex);
1340                     break;
1341                 }
1342                 if (transactionDataLastWaitTime_[pid] != 0) {
1343                     transactionDataLastWaitTime_[pid] = 0;
1344                 }
1345                 ++lastIndex;
1346                 transactionFlags += " [" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
1347             } else {
1348                 RS_LOGE("%{public}s wait curIndex:%{public}" PRIu64 ", lastIndex:%{public}" PRIu64 ", pid:%{public}d",
1349                     __FUNCTION__, curIndex, lastIndex, pid);
1350                 if (transactionDataLastWaitTime_[pid] == 0) {
1351                     transactionDataLastWaitTime_[pid] = timestamp_;
1352                 }
1353                 if ((timestamp_ - transactionDataLastWaitTime_[pid]) / REFRESH_PERIOD > SKIP_COMMAND_FREQ_LIMIT) {
1354                     transactionDataLastWaitTime_[pid] = 0;
1355                     lastIndex = curIndex;
1356                     transactionFlags += " skip to[" + std::to_string(pid) + "," + std::to_string(curIndex) + "]";
1357                     RS_LOGE("%{public}s skip to index:%{public}" PRIu64 ", pid:%{public}d",
1358                         __FUNCTION__, curIndex, pid);
1359                     continue;
1360                 }
1361                 break;
1362             }
1363         }
1364         if (iter != transactionVec.begin()) {
1365             if (transactionDataEffective == nullptr) {
1366                 transactionDataEffective = std::make_shared<TransactionDataMap>();
1367             }
1368             (*transactionDataEffective)[pid].insert((*transactionDataEffective)[pid].end(),
1369                 std::make_move_iterator(transactionVec.begin()), std::make_move_iterator(iter));
1370             transactionVec.erase(transactionVec.begin(), iter);
1371         }
1372     }
1373 }
1374 
ProcessCommandForUniRender()1375 void RSMainThread::ProcessCommandForUniRender()
1376 {
1377 #ifdef RS_ENABLE_GPU
1378     std::shared_ptr<TransactionDataMap> transactionDataEffective = nullptr;
1379     std::string transactionFlags;
1380     bool isNeedCacheCmd = CheckParallelSubThreadNodesStatus();
1381     {
1382         std::lock_guard<std::mutex> lock(transitionDataMutex_);
1383         cachedSkipTransactionDataMap_.clear();
1384         for (auto& rsTransactionElem: effectiveTransactionDataIndexMap_) {
1385             auto& transactionVec = rsTransactionElem.second.second;
1386             if (isNeedCacheCmd) {
1387                 auto pid = rsTransactionElem.first;
1388                 SkipCommandByNodeId(transactionVec, pid);
1389             }
1390             std::sort(transactionVec.begin(), transactionVec.end(), Compare);
1391         }
1392         if (isNeedCacheCmd) {
1393             CacheCommands();
1394         }
1395         CheckAndUpdateTransactionIndex(transactionDataEffective, transactionFlags);
1396     }
1397     DelayedSingleton<RSFrameRateVote>::GetInstance()->SetTransactionFlags(transactionFlags);
1398     if ((transactionDataEffective != nullptr && !transactionDataEffective->empty()) ||
1399         RSPointerWindowManager::Instance().GetBoundHasUpdate()) {
1400         doDirectComposition_ = false;
1401         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by transactionDataEffective not empty");
1402     }
1403     const auto& nodeMap = context_->GetNodeMap();
1404     nodeMap.TraverseCanvasDrawingNodes([](const std::shared_ptr<RSCanvasDrawingRenderNode>& canvasDrawingNode) {
1405         if (canvasDrawingNode == nullptr) {
1406             return;
1407         }
1408         if (canvasDrawingNode->IsNeedProcess()) {
1409             auto drawableNode = DrawableV2::RSRenderNodeDrawableAdapter::OnGenerate(canvasDrawingNode);
1410             if (!drawableNode) {
1411                 RS_LOGE("ProcessCommandForUniRender GetCanvasDrawable Failed NodeId[%{public}" PRIu64 "]",
1412                     canvasDrawingNode->GetId());
1413                 return;
1414             }
1415             std::static_pointer_cast<DrawableV2::RSCanvasDrawingRenderNodeDrawable>(drawableNode)
1416                 ->PostPlaybackInCorrespondThread();
1417         }
1418     });
1419     RS_TRACE_NAME("RSMainThread::ProcessCommandUni" + transactionFlags);
1420     if (transactionFlags != "") {
1421         transactionFlags_ = transactionFlags;
1422     }
1423     if (transactionDataEffective != nullptr && !transactionDataEffective->empty()) {
1424         for (auto& rsTransactionElem : *transactionDataEffective) {
1425             for (auto& rsTransaction : rsTransactionElem.second) {
1426                 if (!rsTransaction) {
1427                     continue;
1428                 }
1429                 RS_TRACE_NAME_FMT("[pid:%d, index:%d]", rsTransactionElem.first, rsTransaction->GetIndex());
1430                 // If this transaction is marked as requiring synchronization and the SyncId for synchronization is not
1431                 // 0, or if there have been previous transactions of this process considered as synchronous, then all
1432                 // subsequent transactions of this process will be synchronized.
1433                 if ((rsTransaction->IsNeedSync() && rsTransaction->GetSyncId() > 0) ||
1434                     syncTransactionData_.count(rsTransactionElem.first) > 0) {
1435                     ProcessSyncRSTransactionData(rsTransaction, rsTransactionElem.first);
1436                 } else {
1437                     ProcessRSTransactionData(rsTransaction, rsTransactionElem.first);
1438                 }
1439             }
1440         }
1441         RSBackgroundThread::Instance().PostTask([transactionDataEffective]() {
1442             RS_TRACE_NAME("RSMainThread::ProcessCommandForUniRender transactionDataEffective clear");
1443             transactionDataEffective->clear();
1444         });
1445     }
1446 #endif
1447 }
1448 
ProcessCommandForDividedRender()1449 void RSMainThread::ProcessCommandForDividedRender()
1450 {
1451     const auto& nodeMap = context_->GetNodeMap();
1452     RS_TRACE_BEGIN("RSMainThread::ProcessCommand");
1453     {
1454         std::lock_guard<std::mutex> lock(transitionDataMutex_);
1455         if (!pendingEffectiveCommands_.empty()) {
1456             effectiveCommands_.swap(pendingEffectiveCommands_);
1457         }
1458         for (auto& [surfaceNodeId, commandMap] : cachedCommands_) {
1459             auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(surfaceNodeId);
1460             auto bufferTimestamp = dividedRenderbufferTimestamps_.find(surfaceNodeId);
1461             std::map<uint64_t, std::vector<std::unique_ptr<RSCommand>>>::iterator effectIter;
1462 
1463             if (!node || !node->IsOnTheTree() || bufferTimestamp == dividedRenderbufferTimestamps_.end()) {
1464                 // If node has been destructed or is not on the tree or has no valid buffer,
1465                 // for all command cached in commandMap should be executed immediately
1466                 effectIter = commandMap.end();
1467             } else {
1468                 uint64_t timestamp = bufferTimestamp->second;
1469                 effectIter = commandMap.upper_bound(timestamp);
1470             }
1471 
1472             for (auto it = commandMap.begin(); it != effectIter; it++) {
1473                 effectiveCommands_[it->first].insert(effectiveCommands_[it->first].end(),
1474                     std::make_move_iterator(it->second.begin()), std::make_move_iterator(it->second.end()));
1475             }
1476             commandMap.erase(commandMap.begin(), effectIter);
1477         }
1478     }
1479     for (auto& [timestamp, commands] : effectiveCommands_) {
1480         context_->transactionTimestamp_ = timestamp;
1481         for (auto& command : commands) {
1482             if (command) {
1483                 command->Process(*context_);
1484             }
1485         }
1486     }
1487     effectiveCommands_.clear();
1488     RS_TRACE_END();
1489 }
1490 
ProcessRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData,pid_t pid)1491 void RSMainThread::ProcessRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData, pid_t pid)
1492 {
1493     context_->transactionTimestamp_ = rsTransactionData->GetTimestamp();
1494     rsTransactionData->Process(*context_);
1495 }
1496 
StartSyncTransactionFallbackTask(std::unique_ptr<RSTransactionData> & rsTransactionData)1497 void RSMainThread::StartSyncTransactionFallbackTask(std::unique_ptr<RSTransactionData>& rsTransactionData)
1498 {
1499     if (handler_) {
1500         auto task = [this, syncId = rsTransactionData->GetSyncId()]() {
1501             if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
1502                     syncTransactionData_.begin()->second.front()->GetSyncId() != syncId) {
1503                 return;
1504             }
1505             ROSEN_LOGD("ProcessAllSyncTransactionData timeout task");
1506             ProcessAllSyncTransactionData();
1507         };
1508         handler_->PostTask(
1509             task, "ProcessAllSyncTransactionsTimeoutTask", RSSystemProperties::GetSyncTransactionWaitDelay());
1510     }
1511 }
1512 
ProcessSyncTransactionCount(std::unique_ptr<RSTransactionData> & rsTransactionData)1513 void RSMainThread::ProcessSyncTransactionCount(std::unique_ptr<RSTransactionData>& rsTransactionData)
1514 {
1515     auto sendingPid = rsTransactionData->GetSendingPid();
1516     auto parentPid = rsTransactionData->GetParentPid();
1517     subSyncTransactionCounts_[sendingPid] += rsTransactionData->GetSyncTransactionNum();
1518     if (subSyncTransactionCounts_[sendingPid] == 0) {
1519         subSyncTransactionCounts_.erase(sendingPid);
1520     }
1521     if (!rsTransactionData->IsNeedCloseSync()) {
1522         subSyncTransactionCounts_[parentPid]--;
1523         if (subSyncTransactionCounts_[parentPid] == 0) {
1524             subSyncTransactionCounts_.erase(parentPid);
1525         }
1526     }
1527     ROSEN_LOGI("ProcessSyncTransactionCount isNeedCloseSync:%{public}d syncId:%{public}" PRIu64 ""
1528                " parentPid:%{public}d syncNum:%{public}d subSyncTransactionCounts_.size:%{public}zd",
1529         rsTransactionData->IsNeedCloseSync(), rsTransactionData->GetSyncId(), parentPid,
1530         rsTransactionData->GetSyncTransactionNum(), subSyncTransactionCounts_.size());
1531 }
1532 
ProcessSyncRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData,pid_t pid)1533 void RSMainThread::ProcessSyncRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData, pid_t pid)
1534 {
1535     if (!rsTransactionData->IsNeedSync()) {
1536         syncTransactionData_[pid].emplace_back(std::move(rsTransactionData));
1537         return;
1538     }
1539 
1540     if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
1541         (syncTransactionData_.begin()->second.front()->GetSyncId() > rsTransactionData->GetSyncId())) {
1542         ROSEN_LOGD("ProcessSyncRSTransactionData while syncId less GetCommandCount: %{public}lu"
1543             "pid: %{public}d", rsTransactionData->GetCommandCount(), rsTransactionData->GetSendingPid());
1544         ProcessRSTransactionData(rsTransactionData, pid);
1545         return;
1546     }
1547 
1548     if (!syncTransactionData_.empty() && syncTransactionData_.begin()->second.front() &&
1549         (syncTransactionData_.begin()->second.front()->GetSyncId() != rsTransactionData->GetSyncId())) {
1550         ProcessAllSyncTransactionData();
1551     }
1552     if (syncTransactionData_.empty()) {
1553         StartSyncTransactionFallbackTask(rsTransactionData);
1554     }
1555     if (syncTransactionData_.count(pid) == 0) {
1556         syncTransactionData_.insert({ pid, std::vector<std::unique_ptr<RSTransactionData>>() });
1557     }
1558     ProcessSyncTransactionCount(rsTransactionData);
1559     syncTransactionData_[pid].emplace_back(std::move(rsTransactionData));
1560     if (subSyncTransactionCounts_.empty()) {
1561         ROSEN_LOGI("SyncTxn suc");
1562         ProcessAllSyncTransactionData();
1563     }
1564 }
1565 
ProcessAllSyncTransactionData()1566 void RSMainThread::ProcessAllSyncTransactionData()
1567 {
1568     RS_TRACE_NAME("RSMainThread::ProcessAllSyncTransactionData");
1569     for (auto& [pid, transactions] : syncTransactionData_) {
1570         for (auto& transaction: transactions) {
1571             ROSEN_LOGD("ProcessAllSyncTransactionData GetCommandCount: %{public}lu pid: %{public}d",
1572                 transaction->GetCommandCount(), pid);
1573             ProcessRSTransactionData(transaction, pid);
1574         }
1575     }
1576     syncTransactionData_.clear();
1577     subSyncTransactionCounts_.clear();
1578     RequestNextVSync();
1579 }
1580 
ConsumeAndUpdateAllNodes()1581 void RSMainThread::ConsumeAndUpdateAllNodes()
1582 {
1583     ResetHardwareEnabledState(isUniRender_);
1584     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::ConsumeAndUpdateAllNodes");
1585     requestNextVsyncTime_ = -1;
1586     if (!isUniRender_) {
1587         dividedRenderbufferTimestamps_.clear();
1588     }
1589     RSDrmUtil::ClearDrmNodes();
1590     LppVideoHandler::Instance().ClearLppSurfaceNode();
1591     const auto& nodeMap = GetContext().GetNodeMap();
1592     isHdrSwitchChanged_ = RSLuminanceControl::Get().IsHdrPictureOn() != prevHdrSwitchStatus_;
1593     isColorTemperatureOn_ = RSColorTemperature::Get().IsColorTemperatureOn();
1594     if (UNLIKELY(consumeAndUpdateNode_ == nullptr)) {
1595         consumeAndUpdateNode_ = [this](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
1596             if (UNLIKELY(surfaceNode == nullptr)) {
1597                 return;
1598             }
1599             surfaceNode->ResetSurfaceNodeStates();
1600             // Reset BasicGeoTrans info at the beginning of cmd process
1601             if (surfaceNode->IsLeashOrMainWindow()) {
1602                 surfaceNode->ResetIsOnlyBasicGeoTransform();
1603             }
1604             if (surfaceNode->GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos ||
1605                 (isHdrSwitchChanged_ && surfaceNode->GetHDRPresent())) {
1606                 RS_LOGD("ConsumeAndUpdateAllNodes set %{public}s content dirty",
1607                     surfaceNode->GetName().c_str());
1608                 surfaceNode->SetContentDirty(); // screen recording capsule and hdr switch change force mark dirty
1609             }
1610             if (UNLIKELY(surfaceNode->IsHardwareEnabledType()) &&
1611                 CheckSubThreadNodeStatusIsDoing(surfaceNode->GetInstanceRootNodeId())) {
1612                 RS_LOGD("SubThread is processing %{public}s, skip acquire buffer", surfaceNode->GetName().c_str());
1613                 return;
1614             }
1615             if (surfaceNode->IsForceRefresh()) {
1616                 isForceRefresh_ = true;
1617             }
1618             auto surfaceHandler = surfaceNode->GetMutableRSSurfaceHandler();
1619             if (surfaceHandler->GetAvailableBufferCount() > 0) {
1620                 if (rsVSyncDistributor_ != nullptr) {
1621                     rsVSyncDistributor_->SetHasNativeBuffer();
1622                 }
1623                 auto name = surfaceNode->GetName().empty() ? DEFAULT_SURFACE_NODE_NAME : surfaceNode->GetName();
1624                 auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr();
1625                 const auto& consumer = surfaceHandler->GetConsumer();
1626                 if (LIKELY(frameRateMgr != nullptr) && consumer != nullptr &&
1627                     consumer->GetSurfaceSourceType() != OH_SURFACE_SOURCE_GAME &&
1628                     consumer->GetSurfaceSourceType() != OH_SURFACE_SOURCE_CAMERA &&
1629                     consumer->GetSurfaceSourceType() != OH_SURFACE_SOURCE_VIDEO) {
1630                     frameRateMgr->UpdateSurfaceTime(name, ExtractPid(surfaceNode->GetId()), UIFWKType::FROM_SURFACE);
1631                 }
1632             }
1633             surfaceHandler->ResetCurrentFrameBufferConsumed();
1634             auto parentNode = surfaceNode->GetParent().lock();
1635             bool needSkip = IsSurfaceConsumerNeedSkip(surfaceHandler->GetConsumer());
1636             LppVideoHandler::Instance().ConsumeAndUpdateLppBuffer(surfaceNode);
1637             if (!needSkip && RSBaseRenderUtil::ConsumeAndUpdateBuffer(
1638                 *surfaceHandler, timestamp_, IsNeedDropFrameByPid(surfaceHandler->GetNodeId()),
1639                 parentNode ? parentNode->GetId() : 0)) {
1640                 HandleTunnelLayerId(surfaceHandler, surfaceNode);
1641                 if (!isUniRender_) {
1642                     this->dividedRenderbufferTimestamps_[surfaceNode->GetId()] =
1643                         static_cast<uint64_t>(surfaceHandler->GetTimestamp());
1644                 }
1645 #ifdef RS_ENABLE_GPU
1646                 if (surfaceHandler->IsCurrentFrameBufferConsumed() && UNLIKELY(surfaceNode->IsHardwareEnabledType())) {
1647                     GpuDirtyRegionCollection::GetInstance().UpdateActiveDirtyInfoForDFX(
1648                         surfaceNode->GetId(), surfaceNode->GetName(), surfaceHandler->GetDamageRegion());
1649                 }
1650 #endif
1651                 if (surfaceHandler->IsCurrentFrameBufferConsumed() && !UNLIKELY(surfaceNode->IsHardwareEnabledType())) {
1652                     surfaceNode->SetContentDirty();
1653                     doDirectComposition_ = false;
1654                     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name %s, id %" PRIu64 " disable directComposition by "
1655                         "buffer consumed and not HardwareEnabledType",
1656                         surfaceNode->GetName().c_str(), surfaceNode->GetId());
1657                 }
1658                 if (isUniRender_ && surfaceHandler->IsCurrentFrameBufferConsumed()) {
1659 #ifdef RS_ENABLE_GPU
1660                     auto buffer = surfaceHandler->GetBuffer();
1661                     auto preBuffer = surfaceHandler->GetPreBuffer();
1662                     RSGpuDirtyCollector::SetGpuDirtyEnabled(buffer,
1663                         RSGpuDirtyCollector::GetInstance().IsGpuDirtyEnable(surfaceNode->GetId()));
1664                     surfaceNode->UpdateBufferInfo(
1665                         buffer, surfaceHandler->GetDamageRegion(), surfaceHandler->GetAcquireFence(), preBuffer);
1666                     if (surfaceHandler->GetBufferSizeChanged() || surfaceHandler->GetBufferTransformTypeChanged()) {
1667                         surfaceNode->SetContentDirty();
1668                         doDirectComposition_ = false;
1669                         surfaceHandler->SetBufferTransformTypeChanged(false);
1670                         RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name %s, id %" PRIu64 " disable directComposition by "
1671                             "surfaceNode buffer size changed", surfaceNode->GetName().c_str(), surfaceNode->GetId());
1672                         RS_LOGD("ConsumeAndUpdateAllNodes name:%{public}s id:%{public}" PRIu64 " buffer size changed, "
1673                                 "buffer:[%{public}d, %{public}d], preBuffer:[%{public}d, %{public}d]",
1674                             surfaceNode->GetName().c_str(), surfaceNode->GetId(),
1675                             buffer ? buffer->GetSurfaceBufferWidth() : 0, buffer ? buffer->GetSurfaceBufferHeight() : 0,
1676                             preBuffer ? preBuffer->GetSurfaceBufferWidth() : 0,
1677                             preBuffer ? preBuffer->GetSurfaceBufferHeight() : 0);
1678                     }
1679 #endif
1680                 }
1681                 if (RSUifirstManager::Instance().GetUiFirstSwitch() && surfaceHandler->IsCurrentFrameBufferConsumed() &&
1682                     UNLIKELY(surfaceNode->IsHardwareEnabledType()) && surfaceNode->IsHardwareForcedDisabledByFilter()) {
1683                     RS_OPTIONAL_TRACE_NAME(
1684                         surfaceNode->GetName() + " SetContentDirty for UIFirst assigning to subthread");
1685                     surfaceNode->SetContentDirty();
1686                     doDirectComposition_ = false;
1687                     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name %s, id %" PRIu64 " disable directComposition by "
1688                         "pc uifirst on", surfaceNode->GetName().c_str(), surfaceNode->GetId());
1689                 }
1690             }
1691 #ifdef RS_ENABLE_VK
1692             if ((RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
1693                     RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR) &&
1694                 (surfaceHandler->GetBufferUsage() & BUFFER_USAGE_PROTECTED)) {
1695                 if (!surfaceNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
1696                     surfaceNode->SetProtectedLayer(true);
1697                 }
1698                 const auto& instanceNode = surfaceNode->GetInstanceRootNode();
1699                 if (instanceNode && instanceNode->IsOnTheTree()) {
1700                     hasProtectedLayer_ = true;
1701                     RSDrmUtil::CollectDrmNodes(surfaceNode);
1702                     RSDrmUtil::PreAllocateProtectedBuffer(surfaceNode, surfaceHandler);
1703                 }
1704             }
1705 #endif
1706             // still have buffer(s) to consume.
1707             if (surfaceHandler->GetAvailableBufferCount() > 0) {
1708                 const auto& consumer = surfaceHandler->GetConsumer();
1709                 int64_t nextVsyncTime = 0;
1710                 GetFrontBufferDesiredPresentTimeStamp(consumer, nextVsyncTime);
1711                 if (requestNextVsyncTime_ == -1 || requestNextVsyncTime_ > nextVsyncTime) {
1712                     requestNextVsyncTime_ = nextVsyncTime;
1713                 }
1714             }
1715             surfaceNode->SetVideoHdrStatus(RSHdrUtil::CheckIsHdrSurface(*surfaceNode));
1716             if (isColorTemperatureOn_ && surfaceNode->GetVideoHdrStatus() == HdrStatus::NO_HDR) {
1717                 surfaceNode->SetSdrHasMetadata(RSHdrUtil::CheckIsSurfaceWithMetadata(*surfaceNode));
1718             }
1719             RSHdrManager::Instance().UpdateHdrNodes(*surfaceNode, surfaceHandler->IsCurrentFrameBufferConsumed());
1720         };
1721     }
1722     RSJankStats::GetInstance().AvcodecVideoCollectBegin();
1723     nodeMap.TraverseSurfaceNodes(consumeAndUpdateNode_);
1724     DelayedSingleton<RSFrameRateVote>::GetInstance()->CheckSurfaceAndUi();
1725     RSJankStats::GetInstance().AvcodecVideoCollectFinish();
1726     prevHdrSwitchStatus_ = RSLuminanceControl::Get().IsHdrPictureOn();
1727     if (requestNextVsyncTime_ != -1) {
1728         RequestNextVSync("unknown", 0, requestNextVsyncTime_);
1729     }
1730     RS_OPTIONAL_TRACE_END();
1731 }
1732 
IsSurfaceConsumerNeedSkip(sptr<IConsumerSurface> consumer)1733 bool RSMainThread::IsSurfaceConsumerNeedSkip(sptr<IConsumerSurface> consumer)
1734 {
1735     bool needSkip = false;
1736     if (consumer != nullptr && rsVSyncDistributor_ != nullptr) {
1737         uint64_t uniqueId = consumer->GetUniqueId();
1738         needSkip = rsVSyncDistributor_->NeedSkipForSurfaceBuffer(uniqueId);
1739     }
1740     return needSkip;
1741 }
1742 
CheckSubThreadNodeStatusIsDoing(NodeId appNodeId) const1743 bool RSMainThread::CheckSubThreadNodeStatusIsDoing(NodeId appNodeId) const
1744 {
1745     for (auto& node : subThreadNodes_) {
1746         if (node == nullptr) {
1747             continue;
1748         }
1749         if (node->GetCacheSurfaceProcessedStatus() != CacheProcessStatus::DOING) {
1750             continue;
1751         }
1752         if (node->GetId() == appNodeId) {
1753             return true;
1754         }
1755         for (auto& child : *node->GetSortedChildren()) {
1756             auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1757             if (surfaceNode && surfaceNode->GetId() == appNodeId) {
1758                 return true;
1759             }
1760         }
1761     }
1762     return false;
1763 }
1764 
CollectInfoForHardwareComposer()1765 void RSMainThread::CollectInfoForHardwareComposer()
1766 {
1767 #ifdef RS_ENABLE_GPU
1768     if (!isUniRender_) {
1769         return;
1770     }
1771 #ifdef RS_ENABLE_OVERLAY_DISPLAY
1772     // pre proc for tv overlay display
1773     RSOverlayDisplayManager::Instance().PreProcForRender();
1774 #endif
1775     CheckIfHardwareForcedDisabled();
1776     if (!pendingUiCaptureTasks_.empty()) {
1777         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by uiCapture");
1778         doDirectComposition_ = false;
1779     }
1780     const auto& nodeMap = GetContext().GetNodeMap();
1781     nodeMap.TraverseSurfaceNodes(
1782         [this, &nodeMap](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
1783             if (surfaceNode == nullptr) {
1784                 return;
1785             }
1786             if (surfaceNode->IsCloneCrossNode()) {
1787                 RSDrmUtil::AddDrmCloneCrossNode(surfaceNode, hardwareEnabledDrwawables_);
1788             }
1789             auto surfaceHandler = surfaceNode->GetMutableRSSurfaceHandler();
1790             if (surfaceHandler->GetBuffer() != nullptr) {
1791                 AddSelfDrawingNodes(surfaceNode);
1792                 selfDrawables_.emplace_back(surfaceNode->GetRenderDrawable());
1793                 RSPointerWindowManager::Instance().SetHardCursorNodeInfo(surfaceNode);
1794             }
1795 
1796             if (!surfaceNode->GetDoDirectComposition()) {
1797                 doDirectComposition_ = false;
1798                 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name %s, id %" PRIu64 " disable directComposition by "
1799                     "surfaceNode doDirectComposition is false", surfaceNode->GetName().c_str(), surfaceNode->GetId());
1800                 surfaceNode->SetDoDirectComposition(true);
1801             }
1802 
1803             if (!surfaceNode->IsOnTheTree()) {
1804                 if (surfaceHandler->IsCurrentFrameBufferConsumed()) {
1805                     surfaceNode->UpdateHardwareDisabledState(true);
1806                     doDirectComposition_ = false;
1807                     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name %s, id %" PRIu64 " disable directComposition by "
1808                         "surfaceNode not on the tree and buffer consumed",
1809                         surfaceNode->GetName().c_str(), surfaceNode->GetId());
1810                 }
1811                 return;
1812             }
1813 
1814             // If hardware don't support hdr render, should disable direct composition
1815             if (RSLuminanceControl::Get().IsCloseHardwareHdr() &&
1816                 surfaceNode->GetVideoHdrStatus() != HdrStatus::NO_HDR &&
1817                 !surfaceNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
1818                 doDirectComposition_ = false;
1819                 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name %s, id %" PRIu64 " disable directComposition by HDR",
1820                     surfaceNode->GetName().c_str(), surfaceNode->GetId());
1821             }
1822 
1823             if (surfaceNode->IsLeashWindow() && surfaceNode->GetForceUIFirstChanged()) {
1824                 forceUIFirstChanged_ = true;
1825                 surfaceNode->SetForceUIFirstChanged(false);
1826             }
1827 
1828             if (!surfaceNode->IsHardwareEnabledType()) {
1829                 return;
1830             }
1831 
1832             // if hwc node is set on the tree this frame, mark its parent app node to be prepared
1833             auto appNodeId = surfaceNode->GetInstanceRootNodeId();
1834             if (surfaceNode->IsNewOnTree()) {
1835                 context_->AddActiveNode(nodeMap.GetRenderNode(appNodeId));
1836             }
1837 
1838             if (surfaceHandler->GetBuffer() != nullptr) {
1839                 // collect hwc nodes vector, used for display node skip and direct composition cases
1840                 surfaceNode->SetIsLastFrameHwcEnabled(!surfaceNode->IsHardwareForcedDisabled());
1841                 hardwareEnabledNodes_.emplace_back(surfaceNode);
1842                 hardwareEnabledDrwawables_.emplace_back(std::make_tuple(surfaceNode->GetScreenNodeId(),
1843                     surfaceNode->GetLogicalDisplayNodeId(), surfaceNode->GetRenderDrawable()));
1844             }
1845 
1846             // set content dirty for hwc node if needed
1847             if (isHardwareForcedDisabled_) {
1848                 // buffer updated or hwc -> gpu
1849                 if (surfaceHandler->IsCurrentFrameBufferConsumed() || surfaceNode->GetIsLastFrameHwcEnabled()) {
1850                     surfaceNode->SetContentDirty();
1851                 }
1852             } else if (!surfaceNode->GetIsLastFrameHwcEnabled()) { // gpu -> hwc
1853                 if (surfaceHandler->IsCurrentFrameBufferConsumed()) {
1854                     surfaceNode->SetContentDirty();
1855                     doDirectComposition_ = false;
1856                     RS_OPTIONAL_TRACE_NAME_FMT(
1857                         "hwc debug: name %s, id %" PRIu64 " disable directComposition by lastFrame not enabled HWC "
1858                         "and buffer consumed", surfaceNode->GetName().c_str(), surfaceNode->GetId());
1859                 } else {
1860                     if (surfaceNode->GetAncoForceDoDirect()) {
1861                         surfaceNode->SetContentDirty();
1862                     }
1863                     surfaceNode->SetHwcDelayDirtyFlag(true);
1864                 }
1865             } else { // hwc -> hwc
1866                 // self-drawing node don't set content dirty when gpu -> hwc
1867                 // so first frame in hwc -> hwc, should set content dirty
1868                 if (surfaceNode->GetHwcDelayDirtyFlag() ||
1869                     RSUniRenderUtil::GetRotationDegreeFromMatrix(surfaceNode->GetTotalMatrix()) % RS_ROTATION_90 != 0) {
1870                     surfaceNode->SetContentDirty();
1871                     surfaceNode->SetHwcDelayDirtyFlag(false);
1872                     doDirectComposition_ = false;
1873                     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name %s, id %" PRIu64 " disable directComposition by "
1874                         "HwcDelayDirtyFlag is true", surfaceNode->GetName().c_str(), surfaceNode->GetId());
1875                 }
1876             }
1877 
1878             if (surfaceHandler->IsCurrentFrameBufferConsumed()) {
1879                 isHardwareEnabledBufferUpdated_ = true;
1880             }
1881         });
1882 #endif
1883 }
1884 
IsLastFrameUIFirstEnabled(NodeId appNodeId) const1885 bool RSMainThread::IsLastFrameUIFirstEnabled(NodeId appNodeId) const
1886 {
1887     for (auto& node : subThreadNodes_) {
1888         if (node == nullptr) {
1889             continue;
1890         }
1891         if (node->IsAppWindow()) {
1892             if (node->GetId() == appNodeId) {
1893                 return true;
1894             }
1895         } else {
1896             for (auto& child : *node->GetSortedChildren()) {
1897                 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1898                 if (surfaceNode && surfaceNode->IsAppWindow() && surfaceNode->GetId() == appNodeId) {
1899                     return true;
1900                 }
1901             }
1902         }
1903     }
1904     return false;
1905 }
1906 
CheckOverlayDisplayEnable()1907 static bool CheckOverlayDisplayEnable()
1908 {
1909 #ifdef RS_ENABLE_OVERLAY_DISPLAY
1910     return RSOverlayDisplayManager::Instance().IsOverlayDisplayEnableForCurrentVsync();
1911 #else
1912     return false;
1913 #endif
1914 }
1915 
GetMultiDisplay(const std::shared_ptr<RSBaseRenderNode> & rootNode)1916 bool RSMainThread::GetMultiDisplay(const std::shared_ptr<RSBaseRenderNode>& rootNode)
1917 {
1918     auto screenNodeList = rootNode->GetChildrenList();
1919     uint32_t validCount = 0;
1920     for (const auto& node : screenNodeList) {
1921         auto screenNode = node.lock();
1922         if (screenNode && screenNode->GetChildrenCount() > 0) {
1923             validCount++;
1924         }
1925     }
1926     return validCount > 1;
1927 }
1928 
CheckIfHardwareForcedDisabled()1929 void RSMainThread::CheckIfHardwareForcedDisabled()
1930 {
1931     ColorFilterMode colorFilterMode = RSBaseRenderEngine::GetColorFilterMode();
1932     bool hasColorFilter = colorFilterMode >= ColorFilterMode::INVERT_COLOR_ENABLE_MODE &&
1933         colorFilterMode <= ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE;
1934     std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
1935     bool isMultiDisplay = GetMultiDisplay(rootNode);
1936     MultiDisplayChange(isMultiDisplay);
1937 
1938     // check all children of global root node, and only disable hardware composer
1939     // in case node's composite type is UNI_RENDER_EXPAND_COMPOSITE or Wired projection
1940     const auto& children = rootNode->GetChildren();
1941     auto itr = std::find_if(children->begin(), children->end(),
1942         [](const std::shared_ptr<RSRenderNode>& child) -> bool {
1943             if (child == nullptr || child->GetType() != RSRenderNodeType::SCREEN_NODE) {
1944                 return false;
1945             }
1946             auto screenNodeSp = std::static_pointer_cast<RSScreenRenderNode>(child);
1947             if (screenNodeSp->GetMirrorSource().lock()) {
1948                 // wired projection case
1949                 return screenNodeSp->GetCompositeType() == CompositeType::UNI_RENDER_COMPOSITE;
1950             }
1951             // virtual expand screen
1952             return screenNodeSp->GetCompositeType() == CompositeType::UNI_RENDER_EXPAND_COMPOSITE;
1953     });
1954 
1955     // In the process of cutting the state, the self-drawing layer with the size before the cut state is probably
1956     // sent, resulting in abnormal display, and this problem is solved by disabling HWC in the cutting state
1957     auto screenManager = CreateOrGetScreenManager();
1958     bool isFoldScreenSwitching = screenManager != nullptr && screenManager->IsScreenSwitching();
1959 
1960     bool isExpandScreenOrWiredProjectionCase = itr != children->end();
1961     bool enableHwcForMirrorMode = RSSystemProperties::GetHardwareComposerEnabledForMirrorMode();
1962     // [PLANNING] GetChildrenCount > 1 indicates multi display, only Mirror Mode need be marked here
1963     // Mirror Mode reuses display node's buffer, so mark it and disable hardware composer in this case
1964     isHardwareForcedDisabled_ = isHardwareForcedDisabled_ || doWindowAnimate_ || isFoldScreenSwitching ||
1965         hasColorFilter || CheckOverlayDisplayEnable() ||
1966         (isMultiDisplay && !hasProtectedLayer_ && (isExpandScreenOrWiredProjectionCase || !enableHwcForMirrorMode));
1967 
1968     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug global: CheckIfHardwareForcedDisabled isHardwareForcedDisabled_:%d "
1969         "isFoldScreenSwitching:%d doWindowAnimate_:%d isMultiDisplay:%d hasColorFilter:%d",
1970         isHardwareForcedDisabled_, isFoldScreenSwitching, doWindowAnimate_.load(), isMultiDisplay, hasColorFilter);
1971 
1972     if (isMultiDisplay && !isHardwareForcedDisabled_) {
1973         // Disable direct composition when hardware composer is enabled for virtual screen
1974         doDirectComposition_ = false;
1975         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by isMultiDisplay");
1976     }
1977 }
1978 
ReleaseAllNodesBuffer()1979 void RSMainThread::ReleaseAllNodesBuffer()
1980 {
1981     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::ReleaseAllNodesBuffer");
1982     const auto& nodeMap = GetContext().GetNodeMap();
1983     nodeMap.TraverseSurfaceNodes([this](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) mutable {
1984         if (surfaceNode == nullptr) {
1985             return;
1986         }
1987         auto surfaceHandler = surfaceNode->GetMutableRSSurfaceHandler();
1988         // surfaceNode's buffer will be released in hardware thread if last frame enables hardware composer
1989         if (surfaceNode->IsHardwareEnabledType()) {
1990             if (surfaceNode->IsLastFrameHardwareEnabled()) {
1991                 if (!surfaceNode->IsCurrentFrameHardwareEnabled()) {
1992                     auto preBuffer = surfaceHandler->GetPreBuffer();
1993                     if (preBuffer != nullptr) {
1994                         auto releaseTask = [buffer = preBuffer, consumer = surfaceHandler->GetConsumer(),
1995                             fence = surfaceHandler->GetPreBufferReleaseFence()]() mutable {
1996                             auto ret = consumer->ReleaseBuffer(buffer, fence);
1997                             if (ret != OHOS::SURFACE_ERROR_OK) {
1998                                 RS_LOGD("surfaceHandler ReleaseBuffer failed(ret: %{public}d)!", ret);
1999                             }
2000                         };
2001                         surfaceHandler->ResetPreBuffer();
2002 #ifdef RS_ENABLE_GPU
2003                         RSHardwareThread::Instance().PostTask(releaseTask);
2004 #endif
2005                     }
2006                 }
2007                 surfaceNode->ResetCurrentFrameHardwareEnabledState();
2008                 return;
2009             }
2010             surfaceNode->ResetCurrentFrameHardwareEnabledState();
2011         }
2012         RSBaseRenderUtil::ReleaseBuffer(*surfaceHandler);
2013     });
2014     RS_OPTIONAL_TRACE_END();
2015 }
2016 
GetRefreshRate() const2017 uint32_t RSMainThread::GetRefreshRate() const
2018 {
2019     auto screenManager = CreateOrGetScreenManager();
2020     if (!screenManager) {
2021         RS_LOGE("GetRefreshRate screenManager is nullptr");
2022         return STANDARD_REFRESH_RATE;
2023     }
2024     uint32_t refreshRate = HgmCore::Instance().GetScreenCurrentRefreshRate(
2025         screenManager->GetDefaultScreenId());
2026     if (refreshRate == 0) {
2027         RS_LOGE("GetRefreshRate refreshRate is invalid");
2028         return STANDARD_REFRESH_RATE;
2029     }
2030     return refreshRate;
2031 }
2032 
GetDynamicRefreshRate() const2033 uint32_t RSMainThread::GetDynamicRefreshRate() const
2034 {
2035     uint32_t refreshRate = HgmCore::Instance().GetScreenCurrentRefreshRate(screenNodeScreenId_);
2036     if (refreshRate == 0) {
2037         RS_LOGE("GetDynamicRefreshRate refreshRate is invalid");
2038         return STANDARD_REFRESH_RATE;
2039     }
2040     return refreshRate;
2041 }
2042 
ClearMemoryCache(ClearMemoryMoment moment,bool deeply,pid_t pid)2043 void RSMainThread::ClearMemoryCache(ClearMemoryMoment moment, bool deeply, pid_t pid)
2044 {
2045 #ifdef RS_ENABLE_GPU
2046     if (!RSSystemProperties::GetReleaseResourceEnabled()) {
2047         return;
2048     }
2049 
2050     this->clearMemoryFinished_ = false;
2051     this->clearMemDeeply_ = this->clearMemDeeply_ || deeply;
2052     this->SetClearMoment(moment);
2053     this->exitedPidSet_.emplace(pid);
2054     auto task =
2055         [this, moment, deeply]() {
2056             auto grContext = GetRenderEngine()->GetRenderContext()->GetDrGPUContext();
2057             if (!grContext) {
2058                 return;
2059             }
2060             RS_LOGD("Clear memory cache %{public}d", this->GetClearMoment());
2061             RS_TRACE_NAME_FMT("Clear memory cache, cause the moment [%d] happen", this->GetClearMoment());
2062             SKResourceManager::Instance().ReleaseResource();
2063             grContext->Flush();
2064             SkGraphics::PurgeAllCaches(); // clear cpu cache
2065             auto pid = *(this->exitedPidSet_.begin());
2066             if (this->exitedPidSet_.size() == 1 && pid == -1) {  // no exited app, just clear scratch resource
2067                 if (deeply || MEMParam::IsDeeplyRelGpuResEnable()) {
2068                     MemoryManager::ReleaseUnlockAndSafeCacheGpuResource(grContext);
2069                 } else {
2070                     MemoryManager::ReleaseUnlockGpuResource(grContext);
2071                 }
2072             } else {
2073                 MemoryManager::ReleaseUnlockGpuResource(grContext, this->exitedPidSet_);
2074             }
2075             grContext->FlushAndSubmit(true);
2076             this->clearMemoryFinished_ = true;
2077             this->exitedPidSet_.clear();
2078             this->clearMemDeeply_ = false;
2079             this->SetClearMoment(ClearMemoryMoment::NO_CLEAR);
2080         };
2081     auto refreshRate = GetRefreshRate();
2082     if (refreshRate > 0) {
2083         if (!isUniRender_ || rsParallelType_ == RsParallelType::RS_PARALLEL_TYPE_SINGLE_THREAD) {
2084             PostTask(task, CLEAR_GPU_CACHE,
2085                 (MEMParam::IsDeeplyRelGpuResEnable() ? TIME_OF_THE_FRAMES : TIME_OF_EIGHT_FRAMES) / refreshRate,
2086                 AppExecFwk::EventQueue::Priority::HIGH);
2087         } else {
2088             RSUniRenderThread::Instance().PostTask(task, CLEAR_GPU_CACHE,
2089                 (MEMParam::IsDeeplyRelGpuResEnable() ? TIME_OF_THE_FRAMES : TIME_OF_EIGHT_FRAMES) / refreshRate,
2090                 AppExecFwk::EventQueue::Priority::HIGH);
2091         }
2092     }
2093 #endif
2094 }
2095 
WaitUntilUnmarshallingTaskFinished()2096 void RSMainThread::WaitUntilUnmarshallingTaskFinished()
2097 {
2098     if (!isUniRender_) {
2099         return;
2100     }
2101     if (!needWaitUnmarshalFinished_) {
2102         /* if needWaitUnmarshalFinished_ is false, it means UnmarshallingTask is finished, no need to wait.
2103          * reset needWaitUnmarshalFinished_ to true, maybe it need to wait next time.
2104          */
2105         needWaitUnmarshalFinished_ = true;
2106         return;
2107     }
2108     RS_OPTIONAL_TRACE_BEGIN("RSMainThread::WaitUntilUnmarshallingTaskFinished");
2109     std::unique_lock<std::mutex> lock(unmarshalMutex_);
2110     if (unmarshalFinishedCount_ > 0) {
2111         waitForDVSyncFrame_.store(false);
2112     } else {
2113         waitForDVSyncFrame_.store(true);
2114     }
2115     if (!unmarshalTaskCond_.wait_for(lock, std::chrono::milliseconds(WAIT_FOR_UNMARSHAL_THREAD_TASK_TIMEOUT),
2116         [this]() { return unmarshalFinishedCount_ > 0; })) {
2117         if (auto task = RSUnmarshalTaskManager::Instance().GetLongestTask()) {
2118             RSUnmarshalThread::Instance().RemoveTask(task.value().name);
2119             RS_LOGI("WaitUntilUnmarshallingTaskFinished"
2120                 "the wait time exceeds %{public}d ms, remove task %{public}s",
2121                 WAIT_FOR_UNMARSHAL_THREAD_TASK_TIMEOUT, task.value().name.c_str());
2122             RS_TRACE_NAME_FMT("RSMainThread::WaitUntilUnmarshallingTaskFinished"
2123                 "the wait time exceeds %d ms, remove task %s",
2124                 WAIT_FOR_UNMARSHAL_THREAD_TASK_TIMEOUT, task.value().name.c_str());
2125         }
2126     }
2127     RSUnmarshalTaskManager::Instance().Clear();
2128     --unmarshalFinishedCount_;
2129     RS_OPTIONAL_TRACE_END();
2130 }
2131 
MergeToEffectiveTransactionDataMap(TransactionDataMap & cachedTransactionDataMap)2132 void RSMainThread::MergeToEffectiveTransactionDataMap(TransactionDataMap& cachedTransactionDataMap)
2133 {
2134     std::lock_guard<std::mutex> lock(transitionDataMutex_);
2135     for (auto& elem : cachedTransactionDataMap) {
2136         auto pid = elem.first;
2137         if (effectiveTransactionDataIndexMap_.count(pid) == 0) {
2138             RS_LOGE("MergeToEffectiveTransactionDataMap pid:%{public}d not valid, skip it", pid);
2139             continue;
2140         }
2141         InsertToEnd(elem.second, effectiveTransactionDataIndexMap_[pid].second);
2142     }
2143     cachedTransactionDataMap.clear();
2144 }
2145 
OnHideNotchStatusCallback(const char * key,const char * value,void * context)2146 void RSMainThread::OnHideNotchStatusCallback(const char *key, const char *value, void *context)
2147 {
2148     if (strcmp(key, HIDE_NOTCH_STATUS) != 0) {
2149         RS_LOGI("OnHideNotchStatusCallback, key is not HIDE_NOTCH_STATUS");
2150         return;
2151     }
2152     RS_LOGI("OnHideNotchStatusCallback HideNotchStatus is change, status is %{public}d",
2153         RSSystemParameters::GetHideNotchStatus());
2154     RSMainThread::Instance()->RequestNextVSync();
2155 }
2156 
OnDrawingCacheDfxSwitchCallback(const char * key,const char * value,void * context)2157 void RSMainThread::OnDrawingCacheDfxSwitchCallback(const char *key, const char *value, void *context)
2158 {
2159     if (strcmp(key, DRAWING_CACHE_DFX) != 0) {
2160         return;
2161     }
2162     bool isDrawingCacheDfxEnabled;
2163     if (value) {
2164         isDrawingCacheDfxEnabled = (std::atoi(value) != 0);
2165     } else {
2166         isDrawingCacheDfxEnabled = RSSystemParameters::GetDrawingCacheEnabledDfx();
2167     }
2168     RSMainThread::Instance()->PostTask([isDrawingCacheDfxEnabled]() {
2169         RSMainThread::Instance()->SetDirtyFlag();
2170         RSMainThread::Instance()->SetDrawingCacheDfxEnabledOfCurFrame(isDrawingCacheDfxEnabled);
2171         RSMainThread::Instance()->RequestNextVSync("DrawingCacheDfx");
2172     });
2173 }
2174 
IsRequestedNextVSync()2175 bool RSMainThread::IsRequestedNextVSync()
2176 {
2177     if (receiver_ != nullptr) {
2178         return receiver_->IsRequestedNextVSync();
2179     }
2180     return false;
2181 }
2182 
ProcessHgmFrameRate(uint64_t timestamp)2183 void RSMainThread::ProcessHgmFrameRate(uint64_t timestamp)
2184 {
2185     hgmContext_.ProcessHgmFrameRate(timestamp, rsVSyncDistributor_, vsyncId_);
2186 }
2187 
SetFrameIsRender(bool isRender)2188 void RSMainThread::SetFrameIsRender(bool isRender)
2189 {
2190     if (rsVSyncDistributor_ != nullptr) {
2191         rsVSyncDistributor_->SetFrameIsRender(isRender);
2192     }
2193 }
2194 
AddUiCaptureTask(NodeId id,std::function<void ()> task)2195 void RSMainThread::AddUiCaptureTask(NodeId id, std::function<void()> task)
2196 {
2197     pendingUiCaptureTasks_.emplace_back(id, task);
2198     if (!IsRequestedNextVSync()) {
2199         RequestNextVSync();
2200     }
2201 }
2202 
PrepareUiCaptureTasks(std::shared_ptr<RSUniRenderVisitor> uniVisitor)2203 void RSMainThread::PrepareUiCaptureTasks(std::shared_ptr<RSUniRenderVisitor> uniVisitor)
2204 {
2205     std::vector<std::tuple<NodeId, std::function<void()>>> remainUiCaptureTasks;
2206     const auto& nodeMap = context_->GetNodeMap();
2207     for (auto [id, captureTask]: pendingUiCaptureTasks_) {
2208         auto node = nodeMap.GetRenderNode(id);
2209         auto cmdFlag = context_->GetUiCaptureHelper().GetUiCaptureCmdsExecutedFlag(id);
2210         uint64_t duration = context_->GetUiCaptureHelper().GetCurrentSteadyTimeMs() - cmdFlag.second;
2211         if (!cmdFlag.first && duration < TIME_OF_CAPTURE_TASK_REMAIN) {
2212             RS_TRACE_NAME_FMT("RSMainThread::PrepareUiCaptureTasks cmds not be processed, id: %" PRIu64
2213                               ", duration: %" PRIu64 "ms", id, duration);
2214             RS_LOGI("PrepareUiCaptureTasks cmds not be processed, id: %{public}" PRIu64
2215                     ", duration: %{public}" PRIu64 "ms", id, duration);
2216             remainUiCaptureTasks.emplace_back(id, captureTask);
2217             continue;
2218         }
2219         context_->GetUiCaptureHelper().EraseUiCaptureCmdsExecutedFlag(id);
2220         if (!node) {
2221             RS_LOGW("PrepareUiCaptureTasks node is nullptr");
2222         } else if (!node->IsOnTheTree() || node->IsDirty() || node->IsSubTreeDirty()) {
2223             node->PrepareSelfNodeForApplyModifiers();
2224         }
2225         uiCaptureTasks_.emplace(id, captureTask);
2226     }
2227     pendingUiCaptureTasks_.clear();
2228     pendingUiCaptureTasks_.insert(pendingUiCaptureTasks_.end(),
2229         remainUiCaptureTasks.begin(), remainUiCaptureTasks.end());
2230     remainUiCaptureTasks.clear();
2231 }
2232 
ProcessUiCaptureTasks()2233 void RSMainThread::ProcessUiCaptureTasks()
2234 {
2235 #ifdef RS_ENABLE_GPU
2236     while (!uiCaptureTasks_.empty()) {
2237         if (RSUiCaptureTaskParallel::GetCaptureCount() >= MAX_CAPTURE_COUNT) {
2238             return;
2239         }
2240         auto captureTask = std::get<1>(uiCaptureTasks_.front());
2241         uiCaptureTasks_.pop();
2242         captureTask();
2243     }
2244 #endif
2245 }
2246 
CheckBlurEffectCountStatistics(std::shared_ptr<RSRenderNode> rootNode)2247 void RSMainThread::CheckBlurEffectCountStatistics(std::shared_ptr<RSRenderNode> rootNode)
2248 {
2249     uint32_t terminateLimit = RSSystemProperties::GetBlurEffectTerminateLimit();
2250     if (terminateLimit == 0) {
2251         return;
2252     }
2253     static std::unique_ptr<AppExecFwk::AppMgrClient> appMgrClient =
2254         std::make_unique<AppExecFwk::AppMgrClient>();
2255     auto children = rootNode->GetChildren();
2256     if (children->empty()) {
2257         return;
2258     }
2259     auto screenNode = RSRenderNode::ReinterpretCast<RSScreenRenderNode>(children->front());
2260     if (screenNode == nullptr) {
2261         return;
2262     }
2263     auto displayNodeChildren = screenNode->GetChildren();
2264     if (displayNodeChildren->empty()) {
2265         return;
2266     }
2267     auto logicalDisplayNode = RSRenderNode::ReinterpretCast<RSLogicalDisplayRenderNode>(children->front());
2268     if (logicalDisplayNode == nullptr) {
2269         return;
2270     }
2271     auto scbPid = logicalDisplayNode->GetCurrentScbPid();
2272     int32_t uid = 0;
2273     std::string bundleName;
2274     for (auto& [pid, count] : rootNode->blurEffectCounter_) {
2275         if (pid == scbPid) {
2276             continue;
2277         }
2278         appMgrClient->GetBundleNameByPid(pid, bundleName, uid);
2279         if (count > terminateLimit) {
2280             auto res = appMgrClient->KillApplicationByUid(bundleName, uid);
2281             if (res) {
2282                 RS_LOGI("bundleName[%{public}s] was killed for too many blur effcts. "
2283                     "BlurEffectCountStatistics: pid[%{public}d] uid[%{public}d] blurCount[%{public}zu]",
2284                     bundleName.c_str(), pid, uid, count);
2285                 rootNode->blurEffectCounter_.erase(pid);
2286             } else {
2287                 RS_LOGE("kill bundleName[%{public}s] for too many blur effcts failed. "
2288                     "BlurEffectCountStatistics: pid[%{public}d] uid[%{public}d] blurCount[%{public}zu]",
2289                     bundleName.c_str(), pid, uid, count);
2290             }
2291         }
2292     }
2293 }
2294 
StartGPUDraw()2295 void RSMainThread::StartGPUDraw()
2296 {
2297     gpuDrawCount_.fetch_add(1, std::memory_order_relaxed);
2298 }
2299 
EndGPUDraw()2300 void RSMainThread::EndGPUDraw()
2301 {
2302     if (gpuDrawCount_.fetch_sub(1, std::memory_order_relaxed) == 1) {
2303         // gpuDrawCount_ is now 0
2304         ClearUnmappedCache();
2305     }
2306 }
2307 
ClearUnmappedCache()2308 void RSMainThread::ClearUnmappedCache()
2309 {
2310     std::set<uint32_t> bufferIds;
2311     {
2312         std::lock_guard<std::mutex> lock(unmappedCacheSetMutex_);
2313         bufferIds.swap(unmappedCacheSet_);
2314     }
2315     if (!bufferIds.empty()) {
2316         auto engine = GetRenderEngine();
2317         if (engine) {
2318             engine->ClearCacheSet(bufferIds);
2319         }
2320         RSHardwareThread::Instance().ClearRedrawGPUCompositionCache(bufferIds);
2321     }
2322 }
2323 
UniRender(std::shared_ptr<RSBaseRenderNode> rootNode)2324 void RSMainThread::UniRender(std::shared_ptr<RSBaseRenderNode> rootNode)
2325 {
2326 #ifdef RS_ENABLE_GPU
2327 #if defined(ROSEN_OHOS) && defined(ENABLE_HPAE_BLUR)
2328     RSHpaeManager::GetInstance().OnUniRenderStart();
2329 #endif
2330     if (isAccessibilityConfigChanged_) {
2331         RS_LOGD("UniRender AccessibilityConfig has Changed");
2332     }
2333     RSUifirstManager::Instance().RefreshUIFirstParam();
2334     auto uniVisitor = std::make_shared<RSUniRenderVisitor>();
2335     uniVisitor->SetProcessorRenderEngine(GetRenderEngine());
2336     int64_t rsPeriod = 0;
2337     if (receiver_) {
2338         receiver_->GetVSyncPeriod(rsPeriod);
2339     }
2340     rsVsyncRateReduceManager_.ResetFrameValues(impl::CalculateRefreshRate(rsPeriod));
2341 
2342     if (isHardwareForcedDisabled_) {
2343         uniVisitor->MarkHardwareForcedDisabled();
2344         doDirectComposition_ = false;
2345         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by HardwareForcedDisabled");
2346     }
2347     // need draw skipped node at cur frame
2348     bool uiFirstNeedNextDraw = RSUifirstManager::Instance().NeedNextDrawForSkippedNode();
2349     if (doDirectComposition_ && uiFirstNeedNextDraw) {
2350         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by uifirst needNextDrawForSkippedNode");
2351     }
2352     doDirectComposition_ &= !uiFirstNeedNextDraw;
2353 
2354     // if screen is power-off, DirectComposition should be disabled.
2355     if (RSUniRenderUtil::CheckRenderSkipIfScreenOff()) {
2356         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by PowerOff");
2357         doDirectComposition_ = false;
2358     }
2359 
2360     bool needTraverseNodeTree = true;
2361     needDrawFrame_ = true;
2362     bool pointerSkip = !RSPointerWindowManager::Instance().IsPointerCanSkipFrameCompareChange(false, true);
2363     bool willGoDirectComposition = doDirectComposition_ && !isDirty_ && !isAccessibilityConfigChanged_ &&
2364                                    !isCachedSurfaceUpdated_ && pointerSkip;
2365     RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: needGoDirectComposition:[%d], isDirty:[%d], "
2366         "isAccessibilityConfigChanged:[%d], isCachedSurfaceUpdated:[%d], pointerSkip:[%d]",
2367         willGoDirectComposition, isDirty_.load(), isAccessibilityConfigChanged_, isCachedSurfaceUpdated_, pointerSkip);
2368     if (willGoDirectComposition) {
2369         doDirectComposition_ = isHardwareEnabledBufferUpdated_;
2370         if (!doDirectComposition_) {
2371             RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by buffer not updated");
2372         }
2373         if (isHardwareEnabledBufferUpdated_) {
2374             needTraverseNodeTree = !DoDirectComposition(rootNode, !directComposeHelper_.isLastFrameDirectComposition_);
2375         } else if (forceUpdateUniRenderFlag_) {
2376             RS_TRACE_NAME("RSMainThread::UniRender ForceUpdateUniRender");
2377         } else if (!pendingUiCaptureTasks_.empty()) {
2378             RS_LOGD("Render pendingUiCaptureTasks_ not empty");
2379         } else {
2380             needDrawFrame_ = false;
2381             RS_LOGD("Render nothing to update");
2382             RS_TRACE_NAME("RSMainThread::UniRender nothing to update");
2383             RSMainThread::Instance()->SetFrameIsRender(false);
2384             RSMainThread::Instance()->SetSkipJankAnimatorFrame(true);
2385             for (auto& node: hardwareEnabledNodes_) {
2386                 if (!node->IsHardwareForcedDisabled()) {
2387                     node->MarkCurrentFrameHardwareEnabled();
2388                 }
2389             }
2390             renderThreadParams_->selfDrawables_ = std::move(selfDrawables_);
2391             renderThreadParams_->hardwareEnabledTypeDrawables_ = std::move(hardwareEnabledDrwawables_);
2392             renderThreadParams_->hardCursorDrawableVec_ = RSPointerWindowManager::Instance().GetHardCursorDrawableVec();
2393             RsFrameReport::GetInstance().DirectRenderEnd();
2394             return;
2395         }
2396     }
2397 
2398     isCachedSurfaceUpdated_ = false;
2399     if (needTraverseNodeTree) {
2400         RSUniRenderThread::Instance().PostTask([] {
2401             RSUniRenderThread::Instance().ResetClearMemoryTask();
2402         });
2403         RSUifirstManager::Instance().ProcessForceUpdateNode();
2404         RSPointerWindowManager::Instance().UpdatePointerInfo();
2405         doDirectComposition_ = false;
2406         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by needTraverseNodeTree");
2407         uniVisitor->SetAnimateState(doWindowAnimate_);
2408         uniVisitor->SetDirtyFlag(isDirty_ || isAccessibilityConfigChanged_ || forceUIFirstChanged_);
2409         forceUIFirstChanged_ = false;
2410         SetFocusLeashWindowId();
2411         uniVisitor->SetFocusedNodeId(focusNodeId_, focusLeashWindowId_);
2412         rsVsyncRateReduceManager_.SetFocusedNodeId(focusNodeId_);
2413         rootNode->QuickPrepare(uniVisitor);
2414         uniVisitor->ResetCrossNodesVisitedStatus();
2415 
2416 #ifdef RES_SCHED_ENABLE
2417         const auto& nodeMapForFrameReport = GetContext().GetNodeMap();
2418         uint32_t frameRatePidFromRSS = ResschedEventListener::GetInstance()->GetCurrentPid();
2419         if (frameRatePidFromRSS != 0) {
2420             nodeMapForFrameReport.TraverseSurfaceNodesBreakOnCondition(
2421                 [this, frameRatePidFromRSS](
2422                     const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) {
2423                     if (surfaceNode == nullptr) {
2424                         return false;
2425                     }
2426                     uint32_t pidFromNode = ExtractPid(surfaceNode->GetId());
2427                     if (frameRatePidFromRSS != pidFromNode) {
2428                         return false;
2429                     }
2430                     auto dirtyManager = surfaceNode->GetDirtyManager();
2431                     if (dirtyManager == nullptr || dirtyManager->GetCurrentFrameDirtyRegion().IsEmpty()) {
2432                         return false;
2433                     }
2434                     ResschedEventListener::GetInstance()->ReportFrameCountAsync(pidFromNode);
2435                     return true;
2436             });
2437         }
2438 #endif // RES_SCHED_ENABLE
2439 
2440         if (SOCPerfParam::IsMultilayersSOCPerfEnable()) {
2441             RSUniRenderUtil::MultiLayersPerf(uniVisitor->GetLayerNum());
2442         }
2443         CheckBlurEffectCountStatistics(rootNode);
2444         uniVisitor->SurfaceOcclusionCallbackToWMS();
2445         SelfDrawingNodeMonitor::GetInstance().TriggerRectChangeCallback();
2446         rsVsyncRateReduceManager_.SetUniVsync();
2447         renderThreadParams_->selfDrawables_ = std::move(selfDrawables_);
2448         renderThreadParams_->hardCursorDrawableVec_ = RSPointerWindowManager::Instance().GetHardCursorDrawableVec();
2449         renderThreadParams_->hardwareEnabledTypeDrawables_ = std::move(hardwareEnabledDrwawables_);
2450         renderThreadParams_->isOverDrawEnabled_ = isOverDrawEnabledOfCurFrame_;
2451         renderThreadParams_->isDrawingCacheDfxEnabled_ = isDrawingCacheDfxEnabledOfCurFrame_;
2452         isAccessibilityConfigChanged_ = false;
2453         isCurtainScreenUsingStatusChanged_ = false;
2454         RSPointLightManager::Instance()->PrepareLight();
2455         systemAnimatedScenesEnabled_ = RSSystemParameters::GetSystemAnimatedScenesEnabled();
2456         lastWatermarkFlag_ = watermarkFlag_;
2457         isOverDrawEnabledOfLastFrame_ = isOverDrawEnabledOfCurFrame_;
2458         isDrawingCacheDfxEnabledOfLastFrame_ = isDrawingCacheDfxEnabledOfCurFrame_;
2459         // set params used in render thread
2460         uniVisitor->SetUniRenderThreadParam(renderThreadParams_);
2461     } else {
2462         RsFrameReport::GetInstance().DirectRenderEnd();
2463     }
2464 
2465     PrepareUiCaptureTasks(uniVisitor);
2466     screenPowerOnChanged_ = false;
2467     forceUpdateUniRenderFlag_ = false;
2468     if (context_) {
2469         context_->SetUnirenderVisibleLeashWindowCount(context_->GetNodeMap().GetVisibleLeashWindowCount());
2470     }
2471 #endif
2472 }
2473 
DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode,bool waitForRT)2474 bool RSMainThread::DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode, bool waitForRT)
2475 {
2476     auto children = rootNode->GetChildrenList();
2477     if (children.empty()) {
2478         return false;
2479     }
2480     RS_TRACE_NAME("DoDirectComposition");
2481     std::shared_ptr<RSScreenRenderNode> screenNode = nullptr;
2482     for (const auto& child : children) {
2483         auto node = child.lock();
2484         if (node && node->GetChildrenCount() > 0) {
2485             screenNode = node->ReinterpretCastTo<RSScreenRenderNode>();
2486             break;
2487         }
2488     }
2489     if (!screenNode ||
2490         screenNode->GetCompositeType() != CompositeType::UNI_RENDER_COMPOSITE) {
2491         RS_LOGE("DoDirectComposition screenNode state error");
2492         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by screenNode state error");
2493         return false;
2494     }
2495     if (UNLIKELY(screenNode->GetForceFreeze())) {
2496         RS_TRACE_NAME("DoDirectComposition skip, screen frozen");
2497         return true;
2498     }
2499     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
2500     if (screenManager == nullptr) {
2501         RS_LOGE("DoDirectComposition screenManager is nullptr");
2502         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by screenManager is nullptr");
2503         return false;
2504     }
2505     auto screenInfo = screenManager->QueryScreenInfo(screenNode->GetScreenId());
2506     if (screenInfo.state != ScreenState::HDI_OUTPUT_ENABLE) {
2507         RS_LOGE("DoDirectComposition: ScreenState error!");
2508         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by screenState error");
2509         return false;
2510     }
2511 
2512 #ifdef RS_ENABLE_GPU
2513     auto processor = RSProcessorFactory::CreateProcessor(screenNode->GetCompositeType());
2514     auto renderEngine = GetRenderEngine();
2515     if (processor == nullptr || renderEngine == nullptr) {
2516         RS_LOGE("DoDirectComposition: RSProcessor or renderEngine is null!");
2517         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by processor or renderEngine is null");
2518         return false;
2519     }
2520 
2521     if (!processor->Init(*screenNode, screenInfo.offsetX, screenInfo.offsetY,
2522         INVALID_SCREEN_ID, renderEngine)) {
2523         RS_LOGE("DoDirectComposition: processor init failed!");
2524         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by processor init failed");
2525         return false;
2526     }
2527 #endif
2528     auto drawable = screenNode->GetRenderDrawable();
2529     if (drawable != nullptr) {
2530 #ifdef RS_ENABLE_GPU
2531         auto screenDrawable = std::static_pointer_cast<DrawableV2::RSScreenRenderNodeDrawable>(drawable);
2532         auto surfaceHandler = screenDrawable->GetRSSurfaceHandlerOnDraw();
2533 #else
2534         auto surfaceHandler = nullptr;
2535 #endif
2536 #ifdef RS_ENABLE_GPU
2537         if (RSAncoManager::Instance()->AncoOptimizeScreenNode(surfaceHandler, hardwareEnabledNodes_,
2538             ScreenRotation::ROTATION_0, screenInfo.GetRotatedPhyWidth(), screenInfo.GetRotatedPhyHeight())) {
2539             RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by ancoOptimizeScreenNode");
2540             return false;
2541         }
2542 #endif
2543     }
2544 
2545     if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
2546         RS_LOGW("DoDirectComposition: hardwareThread task has too many to Execute"
2547                 " TaskNum:[%{public}d]", RSHardwareThread::Instance().GetunExecuteTaskNum());
2548         RSHardwareThread::Instance().DumpEventQueue();
2549     }
2550 #ifdef RS_ENABLE_GPU
2551     auto screenId = screenNode->GetScreenId();
2552     for (auto& surfaceNode : hardwareEnabledNodes_) {
2553         if (surfaceNode == nullptr) {
2554             RS_LOGE("DoDirectComposition: surfaceNode is null!");
2555             continue;
2556         }
2557         RSHdrUtil::UpdateSurfaceNodeNit(*surfaceNode, screenId);
2558         screenNode->CollectHdrStatus(surfaceNode->GetVideoHdrStatus());
2559         auto surfaceHandler = surfaceNode->GetRSSurfaceHandler();
2560         if (!surfaceNode->IsHardwareForcedDisabled()) {
2561             auto params = static_cast<RSSurfaceRenderParams*>(surfaceNode->GetStagingRenderParams().get());
2562             HandleTunnelLayerId(surfaceHandler, surfaceNode);
2563             if (!surfaceHandler->IsCurrentFrameBufferConsumed() && params->GetPreBuffer() != nullptr) {
2564                 params->SetPreBuffer(nullptr);
2565                 surfaceNode->AddToPendingSyncList();
2566             }
2567             if (surfaceNode->GetDeviceOfflineEnable() && processor->ProcessOfflineLayer(surfaceNode)) {
2568                 // use offline buffer instead of original buffer,
2569                 // if succeed, params->SetBufferSynced will not be set true,
2570                 // origianl buffer will be released at next acquirement
2571                 continue;
2572             }
2573             processor->CreateLayer(*surfaceNode, *params);
2574             // buffer is synced to directComposition
2575             params->SetBufferSynced(true);
2576         }
2577     }
2578     RSLuminanceControl::Get().SetHdrStatus(screenId,
2579         screenNode->GetForceCloseHdr() ? HdrStatus::NO_HDR : screenNode->GetDisplayHdrStatus());
2580 #endif
2581 #ifdef RS_ENABLE_GPU
2582     RSPointerWindowManager::Instance().HardCursorCreateLayerForDirect(processor);
2583     DoScreenRcdTask(*screenNode, processor);
2584 #endif
2585     if (waitForRT) {
2586 #ifdef RS_ENABLE_GPU
2587         RSUniRenderThread::Instance().PostSyncTask([processor, screenNode]() {
2588             RS_TRACE_NAME("DoDirectComposition PostProcess");
2589             HgmCore::Instance().SetDirectCompositionFlag(true);
2590             processor->ProcessScreenSurface(*screenNode);
2591             processor->PostProcess();
2592         });
2593 #endif
2594     } else {
2595         HgmCore::Instance().SetDirectCompositionFlag(true);
2596 #ifdef RS_ENABLE_GPU
2597         processor->ProcessScreenSurface(*screenNode);
2598         processor->PostProcess();
2599 #endif
2600     }
2601 
2602     RS_LOGD("DoDirectComposition end");
2603     return true;
2604 }
2605 
ExistBufferIsVisibleAndUpdate()2606 bool RSMainThread::ExistBufferIsVisibleAndUpdate()
2607 {
2608     bool bufferNeedUpdate = false;
2609     for (auto& surfaceNode : hardwareEnabledNodes_) {
2610         if (surfaceNode == nullptr) {
2611             RS_LOGD("[%{public}s]: surfaceNode is null", __func__);
2612             continue;
2613         }
2614         if (surfaceNode->GetRSSurfaceHandler() == nullptr) {
2615             continue;
2616         }
2617         if (surfaceNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
2618             surfaceNode->HwcSurfaceRecorder().GetLastFrameHasVisibleRegion()) {
2619             bufferNeedUpdate = true;
2620             break;
2621         }
2622     }
2623     return bufferNeedUpdate;
2624 }
2625 
GetDesktopPidForRotationScene() const2626 pid_t RSMainThread::GetDesktopPidForRotationScene() const
2627 {
2628     return desktopPidForRotationScene_;
2629 }
2630 
GetForceCommitReason() const2631 uint32_t RSMainThread::GetForceCommitReason() const
2632 {
2633     uint32_t forceCommitReason = 0;
2634     if (isHardwareEnabledBufferUpdated_) {
2635         forceCommitReason |= ForceCommitReason::FORCED_BY_HWC_UPDATE;
2636     }
2637     if (forceUpdateUniRenderFlag_) {
2638         forceCommitReason |= ForceCommitReason::FORCED_BY_UNI_RENDER_FLAG;
2639     }
2640     return forceCommitReason;
2641 }
2642 
Render()2643 void RSMainThread::Render()
2644 {
2645     if (RSSystemParameters::GetRenderStop()) {
2646         return;
2647     }
2648     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
2649     if (rootNode == nullptr) {
2650         RS_LOGE("Render GetGlobalRootRenderNode fail");
2651         return;
2652     }
2653     if (isUniRender_) {
2654 #ifdef RS_ENABLE_GPU
2655         auto& hgmCore = HgmCore::Instance();
2656         renderThreadParams_->SetTimestamp(hgmCore.GetCurrentTimestamp());
2657         renderThreadParams_->SetActualTimestamp(hgmCore.GetActualTimestamp());
2658         renderThreadParams_->SetVsyncId(hgmCore.GetVsyncId());
2659         renderThreadParams_->SetForceRefreshFlag(isForceRefresh_);
2660         renderThreadParams_->SetPendingScreenRefreshRate(hgmCore.GetPendingScreenRefreshRate());
2661         renderThreadParams_->SetPendingConstraintRelativeTime(hgmCore.GetPendingConstraintRelativeTime());
2662         renderThreadParams_->SetForceCommitLayer(GetForceCommitReason());
2663         renderThreadParams_->SetOcclusionEnabled(RSSystemProperties::GetOcclusionEnabled());
2664         renderThreadParams_->SetCacheEnabledForRotation(RSSystemProperties::GetCacheEnabledForRotation());
2665         renderThreadParams_->SetUIFirstCurrentFrameCanSkipFirstWait(
2666             RSUifirstManager::Instance().GetCurrentFrameSkipFirstWait());
2667         // If use DoDirectComposition, we do not sync renderThreadParams,
2668         // so we use hgmCore to keep force refresh flag, then reset flag.
2669         hgmCore.SetForceRefreshFlag(isForceRefresh_);
2670         isForceRefresh_ = false;
2671         uint64_t fastComposeTimeStampDiff = 0;
2672         if (lastFastComposeTimeStamp_ == timestamp_) {
2673             fastComposeTimeStampDiff = lastFastComposeTimeStampDiff_;
2674         }
2675         renderThreadParams_->SetFastComposeTimeStampDiff(fastComposeTimeStampDiff);
2676         hgmCore.SetFastComposeTimeStampDiff(fastComposeTimeStampDiff);
2677 #endif
2678     }
2679     if (RSSystemProperties::GetRenderNodeTraceEnabled()) {
2680         RSPropertyTrace::GetInstance().RefreshNodeTraceInfo();
2681     }
2682     if (focusAppBundleName_.find(DESKTOP_NAME_FOR_ROTATION) != std::string::npos) {
2683         desktopPidForRotationScene_ = focusAppPid_;
2684     }
2685     int dumpTreeCount = RSSystemParameters::GetDumpRSTreeCount();
2686     if (UNLIKELY(dumpTreeCount)) {
2687         RS_TRACE_NAME("dump rstree");
2688         RenderServiceTreeDump(g_dumpStr);
2689         RSSystemParameters::SetDumpRSTreeCount(dumpTreeCount - 1);
2690     }
2691     if (isUniRender_) {
2692 #ifdef RS_ENABLE_GPU
2693         renderThreadParams_->SetWatermark(watermarkFlag_, watermarkImg_);
2694         {
2695             std::lock_guard<std::mutex> lock(watermarkMutex_);
2696             renderThreadParams_->SetWatermarks(surfaceNodeWatermarks_);
2697         }
2698 
2699         renderThreadParams_->SetCurtainScreenUsingStatus(isCurtainScreenOn_);
2700 #ifdef RS_ENABLE_GPU
2701         UniRender(rootNode);
2702 #endif
2703         frameCount_++;
2704 #endif
2705     } else {
2706         auto rsVisitor = std::make_shared<RSRenderServiceVisitor>();
2707         rsVisitor->SetAnimateState(doWindowAnimate_);
2708         rootNode->Prepare(rsVisitor);
2709         CalcOcclusion();
2710         bool doParallelComposition = false;
2711         if (!rsVisitor->ShouldForceSerial() && RSInnovation::GetParallelCompositionEnabled(isUniRender_)) {
2712             doParallelComposition = DoParallelComposition(rootNode);
2713         }
2714         if (doParallelComposition) {
2715             renderEngine_->ShrinkCachesIfNeeded();
2716             return;
2717         }
2718         rootNode->Process(rsVisitor);
2719         renderEngine_->ShrinkCachesIfNeeded();
2720     }
2721     if (!isUniRender_) {
2722         CallbackDrawContextStatusToWMS();
2723         PerfForBlurIfNeeded();
2724     }
2725     CheckSystemSceneStatus();
2726     UpdateLuminanceAndColorTemp();
2727     LppVideoHandler::Instance().JudgeRsDrawLppState(needDrawFrame_, doDirectComposition_);
2728 }
2729 
OnUniRenderDraw()2730 void RSMainThread::OnUniRenderDraw()
2731 {
2732 #ifndef SCREENLESS_DEVICE
2733     if (!isUniRender_) {
2734         RsFrameReport::GetInstance().RenderEnd();
2735         return;
2736     }
2737 #ifdef RS_ENABLE_GPU
2738     isLastFrameNeedPostAndWait_ = needPostAndWait_;
2739     needPostAndWait_ = !doDirectComposition_ && needDrawFrame_;
2740     if (needPostAndWait_) {
2741         renderThreadParams_->SetContext(context_);
2742         renderThreadParams_->SetDiscardJankFrames(GetDiscardJankFrames());
2743         drawFrame_.SetRenderThreadParams(renderThreadParams_);
2744         RsFrameReport::GetInstance().CheckPostAndWaitPoint();
2745         drawFrame_.PostAndWait();
2746         RsFrameReport::GetInstance().RenderEnd();
2747         return;
2748     }
2749     // To remove ClearMemoryTask for first frame of doDirectComposition or if needed
2750     if ((doDirectComposition_ && !directComposeHelper_.isLastFrameDirectComposition_) ||
2751         isNeedResetClearMemoryTask_ || !needDrawFrame_) {
2752         RSUniRenderThread::Instance().PostTask([] {
2753             RSUniRenderThread::Instance().ResetClearMemoryTask(true);
2754         });
2755         isNeedResetClearMemoryTask_ = false;
2756     }
2757 
2758     UpdateScreenNodeScreenId();
2759     RsFrameReport::GetInstance().RenderEnd();
2760 #endif
2761 #endif
2762 }
2763 
CheckSystemSceneStatus()2764 void RSMainThread::CheckSystemSceneStatus()
2765 {
2766     std::lock_guard<std::mutex> lock(systemAnimatedScenesMutex_);
2767     uint64_t curTime = static_cast<uint64_t>(
2768         std::chrono::duration_cast<std::chrono::nanoseconds>(
2769             std::chrono::steady_clock::now().time_since_epoch()).count());
2770     while (!systemAnimatedScenesList_.empty()) {
2771         if (curTime - static_cast<uint64_t>(systemAnimatedScenesList_.front().second) > MAX_SYSTEM_SCENE_STATUS_TIME) {
2772             systemAnimatedScenesList_.pop_front();
2773         } else {
2774             break;
2775         }
2776     }
2777     while (!threeFingerScenesList_.empty()) {
2778         if (curTime - static_cast<uint64_t>(threeFingerScenesList_.front().second) > MAX_SYSTEM_SCENE_STATUS_TIME) {
2779             threeFingerScenesList_.pop_front();
2780         } else {
2781             break;
2782         }
2783     }
2784 }
2785 
CallbackDrawContextStatusToWMS(bool isUniRender)2786 void RSMainThread::CallbackDrawContextStatusToWMS(bool isUniRender)
2787 {
2788 #ifdef RS_ENABLE_GPU
2789     auto& curDrawStatusVec = isUniRender ? RSUniRenderThread::Instance().GetDrawStatusVec() : curDrawStatusVec_;
2790     auto timestamp = isUniRender ? RSUniRenderThread::Instance().GetCurrentTimestamp() : timestamp_;
2791 #else
2792     auto& curDrawStatusVec = curDrawStatusVec_;
2793     auto timestamp = timestamp_;
2794 #endif
2795     VisibleData drawStatusVec;
2796     for (auto dynamicNodeId : curDrawStatusVec) {
2797         if (lastDrawStatusMap_.find(dynamicNodeId) == lastDrawStatusMap_.end()) {
2798             drawStatusVec.emplace_back(std::make_pair(dynamicNodeId,
2799                 WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_DYNAMIC_STATUS));
2800             RS_OPTIONAL_TRACE_NAME_FMT("%s nodeId[%" PRIu64 "] status[%d]",
2801                 __func__, dynamicNodeId, WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_DYNAMIC_STATUS);
2802         }
2803         lastDrawStatusMap_[dynamicNodeId] = timestamp;
2804     }
2805     auto drawStatusIter = lastDrawStatusMap_.begin();
2806     while (drawStatusIter != lastDrawStatusMap_.end()) {
2807         if (timestamp - drawStatusIter->second > MAX_DYNAMIC_STATUS_TIME) {
2808             drawStatusVec.emplace_back(std::make_pair(drawStatusIter->first,
2809                 WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_STATIC_STATUS));
2810             RS_OPTIONAL_TRACE_NAME_FMT("%s nodeId[%" PRIu64 "] status[%d]",
2811                 __func__, drawStatusIter->first, WINDOW_LAYER_INFO_TYPE::WINDOW_LAYER_STATIC_STATUS);
2812             auto tmpIter = drawStatusIter++;
2813             lastDrawStatusMap_.erase(tmpIter);
2814         } else {
2815             drawStatusIter++;
2816         }
2817     }
2818     curDrawStatusVec.clear();
2819     if (!drawStatusVec.empty()) {
2820         std::lock_guard<std::mutex> lock(occlusionMutex_);
2821         for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
2822             if (it->second) {
2823                 it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(drawStatusVec));
2824             }
2825         }
2826     }
2827 }
2828 
CheckSurfaceNeedProcess(OcclusionRectISet & occlusionSurfaces,std::shared_ptr<RSSurfaceRenderNode> curSurface)2829 bool RSMainThread::CheckSurfaceNeedProcess(OcclusionRectISet& occlusionSurfaces,
2830     std::shared_ptr<RSSurfaceRenderNode> curSurface)
2831 {
2832     bool needProcess = false;
2833     if (curSurface->IsFocusedNode(focusNodeId_)) {
2834         needProcess = true;
2835         if (!curSurface->HasContainerWindow() && !curSurface->IsTransparent() &&
2836             !curSurface->HasWindowCorner() &&
2837             !curSurface->GetAnimateState() && // when node animating (i.e. 3d animation), the region cannot be trusted
2838             curSurface->GetName().find("hisearch") == std::string::npos) {
2839             occlusionSurfaces.insert({curSurface->GetId(), curSurface->GetDstRect()});
2840         }
2841     } else {
2842         size_t beforeSize = occlusionSurfaces.size();
2843         occlusionSurfaces.insert({curSurface->GetId(), curSurface->GetDstRect()});
2844         bool insertSuccess = occlusionSurfaces.size() > beforeSize ? true : false;
2845         if (insertSuccess) {
2846             needProcess = true;
2847             if (curSurface->IsTransparent() ||
2848                 curSurface->HasWindowCorner() ||
2849                 curSurface->GetAnimateState() || // when node animating(i.e. 3d animation), the region cannot be trusted
2850                 curSurface->GetName().find("hisearch") != std::string::npos) {
2851                 auto iter = std::find_if(occlusionSurfaces.begin(), occlusionSurfaces.end(),
2852                     [&curSurface](const auto& r) -> bool {return r.second == curSurface->GetDstRect();});
2853                 if (iter != occlusionSurfaces.end()) {
2854                     occlusionSurfaces.erase(iter);
2855                 }
2856             }
2857         }
2858     }
2859     return needProcess;
2860 }
2861 
GetRegionVisibleLevel(const Occlusion::Region & curRegion,const Occlusion::Region & visibleRegion)2862 RSVisibleLevel RSMainThread::GetRegionVisibleLevel(const Occlusion::Region& curRegion,
2863     const Occlusion::Region& visibleRegion)
2864 {
2865     if (visibleRegion.IsEmpty()) {
2866         return RSVisibleLevel::RS_INVISIBLE;
2867     } else if (visibleRegion.Area() == curRegion.Area()) {
2868         return RSVisibleLevel::RS_ALL_VISIBLE;
2869     } else if (static_cast<uint>(visibleRegion.Area()) <
2870         (static_cast<uint>(curRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
2871         return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
2872     }
2873     return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
2874 }
2875 
CalcSurfaceNodeVisibleRegion(const std::shared_ptr<RSScreenRenderNode> & screenNode,const std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedRegion,Occlusion::Region & curRegion,Occlusion::Region & totalRegion)2876 RSVisibleLevel RSMainThread::CalcSurfaceNodeVisibleRegion(const std::shared_ptr<RSScreenRenderNode>& screenNode,
2877     const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2878     Occlusion::Region& accumulatedRegion, Occlusion::Region& curRegion, Occlusion::Region& totalRegion)
2879 {
2880     if (!surfaceNode) {
2881         return RSVisibleLevel::RS_INVISIBLE;
2882     }
2883 
2884     if (!isUniRender_) {
2885         if (screenNode) {
2886             surfaceNode->SetDstRect(screenNode->GetSurfaceDstRect(surfaceNode->GetId()));
2887         }
2888     }
2889 
2890     Occlusion::Rect occlusionRect = surfaceNode->GetSurfaceOcclusionRect(isUniRender_);
2891     curRegion = Occlusion::Region { occlusionRect };
2892     Occlusion::Region subRegion = curRegion.Sub(accumulatedRegion);
2893 
2894     RSVisibleLevel visibleLevel = GetRegionVisibleLevel(curRegion, subRegion);
2895 
2896     if (!isUniRender_) {
2897         Occlusion::Region visSurface = surfaceNode->GetVisibleRegion();
2898         totalRegion = subRegion.Or(visSurface);
2899     } else {
2900         totalRegion = subRegion;
2901     }
2902 
2903     return visibleLevel;
2904 }
2905 
CalcOcclusionImplementation(const std::shared_ptr<RSScreenRenderNode> & screenNode,std::vector<RSBaseRenderNode::SharedPtr> & curAllSurfaces,VisibleData & dstCurVisVec,std::map<NodeId,RSVisibleLevel> & dstVisMapForVsyncRate)2906 void RSMainThread::CalcOcclusionImplementation(const std::shared_ptr<RSScreenRenderNode>& screenNode,
2907     std::vector<RSBaseRenderNode::SharedPtr>& curAllSurfaces, VisibleData& dstCurVisVec,
2908     std::map<NodeId, RSVisibleLevel>& dstVisMapForVsyncRate)
2909 {
2910     Occlusion::Region accumulatedRegion;
2911     VisibleData curVisVec;
2912     OcclusionRectISet occlusionSurfaces;
2913     std::map<NodeId, RSVisibleLevel> visMapForVsyncRate;
2914     bool hasFilterCacheOcclusion = false;
2915     bool filterCacheOcclusionEnabled = RSSystemParameters::GetFilterCacheOcculusionEnabled();
2916 
2917     vsyncControlEnabled_ = rsVsyncRateReduceManager_.GetVRateDeviceSupport() &&
2918                            RSSystemParameters::GetVSyncControlEnabled();
2919     auto calculator = [this, &screenNode, &occlusionSurfaces, &accumulatedRegion, &curVisVec, &visMapForVsyncRate,
2920         &hasFilterCacheOcclusion, filterCacheOcclusionEnabled] (std::shared_ptr<RSSurfaceRenderNode>& curSurface,
2921         bool needSetVisibleRegion) {
2922         curSurface->setQosCal(vsyncControlEnabled_);
2923         if (!CheckSurfaceNeedProcess(occlusionSurfaces, curSurface)) {
2924             curSurface->SetVisibleRegionRecursive({}, curVisVec, visMapForVsyncRate);
2925             return;
2926         }
2927 
2928         Occlusion::Region curRegion {};
2929         Occlusion::Region totalRegion {};
2930         auto visibleLevel =
2931             CalcSurfaceNodeVisibleRegion(screenNode, curSurface, accumulatedRegion, curRegion, totalRegion);
2932 
2933         curSurface->SetVisibleRegionRecursive(totalRegion, curVisVec, visMapForVsyncRate, needSetVisibleRegion,
2934             visibleLevel, !systemAnimatedScenesList_.empty());
2935         curSurface->AccumulateOcclusionRegion(
2936             accumulatedRegion, curRegion, hasFilterCacheOcclusion, isUniRender_, filterCacheOcclusionEnabled);
2937     };
2938 
2939     for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
2940         auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2941         if (curSurface && !curSurface->IsLeashWindow()) {
2942             curSurface->SetOcclusionInSpecificScenes(rsVsyncRateReduceManager_.GetVRateDeviceSupport()
2943                                                     && !threeFingerScenesList_.empty());
2944             calculator(curSurface, true);
2945         }
2946     }
2947 
2948     // if there are valid filter cache occlusion, recalculate surfacenode visibleregionforcallback for WMS/QOS callback
2949     if (hasFilterCacheOcclusion && isUniRender_) {
2950         curVisVec.clear();
2951         visMapForVsyncRate.clear();
2952         occlusionSurfaces.clear();
2953         accumulatedRegion = {};
2954         for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
2955             auto curSurface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2956             if (curSurface && !curSurface->IsLeashWindow()) {
2957                 calculator(curSurface, false);
2958             }
2959         }
2960     }
2961 
2962     dstCurVisVec.insert(dstCurVisVec.end(), curVisVec.begin(), curVisVec.end());
2963     dstVisMapForVsyncRate.insert(visMapForVsyncRate.begin(), visMapForVsyncRate.end());
2964 }
2965 
CalcOcclusion()2966 void RSMainThread::CalcOcclusion()
2967 {
2968     RS_OPTIONAL_TRACE_NAME("RSMainThread::CalcOcclusion");
2969     RS_LOGD("CalcOcclusion animate:%{public}d isUniRender:%{public}d",
2970         doWindowAnimate_.load(), isUniRender_);
2971     if (doWindowAnimate_ && !isUniRender_) {
2972         return;
2973     }
2974     const std::shared_ptr<RSBaseRenderNode> node = context_->GetGlobalRootRenderNode();
2975     if (node == nullptr) {
2976         RS_LOGE("CalcOcclusion GetGlobalRootRenderNode fail");
2977         return;
2978     }
2979     std::map<RSScreenRenderNode::SharedPtr, std::vector<RSBaseRenderNode::SharedPtr>> curAllSurfacesInDisplay;
2980     std::vector<RSBaseRenderNode::SharedPtr> curAllSurfaces;
2981     for (const auto& child : *node->GetSortedChildren()) {
2982         auto screenNode = RSBaseRenderNode::ReinterpretCast<RSScreenRenderNode>(child);
2983         if (screenNode) {
2984             const auto& surfaces = screenNode->GetCurAllSurfaces();
2985             curAllSurfacesInDisplay[screenNode] = surfaces;
2986             curAllSurfaces.insert(curAllSurfaces.end(), surfaces.begin(), surfaces.end());
2987         }
2988     }
2989 
2990     if (node->GetChildrenCount()== 1) {
2991         auto screenNode = RSBaseRenderNode::ReinterpretCast<RSScreenRenderNode>(node->GetFirstChild());
2992         if (screenNode) {
2993             curAllSurfaces = screenNode->GetCurAllSurfaces();
2994         }
2995     } else {
2996         node->CollectSurface(node, curAllSurfaces, isUniRender_, false);
2997     }
2998     // Judge whether it is dirty
2999     // Surface cnt changed or surface DstRectChanged or surface ZorderChanged
3000     std::vector<NodeId> curSurfaceIds;
3001     curSurfaceIds.reserve(curAllSurfaces.size());
3002     for (auto it = curAllSurfaces.begin(); it != curAllSurfaces.end(); ++it) {
3003         auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
3004         if (surface == nullptr) {
3005             continue;
3006         }
3007         curSurfaceIds.emplace_back(surface->GetId());
3008     }
3009     bool winDirty = (isDirty_ || lastFocusNodeId_ != focusNodeId_ || lastSurfaceIds_ != curSurfaceIds);
3010     lastSurfaceIds_ = std::move(curSurfaceIds);
3011     lastFocusNodeId_ = focusNodeId_;
3012     if (!winDirty) {
3013         for (auto it = curAllSurfaces.rbegin(); it != curAllSurfaces.rend(); ++it) {
3014             auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
3015             if (surface == nullptr || surface->IsLeashWindow()) {
3016                 continue;
3017             }
3018             if (surface->GetZorderChanged() || surface->GetDstRectChanged() ||
3019                 surface->IsOpaqueRegionChanged() ||
3020                 surface->GetAlphaChanged() || (isUniRender_ && surface->IsDirtyRegionUpdated())) {
3021                 winDirty = true;
3022             } else if (RSSystemParameters::GetFilterCacheOcculusionEnabled() &&
3023                 surface->IsTransparent() && surface->IsFilterCacheStatusChanged()) {
3024                 // When current frame's filter cache is valid or last frame's occlusion use filter cache as opaque
3025                 // The occlusion needs to be recalculated
3026                 winDirty = true;
3027             }
3028             surface->CleanDstRectChanged();
3029             surface->CleanAlphaChanged();
3030             surface->CleanOpaqueRegionChanged();
3031             surface->CleanDirtyRegionUpdated();
3032         }
3033     }
3034     bool needRefreshRates = systemAnimatedScenesList_.empty() &&
3035         rsVsyncRateReduceManager_.GetIsReduceBySystemAnimatedScenes();
3036     if (!winDirty && !needRefreshRates) {
3037         if (SurfaceOcclusionCallBackIfOnTreeStateChanged()) {
3038             SurfaceOcclusionCallback();
3039         }
3040         return;
3041     }
3042     rsVsyncRateReduceManager_.SetIsReduceBySystemAnimatedScenes(false);
3043     VisibleData dstCurVisVec;
3044     std::map<NodeId, RSVisibleLevel> dstVisMapForVsyncRate;
3045     for (auto& surfaces : curAllSurfacesInDisplay) {
3046         CalcOcclusionImplementation(surfaces.first, surfaces.second, dstCurVisVec, dstVisMapForVsyncRate);
3047     }
3048 
3049     // Callback to WMS and QOS
3050     CallbackToWMS(dstCurVisVec);
3051     rsVsyncRateReduceManager_.SetVSyncRateByVisibleLevel(dstVisMapForVsyncRate, curAllSurfaces);
3052     // Callback for registered self drawing surfacenode
3053     SurfaceOcclusionCallback();
3054 }
3055 
CallbackToWMS(VisibleData & curVisVec)3056 void RSMainThread::CallbackToWMS(VisibleData& curVisVec)
3057 {
3058     // if visible surfaces changed callback to WMS:
3059     // 1. curVisVec size changed
3060     // 2. curVisVec content changed
3061     bool visibleChanged = curVisVec.size() != lastVisVec_.size();
3062     std::sort(curVisVec.begin(), curVisVec.end());
3063     if (!visibleChanged) {
3064         for (uint32_t i = 0; i < curVisVec.size(); i++) {
3065             if ((curVisVec[i].first != lastVisVec_[i].first) || (curVisVec[i].second != lastVisVec_[i].second)) {
3066                 visibleChanged = true;
3067                 break;
3068             }
3069         }
3070     }
3071     if (visibleChanged) {
3072         std::lock_guard<std::mutex> lock(occlusionMutex_);
3073         for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
3074             if (it->second) {
3075                 it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(curVisVec));
3076             }
3077         }
3078     }
3079     lastVisVec_.clear();
3080     std::swap(lastVisVec_, curVisVec);
3081 }
3082 
SurfaceOcclusionCallback()3083 void RSMainThread::SurfaceOcclusionCallback()
3084 {
3085     std::list<std::pair<sptr<RSISurfaceOcclusionChangeCallback>, float>> callbackList;
3086     {
3087         std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
3088         for (auto &listener : surfaceOcclusionListeners_) {
3089             if (!CheckSurfaceOcclusionNeedProcess(listener.first)) {
3090                 continue;
3091             }
3092             uint8_t level = 0;
3093             float visibleAreaRatio = 0.0f;
3094             bool isOnTheTree = savedAppWindowNode_[listener.first].first->IsOnTheTree();
3095             if (isOnTheTree) {
3096                 const auto& property = savedAppWindowNode_[listener.first].second->GetRenderProperties();
3097                 auto& geoPtr = property.GetBoundsGeometry();
3098                 if (!geoPtr) {
3099                     continue;
3100                 }
3101                 auto absRect = geoPtr->GetAbsRect();
3102                 if (absRect.IsEmpty()) {
3103                     continue;
3104                 }
3105                 auto surfaceRegion = Occlusion::Region{ Occlusion::Rect{ absRect } };
3106                 auto visibleRegion = savedAppWindowNode_[listener.first].second->GetVisibleRegion();
3107                 // take the intersection of these two regions to get rid of shadow area, then calculate visible ratio
3108                 visibleAreaRatio = static_cast<float>(visibleRegion.And(surfaceRegion).Area()) /
3109                     static_cast<float>(surfaceRegion.Area());
3110                 auto& partitionVector = std::get<2>(listener.second); // get tuple 2 partition points vector
3111                 bool vectorEmpty = partitionVector.empty();
3112                 if (vectorEmpty && (visibleAreaRatio > 0.0f)) {
3113                     level = 1;
3114                 } else if (!vectorEmpty && ROSEN_EQ(visibleAreaRatio, 1.0f)) {
3115                     level = partitionVector.size();
3116                 } else if (!vectorEmpty && (visibleAreaRatio > 0.0f)) {
3117                     for (const auto &point : partitionVector) {
3118                         if (visibleAreaRatio > point) {
3119                             level += 1;
3120                             continue;
3121                         }
3122                         break;
3123                     }
3124                 }
3125             }
3126             auto& savedLevel = std::get<3>(listener.second); // tuple 3, check visible is changed
3127             if (savedLevel != level) {
3128                 RS_LOGD("SurfaceOcclusionCallback surfacenode: %{public}" PRIu64 ".", listener.first);
3129                 savedLevel = level;
3130                 if (isOnTheTree) {
3131                     callbackList.push_back(std::make_pair(std::get<1>(listener.second), visibleAreaRatio));
3132                 }
3133             }
3134         }
3135     }
3136     for (auto &callback : callbackList) {
3137         if (callback.first) {
3138             callback.first->OnSurfaceOcclusionVisibleChanged(callback.second);
3139         }
3140     }
3141 }
3142 
CheckSurfaceOcclusionNeedProcess(NodeId id)3143 bool RSMainThread::CheckSurfaceOcclusionNeedProcess(NodeId id)
3144 {
3145     const auto& nodeMap = context_->GetNodeMap();
3146     if (savedAppWindowNode_.find(id) == savedAppWindowNode_.end()) {
3147         auto node = nodeMap.GetRenderNode(id);
3148         if (!node || !node->IsOnTheTree()) {
3149             RS_LOGD("SurfaceOcclusionCallback cannot find surfacenode %{public}"
3150                 PRIu64 ".", id);
3151             return false;
3152         }
3153         auto appWindowNodeId = node->GetInstanceRootNodeId();
3154         if (appWindowNodeId == INVALID_NODEID) {
3155             RS_LOGD("SurfaceOcclusionCallback surfacenode %{public}"
3156                 PRIu64 " cannot find app window node.", id);
3157             return false;
3158         }
3159         auto surfaceNode = node->ReinterpretCastTo<RSSurfaceRenderNode>();
3160         auto appWindowNode =
3161             RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
3162         if (!surfaceNode || !appWindowNode) {
3163             RS_LOGD("SurfaceOcclusionCallback ReinterpretCastTo fail.");
3164             return false;
3165         }
3166         savedAppWindowNode_[id] = std::make_pair(surfaceNode, appWindowNode);
3167     } else {
3168         if (!savedAppWindowNode_[id].first || !savedAppWindowNode_[id].second) {
3169             return false;
3170         }
3171         auto appWindowNodeId = savedAppWindowNode_[id].first->GetInstanceRootNodeId();
3172         auto lastAppWindowNodeId = savedAppWindowNode_[id].second->GetId();
3173         if (appWindowNodeId != lastAppWindowNodeId && appWindowNodeId != INVALID_NODEID) {
3174             auto appWindowNode =
3175                 RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
3176             if (!appWindowNode) {
3177                 return false;
3178             }
3179             savedAppWindowNode_[id].second = appWindowNode;
3180         }
3181     }
3182     return true;
3183 }
3184 
WaitHardwareThreadTaskExecute()3185 bool RSMainThread::WaitHardwareThreadTaskExecute()
3186 {
3187 #ifdef RS_ENABLE_GPU
3188     std::unique_lock<std::mutex> lock(hardwareThreadTaskMutex_);
3189     return hardwareThreadTaskCond_.wait_until(lock, std::chrono::system_clock::now() +
3190         std::chrono::milliseconds(WAIT_FOR_HARDWARE_THREAD_TASK_TIMEOUT),
3191         []() { return RSHardwareThread::Instance().GetunExecuteTaskNum() <= HARDWARE_THREAD_TASK_NUM; });
3192 #else
3193     return false;
3194 #endif
3195 }
3196 
NotifyHardwareThreadCanExecuteTask()3197 void RSMainThread::NotifyHardwareThreadCanExecuteTask()
3198 {
3199     RS_TRACE_NAME("RSMainThread::NotifyHardwareThreadCanExecuteTask");
3200     std::lock_guard<std::mutex> lock(hardwareThreadTaskMutex_);
3201     hardwareThreadTaskCond_.notify_one();
3202 }
3203 
GetVsyncRefreshRate()3204 uint32_t RSMainThread::GetVsyncRefreshRate()
3205 {
3206     if (vsyncGenerator_ == nullptr) {
3207         RS_LOGE("GetVsyncRefreshRate vsyncGenerator is nullptr");
3208         return 0;
3209     }
3210     return vsyncGenerator_->GetVsyncRefreshRate();
3211 }
3212 
RequestNextVSync(const std::string & fromWhom,int64_t lastVSyncTS,const int64_t & requestVsyncTime)3213 void RSMainThread::RequestNextVSync(const std::string& fromWhom, int64_t lastVSyncTS, const int64_t& requestVsyncTime)
3214 {
3215     RS_OPTIONAL_TRACE_FUNC();
3216     VSyncReceiver::FrameCallback fcb = {
3217         .userData_ = this,
3218         .callbackWithId_ = [this](uint64_t timestamp, uint64_t frameCount, void* data) {
3219                 OnVsync(timestamp, frameCount, data);
3220             },
3221     };
3222     if (receiver_ != nullptr) {
3223         requestNextVsyncNum_++;
3224         if (requestNextVsyncNum_ > REQUEST_VSYNC_NUMBER_LIMIT) {
3225             RS_LOGD("RequestNextVSync too many times:%{public}d", requestNextVsyncNum_.load());
3226             if ((requestNextVsyncNum_ - currentNum_) >= REQUEST_VSYNC_DUMP_NUMBER) {
3227                 RS_LOGW("RequestNextVSync EventHandler is idle: %{public}d", handler_->IsIdle());
3228                 DumpEventHandlerInfo();
3229             }
3230         }
3231         RequestNextVSyncInner(fcb, fromWhom, lastVSyncTS, requestVsyncTime);
3232         if (requestNextVsyncNum_ >= VSYNC_LOG_ENABLED_TIMES_THRESHOLD &&
3233             requestNextVsyncNum_ % VSYNC_LOG_ENABLED_STEP_TIMES == 0) {
3234             vsyncGenerator_->PrintGeneratorStatus();
3235             rsVSyncDistributor_->PrintConnectionsStatus();
3236         }
3237     }
3238 }
3239 
DumpEventHandlerInfo()3240 void RSMainThread::DumpEventHandlerInfo()
3241 {
3242     std::lock_guard<std::mutex> lock(dumpInfoMutex_);
3243     RSEventDumper dumper;
3244     handler_->Dump(dumper);
3245     dumpInfo_ = dumper.GetOutput().c_str();
3246     RS_LOGW("RequestNextVSync HistoryEventQueue is %{public}s", SubHistoryEventQueue(dumpInfo_).c_str());
3247     size_t immediateStart = dumpInfo_.find("Immediate priority event queue infomation:");
3248     if (immediateStart != std::string::npos) {
3249         size_t immediateEnd = dumpInfo_.find("RSEventDumper High priority event", immediateStart);
3250         if (immediateEnd != std::string::npos) {
3251             std::string priorityEventQueue = dumpInfo_.substr(immediateStart, immediateEnd - immediateStart).c_str();
3252             RS_LOGW("RequestNextVSync PriorityEventQueue is %{public}s",
3253                 SubPriorityEventQueue(priorityEventQueue).c_str());
3254         }
3255     }
3256     currentNum_ = requestNextVsyncNum_.load();
3257 }
3258 
SubHistoryEventQueue(std::string input)3259 std::string RSMainThread::SubHistoryEventQueue(std::string input)
3260 {
3261     const int CONTEXT_LINES = 3;
3262     const std::string TARGET_STRING = "completeTime time = ,";
3263     std::vector<std::string> lines;
3264     std::string line;
3265     std::istringstream stream(input);
3266     bool foundTargetStr = false;
3267     while (std::getline(stream, line)) {
3268         lines.push_back(line);
3269     }
3270     std::string result;
3271     for (int i = 0; i < static_cast<int>(lines.size()); ++i) {
3272         if (lines[i].find(TARGET_STRING) != std::string::npos) {
3273             foundTargetStr = true;
3274             int start = std::max(0, i - CONTEXT_LINES);
3275             int end = std::min(static_cast<int>(lines.size() - 1), i + CONTEXT_LINES);
3276             for (int j = start; j < end; ++j) {
3277                 result += lines[j] + "\n";
3278             }
3279             break;
3280         }
3281     }
3282     if (!foundTargetStr) {
3283         RS_LOGW("SubHistoryEventQueue No task is being executed");
3284         // If the TARGET_STRING is not found, dump the information of the first 10 lines.
3285         int end = std::min(static_cast<int>(lines.size() - 1) - 1, 9);
3286         for (int j = 0; j <= end; ++j) {
3287             result += lines[j] + "\n";
3288         }
3289     }
3290     return result;
3291 }
3292 
SubPriorityEventQueue(std::string input)3293 std::string RSMainThread::SubPriorityEventQueue(std::string input)
3294 {
3295     std::string result;
3296     std::string line;
3297     std::istringstream stream(input);
3298 
3299     while (std::getline(stream, line)) {
3300         if (line.find("RSEventDumper No.") != std::string::npos) {
3301             size_t dot_pos = line.find('.');
3302             if (dot_pos != std::string::npos) {
3303                 size_t space_pos = line.find(' ', dot_pos);
3304                 if (space_pos != std::string::npos) {
3305                     std::string num_str = line.substr(dot_pos + 1, space_pos - dot_pos - 1);
3306                     int num = std::stoi(num_str);
3307                     if (num >= 1 && num <= 3) { // dump the first three lines of information.
3308                         result += line + "\n";
3309                     }
3310                 }
3311             }
3312         } else if (line.find("Total size of Immediate Events") != std::string::npos) {
3313             result += line + "\n";
3314         }
3315     }
3316     return result;
3317 }
3318 
ProcessScreenHotPlugEvents()3319 void RSMainThread::ProcessScreenHotPlugEvents()
3320 {
3321     auto screenManager_ = CreateOrGetScreenManager();
3322     if (!screenManager_) {
3323         RS_LOGE("%{public}s screenManager_ is nullptr", __func__);
3324         return;
3325     }
3326 #ifdef RS_ENABLE_GPU
3327     if (!screenManager_->TrySimpleProcessHotPlugEvents()) {
3328         auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
3329         if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
3330             RSHardwareThread::Instance().PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
3331         } else {
3332             PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
3333         }
3334     }
3335 #endif
3336 }
3337 
OnVsync(uint64_t timestamp,uint64_t frameCount,void * data)3338 void RSMainThread::OnVsync(uint64_t timestamp, uint64_t frameCount, void* data)
3339 {
3340     rsVSyncDistributor_->CheckVsyncTsAndReceived(timestamp);
3341     SetFrameInfo(frameCount, false);
3342     const int64_t onVsyncStartTime = GetCurrentSystimeMs();
3343     const int64_t onVsyncStartTimeSteady = GetCurrentSteadyTimeMs();
3344     const float onVsyncStartTimeSteadyFloat = GetCurrentSteadyTimeMsFloat();
3345     RSJankStatsOnVsyncStart(onVsyncStartTime, onVsyncStartTimeSteady, onVsyncStartTimeSteadyFloat);
3346     timestamp_ = timestamp;
3347     vsyncRsTimestamp_.store(timestamp_);
3348     drawingRequestNextVsyncNum_.store(requestNextVsyncNum_);
3349     curTime_ = static_cast<uint64_t>(
3350         std::chrono::duration_cast<std::chrono::nanoseconds>(
3351             std::chrono::steady_clock::now().time_since_epoch()).count());
3352     RS_PROFILER_PATCH_TIME(timestamp_);
3353     RS_PROFILER_PATCH_TIME(curTime_);
3354     requestNextVsyncNum_ = 0;
3355     vsyncId_ = frameCount;
3356     frameCount_++;
3357     if (isUniRender_) {
3358 #ifdef RS_ENABLE_GPU
3359         MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
3360         if (RSUnmarshalThread::Instance().CachedTransactionDataEmpty()) {
3361             // set needWaitUnmarshalFinished_ to false, it means mainLoop do not wait unmarshalBarrierTask_
3362             needWaitUnmarshalFinished_ = false;
3363         } else {
3364             RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_, DVSYNC_NOTIFY_UNMARSHAL_TASK_NAME);
3365         }
3366 #endif
3367     }
3368     mainLoop_();
3369 #if defined(RS_ENABLE_CHIPSET_VSYNC)
3370     SetVsyncInfo(timestamp);
3371 #endif
3372     ProcessScreenHotPlugEvents();
3373     RSJankStatsOnVsyncEnd(onVsyncStartTime, onVsyncStartTimeSteady, onVsyncStartTimeSteadyFloat);
3374 }
3375 
RSJankStatsOnVsyncStart(int64_t onVsyncStartTime,int64_t onVsyncStartTimeSteady,float onVsyncStartTimeSteadyFloat)3376 void RSMainThread::RSJankStatsOnVsyncStart(int64_t onVsyncStartTime, int64_t onVsyncStartTimeSteady,
3377                                            float onVsyncStartTimeSteadyFloat)
3378 {
3379     if (isUniRender_) {
3380 #ifdef RS_ENABLE_GPU
3381         if (!renderThreadParams_) {
3382             // fill the params, and sync to render thread later
3383             renderThreadParams_ = std::make_unique<RSRenderThreadParams>();
3384         }
3385         renderThreadParams_->SetIsUniRenderAndOnVsync(true);
3386         renderThreadParams_->SetOnVsyncStartTime(onVsyncStartTime);
3387         renderThreadParams_->SetOnVsyncStartTimeSteady(onVsyncStartTimeSteady);
3388         renderThreadParams_->SetOnVsyncStartTimeSteadyFloat(onVsyncStartTimeSteadyFloat);
3389         SetSkipJankAnimatorFrame(false);
3390         isImplicitAnimationEnd_ = false;
3391 #endif
3392     }
3393 }
3394 
AddSelfDrawingNodes(std::shared_ptr<RSSurfaceRenderNode> selfDrawingNode)3395 void RSMainThread::AddSelfDrawingNodes(std::shared_ptr<RSSurfaceRenderNode> selfDrawingNode)
3396 {
3397     selfDrawingNodes_.emplace_back(selfDrawingNode);
3398 }
3399 
GetSelfDrawingNodes() const3400 const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& RSMainThread::GetSelfDrawingNodes() const
3401 {
3402     return selfDrawingNodes_;
3403 }
3404 
ClearSelfDrawingNodes()3405 void RSMainThread::ClearSelfDrawingNodes()
3406 {
3407     selfDrawingNodes_.clear();
3408 }
3409 
RSJankStatsOnVsyncEnd(int64_t onVsyncStartTime,int64_t onVsyncStartTimeSteady,float onVsyncStartTimeSteadyFloat)3410 void RSMainThread::RSJankStatsOnVsyncEnd(int64_t onVsyncStartTime, int64_t onVsyncStartTimeSteady,
3411                                          float onVsyncStartTimeSteadyFloat)
3412 {
3413 #ifdef RS_ENABLE_GPU
3414     if (isUniRender_ && !needPostAndWait_) {
3415         const JankDurationParams rsParams = { .timeStart_ = onVsyncStartTime,
3416                                               .timeStartSteady_ = onVsyncStartTimeSteady,
3417                                               .timeStartSteadyFloat_ = onVsyncStartTimeSteadyFloat,
3418                                               .timeEnd_ = GetCurrentSystimeMs(),
3419                                               .timeEndSteady_ = GetCurrentSteadyTimeMs(),
3420                                               .timeEndSteadyFloat_ = GetCurrentSteadyTimeMsFloat(),
3421                                               .refreshRate_ = GetDynamicRefreshRate(),
3422                                               .discardJankFrames_ = GetDiscardJankFrames(),
3423                                               .skipJankAnimatorFrame_ = GetSkipJankAnimatorFrame(),
3424                                               .implicitAnimationEnd_ = isImplicitAnimationEnd_ };
3425         // optimize jank load when 1) global optimization flag is true, 2) at least two consecutive frames do direct
3426         // composition, 3) refresh rate of current frame does not overstep a preset threshold
3427         bool optimizeLoad = RSSystemProperties::GetJankLoadOptimizeEnabled() && !isLastFrameNeedPostAndWait_ &&
3428             rsParams.refreshRate_ <= MAX_REFRESH_RATE_TO_OPTIMIZE_JANK_LOAD;
3429         drawFrame_.PostDirectCompositionJankStats(rsParams, optimizeLoad);
3430     }
3431     if (isUniRender_) {
3432         SetDiscardJankFrames(false);
3433     }
3434 #endif
3435 }
3436 
3437 #if defined(RS_ENABLE_CHIPSET_VSYNC)
ConnectChipsetVsyncSer()3438 void RSMainThread::ConnectChipsetVsyncSer()
3439 {
3440     if (initVsyncServiceFlag_ && (RsChipsetVsync::Instance().InitChipsetVsync() == -1)) {
3441         initVsyncServiceFlag_ = true;
3442     } else {
3443         initVsyncServiceFlag_ = false;
3444     }
3445 }
3446 #endif
3447 
3448 #if defined(RS_ENABLE_CHIPSET_VSYNC)
SetVsyncInfo(uint64_t timestamp)3449 void RSMainThread::SetVsyncInfo(uint64_t timestamp)
3450 {
3451     int64_t vsyncPeriod = 0;
3452     bool allowFramerateChange = false;
3453     if (receiver_) {
3454         receiver_->GetVSyncPeriod(vsyncPeriod);
3455     }
3456     if (context_) {
3457         // framerate not vote at animation and mult-window scenario
3458         allowFramerateChange = context_->GetAnimatingNodeList().empty() &&
3459             context_->GetNodeMap().GetVisibleLeashWindowCount() < MULTI_WINDOW_PERF_START_NUM;
3460     }
3461     RsChipsetVsync::Instance().SetVsync(timestamp, curTime_, vsyncPeriod, allowFramerateChange);
3462     RS_LOGD("UpdateVsyncTime = %{public}lld, curTime_ = %{public}lld, "
3463         "period = %{public}lld, allowFramerateChange = %{public}d",
3464         static_cast<long long>(timestamp), static_cast<long long>(curTime_),
3465         static_cast<long long>(vsyncPeriod), allowFramerateChange);
3466 }
3467 #endif
3468 
Animate(uint64_t timestamp)3469 void RSMainThread::Animate(uint64_t timestamp)
3470 {
3471     RS_TRACE_FUNC();
3472     lastAnimateTimestamp_ = timestamp;
3473     hgmContext_.GetRSCurrRangeRef().Reset();
3474     if (context_->animatingNodeList_.empty()) {
3475         doWindowAnimate_ = false;
3476         context_->SetRequestedNextVsyncAnimate(false);
3477         return;
3478     }
3479     UpdateAnimateNodeFlag();
3480     bool curWinAnim = false;
3481     bool needRequestNextVsync = false;
3482     // isCalculateAnimationValue is embedded modify for stat animate frame drop
3483     bool isCalculateAnimationValue = false;
3484     bool isRateDeciderEnabled = (context_->animatingNodeList_.size() <= CAL_NODE_PREFERRED_FPS_LIMIT);
3485     bool isDisplaySyncEnabled = true;
3486     int64_t period = 0;
3487     int64_t minLeftDelayTime = RSSystemProperties::GetAnimationDelayOptimizeEnabled() ? INT64_MAX : 0;
3488     if (receiver_) {
3489         receiver_->GetVSyncPeriod(period);
3490     }
3491     RSRenderAnimation::isCalcAnimateVelocity_ = isRateDeciderEnabled;
3492     uint32_t totalAnimationSize = 0;
3493     uint32_t animatingNodeSize = context_->animatingNodeList_.size();
3494     bool needPrintAnimationDFX = IsTagEnabled(HITRACE_TAG_GRAPHIC_AGP) ? true : false;
3495     std::set<pid_t> animationPids;
3496     // iterate and animate all animating nodes, remove if animation finished
3497     EraseIf(context_->animatingNodeList_,
3498         [this, timestamp, period, isDisplaySyncEnabled, isRateDeciderEnabled, &totalAnimationSize,
3499         &curWinAnim, &needRequestNextVsync, &isCalculateAnimationValue, &needPrintAnimationDFX, &minLeftDelayTime,
3500         &animationPids](const auto& iter) -> bool {
3501         auto node = iter.second.lock();
3502         if (node == nullptr) {
3503             RS_LOGD("Animate removing expired animating node");
3504             return true;
3505         }
3506         if (cacheCmdSkippedInfo_.count(ExtractPid(node->GetId())) > 0) {
3507             hgmContext_.GetRSCurrRangeRef().Merge(node->animationManager_.GetDecideFrameRateRange());
3508             RS_LOGD("Animate skip the cached node");
3509             return false;
3510         }
3511         totalAnimationSize += node->animationManager_.GetAnimationsSize();
3512         node->animationManager_.SetRateDeciderEnable(
3513             isRateDeciderEnabled, hgmContext_.FrameRateGetFunc);
3514         auto [hasRunningAnimation, nodeNeedRequestNextVsync, nodeCalculateAnimationValue] =
3515             node->Animate(timestamp, minLeftDelayTime, period, isDisplaySyncEnabled);
3516         if (!hasRunningAnimation) {
3517             node->InActivateDisplaySync();
3518             RS_LOGD("Animate removing finished animating node %{public}" PRIu64, node->GetId());
3519         } else {
3520             node->UpdateDisplaySyncRange();
3521             hgmContext_.GetRSCurrRangeRef().Merge(node->animationManager_.GetDecideFrameRateRange());
3522         }
3523         // request vsync if: 1. node has running animation, or 2. transition animation just ended
3524         needRequestNextVsync = needRequestNextVsync || nodeNeedRequestNextVsync || (node.use_count() == 1);
3525         isCalculateAnimationValue = isCalculateAnimationValue || nodeCalculateAnimationValue;
3526         if (node->template IsInstanceOf<RSSurfaceRenderNode>() && hasRunningAnimation) {
3527             if (isUniRender_) {
3528 #ifdef RS_ENABLE_GPU
3529                 auto surfacenode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
3530                 surfacenode->SetAnimateState();
3531 #endif
3532             }
3533             curWinAnim = true;
3534         }
3535         if (needPrintAnimationDFX && needRequestNextVsync && node->animationManager_.GetAnimationsSize() > 0) {
3536             animationPids.insert(node->animationManager_.GetAnimationPid());
3537         }
3538         return !hasRunningAnimation;
3539     });
3540     if (needPrintAnimationDFX && needRequestNextVsync && animationPids.size() > 0) {
3541         std::string pidList;
3542         for (const auto& pid : animationPids) {
3543             pidList += "[" + std::to_string(pid) + "]";
3544         }
3545         RS_TRACE_NAME_FMT("Animate from pid %s", pidList.c_str());
3546     }
3547 
3548     RS_TRACE_NAME_FMT("Animate [nodeSize, totalAnimationSize] is [%lu, %lu]", animatingNodeSize, totalAnimationSize);
3549     if (!isCalculateAnimationValue && needRequestNextVsync) {
3550         RS_TRACE_NAME("Animation running empty");
3551     }
3552 
3553     doWindowAnimate_ = curWinAnim;
3554     RS_LOGD("Animate end, animating nodes remains, has window animation: %{public}d", curWinAnim);
3555 
3556     if (needRequestNextVsync) {
3557         HgmEnergyConsumptionPolicy::Instance().StatisticAnimationTime(timestamp / NS_PER_MS);
3558         // greater than one frame time (16.6 ms)
3559         constexpr int64_t oneFrameTimeInFPS60 = 17;
3560         // maximum delay time 60000 milliseconds, which is equivalent to 60 seconds.
3561         constexpr int64_t delayTimeMax = 60000;
3562         if (minLeftDelayTime > oneFrameTimeInFPS60) {
3563             minLeftDelayTime = std::min(minLeftDelayTime, delayTimeMax);
3564             auto RequestNextVSyncTask = [this]() {
3565                 RS_TRACE_NAME("Animate with delay RequestNextVSync");
3566                 RequestNextVSync("animate", timestamp_);
3567             };
3568             RS_TRACE_NAME_FMT("Animate minLeftDelayTime: %ld", minLeftDelayTime);
3569             PostTask(RequestNextVSyncTask, "animate_request_next_vsync", minLeftDelayTime - oneFrameTimeInFPS60,
3570                 AppExecFwk::EventQueue::Priority::IMMEDIATE);
3571         } else {
3572             RequestNextVSync("animate", timestamp_);
3573         }
3574     } else if (isUniRender_) {
3575 #ifdef RS_ENABLE_GPU
3576         isImplicitAnimationEnd_ = true;
3577         renderThreadParams_->SetImplicitAnimationEnd(true);
3578 #endif
3579     }
3580     context_->SetRequestedNextVsyncAnimate(needRequestNextVsync);
3581 
3582     PerfAfterAnim(needRequestNextVsync);
3583     UpdateDirectCompositionByAnimate(needRequestNextVsync);
3584 }
3585 
UpdateDirectCompositionByAnimate(bool animateNeedRequestNextVsync)3586 void RSMainThread::UpdateDirectCompositionByAnimate(bool animateNeedRequestNextVsync)
3587 {
3588     // if the animation is running or it's on the last frame of the animation, then change the doDirectComposition_ flag
3589     // to false.
3590     if (animateNeedRequestNextVsync || (!animateNeedRequestNextVsync && lastAnimateNeedRequestNextVsync_)) {
3591         doDirectComposition_ = false;
3592         RS_OPTIONAL_TRACE_NAME("hwc debug: disable directComposition by animate");
3593     }
3594     lastAnimateNeedRequestNextVsync_ = animateNeedRequestNextVsync;
3595 }
3596 
IsNeedProcessBySingleFrameComposer(std::unique_ptr<RSTransactionData> & rsTransactionData)3597 bool RSMainThread::IsNeedProcessBySingleFrameComposer(std::unique_ptr<RSTransactionData>& rsTransactionData)
3598 {
3599     if (!isUniRender_ || !rsTransactionData) {
3600         return false;
3601     }
3602 
3603     if (!RSSingleFrameComposer::IsShouldProcessByIpcThread(rsTransactionData->GetSendingPid()) &&
3604         !RSSystemProperties::GetSingleFrameComposerEnabled()) {
3605         return false;
3606     }
3607 
3608     return true;
3609 }
3610 
ProcessDataBySingleFrameComposer(std::unique_ptr<RSTransactionData> & rsTransactionData)3611 void RSMainThread::ProcessDataBySingleFrameComposer(std::unique_ptr<RSTransactionData>& rsTransactionData)
3612 {
3613     if (!rsTransactionData || !isUniRender_) {
3614         return;
3615     }
3616 
3617     if (RSSystemProperties::GetSingleFrameComposerEnabled()) {
3618         RSSingleFrameComposer::SetSingleFrameFlag(std::this_thread::get_id());
3619         context_->transactionTimestamp_ = rsTransactionData->GetTimestamp();
3620         rsTransactionData->ProcessBySingleFrameComposer(*context_);
3621     }
3622 
3623     {
3624         std::lock_guard<std::mutex> lock(transitionDataMutex_);
3625         RSTransactionMetricCollector::GetInstance().Collect(rsTransactionData);
3626         cachedTransactionDataMap_[rsTransactionData->GetSendingPid()].emplace_back(std::move(rsTransactionData));
3627     }
3628     PostTask([this]() {
3629         if (!context_) {
3630             return;
3631         }
3632         // animation node will call RequestNextVsync() in mainLoop_, here we simply ignore animation scenario
3633         // and also ignore mult-window scenario
3634         bool isNeedSingleFrameCompose = context_->GetAnimatingNodeList().empty() &&
3635             context_->GetNodeMap().GetVisibleLeashWindowCount() < MULTI_WINDOW_PERF_START_NUM;
3636         if (isNeedSingleFrameCompose) {
3637             ForceRefreshForUni();
3638         } else {
3639             RequestNextVSync();
3640         }
3641     });
3642 }
3643 
RecvRSTransactionData(std::unique_ptr<RSTransactionData> & rsTransactionData)3644 void RSMainThread::RecvRSTransactionData(std::unique_ptr<RSTransactionData>& rsTransactionData)
3645 {
3646     if (!rsTransactionData) {
3647         return;
3648     }
3649     int64_t timestamp = static_cast<int64_t>(rsTransactionData->GetTimestamp());
3650     if (isUniRender_) {
3651 #ifdef RS_ENABLE_GPU
3652         std::lock_guard<std::mutex> lock(transitionDataMutex_);
3653         RSTransactionMetricCollector::GetInstance().Collect(rsTransactionData);
3654         cachedTransactionDataMap_[rsTransactionData->GetSendingPid()].emplace_back(std::move(rsTransactionData));
3655 #endif
3656     } else {
3657         RSMainThread::Instance()->PostTask([this, transactionData = std::shared_ptr(std::move(rsTransactionData))]() {
3658             if (!RSMainThread::Instance() || !(transactionData)) {
3659                 return;
3660             }
3661             RSMainThread::Instance()->ClassifyRSTransactionData(transactionData);
3662         });
3663     }
3664     RequestNextVSync("UI", timestamp);
3665 }
3666 
ClassifyRSTransactionData(std::shared_ptr<RSTransactionData> rsTransactionData)3667 void RSMainThread::ClassifyRSTransactionData(std::shared_ptr<RSTransactionData> rsTransactionData)
3668 {
3669     const auto& nodeMap = context_->GetNodeMap();
3670     std::lock_guard<std::mutex> lock(transitionDataMutex_);
3671     auto timestamp = rsTransactionData->GetTimestamp();
3672     RS_LOGD("RecvRSTransactionData timestamp = %{public}" PRIu64, timestamp);
3673     for (auto& [nodeId, followType, command] : rsTransactionData->GetPayload()) {
3674         if (nodeId == 0 || followType == FollowType::NONE) {
3675             pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
3676             continue;
3677         }
3678         auto node = nodeMap.GetRenderNode(nodeId);
3679         if (node && followType == FollowType::FOLLOW_TO_PARENT) {
3680             auto parentNode = node->GetParent().lock();
3681             if (parentNode) {
3682                 nodeId = parentNode->GetId();
3683             } else {
3684                 pendingEffectiveCommands_[timestamp].emplace_back(std::move(command));
3685                 continue;
3686             }
3687         }
3688         cachedCommands_[nodeId][timestamp].emplace_back(std::move(command));
3689     }
3690 }
3691 
PostTask(RSTaskMessage::RSTask task)3692 void RSMainThread::PostTask(RSTaskMessage::RSTask task)
3693 {
3694     if (handler_) {
3695         handler_->PostTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
3696     }
3697 }
3698 
PostTask(RSTaskMessage::RSTask task,const std::string & name,int64_t delayTime,AppExecFwk::EventQueue::Priority priority)3699 void RSMainThread::PostTask(RSTaskMessage::RSTask task, const std::string& name, int64_t delayTime,
3700     AppExecFwk::EventQueue::Priority priority)
3701 {
3702     if (handler_) {
3703         handler_->PostTask(task, name, delayTime, priority);
3704     }
3705 }
3706 
RemoveTask(const std::string & name)3707 void RSMainThread::RemoveTask(const std::string& name)
3708 {
3709     if (handler_) {
3710         handler_->RemoveTask(name);
3711     }
3712 }
3713 
PostSyncTask(RSTaskMessage::RSTask task)3714 void RSMainThread::PostSyncTask(RSTaskMessage::RSTask task)
3715 {
3716     if (handler_) {
3717         handler_->PostSyncTask(task, AppExecFwk::EventQueue::Priority::IMMEDIATE);
3718     }
3719 }
3720 
IsIdle() const3721 bool RSMainThread::IsIdle() const
3722 {
3723     return handler_ ? handler_->IsIdle() : false;
3724 }
3725 
RegisterApplicationAgent(uint32_t pid,sptr<IApplicationAgent> app)3726 void RSMainThread::RegisterApplicationAgent(uint32_t pid, sptr<IApplicationAgent> app)
3727 {
3728     applicationAgentMap_.insert_or_assign(pid, app);
3729 }
3730 
UnRegisterApplicationAgent(sptr<IApplicationAgent> app)3731 void RSMainThread::UnRegisterApplicationAgent(sptr<IApplicationAgent> app)
3732 {
3733     RSReclaimMemoryManager::Instance().TriggerReclaimTask();
3734 
3735     EraseIf(applicationAgentMap_,
3736         [&app](const auto& iter) { return iter.second && app && iter.second->AsObject() == app->AsObject(); });
3737 }
3738 
RegisterOcclusionChangeCallback(pid_t pid,sptr<RSIOcclusionChangeCallback> callback)3739 void RSMainThread::RegisterOcclusionChangeCallback(pid_t pid, sptr<RSIOcclusionChangeCallback> callback)
3740 {
3741     std::lock_guard<std::mutex> lock(occlusionMutex_);
3742     occlusionListeners_[pid] = callback;
3743 }
3744 
UnRegisterOcclusionChangeCallback(pid_t pid)3745 void RSMainThread::UnRegisterOcclusionChangeCallback(pid_t pid)
3746 {
3747     std::lock_guard<std::mutex> lock(occlusionMutex_);
3748     occlusionListeners_.erase(pid);
3749 }
3750 
RegisterSurfaceOcclusionChangeCallback(NodeId id,pid_t pid,sptr<RSISurfaceOcclusionChangeCallback> callback,std::vector<float> & partitionPoints)3751 void RSMainThread::RegisterSurfaceOcclusionChangeCallback(
3752     NodeId id, pid_t pid, sptr<RSISurfaceOcclusionChangeCallback> callback, std::vector<float>& partitionPoints)
3753 {
3754     std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
3755     uint8_t level = 1;
3756     if (!partitionPoints.empty()) {
3757         level = partitionPoints.size();
3758     }
3759     auto it = surfaceOcclusionListeners_.find(id);
3760     if (it != surfaceOcclusionListeners_.end()) {
3761         it->second = std::make_tuple(pid, callback, partitionPoints, level);
3762     } else if (surfaceOcclusionListeners_.size() < MAX_SURFACE_OCCLUSION_LISTENERS_SIZE) {
3763         surfaceOcclusionListeners_.emplace(id, std::make_tuple(pid, callback, partitionPoints, level));
3764     } else {
3765         RS_LOGW("%{public}s: register failed because surfaceOcclusionListeners_ reached max size", __func__);
3766     }
3767 }
3768 
UnRegisterSurfaceOcclusionChangeCallback(NodeId id)3769 void RSMainThread::UnRegisterSurfaceOcclusionChangeCallback(NodeId id)
3770 {
3771     std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
3772     surfaceOcclusionListeners_.erase(id);
3773     savedAppWindowNode_.erase(id);
3774 }
3775 
ClearSurfaceOcclusionChangeCallback(pid_t pid)3776 void RSMainThread::ClearSurfaceOcclusionChangeCallback(pid_t pid)
3777 {
3778     std::lock_guard<std::mutex> lock(surfaceOcclusionMutex_);
3779     for (auto it = surfaceOcclusionListeners_.begin(); it != surfaceOcclusionListeners_.end();) {
3780         if (std::get<0>(it->second) == pid) {
3781             if (savedAppWindowNode_.find(it->first) != savedAppWindowNode_.end()) {
3782                 savedAppWindowNode_.erase(it->first);
3783             }
3784             surfaceOcclusionListeners_.erase(it++);
3785         } else {
3786             it++;
3787         }
3788     }
3789 }
3790 
SurfaceOcclusionChangeCallback(VisibleData & dstCurVisVec)3791 void RSMainThread::SurfaceOcclusionChangeCallback(VisibleData& dstCurVisVec)
3792 {
3793     std::lock_guard<std::mutex> lock(occlusionMutex_);
3794     for (auto it = occlusionListeners_.begin(); it != occlusionListeners_.end(); it++) {
3795         if (it->second) {
3796             it->second->OnOcclusionVisibleChanged(std::make_shared<RSOcclusionData>(dstCurVisVec));
3797         }
3798     }
3799 }
3800 
SurfaceOcclusionCallBackIfOnTreeStateChanged()3801 bool RSMainThread::SurfaceOcclusionCallBackIfOnTreeStateChanged()
3802 {
3803     std::vector<NodeId> registeredSurfaceOnTree;
3804     for (auto it = savedAppWindowNode_.begin(); it != savedAppWindowNode_.end(); ++it) {
3805         if (it->second.first->IsOnTheTree()) {
3806             registeredSurfaceOnTree.push_back(it->first);
3807         }
3808     }
3809     if (lastRegisteredSurfaceOnTree_ != registeredSurfaceOnTree) {
3810         lastRegisteredSurfaceOnTree_ = registeredSurfaceOnTree;
3811         return true;
3812     }
3813     return false;
3814 }
3815 
SendCommands()3816 void RSMainThread::SendCommands()
3817 {
3818     RS_OPTIONAL_TRACE_FUNC();
3819     RsFrameReport::GetInstance().SendCommandsStart();
3820     if (!context_->needSyncFinishAnimationList_.empty()) {
3821         for (const auto& [nodeId, animationId, token] : context_->needSyncFinishAnimationList_) {
3822             RS_LOGI("SendCommands sync finish animation node is %{public}" PRIu64 ","
3823                 " animation is %{public}" PRIu64, nodeId, animationId);
3824             std::unique_ptr<RSCommand> command =
3825                 std::make_unique<RSAnimationCallback>(nodeId, animationId, token, FINISHED);
3826             RSMessageProcessor::Instance().AddUIMessage(ExtractPid(animationId), std::move(command));
3827         }
3828         context_->needSyncFinishAnimationList_.clear();
3829     }
3830     if (!RSMessageProcessor::Instance().HasTransaction()) {
3831         return;
3832     }
3833 
3834     // dispatch messages to corresponding application
3835     auto transactionMapPtr = std::make_shared<std::unordered_map<uint32_t, std::shared_ptr<RSTransactionData>>>(
3836         RSMessageProcessor::Instance().GetAllTransactions());
3837     PostTask([this, transactionMapPtr]() {
3838         std::string dfxString;
3839         for (const auto& transactionIter : *transactionMapPtr) {
3840             auto pid = transactionIter.first;
3841             auto appIter = applicationAgentMap_.find(pid);
3842             if (appIter == applicationAgentMap_.end()) {
3843                 RS_LOGW("SendCommand no application agent registered as pid %{public}d,"
3844                     "this will cause memory leak!", pid);
3845                 continue;
3846             }
3847             auto& app = appIter->second;
3848             auto transactionPtr = transactionIter.second;
3849             if (transactionPtr != nullptr) {
3850                 dfxString += "[pid:" + std::to_string(pid) + ",index:" + std::to_string(transactionPtr->GetIndex())
3851                     + ",cnt:" + std::to_string(transactionPtr->GetCommandCount()) + "]";
3852             }
3853             app->OnTransaction(transactionPtr);
3854         }
3855         RS_LOGD("RS send to %{public}s", dfxString.c_str());
3856         RS_TRACE_NAME_FMT("RSMainThread::SendCommand to %s", dfxString.c_str());
3857     });
3858 }
3859 
TransactionDataMapDump(const TransactionDataMap & transactionDataMap,std::string & dumpString)3860 void RSMainThread::TransactionDataMapDump(const TransactionDataMap& transactionDataMap, std::string& dumpString)
3861 {
3862     for (const auto& [pid, transactionData] : transactionDataMap) {
3863         dumpString.append("[pid: " + std::to_string(pid));
3864         for (const auto& transcation : transactionData) {
3865             dumpString.append(", [index: " + std::to_string(transcation->GetIndex()));
3866             transcation->DumpCommand(dumpString);
3867             dumpString.append("]");
3868         }
3869         dumpString.append("]");
3870     }
3871 }
3872 
RenderServiceTreeDump(std::string & dumpString,bool forceDumpSingleFrame,bool needUpdateJankStats)3873 void RSMainThread::RenderServiceTreeDump(std::string& dumpString, bool forceDumpSingleFrame, bool needUpdateJankStats)
3874 {
3875     if (LIKELY(forceDumpSingleFrame)) {
3876         int64_t onVsyncStartTime = 0;
3877         int64_t onVsyncStartTimeSteady = 0;
3878         float onVsyncStartTimeSteadyFloat = 0.0f;
3879         if (needUpdateJankStats) {
3880             onVsyncStartTime = GetCurrentSystimeMs();
3881             onVsyncStartTimeSteady = GetCurrentSteadyTimeMs();
3882             onVsyncStartTimeSteadyFloat = GetCurrentSteadyTimeMsFloat();
3883             RSJankStatsOnVsyncStart(onVsyncStartTime, onVsyncStartTimeSteady, onVsyncStartTimeSteadyFloat);
3884         }
3885         RS_TRACE_NAME("GetDumpTree");
3886         dumpString.append("-- RS transactionFlags: " + transactionFlags_ + "\n");
3887         dumpString.append("-- current timeStamp: " + std::to_string(timestamp_) + "\n");
3888         dumpString.append("-- vsyncId: " + std::to_string(vsyncId_) + "\n");
3889         dumpString.append("Animating Node: [");
3890         for (auto& [nodeId, _]: context_->animatingNodeList_) {
3891             dumpString.append(std::to_string(nodeId) + ", ");
3892         }
3893         dumpString.append("];\n");
3894         dumpString.append("-- CacheTransactionData: ");
3895         {
3896             std::lock_guard<std::mutex> lock(transitionDataMutex_);
3897             TransactionDataMapDump(cachedTransactionDataMap_, dumpString);
3898         }
3899         dumpString.append("\n");
3900         const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
3901         if (rootNode == nullptr) {
3902             dumpString.append("rootNode is null\n");
3903             return;
3904         }
3905         rootNode->DumpTree(0, dumpString);
3906 
3907         dumpString += "\n-- RenderServiceUniThread\n";
3908         RSUniRenderThread::Instance().RenderServiceTreeDump(dumpString);
3909 
3910         if (needUpdateJankStats) {
3911             isLastFrameNeedPostAndWait_ = needPostAndWait_;
3912             needPostAndWait_ = false;
3913             RSJankStatsOnVsyncEnd(onVsyncStartTime, onVsyncStartTimeSteady, onVsyncStartTimeSteadyFloat);
3914         }
3915     } else {
3916         dumpString += g_dumpStr;
3917         g_dumpStr = "";
3918     }
3919 }
3920 
Data2String(std::string data,uint32_t tagetNumber)3921 static std::string Data2String(std::string data, uint32_t tagetNumber)
3922 {
3923     if (data.length() < tagetNumber) {
3924         return std::string(tagetNumber - data.length(), ' ') + data;
3925     } else {
3926         return data;
3927     }
3928 }
3929 
RenderServiceAllNodeDump(DfxString & log)3930 void RSMainThread::RenderServiceAllNodeDump(DfxString& log)
3931 {
3932     std::unordered_map<int, std::pair<int, int>> node_info; // [pid, [count, ontreecount]]
3933     std::unordered_map<int, int> nullnode_info; // [pid, count]
3934     for (auto& [nodeId, info] : MemoryTrack::Instance().GetMemNodeMap()) {
3935         auto node = context_->GetMutableNodeMap().GetRenderNode(nodeId);
3936         int pid = info.pid;
3937         if (node) {
3938             if (node_info.count(pid)) {
3939                 node_info[pid].first++;
3940                 node_info[pid].second += node->IsOnTheTree() ? 1 : 0;
3941             } else {
3942                 node_info[pid].first = 1;
3943                 node_info[pid].second = node->IsOnTheTree() ? 1 : 0;
3944             }
3945         } else {
3946             if (nullnode_info.count(pid)) {
3947                 nullnode_info[pid]++;
3948             } else {
3949                 nullnode_info[pid] = 1;
3950             }
3951         }
3952     }
3953     std::string log_str = Data2String("Pid", NODE_DUMP_STRING_LEN) + "\t" +
3954         Data2String("Count", NODE_DUMP_STRING_LEN) + "\t" +
3955         Data2String("OnTree", NODE_DUMP_STRING_LEN);
3956     log.AppendFormat("%s\n", log_str.c_str());
3957     for (auto& [pid, info]: node_info) {
3958         log_str = Data2String(std::to_string(pid), NODE_DUMP_STRING_LEN) + "\t" +
3959             Data2String(std::to_string(info.first), NODE_DUMP_STRING_LEN) + "\t" +
3960             Data2String(std::to_string(info.second), NODE_DUMP_STRING_LEN);
3961         log.AppendFormat("%s\n", log_str.c_str());
3962     }
3963     if (!nullnode_info.empty()) {
3964         log_str = "Purgeable node: \n" +
3965             Data2String("Pid", NODE_DUMP_STRING_LEN) + "\t" +
3966             Data2String("Count", NODE_DUMP_STRING_LEN);
3967         log.AppendFormat("%s\n", log_str.c_str());
3968         for (auto& [pid, info]: nullnode_info) {
3969             log_str = Data2String(std::to_string(pid), NODE_DUMP_STRING_LEN) + "\t" +
3970                 Data2String(std::to_string(info), NODE_DUMP_STRING_LEN);
3971             log.AppendFormat("%s\n", log_str.c_str());
3972         }
3973     }
3974     node_info.clear();
3975     nullnode_info.clear();
3976 }
3977 
RenderServiceAllSurafceDump(DfxString & log)3978 void RSMainThread::RenderServiceAllSurafceDump(DfxString& log)
3979 {
3980     log.AppendFormat("%s\n", "the memory of size of all surfaces buffer: ");
3981     const auto& nodeMap = context_->GetNodeMap();
3982     nodeMap.TraversalNodes([&log](const std::shared_ptr<RSBaseRenderNode>& node) {
3983         if (node == nullptr || !node->IsInstanceOf<RSSurfaceRenderNode>()) {
3984             return;
3985         }
3986         const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
3987         const auto& surfaceConsumer = surfaceNode->GetRSSurfaceHandler()->GetConsumer();
3988         if (surfaceConsumer == nullptr) {
3989             return;
3990         }
3991         std::string dumpSurfaceInfo;
3992         surfaceConsumer->Dump(dumpSurfaceInfo);
3993         if (dumpSurfaceInfo.find("sequence") == std::string::npos) {
3994             return;
3995         }
3996         log.AppendFormat("pid = %d nodeId:%llu", ExtractPid(node->GetId()), node->GetId());
3997         log.AppendFormat("%s\n", dumpSurfaceInfo.c_str());
3998     });
3999 }
4000 
SendClientDumpNodeTreeCommands(uint32_t taskId)4001 void RSMainThread::SendClientDumpNodeTreeCommands(uint32_t taskId)
4002 {
4003     RS_TRACE_NAME_FMT("DumpClientNodeTree start task[%u]", taskId);
4004     std::unique_lock<std::mutex> lock(nodeTreeDumpMutex_);
4005     if (nodeTreeDumpTasks_.find(taskId) != nodeTreeDumpTasks_.end()) {
4006         RS_LOGW("SendClientDumpNodeTreeCommands task[%{public}u] duplicate", taskId);
4007         return;
4008     }
4009 
4010     std::unordered_map<pid_t, std::vector<std::pair<NodeId, uint64_t>>> topNodes;
4011     if (const auto& rootNode = context_->GetGlobalRootRenderNode()) {
4012         for (const auto& screenNode : *rootNode->GetSortedChildren()) {
4013             for (const auto& node : *screenNode->GetSortedChildren()) {
4014                 NodeId id = node->GetId();
4015                 const auto& tokenList = node->GetUIContextTokenList();
4016                 if (tokenList.empty()) {
4017                     topNodes[ExtractPid(id)].emplace_back(id, node->GetUIContextToken());
4018                 } else {
4019                     for (const auto& token : tokenList) {
4020                         topNodes[ExtractPid(id)].emplace_back(id, token);
4021                     }
4022                 }
4023             }
4024         }
4025     }
4026     context_->GetNodeMap().TraversalNodes([this, &topNodes](const std::shared_ptr<RSBaseRenderNode>& node) {
4027         if (node->IsOnTheTree() && node->GetType() == RSRenderNodeType::ROOT_NODE) {
4028             if (auto parent = node->GetParent().lock()) {
4029                 NodeId id = parent->GetId();
4030                 const auto& tokenList = parent->GetUIContextTokenList();
4031                 if (tokenList.empty()) {
4032                     topNodes[ExtractPid(id)].emplace_back(id, parent->GetUIContextToken());
4033                 } else {
4034                     for (const auto& token : tokenList) {
4035                         topNodes[ExtractPid(id)].emplace_back(id, token);
4036                     }
4037                 }
4038             }
4039             NodeId id = node->GetId();
4040             const auto& tokenList = node->GetUIContextTokenList();
4041             if (tokenList.empty()) {
4042                 topNodes[ExtractPid(id)].emplace_back(id, node->GetUIContextToken());
4043             } else {
4044                 for (const auto& token : tokenList) {
4045                     topNodes[ExtractPid(id)].emplace_back(id, token);
4046                 }
4047             }
4048         }
4049     });
4050 
4051     auto& task = nodeTreeDumpTasks_[taskId];
4052     for (const auto& [pid, nodeInfoList] : topNodes) {
4053         auto iter = applicationAgentMap_.find(pid);
4054         if (iter == applicationAgentMap_.end() || !iter->second) {
4055             continue;
4056         }
4057         auto transactionData = std::make_shared<RSTransactionData>();
4058         for (const auto& [nodeId, token] : nodeInfoList) {
4059             auto command = std::make_unique<RSDumpClientNodeTree>(nodeId, pid, token, taskId);
4060             transactionData->AddCommand(std::move(command), nodeId, FollowType::NONE);
4061             task.count++;
4062             RS_TRACE_NAME_FMT(
4063                 "DumpClientNodeTree add task[%u] pid[%u] node[%" PRIu64 "] token[%lu]", taskId, pid, nodeId, token);
4064             RS_LOGI("SendClientDumpNodeTreeCommands add task[%{public}u] pid[%{public}u] node[%{public}" PRIu64
4065                     "] token[%{public}" PRIu64 "]",
4066                 taskId, pid, nodeId, token);
4067         }
4068         iter->second->OnTransaction(transactionData);
4069     }
4070     RS_LOGI("SendClientDumpNodeTreeCommands send task[%{public}u] count[%{public}zu]",
4071         taskId, task.count);
4072 }
4073 
CollectClientNodeTreeResult(uint32_t taskId,std::string & dumpString,size_t timeout)4074 void RSMainThread::CollectClientNodeTreeResult(uint32_t taskId, std::string& dumpString, size_t timeout)
4075 {
4076     std::unique_lock<std::mutex> lock(nodeTreeDumpMutex_);
4077     {
4078         RS_TRACE_NAME_FMT("DumpClientNodeTree wait task[%u]", taskId);
4079         nodeTreeDumpCondVar_.wait_for(lock, std::chrono::milliseconds(timeout), [this, taskId] () {
4080             const auto& task = nodeTreeDumpTasks_[taskId];
4081             return task.completionCount == task.count;
4082         });
4083     }
4084 
4085     const auto& task = nodeTreeDumpTasks_[taskId];
4086     size_t completed = task.completionCount;
4087     RS_TRACE_NAME_FMT("DumpClientNodeTree end task[%u] completionCount[%zu]", taskId, completed);
4088     dumpString += "\n-- ClientNodeTreeDump: ";
4089     for (const auto& [pid, data] : task.data) {
4090         dumpString += "\n| pid[";
4091         dumpString += std::to_string(pid);
4092         dumpString += "]";
4093         if (data) {
4094             dumpString += "\n";
4095             dumpString += data.value();
4096         }
4097     }
4098     nodeTreeDumpTasks_.erase(taskId);
4099 
4100     RS_LOGI("CollectClientNodeTreeResult task[%{public}u] completionCount[%{public}zu]",
4101         taskId, completed);
4102 }
4103 
OnCommitDumpClientNodeTree(NodeId nodeId,pid_t pid,uint32_t taskId,const std::string & result)4104 void RSMainThread::OnCommitDumpClientNodeTree(NodeId nodeId, pid_t pid, uint32_t taskId, const std::string& result)
4105 {
4106     RS_TRACE_NAME_FMT("DumpClientNodeTree collected task[%u] dataSize[%zu] pid[%d]",
4107         taskId, result.size(), pid);
4108     {
4109         std::unique_lock<std::mutex> lock(nodeTreeDumpMutex_);
4110         auto iter = nodeTreeDumpTasks_.find(taskId);
4111         if (iter == nodeTreeDumpTasks_.end()) {
4112             RS_LOGW("OnDumpClientNodeTree task[%{public}u] not found for pid[%d]", taskId, pid);
4113             return;
4114         }
4115 
4116         iter->second.completionCount++;
4117         auto& data = iter->second.data[pid];
4118         if (data) {
4119             data->append("\n");
4120             data->append(result);
4121         } else {
4122             data = result;
4123         }
4124         nodeTreeDumpCondVar_.notify_all();
4125     }
4126 
4127     RS_LOGI("OnDumpClientNodeTree task[%{public}u] dataSize[%{public}zu] pid[%d]",
4128         taskId, result.size(), pid);
4129 }
4130 
4131 
DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)4132 bool RSMainThread::DoParallelComposition(std::shared_ptr<RSBaseRenderNode> rootNode)
4133 {
4134     using CreateParallelSyncSignalFunc = void* (*)(uint32_t);
4135     using SignalCountDownFunc = void (*)(void*);
4136     using SignalAwaitFunc = void (*)(void*);
4137     using AssignTaskFunc = void (*)(std::function<void()>);
4138     using RemoveStoppedThreadsFunc = void (*)();
4139 
4140     auto CreateParallelSyncSignal = (CreateParallelSyncSignalFunc)RSInnovation::_s_createParallelSyncSignal;
4141     auto SignalCountDown = (SignalCountDownFunc)RSInnovation::_s_signalCountDown;
4142     auto SignalAwait = (SignalAwaitFunc)RSInnovation::_s_signalAwait;
4143     auto AssignTask = (AssignTaskFunc)RSInnovation::_s_assignTask;
4144     auto RemoveStoppedThreads = (RemoveStoppedThreadsFunc)RSInnovation::_s_removeStoppedThreads;
4145 
4146     void* syncSignal = (*CreateParallelSyncSignal)(rootNode->GetChildrenCount());
4147     if (!syncSignal) {
4148         return false;
4149     }
4150 
4151     (*RemoveStoppedThreads)();
4152 
4153     auto children = *rootNode->GetSortedChildren();
4154     bool animate_ = doWindowAnimate_;
4155     for (auto it = children.rbegin(); it != children.rend(); it++) {
4156         auto child = *it;
4157         auto task = [&syncSignal, SignalCountDown, child, animate_]() {
4158             std::shared_ptr<RSNodeVisitor> visitor;
4159             auto rsVisitor = std::make_shared<RSRenderServiceVisitor>(true);
4160             rsVisitor->SetAnimateState(animate_);
4161             visitor = rsVisitor;
4162             child->Process(visitor);
4163             (*SignalCountDown)(syncSignal);
4164         };
4165         if (*it == *children.begin()) {
4166             task();
4167         } else {
4168             (*AssignTask)(task);
4169         }
4170     }
4171     (*SignalAwait)(syncSignal);
4172     return true;
4173 }
4174 
ClearTransactionDataPidInfo(pid_t remotePid)4175 void RSMainThread::ClearTransactionDataPidInfo(pid_t remotePid)
4176 {
4177     if (!isUniRender_) {
4178         return;
4179     }
4180     std::lock_guard<std::mutex> lock(transitionDataMutex_);
4181     auto it = effectiveTransactionDataIndexMap_.find(remotePid);
4182     if (it != effectiveTransactionDataIndexMap_.end()) {
4183         if (!it->second.second.empty()) {
4184             RS_LOGD("ClearTransactionDataPidInfo process:%{public}d destroyed, skip commands", remotePid);
4185         }
4186         effectiveTransactionDataIndexMap_.erase(it);
4187     }
4188     transactionDataLastWaitTime_.erase(remotePid);
4189 
4190     // clear cpu cache when process exit
4191     // CLEAN_CACHE_FREQ to prevent multiple cleanups in a short period of time
4192     if (remotePid != lastCleanCachePid_ ||
4193         ((timestamp_ - lastCleanCacheTimestamp_) / REFRESH_PERIOD) > CLEAN_CACHE_FREQ) {
4194 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
4195         RS_LOGD("RSMainThread: clear cpu cache pid:%{public}d", remotePid);
4196         if (!IsResidentProcess(remotePid)) {
4197             if (isUniRender_) {
4198                 RSUniRenderThread::Instance().ClearMemoryCache(ClearMemoryMoment::PROCESS_EXIT, true, remotePid);
4199                 isNeedResetClearMemoryTask_ = true;
4200             } else {
4201                 ClearMemoryCache(ClearMemoryMoment::PROCESS_EXIT, true);
4202             }
4203             lastCleanCacheTimestamp_ = timestamp_;
4204             lastCleanCachePid_ = remotePid;
4205         }
4206 #endif
4207     }
4208 }
4209 
IsResidentProcess(pid_t pid) const4210 bool RSMainThread::IsResidentProcess(pid_t pid) const
4211 {
4212     return pid == ExtractPid(context_->GetNodeMap().GetEntryViewNodeId());
4213 }
4214 
TrimMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString)4215 void RSMainThread::TrimMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString)
4216 {
4217 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
4218     if (!RSUniRenderJudgement::IsUniRender()) {
4219         dumpString.append("\n---------------\nNot in UniRender and no resource can be released");
4220         return;
4221     }
4222     std::string type;
4223     argSets.erase(u"trimMem");
4224     if (!argSets.empty()) {
4225         type = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
4226     }
4227     RSUniRenderThread::Instance().TrimMem(dumpString, type);
4228 #endif
4229 }
4230 
DumpNode(std::string & result,uint64_t nodeId) const4231 void RSMainThread::DumpNode(std::string& result, uint64_t nodeId) const
4232 {
4233     const auto& nodeMap = context_->GetNodeMap();
4234     auto node = nodeMap.GetRenderNode<RSRenderNode>(nodeId);
4235     if (!node) {
4236         result.append("have no this node");
4237         return;
4238     }
4239     DfxString log;
4240     node->DumpNodeInfo(log);
4241     result.append(log.GetString());
4242 }
4243 
DumpMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString,std::string & type,pid_t pid)4244 void RSMainThread::DumpMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString,
4245     std::string& type, pid_t pid)
4246 {
4247 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
4248     DfxString log;
4249     if (pid != 0) {
4250         RSUniRenderThread::Instance().PostSyncTask([&log, pid] {
4251             RS_TRACE_NAME_FMT("Dumping memory of pid[%d]", pid);
4252             MemoryManager::DumpPidMemory(log, pid,
4253                 RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
4254         });
4255     } else {
4256         MemoryManager::DumpMemoryUsage(log, type);
4257     }
4258     if ((type.empty() || type == MEM_GPU_TYPE) && RSSystemProperties::GetGpuApiType() != GpuApiType::DDGR) {
4259         auto subThreadManager = RSSubThreadManager::Instance();
4260         if (subThreadManager) {
4261             subThreadManager->DumpMem(log);
4262         }
4263     }
4264     dumpString.append("dumpMem: " + type + "\n");
4265     auto screenManager = CreateOrGetScreenManager();
4266     if (!screenManager) {
4267         RS_LOGE("DumpMem screenManager is nullptr");
4268         return;
4269     }
4270     auto maxScreenInfo = screenManager->GetActualScreenMaxResolution();
4271     dumpString.append("ScreenResolution = " + std::to_string(maxScreenInfo.phyWidth) +
4272         "x" + std::to_string(maxScreenInfo.phyHeight) + "\n");
4273     dumpString.append(log.GetString());
4274 
4275     RSUniRenderThread::Instance().DumpVkImageInfo(dumpString);
4276     RSHardwareThread::Instance().DumpVkImageInfo(dumpString);
4277 #else
4278     dumpString.append("No GPU in this device");
4279 #endif
4280 }
4281 
CountMem(int pid,MemoryGraphic & mem)4282 void RSMainThread::CountMem(int pid, MemoryGraphic& mem)
4283 {
4284 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
4285     RSUniRenderThread::Instance().PostSyncTask([&mem, pid] {
4286         RS_TRACE_NAME_FMT("Counting memory of pid[%d]", pid);
4287         mem = MemoryManager::CountPidMemory(pid,
4288             RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
4289     });
4290 #endif
4291 }
4292 
CountMem(std::vector<MemoryGraphic> & mems)4293 void RSMainThread::CountMem(std::vector<MemoryGraphic>& mems)
4294 {
4295 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
4296     if (!context_) {
4297         RS_LOGE("CountMem Context is nullptr");
4298         return;
4299     }
4300     const auto& nodeMap = context_->GetNodeMap();
4301     std::vector<pid_t> pids;
4302     nodeMap.TraverseSurfaceNodes([&pids] (const std::shared_ptr<RSSurfaceRenderNode>& node) {
4303         auto pid = ExtractPid(node->GetId());
4304         if (std::find(pids.begin(), pids.end(), pid) == pids.end()) {
4305             pids.emplace_back(pid);
4306         }
4307     });
4308     RSUniRenderThread::Instance().PostSyncTask([&mems, &pids] {
4309         MemoryManager::CountMemory(pids,
4310             RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetDrGPUContext(), mems);
4311     });
4312 #endif
4313 }
4314 
AddTransactionDataPidInfo(pid_t remotePid)4315 void RSMainThread::AddTransactionDataPidInfo(pid_t remotePid)
4316 {
4317     if (!isUniRender_) {
4318         return;
4319     }
4320     std::lock_guard<std::mutex> lock(transitionDataMutex_);
4321     auto it = effectiveTransactionDataIndexMap_.find(remotePid);
4322     if (it != effectiveTransactionDataIndexMap_.end()) {
4323         RS_LOGW("AddTransactionDataPidInfo remotePid:%{public}d already exists", remotePid);
4324         it->second.first = 0;
4325     } else {
4326         effectiveTransactionDataIndexMap_.emplace(remotePid,
4327             std::make_pair(0, std::vector<std::unique_ptr<RSTransactionData>>()));;
4328     }
4329 }
4330 
SetDirtyFlag(bool isDirty)4331 void RSMainThread::SetDirtyFlag(bool isDirty)
4332 {
4333     isDirty_ = isDirty;
4334 }
4335 
GetDirtyFlag()4336 bool RSMainThread::GetDirtyFlag()
4337 {
4338     return isDirty_;
4339 }
4340 
SetScreenPowerOnChanged(bool val)4341 void RSMainThread::SetScreenPowerOnChanged(bool val)
4342 {
4343     screenPowerOnChanged_ = val;
4344 }
4345 
GetScreenPowerOnChanged() const4346 bool RSMainThread::GetScreenPowerOnChanged() const
4347 {
4348     return screenPowerOnChanged_;
4349 }
4350 
SetAccessibilityConfigChanged()4351 void RSMainThread::SetAccessibilityConfigChanged()
4352 {
4353     isAccessibilityConfigChanged_ = true;
4354 }
4355 
IsAccessibilityConfigChanged() const4356 bool RSMainThread::IsAccessibilityConfigChanged() const
4357 {
4358     return isAccessibilityConfigChanged_;
4359 }
4360 
IsCurtainScreenUsingStatusChanged() const4361 bool RSMainThread::IsCurtainScreenUsingStatusChanged() const
4362 {
4363     return isCurtainScreenUsingStatusChanged_;
4364 }
4365 
PerfAfterAnim(bool needRequestNextVsync)4366 void RSMainThread::PerfAfterAnim(bool needRequestNextVsync)
4367 {
4368     if (!isUniRender_) {
4369         return;
4370     }
4371     if (needRequestNextVsync && timestamp_ - prePerfTimestamp_ > PERF_PERIOD) {
4372         RS_LOGD("soc perf to render_service_animation");
4373         prePerfTimestamp_ = timestamp_;
4374     } else if (!needRequestNextVsync && prePerfTimestamp_) {
4375         RS_LOGD("soc perf off render_service_animation");
4376         prePerfTimestamp_ = 0;
4377     }
4378 }
4379 
IsFastComposeAllow(uint64_t unsignedVsyncPeriod,bool nextVsyncRequested,uint64_t unsignedNowTime,uint64_t lastVsyncTime)4380 bool RSMainThread::IsFastComposeAllow(uint64_t unsignedVsyncPeriod, bool nextVsyncRequested,
4381     uint64_t unsignedNowTime, uint64_t lastVsyncTime)
4382 {
4383     if (unsignedVsyncPeriod == 0) {
4384         return false;
4385     }
4386     // only support 60hz fastcompose
4387     if (unsignedVsyncPeriod > REFRESH_PERIOD + PERIOD_MAX_OFFSET ||
4388         unsignedVsyncPeriod < REFRESH_PERIOD - PERIOD_MAX_OFFSET) {
4389         return false;
4390     }
4391     // fastcompose not work at dvsync preTime scene
4392     if (timestamp_ > curTime_ && timestamp_ - curTime_ > PERIOD_MAX_OFFSET) {
4393         return false;
4394     }
4395     // if buffer come after Vsync and before onVsync invoke by others, don't fastcompose
4396     if (nextVsyncRequested && (unsignedNowTime - lastVsyncTime) % unsignedVsyncPeriod < FASTCOMPOSE_OFFSET) {
4397         return false;
4398     }
4399     return true;
4400 }
4401 
IsFastComposeVsyncTimeSync(uint64_t unsignedVsyncPeriod,bool nextVsyncRequested,uint64_t unsignedNowTime,uint64_t lastVsyncTime,int64_t vsyncTimeStamp)4402 bool RSMainThread::IsFastComposeVsyncTimeSync(uint64_t unsignedVsyncPeriod, bool nextVsyncRequested,
4403     uint64_t unsignedNowTime, uint64_t lastVsyncTime, int64_t vsyncTimeStamp)
4404 {
4405     if (unsignedVsyncPeriod == 0) {
4406         return false;
4407     }
4408     if (vsyncTimeStamp < 0) {
4409         return false;
4410     }
4411     // if vsynctimestamp updated but timestamp_ not, diff > 1/2 vsync, don't fastcompose
4412     if (static_cast<uint64_t>(vsyncTimeStamp) - timestamp_ > REFRESH_PERIOD / 2) {
4413         return false;
4414     }
4415     // when buffer come near vsync time, difference value need to add offset before division
4416     if (!nextVsyncRequested && (unsignedNowTime - lastVsyncTime) % unsignedVsyncPeriod >
4417         unsignedVsyncPeriod - FASTCOMPOSE_OFFSET) {
4418         lastFastComposeTimeStampDiff_ = (unsignedNowTime + FASTCOMPOSE_OFFSET - lastVsyncTime) % unsignedVsyncPeriod;
4419     } else {
4420         lastFastComposeTimeStampDiff_ = (unsignedNowTime - lastVsyncTime) % unsignedVsyncPeriod;
4421     }
4422     return true;
4423 }
4424 
CheckFastCompose(int64_t lastFlushedDesiredPresentTimeStamp)4425 void RSMainThread::CheckFastCompose(int64_t lastFlushedDesiredPresentTimeStamp)
4426 {
4427     auto nowTime = SystemTime();
4428     uint64_t unsignedNowTime = static_cast<uint64_t>(nowTime);
4429     uint64_t unsignedLastFlushedDesiredPresentTimeStamp = static_cast<uint64_t>(lastFlushedDesiredPresentTimeStamp);
4430     int64_t vsyncPeriod = 0;
4431     int64_t vsyncTimeStamp = 0;
4432     bool nextVsyncRequested = true;
4433     bool earlyFastComposeFlag = false;
4434     VsyncError ret = VSYNC_ERROR_UNKOWN;
4435     if (receiver_) {
4436         ret = receiver_->GetVSyncPeriodAndLastTimeStamp(vsyncPeriod, vsyncTimeStamp);
4437         nextVsyncRequested = receiver_->IsRequestedNextVSync();
4438     }
4439     uint64_t unsignedVsyncPeriod = static_cast<uint64_t>(vsyncPeriod);
4440     uint64_t lastVsyncTime = 0;
4441     if (lastFastComposeTimeStamp_ > 0 && timestamp_ == lastFastComposeTimeStamp_) {
4442         lastVsyncTime = timestamp_ - lastFastComposeTimeStampDiff_;
4443     } else {
4444         lastVsyncTime = timestamp_;
4445         lastFastComposeTimeStampDiff_ = 0;
4446     }
4447     if (!IsFastComposeVsyncTimeSync(unsignedVsyncPeriod, nextVsyncRequested,
4448         unsignedNowTime, lastVsyncTime, vsyncTimeStamp)) {
4449         RequestNextVSync();
4450         return;
4451     }
4452     if (ret != VSYNC_ERROR_OK || !context_ ||
4453         !IsFastComposeAllow(unsignedVsyncPeriod, nextVsyncRequested, unsignedNowTime, lastVsyncTime)) {
4454         RequestNextVSync();
4455         return;
4456     }
4457     // if buffer come near vsync and next vsync not requested, do fast compose
4458     if (!nextVsyncRequested && (unsignedNowTime - lastVsyncTime) % unsignedVsyncPeriod >
4459         unsignedVsyncPeriod - FASTCOMPOSE_OFFSET) {
4460         unsignedNowTime += FASTCOMPOSE_OFFSET;
4461         earlyFastComposeFlag = true;
4462     }
4463     lastVsyncTime = unsignedNowTime - (unsignedNowTime - lastVsyncTime) % unsignedVsyncPeriod;
4464     RS_TRACE_NAME_FMT("RSMainThread::CheckFastCompose now = %" PRIu64 ", lastVsyncTime = %" PRIu64 ", timestamp_ = %"
4465         "" PRIu64 "earlyFastCompose = %d", unsignedNowTime, lastVsyncTime, timestamp_, earlyFastComposeFlag);
4466     // ignore animation scenario and mult-window scenario
4467     bool isNeedSingleFrameCompose = context_->GetAnimatingNodeList().empty() &&
4468         context_->GetUnirenderVisibleLeashWindowCount() < MULTI_WINDOW_PERF_START_NUM;
4469     // 1/2 vsync period to support continunous fastcompose
4470     if (isNeedSingleFrameCompose && unsignedNowTime - timestamp_ > unsignedVsyncPeriod / 2 &&
4471         unsignedLastFlushedDesiredPresentTimeStamp < lastVsyncTime &&
4472         unsignedNowTime - lastVsyncTime < REFRESH_PERIOD / 2) { // invoke when late less than 1/2 refresh period
4473         RS_TRACE_NAME("RSMainThread::CheckFastCompose success, start fastcompose");
4474         ForceRefreshForUni(true);
4475         return;
4476     }
4477     RequestNextVSync();
4478 }
4479 
CheckAdaptiveCompose()4480 bool RSMainThread::CheckAdaptiveCompose()
4481 {
4482     auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr();
4483     if (frameRateMgr == nullptr || !context_) {
4484         return false;
4485     }
4486     auto adaptiveStatus = frameRateMgr->AdaptiveStatus();
4487     if (adaptiveStatus != SupportASStatus::SUPPORT_AS) {
4488         return false;
4489     }
4490     bool onlyGameNodeOnTree = frameRateMgr->HandleGameNode(GetContext().GetNodeMap());
4491     bool isNeedAdaptiveCompose = onlyGameNodeOnTree &&
4492         context_->GetAnimatingNodeList().empty() &&
4493         context_->GetNodeMap().GetVisibleLeashWindowCount() < MULTI_WINDOW_PERF_START_NUM;
4494     // in game adaptive sync mode and ignore animation scenario and mult-window scenario
4495     // selfdrawing node request next vsync as UrgentSelfdrawing
4496     return isNeedAdaptiveCompose;
4497 }
4498 
4499 
ForceRefreshForUni(bool needDelay)4500 void RSMainThread::ForceRefreshForUni(bool needDelay)
4501 {
4502     RS_LOGI("ForceRefreshForUni call");
4503     if (isUniRender_) {
4504 #ifdef RS_ENABLE_GPU
4505         PostTask([=]() {
4506             const int64_t onVsyncStartTime = GetCurrentSystimeMs();
4507             const int64_t onVsyncStartTimeSteady = GetCurrentSteadyTimeMs();
4508             const float onVsyncStartTimeSteadyFloat = GetCurrentSteadyTimeMsFloat();
4509             RSJankStatsOnVsyncStart(onVsyncStartTime, onVsyncStartTimeSteady, onVsyncStartTimeSteadyFloat);
4510             MergeToEffectiveTransactionDataMap(cachedTransactionDataMap_);
4511             RSUnmarshalThread::Instance().PostTask(unmarshalBarrierTask_);
4512             auto now = std::chrono::duration_cast<std::chrono::nanoseconds>(
4513                 std::chrono::steady_clock::now().time_since_epoch()).count();
4514             RS_PROFILER_PATCH_TIME(now);
4515             timestamp_ = timestamp_ + (now - curTime_);
4516             vsyncRsTimestamp_.store(timestamp_);
4517             int64_t vsyncPeriod = 0;
4518             VsyncError ret = VSYNC_ERROR_UNKOWN;
4519             if (receiver_) {
4520                 ret = receiver_->GetVSyncPeriod(vsyncPeriod);
4521             }
4522             if (ret == VSYNC_ERROR_OK && vsyncPeriod > 0) {
4523                 lastFastComposeTimeStamp_ = timestamp_;
4524                 RS_TRACE_NAME_FMT("RSMainThread::ForceRefreshForUni record"
4525                     "Time diff: %" PRIu64, lastFastComposeTimeStampDiff_);
4526                 // When fast compose by buffer, pipeline still need to delay to maintain smooth rendering
4527                 isForceRefresh_ = !needDelay;
4528             } else {
4529                 isForceRefresh_ = true;
4530             }
4531             curTime_ = now;
4532             // Not triggered by vsync, so we set frameCount to 0.
4533             SetFrameInfo(0, isForceRefresh_);
4534             RS_TRACE_NAME("RSMainThread::ForceRefreshForUni timestamp:" + std::to_string(timestamp_));
4535             mainLoop_();
4536             RSJankStatsOnVsyncEnd(onVsyncStartTime, onVsyncStartTimeSteady, onVsyncStartTimeSteadyFloat);
4537         });
4538         auto screenManager_ = CreateOrGetScreenManager();
4539         if (screenManager_ != nullptr) {
4540             auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
4541             if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
4542                 RSHardwareThread::Instance().PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
4543             } else {
4544                 PostTask([=]() { screenManager_->ProcessScreenHotPlugEvents(); });
4545             }
4546         }
4547 #endif
4548     } else {
4549         RequestNextVSync();
4550     }
4551 }
4552 
PerfForBlurIfNeeded()4553 void RSMainThread::PerfForBlurIfNeeded()
4554 {
4555     if (!SOCPerfParam::IsBlurSOCPerfEnable()) {
4556         return;
4557     }
4558     handler_->RemoveTask(PERF_FOR_BLUR_IF_NEEDED_TASK_NAME);
4559     static uint64_t prePerfTimestamp = 0;
4560     static int preBlurCnt = 0;
4561     static int cnt = 0;
4562 
4563     auto task = [this]() {
4564         if (preBlurCnt == 0) {
4565             return;
4566         }
4567         auto now = std::chrono::steady_clock::now().time_since_epoch();
4568         auto timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
4569         RS_OPTIONAL_TRACE_NAME_FMT("PerfForBlurIfNeeded now[%ld] timestamp[%ld] preBlurCnt[%d]",
4570             std::chrono::steady_clock::now().time_since_epoch(), timestamp, preBlurCnt);
4571         if (static_cast<uint64_t>(timestamp) - prePerfTimestamp > PERF_PERIOD_BLUR_TIMEOUT && preBlurCnt != 0) {
4572             PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(preBlurCnt), false);
4573             prePerfTimestamp = 0;
4574             preBlurCnt = 0;
4575         }
4576     };
4577     // delay 100ms
4578     handler_->PostTask(task, PERF_FOR_BLUR_IF_NEEDED_TASK_NAME, 100);
4579     int blurCnt = RSPropertiesPainter::GetAndResetBlurCnt();
4580     // clamp blurCnt to 0~3.
4581     blurCnt = std::clamp<int>(blurCnt, 0, 3);
4582     if (blurCnt < preBlurCnt) {
4583         cnt++;
4584     } else {
4585         cnt = 0;
4586     }
4587     // if blurCnt > preBlurCnt, than change perf code;
4588     // if blurCnt < preBlurCnt 10 times continuously, than change perf code.
4589     bool cntIsMatch = blurCnt > preBlurCnt || cnt > 10;
4590     if (cntIsMatch && preBlurCnt != 0) {
4591         RS_OPTIONAL_TRACE_NAME_FMT("PerfForBlurIfNeeded Perf close, preBlurCnt[%d] blurCnt[%d]", preBlurCnt, blurCnt);
4592         PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(preBlurCnt), false);
4593         preBlurCnt = blurCnt == 0 ? 0 : preBlurCnt;
4594     }
4595     if (blurCnt == 0) {
4596         return;
4597     }
4598     if (timestamp_ - prePerfTimestamp > PERF_PERIOD_BLUR || cntIsMatch) {
4599         RS_OPTIONAL_TRACE_NAME_FMT("PerfForBlurIfNeeded PerfRequest, preBlurCnt[%d] blurCnt[%d]", preBlurCnt, blurCnt);
4600         PerfRequest(BLUR_CNT_TO_BLUR_CODE.at(blurCnt), true);
4601         prePerfTimestamp = timestamp_;
4602         preBlurCnt = blurCnt;
4603     }
4604 }
4605 
PerfMultiWindow()4606 void RSMainThread::PerfMultiWindow()
4607 {
4608     if (!isUniRender_) {
4609         return;
4610     }
4611     static uint64_t lastPerfTimestamp = 0;
4612     if (appWindowNum_ >= MULTI_WINDOW_PERF_START_NUM && appWindowNum_ <= MULTI_WINDOW_PERF_END_NUM
4613         && timestamp_ - lastPerfTimestamp > PERF_PERIOD_MULTI_WINDOW) {
4614         RS_LOGD("PerfMultiWindow soc perf");
4615         PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, true);
4616         lastPerfTimestamp = timestamp_;
4617     } else if ((appWindowNum_ < MULTI_WINDOW_PERF_START_NUM || appWindowNum_ > MULTI_WINDOW_PERF_END_NUM)
4618         && timestamp_ - lastPerfTimestamp < PERF_PERIOD_MULTI_WINDOW) {
4619         RS_LOGD("PerfMultiWindow soc perf off");
4620         PerfRequest(PERF_MULTI_WINDOW_REQUESTED_CODE, false);
4621     }
4622 }
4623 
RenderFrameStart(uint64_t timestamp)4624 void RSMainThread::RenderFrameStart(uint64_t timestamp)
4625 {
4626     uint32_t unExecuteTaskNum = RSHardwareThread::Instance().GetunExecuteTaskNum();
4627     RsFrameReport::GetInstance().ReportBufferCount(unExecuteTaskNum);
4628 #ifdef RS_ENABLE_GPU
4629     int hardwareTid = RSHardwareThread::Instance().GetHardwareTid();
4630     RsFrameReport::GetInstance().ReportHardwareInfo(hardwareTid);
4631 #endif
4632     int skipFirstFrame = (drawingRequestNextVsyncNum_.load() == SKIP_FIRST_FRAME_DRAWING_NUM) &&
4633         forceUpdateUniRenderFlag_;
4634     RsFrameReport::GetInstance().RenderStart(timestamp, skipFirstFrame);
4635     RenderFrameTrace::GetInstance().RenderStartFrameTrace(RS_INTERVAL_NAME);
4636 }
4637 
SetAppWindowNum(uint32_t num)4638 void RSMainThread::SetAppWindowNum(uint32_t num)
4639 {
4640     appWindowNum_ = num;
4641 }
4642 
SetSystemAnimatedScenes(SystemAnimatedScenes systemAnimatedScenes,bool isRegularAnimation)4643 bool RSMainThread::SetSystemAnimatedScenes(SystemAnimatedScenes systemAnimatedScenes, bool isRegularAnimation)
4644 {
4645     RS_OPTIONAL_TRACE_NAME_FMT("%s systemAnimatedScenes[%u] systemAnimatedScenes_[%u] threeFingerScenesListSize[%d] "
4646         "systemAnimatedScenesListSize_[%d] isRegularAnimation_[%d]", __func__, systemAnimatedScenes,
4647         systemAnimatedScenes_, threeFingerScenesList_.size(), systemAnimatedScenesList_.size(), isRegularAnimation);
4648     if (systemAnimatedScenes < SystemAnimatedScenes::ENTER_MISSION_CENTER ||
4649             systemAnimatedScenes > SystemAnimatedScenes::OTHERS) {
4650         RS_LOGD("SetSystemAnimatedScenes Out of range.");
4651         return false;
4652     }
4653     systemAnimatedScenes_ = systemAnimatedScenes;
4654     isRegularAnimation_ = isRegularAnimation;
4655     if (!systemAnimatedScenesEnabled_) {
4656         return true;
4657     }
4658     {
4659         std::lock_guard<std::mutex> lock(systemAnimatedScenesMutex_);
4660         if (systemAnimatedScenes == SystemAnimatedScenes::OTHERS) {
4661             if (!threeFingerScenesList_.empty()) {
4662                 threeFingerScenesList_.pop_front();
4663             }
4664             if (!systemAnimatedScenesList_.empty()) {
4665                 systemAnimatedScenesList_.pop_front();
4666             }
4667         } else {
4668             uint64_t curTime = static_cast<uint64_t>(
4669                 std::chrono::duration_cast<std::chrono::nanoseconds>(
4670                     std::chrono::steady_clock::now().time_since_epoch()).count());
4671             if (systemAnimatedScenes == SystemAnimatedScenes::ENTER_TFS_WINDOW ||
4672                 systemAnimatedScenes == SystemAnimatedScenes::EXIT_TFU_WINDOW ||
4673                 systemAnimatedScenes == SystemAnimatedScenes::ENTER_WIND_CLEAR ||
4674                 systemAnimatedScenes == SystemAnimatedScenes::ENTER_WIND_RECOVER) {
4675                 if (threeFingerScenesList_.size() > MAX_ANIMATED_SCENES_NUM) {
4676                     RS_LOGD("%{public}s: threeFingerScenesList is over max size!", __func__);
4677                     return false;
4678                 }
4679                 threeFingerScenesList_.push_back(std::make_pair(systemAnimatedScenes, curTime));
4680             }
4681             if (systemAnimatedScenes != SystemAnimatedScenes::APPEAR_MISSION_CENTER &&
4682                 systemAnimatedScenes != SystemAnimatedScenes::ENTER_RECENTS &&
4683                 systemAnimatedScenes != SystemAnimatedScenes::EXIT_RECENTS) {
4684                 if (systemAnimatedScenesList_.size() > MAX_ANIMATED_SCENES_NUM) {
4685                     RS_LOGD("%{public}s: systemAnimatedScenesList is over max size!", __func__);
4686                     return false;
4687                 }
4688                 // systemAnimatedScenesList_ is only for pc now
4689                 systemAnimatedScenesList_.push_back(std::make_pair(systemAnimatedScenes, curTime));
4690             }
4691         }
4692     }
4693     return true;
4694 }
GetIsRegularAnimation() const4695 bool RSMainThread::GetIsRegularAnimation() const
4696 {
4697     return (isRegularAnimation_ &&
4698         systemAnimatedScenes_ < SystemAnimatedScenes::OTHERS &&
4699         RSSystemParameters::GetAnimationOcclusionEnabled()) || IsPCThreeFingerScenesListScene();
4700 }
4701 
GetSystemAnimatedScenes()4702 SystemAnimatedScenes RSMainThread::GetSystemAnimatedScenes()
4703 {
4704     return systemAnimatedScenes_;
4705 }
4706 
CheckNodeHasToBePreparedByPid(NodeId nodeId,bool isClassifyByRoot)4707 bool RSMainThread::CheckNodeHasToBePreparedByPid(NodeId nodeId, bool isClassifyByRoot)
4708 {
4709     std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
4710     if (context_->activeNodesInRoot_.empty() || nodeId == INVALID_NODEID) {
4711         return false;
4712     }
4713     if (!isClassifyByRoot) {
4714         // Match by PID
4715         auto pid = ExtractPid(nodeId);
4716         return std::any_of(context_->activeNodesInRoot_.begin(), context_->activeNodesInRoot_.end(),
4717             [pid](const auto& iter) { return ExtractPid(iter.first) == pid; });
4718     } else {
4719         return context_->activeNodesInRoot_.count(nodeId);
4720     }
4721 }
4722 
IsDrawingGroupChanged(const RSRenderNode & cacheRootNode) const4723 bool RSMainThread::IsDrawingGroupChanged(const RSRenderNode& cacheRootNode) const
4724 {
4725     std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
4726     auto iter = context_->activeNodesInRoot_.find(cacheRootNode.GetInstanceRootNodeId());
4727     if (iter != context_->activeNodesInRoot_.end()) {
4728         const auto& activeNodeIds = iter->second;
4729         // do not need to check cacheroot node itself
4730         // in case of tree change, parent node would set content dirty and reject before
4731         auto cacheRootId = cacheRootNode.GetId();
4732         auto groupNodeIds = cacheRootNode.GetVisitedCacheRootIds();
4733         for (auto [id, subNode] : activeNodeIds) {
4734             auto node = subNode.lock();
4735             if (node == nullptr || id == cacheRootId) {
4736                 continue;
4737             }
4738             if (groupNodeIds.find(node->GetDrawingCacheRootId()) != groupNodeIds.end()) {
4739                 return true;
4740             }
4741         }
4742     }
4743     return false;
4744 }
4745 
CheckAndUpdateInstanceContentStaticStatus(std::shared_ptr<RSSurfaceRenderNode> instanceNode) const4746 CM_INLINE void RSMainThread::CheckAndUpdateInstanceContentStaticStatus(
4747     std::shared_ptr<RSSurfaceRenderNode> instanceNode) const
4748 {
4749     if (instanceNode == nullptr) {
4750         RS_LOGE("CheckAndUpdateInstanceContentStaticStatus instanceNode invalid.");
4751         return ;
4752     }
4753     std::lock_guard<std::mutex> lock(context_->activeNodesInRootMutex_);
4754     auto iter = context_->activeNodesInRoot_.find(instanceNode->GetId());
4755     if (iter != context_->activeNodesInRoot_.end()) {
4756         instanceNode->UpdateSurfaceCacheContentStatic(iter->second);
4757     } else {
4758         instanceNode->UpdateSurfaceCacheContentStatic();
4759     }
4760 }
4761 
ResetHardwareEnabledState(bool isUniRender)4762 void RSMainThread::ResetHardwareEnabledState(bool isUniRender)
4763 {
4764     if (isUniRender) {
4765 #ifdef RS_ENABLE_GPU
4766         isHardwareForcedDisabled_ = !RSSystemProperties::GetHardwareComposerEnabled();
4767         directComposeHelper_.isLastFrameDirectComposition_ = doDirectComposition_;
4768         doDirectComposition_ = isHardwareForcedDisabled_ ? false : RSSystemProperties::GetDoDirectCompositionEnabled();
4769         isHardwareEnabledBufferUpdated_ = false;
4770         hasProtectedLayer_ = false;
4771         hardwareEnabledNodes_.clear();
4772         hardwareEnabledDrwawables_.clear();
4773         ClearSelfDrawingNodes();
4774         selfDrawables_.clear();
4775         RSPointerWindowManager::Instance().ResetHardCursorDrawables();
4776 #endif
4777     }
4778 }
4779 
IsHardwareEnabledNodesNeedSync()4780 bool RSMainThread::IsHardwareEnabledNodesNeedSync()
4781 {
4782     bool needSync = false;
4783 #ifdef RS_ENABLE_GPU
4784     for (const auto& node : hardwareEnabledNodes_) {
4785         if (node != nullptr && ((!doDirectComposition_ && node->GetStagingRenderParams() != nullptr &&
4786             node->GetStagingRenderParams()->NeedSync()) ||
4787             (doDirectComposition_ && !node->IsHardwareForcedDisabled()))) {
4788             needSync = true;
4789             break;
4790         }
4791     }
4792 #endif
4793     RS_TRACE_NAME_FMT("%s %u", __func__, needSync);
4794     RS_LOGD("%{public}s %{public}u", __func__, needSync);
4795 
4796     return needSync;
4797 }
4798 
IsOcclusionNodesNeedSync(NodeId id,bool useCurWindow)4799 bool RSMainThread::IsOcclusionNodesNeedSync(NodeId id, bool useCurWindow)
4800 {
4801     auto nodePtr = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
4802         GetContext().GetNodeMap().GetRenderNode(id));
4803     if (nodePtr == nullptr) {
4804         return false;
4805     }
4806 
4807     if (useCurWindow == false) {
4808         auto parentNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr->GetParent().lock());
4809         if (parentNode && parentNode->IsLeashWindow() && parentNode->ShouldPaint()) {
4810             nodePtr = parentNode;
4811         }
4812     }
4813 
4814     if (nodePtr->GetIsFullChildrenListValid() == false || !nodePtr->IsOnTheTree()) {
4815         nodePtr->PrepareSelfNodeForApplyModifiers();
4816         return true;
4817     }
4818 
4819     bool needSync = false;
4820     if (nodePtr->IsLeashWindow()) {
4821         auto children = nodePtr->GetSortedChildren();
4822         for (auto child : *children) {
4823             auto childSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
4824             if (childSurfaceNode && childSurfaceNode->IsMainWindowType() &&
4825                 childSurfaceNode->GetVisibleRegion().IsEmpty()) {
4826                 childSurfaceNode->PrepareSelfNodeForApplyModifiers();
4827                 needSync = true;
4828             }
4829         }
4830     } else if (nodePtr->IsMainWindowType() && nodePtr->GetVisibleRegion().IsEmpty()) {
4831         nodePtr->PrepareSelfNodeForApplyModifiers();
4832         needSync = true;
4833     }
4834 
4835     return needSync;
4836 }
4837 
SetWatermark(const pid_t & pid,const std::string & name,std::shared_ptr<Media::PixelMap> watermark)4838 void RSMainThread::SetWatermark(const pid_t& pid, const std::string& name, std::shared_ptr<Media::PixelMap> watermark)
4839 {
4840     std::lock_guard<std::mutex> lock(watermarkMutex_);
4841     static constexpr uint32_t REGISTER_SURFACE_WATER_MASK_LIMIT = 100;
4842     auto iter = surfaceNodeWatermarks_.find({pid, name});
4843     if (iter == std::end(surfaceNodeWatermarks_)) {
4844         if (registerSurfaceWaterMaskCount_[pid] >= REGISTER_SURFACE_WATER_MASK_LIMIT) {
4845             RS_LOGE("RSMainThread::SetWatermark surfaceNodeWatermark:"
4846                 "[Pid:%{public}s] limit", std::to_string(pid).c_str());
4847             return;
4848         }
4849         registerSurfaceWaterMaskCount_[pid]++;
4850         surfaceNodeWatermarks_.insert({{pid, name}, watermark});
4851     } else {
4852         iter->second = watermark;
4853     }
4854 }
4855 
ClearWatermark(pid_t pid)4856 void RSMainThread::ClearWatermark(pid_t pid)
4857 {
4858     std::lock_guard<std::mutex> lock(watermarkMutex_);
4859     registerSurfaceWaterMaskCount_.erase(pid);
4860     if (surfaceNodeWatermarks_.size() > 0) {
4861         RS_TRACE_NAME_FMT("RSMainThread::ClearWatermark %d", pid);
4862         EraseIf(surfaceNodeWatermarks_, [pid](const auto& pair) {
4863             return pair.first.first == pid;
4864         });
4865     }
4866 }
4867 
ShowWatermark(const std::shared_ptr<Media::PixelMap> & watermarkImg,bool flag)4868 void RSMainThread::ShowWatermark(const std::shared_ptr<Media::PixelMap> &watermarkImg, bool flag)
4869 {
4870     std::lock_guard<std::mutex> lock(watermarkMutex_);
4871     auto screenManager_ = CreateOrGetScreenManager();
4872     if (flag && screenManager_) {
4873         auto screenInfo = screenManager_->QueryDefaultScreenInfo();
4874         constexpr int32_t maxScale = 2;
4875         if (screenInfo.id != INVALID_SCREEN_ID && watermarkImg &&
4876             (watermarkImg->GetWidth() > maxScale * static_cast<int32_t>(screenInfo.width) ||
4877             watermarkImg->GetHeight() > maxScale * static_cast<int32_t>(screenInfo.height))) {
4878             RS_LOGE("ShowWatermark width %{public}" PRId32" or height %{public}" PRId32" has reached"
4879                 " the maximum limit!", watermarkImg->GetWidth(), watermarkImg->GetHeight());
4880             return;
4881         }
4882     }
4883 
4884     watermarkFlag_ = flag;
4885     if (flag) {
4886         watermarkImg_ = RSPixelMapUtil::ExtractDrawingImage(watermarkImg);
4887     } else {
4888         watermarkImg_ = nullptr;
4889     }
4890     SetDirtyFlag();
4891     RequestNextVSync();
4892 }
4893 
GetWatermarkImg()4894 std::shared_ptr<Drawing::Image> RSMainThread::GetWatermarkImg()
4895 {
4896     return watermarkImg_;
4897 }
4898 
GetWatermarkFlag()4899 bool RSMainThread::GetWatermarkFlag()
4900 {
4901     return watermarkFlag_;
4902 }
4903 
IsSingleDisplay()4904 bool RSMainThread::IsSingleDisplay()
4905 {
4906     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
4907     if (rootNode == nullptr) {
4908         RS_LOGE("IsSingleDisplay GetGlobalRootRenderNode fail");
4909         return false;
4910     }
4911     return rootNode->GetChildrenCount() == 1;
4912 }
4913 
HasMirrorDisplay() const4914 bool RSMainThread::HasMirrorDisplay() const
4915 {
4916     bool hasWiredMirrorDisplay = false;
4917     bool hasVirtualMirrorDisplay = false;
4918     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
4919     bool isSingleNodeOrEmpty = rootNode == nullptr || rootNode->GetChildrenCount() <= 1;
4920     if (isSingleNodeOrEmpty) {
4921         hasWiredMirrorDisplay_.store(false);
4922         hasVirtualMirrorDisplay_.store(false);
4923         LppVideoHandler::Instance().SetHasVirtualMirrorDisplay(false);
4924         return false;
4925     }
4926 
4927     for (auto& child : *rootNode->GetSortedChildren()) {
4928         bool isScreenNodeChild = child && child->IsInstanceOf<RSScreenRenderNode>();
4929         if (!isScreenNodeChild) {
4930             continue;
4931         }
4932         auto screenNode = child->ReinterpretCastTo<RSScreenRenderNode>();
4933         if (!screenNode) {
4934             continue;
4935         }
4936         if (auto mirroredNode = screenNode->GetMirrorSource().lock()) {
4937             if (screenNode->GetCompositeType() == CompositeType::UNI_RENDER_COMPOSITE) {
4938                 hasWiredMirrorDisplay = true;
4939             } else {
4940                 hasVirtualMirrorDisplay = true;
4941             }
4942         }
4943     }
4944     hasWiredMirrorDisplay_.store(hasWiredMirrorDisplay);
4945     hasVirtualMirrorDisplay_.store(hasVirtualMirrorDisplay);
4946     LppVideoHandler::Instance().SetHasVirtualMirrorDisplay(hasVirtualMirrorDisplay);
4947     return hasWiredMirrorDisplay || hasVirtualMirrorDisplay;
4948 }
4949 
UpdateScreenNodeScreenId()4950 void RSMainThread::UpdateScreenNodeScreenId()
4951 {
4952     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
4953     if (!rootNode) {
4954         RS_LOGE("UpdateScreenNodeScreenId rootNode is nullptr");
4955         return;
4956     }
4957     auto childList = rootNode->GetChildrenList();
4958     for (auto& child : childList) {
4959         if (auto node = child.lock()) {
4960             auto screenNode = node->ReinterpretCastTo<RSScreenRenderNode>();
4961             if (screenNode && screenNode->GetChildrenCount() > 0) {
4962                 screenNodeScreenId_ = screenNode->GetScreenId();
4963                 break;
4964             }
4965         }
4966     }
4967 }
4968 
4969 const uint32_t FOLD_DEVICE_SCREEN_NUMBER = 2; // alt device has two screens
4970 
UpdateAnimateNodeFlag()4971 void RSMainThread::UpdateAnimateNodeFlag()
4972 {
4973     if (!context_) {
4974         return;
4975     }
4976     context_->curFrameAnimatingNodeList_.insert(context_->animatingNodeList_.begin(),
4977         context_->animatingNodeList_.end());
4978     for (auto& item : context_->curFrameAnimatingNodeList_) {
4979         auto node = item.second.lock();
4980         if (node) {
4981             node->SetCurFrameHasAnimation(true);
4982         }
4983     }
4984 }
4985 
ResetAnimateNodeFlag()4986 void RSMainThread::ResetAnimateNodeFlag()
4987 {
4988     if (!context_) {
4989         return;
4990     }
4991     for (auto& item : context_->curFrameAnimatingNodeList_) {
4992         auto node = item.second.lock();
4993         if (node) {
4994             node->SetCurFrameHasAnimation(false);
4995         }
4996     }
4997     context_->curFrameAnimatingNodeList_.clear();
4998 }
4999 
ReleaseSurface()5000 void RSMainThread::ReleaseSurface()
5001 {
5002     std::lock_guard<std::mutex> lock(mutex_);
5003     while (tmpSurfaces_.size() > 0) {
5004         auto tmp = tmpSurfaces_.front();
5005         tmpSurfaces_.pop();
5006         tmp = nullptr;
5007     }
5008 }
5009 
AddToReleaseQueue(std::shared_ptr<Drawing::Surface> && surface)5010 void RSMainThread::AddToReleaseQueue(std::shared_ptr<Drawing::Surface>&& surface)
5011 {
5012     std::lock_guard<std::mutex> lock(mutex_);
5013     tmpSurfaces_.push(std::move(surface));
5014 }
5015 
GetAppMemoryInMB(float & cpuMemSize,float & gpuMemSize)5016 void RSMainThread::GetAppMemoryInMB(float& cpuMemSize, float& gpuMemSize)
5017 {
5018 #ifdef RS_ENABLE_GPU
5019     RSUniRenderThread::Instance().PostSyncTask([&cpuMemSize, &gpuMemSize] {
5020         gpuMemSize = MemoryManager::GetAppGpuMemoryInMB(
5021             RSUniRenderThread::Instance().GetRenderEngine()->GetRenderContext()->GetDrGPUContext());
5022         cpuMemSize = MemoryTrack::Instance().GetAppMemorySizeInMB();
5023     });
5024 #endif
5025 }
5026 
SubscribeAppState()5027 void RSMainThread::SubscribeAppState()
5028 {
5029     RSBackgroundThread::Instance().PostTask(
5030         [this]() {
5031             rsAppStateListener_ = std::make_shared<RSAppStateListener>();
5032             if (Memory::MemMgrClient::GetInstance().SubscribeAppState(*rsAppStateListener_) != -1) {
5033                 RS_LOGD("Subscribe MemMgr Success");
5034                 subscribeFailCount_ = 0;
5035                 return;
5036             } else {
5037                 RS_LOGE("Subscribe Failed, try again");
5038                 subscribeFailCount_++;
5039                 if (subscribeFailCount_ < 10) { // The maximum number of failures is 10
5040                     SubscribeAppState();
5041                 } else {
5042                     RS_LOGE("Subscribe Failed 10 times, exiting");
5043                 }
5044             }
5045         });
5046 }
5047 
HandleOnTrim(Memory::SystemMemoryLevel level)5048 void RSMainThread::HandleOnTrim(Memory::SystemMemoryLevel level)
5049 {
5050     if (handler_) {
5051         handler_->PostTask(
5052             [level, this]() {
5053                 RS_LOGD("Enter level:%{public}d, OnTrim Success", level);
5054                 RS_TRACE_NAME_FMT("System is low memory, HandleOnTrim Enter level:%d", level);
5055                 switch (level) {
5056                     case Memory::SystemMemoryLevel::MEMORY_LEVEL_CRITICAL:
5057                         if (isUniRender_) {
5058 #ifdef RS_ENABLE_GPU
5059                             RSUniRenderThread::Instance().ClearMemoryCache(ClearMemoryMoment::LOW_MEMORY, true);
5060                             isNeedResetClearMemoryTask_ = true;
5061 #endif
5062                         } else {
5063                             ClearMemoryCache(ClearMemoryMoment::LOW_MEMORY, true);
5064                         }
5065                         break;
5066                     case Memory::SystemMemoryLevel::MEMORY_LEVEL_LOW:
5067                     case Memory::SystemMemoryLevel::MEMORY_LEVEL_MODERATE:
5068                     case Memory::SystemMemoryLevel::MEMORY_LEVEL_PURGEABLE:
5069                         break;
5070                     default:
5071                         break;
5072                 }
5073             },
5074             AppExecFwk::EventQueue::Priority::IDLE);
5075     }
5076 }
5077 
SetCurtainScreenUsingStatus(bool isCurtainScreenOn)5078 void RSMainThread::SetCurtainScreenUsingStatus(bool isCurtainScreenOn)
5079 {
5080     if (!AccessibilityParam::IsCurtainScreenEnabled()) {
5081         RS_LOGE("SetCurtainScreenUsingStatus CurtainScreenEnabled is not supported");
5082         return;
5083     }
5084 
5085 #ifdef RS_ENABLE_GPU
5086     if (isCurtainScreenOn_ == isCurtainScreenOn) {
5087         RS_LOGD("SetCurtainScreenUsingStatus: curtain screen status not change");
5088         return;
5089     }
5090     isCurtainScreenOn_ = isCurtainScreenOn;
5091     isCurtainScreenUsingStatusChanged_ = true;
5092     SetDirtyFlag();
5093     RequestNextVSync();
5094     RS_LOGD("SetCurtainScreenUsingStatus %{public}d", isCurtainScreenOn);
5095 #endif
5096 }
5097 
AddPidNeedDropFrame(std::vector<int32_t> pidList)5098 void RSMainThread::AddPidNeedDropFrame(std::vector<int32_t> pidList)
5099 {
5100     if (surfacePidNeedDropFrame_.size() > MAX_DROP_FRAME_PID_LIST_SIZE) {
5101         surfacePidNeedDropFrame_.clear();
5102     }
5103 
5104     for (const auto& pid: pidList) {
5105         surfacePidNeedDropFrame_.insert(pid);
5106     }
5107 }
5108 
ClearNeedDropframePidList()5109 void RSMainThread::ClearNeedDropframePidList()
5110 {
5111     surfacePidNeedDropFrame_.clear();
5112 }
5113 
IsNeedDropFrameByPid(NodeId nodeId)5114 bool RSMainThread::IsNeedDropFrameByPid(NodeId nodeId)
5115 {
5116     int32_t pid = ExtractPid(nodeId);
5117     return surfacePidNeedDropFrame_.find(pid) != surfacePidNeedDropFrame_.end();
5118 }
5119 
SetLuminanceChangingStatus(ScreenId id,bool isLuminanceChanged)5120 void RSMainThread::SetLuminanceChangingStatus(ScreenId id, bool isLuminanceChanged)
5121 {
5122     std::lock_guard<std::mutex> lock(luminanceMutex_);
5123     displayLuminanceChanged_[id] = isLuminanceChanged;
5124 }
5125 
ExchangeLuminanceChangingStatus(ScreenId id)5126 bool RSMainThread::ExchangeLuminanceChangingStatus(ScreenId id)
5127 {
5128     std::lock_guard<std::mutex> lock(luminanceMutex_);
5129     bool ret = false;
5130     auto it = displayLuminanceChanged_.find(id);
5131     if (it != displayLuminanceChanged_.end()) {
5132         ret = it->second;
5133         it->second = false;
5134     }
5135     return ret;
5136 }
5137 
IsCurtainScreenOn() const5138 bool RSMainThread::IsCurtainScreenOn() const
5139 {
5140     return isCurtainScreenOn_;
5141 }
5142 
GetCurrentSystimeMs() const5143 int64_t RSMainThread::GetCurrentSystimeMs() const
5144 {
5145     auto curTime = std::chrono::system_clock::now().time_since_epoch();
5146     int64_t curSysTime = std::chrono::duration_cast<std::chrono::milliseconds>(curTime).count();
5147     return curSysTime;
5148 }
5149 
GetCurrentSteadyTimeMs() const5150 int64_t RSMainThread::GetCurrentSteadyTimeMs() const
5151 {
5152     auto curTime = std::chrono::steady_clock::now().time_since_epoch();
5153     int64_t curSteadyTime = std::chrono::duration_cast<std::chrono::milliseconds>(curTime).count();
5154     return curSteadyTime;
5155 }
5156 
GetCurrentSteadyTimeMsFloat() const5157 float RSMainThread::GetCurrentSteadyTimeMsFloat() const
5158 {
5159     auto curTime = std::chrono::steady_clock::now().time_since_epoch();
5160     int64_t curSteadyTimeUs = std::chrono::duration_cast<std::chrono::microseconds>(curTime).count();
5161     float curSteadyTime = curSteadyTimeUs / MS_TO_US;
5162     return curSteadyTime;
5163 }
5164 
UpdateLuminanceAndColorTemp()5165 void RSMainThread::UpdateLuminanceAndColorTemp()
5166 {
5167     const std::shared_ptr<RSBaseRenderNode> rootNode = context_->GetGlobalRootRenderNode();
5168     if (rootNode == nullptr) {
5169         return;
5170     }
5171     bool isNeedRefreshAll{false};
5172     if (auto screenManager = CreateOrGetScreenManager()) {
5173         auto& rsLuminance = RSLuminanceControl::Get();
5174         auto& rsColorTemperature = RSColorTemperature::Get();
5175         for (const auto& child : *rootNode->GetSortedChildren()) {
5176             auto screenNode = RSBaseRenderNode::ReinterpretCast<RSScreenRenderNode>(child);
5177             if (screenNode == nullptr) {
5178                 continue;
5179             }
5180             auto screenId = screenNode->GetScreenId();
5181             if (rsLuminance.IsNeedUpdateLuminance(screenId)) {
5182                 uint32_t newLevel = rsLuminance.GetNewHdrLuminance(screenId);
5183                 screenManager->SetScreenBacklight(screenId, newLevel);
5184                 rsLuminance.SetNowHdrLuminance(screenId, newLevel);
5185             }
5186             if (rsLuminance.IsDimmingOn(screenId)) {
5187                 rsLuminance.DimmingIncrease(screenId);
5188                 isNeedRefreshAll = true;
5189                 SetLuminanceChangingStatus(screenId, true);
5190             }
5191             if (rsColorTemperature.IsDimmingOn(screenId)) {
5192                 std::vector<float> matrix = rsColorTemperature.GetNewLinearCct(screenId);
5193                 screenManager->SetScreenLinearMatrix(screenId, matrix);
5194                 rsColorTemperature.DimmingIncrease(screenId);
5195                 isNeedRefreshAll = true;
5196             }
5197         }
5198     }
5199     if (isNeedRefreshAll) {
5200         SetForceUpdateUniRenderFlag(true);
5201         SetDirtyFlag();
5202         RequestNextVSync();
5203     }
5204 }
5205 
RegisterUIExtensionCallback(pid_t pid,uint64_t userId,sptr<RSIUIExtensionCallback> callback,bool unobscured)5206 void RSMainThread::RegisterUIExtensionCallback(pid_t pid, uint64_t userId, sptr<RSIUIExtensionCallback> callback,
5207     bool unobscured)
5208 {
5209     std::lock_guard<std::mutex> lock(uiExtensionMutex_);
5210     RS_LOGI("RegisterUIExtensionCallback for User: %{public}" PRIu64 " PID: %{public}d.", userId, pid);
5211     if (!unobscured) {
5212         uiExtensionListenners_[pid] = std::pair<uint64_t, sptr<RSIUIExtensionCallback>>(userId, callback);
5213     } else {
5214         uiUnobscuredExtensionListenners_[pid] = std::pair<uint64_t, sptr<RSIUIExtensionCallback>>(userId, callback);
5215     }
5216 }
5217 
UnRegisterUIExtensionCallback(pid_t pid)5218 void RSMainThread::UnRegisterUIExtensionCallback(pid_t pid)
5219 {
5220     std::lock_guard<std::mutex> lock(uiExtensionMutex_);
5221     if (uiExtensionListenners_.erase(pid) != 0) {
5222         RS_LOGI("UnRegisterUIExtensionCallback for PID: %{public}d.", pid);
5223     }
5224     if (uiUnobscuredExtensionListenners_.erase(pid) != 0) {
5225         RS_LOGI("UnRegisterUIUnobscuredExtensionCallback for PID: %{public}d.", pid);
5226     }
5227 }
5228 
SetAncoForceDoDirect(bool direct)5229 void RSMainThread::SetAncoForceDoDirect(bool direct)
5230 {
5231     RS_LOGI("SetAncoForceDoDirect %{public}d.", direct);
5232     RSSurfaceRenderNode::SetAncoForceDoDirect(direct);
5233 }
5234 
UIExtensionNodesTraverseAndCallback()5235 void RSMainThread::UIExtensionNodesTraverseAndCallback()
5236 {
5237     std::lock_guard<std::mutex> lock(uiExtensionMutex_);
5238 #ifdef RS_ENABLE_GPU
5239     RSUniRenderUtil::UIExtensionFindAndTraverseAncestor(context_->GetNodeMap(), uiExtensionCallbackData_);
5240     RSUniRenderUtil::UIExtensionFindAndTraverseAncestor(context_->GetNodeMap(), unobscureduiExtensionCallbackData_,
5241         true);
5242 #endif
5243     if (CheckUIExtensionCallbackDataChanged()) {
5244         RS_OPTIONAL_TRACE_NAME_FMT("RSMainThread::UIExtensionNodesTraverseAndCallback data size: [%lu]",
5245             uiExtensionCallbackData_.size());
5246         for (const auto& item : uiExtensionListenners_) {
5247             auto userId = item.second.first;
5248             auto callback = item.second.second;
5249             if (callback) {
5250                 callback->OnUIExtension(std::make_shared<RSUIExtensionData>(uiExtensionCallbackData_), userId);
5251             }
5252         }
5253         for (const auto& item : uiUnobscuredExtensionListenners_) {
5254             auto userId = item.second.first;
5255             auto callback = item.second.second;
5256             if (callback) {
5257                 callback->OnUIExtension(std::make_shared<RSUIExtensionData>(unobscureduiExtensionCallbackData_),
5258                     userId);
5259             }
5260         }
5261     }
5262     lastFrameUIExtensionDataEmpty_ = uiExtensionCallbackData_.empty();
5263     uiExtensionCallbackData_.clear();
5264 }
5265 
CheckUIExtensionCallbackDataChanged() const5266 bool RSMainThread::CheckUIExtensionCallbackDataChanged() const
5267 {
5268     // empty for two consecutive frames, callback can be skipped.
5269     if (uiExtensionCallbackData_.empty()) {
5270         return !lastFrameUIExtensionDataEmpty_;
5271     }
5272     // layout of host node was not changed, callback can be skipped.
5273     const auto& nodeMap = context_->GetNodeMap();
5274     for (const auto& data : uiExtensionCallbackData_) {
5275         auto hostNode = nodeMap.GetRenderNode(data.first);
5276         if (hostNode != nullptr && !hostNode->LastFrameSubTreeSkipped()) {
5277             return true;
5278         }
5279     }
5280     RS_OPTIONAL_TRACE_NAME("RSMainThread::CheckUIExtensionCallbackDataChanged, all host nodes were not changed.");
5281     return false;
5282 }
5283 
RequestNextVSyncInner(VSyncReceiver::FrameCallback callback,const std::string & fromWhom,int64_t lastVSyncTS,const int64_t & requestVsyncTime)5284 void RSMainThread::RequestNextVSyncInner(VSyncReceiver::FrameCallback callback, const std::string& fromWhom,
5285     int64_t lastVSyncTS, const int64_t& requestVsyncTime)
5286 {
5287     if (Rosen::RSSystemProperties::GetTimeVsyncDisabled()) {
5288         receiver_->RequestNextVSync(callback, fromWhom, lastVSyncTS);
5289     } else {
5290         int64_t requestVsyncTimeTmp = 0;
5291         if (requestVsyncTime > 0 && static_cast<uint64_t>(requestVsyncTime) > vsyncRsTimestamp_.load()) {
5292             requestVsyncTimeTmp = requestVsyncTime;
5293         }
5294         receiver_->RequestNextVSync(callback, fromWhom, lastVSyncTS, requestVsyncTimeTmp);
5295     }
5296 }
5297 
SetHardwareTaskNum(uint32_t num)5298 void RSMainThread::SetHardwareTaskNum(uint32_t num)
5299 {
5300     rsVSyncDistributor_->SetHardwareTaskNum(num);
5301 }
5302 
GetRealTimeOffsetOfDvsync(int64_t time)5303 uint64_t RSMainThread::GetRealTimeOffsetOfDvsync(int64_t time)
5304 {
5305     return rsVSyncDistributor_->GetRealTimeOffsetOfDvsync(time);
5306 }
5307 
SetFrameInfo(uint64_t frameCount,bool forceRefreshFlag)5308 void RSMainThread::SetFrameInfo(uint64_t frameCount, bool forceRefreshFlag)
5309 {
5310     // use the same function as vsync to get current time
5311     int64_t currentTimestamp = SystemTime();
5312     auto &hgmCore = HgmCore::Instance();
5313     hgmCore.SetActualTimestamp(currentTimestamp);
5314     hgmCore.SetVsyncId(frameCount);
5315 
5316     auto &frameDeadline = RsFrameDeadlinePredict::GetInstance();
5317     frameDeadline.ReportRsFrameDeadline(hgmCore, forceRefreshFlag);
5318 }
5319 
MultiDisplayChange(bool isMultiDisplay)5320 void RSMainThread::MultiDisplayChange(bool isMultiDisplay)
5321 {
5322     if (isMultiDisplay == isMultiDisplayPre_) {
5323         isMultiDisplayChange_ = false;
5324         return;
5325     }
5326     isMultiDisplayChange_ = true;
5327     isMultiDisplayPre_ = isMultiDisplay;
5328 }
5329 
HandleTouchEvent(int32_t touchStatus,int32_t touchCnt)5330 void RSMainThread::HandleTouchEvent(int32_t touchStatus, int32_t touchCnt)
5331 {
5332     rsVSyncDistributor_->HandleTouchEvent(touchStatus, touchCnt);
5333 }
5334 
SetBufferInfo(uint64_t id,const std::string & name,uint32_t queueSize,int32_t bufferCount,int64_t lastConsumeTime,bool isUrgent)5335 void RSMainThread::SetBufferInfo(uint64_t id, const std::string &name, uint32_t queueSize,
5336     int32_t bufferCount, int64_t lastConsumeTime, bool isUrgent)
5337 {
5338     rsVSyncDistributor_->SetBufferInfo(id, name, queueSize, bufferCount, lastConsumeTime, isUrgent);
5339 }
5340 
NotifyPackageEvent(const std::vector<std::string> & packageList)5341 void RSMainThread::NotifyPackageEvent(const std::vector<std::string>& packageList)
5342 {
5343     rsVSyncDistributor_->NotifyPackageEvent(packageList);
5344 }
5345 
SetTaskEndWithTime(int64_t time)5346 void RSMainThread::SetTaskEndWithTime(int64_t time)
5347 {
5348     rsVSyncDistributor_->SetTaskEndWithTime(time);
5349 }
5350 
OnFmtTraceSwitchCallback(const char * key,const char * value,void * context)5351 void RSMainThread::OnFmtTraceSwitchCallback(const char *key, const char *value, void *context)
5352 {
5353     if (strcmp(key, ENABLE_DEBUG_FMT_TRACE) != 0) {
5354         return;
5355     }
5356     bool isTraceEnable = (std::atoi(value) != 0);
5357     RSSystemProperties::SetDebugFmtTraceEnabled(isTraceEnable);
5358 }
5359 
RegisterScreenNodeListener()5360 void RSMainThread::RegisterScreenNodeListener()
5361 {
5362     auto screenManager = CreateOrGetScreenManager();
5363     if (!screenManager) {
5364         RS_LOGE("%{public}s failed: screenManager is null.", __func__);
5365         return;
5366     }
5367 
5368     screenManager->RegisterScreenNodeListener(std::make_shared<RSScreenNodeListener>());
5369 }
5370 
OnScreenConnect(ScreenId id)5371 void RSMainThread::RSScreenNodeListener::OnScreenConnect(ScreenId id)
5372 {
5373     auto mainThread = RSMainThread::Instance();
5374     auto task = [context = mainThread->context_, id]() {
5375         auto& nodeMap = context->GetMutableNodeMap();
5376         auto node = std::shared_ptr<RSScreenRenderNode>(new RSScreenRenderNode(GenerateUniqueNodeIdForRS(),
5377             id, context->weak_from_this()), RSRenderNodeGC::NodeDestructor);
5378         nodeMap.RegisterRenderNode(node);
5379         context->GetGlobalRootRenderNode()->AddChild(node);
5380 
5381         auto setOnTree = [id, context] (auto& node) {
5382             bool isConditionMet = node && node->GetScreenId() == id &&
5383                 !node->IsOnTheTree() && node->IsWaitToSetOnTree();
5384             if (isConditionMet) {
5385                 DisplayNodeCommandHelper::AddDisplayNodeToTree(*context, node->GetId());
5386             }
5387         };
5388         nodeMap.TraverseLogicalDisplayNodes(setOnTree);
5389     };
5390     if (mainThread->isRunning_) {
5391         mainThread->PostTask(task);
5392     } else {
5393         task();
5394     }
5395 }
5396 
OnScreenDisconnect(ScreenId id)5397 void RSMainThread::RSScreenNodeListener::OnScreenDisconnect(ScreenId id)
5398 {
5399     auto mainThread = RSMainThread::Instance();
5400     auto task = [context = mainThread->context_, id]() {
5401         std::shared_ptr<RSScreenRenderNode> screenNode = nullptr;
5402         auto& nodeMap = context->GetMutableNodeMap();
5403         nodeMap.TraverseScreenNodes(
5404             [id, &screenNode](const std::shared_ptr<RSScreenRenderNode>& node) {
5405             if (node && node->GetScreenId() == id) {
5406                 screenNode = node;
5407             }
5408         });
5409         if (screenNode == nullptr) {
5410             return;
5411         }
5412         screenNode->ResetMirrorSource();
5413         context->GetGlobalRootRenderNode()->RemoveChild(screenNode);
5414         nodeMap.UnregisterRenderNode(screenNode->GetId());
5415     };
5416 
5417     mainThread->PostTask(task);
5418 }
5419 
HandleTunnelLayerId(const std::shared_ptr<RSSurfaceHandler> & surfaceHandler,const std::shared_ptr<RSSurfaceRenderNode> & surfaceNode)5420 void RSMainThread::HandleTunnelLayerId(const std::shared_ptr<RSSurfaceHandler>& surfaceHandler,
5421     const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode)
5422 {
5423     if (surfaceHandler == nullptr || surfaceNode == nullptr) {
5424         RS_LOGI("%{public}s surfaceHandler or surfaceNode is null", __func__);
5425         return;
5426     }
5427 
5428     if (surfaceHandler->GetSourceType() !=
5429         static_cast<uint32_t>(OHSurfaceSource::OH_SURFACE_SOURCE_LOWPOWERVIDEO)) {
5430         surfaceNode->SetTunnelLayerId(0);
5431         return;
5432     }
5433 
5434     auto consumer = surfaceHandler->GetConsumer();
5435     if (consumer == nullptr) {
5436         RS_LOGI("%{public}s consumer is null", __func__);
5437         return;
5438     }
5439 
5440     uint64_t currentTunnelLayerId = surfaceNode->GetTunnelLayerId();
5441     uint64_t newTunnelLayerId = consumer->GetUniqueId();
5442     if (currentTunnelLayerId == newTunnelLayerId) {
5443         return;
5444     }
5445 
5446     surfaceNode->SetTunnelLayerId(newTunnelLayerId);
5447     RS_LOGI("%{public}s lpp surfaceid:%{public}" PRIu64, __func__, newTunnelLayerId);
5448     RS_TRACE_NAME_FMT("%s lpp surfaceid=%" PRIu64, __func__, newTunnelLayerId);
5449 }
5450 
DVSyncUpdate(uint64_t dvsyncTime,uint64_t vsyncTime)5451 void RSMainThread::DVSyncUpdate(uint64_t dvsyncTime, uint64_t vsyncTime)
5452 {
5453     rsVSyncDistributor_->DVSyncUpdate(dvsyncTime, vsyncTime);
5454 }
5455 
SetForceRsDVsync(const std::string & sceneId)5456 void RSMainThread::SetForceRsDVsync(const std::string& sceneId)
5457 {
5458     if (rsVSyncDistributor_ != nullptr) {
5459         RS_TRACE_NAME("RSMainThread::SetForceRsDVsync");
5460         rsVSyncDistributor_->ForceRsDVsync(sceneId);
5461     }
5462 }
5463 } // namespace Rosen
5464 } // namespace OHOS
5465