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