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