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