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