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