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