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