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