1 /*
2 * Copyright (c) 2022 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 #include "pipeline/main_thread/rs_uni_render_visitor.h"
17 #include <memory>
18 #include "rs_trace.h"
19 #include "screen_manager/rs_screen_manager.h"
20
21 #include "common/rs_common_def.h"
22 #include "common/rs_common_hook.h"
23 #include "common/rs_obj_abs_geometry.h"
24 #include "common/rs_optional_trace.h"
25 #include "common/rs_singleton.h"
26 #include "feature/dirty/rs_uni_dirty_compute_util.h"
27 #include "feature/hwc/rs_uni_hwc_compute_util.h"
28 #include "feature/occlusion_culling/rs_occlusion_handler.h"
29 #ifdef RS_ENABLE_OVERLAY_DISPLAY
30 #include "feature/overlay_display/rs_overlay_display_manager.h"
31 #endif
32 #include "common/rs_special_layer_manager.h"
33 #include "display_engine/rs_luminance_control.h"
34 #include "feature/drm/rs_drm_util.h"
35 #include "feature/opinc/rs_opinc_cache.h"
36 #include "feature/opinc/rs_opinc_manager.h"
37 #include "feature/hpae/rs_hpae_manager.h"
38 #include "feature/uifirst/rs_sub_thread_manager.h"
39 #include "feature/uifirst/rs_uifirst_manager.h"
40 #include "feature/hdr/rs_hdr_util.h"
41 #include "memory/rs_tag_tracker.h"
42 #include "monitor/self_drawing_node_monitor.h"
43 #include "params/rs_screen_render_params.h"
44 #include "pipeline/render_thread/rs_base_render_util.h"
45 #include "pipeline/render_thread/rs_uni_render_util.h"
46 #include "pipeline/render_thread/rs_uni_render_virtual_processor.h"
47 #include "pipeline/rs_base_render_node.h"
48 #include "pipeline/rs_screen_render_node.h"
49 #include "pipeline/rs_effect_render_node.h"
50 #include "pipeline/rs_logical_display_render_node.h"
51 #include "pipeline/rs_paint_filter_canvas.h"
52 #include "pipeline/rs_pointer_window_manager.h"
53 #include "pipeline/hardware_thread/rs_realtime_refresh_rate_manager.h"
54 #include "pipeline/rs_root_render_node.h"
55 #include "pipeline/rs_surface_render_node.h"
56 #include "pipeline/hwc/rs_uni_hwc_visitor.h"
57 #include "platform/common/rs_log.h"
58 #include "platform/common/rs_system_properties.h"
59 #include "property/rs_properties_painter.h"
60 #include "render/rs_effect_luminance_manager.h"
61 #include "system/rs_system_parameters.h"
62 #include "hgm_core.h"
63 #include "metadata_helper.h"
64 #include <v1_0/buffer_handle_meta_key_type.h>
65 #include <v1_0/cm_color_space.h>
66
67 #include "feature_cfg/graphic_feature_param_manager.h"
68 #include "feature/round_corner_display/rs_round_corner_display_manager.h"
69 #include "feature/round_corner_display/rs_message_bus.h"
70
71 #include "rs_profiler.h"
72 #ifdef SUBTREE_PARALLEL_ENABLE
73 #include "rs_parallel_manager.h"
74 #endif
75
76 #ifdef RS_PROFILER_ENABLED
77 #include "rs_profiler_capture_recorder.h"
78 #endif
79
80 // blur predict
81 #include "rs_frame_blur_predict.h"
82
83 #undef LOG_TAG
84 #define LOG_TAG "RSUniRenderVisitor"
85
86 namespace OHOS {
87 namespace Rosen {
88 namespace {
89 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
90 constexpr int EXPAND_ONE_PIX = 1;
91 constexpr int MAX_ALPHA = 255;
92 constexpr int TRACE_LEVEL_THREE = 3;
93 constexpr float EPSILON_SCALE = 0.00001f;
94 static const std::string CAPTURE_WINDOW_NAME = "CapsuleWindow";
95 constexpr uint64_t INPUT_HWC_LAYERS = 3;
96 constexpr int TRACE_LEVEL_PRINT_NODEID = 6;
97
CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)98 bool CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
99 {
100 if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
101 auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
102 const auto& property = rootNode->GetRenderProperties();
103 if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
104 return true;
105 }
106 }
107 return false;
108 }
109
CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)110 bool CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
111 {
112 if (child != nullptr && child->IsInstanceOf<RSCanvasRenderNode>()) {
113 auto canvasRenderNode = child->ReinterpretCastTo<RSCanvasRenderNode>();
114 const auto& property = canvasRenderNode->GetRenderProperties();
115 if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0) {
116 return true;
117 }
118 }
119 return false;
120 }
121
IsFirstFrameReadyToDraw(const RSSurfaceRenderNode & node)122 bool IsFirstFrameReadyToDraw(const RSSurfaceRenderNode& node)
123 {
124 bool result = false;
125 auto sortedChildren = node.GetSortedChildren();
126 if (node.IsScbScreen()) {
127 for (const auto& child : *sortedChildren) {
128 result = CheckScbReadyToDraw(child);
129 }
130 return result;
131 }
132 for (auto& child : *sortedChildren) {
133 result = CheckRootNodeReadyToDraw(child);
134 // when appWindow has abilityComponent node
135 if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>()) {
136 for (const auto& surfaceNodeChild : *child->GetSortedChildren()) {
137 result = CheckRootNodeReadyToDraw(surfaceNodeChild);
138 }
139 }
140 }
141 return result;
142 }
143
VisibleDataToString(const VisibleData & val)144 std::string VisibleDataToString(const VisibleData& val)
145 {
146 std::stringstream ss;
147 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
148 for (const auto& v : val) {
149 auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(v.first);
150 auto name = surfaceNode ? surfaceNode->GetName() : "";
151 ss << "[" << name << ", " << v.first << ", " << v.second << "], ";
152 }
153 return ss.str();
154 }
155
156 } // namespace
157
158 bool RSUniRenderVisitor::isLastFrameRotating_ = false;
159
RSUniRenderVisitor()160 RSUniRenderVisitor::RSUniRenderVisitor()
161 : hwcVisitor_(std::make_unique<RSUniHwcVisitor>(*this)),
162 curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
163 {
164 PartialRenderOptionInit();
165 auto mainThread = RSMainThread::Instance();
166 renderEngine_ = mainThread->GetRenderEngine();
167 hasMirrorDisplay_ = mainThread->HasMirrorDisplay();
168 // when occlusion enabled is false, subTree do not skip, but not influence visible region
169 isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
170 isDrawingCacheEnabled_ = RSSystemParameters::GetDrawingCacheEnabled();
171 RSTagTracker::UpdateReleaseResourceEnabled(RSSystemProperties::GetReleaseResourceEnabled());
172 #ifdef DDGR_ENABLE_FEATURE_OPINC
173 autoCacheEnable_ = RSOpincManager::Instance().GetOPIncSwitch();
174 #endif
175 isScreenRotationAnimating_ = RSSystemProperties::GetCacheEnabledForRotation();
176 isFirstFrameAfterScreenRotation_ = !isScreenRotationAnimating_ && isLastFrameRotating_;
177 isLastFrameRotating_ = isScreenRotationAnimating_;
178 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
179 if (renderEngine_ && renderEngine_->GetRenderContext()) {
180 auto subThreadManager = RSSubThreadManager::Instance();
181 subThreadManager->Start(renderEngine_->GetRenderContext().get());
182 }
183 #endif
184 isUIFirstDebugEnable_ = RSSystemProperties::GetUIFirstDebugEnabled();
185 isCrossNodeOffscreenOn_ = RSSystemProperties::GetCrossNodeOffScreenStatus();
186 isDumpRsTreeDetailEnabled_ = RSSystemProperties::GetDumpRsTreeDetailEnabled();
187 screenManager_ = CreateOrGetScreenManager();
188 }
189
~RSUniRenderVisitor()190 RSUniRenderVisitor::~RSUniRenderVisitor() {}
191
PartialRenderOptionInit()192 void RSUniRenderVisitor::PartialRenderOptionInit()
193 {
194 isPartialRenderEnabled_ = DirtyRegionParam::IsDirtyRegionEnable();
195 isAdvancedDirtyRegionEnabled_ = DirtyRegionParam::IsAdvancedDirtyRegionEnable();
196 isDirtyAlignEnabled_ = DirtyRegionParam::IsTileBasedAlignEnable();
197
198 if (RSSystemProperties::GetStencilPixelOcclusionCullingEnabled() == StencilPixelOcclusionCullingType::DEFAULT) {
199 isStencilPixelOcclusionCullingEnabled_ =
200 OcclusionCullingParam::IsStencilPixelOcclusionCullingEnable();
201 } else {
202 isStencilPixelOcclusionCullingEnabled_ =
203 RSSystemProperties::GetStencilPixelOcclusionCullingEnabled() != StencilPixelOcclusionCullingType::DISABLED;
204 }
205
206 partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
207 isPartialRenderEnabled_ &= (partialRenderType_ > PartialRenderType::DISABLED);
208
209 isCompleteRenderEnabled_ = (partialRenderType_ == PartialRenderType::SET_DAMAGE_BUT_COMPLETE_RENDER);
210 dirtyRegionDebugType_ = RSSystemProperties::GetDirtyRegionDebugType();
211 surfaceRegionDebugType_ = RSSystemProperties::GetSurfaceRegionDfxType();
212 isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_) &&
213 (surfaceRegionDebugType_ == SurfaceRegionDebugType::DISABLED);
214 isTargetUIFirstDfxEnabled_ = RSSystemProperties::GetTargetUIFirstDfxEnabled(dfxUIFirstSurfaceNames_);
215 isRegionDebugEnabled_ = (dirtyRegionDebugType_ != DirtyRegionDebugType::DISABLED) ||
216 (surfaceRegionDebugType_ != SurfaceRegionDebugType::DISABLED) || (dfxTargetSurfaceNames_.size() > 0);
217 isVisibleRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::VISIBLE_REGION);
218 isOpaqueRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::OPAQUE_REGION);
219 isAllSurfaceVisibleDebugEnabled_ = RSSystemProperties::GetAllSurfaceVisibleDebugEnabled();
220 isDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
221 (dirtyRegionDebugType_ == DirtyRegionDebugType::EGL_DAMAGE);
222 isDisplayDirtyDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
223 (dirtyRegionDebugType_ == DirtyRegionDebugType::DISPLAY_DIRTY);
224 isMergedDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
225 (dirtyRegionDebugType_ == DirtyRegionDebugType::MERGED_DIRTY);
226 isOpDropped_ = isPartialRenderEnabled_ &&
227 (partialRenderType_ != PartialRenderType::SET_DAMAGE) && !isRegionDebugEnabled_;
228 isVirtualDirtyDfxEnabled_ = RSSystemProperties::GetVirtualDirtyDebugEnabled();
229 isVirtualDirtyEnabled_ = RSSystemProperties::GetVirtualDirtyEnabled() &&
230 (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) && !isRegionDebugEnabled_;
231 isExpandScreenDirtyEnabled_ = RSSystemProperties::GetExpandScreenDirtyEnabled();
232 advancedDirtyType_ = isAdvancedDirtyRegionEnabled_ ?
233 RSSystemProperties::GetAdvancedDirtyRegionEnabled() : AdvancedDirtyRegionType::DISABLED;
234 isDirtyAlignEnabled_ &= RSSystemProperties::GetDirtyAlignEnabled() != DirtyAlignType::DISABLED;
235 if (isStencilPixelOcclusionCullingEnabled_) {
236 // SPOC relies on dirty region alignment; when SPOC is enabled, dirty region alignment must also be enabled
237 isDirtyAlignEnabled_ = true;
238 }
239 }
240
MergeRemovedChildDirtyRegion(RSRenderNode & node,bool needMap)241 void RSUniRenderVisitor::MergeRemovedChildDirtyRegion(RSRenderNode& node, bool needMap)
242 {
243 RectI dirtyRect = RSSystemProperties::GetOptimizeParentNodeRegionEnabled() ?
244 node.GetRemovedChildrenRect() : node.GetChildrenRect();
245 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curScreenDirtyManager_;
246 if (dirtyManager == nullptr || dirtyRect.IsEmpty()) {
247 node.ResetHasRemovedChild();
248 return;
249 }
250
251 // [planning] merge removed child's rect instead
252 if (needMap) {
253 if (auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry()) {
254 dirtyRect = geoPtr->MapRect(dirtyRect.ConvertTo<float>(), node.GetOldAbsMatrix());
255 }
256 if (!node.HasChildrenOutOfRect()) {
257 dirtyRect = dirtyRect.IntersectRect(node.GetOldClipRect());
258 }
259 } else {
260 dirtyRect = prepareClipRect_.IntersectRect(node.GetChildrenRect());
261 }
262 dirtyManager->MergeDirtyRect(dirtyRect);
263 RS_OPTIONAL_TRACE_NAME_FMT("MergeRemovedChildDirtyRegion NodeId:%" PRIu64 ", dirty rect:%s",
264 node.GetId(), dirtyRect.ToString().c_str());
265 if (dirtyManager->IsTargetForDfx()) {
266 // since childRect includes multiple rects, defaultly marked as canvas_node
267 dirtyManager->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
268 DirtyRegionType::REMOVE_CHILD_RECT, dirtyRect);
269 }
270 node.ResetHasRemovedChild();
271 }
272
CheckColorSpace(RSSurfaceRenderNode & node)273 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
274 {
275 if (!node.IsAppWindow()) {
276 return;
277 }
278 if (!curScreenNode_) {
279 RS_LOGD("CheckColorSpace: curScreenNode_ is nullptr");
280 return;
281 }
282 GraphicColorGamut gamut = node.GetColorSpace();
283 if (gamut != GRAPHIC_COLOR_GAMUT_SRGB) {
284 curScreenNode_->UpdateColorSpace(gamut);
285 RS_LOGD("CheckColorSpace: node(%{public}s) set new colorgamut %{public}d",
286 node.GetName().c_str(), static_cast<int>(gamut));
287 }
288 }
289
CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode & node)290 void RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode& node)
291 {
292 if (!node.IsOnTheTree()) {
293 RS_LOGD("CheckColorSpaceWithSelfDrawingNode node(%{public}s) is not on the tree",
294 node.GetName().c_str());
295 return;
296 }
297 if (!node.IsHardwareForcedDisabled()) {
298 RS_LOGD("CheckColorSpaceWithSelfDrawingNode node(%{public}s) is hardware-enabled",
299 node.GetName().c_str());
300 return;
301 }
302 if (curScreenNode_ == nullptr) {
303 RS_LOGD("CheckColorSpaceWithSelfDrawingNode curScreenNode_ is nullptr");
304 return;
305 }
306 // currently, P3 is the only supported wide color gamut, this may be modified later.
307 node.UpdateColorSpaceWithMetadata();
308 auto appSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetInstanceRootNode());
309 if (ColorGamutParam::SkipOccludedNodeDuringColorGamutCollection() && appSurfaceNode
310 && appSurfaceNode->IsMainWindowType() && appSurfaceNode->GetVisibleRegion().IsEmpty() && GetIsOpDropped()) {
311 RS_LOGD("CheckColorSpaceWithSelfDrawingNode node(%{public}s) failed to set new color "
312 "gamut because the window is blocked", node.GetName().c_str());
313 return;
314 }
315
316 GraphicColorGamut gamut = node.GetColorSpace();
317 if (gamut != GRAPHIC_COLOR_GAMUT_SRGB) {
318 curScreenNode_->UpdateColorSpace(gamut);
319 RS_LOGD("CheckColorSpaceWithSelfDrawingNode node(%{public}s) set new colorgamut %{public}d",
320 node.GetName().c_str(), static_cast<int>(gamut));
321 }
322 }
323
UpdateColorSpaceAfterHwcCalc(RSScreenRenderNode & node)324 void RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc(RSScreenRenderNode& node)
325 {
326 auto colorSpace = node.GetColorSpace();
327 const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
328 for (const auto& selfDrawingNode : selfDrawingNodes) {
329 if (!selfDrawingNode) {
330 RS_LOGD("UpdateColorSpaceAfterHwcCalc selfDrawingNode is nullptr");
331 continue;
332 }
333 auto ancestorNode = selfDrawingNode->GetAncestorScreenNode().lock();
334 if (!ancestorNode) {
335 RS_LOGD("UpdateColorSpaceAfterHwcCalc ancestorNode is nullptr");
336 continue;
337 }
338 auto ancestorScreenNode = ancestorNode->ReinterpretCastTo<RSScreenRenderNode>();
339 if (ancestorScreenNode != nullptr && node.GetId() == ancestorScreenNode->GetId()) {
340 CheckColorSpaceWithSelfDrawingNode(*selfDrawingNode);
341 }
342 }
343 }
344
IsScreenSupportedWideColorGamut(ScreenId id,const sptr<RSScreenManager> & screenManager)345 bool IsScreenSupportedWideColorGamut(ScreenId id, const sptr<RSScreenManager>& screenManager)
346 {
347 std::vector<ScreenColorGamut> supportedColorGamut;
348 if (screenManager->GetScreenSupportedColorGamuts(id, supportedColorGamut) != SUCCESS) {
349 return false;
350 }
351 for (auto item : supportedColorGamut) {
352 if (item == ScreenColorGamut::COLOR_GAMUT_DCI_P3 || item == ScreenColorGamut::COLOR_GAMUT_DISPLAY_P3) {
353 return true;
354 }
355 }
356 return false;
357 }
358
HandleColorGamuts(RSScreenRenderNode & node)359 void RSUniRenderVisitor::HandleColorGamuts(RSScreenRenderNode& node)
360 {
361 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
362 if (screenManager_->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
363 RS_LOGD("HandleColorGamuts get screen type failed.");
364 return;
365 }
366
367 if (screenType == VIRTUAL_TYPE_SCREEN) {
368 ScreenColorGamut screenColorGamut;
369 if (screenManager_->GetScreenColorGamut(node.GetScreenId(), screenColorGamut) != SUCCESS) {
370 RS_LOGD("HandleColorGamuts get screen color gamut failed.");
371 return;
372 }
373 node.SetColorSpace(static_cast<GraphicColorGamut>(screenColorGamut));
374 return;
375 } else if (ColorGamutParam::DisableP3OnWiredExtendedScreen() &&
376 !RSMainThread::Instance()->HasWiredMirrorDisplay() && node.GetScreenId() != 0) {
377 // Current PC external screen do not support P3.
378 // The wired extended screen is fixed to sRGB color space.
379 node.SetColorSpace(GRAPHIC_COLOR_GAMUT_SRGB);
380 return;
381 }
382 std::vector<ScreenColorGamut> mode;
383 int32_t ret = screenManager_->GetScreenSupportedColorGamuts(node.GetScreenId(), mode);
384 if (ret != SUCCESS) {
385 RS_LOGD("HandleColorGamuts GetScreenSupportedColorGamuts failed, ret=%{public}d", ret);
386 mode = std::vector<ScreenColorGamut>{GRAPHIC_COLOR_GAMUT_SRGB};
387 }
388 node.SelectBestGamut(mode);
389
390 if (RSMainThread::Instance()->HasWiredMirrorDisplay() && !MultiScreenParam::IsMirrorDisplayCloseP3()) {
391 std::shared_ptr<RSScreenRenderNode> mirrorNode = node.GetMirrorSource().lock();
392 if (!mirrorNode) {
393 return;
394 }
395 std::vector<ScreenColorGamut> mode;
396 int32_t ret = screenManager_->GetScreenSupportedColorGamuts(node.GetScreenId(), mode);
397 if (ret != SUCCESS) {
398 RS_LOGD("HandleColorGamuts GetScreenSupportedColorGamuts failed, errorCode=%{public}d",
399 ret);
400 return;
401 }
402 bool isSupportedDisplayP3 =
403 std::any_of(mode.begin(), mode.end(), [](const auto& gamut) { return gamut == COLOR_GAMUT_DISPLAY_P3; });
404 if (isSupportedDisplayP3) {
405 // wired mirror and mirror support P3, mirror gamut = main gamut
406 node.SetColorSpace(mirrorNode->GetColorSpace());
407 }
408 }
409 }
410
CheckPixelFormat(RSSurfaceRenderNode & node)411 void RSUniRenderVisitor::CheckPixelFormat(RSSurfaceRenderNode& node)
412 {
413 if (hasFingerprint_) {
414 RS_LOGD("CheckPixelFormat hasFingerprint is true.");
415 return;
416 }
417 if (!curScreenNode_) {
418 RS_LOGE("CheckPixelFormat curScreenNode is null");
419 return;
420 }
421 if (node.GetFingerprint()) {
422 hasFingerprint_ = true;
423 curScreenNode_->SetPixelFormat(GRAPHIC_PIXEL_FMT_RGBA_1010102);
424 RS_LOGD("CheckPixelFormat newPixelFormate_ is set 1010102 for fingerprint.");
425 return;
426 }
427 if (!RSSystemProperties::GetHdrImageEnabled()) {
428 RS_LOGD("CheckPixelFormat HdrImageEnabled false");
429 return;
430 }
431 if (curScreenNode_->GetForceCloseHdr()) {
432 RS_LOGD("CheckPixelFormat curScreenNode_ forceclosehdr.");
433 return;
434 }
435 if (node.GetHDRPresent() || node.IsHdrEffectColorGamut()) {
436 RS_LOGD("CheckPixelFormat HDRService SetHDRPresent true, surfaceNode: %{public}" PRIu64 "",
437 node.GetId());
438 curScreenNode_->SetHasUniRenderHdrSurface(true);
439 if (node.GetHDRPresent()) {
440 curScreenNode_->CollectHdrStatus(HdrStatus::HDR_PHOTO);
441 }
442 if (node.IsHdrEffectColorGamut()) {
443 curScreenNode_->CollectHdrStatus(HdrStatus::HDR_EFFECT);
444 }
445 RSHdrUtil::SetHDRParam(*curScreenNode_, node, true);
446 }
447 }
448
HandlePixelFormat(RSScreenRenderNode & node)449 void RSUniRenderVisitor::HandlePixelFormat(RSScreenRenderNode& node)
450 {
451 if (!curScreenNode_) {
452 RS_LOGE("HandlePixelFormat curScreenNode is null");
453 return;
454 }
455 SetHdrWhenMultiDisplayChange();
456 RS_LOGD("HDRSwitch isHdrImageEnabled: %{public}d, isHdrVideoEnabled: %{public}d",
457 RSSystemProperties::GetHdrImageEnabled(), RSSystemProperties::GetHdrVideoEnabled());
458 ScreenId screenId = node.GetScreenId();
459 bool hasUniRenderHdrSurface = node.GetHasUniRenderHdrSurface();
460 if ((RSLuminanceControl::Get().IsCloseHardwareHdr() && !drmNodes_.empty()) || node.GetForceCloseHdr()) {
461 // Disable hdr when drm videos exist to avoid flicker
462 RSLuminanceControl::Get().SetHdrStatus(screenId, HdrStatus::NO_HDR);
463 } else {
464 RSLuminanceControl::Get().SetHdrStatus(screenId, node.GetDisplayHdrStatus());
465 }
466 bool isHdrOn = RSLuminanceControl::Get().IsHdrOn(screenId);
467 rsHdrCollection_->HandleHdrState(isHdrOn);
468 float brightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0);
469 float displayHeadroom =
470 RSLuminanceControl::Get().GetDisplayNits(screenId) / RSLuminanceControl::Get().GetSdrDisplayNits(screenId);
471 RSEffectLuminanceManager::GetInstance().SetDisplayHeadroom(node.GetScreenNodeId(), displayHeadroom);
472 RS_TRACE_NAME_FMT("HDR:%d, in Unirender:%d, brightnessRatio:%f, screenId:%" PRIu64 ", status:%d", isHdrOn,
473 hasUniRenderHdrSurface, brightnessRatio, screenId, node.GetDisplayHdrStatus());
474 RS_LOGD("HandlePixelFormat HDRService isHdrOn:%{public}d hasUniRenderHdrSurface:%{public}d "
475 "brightnessRatio:%{public}f screenId:%{public}" PRIu64 " status:%{public}d", isHdrOn, hasUniRenderHdrSurface,
476 brightnessRatio, screenId, node.GetDisplayHdrStatus());
477 if ((!hasUniRenderHdrSurface && !RSLuminanceControl::Get().IsCloseHardwareHdr()) || node.GetForceCloseHdr()) {
478 isHdrOn = false;
479 }
480 node.SetHDRPresent(isHdrOn);
481 hasDisplayHdrOn_ |= isHdrOn;
482 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
483 if (screenManager_->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
484 RS_LOGD("HandlePixelFormat get screen type failed.");
485 return;
486 }
487
488 RSHdrUtil::HandleVirtualScreenHDRStatus(node, screenManager_);
489
490 if (screenType == VIRTUAL_TYPE_SCREEN) {
491 auto pixelFormat = node.GetPixelFormat();
492 if (screenManager_->GetPixelFormat(node.GetScreenId(), pixelFormat) != SUCCESS) {
493 RS_LOGD("HandlePixelFormat get screen color gamut failed.");
494 } else {
495 node.SetPixelFormat(pixelFormat);
496 }
497 }
498 }
499
ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode & node)500 void RSUniRenderVisitor::ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode& node)
501 {
502 // record current frame mainwindow or leashwindow node
503 if (node.IsMainWindowType() || node.IsLeashWindow()) {
504 curMainAndLeashWindowNodesIds_.push(node.GetId());
505 RSMainThread::Instance()->GetRSVsyncRateReduceManager().PushWindowNodeId(node.GetId());
506 curScreenNode_->RecordMainAndLeashSurfaces(node.shared_from_this());
507 }
508 // only reset for instance node
509 if (curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetId()) {
510 return;
511 }
512 if (auto directParent = node.GetParent().lock()) {
513 if (auto parentInstance = directParent->GetInstanceRootNode()) {
514 // in case leashwindow is not directParent
515 auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
516 if (surfaceParent && (surfaceParent->IsLeashOrMainWindow())) {
517 curSurfaceNode_ = surfaceParent;
518 curSurfaceDirtyManager_ = surfaceParent->GetDirtyManager();
519 filterInGlobal_ = surfaceParent->IsTransparent();
520 return;
521 }
522 curSurfaceNode_ = nullptr;
523 curSurfaceDirtyManager_ = nullptr;
524 filterInGlobal_ = true;
525 }
526 }
527 }
528
IsHardwareComposerEnabled()529 bool RSUniRenderVisitor::IsHardwareComposerEnabled()
530 {
531 return !hwcVisitor_->isHardwareForcedDisabled_;
532 }
533
MarkHardwareForcedDisabled()534 void RSUniRenderVisitor::MarkHardwareForcedDisabled()
535 {
536 hwcVisitor_->isHardwareForcedDisabled_ = true;
537 }
538
DealWithSpecialLayer(RSSurfaceRenderNode & node)539 void RSUniRenderVisitor::DealWithSpecialLayer(RSSurfaceRenderNode& node)
540 {
541 if (node.IsCloneCrossNode()) {
542 auto sourceNode = node.GetSourceCrossNode().lock();
543 auto sourceSurface = sourceNode ? sourceNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
544 if (sourceSurface == nullptr) {
545 return;
546 }
547 UpdateSpecialLayersRecord(*sourceSurface);
548 } else {
549 UpdateSpecialLayersRecord(node);
550 }
551 UpdateBlackListRecord(node);
552 node.UpdateVirtualScreenWhiteListInfo(screenWhiteList_);
553 }
554
UpdateBlackListRecord(RSSurfaceRenderNode & node)555 void RSUniRenderVisitor::UpdateBlackListRecord(RSSurfaceRenderNode& node)
556 {
557 if (!hasMirrorDisplay_ || !screenManager_) {
558 return;
559 }
560 std::unordered_set<uint64_t> virtualScreens = screenManager_->GetBlackListVirtualScreenByNode(node.GetId());
561 if (node.IsLeashWindow()) {
562 const auto& leashVirtualScreens = screenManager_->GetBlackListVirtualScreenByNode(node.GetLeashPersistentId());
563 virtualScreens.insert(leashVirtualScreens.begin(), leashVirtualScreens.end());
564 }
565 if (virtualScreens.empty()) {
566 node.UpdateBlackListStatus(INVALID_SCREEN_ID, false);
567 return;
568 }
569 for (const auto& screenId : virtualScreens) {
570 node.UpdateBlackListStatus(screenId, true);
571 }
572 }
573
UpdateSpecialLayersRecord(RSSurfaceRenderNode & node)574 void RSUniRenderVisitor::UpdateSpecialLayersRecord(RSSurfaceRenderNode& node)
575 {
576 if (node.ShouldPaint() == false) {
577 return;
578 }
579 auto specialLayerMgr = node.GetMultableSpecialLayerMgr();
580 if (specialLayerMgr.Find(SpecialLayerType::HAS_SECURITY)) {
581 curLogicalDisplayNode_->AddSecurityLayer(node.IsLeashWindow() ? node.GetLeashPersistentId() : node.GetId());
582 curLogicalDisplayNode_->AddSecurityVisibleLayer(node.GetId());
583 }
584 if (specialLayerMgr.Find(SpecialLayerType::HAS_PROTECTED)) {
585 screenManager_->SetScreenHasProtectedLayer(curLogicalDisplayNode_->GetScreenId(), true);
586 RS_TRACE_NAME_FMT("SetScreenHasProtectedLayer: %d", curLogicalDisplayNode_->GetScreenId());
587 }
588 auto specialLayerType = specialLayerMgr.Get();
589 if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
590 specialLayerType &= ~SpecialLayerType::HAS_SKIP;
591 }
592 curLogicalDisplayNode_->GetMultableSpecialLayerMgr().AddIds((specialLayerType >> SPECIAL_TYPE_NUM), node.GetId());
593 if (node.IsSpecialLayerChanged()) {
594 curLogicalDisplayNode_->SetDisplaySpecialSurfaceChanged(true);
595 }
596 }
597
UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode & node)598 void RSUniRenderVisitor::UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode& node)
599 {
600 if (!node.IsMainWindowType()) {
601 return;
602 }
603 auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
604 if (!geoPtr) {
605 return;
606 }
607 if (RSUniRenderUtil::GetRotationDegreeFromMatrix(geoPtr->GetAbsMatrix()) % RS_ROTATION_90 != 0) {
608 node.SetIsRotating(true);
609 }
610 }
611
IsSubTreeOccluded(RSRenderNode & node) const612 bool RSUniRenderVisitor::IsSubTreeOccluded(RSRenderNode& node) const
613 {
614 if (!isOcclusionEnabled_) {
615 return false;
616 }
617 // step1. apply occlusion info for surfacenode and skip fully covered subtree
618 if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
619 auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
620 if (surfaceNode.IsMainWindowType()) {
621 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::IsSubTreeOccluded node[%s]"
622 "name:[%s] visibleRegionIsEmpty[%d]",
623 std::to_string(node.GetId()).c_str(), surfaceNode.GetName().c_str(),
624 surfaceNode.GetVisibleRegion().IsEmpty());
625 auto isOccluded = hasMirrorDisplay_ ?
626 surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
627 isOccluded = isOccluded && (!RSUifirstManager::Instance().IsSubTreeNeedPrepareForSnapshot(surfaceNode));
628 if (isOccluded && curSurfaceDirtyManager_) {
629 curSurfaceDirtyManager_->Clear();
630 }
631 surfaceNode.AccumulateDirtyInOcclusion(isOccluded);
632 return isOccluded;
633 }
634 }
635 // step2.1 For partial visible surface, intersected region->rects in surface
636 // step2.2 check if clean subtree in occlusion rects
637 return false;
638 }
639
ResetDisplayDirtyRegion()640 void RSUniRenderVisitor::ResetDisplayDirtyRegion()
641 {
642 if (!curScreenDirtyManager_) {
643 return;
644 }
645 if (curScreenNode_ == nullptr || screenManager_ == nullptr) {
646 return;
647 }
648 bool ret = CheckScreenPowerChange() ||
649 CheckCurtainScreenUsingStatusChange() ||
650 curScreenDirtyManager_->GetEnabledChanged() ||
651 IsWatermarkFlagChanged() ||
652 zoomStateChange_ ||
653 isCompleteRenderEnabled_ ||
654 curScreenNode_->GetIsLuminanceStatusChange() ||
655 IsFirstFrameOfOverdrawSwitch() ||
656 IsFirstFrameOfDrawingCacheDfxSwitch() ||
657 IsAccessibilityConfigChanged() ||
658 curScreenNode_->HasMirroredScreenChanged() ||
659 screenManager_->CheckPSurfaceChanged(curScreenNode_->GetScreenId());
660
661 #ifdef RS_ENABLE_OVERLAY_DISPLAY
662 // if overlay display status changed, ......
663 ret = ret || RSOverlayDisplayManager::Instance().CheckStatusChanged();
664 #endif
665 if (ret) {
666 curScreenDirtyManager_->ResetDirtyAsSurfaceSize();
667 RS_LOGD("ResetDisplayDirtyRegion on");
668 }
669 }
670
IsAccessibilityConfigChanged() const671 bool RSUniRenderVisitor::IsAccessibilityConfigChanged() const
672 {
673 return RSMainThread::Instance()->IsAccessibilityConfigChanged();
674 }
675
CheckScreenPowerChange() const676 bool RSUniRenderVisitor::CheckScreenPowerChange() const
677 {
678 if (!RSMainThread::Instance()->GetScreenPowerOnChanged()) {
679 return false;
680 }
681 RS_LOGD("CheckScreenPowerChange changed");
682 return true;
683 }
684
CheckCurtainScreenUsingStatusChange() const685 bool RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange() const
686 {
687 if (!RSMainThread::Instance()->IsCurtainScreenUsingStatusChanged()) {
688 return false;
689 }
690 RS_LOGD("CheckCurtainScreenUsingStatusChange changed");
691 return true;
692 }
693
CheckLuminanceStatusChange(ScreenId id)694 bool RSUniRenderVisitor::CheckLuminanceStatusChange(ScreenId id)
695 {
696 // ExchangeLuminanceChangingStatus will be reset false after called in one frame
697 // Use isLuminanceStatusChange_ if need call this function multiple times in one frame
698 if (!RSMainThread::Instance()->ExchangeLuminanceChangingStatus(id)) {
699 return false;
700 }
701 curScreenNode_->SetIsLuminanceStatusChange(true);
702 RS_LOGD("CheckLuminanceStatusChange changed");
703 return true;
704 }
705
IsFirstFrameOfDrawingCacheDfxSwitch() const706 bool RSUniRenderVisitor::IsFirstFrameOfDrawingCacheDfxSwitch() const
707 {
708 return RSMainThread::Instance()->IsFirstFrameOfDrawingCacheDFXSwitch();
709 }
710
IsFirstFrameOfOverdrawSwitch() const711 bool RSUniRenderVisitor::IsFirstFrameOfOverdrawSwitch() const
712 {
713 if (!RSMainThread::Instance()->IsFirstFrameOfOverdrawSwitch()) {
714 return false;
715 }
716 RS_LOGD("IsFirstFrameOfOverdrawSwitch");
717 return true;
718 }
719
IsWatermarkFlagChanged() const720 bool RSUniRenderVisitor::IsWatermarkFlagChanged() const
721 {
722 if (RSMainThread::Instance()->IsWatermarkFlagChanged()) {
723 RS_LOGD("FirstOrLastFrameOfWatermark");
724 return true;
725 } else {
726 return false;
727 }
728 }
729
UpdateDisplayZoomState()730 void RSUniRenderVisitor::UpdateDisplayZoomState()
731 {
732 if (!curScreenNode_) {
733 zoomStateChange_ = false;
734 return;
735 }
736 auto scale = curScreenNode_->GetRenderProperties().GetScale();
737 bool curZoomState = scale.x_ > 1.f || scale.y_ > 1.f;
738 curScreenNode_->UpdateZoomState(curZoomState);
739 zoomStateChange_ = curZoomState || curScreenNode_->IsZoomStateChange();
740 }
741
UpdateVirtualDisplayInfo(RSLogicalDisplayRenderNode & node)742 void RSUniRenderVisitor::UpdateVirtualDisplayInfo(RSLogicalDisplayRenderNode& node)
743 {
744 // only for virtual screen
745 if (!node.IsMirrorDisplay()) {
746 node.ClearSecurityLayerList();
747 node.ClearSecurityVisibleLayerList();
748 return;
749 }
750 auto mirrorNode = node.GetMirrorSource().lock();
751 if (mirrorNode == nullptr || screenManager_ == nullptr) {
752 return;
753 }
754
755 UpdateVirtualDisplaySecurityExemption(node, *mirrorNode);
756 UpdateVirtualDisplayVisibleRectSecurity(node, *mirrorNode);
757 }
758
UpdateVirtualDisplaySecurityExemption(RSLogicalDisplayRenderNode & node,RSLogicalDisplayRenderNode & mirrorNode)759 void RSUniRenderVisitor::UpdateVirtualDisplaySecurityExemption(RSLogicalDisplayRenderNode& node,
760 RSLogicalDisplayRenderNode& mirrorNode)
761 {
762 auto securityExemptionList = screenManager_->GetVirtualScreenSecurityExemptionList(node.GetScreenId());
763 if (securityExemptionList.size() == 0) {
764 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:false",
765 node.GetId());
766 node.SetSecurityExemption(false);
767 return;
768 }
769 auto securityLayerList = mirrorNode.GetSecurityLayerList();
770 for (const auto& exemptionLayer : securityExemptionList) {
771 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64
772 " securityExemption nodeId %{public}" PRIu64 ".", node.GetId(), exemptionLayer);
773 }
774 for (const auto& secLayer : securityLayerList) {
775 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64
776 " securityLayer nodeId %{public}" PRIu64 ".", mirrorNode.GetId(), secLayer);
777 }
778 bool isSecurityExemption = false;
779 if (securityExemptionList.size() >= securityLayerList.size()) {
780 isSecurityExemption = true;
781 for (const auto& secLayer : securityLayerList) {
782 if (std::find(securityExemptionList.begin(), securityExemptionList.end(), secLayer) ==
783 securityExemptionList.end()) {
784 isSecurityExemption = false;
785 break;
786 }
787 }
788 }
789 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:%{public}d",
790 node.GetId(), isSecurityExemption);
791 node.SetSecurityExemption(isSecurityExemption);
792 }
793
UpdateVirtualDisplayVisibleRectSecurity(RSLogicalDisplayRenderNode & node,RSLogicalDisplayRenderNode & mirrorNode)794 void RSUniRenderVisitor::UpdateVirtualDisplayVisibleRectSecurity(RSLogicalDisplayRenderNode& node,
795 RSLogicalDisplayRenderNode& mirrorNode)
796 {
797 if (!curScreenNode_->GetScreenInfo().enableVisibleRect) {
798 return;
799 }
800 auto rect = screenManager_->GetMirrorScreenVisibleRect(node.GetScreenId());
801 RectI visibleRect(rect.x, rect.y, rect.w, rect.h);
802 auto securityVisibleLayerList = mirrorNode.GetSecurityVisibleLayerList();
803 bool hasSecLayerInVisibleRect = false;
804 for (const auto& secLayerId : securityVisibleLayerList) {
805 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
806 RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode(secLayerId));
807 if (surfaceNode == nullptr) {
808 continue;
809 }
810 const auto& dstRect = surfaceNode->GetDstRect();
811 if (dstRect.Intersect(visibleRect)) {
812 hasSecLayerInVisibleRect = true;
813 break;
814 }
815 }
816 RS_LOGD("%{public}s: hasSecLayerInVisibleRect:%{public}d.", __func__, hasSecLayerInVisibleRect);
817 node.SetHasSecLayerInVisibleRect(hasSecLayerInVisibleRect);
818 }
819
UpdateCurFrameInfoDetail(RSRenderNode & node,bool subTreeSkipped,bool isPostPrepare)820 void RSUniRenderVisitor::UpdateCurFrameInfoDetail(RSRenderNode& node, bool subTreeSkipped, bool isPostPrepare)
821 {
822 if (GetDumpRsTreeDetailEnabled()) {
823 auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
824 curFrameInfoDetail.curFrameVsyncId = HgmCore::Instance().GetVsyncId();
825 curFrameInfoDetail.curFrameSubTreeSkipped = subTreeSkipped;
826 if (isPostPrepare) {
827 curFrameInfoDetail.curFramePostPrepareSeqNum = IncreasePostPrepareSeq();
828 } else {
829 curFrameInfoDetail.curFramePrepareSeqNum = IncreasePrepareSeq();
830 }
831 }
832 }
833
QuickPrepareScreenRenderNode(RSScreenRenderNode & node)834 void RSUniRenderVisitor::QuickPrepareScreenRenderNode(RSScreenRenderNode& node)
835 {
836 RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "QuickPrepareScreenRenderNode nodeId[%llu]", node.GetId());
837 UpdateCurFrameInfoDetail(node);
838 // 0. init display info
839 RS_TRACE_NAME("RSUniRender:QuickPrepareScreenRenderNode " + std::to_string(node.GetScreenId()));
840 if (!InitScreenInfo(node)) {
841 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
842 return;
843 }
844 UpdateDisplayZoomState();
845 SendRcdMessage(node);
846 ancestorNodeHasAnimation_ = false;
847 dirtyFlag_ = isDirty_ || zoomStateChange_ || curScreenDirtyManager_->IsActiveSurfaceRectChanged() ||
848 curScreenDirtyManager_->IsSurfaceRectChanged() || node.IsDirty();
849 if (dirtyFlag_) {
850 RS_TRACE_NAME_FMT("need recalculate dirty region");
851 RS_LOGD("need recalculate dirty region");
852 }
853 prepareClipRect_ = curScreenNode_->GetScreenRect();
854 hasAccumulatedClip_ = false;
855
856 globalShouldPaint_ = true;
857 curAlpha_ = 1.0f;
858 globalZOrder_ = 0.0f;
859 appWindowZOrder_ = 0;
860 hasSkipLayer_ = false;
861 hwcVisitor_->curZOrderForHwcEnableByFilter_ = 0;
862 node.GetHwcRecorder().SetZOrderForHwcEnableByFilter(hwcVisitor_->curZOrderForHwcEnableByFilter_++);
863 if (!(RSMainThread::Instance()->IsRequestedNextVSync())) {
864 RS_OPTIONAL_TRACE_NAME_FMT("do not request next vsync");
865 needRequestNextVsync_ = false;
866 }
867
868 rsScreenNodeChildNum_ = 0;
869 RSHdrUtil::LuminanceChangeSetDirty(node);
870 QuickPrepareChildren(node);
871 TryNotifyUIBufferAvailable();
872
873 PostPrepare(node);
874 UpdateCompositeType(node);
875 hwcVisitor_->UpdateHwcNodeEnable();
876 UpdateSurfaceDirtyAndGlobalDirty();
877 UpdateSurfaceOcclusionInfo();
878 if (needRecalculateOcclusion_) {
879 // Callback for registered self drawing surfacenode
880 RSMainThread::Instance()->SurfaceOcclusionCallback();
881 }
882 curScreenNode_->UpdatePartialRenderParams();
883 curScreenNode_->SetFingerprint(hasFingerprint_);
884 curScreenNode_->UpdateScreenRenderParams();
885 UpdateColorSpaceAfterHwcCalc(node);
886 RSHdrUtil::UpdatePixelFormatAfterHwcCalc(node);
887
888 #ifdef SUBTREE_PARALLEL_ENABLE
889 RSParallelManager::Singleton().HitPolicy(node);
890 #endif
891
892 HandleColorGamuts(node);
893 HandlePixelFormat(node);
894 if (UNLIKELY(!SharedTransitionParam::unpairedShareTransitions_.empty())) {
895 ProcessUnpairedSharedTransitionNode();
896 }
897 node.HandleCurMainAndLeashSurfaceNodes();
898 layerNum_ += node.GetSurfaceCountForMultiLayersPerf();
899 node.RenderTraceDebug();
900 curScreenNode_->ResetMirroredScreenChangedFlag();
901 PrepareForMultiScreenViewDisplayNode(node);
902 node.ResetDirtyFlag();
903 RS_TRACE_NAME_FMT("RSUniRenderVisitor::QuickPrepareScreenRenderNode childNumber: %d", rsScreenNodeChildNum_);
904 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
905 }
906
InitLogicalDisplayInfo(RSLogicalDisplayRenderNode & node)907 bool RSUniRenderVisitor::InitLogicalDisplayInfo(RSLogicalDisplayRenderNode& node)
908 {
909 curLogicalDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSLogicalDisplayRenderNode>();
910 curLogicalDisplayNode_->SetDisplaySpecialSurfaceChanged(false);
911 curLogicalDisplayNode_->GetMultableSpecialLayerMgr().Set(HAS_GENERAL_SPECIAL, false);
912 curLogicalDisplayNode_->SetCompositeType(curScreenNode_->GetCompositeType());
913 curLogicalDisplayNode_->SetHasCaptureWindow(false);
914 occlusionSurfaceOrder_ = TOP_OCCLUSION_SURFACES_NUM;
915 auto mirrorSourceNode = curLogicalDisplayNode_->GetMirrorSource().lock();
916 auto mirrorSourceScreenNode = mirrorSourceNode ?
917 std::static_pointer_cast<RSScreenRenderNode>(mirrorSourceNode->GetParent().lock()) : nullptr;
918 if (mirrorSourceScreenNode) {
919 curScreenNode_->SetIsMirrorScreen(true);
920 curScreenNode_->SetMirrorSource(mirrorSourceScreenNode);
921 } else {
922 curScreenNode_->SetIsMirrorScreen(false);
923 curScreenNode_->ResetMirrorSource();
924 }
925 curScreenNode_->GetLogicalDisplayNodeDrawables().push_back(curLogicalDisplayNode_->GetRenderDrawable());
926 return true;
927 }
928
QuickPrepareLogicalDisplayRenderNode(RSLogicalDisplayRenderNode & node)929 void RSUniRenderVisitor::QuickPrepareLogicalDisplayRenderNode(RSLogicalDisplayRenderNode& node)
930 {
931 RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID,
932 "QuickPrepareLogicalDisplayRenderNode nodeId[%llu]", node.GetId());
933 RS_TRACE_NAME("RSUniRender:QuickPrepareLogicalDisplayRenderNode " + std::to_string(node.GetScreenId()));
934 UpdateCurFrameInfoDetail(node);
935 if (!InitLogicalDisplayInfo(node)) {
936 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
937 return;
938 }
939 // 0. check ......
940 auto dirtyManager = curScreenDirtyManager_;
941 if (!dirtyManager) {
942 RS_LOGE("QuickPrepareLogicalDisplayRenderNode dirtyManager is nullptr");
943 return;
944 }
945 UpdateVirtualDisplayInfo(node);
946 auto dirtyFlag = dirtyFlag_;
947 displayNodeRotationChanged_ = node.IsRotationChanged();
948 dirtyFlag_ |= displayNodeRotationChanged_;
949 auto prevAlpha = curAlpha_;
950 auto curCornerRadius = curCornerRadius_;
951 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
952 auto preGlobalShouldPaint = globalShouldPaint_;
953 globalShouldPaint_ &= node.ShouldPaint();
954 CheckFilterCacheNeedForceClearOrSave(node);
955 RectI prepareClipRect = prepareClipRect_;
956 bool hasAccumulatedClip = hasAccumulatedClip_;
957 dirtyFlag_ =
958 node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
959 node.UpdateCurCornerRadius(curCornerRadius_);
960 node.UpdateRotation();
961 RSUifirstManager::Instance().PreStatusProcess(displayNodeRotationChanged_ || isScreenRotationAnimating_);
962
963 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
964 QuickPrepareChildren(node);
965
966 PostPrepare(node);
967 prepareClipRect_ = prepareClipRect;
968 hasAccumulatedClip_ = hasAccumulatedClip;
969 dirtyFlag_ = dirtyFlag;
970 curAlpha_ = prevAlpha;
971 curCornerRadius_ = curCornerRadius;
972 globalShouldPaint_ = preGlobalShouldPaint;
973 node.UpdateOffscreenRenderParams(node.IsRotationChanged());
974 node.RenderTraceDebug();
975 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
976 }
977
CheckFilterCacheNeedForceClearOrSave(RSRenderNode & node)978 void RSUniRenderVisitor::CheckFilterCacheNeedForceClearOrSave(RSRenderNode& node)
979 {
980 if (!node.HasBlurFilter()) {
981 return;
982 }
983 bool rotationChanged = curLogicalDisplayNode_ ?
984 curLogicalDisplayNode_->IsRotationChanged() || curLogicalDisplayNode_->IsLastRotationChanged() : false;
985 bool rotationStatusChanged = curLogicalDisplayNode_ ?
986 curLogicalDisplayNode_->GetPreRotationStatus() != curLogicalDisplayNode_->GetCurRotationStatus() : false;
987 node.CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
988 }
989
PrepareForSkippedCrossNode(RSSurfaceRenderNode & surfaceNode)990 void RSUniRenderVisitor::PrepareForSkippedCrossNode(RSSurfaceRenderNode& surfaceNode)
991 {
992 // 1. Find the actual surface node of which the coordinates must be recalculated.
993 auto sourceNode = surfaceNode.GetSourceCrossNode().lock();
994 auto sourceSurface = sourceNode ? sourceNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
995 RSSurfaceRenderNode& nodeRef = sourceSurface ? *sourceSurface : surfaceNode;
996 auto geoPtr = nodeRef.GetRenderProperties().GetBoundsGeometry();
997 if (!geoPtr) {
998 return;
999 }
1000 // 2. Get the AbsMatrix under current display node. Concatenate current parent matrix and nodeRef relative matrix.
1001 Drawing::Matrix nodeAbsMatrix = geoPtr->GetMatrix();
1002 if (nodeRef.GetGlobalPositionEnabled()) {
1003 nodeAbsMatrix.PostTranslate(-curScreenNode_->GetScreenOffsetX(), -curScreenNode_->GetScreenOffsetY());
1004 }
1005 if (auto parent = surfaceNode.GetParent().lock()) {
1006 auto parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
1007 nodeAbsMatrix.PostConcat(parentGeoPtr ? parentGeoPtr->GetAbsMatrix() : Drawing::Matrix());
1008 }
1009 // 3. Get the conversion matrix from first display coordinate system to current display coordinate system.
1010 // 3.1 Invert AbsMatrix under first display.
1011 // 3.2 Apply AbsMatrix under second display.
1012 Drawing::Matrix conversionMatrix;
1013 if (!geoPtr->GetAbsMatrix().Invert(conversionMatrix)) {
1014 curScreenDirtyManager_->ResetDirtyAsSurfaceSize();
1015 RS_LOGW("Cross-Node matrix inverting for %{public}s failed, set full screen dirty.", nodeRef.GetName().c_str());
1016 return;
1017 }
1018 conversionMatrix.PostConcat(nodeAbsMatrix);
1019
1020 // 4. record this surface node and its position on second display, for global dirty region conversion.
1021 curScreenNode_->RecordMainAndLeashSurfaces(nodeRef.shared_from_this());
1022 nodeRef.UpdateCrossNodeSkipDisplayConversionMatrices(curScreenNode_->GetId(), conversionMatrix);
1023 RectI surfaceRect =
1024 geoPtr->MapRect(nodeRef.GetOldDirty().ConvertTo<float>(), conversionMatrix)
1025 .IntersectRect(curScreenNode_->GetScreenRect());
1026 curScreenNode_->UpdateSurfaceNodePos(nodeRef.GetId(), surfaceRect);
1027 curScreenNode_->AddSurfaceNodePosByDescZOrder(nodeRef.GetId(), surfaceRect);
1028 // 5. record all children surface nodes and their position on second display, for global dirty region conversion.
1029 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
1030 nodeRef.GetAllSubSurfaceNodes(allSubSurfaceNodes);
1031 for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
1032 if (auto childPtr = subSurfaceNode.lock()) {
1033 curScreenNode_->RecordMainAndLeashSurfaces(childPtr);
1034 childPtr->SetFirstLevelCrossNode(nodeRef.IsFirstLevelCrossNode());
1035 childPtr->UpdateCrossNodeSkipDisplayConversionMatrices(curScreenNode_->GetId(), conversionMatrix);
1036 RectI childSurfaceRect = geoPtr->MapRect(
1037 childPtr->GetOldDirty().ConvertTo<float>(), conversionMatrix)
1038 .IntersectRect(curScreenNode_->GetScreenRect());
1039 curScreenNode_->UpdateSurfaceNodePos(childPtr->GetId(), childSurfaceRect);
1040 curScreenNode_->AddSurfaceNodePosByDescZOrder(childPtr->GetId(), childSurfaceRect);
1041 }
1042 }
1043 }
1044
CheckSkipAndPrepareForCrossNode(RSSurfaceRenderNode & node)1045 bool RSUniRenderVisitor::CheckSkipAndPrepareForCrossNode(RSSurfaceRenderNode& node)
1046 {
1047 auto sourceRenderNode = node.GetSourceCrossNode().lock();
1048 RSSurfaceRenderNode::SharedPtr sourceNode = sourceRenderNode ?
1049 sourceRenderNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1050 // CloneCrossNode must have a source node.
1051 if (node.IsCloneCrossNode() && sourceNode == nullptr) {
1052 RS_LOGE("QuickPrepareSurfaceRenderNode source node of clone node %{public}"
1053 PRIu64 " is null", node.GetId());
1054 return true;
1055 }
1056
1057 // skip CrossNode not on first display
1058 if (CheckSkipCrossNode(node)) {
1059 // when skip cloneCrossNode prepare, we need switch to record sourceNode dirty info
1060 PrepareForSkippedCrossNode(node);
1061 return true;
1062 }
1063
1064 // when prepare CloneCrossNode on first display, we need switch to prepare sourceNode.
1065 if (node.IsCloneCrossNode()) {
1066 isSwitchToSourceCrossNodePrepare_ = true;
1067 sourceNode->SetCurCloneNodeParent(node.GetParent().lock());
1068 sourceNode->SetFirstLevelCrossNode(true);
1069 sourceNode->QuickPrepare(shared_from_this());
1070 sourceNode->SetCurCloneNodeParent(nullptr);
1071 isSwitchToSourceCrossNodePrepare_ = false;
1072 return true;
1073 }
1074 return false;
1075 }
1076
CheckIfSkipDrawInVirtualScreen(RSSurfaceRenderNode & node)1077 bool RSUniRenderVisitor::CheckIfSkipDrawInVirtualScreen(RSSurfaceRenderNode& node)
1078 {
1079 //if node special layer type is skip drawing, return true
1080 if (node.GetSpecialLayerMgr().Find(SpecialLayerType::SKIP) ||
1081 allBlackList_.find(node.GetId()) != allBlackList_.end() ||
1082 allBlackList_.find(node.GetLeashPersistentId()) != allBlackList_.end()) {
1083 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::CheckIfSkipDrawInVirtualScreen:[%{public}s] "
1084 "nodeid:[%{public}" PRIu64 "], set isSkipDrawInVirtualScreen_ true", node.GetName().c_str(), node.GetId());
1085 return true;
1086 }
1087 return false;
1088 }
1089
QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode & node)1090 void RSUniRenderVisitor::QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
1091 {
1092 RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "QuickPrepareSurfaceRenderNode nodeId[%llu]", node.GetId());
1093 UpdateCurFrameInfoDetail(node);
1094 RS_TRACE_NAME_FMT("RSUniRender::QuickPrepare:[%s] nodeId[%" PRIu64 "] pid[%d] nodeType[%u]"
1095 " subTreeDirty[%d], crossDisplay:[%d]", node.GetName().c_str(), node.GetId(), ExtractPid(node.GetId()),
1096 static_cast<uint>(node.GetSurfaceNodeType()), node.IsSubTreeDirty(), node.IsFirstLevelCrossNode());
1097 RS_LOGD("RSUniRender::QuickPrepareSurfaceRenderNode:[%{public}s] nodeid:[%{public}" PRIu64 "] pid:[%{public}d] "
1098 "nodeType:[%{public}d] subTreeDirty[%{public}d] crossDisplay[%{public}d]", node.GetName().c_str(), node.GetId(),
1099 ExtractPid(node.GetId()), static_cast<int>(node.GetSurfaceNodeType()), node.IsSubTreeDirty(),
1100 node.IsFirstLevelCrossNode());
1101
1102 if (PrepareForCloneNode(node)) {
1103 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1104 return;
1105 }
1106
1107 // AppWindow is traversed in reverse order
1108 // Prepare operation will be executed first when the node is at the top level
1109 // The value of appWindowZOrder_ decreases from 0 to negative
1110 if (node.IsAppWindow()) {
1111 node.SetAppWindowZOrder(appWindowZOrder_--);
1112 }
1113
1114 // avoid cross node subtree visited twice or more
1115 DealWithSpecialLayer(node);
1116 if (CheckSkipAndPrepareForCrossNode(node)) {
1117 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1118 return;
1119 }
1120 // 0. init curSurface info and check node info
1121 auto curCornerRadius = curCornerRadius_;
1122 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
1123 if (!BeforeUpdateSurfaceDirtyCalc(node)) {
1124 RS_LOGE("QuickPrepareSurfaceRenderNode BeforeUpdateSurfaceDirtyCalc fail");
1125 RSUifirstManager::Instance().DisableUifirstNode(node);
1126 node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1127 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1128 return;
1129 }
1130
1131 if (curSurfaceDirtyManager_ == nullptr) {
1132 RS_LOGE("QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
1133 node.GetName().c_str());
1134 node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1135 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1136 return;
1137 }
1138 curSurfaceDirtyManager_->SetAdvancedDirtyRegionType(advancedDirtyType_);
1139
1140 // 1. Update matrix and collect dirty region
1141 auto dirtyFlag = dirtyFlag_;
1142 auto prepareClipRect = prepareClipRect_;
1143 bool hasAccumulatedClip = hasAccumulatedClip_;
1144 auto prevAlpha = curAlpha_;
1145 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1146 node.SetGlobalAlpha(curAlpha_);
1147 auto preGlobalShouldPaint = globalShouldPaint_;
1148 globalShouldPaint_ &= node.ShouldPaint();
1149 node.SetSelfAndParentShouldPaint(globalShouldPaint_);
1150 CheckFilterCacheNeedForceClearOrSave(node);
1151 MarkFilterInForegroundFilterAndCheckNeedForceClearCache(node);
1152 node.CheckContainerDirtyStatusAndUpdateDirty(curContainerDirty_);
1153 node.ClearCrossNodeSkipDisplayConversionMatrices();
1154 auto& screenInfo = curScreenNode_->GetScreenInfo();
1155 node.SetPreparedDisplayOffsetX(screenInfo.offsetX);
1156 node.SetPreparedDisplayOffsetY(screenInfo.offsetY);
1157 if (node.GetGlobalPositionEnabled()) {
1158 parentSurfaceNodeMatrix_.Translate(-screenInfo.offsetX, -screenInfo.offsetY);
1159 }
1160
1161 dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
1162 *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix);
1163 auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
1164 if (!geoPtr) {
1165 node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1166 globalShouldPaint_ = preGlobalShouldPaint;
1167 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1168 return;
1169 }
1170 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
1171 if (!AfterUpdateSurfaceDirtyCalc(node)) {
1172 RS_LOGE("QuickPrepareSurfaceRenderNode AfterUpdateSurfaceDirtyCalc fail");
1173 RSUifirstManager::Instance().DisableUifirstNode(node);
1174 node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1175 globalShouldPaint_ = preGlobalShouldPaint;
1176 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1177 return;
1178 }
1179 bool isDimmingOn = RSLuminanceControl::Get().IsDimmingOn(curScreenNode_->GetScreenId());
1180 if (isDimmingOn) {
1181 bool hasHdrPresent = node.GetHDRPresent();
1182 bool hasHdrVideo = node.GetVideoHdrStatus() != HdrStatus::NO_HDR;
1183 RS_LOGD("HDRDiming IsDimmingOn: %{public}d, GetHDRPresent: %{public}d, GetHdrVideo: %{public}d",
1184 isDimmingOn, hasHdrPresent, hasHdrVideo);
1185 if (hasHdrPresent || hasHdrVideo) {
1186 node.SetContentDirty(); // HDR content is dirty on Dimming status.
1187 }
1188 }
1189 #ifdef SUBTREE_PARALLEL_ENABLE
1190 const bool isInFocusSurface = isInFocusSurface_;
1191 isInFocusSurface_ = node.IsFocusedNode(currentFocusedNodeId_) ||
1192 node.IsFocusedNode(focusedLeashWindowId_) || isInFocusSurface_;
1193 #endif
1194 CollectSelfDrawingNodeRectInfo(node);
1195 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1196 // Initialize the handler of control-level occlusion culling.
1197 InitializeOcclusionHandler(node);
1198 bool preIsSkipDraw = isSkipDrawInVirtualScreen_;
1199 isSkipDrawInVirtualScreen_ = isSkipDrawInVirtualScreen_ || CheckIfSkipDrawInVirtualScreen(node);
1200 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_, IsSubTreeOccluded(node)) ||
1201 ForcePrepareSubTree();
1202 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1203 node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
1204 if (curSurfaceDirtyManager_ == nullptr) {
1205 RS_LOGE("QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager "
1206 "is set to nullptr by QuickPrepareChildren", node.GetName().c_str());
1207 node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1208 globalShouldPaint_ = preGlobalShouldPaint;
1209 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1210 return;
1211 }
1212 if (!node.IsFirstLevelCrossNode()) {
1213 curSurfaceDirtyManager_->ClipDirtyRectWithinSurface();
1214 }
1215 auto dirtyRect = node.GetDirtyManager()->GetCurrentFrameDirtyRegion();
1216 RS_LOGD("QuickPrepare [%{public}s, %{public}" PRIu64 "] DirtyRect[%{public}d, %{public}d, %{public}d, %{public}d]",
1217 node.GetName().c_str(), node.GetId(), dirtyRect.GetLeft(), dirtyRect.GetTop(), dirtyRect.GetWidth(),
1218 dirtyRect.GetHeight());
1219
1220 RSUifirstManager::Instance().RecordDirtyRegionMatrix(node, geoPtr->GetAbsMatrix());
1221
1222 if (node.IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()) {
1223 CheckIsGpuOverDrawBufferOptimizeNode(node);
1224 }
1225 PostPrepare(node, !isSubTreeNeedPrepare);
1226 if (node.IsHardwareEnabledTopSurface() && node.shared_from_this()) {
1227 RSUniHwcComputeUtil::UpdateHwcNodeProperty(node.shared_from_this()->ReinterpretCastTo<RSSurfaceRenderNode>());
1228 }
1229 CalculateOpaqueAndTransparentRegion(node);
1230 curAlpha_ = prevAlpha;
1231 globalShouldPaint_ = preGlobalShouldPaint;
1232 prepareClipRect_ = prepareClipRect;
1233 hasAccumulatedClip_ = hasAccumulatedClip;
1234 dirtyFlag_ = dirtyFlag;
1235 isSkipDrawInVirtualScreen_ = preIsSkipDraw;
1236 PrepareForUIFirstNode(node);
1237 PrepareForCrossNode(node);
1238 #ifdef SUBTREE_PARALLEL_ENABLE
1239 if (node.GetSubThreadAssignable() || !isInFocusSurface_) {
1240 node.ClearSubtreeParallelNodes();
1241 }
1242 isInFocusSurface_ = isInFocusSurface;
1243 #endif
1244 node.UpdateInfoForClonedNode(clonedSourceNodeId_);
1245 node.GetOpincCache().OpincSetInAppStateEnd(unchangeMarkInApp_);
1246 ResetCurSurfaceInfoAsUpperSurfaceParent(node);
1247 curCornerRadius_ = curCornerRadius;
1248 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
1249
1250 // [Attention] Only used in PC window resize scene now
1251 windowKeyFrameNodeInf_.PrepareRootNodeOffscreen(node);
1252
1253 node.RenderTraceDebug();
1254 node.SetNeedOffscreen(isScreenRotationAnimating_);
1255 if (node.NeedUpdateDrawableBehindWindow()) {
1256 node.UpdateDrawableBehindWindow();
1257 node.SetOldNeedDrawBehindWindow(node.NeedDrawBehindWindow());
1258 }
1259 if (node.IsUIBufferAvailable()) {
1260 uiBufferAvailableId_.emplace_back(node.GetId());
1261 }
1262 HandleTunnelLayerId(node);
1263 PrepareForMultiScreenViewSurfaceNode(node);
1264 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1265 }
1266
PrepareForMultiScreenViewSurfaceNode(RSSurfaceRenderNode & node)1267 void RSUniRenderVisitor::PrepareForMultiScreenViewSurfaceNode(RSSurfaceRenderNode& node)
1268 {
1269 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1270 auto sourceNode = nodeMap.GetRenderNode<RSScreenRenderNode>(node.GetSourceDisplayRenderNodeId());
1271 if (!sourceNode) {
1272 return;
1273 }
1274 node.SetContentDirty();
1275 sourceNode->SetTargetSurfaceRenderNodeId(node.GetId());
1276 auto sourceNodeDrawable = sourceNode->GetRenderDrawable();
1277 if (!sourceNodeDrawable) {
1278 return;
1279 }
1280 RS_TRACE_NAME_FMT("PrepareForMultiScreenViewSurfaceNode surfaceNodeId: %llu sourceVirtualDisplayId: %llu",
1281 node.GetId(), node.GetSourceDisplayRenderNodeId());
1282 node.SetSourceDisplayRenderNodeDrawable(sourceNodeDrawable);
1283 }
1284
PrepareForMultiScreenViewDisplayNode(RSScreenRenderNode & node)1285 void RSUniRenderVisitor::PrepareForMultiScreenViewDisplayNode(RSScreenRenderNode& node)
1286 {
1287 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1288 auto targetNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(node.GetTargetSurfaceRenderNodeId());
1289 if (!targetNode) {
1290 return;
1291 }
1292 auto targetRenderNodeDrawable = targetNode->GetRenderDrawable();
1293 if (!targetRenderNodeDrawable) {
1294 return;
1295 }
1296 RS_TRACE_NAME_FMT("PrepareForMultiScreenViewDisplayNode screenNodeId: %llu targetSurfaceRenderNodeId: %llu",
1297 node.GetId(), node.GetTargetSurfaceRenderNodeId());
1298 node.SetTargetSurfaceRenderNodeDrawable(targetRenderNodeDrawable);
1299 }
1300
PrepareForCloneNode(RSSurfaceRenderNode & node)1301 bool RSUniRenderVisitor::PrepareForCloneNode(RSSurfaceRenderNode& node)
1302 {
1303 if (!node.IsCloneNode() || !node.IsLeashOrMainWindow()) {
1304 return false;
1305 }
1306 RS_LOGD("PrepareForCloneNode %{public}s is cloneNode", node.GetName().c_str());
1307 node.SetIsClonedNodeOnTheTree(false);
1308 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1309 auto clonedNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(node.GetClonedNodeId());
1310 if (clonedNode == nullptr) {
1311 RS_LOGE("PrepareForCloneNode clonedNode is nullptr");
1312 return false;
1313 }
1314 if (!clonedNode->IsMainWindowType()) {
1315 return false;
1316 }
1317 auto clonedNodeRenderDrawable = clonedNode->GetRenderDrawable();
1318 if (clonedNodeRenderDrawable == nullptr) {
1319 RS_LOGE("PrepareForCloneNode clonedNodeRenderDrawable is nullptr");
1320 return false;
1321 }
1322 node.SetIsClonedNodeOnTheTree(clonedNode->IsOnTheTree());
1323 clonedSourceNodeId_ = node.GetClonedNodeId();
1324 node.SetClonedNodeRenderDrawable(clonedNodeRenderDrawable);
1325 node.UpdateRenderParams();
1326 node.AddToPendingSyncList();
1327 return true;
1328 }
1329
PrepareForCrossNode(RSSurfaceRenderNode & node)1330 void RSUniRenderVisitor::PrepareForCrossNode(RSSurfaceRenderNode& node)
1331 {
1332 if (isCrossNodeOffscreenOn_ == CrossNodeOffScreenRenderDebugType::DISABLED) {
1333 return;
1334 }
1335 if (curLogicalDisplayNode_ == nullptr) {
1336 RS_LOGE("%{public}s curScreenNode_ is nullptr", __func__);
1337 return;
1338 }
1339 if (curScreenNode_->IsFirstVisitCrossNodeDisplay() && node.IsCrossNode()) {
1340 // check surface cache condition, not support ratation, transparent filter situation.
1341 bool needCacheSurface = node.QuerySubAssignable(curLogicalDisplayNode_->IsRotationChanged());
1342 if (needCacheSurface) {
1343 node.SetHwcChildrenDisabledState();
1344 RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " children disabled by crossNode",
1345 node.GetName().c_str(), node.GetId());
1346 }
1347 node.SetNeedCacheSurface(needCacheSurface);
1348 }
1349 }
1350
CheckSkipCrossNode(RSSurfaceRenderNode & node)1351 bool RSUniRenderVisitor::CheckSkipCrossNode(RSSurfaceRenderNode& node)
1352 {
1353 if (!node.IsCrossNode() || isSwitchToSourceCrossNodePrepare_) {
1354 return false;
1355 }
1356 if (curScreenNode_ == nullptr) {
1357 RS_LOGE("%{public}s curScreenNode_ is nullptr", __func__);
1358 return false;
1359 }
1360 node.SetCrossNodeOffScreenStatus(isCrossNodeOffscreenOn_);
1361 curScreenNode_->SetHasChildCrossNode(true);
1362 if (node.HasVisitedCrossNode()) {
1363 RS_OPTIONAL_TRACE_NAME_FMT("%s cross node[%s] skip", __func__, node.GetName().c_str());
1364 return true;
1365 }
1366 curScreenNode_->SetIsFirstVisitCrossNodeDisplay(true);
1367 node.SetCrossNodeVisitedStatus(true);
1368 // If there are n source cross screen nodes, they will enter n times. size of hasVisitedCrossNodeIds_.() is n.
1369 hasVisitedCrossNodeIds_.push_back(node.GetId());
1370 return false;
1371 }
1372
ResetCrossNodesVisitedStatus()1373 void RSUniRenderVisitor::ResetCrossNodesVisitedStatus()
1374 {
1375 if (hasVisitedCrossNodeIds_.empty()) {
1376 return;
1377 }
1378 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1379 for (NodeId& nodeId : hasVisitedCrossNodeIds_) {
1380 auto visitedNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(nodeId);
1381 if (!visitedNode) {
1382 RS_LOGE("%{public}s visitedNode is nullptr NodeId[%{public}" PRIu64 "]", __func__, nodeId);
1383 continue;
1384 }
1385 RS_LOGD("%{public}s NodeId[%{public}" PRIu64 "]", __func__, nodeId);
1386 visitedNode->SetCrossNodeVisitedStatus(false);
1387 }
1388 hasVisitedCrossNodeIds_.clear();
1389 }
1390
GetSurfaceTransparentFilterRegion(const RSSurfaceRenderNode & surfaceNode) const1391 Occlusion::Region RSUniRenderVisitor::GetSurfaceTransparentFilterRegion(const RSSurfaceRenderNode& surfaceNode) const
1392 {
1393 Occlusion::Region surfaceTransparentFilterRegion;
1394 if (!surfaceNode.IsTransparent()) {
1395 return surfaceTransparentFilterRegion;
1396 }
1397 if (auto surfaceDirtyManager = surfaceNode.GetDirtyManager()) {
1398 auto& filterList = surfaceDirtyManager->GetFilterCollector().GetFilterDirtyRegionInfoList(false);
1399 std::for_each(filterList.begin(), filterList.end(), [&](const FilterDirtyRegionInfo& filterInfo) {
1400 surfaceTransparentFilterRegion.OrSelf(filterInfo.filterDirty_);
1401 });
1402 }
1403 return surfaceTransparentFilterRegion;
1404 }
1405
CollectTopOcclusionSurfacesInfo(RSSurfaceRenderNode & node,bool isParticipateInOcclusion)1406 void RSUniRenderVisitor::CollectTopOcclusionSurfacesInfo(RSSurfaceRenderNode& node, bool isParticipateInOcclusion)
1407 {
1408 if (!isStencilPixelOcclusionCullingEnabled_ || occlusionSurfaceOrder_ <= DEFAULT_OCCLUSION_SURFACE_ORDER ||
1409 node.IsFirstLevelCrossNode()) {
1410 return;
1411 }
1412 if (curLogicalDisplayNode_ == nullptr) {
1413 RS_LOGE("%s: curLogicalDisplayNode_ is nullptr", __func__);
1414 return;
1415 }
1416 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1417 if (!parent || !parent->IsLeashWindow()) {
1418 return;
1419 }
1420 auto stencilVal = occlusionSurfaceOrder_ * OCCLUSION_ENABLE_SCENE_NUM;
1421 // When the transparent blur region overlaps with the collected opaque regions,
1422 // the underlying applications beneath the transparent blur cannot participate in occlusion culling.
1423 if (occlusionSurfaceOrder_ < TOP_OCCLUSION_SURFACES_NUM && node.IsTransparent() &&
1424 !GetSurfaceTransparentFilterRegion(node).And(
1425 curLogicalDisplayNode_->GetTopSurfaceOpaqueRegion()).IsEmpty()) {
1426 RS_OPTIONAL_TRACE_NAME_FMT("%s: %s's transparent filter terminate spoc, current occlusion surface "
1427 "order: %" PRId16, "", __func__, node.GetName().c_str(), occlusionSurfaceOrder_);
1428 occlusionSurfaceOrder_ = DEFAULT_OCCLUSION_SURFACE_ORDER;
1429 }
1430 auto opaqueRegionRects = node.GetOpaqueRegion().GetRegionRects();
1431 if (!isParticipateInOcclusion || opaqueRegionRects.empty()) {
1432 ++stencilVal;
1433 RS_OPTIONAL_TRACE_NAME_FMT("%s: %s set stencil[%d]", __func__,
1434 node.GetName().c_str(), static_cast<int>(stencilVal));
1435 parent->SetStencilVal(stencilVal);
1436 return;
1437 }
1438 parent->SetStencilVal(stencilVal);
1439 if (occlusionSurfaceOrder_ > 0) {
1440 auto maxOpaqueRect = std::max_element(opaqueRegionRects.begin(), opaqueRegionRects.end(),
1441 [](Occlusion::Rect a, Occlusion::Rect b) ->bool { return a.Area() < b.Area(); });
1442 RS_OPTIONAL_TRACE_NAME_FMT("%s: record name[%s] rect[%s] stencil[%d]", __func__,
1443 node.GetName().c_str(), maxOpaqueRect->GetRectInfo().c_str(), static_cast<int>(stencilVal));
1444 curLogicalDisplayNode_->RecordTopSurfaceOpaqueRects(*maxOpaqueRect);
1445 --occlusionSurfaceOrder_;
1446 }
1447 }
1448
PrepareForUIFirstNode(RSSurfaceRenderNode & node)1449 CM_INLINE void RSUniRenderVisitor::PrepareForUIFirstNode(RSSurfaceRenderNode& node)
1450 {
1451 RSUifirstManager::Instance().MarkSubHighPriorityType(node);
1452 if (isTargetUIFirstDfxEnabled_) {
1453 auto isTargetUIFirstDfxSurface = CheckIfSurfaceForUIFirstDFX(node.GetName());
1454 if (!node.isTargetUIFirstDfxEnabled_ && isTargetUIFirstDfxSurface) {
1455 RS_LOGD("UIFirstDFX Name[%{public}s] ID[%{public}" PRIu64 "] OpenDebug",
1456 node.GetName().c_str(), node.GetId());
1457 }
1458 node.isTargetUIFirstDfxEnabled_ = isTargetUIFirstDfxSurface;
1459 }
1460 RSUifirstManager::Instance().UpdateUifirstNodes(node, ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation());
1461 RSUifirstManager::Instance().RecordScreenRect(node, curScreenNode_->GetScreenRect());
1462 }
1463
UpdateNodeVisibleRegion(RSSurfaceRenderNode & node)1464 void RSUniRenderVisitor::UpdateNodeVisibleRegion(RSSurfaceRenderNode& node)
1465 {
1466 if (!curScreenNode_) {
1467 RS_LOGE("UpdateNodeVisibleRegion curScreenNode is nullptr");
1468 return;
1469 }
1470 // occlusion - 0. Calculate node visible region considering accumulated opaque region of upper surface nodes.
1471 if (!curScreenNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) {
1472 RS_LOGD("UpdateNodeVisibleRegion NodeName: %{public}s, NodeId: %{public}" PRIu64
1473 " not paticipate in occlusion when cross node in expand screen", node.GetName().c_str(), node.GetId());
1474 return;
1475 }
1476 Occlusion::Rect selfDrawRect = node.GetSurfaceOcclusionRect(true);
1477 Occlusion::Region selfDrawRegion { selfDrawRect };
1478 needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.CheckIfOcclusionChanged() ||
1479 node.IsBehindWindowOcclusionChanged();
1480 if (needRecalculateOcclusion_) {
1481 Occlusion::Region subResult = selfDrawRegion.Sub(accumulatedOcclusionRegion_);
1482 node.SetVisibleRegion(subResult);
1483 node.SetVisibleRegionBehindWindow(subResult.Sub(accumulatedOcclusionRegionBehindWindow_));
1484 Occlusion::Region subResultWithoutSkipLayer = selfDrawRegion.Sub(occlusionRegionWithoutSkipLayer_);
1485 node.SetVisibleRegionInVirtual(subResultWithoutSkipLayer);
1486 }
1487 RS_OPTIONAL_TRACE_NAME_FMT_LEVEL(TRACE_LEVEL_THREE,
1488 "RSUniRenderVisitor::UpdateNodeVisibleRegion name[%s] visibleRegion[%s] "
1489 "visibleRegionBehindWindow[%s]",
1490 node.GetName().c_str(), node.GetVisibleRegion().GetRegionInfo().c_str(),
1491 node.GetVisibleRegionBehindWindow().GetRegionInfo().c_str());
1492 }
1493
CalculateOpaqueAndTransparentRegion(RSSurfaceRenderNode & node)1494 CM_INLINE void RSUniRenderVisitor::CalculateOpaqueAndTransparentRegion(RSSurfaceRenderNode& node)
1495 {
1496 if (!curScreenNode_) {
1497 RS_LOGE("CalculateOpaqueAndTransparentRegion curScreenNode is nullptr");
1498 return;
1499 }
1500 // occlusion - 1. Only non-cross-screen main window surface node participate in occlusion.
1501 if ((!curScreenNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) ||
1502 !node.IsMainWindowType()) {
1503 RS_LOGD("CalculateOpaqueAndTransparentRegion Node: %{public}s, NodeId: %{public}" PRIu64
1504 " not paticipate in occlusion", node.GetName().c_str(), node.GetId());
1505 return;
1506 }
1507
1508 // occlusion - 2. Calculate opaque/transparent region based on round corner, container window, etc.
1509 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1510 auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
1511 (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
1512 node.CheckAndUpdateOpaqueRegion(curScreenNode_->GetScreenRect(), curLogicalDisplayNode_->GetRotation(), isFocused);
1513 // occlusion - 3. Accumulate opaque region to occlude lower surface nodes (with/without special layer).
1514 hasSkipLayer_ = hasSkipLayer_ || node.GetSpecialLayerMgr().Find(SpecialLayerType::SKIP);
1515 auto mainThread = RSMainThread::Instance();
1516 node.SetOcclusionInSpecificScenes(mainThread->GetIsRegularAnimation());
1517 bool occlusionInAnimation = node.GetOcclusionInSpecificScenes() || !ancestorNodeHasAnimation_;
1518 bool isParticipateInOcclusion = node.CheckParticipateInOcclusion() &&
1519 occlusionInAnimation && !isAllSurfaceVisibleDebugEnabled_ && !node.IsAttractionAnimation();
1520 CollectTopOcclusionSurfacesInfo(node, isParticipateInOcclusion);
1521 if (isParticipateInOcclusion) {
1522 RS_OPTIONAL_TRACE_NAME_FMT("Occlusion: surface node[%s] participate in occlusion with opaque region: [%s]",
1523 node.GetName().c_str(), node.GetOpaqueRegion().GetRegionInfo().c_str());
1524 accumulatedOcclusionRegion_.OrSelf(node.GetOpaqueRegion());
1525 if (node.NeedDrawBehindWindow()) {
1526 accumulatedOcclusionRegionBehindWindow_.OrSelf(Occlusion::Region(Occlusion::Rect(node.GetFilterRect())));
1527 }
1528 if (IsValidInVirtualScreen(node)) {
1529 occlusionRegionWithoutSkipLayer_.OrSelf(node.GetOpaqueRegion());
1530 }
1531 }
1532 needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.CheckIfOcclusionChanged();
1533 node.SetOcclusionInSpecificScenes(false);
1534 CollectOcclusionInfoForWMS(node);
1535 RSMainThread::Instance()->GetRSVsyncRateReduceManager().CollectSurfaceVsyncInfo(
1536 curScreenNode_->GetScreenInfo(), node);
1537 }
1538
CollectOcclusionInfoForWMS(RSSurfaceRenderNode & node)1539 void RSUniRenderVisitor::CollectOcclusionInfoForWMS(RSSurfaceRenderNode& node)
1540 {
1541 if (!node.IsMainWindowType()) {
1542 return;
1543 }
1544 // collect mainWindow occlusion visibleLevel
1545 Occlusion::Region selfDrawRegion { node.GetSurfaceOcclusionRect(true) };
1546 auto visibleLevel = GetRegionVisibleLevel(node.GetVisibleRegion(), selfDrawRegion);
1547
1548 // wms default all visible about sefdrawing node and AbilityComponent node
1549 auto instanceNode = node.GetInstanceRootNode() ?
1550 node.GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1551 if (instanceNode == nullptr) {
1552 return;
1553 }
1554 if ((node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
1555 !instanceNode->GetVisibleRegion().IsEmpty()) || node.IsAbilityComponent()) {
1556 dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1557 WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1558 return;
1559 }
1560 dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1561 node.GetVisibleLevelForWMS(visibleLevel)));
1562 }
1563
SurfaceOcclusionCallbackToWMS()1564 void RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS()
1565 {
1566 if (RSSystemParameters::GetOcclusionCallBackToWMSDebugType()) {
1567 allDstCurVisVec_.clear();
1568 const auto& curAllSurfaces = curScreenNode_->GetAllMainAndLeashSurfaces();
1569 for (const auto& surfacePtr : curAllSurfaces) {
1570 if (surfacePtr == nullptr) {
1571 continue;
1572 }
1573 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*surfacePtr);
1574 if (surfaceNode.IsMainWindowType()) {
1575 allDstCurVisVec_.emplace_back(std::make_pair(surfacePtr->GetId(),
1576 WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1577 }
1578 }
1579 }
1580 if (allDstCurVisVec_ != allLastVisVec_) {
1581 RSMainThread::Instance()->SurfaceOcclusionChangeCallback(allDstCurVisVec_);
1582 HILOG_COMM_INFO("OcclusionInfo %{public}s", VisibleDataToString(allDstCurVisVec_).c_str());
1583 allLastVisVec_ = std::move(allDstCurVisVec_);
1584 }
1585 }
1586
GetRegionVisibleLevel(const Occlusion::Region & visibleRegion,const Occlusion::Region & selfDrawRegion)1587 RSVisibleLevel RSUniRenderVisitor::GetRegionVisibleLevel(const Occlusion::Region& visibleRegion,
1588 const Occlusion::Region& selfDrawRegion)
1589 {
1590 if (visibleRegion.IsEmpty()) {
1591 return RSVisibleLevel::RS_INVISIBLE;
1592 } else if (visibleRegion.Area() == selfDrawRegion.Area()) {
1593 return RSVisibleLevel::RS_ALL_VISIBLE;
1594 } else if (static_cast<uint>(visibleRegion.Area()) <
1595 (static_cast<uint>(selfDrawRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
1596 return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
1597 }
1598 return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
1599 }
1600
QuickPrepareEffectRenderNode(RSEffectRenderNode & node)1601 void RSUniRenderVisitor::QuickPrepareEffectRenderNode(RSEffectRenderNode& node)
1602 {
1603 RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "CheckCacheTypeAndDraw nodeId[%llu]", node.GetId());
1604 UpdateCurFrameInfoDetail(node);
1605 // 0. check current node need to tranverse
1606 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curScreenDirtyManager_;
1607 if (!dirtyManager) {
1608 RS_LOGE("QuickPrepareEffectRenderNode dirtyManager is nullptr");
1609 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1610 return;
1611 }
1612 auto dirtyFlag = dirtyFlag_;
1613 auto prevAlpha = curAlpha_;
1614 auto curCornerRadius = curCornerRadius_;
1615 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1616 UpdateRotationStatusForEffectNode(node);
1617 CheckFilterCacheNeedForceClearOrSave(node);
1618 MarkFilterInForegroundFilterAndCheckNeedForceClearCache(node);
1619 RectI prepareClipRect = prepareClipRect_;
1620 bool hasAccumulatedClip = hasAccumulatedClip_;
1621 dirtyFlag_ =
1622 node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1623 node.UpdateCurCornerRadius(curCornerRadius_);
1624 // 1. Recursively traverse child nodes
1625 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1626 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
1627 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1628 node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1629
1630 PostPrepare(node, !isSubTreeNeedPrepare);
1631 prepareClipRect_ = prepareClipRect;
1632 hasAccumulatedClip_ = hasAccumulatedClip;
1633 dirtyFlag_ = dirtyFlag;
1634 curAlpha_ = prevAlpha;
1635 curCornerRadius_ = curCornerRadius;
1636 node.RenderTraceDebug();
1637 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1638 }
1639
MarkFilterInForegroundFilterAndCheckNeedForceClearCache(RSRenderNode & node)1640 void RSUniRenderVisitor::MarkFilterInForegroundFilterAndCheckNeedForceClearCache(RSRenderNode& node)
1641 {
1642 node.MarkFilterInForegroundFilterAndCheckNeedForceClearCache(offscreenCanvasNodeId_);
1643 }
1644
UpdateDrawingCacheInfoBeforeChildren(RSCanvasRenderNode & node)1645 void RSUniRenderVisitor::UpdateDrawingCacheInfoBeforeChildren(RSCanvasRenderNode& node)
1646 {
1647 if (!isDrawingCacheEnabled_) {
1648 return;
1649 }
1650 node.UpdateDrawingCacheInfoBeforeChildren(isScreenRotationAnimating_);
1651 if (node.GetDrawingCacheType() == RSDrawingCacheType::FOREGROUND_FILTER_CACHE) {
1652 offscreenCanvasNodeId_ = node.GetId();
1653 }
1654 }
1655
UpdateOffscreenCanvasNodeId(RSCanvasRenderNode & node)1656 void RSUniRenderVisitor::UpdateOffscreenCanvasNodeId(RSCanvasRenderNode& node)
1657 {
1658 if (node.IsForegroundFilterEnable()) {
1659 offscreenCanvasNodeId_ = node.GetId();
1660 }
1661 }
1662
QuickPrepareCanvasRenderNode(RSCanvasRenderNode & node)1663 void RSUniRenderVisitor::QuickPrepareCanvasRenderNode(RSCanvasRenderNode& node)
1664 {
1665 RS_OPTIONAL_TRACE_BEGIN_LEVEL(TRACE_LEVEL_PRINT_NODEID, "QuickPrepareCanvasRenderNode nodeId[%llu]", node.GetId());
1666 UpdateCurFrameInfoDetail(node);
1667 // 0. check current node need to traverse
1668 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curScreenDirtyManager_;
1669 auto dirtyFlag = dirtyFlag_;
1670 auto prevAlpha = curAlpha_;
1671 auto curCornerRadius = curCornerRadius_;
1672 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1673 auto preGlobalShouldPaint = globalShouldPaint_;
1674 auto preOffscreenCanvasNodeId = offscreenCanvasNodeId_;
1675 globalShouldPaint_ &= node.ShouldPaint();
1676 CheckFilterCacheNeedForceClearOrSave(node);
1677 bool isAccessibilityConfigChanged = IsAccessibilityConfigChanged();
1678 if (isAccessibilityConfigChanged) {
1679 node.SetIsAccessibilityConfigChanged(true);
1680 }
1681 UpdateDrawingCacheInfoBeforeChildren(node);
1682 UpdateOffscreenCanvasNodeId(node);
1683 MarkFilterInForegroundFilterAndCheckNeedForceClearCache(node);
1684 node.SetIsAccessibilityConfigChanged(false);
1685 // The opinc state needs to be reset in the following cases:
1686 // 1. subtree is dirty
1687 // 2. content is dirty
1688 // 3. the node is marked as a node group
1689 // 4. the node is marked as a root node of opinc and the high-contrast state change
1690 auto isSelfDirty = node.IsSubTreeDirty() || node.IsContentDirty() ||
1691 node.GetNodeGroupType() > RSRenderNode::NodeGroupType::NONE ||
1692 (node.GetOpincCache().OpincGetRootFlag() && isAccessibilityConfigChanged);
1693 node.GetOpincCache().OpincQuickMarkStableNode(unchangeMarkInApp_, unchangeMarkEnable_, isSelfDirty);
1694 node.UpdateOpincParam();
1695 RectI prepareClipRect = prepareClipRect_;
1696 bool hasAccumulatedClip = hasAccumulatedClip_;
1697
1698 if (!dirtyManager) {
1699 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1700 return;
1701 }
1702 dirtyFlag_ =
1703 node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1704
1705 // update prepare clip before children
1706 hwcVisitor_->UpdatePrepareClip(node);
1707 node.UpdateCurCornerRadius(curCornerRadius_);
1708
1709 bool isCurrOffscreen = hwcVisitor_->UpdateIsOffscreen(node);
1710 hwcVisitor_->UpdateForegroundColorValid(node);
1711
1712 node.GetHwcRecorder().UpdatePositionZ(node.GetRenderProperties().GetPositionZ());
1713 if (node.GetHwcRecorder().GetZorderChanged() && curSurfaceNode_) {
1714 curSurfaceNode_->SetNeedCollectHwcNode(true);
1715 }
1716
1717 // 1. Recursively traverse child nodes if above curSurfaceNode and subnode need draw
1718 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1719 bool isOpincSubTreeDirty = RSOpincManager::Instance().IsOpincSubTreeDirty(node, autoCacheEnable_);
1720 bool isSubTreeNeedPrepare = !curSurfaceNode_ || node.IsSubTreeNeedPrepare(filterInGlobal_) ||
1721 ForcePrepareSubTree() || isOpincSubTreeDirty;
1722 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1723 node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1724
1725 PostPrepare(node, !isSubTreeNeedPrepare);
1726 prepareClipRect_ = prepareClipRect;
1727 hasAccumulatedClip_ = hasAccumulatedClip;
1728 dirtyFlag_ = dirtyFlag;
1729 curAlpha_ = prevAlpha;
1730 curCornerRadius_ = curCornerRadius;
1731 node.GetOpincCache().OpincUpdateRootFlag(unchangeMarkEnable_,
1732 RSOpincManager::Instance().OpincGetNodeSupportFlag(node));
1733 node.UpdateOpincParam();
1734 offscreenCanvasNodeId_ = preOffscreenCanvasNodeId;
1735 #ifdef SUBTREE_PARALLEL_ENABLE
1736 // used in subtree, add node into parallel list
1737 node.UpdateSubTreeParallelNodes();
1738 #endif
1739 // [Attention] Only used in PC window resize scene now
1740 NodeId linedRootNodeId = node.GetLinkedRootNodeId();
1741 if (UNLIKELY(linedRootNodeId != INVALID_NODEID)) {
1742 windowKeyFrameNodeInf_.UpdateLinkedNodeId(node.GetId(), linedRootNodeId);
1743 }
1744
1745 globalShouldPaint_ = preGlobalShouldPaint;
1746
1747 hwcVisitor_->RestoreIsOffscreen(isCurrOffscreen);
1748
1749 node.RenderTraceDebug();
1750 RS_OPTIONAL_TRACE_END_LEVEL(TRACE_LEVEL_PRINT_NODEID);
1751 }
1752
UpdateRotationStatusForEffectNode(RSEffectRenderNode & node)1753 void RSUniRenderVisitor::UpdateRotationStatusForEffectNode(RSEffectRenderNode& node)
1754 {
1755 // folding/expanding screen force invalidate cache.
1756 node.SetFoldStatusChanged(doAnimate_ &&
1757 curScreenNode_->GetScreenId() != node.GetCurrentAttachedScreenId());
1758 node.SetCurrentAttachedScreenId(curScreenNode_->GetScreenId());
1759 node.SetRotationChanged(curLogicalDisplayNode_->IsRotationChanged());
1760 }
1761
IsLeashAndHasMainSubNode(RSRenderNode & node) const1762 bool RSUniRenderVisitor::IsLeashAndHasMainSubNode(RSRenderNode& node) const
1763 {
1764 if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
1765 return false;
1766 }
1767 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1768 if (!surfaceNode.IsLeashWindow()) {
1769 return false;
1770 }
1771 // check leashWindow surface has first level mainwindow node
1772 auto children = node.GetSortedChildren();
1773 auto iter = std::find_if((*children).begin(), (*children).end(),
1774 [](const std::shared_ptr<RSRenderNode>& node) {
1775 if (node && node->GetType() == RSRenderNodeType::SURFACE_NODE) {
1776 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*node);
1777 return surfaceNode.IsMainWindowType();
1778 }
1779 return false;
1780 });
1781 return iter != (*children).end();
1782 }
1783
NeedPrepareChindrenInReverseOrder(RSRenderNode & node) const1784 bool RSUniRenderVisitor::NeedPrepareChindrenInReverseOrder(RSRenderNode& node) const
1785 {
1786 if ((!curSurfaceNode_ && node.GetType() != RSRenderNodeType::RS_NODE)) {
1787 return true;
1788 }
1789 return IsLeashAndHasMainSubNode(node);
1790 }
1791
QuickPrepareChildren(RSRenderNode & node)1792 void RSUniRenderVisitor::QuickPrepareChildren(RSRenderNode& node)
1793 {
1794 if (UNLIKELY(node.HasRemovedChild())) {
1795 MergeRemovedChildDirtyRegion(node, true);
1796 }
1797 if (node.LastFrameSubTreeSkipped() && curSurfaceDirtyManager_) {
1798 node.ForceMergeSubTreeDirtyRegion(*curSurfaceDirtyManager_, prepareClipRect_);
1799 }
1800 // Collect prepared node into the control-level occlusion culling handler.
1801 CollectNodeForOcclusion(node);
1802 bool animationBackup = ancestorNodeHasAnimation_;
1803 ancestorNodeHasAnimation_ = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
1804 node.ResetChildRelevantFlags();
1805 node.ResetChildUifirstSupportFlag();
1806 #ifdef SUBTREE_PARALLEL_ENABLE
1807 node.ClearSubtreeParallelNodes();
1808 node.ResetRepaintBoundaryInfo();
1809 #endif
1810 auto children = node.GetSortedChildren();
1811 if (NeedPrepareChindrenInReverseOrder(node)) {
1812 auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
1813 curFrameInfoDetail.curFrameReverseChildren = true;
1814 RS_LOGD("%{public}s NeedPrepareChindrenInReverseOrder nodeId: %{public}" PRIu64,
1815 __func__, node.GetId());
1816 std::for_each(
1817 (*children).rbegin(), (*children).rend(), [this, &node](const std::shared_ptr<RSRenderNode>& child) {
1818 if (!child) {
1819 return;
1820 }
1821 rsScreenNodeChildNum_++;
1822 auto containerDirty = curContainerDirty_;
1823 curDirty_ = child->IsDirty();
1824 curContainerDirty_ = curContainerDirty_ || child->IsDirty();
1825 child->SetFirstLevelCrossNode(node.IsFirstLevelCrossNode() || child->IsCrossNode());
1826 child->GetHwcRecorder().SetZOrderForHwcEnableByFilter(hwcVisitor_->curZOrderForHwcEnableByFilter_++);
1827 child->QuickPrepare(shared_from_this());
1828 #ifdef SUBTREE_PARALLEL_ENABLE
1829 node.MergeSubtreeParallelNodes(*child);
1830 #endif
1831 curContainerDirty_ = containerDirty;
1832 });
1833 } else {
1834 auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
1835 curFrameInfoDetail.curFrameReverseChildren = false;
1836 std::for_each(
1837 (*children).begin(), (*children).end(), [this, &node](const std::shared_ptr<RSRenderNode>& child) {
1838 if (!child) {
1839 return;
1840 }
1841 rsScreenNodeChildNum_++;
1842 curDirty_ = child->IsDirty();
1843 child->SetFirstLevelCrossNode(node.IsFirstLevelCrossNode() || child->IsCrossNode());
1844 child->GetHwcRecorder().SetZOrderForHwcEnableByFilter(hwcVisitor_->curZOrderForHwcEnableByFilter_++);
1845 child->QuickPrepare(shared_from_this());
1846 #ifdef SUBTREE_PARALLEL_ENABLE
1847 node.MergeSubtreeParallelNodes(*child);
1848 #endif
1849 });
1850 }
1851 ancestorNodeHasAnimation_ = animationBackup;
1852 node.ResetGeoUpdateDelay();
1853 }
1854
1855 // Used to collect prepared node into the control-level occlusion culling handler.
CollectNodeForOcclusion(RSRenderNode & node)1856 inline void RSUniRenderVisitor::CollectNodeForOcclusion(RSRenderNode& node)
1857 {
1858 if (curOcclusionHandler_) {
1859 curOcclusionHandler_->CollectNode(node);
1860 }
1861 }
1862
RegisterHpaeCallback(RSRenderNode & node)1863 void RSUniRenderVisitor::RegisterHpaeCallback(RSRenderNode& node)
1864 {
1865 #if defined(ROSEN_OHOS) && defined(ENABLE_HPAE_BLUR)
1866 RSHpaeManager::GetInstance().RegisterHpaeCallback(node, screenInfo_.phyWidth, screenInfo_.phyHeight);
1867 #endif
1868 }
1869
UpdateCompositeType(RSScreenRenderNode & node)1870 void RSUniRenderVisitor::UpdateCompositeType(RSScreenRenderNode& node)
1871 {
1872 // 5. check compositeType
1873 auto mirrorNode = node.GetMirrorSource().lock();
1874 switch (node.GetScreenInfo().state) {
1875 case ScreenState::SOFTWARE_OUTPUT_ENABLE:
1876 node.SetCompositeType(mirrorNode ?
1877 CompositeType::UNI_RENDER_MIRROR_COMPOSITE :
1878 CompositeType::UNI_RENDER_EXPAND_COMPOSITE);
1879 break;
1880 case ScreenState::HDI_OUTPUT_ENABLE:
1881 node.SetCompositeType(node.IsForceSoftComposite() ?
1882 CompositeType::SOFTWARE_COMPOSITE :
1883 CompositeType::UNI_RENDER_COMPOSITE);
1884 break;
1885 default:
1886 break;
1887 }
1888 }
1889
InitScreenInfo(RSScreenRenderNode & node)1890 bool RSUniRenderVisitor::InitScreenInfo(RSScreenRenderNode& node)
1891 {
1892 // 1 init curScreen and curScreenDirtyManager
1893 hasFingerprint_ = false;
1894 curScreenDirtyManager_ = node.GetDirtyManager();
1895 curScreenNode_ = node.shared_from_this()->ReinterpretCastTo<RSScreenRenderNode>();
1896 if (!curScreenDirtyManager_ || !curScreenNode_) {
1897 RS_LOGE("InitScreenInfo dirtyMgr or node ptr is nullptr");
1898 return false;
1899 }
1900 #ifdef RS_ENABLE_PREFETH
1901 __builtin_prefetch(curScreenNode_.get(), 0, 1);
1902 #endif
1903 curScreenDirtyManager_->SetAdvancedDirtyRegionType(advancedDirtyType_);
1904 curScreenDirtyManager_->Clear();
1905 hwcVisitor_->transparentHwcCleanFilter_.clear();
1906 hwcVisitor_->transparentHwcDirtyFilter_.clear();
1907 node.SetHasChildCrossNode(false);
1908 node.SetIsFirstVisitCrossNodeDisplay(false);
1909 node.SetHasUniRenderHdrSurface(false);
1910 node.SetIsLuminanceStatusChange(false);
1911 node.SetPixelFormat(GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_8888);
1912 node.SetExistHWCNode(false);
1913 CheckLuminanceStatusChange(curScreenNode_->GetScreenId());
1914
1915 // 2 init screenManager info
1916 auto screenInfo = screenManager_->QueryScreenInfo(node.GetScreenId());
1917 node.SetScreenRect(screenInfo.activeRect.IsEmpty() ? RectI{0, 0, screenInfo.width, screenInfo.height} :
1918 screenInfo.activeRect);
1919 node.SetScreenInfo(std::move(screenInfo));
1920 curScreenDirtyManager_->SetSurfaceSize(
1921 curScreenNode_->GetScreenInfo().width, curScreenNode_->GetScreenInfo().height);
1922 curScreenDirtyManager_->SetActiveSurfaceRect(curScreenNode_->GetScreenInfo().activeRect);
1923 screenManager_->SetScreenHasProtectedLayer(node.GetScreenId(), false);
1924 allBlackList_ = screenManager_->GetAllBlackList();
1925 allWhiteList_ = screenManager_->GetAllWhiteList();
1926 screenWhiteList_ = screenManager_->GetScreenWhiteList();
1927 node.GetLogicalDisplayNodeDrawables().clear();
1928
1929 // 3 init Occlusion info
1930 needRecalculateOcclusion_ = false;
1931 accumulatedOcclusionRegion_.Reset();
1932 accumulatedOcclusionRegionBehindWindow_.Reset();
1933 occlusionRegionWithoutSkipLayer_.Reset();
1934 if (!curMainAndLeashWindowNodesIds_.empty()) {
1935 std::queue<NodeId>().swap(curMainAndLeashWindowNodesIds_);
1936 }
1937
1938 // 4. check isHardwareForcedDisabled
1939 auto geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
1940 if (geoPtr == nullptr) {
1941 RS_LOGE("InitScreenInfo geoPtr is nullptr");
1942 return false;
1943 }
1944 if (geoPtr->IsNeedClientCompose()) {
1945 hwcVisitor_->isHardwareForcedDisabled_ = true;
1946 RS_OPTIONAL_TRACE_FMT("hwc debug: id:%" PRIu64 " disabled by screenNode rotation", node.GetId());
1947 }
1948
1949 // init hdr
1950 node.ResetDisplayHdrStatus();
1951 node.SetColorSpace(GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB);
1952
1953 // [Attention] Only used in PC window resize scene now
1954 windowKeyFrameNodeInf_.ClearLinkedNodeInfo();
1955
1956 return true;
1957 }
1958
BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1959 CM_INLINE bool RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1960 {
1961 // 1. init and record surface info
1962 if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
1963 curLogicalDisplayNode_->SetHasCaptureWindow(true);
1964 }
1965 node.UpdateUIFirstFrameGravity();
1966 if (node.IsMainWindowType() || node.IsLeashWindow()) {
1967 // if firstLevelNode has attration animation,
1968 // subsurface with main window type, set attraction animation flag to skip filter cache occlusion
1969 auto firstLevelNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
1970 node.GetFirstLevelNode());
1971 node.SetAttractionAnimation(firstLevelNode != nullptr &&
1972 firstLevelNode->GetRenderProperties().IsAttractionValid());
1973 node.SetStencilVal(Drawing::Canvas::INVALID_STENCIL_VAL);
1974 // UpdateCurCornerRadius must process before curSurfaceNode_ update
1975 node.UpdateCurCornerRadius(curCornerRadius_);
1976 curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1977 // dirty manager should not be overrode by cross node in expand screen
1978 curSurfaceDirtyManager_ = (!curScreenNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) ?
1979 std::make_shared<RSDirtyRegionManager>() : node.GetDirtyManager();
1980 if (!curSurfaceDirtyManager_ || !curSurfaceNode_) {
1981 RS_LOGE("BeforeUpdateSurfaceDirtyCalc %{public}s has invalid "
1982 "SurfaceDirtyManager or node ptr", node.GetName().c_str());
1983 return false;
1984 }
1985 curSurfaceDirtyManager_->Clear();
1986 auto& screenInfo = curScreenNode_->GetScreenInfo();
1987 curSurfaceDirtyManager_->SetSurfaceSize(screenInfo.width, screenInfo.height);
1988 curSurfaceDirtyManager_->SetActiveSurfaceRect(screenInfo.activeRect);
1989 filterInGlobal_ = curSurfaceNode_->IsTransparent();
1990 // update surfaceNode contentDirty and subTreeDirty flag for UIFirst purging policy
1991 RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1992 curSurfaceNode_->UpdateSurfaceCacheContentStaticFlag(IsAccessibilityConfigChanged());
1993 curSurfaceNode_->UpdateSurfaceSubTreeDirtyFlag();
1994 } else if (node.IsAbilityComponent()) {
1995 if (auto nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>()) {
1996 RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(nodePtr);
1997 nodePtr->UpdateSurfaceCacheContentStaticFlag(IsAccessibilityConfigChanged());
1998 }
1999 }
2000 // 2. update surface info and CheckIfOcclusionReusable
2001 node.SetAncestorScreenNode(curScreenNode_); // set for boot animation
2002 node.UpdateAncestorScreenNodeInRenderParams();
2003 node.CleanDstRectChanged();
2004 // [planning] check node isDirty can be optimized.
2005 needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.IsDirty() ||
2006 node.CheckIfOcclusionReusable(preMainAndLeashWindowNodesIds_);
2007 if (autoCacheEnable_ && node.IsAppWindow()) {
2008 node.GetOpincCache().OpincSetInAppStateStart(unchangeMarkInApp_);
2009 }
2010 // 3. check pixelFormat and update RelMatrix
2011 CheckPixelFormat(node);
2012 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
2013 node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
2014 }
2015 // 4. collect cursors and check for null
2016 RSPointerWindowManager::Instance().CollectAllHardCursor(node, curScreenNode_, curLogicalDisplayNode_);
2017 return true;
2018 }
2019
AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)2020 CM_INLINE bool RSUniRenderVisitor::AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
2021 {
2022 // 1. Update surfaceNode info and AppWindow gravity
2023 const auto& property = node.GetRenderProperties();
2024 if (node.IsAppWindow()) {
2025 boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
2026 frameGravity_ = property.GetFrameGravity();
2027 }
2028 auto& geoPtr = property.GetBoundsGeometry();
2029 if (geoPtr == nullptr) {
2030 return false;
2031 }
2032 hwcVisitor_->UpdateCrossInfoForProtectedHwcNode(node);
2033 hwcVisitor_->UpdateDstRect(node, geoPtr->GetAbsRect(), prepareClipRect_);
2034 node.UpdatePositionZ();
2035 if (node.IsHardwareEnabledType() && node.GetZorderChanged() && curSurfaceNode_) {
2036 curSurfaceNode_->SetNeedCollectHwcNode(true);
2037 }
2038 UpdateSurfaceRenderNodeScale(node);
2039 UpdateSurfaceRenderNodeRotate(node);
2040 if (node.IsLeashWindow()) {
2041 curScreenNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirtyInSurface());
2042 curScreenNode_->AddSurfaceNodePosByDescZOrder(node.GetId(), node.GetOldDirtyInSurface());
2043 }
2044 // 2. Update Occlusion info before children preparation
2045 if (node.IsLeashOrMainWindow()) {
2046 UpdateNodeVisibleRegion(node);
2047 }
2048 // 3. Update HwcNode Info for appNode
2049 UpdateHwcNodeInfoForAppNode(node);
2050 if (node.IsHardwareEnabledTopSurface()) {
2051 hwcVisitor_->UpdateTopSurfaceSrcRect(node, geoPtr->GetAbsMatrix(), geoPtr->GetAbsRect());
2052 RSPointerWindowManager::CheckHardCursorValid(node);
2053 }
2054 // 4. Update color gamut for appNode
2055 if (!ColorGamutParam::SkipOccludedNodeDuringColorGamutCollection() ||
2056 !node.GetVisibleRegion().IsEmpty() || !GetIsOpDropped()) {
2057 CheckColorSpace(node);
2058 }
2059 return true;
2060 }
2061
UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode & node)2062 void RSUniRenderVisitor::UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode& node)
2063 {
2064 // app node
2065 if (node.GetNeedCollectHwcNode()) {
2066 node.ResetChildHardwareEnabledNodes();
2067 node.SetExistTransparentHardwareEnabledNode(false);
2068 }
2069 // hwc node
2070 if (node.IsHardwareEnabledType() && curSurfaceNode_) {
2071 if (curSurfaceNode_->GetNeedCollectHwcNode()) {
2072 curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
2073 }
2074 auto& geo = node.GetRenderProperties().GetBoundsGeometry();
2075 if (geo == nullptr) {
2076 return;
2077 }
2078 hwcVisitor_->UpdateHwcNodeInfo(node, geo->GetAbsMatrix(), geo->GetAbsRect());
2079 }
2080 }
2081
ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode> & hwcNodePtr,bool & ancoHasGpu)2082 void RSUniRenderVisitor::ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr, bool& ancoHasGpu)
2083 {
2084 if (hwcNodePtr == nullptr) {
2085 return;
2086 }
2087 auto alpha = hwcNodePtr->GetGlobalAlpha();
2088 RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 "src %{public}s dst %{public}s "
2089 "alpha:%{public}.2f", hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(),
2090 hwcNodePtr->GetSrcRect().ToString().c_str(), hwcNodePtr->GetDstRect().ToString().c_str(), alpha);
2091 if (ROSEN_EQ(alpha, 0.0f)) {
2092 return;
2093 }
2094
2095 if (!hwcNodePtr->GetRSSurfaceHandler() || !hwcNodePtr->GetRSSurfaceHandler()->GetBuffer()) {
2096 RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 " handler or buffer is null, skip",
2097 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2098 return;
2099 }
2100 if (hwcNodePtr->IsHardwareForcedDisabled()) {
2101 RS_OPTIONAL_TRACE_NAME_FMT("ProcessAncoNode: name:%s id:%" PRIu64 " hardware forced disabled",
2102 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2103 }
2104 ancoHasGpu = (ancoHasGpu || hwcNodePtr->IsHardwareForcedDisabled());
2105 }
2106
UpdateAncoNodeHWCDisabledState(std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>> & ancoNodes)2107 void RSUniRenderVisitor::UpdateAncoNodeHWCDisabledState(
2108 std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>>& ancoNodes)
2109 {
2110 bool ancoHasGpu = false;
2111 for (auto hwcNodePtr : ancoNodes) {
2112 ProcessAncoNode(hwcNodePtr, ancoHasGpu);
2113 }
2114 if (ancoHasGpu) {
2115 for (const auto& hwcNodePtr : ancoNodes) {
2116 RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by anco has gpu",
2117 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2118 hwcNodePtr->SetHardwareForcedDisabledState(true);
2119 }
2120 }
2121 }
2122
PrevalidateHwcNode()2123 void RSUniRenderVisitor::PrevalidateHwcNode()
2124 {
2125 if (!RSUniHwcPrevalidateUtil::GetInstance().IsPrevalidateEnable()) {
2126 RS_LOGD_IF(DEBUG_PREVALIDATE, "PrevalidateHwcNode prevalidate close");
2127 hwcVisitor_->PrintHiperfCounterLog("counter2", static_cast<uint64_t>(0));
2128 return;
2129 }
2130 auto& curMainAndLeashSurfaces = curScreenNode_->GetAllMainAndLeashSurfaces();
2131 std::vector<RequestLayerInfo> prevalidLayers;
2132 uint32_t curFps = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(curScreenNode_->GetScreenId());
2133 uint32_t zOrder = static_cast<uint32_t>(globalZOrder_);
2134 // add surfaceNode layer
2135 RSUniHwcPrevalidateUtil::GetInstance().CollectSurfaceNodeLayerInfo(
2136 prevalidLayers, curMainAndLeashSurfaces, curFps, zOrder, curScreenNode_->GetScreenInfo());
2137 RS_TRACE_NAME_FMT("PrevalidateHwcNode hwcLayer: %u", prevalidLayers.size());
2138 if (prevalidLayers.size() == 0) {
2139 RS_LOGI_IF(DEBUG_PREVALIDATE, "PrevalidateHwcNode no hardware layer");
2140 hwcVisitor_->PrintHiperfCounterLog("counter2", INPUT_HWC_LAYERS);
2141 RSHpaeOfflineProcessor::GetOfflineProcessor().CheckAndPostClearOfflineResourceTask();
2142 return;
2143 }
2144 // add display layer
2145 RequestLayerInfo screenLayer;
2146 if (RSUniHwcPrevalidateUtil::GetInstance().CreateScreenNodeLayerInfo(
2147 zOrder++, curScreenNode_, curScreenNode_->GetScreenInfo(), curFps, screenLayer)) {
2148 prevalidLayers.emplace_back(screenLayer);
2149 }
2150 // add rcd layer
2151 RequestLayerInfo rcdLayer;
2152 if (RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
2153 auto rcdSurface = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curScreenNode_->GetRcdSurfaceNodeTop());
2154 if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(
2155 rcdSurface, curScreenNode_->GetScreenInfo(), curFps, rcdLayer)) {
2156 prevalidLayers.emplace_back(rcdLayer);
2157 }
2158 rcdSurface = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curScreenNode_->GetRcdSurfaceNodeBottom());
2159 if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(
2160 rcdSurface, curScreenNode_->GetScreenInfo(), curFps, rcdLayer)) {
2161 prevalidLayers.emplace_back(rcdLayer);
2162 }
2163 }
2164 hwcVisitor_->PrintHiperfCounterLog("counter2", static_cast<uint64_t>(prevalidLayers.size()));
2165 std::map<uint64_t, RequestCompositionType> strategy;
2166 if (!RSUniHwcPrevalidateUtil::GetInstance().PreValidate(
2167 curScreenNode_->GetScreenInfo().id, prevalidLayers, strategy)) {
2168 RS_LOGI_IF(DEBUG_PREVALIDATE, "PrevalidateHwcNode prevalidate failed");
2169 return;
2170 }
2171 {
2172 auto iter = std::find_if(strategy.begin(), strategy.end(),
2173 [](const auto& elem) { return elem.second == RequestCompositionType::OFFLINE_DEVICE; });
2174 if (iter == strategy.end()) {
2175 RSHpaeOfflineProcessor::GetOfflineProcessor().CheckAndPostClearOfflineResourceTask();
2176 }
2177 }
2178 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2179 for (auto it : strategy) {
2180 RS_LOGD_IF(DEBUG_PREVALIDATE, "PrevalidateHwcNode id: %{public}" PRIu64 ","
2181 " result: %{public}d", it.first, it.second);
2182 if (it.second == RequestCompositionType::DEVICE) {
2183 continue;
2184 }
2185 auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(it.first);
2186 if (node == nullptr) {
2187 continue;
2188 }
2189 if (it.second == RequestCompositionType::DEVICE_VSCF) {
2190 node->SetArsrTag(false);
2191 continue;
2192 }
2193 if (it.second == RequestCompositionType::OFFLINE_DEVICE &&
2194 RSHpaeOfflineProcessor::GetOfflineProcessor().IsRSHpaeOfflineProcessorReady()) {
2195 node->SetDeviceOfflineEnable(true);
2196 continue;
2197 }
2198 if (node->IsInFixedRotation() || node->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2199 continue;
2200 }
2201 RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by preValidate",
2202 node->GetName().c_str(), node->GetId());
2203 hwcVisitor_->PrintHiperfLog(node, "preValidate");
2204 node->SetHardwareForcedDisabledState(true);
2205 if (node->GetRSSurfaceHandler()) {
2206 node->GetRSSurfaceHandler()->SetGlobalZOrder(-1.f);
2207 }
2208 hwcVisitor_->Statistics().UpdateHwcDisabledReasonForDFX(node->GetId(),
2209 HwcDisabledReasons::DISABLED_BY_PREVALIDATE, node->GetName());
2210 }
2211 }
2212
UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode> & node)2213 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode>& node)
2214 {
2215 const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
2216 if (hwcNodes.empty() || !curScreenNode_) {
2217 return;
2218 }
2219 std::vector<std::shared_ptr<RSSurfaceRenderNode>> topLayers;
2220 for (auto hwcNode : hwcNodes) {
2221 auto hwcNodePtr = hwcNode.lock();
2222 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2223 continue;
2224 }
2225 auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
2226 if (hwcNodePtr->IsLayerTop()) {
2227 topLayers.emplace_back(hwcNodePtr);
2228 if (hasMirrorDisplay_ && hwcNodePtr->GetRSSurfaceHandler() &&
2229 hwcNodePtr->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
2230 !(node->GetVisibleRegion().IsEmpty()) && curScreenDirtyManager_) {
2231 // merge hwc top node dst rect for virtual screen dirty, in case the main display node skip
2232 curScreenDirtyManager_->MergeHwcDirtyRect(hwcNodePtr->GetDstRect());
2233 }
2234 continue;
2235 }
2236 if (((curScreenNode_->GetHasUniRenderHdrSurface() && !RSHdrUtil::GetRGBA1010108Enabled()) ||
2237 !drmNodes_.empty() || hasFingerprint_) &&
2238 !hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2239 RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64
2240 " disabled by Having UniRenderHdrSurface/DRM node",
2241 node->GetName().c_str(), node->GetId());
2242 hwcVisitor_->PrintHiperfLog(node, "uniRender HDR");
2243 hwcNodePtr->SetHardwareForcedDisabledState(true);
2244 // DRM will force HDR to use unirender
2245 curScreenNode_->SetHasUniRenderHdrSurface(curScreenNode_->GetHasUniRenderHdrSurface() ||
2246 RSHdrUtil::CheckIsHdrSurface(*hwcNodePtr) != HdrStatus::NO_HDR);
2247 hwcVisitor_->Statistics().UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
2248 HwcDisabledReasons::DISABLED_BY_RENDER_HDR_SURFACE, hwcNodePtr->GetName());
2249 }
2250 UpdateHwcNodeDirtyRegionForApp(node, hwcNodePtr);
2251 hwcNodePtr->SetCalcRectInPrepare(false);
2252 surfaceHandler->SetGlobalZOrder(hwcNodePtr->IsHardwareForcedDisabled() &&
2253 !hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED) ? -1.f : globalZOrder_++);
2254 auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(hwcNodePtr->GetStagingRenderParams().get());
2255 if (stagingSurfaceParams->GetIsHwcEnabledBySolidLayer()) {
2256 surfaceHandler->SetGlobalZOrder(globalZOrder_++);
2257 }
2258 auto transform = RSUniHwcComputeUtil::GetLayerTransform(*hwcNodePtr, curScreenNode_->GetScreenInfo());
2259 hwcNodePtr->UpdateHwcNodeLayerInfo(transform);
2260 }
2261 curScreenNode_->SetDisplayGlobalZOrder(globalZOrder_);
2262 if (!topLayers.empty()) {
2263 UpdateTopLayersDirtyStatus(topLayers);
2264 }
2265 }
2266
UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode> & pointWindow)2267 void RSUniRenderVisitor::UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode>& pointWindow)
2268 {
2269 if (!pointWindow->IsHardwareEnabledTopSurface()) {
2270 pointWindow->SetHardCursorStatus(false);
2271 RSPointerWindowManager::Instance().SetIsPointerEnableHwc(false);
2272 return;
2273 }
2274 std::shared_ptr<RSSurfaceHandler> pointSurfaceHandler = pointWindow->GetMutableRSSurfaceHandler();
2275 if (pointSurfaceHandler) {
2276 // globalZOrder_ is screenNode layer, point window must be at the top.
2277 pointSurfaceHandler->SetGlobalZOrder(static_cast<float>(TopLayerZOrder::POINTER_WINDOW));
2278 if (!curScreenNode_) {
2279 return;
2280 }
2281 bool isHardCursor = RSPointerWindowManager::Instance().CheckHardCursorSupport(curScreenNode_->GetScreenId());
2282 if (isHardCursor) {
2283 // Set the highest z-order for hardCursor
2284 pointSurfaceHandler->SetGlobalZOrder(static_cast<float>(TopLayerZOrder::POINTER_WINDOW));
2285 }
2286 pointWindow->SetHardwareForcedDisabledState(true);
2287 RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by pointWindow and pointSurfaceHandler",
2288 pointWindow->GetName().c_str(), pointWindow->GetId());
2289 bool isMirrorMode = RSPointerWindowManager::Instance().HasMirrorDisplay();
2290 RSPointerWindowManager::Instance().SetIsPointerEnableHwc(isHardCursor && !isMirrorMode);
2291 auto transform = RSUniHwcComputeUtil::GetLayerTransform(*pointWindow, curScreenNode_->GetScreenInfo());
2292 pointWindow->SetHardCursorStatus(isHardCursor);
2293 pointWindow->UpdateHwcNodeLayerInfo(transform, isHardCursor);
2294 if (isHardCursor) {
2295 RSPointerWindowManager::Instance().UpdatePointerDirtyToGlobalDirty(pointWindow, curScreenNode_);
2296 }
2297 }
2298 }
2299
UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>> & topLayers)2300 void RSUniRenderVisitor::UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& topLayers)
2301 {
2302 for (const auto& topLayer : topLayers) {
2303 std::shared_ptr<RSSurfaceHandler> topLayerSurfaceHandler = topLayer->GetMutableRSSurfaceHandler();
2304 if (topLayerSurfaceHandler) {
2305 if (topLayer->GetTopLayerZOrder() == 0) {
2306 topLayerSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 1);
2307 } else {
2308 topLayerSurfaceHandler->SetGlobalZOrder(static_cast<float>(topLayer->GetTopLayerZOrder()));
2309 }
2310 topLayer->SetCalcRectInPrepare(false);
2311 bool hwcDisabled = !IsHardwareComposerEnabled() || !topLayer->ShouldPaint() ||
2312 curScreenNode_->GetHasUniRenderHdrSurface() || !drmNodes_.empty();
2313 topLayer->SetHardwareForcedDisabledState(hwcDisabled);
2314 if (hwcDisabled) {
2315 RS_OPTIONAL_TRACE_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by toplayers dirty status, "
2316 "IsHardwareComposerEnabled[%d],TopLayerShouldPaint[%d],HasUniRenderHdrSurface[%d],DrmNodeEmpty[%d]",
2317 topLayer->GetName().c_str(), topLayer->GetId(), IsHardwareComposerEnabled(),
2318 topLayer->ShouldPaint(), curScreenNode_->GetHasUniRenderHdrSurface(), drmNodes_.empty());
2319 }
2320 auto transform = RSUniHwcComputeUtil::GetLayerTransform(*topLayer, curScreenNode_->GetScreenInfo());
2321 topLayer->UpdateHwcNodeLayerInfo(transform);
2322 }
2323 }
2324 }
2325
UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode> & appNode,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2326 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode>& appNode,
2327 std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2328 {
2329 // if current frame hwc enable status not equal with last frame
2330 // or current frame do gpu composition and has buffer consumed,
2331 // we need merge hwc node dst rect to dirty region.
2332 if (!hwcNode->IsHardwareForcedDisabled() != hwcNode->GetIsLastFrameHwcEnabled()) {
2333 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
2334 return;
2335 }
2336 if (!hwcNode->GetRSSurfaceHandler()) {
2337 return;
2338 }
2339 if (hwcNode->IsHardwareForcedDisabled() && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
2340 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetOldDirtyInSurface());
2341 }
2342 if (hasMirrorDisplay_ && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
2343 !appNode->GetVisibleRegion().IsEmpty()) {
2344 // merge hwc node dst rect for virtual screen dirty, in case the main display node skip
2345 curScreenDirtyManager_->MergeHwcDirtyRect(hwcNode->GetDstRect());
2346 }
2347 }
2348
UpdateSurfaceDirtyAndGlobalDirty()2349 void RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty()
2350 {
2351 UpdateDisplayDirtyAndExtendVisibleRegion();
2352 auto& curMainAndLeashSurfaces = curScreenNode_->GetAllMainAndLeashSurfaces();
2353 // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
2354 Occlusion::Region accumulatedDirtyRegion;
2355 bool hasMainAndLeashSurfaceDirty = false;
2356 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2357 [this, &accumulatedDirtyRegion, &hasMainAndLeashSurfaceDirty](RSBaseRenderNode::SharedPtr& nodePtr) {
2358 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2359 if (!surfaceNode) {
2360 RS_LOGE("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surfaceNode is nullptr");
2361 return;
2362 }
2363 accumulatedDirtyRegion.OrSelf(curScreenNode_->GetDisappearedSurfaceRegionBelowCurrent(surfaceNode->GetId()));
2364 auto dirtyManager = surfaceNode->GetDirtyManager();
2365 RSMainThread::Instance()->GetContext().AddPendingSyncNode(nodePtr);
2366 // 0. update hwc node dirty region and create layer
2367 UpdateHwcNodeDirtyRegionAndCreateLayer(surfaceNode);
2368 // cal done node dirtyRegion for uifirst
2369 RSUifirstManager::Instance().MergeOldDirtyToDirtyManager(surfaceNode);
2370 UpdatePointWindowDirtyStatus(surfaceNode);
2371 // 1. calculate abs dirtyrect and update partialRenderParams
2372 // currently only sync visible region info
2373 surfaceNode->UpdatePartialRenderParams();
2374 // 2. check surface node dirtyrect need merge into displayDirtyManager
2375 CheckMergeSurfaceDirtysForDisplay(surfaceNode);
2376 // 3. check merge transparent filter when it intersects with pre-dirty.
2377 CheckMergeFilterDirtyWithPreDirty(dirtyManager, accumulatedDirtyRegion, surfaceNode->IsTransparent() ?
2378 FilterDirtyType::TRANSPARENT_SURFACE_FILTER : FilterDirtyType::OPAQUE_SURFACE_FILTER);
2379 // 4. for cross-display node, process its filter (which is not collected during prepare).
2380 CollectFilterInCrossDisplayWindow(surfaceNode, accumulatedDirtyRegion);
2381 // 5. accumulate dirty region of this surface.
2382 AccumulateSurfaceDirtyRegion(surfaceNode, accumulatedDirtyRegion);
2383 hasMainAndLeashSurfaceDirty |=
2384 dirtyManager && dirtyManager->IsCurrentFrameDirty() &&
2385 surfaceNode->GetVisibleRegion().IsIntersectWith(dirtyManager->GetCurrentFrameDirtyRegion());
2386 });
2387 curScreenNode_->SetMainAndLeashSurfaceDirty(hasMainAndLeashSurfaceDirty);
2388 CheckMergeDebugRectforRefreshRate(curMainAndLeashSurfaces);
2389 CheckMergeScreenDirtyByRoundCornerDisplay();
2390 CheckMergeFilterDirtyWithPreDirty(curScreenDirtyManager_, accumulatedDirtyRegion, CONTAINER_FILTER);
2391 ResetDisplayDirtyRegion();
2392 if (curScreenDirtyManager_) {
2393 curScreenDirtyManager_->ClipDirtyRectWithinSurface();
2394 if (curScreenDirtyManager_->IsActiveSurfaceRectChanged()) {
2395 RS_TRACE_NAME_FMT("ActiveSurfaceRectChanged, form %s to %s",
2396 curScreenDirtyManager_->GetLastActiveSurfaceRect().ToString().c_str(),
2397 curScreenDirtyManager_->GetActiveSurfaceRect().ToString().c_str());
2398 curScreenDirtyManager_->MergeDirtyRect(curScreenDirtyManager_->GetSurfaceRect());
2399 }
2400 }
2401 UpdateIfHwcNodesHaveVisibleRegion(curMainAndLeashSurfaces);
2402 curScreenNode_->ClearCurrentSurfacePos();
2403 std::swap(preMainAndLeashWindowNodesIds_, curMainAndLeashWindowNodesIds_);
2404
2405 #ifdef RS_PROFILER_ENABLED
2406 RS_PROFILER_SET_DIRTY_REGION(accumulatedDirtyRegion);
2407 #endif
2408 }
2409
CheckMergeFilterDirtyWithPreDirty(const std::shared_ptr<RSDirtyRegionManager> & dirtyManager,const Occlusion::Region & accumulatedDirtyRegion,FilterDirtyType filterDirtyType)2410 void RSUniRenderVisitor::CheckMergeFilterDirtyWithPreDirty(const std::shared_ptr<RSDirtyRegionManager>& dirtyManager,
2411 const Occlusion::Region& accumulatedDirtyRegion, FilterDirtyType filterDirtyType)
2412 {
2413 if (UNLIKELY(dirtyManager == nullptr)) {
2414 return;
2415 }
2416 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2417 auto update = [&] (const FilterDirtyRegionInfo& filterInfo) {
2418 auto filterNode = nodeMap.GetRenderNode<RSRenderNode>(filterInfo.id_);
2419 if (!filterNode) {
2420 return;
2421 }
2422 Occlusion::Region belowDirtyToConsider;
2423 // for transparent surface filter or container filter, accumulated surface dirty should be considered.
2424 belowDirtyToConsider.OrSelf(filterDirtyType != FilterDirtyType::OPAQUE_SURFACE_FILTER ?
2425 accumulatedDirtyRegion : Occlusion::Region());
2426 // for filter in surface, accumulated dirty within surface should be considered.
2427 belowDirtyToConsider.OrSelf(filterDirtyType != FilterDirtyType::CONTAINER_FILTER ?
2428 filterInfo.belowDirty_ : Occlusion::Region());
2429 if (filterNode->GetRenderProperties().GetBackgroundFilter() ||
2430 filterNode->GetRenderProperties().GetNeedDrawBehindWindow()) {
2431 // backgroundfilter affected by below dirty
2432 filterNode->UpdateFilterCacheWithBelowDirty(
2433 filterInfo.isBackgroundFilterClean_ ? accumulatedDirtyRegion : belowDirtyToConsider, false);
2434 }
2435 if (filterNode->GetRenderProperties().GetFilter()) {
2436 // foregroundfilter affected by below dirty
2437 filterNode->UpdateFilterCacheWithBelowDirty(belowDirtyToConsider, true);
2438 }
2439 bool isIntersect = belowDirtyToConsider.IsIntersectWith(Occlusion::Rect(filterNode->GetFilterRect()));
2440 filterNode->PostPrepareForBlurFilterNode(*dirtyManager, needRequestNextVsync_);
2441 RsFrameBlurPredict::GetInstance().PredictDrawLargeAreaBlur(*filterNode);
2442 if (isIntersect) {
2443 RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeFilterDirtyWithPreDirty [%" PRIu64 "] type %d intersects below dirty"
2444 " Add %s to dirty.", filterInfo.id_, filterDirtyType, filterInfo.filterDirty_.GetRegionInfo().c_str());
2445 dirtyManager->MergeDirtyRect(filterInfo.filterDirty_.GetBound().ToRectI());
2446 } else {
2447 dirtyManager->GetFilterCollector().CollectFilterDirtyRegionInfo(filterInfo, true);
2448 }
2449 };
2450 auto& filtersToUpdate = dirtyManager->GetFilterCollector().GetFilterDirtyRegionInfoList(false);
2451 std::for_each(filtersToUpdate.begin(), filtersToUpdate.end(), update);
2452 filtersToUpdate.clear();
2453 }
2454
UpdateIfHwcNodesHaveVisibleRegion(std::vector<RSBaseRenderNode::SharedPtr> & curMainAndLeashSurfaces)2455 void RSUniRenderVisitor::UpdateIfHwcNodesHaveVisibleRegion(
2456 std::vector<RSBaseRenderNode::SharedPtr>& curMainAndLeashSurfaces)
2457 {
2458 bool needForceUpdateHwcNodes = false;
2459 bool hasVisibleHwcNodes = false;
2460 for (auto& nodePtr : curMainAndLeashSurfaces) {
2461 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2462 if (!surfaceNode) {
2463 RS_LOGD("[%{public}s]: surfaceNode is nullptr", __func__);
2464 continue;
2465 }
2466 if (surfaceNode->GetVisibleRegion().IsEmpty()) {
2467 continue;
2468 }
2469 const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2470 if (hwcNodes.empty()) {
2471 continue;
2472 }
2473 UpdateHwcNodesIfVisibleForApp(surfaceNode, hwcNodes, hasVisibleHwcNodes, needForceUpdateHwcNodes);
2474 if (needForceUpdateHwcNodes) {
2475 break;
2476 }
2477 }
2478 curScreenNode_->SetNeedForceUpdateHwcNodes(needForceUpdateHwcNodes, hasVisibleHwcNodes);
2479 }
2480
UpdateHwcNodesIfVisibleForApp(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,const std::vector<std::weak_ptr<RSSurfaceRenderNode>> & hwcNodes,bool & hasVisibleHwcNodes,bool & needForceUpdateHwcNodes)2481 void RSUniRenderVisitor::UpdateHwcNodesIfVisibleForApp(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2482 const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes,
2483 bool& hasVisibleHwcNodes, bool& needForceUpdateHwcNodes)
2484 {
2485 for (auto& hwcNode : hwcNodes) {
2486 auto hwcNodePtr = hwcNode.lock();
2487 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2488 continue;
2489 }
2490 if (hwcNodePtr->IsHardwareForcedDisabled() || hwcNodePtr->GetRSSurfaceHandler() == nullptr) {
2491 continue;
2492 }
2493 if (surfaceNode->GetVisibleRegion().IsEmpty()) {
2494 continue;
2495 }
2496
2497 // 1.hwcNode moving to extended screen 2.hwcNode is crossNode
2498 // 3. sufaceNode is top layer 4. In drm Scene
2499 if (hwcNodePtr->GetHwcGlobalPositionEnabled() ||
2500 hwcNodePtr->IsHwcCrossNode() ||
2501 surfaceNode->IsLayerTop() ||
2502 surfaceNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2503 hwcNodePtr->HwcSurfaceRecorder().SetLastFrameHasVisibleRegion(true); // visible Region
2504 needForceUpdateHwcNodes = true;
2505 continue;
2506 }
2507
2508 auto visibleRegion = surfaceNode->GetVisibleRegion();
2509 visibleRegion.MakeBound();
2510 auto visibleRectI = visibleRegion.GetBound().ToRectI();
2511 auto widthRatio = curScreenNode_->GetScreenInfo().GetRogWidthRatio();
2512 auto heightRatio = curScreenNode_->GetScreenInfo().GetRogHeightRatio();
2513 visibleRectI.left_ = static_cast<int>(std::round(visibleRectI.left_ * widthRatio));
2514 visibleRectI.top_ = static_cast<int>(std::round(visibleRectI.top_ * heightRatio));
2515 visibleRectI.width_ = static_cast<int>(std::round(visibleRectI.width_ * widthRatio));
2516 visibleRectI.height_ = static_cast<int>(std::round(visibleRectI.height_ * heightRatio));
2517 auto newRegionRect = Occlusion::Rect(visibleRectI, true);
2518 newRegionRect.Expand(EXPAND_ONE_PIX, EXPAND_ONE_PIX, EXPAND_ONE_PIX, EXPAND_ONE_PIX);
2519 Occlusion::Rect dstRect(hwcNodePtr->GetDstRect());
2520 if (newRegionRect.IsIntersect(dstRect)) {
2521 hwcNodePtr->HwcSurfaceRecorder().SetLastFrameHasVisibleRegion(true); // visible Region
2522 hasVisibleHwcNodes = true;
2523 if (hwcNodePtr->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
2524 needForceUpdateHwcNodes = true;
2525 }
2526 } else {
2527 hwcNodePtr->HwcSurfaceRecorder().SetLastFrameHasVisibleRegion(false); // invisible Region
2528 }
2529 }
2530 }
2531
UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,std::vector<RectI> & hwcRects)2532 void RSUniRenderVisitor::UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,
2533 std::vector<RectI>& hwcRects)
2534 {
2535 if (!hwcNode || !hwcNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2536 return;
2537 }
2538 auto instanceNode = hwcNode->GetInstanceRootNode() ?
2539 hwcNode->GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
2540 if (!instanceNode) {
2541 hwcNode->SetCornerRadiusInfoForDRM({});
2542 return;
2543 }
2544 auto instanceAbsRect = instanceNode->GetAbsDrawRect();
2545 auto instanceCornerRadius = instanceNode->GetGlobalCornerRadius();
2546 if (instanceAbsRect.IsEmpty() || instanceCornerRadius.IsZero() ||
2547 ROSEN_EQ(instanceNode->GetRenderProperties().GetBoundsWidth(), 0.0f)) {
2548 hwcNode->SetCornerRadiusInfoForDRM({});
2549 return;
2550 }
2551 auto hwcGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2552 if (!hwcGeo) {
2553 hwcNode->SetCornerRadiusInfoForDRM({});
2554 return;
2555 }
2556 auto hwcAbsRect = hwcGeo->MapRect(hwcNode->GetSelfDrawRect(), hwcNode->GetTotalMatrix());
2557 hwcAbsRect = hwcAbsRect.IntersectRect(instanceAbsRect);
2558 if (hwcAbsRect.IsEmpty()) {
2559 hwcNode->SetCornerRadiusInfoForDRM({});
2560 return;
2561 }
2562 auto ratio = static_cast<float>(instanceAbsRect.GetWidth()) /
2563 instanceNode->GetRenderProperties().GetBoundsWidth();
2564 std::vector<float> ratioVector = { 0.0f, 0.0f, 0.0f, 0.0f };
2565 bool isIntersectWithRoundCorner =
2566 CheckIfRoundCornerIntersectDRM(ratio, ratioVector, instanceCornerRadius, instanceAbsRect, hwcAbsRect);
2567 // store radius information when drm overlaps with other hwc nodes
2568 if (isIntersectWithRoundCorner) {
2569 for (const auto& rect : hwcRects) {
2570 if (hwcAbsRect.Intersect(rect)) {
2571 std::vector<float> drmCornerRadiusInfo = {
2572 static_cast<float>(hwcAbsRect.GetLeft()), static_cast<float>(hwcAbsRect.GetTop()),
2573 static_cast<float>(hwcAbsRect.GetWidth()), static_cast<float>(hwcAbsRect.GetHeight()),
2574 // get corner radius num by index 0, 1, 2, 3
2575 instanceCornerRadius[0] * ratioVector[0], instanceCornerRadius[1] * ratioVector[1],
2576 instanceCornerRadius[2] * ratioVector[2], instanceCornerRadius[3] * ratioVector[3]};
2577 hwcNode->SetCornerRadiusInfoForDRM(drmCornerRadiusInfo);
2578 return;
2579 }
2580 }
2581 }
2582 hwcNode->SetCornerRadiusInfoForDRM({});
2583 }
2584
CheckIfRoundCornerIntersectDRM(const float & ratio,std::vector<float> & ratioVector,const Vector4f & instanceCornerRadius,const RectI & instanceAbsRect,const RectI & hwcAbsRect)2585 bool RSUniRenderVisitor::CheckIfRoundCornerIntersectDRM(const float& ratio, std::vector<float>& ratioVector,
2586 const Vector4f& instanceCornerRadius, const RectI& instanceAbsRect, const RectI& hwcAbsRect)
2587 {
2588 auto maxRadius = *std::max_element(std::begin(instanceCornerRadius.data_),
2589 std::end(instanceCornerRadius.data_)) * ratio;
2590 bool isIntersectWithRoundCorner = false;
2591 static const std::vector<UIPoint> offsetVecs = { UIPoint { 0, 0 }, UIPoint { 1, 0 },
2592 UIPoint { 0, 1 }, UIPoint { 1, 1 } };
2593 UIPoint offset { instanceAbsRect.GetWidth() - maxRadius, instanceAbsRect.GetHeight() - maxRadius };
2594 UIPoint anchorPoint { instanceAbsRect.GetLeft(), instanceAbsRect.GetTop() };
2595 // if round corners intersect drm, update ratioVectors
2596 for (size_t i = 0; i < offsetVecs.size(); i++) {
2597 auto res = anchorPoint + offset * offsetVecs[i];
2598 if (RectI(res.x_, res.y_, maxRadius, maxRadius).Intersect(hwcAbsRect)) {
2599 isIntersectWithRoundCorner = true;
2600 ratioVector[i] = ratio;
2601 }
2602 }
2603 return isIntersectWithRoundCorner;
2604 }
2605
UpdateSurfaceOcclusionInfo()2606 void RSUniRenderVisitor::UpdateSurfaceOcclusionInfo()
2607 {
2608 allDstCurVisVec_.insert(allDstCurVisVec_.end(), dstCurVisVec_.begin(), dstCurVisVec_.end());
2609 dstCurVisVec_.clear();
2610 }
2611
CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode & surfaceNode) const2612 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode& surfaceNode) const
2613 {
2614 // surfaceNode is transparent
2615 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2616 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2617 Occlusion::Region visibleRegion = hasMirrorDisplay_ ?
2618 surfaceNode.GetVisibleRegionInVirtual() : surfaceNode.GetVisibleRegion();
2619 if (surfaceNode.IsMainWindowType() && !visibleRegion.IsIntersectWith(dirtyRect)) {
2620 return;
2621 }
2622 if (surfaceNode.IsTransparent()) {
2623 RectI transparentDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2624 if (!transparentDirtyRect.IsEmpty()) {
2625 RS_LOGD("CheckMergeDisplayDirtyByTransparent global merge transparent dirty "
2626 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2627 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2628 transparentDirtyRect.ToString().c_str());
2629 curScreenNode_->GetDirtyManager()->MergeDirtyRect(transparentDirtyRect);
2630 }
2631 }
2632 // surfaceNode has transparent regions
2633 CheckMergeDisplayDirtyByTransparentRegions(surfaceNode);
2634 }
2635
CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode & surfaceNode) const2636 void RSUniRenderVisitor::CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode& surfaceNode) const
2637 {
2638 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2639 if (surfaceNode.GetZorderChanged()) {
2640 RS_LOGD("CheckMergeDisplayDirtyByZorderChanged global merge GetZorderChanged "
2641 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2642 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2643 oldDirtyInSurface.ToString().c_str());
2644 curScreenNode_->GetDirtyManager()->MergeDirtyRect(oldDirtyInSurface);
2645 }
2646 }
2647
CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode & surfaceNode) const2648 void RSUniRenderVisitor::CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode& surfaceNode) const
2649 {
2650 bool isHardCursor = RSPointerWindowManager::Instance().CheckHardCursorSupport(curScreenNode_->GetScreenId());
2651 if (isHardCursor && surfaceNode.IsHardwareEnabledTopSurface() && surfaceNode.GetHardCursorStatus()) {
2652 return;
2653 }
2654 RectI lastFrameSurfacePos = curScreenNode_->GetLastFrameSurfacePos(surfaceNode.GetId());
2655 RectI currentFrameSurfacePos = curScreenNode_->GetCurrentFrameSurfacePos(surfaceNode.GetId());
2656 if (surfaceNode.GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
2657 RS_LOGD("CheckMergeDisplayDirtyByPosChanged global merge surface pos changed "
2658 "%{public}s: global dirty %{public}s, lastFrameRect %{public}s currentFrameRect %{public}s",
2659 surfaceNode.GetName().c_str(),
2660 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2661 lastFrameSurfacePos.ToString().c_str(), currentFrameSurfacePos.ToString().c_str());
2662 if (!lastFrameSurfacePos.IsEmpty()) {
2663 curScreenNode_->GetDirtyManager()->MergeDirtyRect(lastFrameSurfacePos);
2664 }
2665 if (!currentFrameSurfacePos.IsEmpty()) {
2666 curScreenNode_->GetDirtyManager()->MergeDirtyRect(currentFrameSurfacePos);
2667 }
2668 }
2669 }
2670
CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode & surfaceNode) const2671 void RSUniRenderVisitor::CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode& surfaceNode) const
2672 {
2673 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2674 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2675 bool isShadowDisappear = !surfaceNode.GetRenderProperties().IsShadowValid() &&
2676 surfaceNode.IsShadowValidLastFrame();
2677 if (surfaceNode.GetRenderProperties().IsShadowValid() || isShadowDisappear) {
2678 RectI shadowDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2679 // There are two situation here:
2680 // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
2681 // dirtyRect == surfaceNode.GetOldDirtyInSurface()
2682 // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
2683 // dirtyRect > surfaceNode.GetOldDirtyInSurface()
2684 // So we should always merge dirtyRect here.
2685 if (!shadowDirtyRect.IsEmpty()) {
2686 RS_LOGD("CheckMergeDisplayDirtyByShadowChanged global merge ShadowValid %{public}s: "
2687 "global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2688 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2689 dirtyRect.ToString().c_str());
2690 curScreenNode_->GetDirtyManager()->MergeDirtyRect(dirtyRect);
2691 }
2692 if (isShadowDisappear) {
2693 surfaceNode.SetShadowValidLastFrame(false);
2694 }
2695 }
2696 }
2697
CheckMergeDisplayDirtyBySurfaceChanged() const2698 void RSUniRenderVisitor::CheckMergeDisplayDirtyBySurfaceChanged() const
2699 {
2700 std::vector<RectI> surfaceChangedRects = curScreenNode_->GetSurfaceChangedRects();
2701 for (auto& surfaceChangedRect : surfaceChangedRects) {
2702 if (!surfaceChangedRect.IsEmpty()) {
2703 RS_LOGD("CheckMergeDisplayDirtyBySurfaceChanged global merge Surface closed, global dirty %{public}s,"
2704 "add rect %{public}s",
2705 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2706 surfaceChangedRect.ToString().c_str());
2707 curScreenNode_->GetDirtyManager()->MergeDirtyRect(surfaceChangedRect);
2708 }
2709 }
2710 }
2711
CheckMergeDisplayDirtyByAttractionChanged(RSSurfaceRenderNode & surfaceNode) const2712 void RSUniRenderVisitor::CheckMergeDisplayDirtyByAttractionChanged(RSSurfaceRenderNode& surfaceNode) const
2713 {
2714 if (surfaceNode.GetRenderProperties().IsAttractionValid()) {
2715 auto attractionDirtyRect = surfaceNode.GetRenderProperties().GetAttractionEffectCurrentDirtyRegion();
2716 RS_LOGD("CheckMergeDisplayDirtyByAttraction global merge attraction %{public}s: global dirty %{public}s,"
2717 "add rect %{public}s", surfaceNode.GetName().c_str(),
2718 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2719 attractionDirtyRect.ToString().c_str());
2720 auto boundsGeometry = curScreenNode_->GetRenderProperties().GetBoundsGeometry();
2721 if (boundsGeometry) {
2722 Drawing::Rect rect(attractionDirtyRect.GetLeft(), attractionDirtyRect.GetTop(),
2723 attractionDirtyRect.GetRight(), attractionDirtyRect.GetBottom());
2724 Drawing::Rect tempRect;
2725 boundsGeometry->GetMatrix().MapRect(tempRect, rect);
2726 attractionDirtyRect =
2727 RectI(tempRect.GetLeft(), tempRect.GetTop(), tempRect.GetWidth(), tempRect.GetHeight());
2728 }
2729 curScreenNode_->GetDirtyManager()->MergeDirtyRect(attractionDirtyRect);
2730 }
2731 }
2732
CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2733 void RSUniRenderVisitor::CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2734 {
2735 if (surfaceNode->GetDirtyManager() == nullptr || curScreenNode_->GetDirtyManager() == nullptr) {
2736 return;
2737 }
2738 // 1 handle last and curframe surfaces which appear or disappear case
2739 CheckMergeDisplayDirtyBySurfaceChanged();
2740 // 2 if the surface node is cross-display and prepared again, convert its dirty region into global.
2741 if (surfaceNode->IsFirstLevelCrossNode() && !curScreenNode_->IsFirstVisitCrossNodeDisplay()) {
2742 CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2743 CheckMergeDisplayDirtyByCrossDisplayWindow(*surfaceNode);
2744 return;
2745 }
2746 // 3 Handles the case of transparent surface, merge transparent dirty rect
2747 CheckMergeDisplayDirtyByTransparent(*surfaceNode);
2748 // 4 Zorder changed case, merge surface dest Rect
2749 CheckMergeDisplayDirtyByZorderChanged(*surfaceNode);
2750 // 5 surfacePos chanded case, merge surface lastframe pos or curframe pos
2751 CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2752 // 6 shadow disappear and appear case.
2753 CheckMergeDisplayDirtyByShadowChanged(*surfaceNode);
2754 // 7 handle surface has attraction effect
2755 CheckMergeDisplayDirtyByAttractionChanged(*surfaceNode);
2756 // More: any other screen dirty caused by surfaceNode should be added here like CheckMergeDisplayDirtByXXX
2757 }
2758
CheckMergeDisplayDirtyByCrossDisplayWindow(RSSurfaceRenderNode & surfaceNode) const2759 void RSUniRenderVisitor::CheckMergeDisplayDirtyByCrossDisplayWindow(RSSurfaceRenderNode& surfaceNode) const
2760 {
2761 auto geoPtr = surfaceNode.GetRenderProperties().GetBoundsGeometry();
2762 if (!geoPtr) {
2763 return;
2764 }
2765 // transfer from the display coordinate system during quickprepare into current display coordinate system.
2766 auto dirtyRect = geoPtr->MapRect(surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion().ConvertTo<float>(),
2767 surfaceNode.GetCrossNodeSkipDisplayConversionMatrix(curScreenNode_->GetId()));
2768 RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeDisplayDirtyByCrossDisplayWindow %s, global dirty %s, add rect %s",
2769 surfaceNode.GetName().c_str(), curScreenDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
2770 dirtyRect.ToString().c_str());
2771 curScreenDirtyManager_->MergeDirtyRect(dirtyRect);
2772 }
2773
CollectFilterInCrossDisplayWindow(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedDirtyRegion)2774 void RSUniRenderVisitor::CollectFilterInCrossDisplayWindow(
2775 std::shared_ptr<RSSurfaceRenderNode>& surfaceNode, Occlusion::Region& accumulatedDirtyRegion)
2776 {
2777 auto geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
2778 if (!surfaceNode->IsFirstLevelCrossNode() || curScreenNode_->IsFirstVisitCrossNodeDisplay() || !geoPtr) {
2779 return;
2780 }
2781 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2782 for (auto& child : surfaceNode->GetVisibleFilterChild()) {
2783 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2784 if (!filterNode) {
2785 continue;
2786 }
2787 auto filterRect = geoPtr->MapRect(filterNode->GetAbsDrawRect().ConvertTo<float>(),
2788 surfaceNode->GetCrossNodeSkipDisplayConversionMatrix(curScreenNode_->GetId())).IntersectRect(
2789 curScreenNode_->GetScreenRect());
2790 curScreenDirtyManager_->GetFilterCollector().CollectFilterDirtyRegionInfo(
2791 RSUniFilterDirtyComputeUtil::GenerateFilterDirtyRegionInfo(*filterNode, std::nullopt, true), true);
2792 }
2793 }
2794
CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode & surfaceNode) const2795 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode& surfaceNode) const
2796 {
2797 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2798 if (surfaceNode.HasContainerWindow()) {
2799 // If a surface's dirty is intersect with container region (which can be considered transparent)
2800 // should be added to Screen dirty region.
2801 // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
2802 auto containerRegion = surfaceNode.GetContainerRegion();
2803 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2804 auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
2805 if (!containerDirtyRegion.IsEmpty()) {
2806 RS_LOGD("CheckMergeDisplayDirtyByContainer global merge containerDirtyRegion "
2807 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2808 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2809 containerDirtyRegion.GetRegionInfo().c_str());
2810 // plan: we can use surfacenode's absrect as containerRegion's bound
2811 const auto& rect = containerRegion.GetBoundRef();
2812 curScreenNode_->GetDirtyManager()->MergeDirtyRect(
2813 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2814 }
2815 } else {
2816 // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
2817 // transparent region and opaque region in adjacent frame, may cause Screendirty region incomplete after
2818 // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
2819 // which include transparent region but not counted in Screen dirtyregion)
2820 if (!surfaceNode.IsNodeDirty()) {
2821 return;
2822 }
2823 auto transparentRegion = surfaceNode.GetTransparentRegion();
2824 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2825 Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
2826 if (!transparentDirtyRegion.IsEmpty()) {
2827 RS_LOGD("CheckMergeDisplayDirtyByTransparentRegions global merge TransparentDirtyRegion "
2828 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2829 curScreenNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2830 transparentDirtyRegion.GetRegionInfo().c_str());
2831 const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
2832 for (const auto& rect : rects) {
2833 curScreenNode_->GetDirtyManager()->MergeDirtyRect(
2834 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2835 }
2836 }
2837 }
2838 }
2839
AccumulateSurfaceDirtyRegion(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedDirtyRegion) const2840 void RSUniRenderVisitor::AccumulateSurfaceDirtyRegion(
2841 std::shared_ptr<RSSurfaceRenderNode>& surfaceNode, Occlusion::Region& accumulatedDirtyRegion) const
2842 {
2843 auto geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
2844 if (!surfaceNode->GetDirtyManager() || !geoPtr) {
2845 return;
2846 }
2847 auto surfaceDirtyRect = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
2848 if (surfaceNode->IsFirstLevelCrossNode() && !curScreenNode_->IsFirstVisitCrossNodeDisplay()) {
2849 surfaceDirtyRect = geoPtr->MapRect(surfaceDirtyRect.ConvertTo<float>(),
2850 surfaceNode->GetCrossNodeSkipDisplayConversionMatrix(curScreenNode_->GetId()));
2851 }
2852 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ surfaceDirtyRect } };
2853 auto surfaceVisibleDirtyRegion = surfaceNode->IsMainWindowType() ?
2854 surfaceDirtyRegion.And(surfaceNode->GetVisibleRegion()) : surfaceDirtyRegion;
2855 accumulatedDirtyRegion.OrSelf(surfaceVisibleDirtyRegion);
2856 }
2857
UpdateDisplayDirtyAndExtendVisibleRegion()2858 void RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion()
2859 {
2860 if (curScreenNode_ == nullptr) {
2861 RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion curScreenNode_ is nullptr");
2862 return;
2863 }
2864 auto& curMainAndLeashSurfaces = curScreenNode_->GetAllMainAndLeashSurfaces();
2865 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2866 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2867 [this, &nodeMap](RSBaseRenderNode::SharedPtr& nodePtr) {
2868 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2869 if (surfaceNode == nullptr) {
2870 RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion surfaceNode is nullptr");
2871 return;
2872 }
2873 if (!surfaceNode->IsMainWindowType()) {
2874 return;
2875 }
2876 Occlusion::Region extendRegion;
2877 if (!surfaceNode->GetVisibleRegion().IsEmpty()) {
2878 ProcessFilterNodeObscured(surfaceNode, extendRegion, nodeMap);
2879 }
2880 surfaceNode->UpdateExtendVisibleRegion(extendRegion);
2881 });
2882 }
2883
ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & extendRegion,const RSRenderNodeMap & nodeMap)2884 void RSUniRenderVisitor::ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2885 Occlusion::Region& extendRegion, const RSRenderNodeMap& nodeMap)
2886 {
2887 const auto& visibleFilterChild = surfaceNode->GetVisibleFilterChild();
2888 auto visibleRegion = surfaceNode->GetVisibleRegion();
2889 auto currentFrameDirtyRegion = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
2890 auto isTransparent = surfaceNode->IsTransparent();
2891 for (const auto& child : visibleFilterChild) {
2892 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2893 if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
2894 continue;
2895 }
2896 MarkBlurIntersectWithDRM(filterNode);
2897 auto filterRect = filterNode->GetOldDirtyInSurface();
2898 auto visibleRects = visibleRegion.GetRegionRectIs();
2899 auto iter = std::find_if(visibleRects.begin(), visibleRects.end(), [&filterRect](const auto& rect) {
2900 return filterRect.IsInsideOf(rect);
2901 });
2902 if (iter != visibleRects.end()) {
2903 continue;
2904 }
2905 if (!visibleRegion.IsIntersectWith(filterRect)) {
2906 continue;
2907 }
2908 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ filterRect } };
2909 extendRegion = extendRegion.Or(filterRegion);
2910 if (!isTransparent && filterRect.Intersect(currentFrameDirtyRegion)) {
2911 curScreenNode_->GetDirtyManager()->MergeDirtyRect(filterRect);
2912 }
2913 }
2914 }
2915
UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2916 void RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2917 {
2918 if (surfaceNode == nullptr) {
2919 return;
2920 }
2921 if (surfaceNode->HasBlurFilter()) {
2922 surfaceNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
2923 }
2924 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2925 for (auto& child : surfaceNode->GetVisibleFilterChild()) {
2926 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2927 if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
2928 continue;
2929 }
2930 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode "
2931 "surfaceNode: %s, filterNode:[%lld], IsOccludedByFilterCache:%d", surfaceNode->GetName().c_str(),
2932 filterNode->GetId(), surfaceNode->IsOccludedByFilterCache());
2933 filterNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
2934 }
2935 }
2936
CollectEffectInfo(RSRenderNode & node)2937 void RSUniRenderVisitor::CollectEffectInfo(RSRenderNode& node)
2938 {
2939 auto nodeParent = node.GetParent().lock();
2940 if (nodeParent == nullptr) {
2941 return;
2942 }
2943 if (RSUniHwcComputeUtil::IsBlendNeedFilter(node) || node.ChildHasVisibleFilter()) {
2944 nodeParent->SetChildHasVisibleFilter(true);
2945 nodeParent->UpdateVisibleFilterChild(node);
2946 }
2947 if ((node.GetRenderProperties().GetUseEffect() || node.ChildHasVisibleEffect()) && node.ShouldPaint()) {
2948 nodeParent->SetChildHasVisibleEffect(true);
2949 nodeParent->UpdateVisibleEffectChild(node);
2950 }
2951 if (node.GetSharedTransitionParam() || node.ChildHasSharedTransition()) {
2952 nodeParent->SetChildHasSharedTransition(true);
2953 }
2954 }
2955
PostPrepare(RSRenderNode & node,bool subTreeSkipped)2956 CM_INLINE void RSUniRenderVisitor::PostPrepare(RSRenderNode& node, bool subTreeSkipped)
2957 {
2958 UpdateCurFrameInfoDetail(node, subTreeSkipped, true);
2959 if (const auto& sharedTransitionParam = node.GetSharedTransitionParam()) {
2960 sharedTransitionParam->GenerateDrawable(node);
2961 }
2962 auto curDirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curScreenDirtyManager_;
2963 if (!curDirtyManager) {
2964 return;
2965 }
2966 auto isOccluded = curSurfaceNode_ ?
2967 curSurfaceNode_->IsMainWindowType() && curSurfaceNode_->GetVisibleRegion().IsEmpty() : false;
2968 if (subTreeSkipped && (!isOccluded || node.IsFirstLevelCrossNode())) {
2969 hwcVisitor_->UpdateHwcNodeRectInSkippedSubTree(node);
2970 CheckFilterNodeInSkippedSubTreeNeedClearCache(node, *curDirtyManager);
2971 UpdateSubSurfaceNodeRectInSkippedSubTree(node);
2972 }
2973 if (node.NeedUpdateDrawableBehindWindow()) {
2974 node.GetMutableRenderProperties().SetNeedDrawBehindWindow(node.NeedDrawBehindWindow());
2975 }
2976 auto globalFilterRect = node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren() ?
2977 GetVisibleEffectDirty(node) : node.GetOldDirtyInSurface();
2978 auto globalHwcFilterRect = node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren() ?
2979 hwcVisitor_->GetHwcVisibleEffectDirty(node, globalFilterRect) : globalFilterRect;
2980 if (node.NeedDrawBehindWindow()) {
2981 if (isOccluded && !node.IsFirstLevelCrossNode()) {
2982 UpdateChildBlurBehindWindowAbsMatrix(node);
2983 }
2984 node.CalDrawBehindWindowRegion();
2985 globalFilterRect = node.GetFilterRect();
2986 }
2987 if (RSUniHwcComputeUtil::IsBlendNeedBackground(node)) {
2988 hwcVisitor_->UpdateHwcNodeEnableByFilterRect(
2989 curSurfaceNode_, node, node.GetHwcRecorder().GetZOrderForHwcEnableByFilter());
2990 }
2991 if (RSUniHwcComputeUtil::IsBlendNeedFilter(node)) {
2992 node.CalVisibleFilterRect(prepareClipRect_);
2993 node.MarkClearFilterCacheIfEffectChildrenChanged();
2994 CollectFilterInfoAndUpdateDirty(node, *curDirtyManager, globalFilterRect, globalHwcFilterRect);
2995 node.SetGlobalAlpha(curAlpha_);
2996 }
2997 CollectEffectInfo(node);
2998 node.NodePostPrepare(curSurfaceNode_, prepareClipRect_);
2999
3000 if (isDrawingCacheEnabled_) {
3001 bool isInBlackList = false;
3002 if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
3003 auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
3004 if (surfaceNode.IsLeashWindow() &&
3005 allBlackList_.find(surfaceNode.GetLeashPersistentId()) != allBlackList_.end()) {
3006 isInBlackList = true;
3007 }
3008 }
3009 node.UpdateDrawingCacheInfoAfterChildren(isInBlackList);
3010 }
3011 if (auto nodeParent = node.GetParent().lock()) {
3012 nodeParent->UpdateChildUifirstSupportFlag(node.GetUifirstSupportFlag());
3013 nodeParent->GetOpincCache().UpdateSubTreeSupportFlag(
3014 RSOpincManager::Instance().OpincGetNodeSupportFlag(node),
3015 node.GetOpincCache().OpincGetRootFlag(),
3016 nodeParent->GetNodeGroupType() == RSRenderNode::NodeGroupType::NONE);
3017 #ifdef SUBTREE_PARALLEL_ENABLE
3018 nodeParent->UpdateRepaintBoundaryInfo(node);
3019 #endif
3020 }
3021 auto& stagingRenderParams = node.GetStagingRenderParams();
3022 if (stagingRenderParams != nullptr) {
3023 if (node.GetSharedTransitionParam() && node.GetRenderProperties().GetSandBox()) {
3024 stagingRenderParams->SetAlpha(curAlpha_);
3025 } else {
3026 stagingRenderParams->SetAlpha(node.GetRenderProperties().GetAlpha());
3027 }
3028 }
3029
3030 // Collect prepared subtree into the control-level occlusion culling handler.
3031 // For the surface node, trigger occlusion detection.
3032 CollectSubTreeAndProcessOcclusion(node, subTreeSkipped);
3033
3034 // planning: only do this if node is dirty
3035 node.UpdateRenderParams();
3036
3037 // add if node is dirty
3038 node.AddToPendingSyncList();
3039 }
3040
CollectSubTreeAndProcessOcclusion(OHOS::Rosen::RSRenderNode & node,bool subTreeSkipped)3041 void RSUniRenderVisitor::CollectSubTreeAndProcessOcclusion(OHOS::Rosen::RSRenderNode& node, bool subTreeSkipped)
3042 {
3043 if (!curOcclusionHandler_) {
3044 return;
3045 }
3046
3047 curOcclusionHandler_->UpdateChildrenOutOfRectInfo(node);
3048 curOcclusionHandler_->CollectSubTree(node, !subTreeSkipped);
3049 if (node.GetId() != curOcclusionHandler_->GetRootNodeId()) {
3050 return;
3051 }
3052
3053 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.shared_from_this());
3054 if (surfaceNode == nullptr) {
3055 curOcclusionHandler_ = nullptr;
3056 return;
3057 }
3058 curOcclusionHandler_->UpdateSkippedSubTreeProp();
3059 curOcclusionHandler_->CalculateFrameOcclusion();
3060 auto occlusionParams = surfaceNode->GetOcclusionParams();
3061 occlusionParams->SetCulledNodes(curOcclusionHandler_->TakeCulledNodes());
3062 occlusionParams->SetCulledEntireSubtree(curOcclusionHandler_->TakeCulledEntireSubtree());
3063 occlusionParams->CheckKeyOcclusionNodeValidity(curOcclusionHandler_->GetOcclusionNodes());
3064 curOcclusionHandler_ = nullptr;
3065 }
3066
MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const3067 void RSUniRenderVisitor::MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const
3068 {
3069 if (!RSSystemProperties::GetDrmMarkedFilterEnabled()) {
3070 return;
3071 }
3072 RSDrmUtil::MarkBlurIntersectWithDRM(node, drmNodes_, curScreenNode_);
3073 }
3074
CheckFilterNodeInSkippedSubTreeNeedClearCache(const RSRenderNode & rootNode,RSDirtyRegionManager & dirtyManager)3075 void RSUniRenderVisitor::CheckFilterNodeInSkippedSubTreeNeedClearCache(
3076 const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager)
3077 {
3078 bool rotationChanged = curLogicalDisplayNode_ ?
3079 curLogicalDisplayNode_->IsRotationChanged() || curLogicalDisplayNode_->IsLastRotationChanged() : false;
3080 bool rotationStatusChanged = curLogicalDisplayNode_ ?
3081 curLogicalDisplayNode_->GetPreRotationStatus() != curLogicalDisplayNode_->GetCurRotationStatus() : false;
3082 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3083 for (auto& child : rootNode.GetVisibleFilterChild()) {
3084 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3085 if (filterNode == nullptr) {
3086 continue;
3087 }
3088 RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterNodeInSkippedSubTreeNeedClearCache node[%lld]", filterNode->GetId());
3089 if (auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode)) {
3090 UpdateRotationStatusForEffectNode(*effectNode);
3091 }
3092 filterNode->CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
3093 filterNode->MarkClearFilterCacheIfEffectChildrenChanged();
3094 if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3095 filterNode->UpdateFilterCacheWithBelowDirty(
3096 Occlusion::Rect(dirtyManager.GetCurrentFrameDirtyRegion()), false);
3097 }
3098 RectI filterRect;
3099 filterNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, prepareClipRect_);
3100 hwcVisitor_->UpdateHwcNodeEnableByFilterRect(curSurfaceNode_, *filterNode);
3101 CollectFilterInfoAndUpdateDirty(*filterNode, dirtyManager, filterRect, filterRect);
3102 }
3103 }
3104
ResetSubSurfaceNodesCalState(std::vector<std::pair<NodeId,std::weak_ptr<RSSurfaceRenderNode>>> & subSurfaceNodes)3105 inline static void ResetSubSurfaceNodesCalState(
3106 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>>& subSurfaceNodes)
3107 {
3108 for (auto& [id, node] : subSurfaceNodes) {
3109 auto subSurfaceNodePtr = node.lock();
3110 if (!subSurfaceNodePtr) {
3111 continue;
3112 }
3113 subSurfaceNodePtr->SetCalcRectInPrepare(false);
3114 }
3115 }
3116
UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode & rootNode)3117 void RSUniRenderVisitor::UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3118 {
3119 if (!curSurfaceNode_ || !curSurfaceDirtyManager_) {
3120 return;
3121 }
3122 auto rootGeo = rootNode.GetRenderProperties().GetBoundsGeometry();
3123 if (!rootGeo) {
3124 return;
3125 }
3126
3127 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
3128 curSurfaceNode_->GetAllSubSurfaceNodes(allSubSurfaceNodes);
3129 for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
3130 auto subSurfaceNodePtr = subSurfaceNode.lock();
3131 Drawing::Matrix absMatrix;
3132 if (!subSurfaceNodePtr || subSurfaceNodePtr->GetCalcRectInPrepare() ||
3133 !subSurfaceNodePtr->GetAbsMatrixReverse(rootNode, absMatrix)) {
3134 continue;
3135 }
3136
3137 Drawing::RectF absDrawRect;
3138 absMatrix.MapRect(absDrawRect, RSPropertiesPainter::Rect2DrawingRect(subSurfaceNodePtr->GetSelfDrawRect()));
3139 RectI subSurfaceRect = RectI(absDrawRect.GetLeft(), absDrawRect.GetTop(),
3140 absDrawRect.GetWidth(), absDrawRect.GetHeight());
3141
3142 subSurfaceNodePtr->SetOldDirtyInSurface(subSurfaceRect.IntersectRect(prepareClipRect_));
3143 UpdateNodeVisibleRegion(*subSurfaceNodePtr);
3144 hwcVisitor_->UpdateDstRect(*subSurfaceNodePtr, subSurfaceRect, prepareClipRect_);
3145 subSurfaceNodePtr->SetCalcRectInPrepare(true);
3146 if (subSurfaceNodePtr->IsLeashOrMainWindow()) {
3147 curMainAndLeashWindowNodesIds_.push(subSurfaceNodePtr->GetId());
3148 curScreenNode_->RecordMainAndLeashSurfaces(subSurfaceNodePtr);
3149 curScreenNode_->UpdateSurfaceNodePos(
3150 subSurfaceNodePtr->GetId(), subSurfaceNodePtr->GetOldDirtyInSurface());
3151 if (auto subSurfaceDirtyManager = subSurfaceNodePtr->GetDirtyManager()) {
3152 subSurfaceDirtyManager->MergeDirtyRect(subSurfaceNodePtr->GetOldDirtyInSurface().IntersectRect(
3153 curSurfaceDirtyManager_->GetCurrentFrameDirtyRegion()));
3154 }
3155 CollectOcclusionInfoForWMS(*subSurfaceNodePtr);
3156 subSurfaceNodePtr->UpdateRenderParams();
3157 auto& rateReduceManager = RSMainThread::Instance()->GetRSVsyncRateReduceManager();
3158 rateReduceManager.PushWindowNodeId(subSurfaceNodePtr->GetId());
3159 rateReduceManager.CollectSurfaceVsyncInfo(curScreenNode_->GetScreenInfo(), *subSurfaceNodePtr);
3160 }
3161 }
3162 ResetSubSurfaceNodesCalState(allSubSurfaceNodes);
3163 }
3164
GetVisibleEffectDirty(RSRenderNode & node) const3165 RectI RSUniRenderVisitor::GetVisibleEffectDirty(RSRenderNode& node) const
3166 {
3167 RectI childEffectRect;
3168 auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3169 for (auto& nodeId : node.GetVisibleEffectChild()) {
3170 if (auto& subnode = nodeMap.GetRenderNode<RSRenderNode>(nodeId)) {
3171 childEffectRect = childEffectRect.JoinRect(subnode->GetOldDirtyInSurface());
3172 }
3173 }
3174 return childEffectRect;
3175 }
3176
CollectFilterInfoAndUpdateDirty(RSRenderNode & node,RSDirtyRegionManager & dirtyManager,const RectI & globalFilterRect,const RectI & globalHwcFilterRect)3177 void RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty(RSRenderNode& node,
3178 RSDirtyRegionManager& dirtyManager, const RectI& globalFilterRect, const RectI& globalHwcFilterRect)
3179 {
3180 // case - 1. Deal with filter node self dirty.
3181 node.UpdateFilterCacheWithSelfDirty();
3182 // case - 2. Collect filter node with its current below dirty, process later.
3183 dirtyManager.GetFilterCollector().CollectFilterDirtyRegionInfo(
3184 RSUniFilterDirtyComputeUtil::GenerateFilterDirtyRegionInfo(
3185 node, Occlusion::Region(Occlusion::Rect(dirtyManager.GetCurrentFrameDirtyRegion())),
3186 curSurfaceNode_ != nullptr), false);
3187
3188 if (curSurfaceNode_) {
3189 bool isIntersect = dirtyManager.GetCurrentFrameDirtyRegion().Intersect(globalFilterRect);
3190 if (curSurfaceNode_->IsTransparent()) {
3191 if (!isIntersect || (isIntersect && (node.GetRenderProperties().GetBackgroundFilter() ||
3192 node.GetRenderProperties().GetNeedDrawBehindWindow()) && !node.IsBackgroundInAppOrNodeSelfDirty())) {
3193 hwcVisitor_->transparentHwcCleanFilter_[curSurfaceNode_->GetId()].
3194 push_back({node.GetId(), globalHwcFilterRect});
3195 }
3196 if (isIntersect) {
3197 hwcVisitor_->transparentHwcDirtyFilter_[curSurfaceNode_->GetId()].
3198 push_back({node.GetId(), globalHwcFilterRect});
3199 }
3200 }
3201 }
3202 }
3203
UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode & node)3204 void RSUniRenderVisitor::UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode& node)
3205 {
3206 if (!node.IsLeashWindow()) {
3207 return;
3208 }
3209 auto& property = node.GetMutableRenderProperties();
3210 auto& geoPtr = (property.GetBoundsGeometry());
3211 if (geoPtr == nullptr) {
3212 return;
3213 }
3214 auto absMatrix = geoPtr->GetAbsMatrix();
3215 bool isScale = false;
3216 if (RSUifirstManager::Instance().GetUiFirstType() == UiFirstCcmType::MULTI) {
3217 isScale = (!ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_X), 1.f, EPSILON_SCALE) ||
3218 !ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_Y), 1.f, EPSILON_SCALE));
3219 } else {
3220 bool getMinMaxScales = false;
3221 // scaleFactors[0]-minimum scaling factor, scaleFactors[1]-maximum scaling factor
3222 Drawing::scalar scaleFactors[2];
3223 getMinMaxScales = absMatrix.GetMinMaxScales(scaleFactors);
3224 if (getMinMaxScales) {
3225 isScale = !ROSEN_EQ(scaleFactors[0], 1.f, EPSILON_SCALE) || !ROSEN_EQ(scaleFactors[1], 1.f, EPSILON_SCALE);
3226 }
3227 if (!getMinMaxScales) {
3228 RS_LOGD("getMinMaxScales fail, node:%{public}s %{public}" PRIu64 "", node.GetName().c_str(), node.GetId());
3229 const auto& dstRect = node.GetDstRect();
3230 float dstRectWidth = dstRect.GetWidth();
3231 float dstRectHeight = dstRect.GetHeight();
3232 float boundsWidth = property.GetBoundsWidth();
3233 float boundsHeight = property.GetBoundsHeight();
3234 isScale =
3235 !ROSEN_EQ(std::min(dstRectWidth, dstRectHeight), std::min(boundsWidth, boundsHeight), EPSILON_SCALE) ||
3236 !ROSEN_EQ(std::max(dstRectWidth, dstRectHeight), std::max(boundsWidth, boundsHeight), EPSILON_SCALE);
3237 }
3238 }
3239 node.SetIsScaleInPreFrame(node.IsScale());
3240 node.SetIsScale(isScale);
3241 }
3242
PrepareRootRenderNode(RSRootRenderNode & node)3243 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
3244 {
3245 RS_TRACE_NAME_FMT("RSUniRender::PrepareRootRenderNode:node[%" PRIu64 "] pid[%d] subTreeDirty[%d]",
3246 node.GetId(), ExtractPid(node.GetId()), node.IsSubTreeDirty());
3247 bool dirtyFlag = dirtyFlag_;
3248 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
3249 auto prepareClipRect = prepareClipRect_;
3250
3251 auto nodeParent = (node.GetParent().lock());
3252 const auto& property = node.GetRenderProperties();
3253 bool geoDirty = property.IsGeoDirty();
3254 auto& geoPtr = (property.GetBoundsGeometry());
3255 auto prevAlpha = curAlpha_;
3256 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
3257
3258 if (curSurfaceDirtyManager_ == nullptr) {
3259 RS_LOGE_LIMIT(
3260 __func__, __line__, "RSUniRenderVisitor::PrepareRootRenderNode curSurfaceDirtyManager is nullptr");
3261 return;
3262 }
3263 dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
3264 *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
3265 if (nodeParent == curSurfaceNode_) {
3266 const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
3267 const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
3268 Drawing::Matrix gravityMatrix;
3269 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
3270 RectF { 0.0f, 0.0f, boundsRect_.GetWidth(), boundsRect_.GetHeight() },
3271 rootWidth, rootHeight, gravityMatrix);
3272 // Only Apply gravityMatrix when rootNode is dirty
3273 if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
3274 geoPtr->ConcatMatrix(gravityMatrix);
3275 }
3276 }
3277
3278 if (geoPtr != nullptr) {
3279 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3280 }
3281
3282 node.EnableWindowKeyFrame(false);
3283
3284 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
3285 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
3286 node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
3287 PostPrepare(node, !isSubTreeNeedPrepare);
3288
3289 curAlpha_ = prevAlpha;
3290 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3291 dirtyFlag_ = dirtyFlag;
3292 prepareClipRect_ = prepareClipRect;
3293 }
3294
InitializeOcclusionHandler(RSSurfaceRenderNode & node)3295 void RSUniRenderVisitor::InitializeOcclusionHandler(RSSurfaceRenderNode& node)
3296 {
3297 if (!OcclusionCullingParam::IsIntraAppControlsLevelOcclusionCullingEnable()) {
3298 return;
3299 }
3300 if (curOcclusionHandler_) {
3301 return;
3302 }
3303 auto occlusionParams = node.GetOcclusionParams();
3304 if (!occlusionParams->IsOcclusionCullingOn()) {
3305 return;
3306 }
3307
3308 curOcclusionHandler_ = occlusionParams->GetOcclusionHandler();
3309 if (curOcclusionHandler_ == nullptr) {
3310 curOcclusionHandler_ = std::make_shared<RSOcclusionHandler>(node.GetId());
3311 occlusionParams->SetOcclusionHandler(curOcclusionHandler_);
3312 }
3313 }
3314
SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams> & renderThreadParams)3315 void RSUniRenderVisitor::SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams>& renderThreadParams)
3316 {
3317 if (!renderThreadParams) {
3318 RS_LOGE("RSUniRenderVisitor::SetUniRenderThreadParam renderThreadParams is nullptr");
3319 return;
3320 }
3321 renderThreadParams->isPartialRenderEnabled_ = isPartialRenderEnabled_;
3322 renderThreadParams->isRegionDebugEnabled_ = isRegionDebugEnabled_;
3323 renderThreadParams->isDirtyRegionDfxEnabled_ = isDirtyRegionDfxEnabled_;
3324 renderThreadParams->isDisplayDirtyDfxEnabled_ = isDisplayDirtyDfxEnabled_;
3325 renderThreadParams->isMergedDirtyRegionDfxEnabled_ = isMergedDirtyRegionDfxEnabled_;
3326 renderThreadParams->isOpaqueRegionDfxEnabled_ = isOpaqueRegionDfxEnabled_;
3327 renderThreadParams->isVisibleRegionDfxEnabled_ = isVisibleRegionDfxEnabled_;
3328 renderThreadParams->isAllSurfaceVisibleDebugEnabled_ = isAllSurfaceVisibleDebugEnabled_;
3329 renderThreadParams->isTargetDirtyRegionDfxEnabled_ = isTargetDirtyRegionDfxEnabled_;
3330 renderThreadParams->dirtyRegionDebugType_ = dirtyRegionDebugType_;
3331 renderThreadParams->isOpDropped_ = isOpDropped_;
3332 renderThreadParams->isDirtyAlignEnabled_ = isDirtyAlignEnabled_;
3333 renderThreadParams->isStencilPixelOcclusionCullingEnabled_ = isStencilPixelOcclusionCullingEnabled_;
3334 renderThreadParams->isCrossNodeOffscreenOn_ = isCrossNodeOffscreenOn_;
3335 renderThreadParams->isUIFirstDebugEnable_ = isUIFirstDebugEnable_;
3336 renderThreadParams->dfxTargetSurfaceNames_ = std::move(dfxTargetSurfaceNames_);
3337 renderThreadParams->isVirtualDirtyEnabled_ = isVirtualDirtyEnabled_;
3338 renderThreadParams->isVirtualDirtyDfxEnabled_ = isVirtualDirtyDfxEnabled_;
3339 renderThreadParams->isExpandScreenDirtyEnabled_ = isExpandScreenDirtyEnabled_;
3340 renderThreadParams->advancedDirtyType_ = advancedDirtyType_;
3341 renderThreadParams->hasDisplayHdrOn_ = hasDisplayHdrOn_;
3342 renderThreadParams->hasMirrorDisplay_ = hasMirrorDisplay_;
3343 if (RSPointerWindowManager::Instance().IsNeedForceCommitByPointer()) {
3344 renderThreadParams->forceCommitReason_ |= ForceCommitReason::FORCED_BY_POINTER_WINDOW;
3345 }
3346 }
3347
SendRcdMessage(RSScreenRenderNode & node)3348 void RSUniRenderVisitor::SendRcdMessage(RSScreenRenderNode& node)
3349 {
3350 if (RoundCornerDisplayManager::CheckRcdRenderEnable(curScreenNode_->GetScreenInfo()) &&
3351 RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
3352 using rcd_msg = RSSingleton<RsMessageBus>;
3353 auto& screenInfo = curScreenNode_->GetScreenInfo();
3354 uint32_t left = 0; // render region
3355 uint32_t top = 0;
3356 uint32_t width = screenInfo.width;
3357 uint32_t height = screenInfo.height;
3358 if (!screenInfo.activeRect.IsEmpty()) {
3359 left = static_cast<uint32_t>(std::max(0, screenInfo.activeRect.GetLeft()));
3360 top = static_cast<uint32_t>(std::max(0, screenInfo.activeRect.GetTop()));
3361 width = static_cast<uint32_t>(std::max(0, screenInfo.activeRect.GetWidth()));
3362 height = static_cast<uint32_t>(std::max(0, screenInfo.activeRect.GetHeight()));
3363 }
3364 rcd_msg::GetInstance().SendMsg<NodeId, uint32_t, uint32_t, uint32_t, uint32_t>(TOPIC_RCD_DISPLAY_SIZE,
3365 node.GetId(), left, top, width, height);
3366 // rcd_msg::GetInstance().SendMsg<NodeId, ScreenRotation>(TOPIC_RCD_DISPLAY_ROTATION,
3367 // node.GetId(), node.GetScreenRotation());
3368 rcd_msg::GetInstance().SendMsg<NodeId, int>(TOPIC_RCD_DISPLAY_NOTCH,
3369 node.GetId(), RSSystemParameters::GetHideNotchStatus());
3370 }
3371 }
3372
ProcessUnpairedSharedTransitionNode()3373 void RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode()
3374 {
3375 static auto unpairNode = [](const std::weak_ptr<RSRenderNode>& wptr) {
3376 auto sptr = wptr.lock();
3377 if (sptr == nullptr) {
3378 return;
3379 }
3380 // make sure parent regenerates ChildrenDrawable
3381 auto parent = sptr->GetParent().lock();
3382 if (parent == nullptr) {
3383 return;
3384 }
3385 parent->AddDirtyType(ModifierNG::RSModifierType::CHILDREN);
3386 parent->ApplyModifiers();
3387 // avoid changing the paired status or unpairedShareTransitions_
3388 auto param = sptr->GetSharedTransitionParam();
3389 if (param == nullptr) {
3390 ROSEN_LOGE("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: param is null");
3391 return;
3392 }
3393 param->paired_ = false;
3394 SharedTransitionParam::unpairedShareTransitions_.clear();
3395 };
3396 auto unpairedShareTransitions = std::move(SharedTransitionParam::unpairedShareTransitions_);
3397 for (auto& [id, wptr] : unpairedShareTransitions) {
3398 auto sharedTransitionParam = wptr.lock();
3399 // If the unpaired share transition is already deal with, do nothing
3400 if (!sharedTransitionParam) {
3401 continue;
3402 }
3403 sharedTransitionParam->ResetRelation();
3404 if (!sharedTransitionParam->paired_) {
3405 continue;
3406 }
3407 ROSEN_LOGD("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: mark %s as unpaired",
3408 sharedTransitionParam->Dump().c_str());
3409 sharedTransitionParam->paired_ = false;
3410 unpairNode(sharedTransitionParam->inNode_);
3411 unpairNode(sharedTransitionParam->outNode_);
3412 }
3413 }
3414
CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr> & surfaces)3415 void RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr>& surfaces)
3416 {
3417 // Debug dirtyregion of show current refreshRation
3418 if (!RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
3419 return;
3420 }
3421 if (curScreenNode_ == nullptr) {
3422 RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate curScreenNode is nullptr");
3423 return;
3424 }
3425 static const RectI refreshDirtyRect = {100, 100, 500, 200}; // setDirtyRegion for RealtimeRefreshRate
3426 bool surfaceNodeSet = false;
3427 for (auto surface : surfaces) {
3428 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surface);
3429 if (surfaceNode == nullptr) {
3430 RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate surfaceNode is nullptr");
3431 continue;
3432 }
3433 if (surfaceNode->GetSurfaceWindowType() == SurfaceWindowType::SCB_GESTURE_BACK) {
3434 // refresh rate rect for mainwindow
3435 auto& surfaceGeoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
3436 if (!surfaceGeoPtr) {
3437 continue;
3438 }
3439 auto displayNodeId = surfaceNode->GetLogicalDisplayNodeId();
3440 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3441 auto displayNode = nodeMap.GetRenderNode<RSLogicalDisplayRenderNode>(displayNodeId);
3442 if (!displayNode) {
3443 continue;
3444 }
3445 auto& displayGeoPtr = displayNode->GetRenderProperties().GetBoundsGeometry();
3446 if (!displayGeoPtr) {
3447 continue;
3448 }
3449 auto tmpRect = refreshDirtyRect;
3450 auto windowContainer = displayNode->GetWindowContainer();
3451 if (windowContainer &&
3452 (!ROSEN_EQ(windowContainer->GetRenderProperties().GetScaleX(), 1.0f, EPSILON_SCALE) ||
3453 !ROSEN_EQ(windowContainer->GetRenderProperties().GetScaleY(), 1.0f, EPSILON_SCALE))) {
3454 tmpRect = displayGeoPtr->MapAbsRect(tmpRect.ConvertTo<float>());
3455 } else {
3456 tmpRect = surfaceGeoPtr->MapAbsRect(tmpRect.ConvertTo<float>());
3457 }
3458 curScreenNode_->GetDirtyManager()->MergeDirtyRect(tmpRect, true);
3459 surfaceNodeSet = true;
3460 }
3461 }
3462 if (!surfaceNodeSet) {
3463 for (auto& displayNode : *curScreenNode_->GetChildren()) {
3464 auto& geoPtr = curScreenNode_->GetRenderProperties().GetBoundsGeometry();
3465 if (!geoPtr) {
3466 continue;
3467 }
3468 auto tmpRect = refreshDirtyRect;
3469 tmpRect = geoPtr->MapAbsRect(tmpRect.ConvertTo<float>());
3470 curScreenNode_->GetDirtyManager()->MergeDirtyRect(tmpRect, true);
3471 }
3472 }
3473 }
3474
CheckMergeScreenDirtyByRoundCornerDisplay() const3475 void RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay() const
3476 {
3477 if (!screenManager_ || !curScreenNode_) {
3478 RS_LOGE(
3479 "RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay screenmanager or displaynode is nullptr");
3480 return;
3481 }
3482 if (!RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
3483 RS_LOGD("RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay rcd disabled!");
3484 return;
3485 }
3486 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
3487 if (screenManager_->GetScreenType(curScreenNode_->GetScreenId(), screenType) != SUCCESS) {
3488 RS_LOGD("RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay get screen type failed.");
3489 return;
3490 }
3491 if (screenType != EXTERNAL_TYPE_SCREEN) {
3492 RectI dirtyRectTop;
3493 RectI dirtyRectBottom;
3494 if (RSSingleton<RoundCornerDisplayManager>::GetInstance().HandleRoundCornerDirtyRect(
3495 curScreenNode_->GetId(), dirtyRectTop, RoundCornerDisplayManager::RCDLayerType::TOP)) {
3496 RS_LOGD("RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay global merge topRcdNode dirty "
3497 "%{public}s, global dirty %{public}s, add rect %{public}s",
3498 std::to_string(curScreenNode_->GetScreenId()).c_str(),
3499 curScreenDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
3500 dirtyRectTop.ToString().c_str());
3501 curScreenNode_->GetDirtyManager()->MergeDirtyRect(dirtyRectTop);
3502 }
3503 if (RSSingleton<RoundCornerDisplayManager>::GetInstance().HandleRoundCornerDirtyRect(
3504 curScreenNode_->GetId(), dirtyRectBottom, RoundCornerDisplayManager::RCDLayerType::BOTTOM)) {
3505 RS_LOGD("RSUniRenderVisitor::CheckMergeScreenDirtyByRoundCornerDisplay global merge bottomRcdNode dirty "
3506 "%{public}s, global dirty %{public}s, add rect %{public}s",
3507 std::to_string(curScreenNode_->GetScreenId()).c_str(),
3508 curScreenDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
3509 dirtyRectBottom.ToString().c_str());
3510 curScreenNode_->GetDirtyManager()->MergeDirtyRect(dirtyRectBottom);
3511 }
3512 }
3513 }
3514
CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode & node)3515 void RSUniRenderVisitor::CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode& node)
3516 {
3517 bool hasAnim = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
3518 if (!node.IsScale() || hasAnim || curCornerRadius_.IsZero() || curAlpha_ < 1) {
3519 node.SetGpuOverDrawBufferOptimizeNode(false);
3520 return;
3521 }
3522
3523 for (auto& child : *(node.GetChildren())) {
3524 if (!child || !(child->IsInstanceOf<RSSurfaceRenderNode>() &&
3525 RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsLeashOrMainWindow())) {
3526 continue;
3527 }
3528 auto rootNode = child->GetFirstChild();
3529 if (!rootNode) {
3530 break;
3531 }
3532 auto canvasNode = rootNode->GetFirstChild();
3533 if (!canvasNode) {
3534 break;
3535 }
3536 const auto& surfaceProperties = node.GetRenderProperties();
3537 const auto& canvasProperties = canvasNode->GetRenderProperties();
3538 if (canvasProperties.GetAlpha() >= 1 &&
3539 canvasProperties.GetBackgroundColor().GetAlpha() >= MAX_ALPHA &&
3540 canvasProperties.GetFrameWidth() == surfaceProperties.GetFrameWidth() &&
3541 canvasProperties.GetFrameHeight() == surfaceProperties.GetFrameHeight()) {
3542 node.SetGpuOverDrawBufferOptimizeNode(true);
3543 node.SetOverDrawBufferNodeCornerRadius(curCornerRadius_);
3544 return;
3545 }
3546 }
3547
3548 node.SetGpuOverDrawBufferOptimizeNode(false);
3549 }
3550
SetHdrWhenMultiDisplayChange()3551 void RSUniRenderVisitor::SetHdrWhenMultiDisplayChange()
3552 {
3553 auto mainThread = RSMainThread::Instance();
3554 if (!mainThread->GetMultiDisplayChange()) {
3555 return;
3556 }
3557 auto isMultiDisplay = mainThread->GetMultiDisplayStatus();
3558 RS_LOGI("RSUniRenderVisitor::SetHdrWhenMultiDisplayChange closeHdrStatus: %{public}d.", isMultiDisplay);
3559 RS_TRACE_NAME_FMT("RSUniRenderVisitor::SetHdrWhenMultiDisplayChange closeHdrStatus: %d", isMultiDisplay);
3560 RSLuminanceControl::Get().ForceCloseHdr(CLOSEHDR_SCENEID::MULTI_DISPLAY, isMultiDisplay);
3561 }
3562
TryNotifyUIBufferAvailable()3563 void RSUniRenderVisitor::TryNotifyUIBufferAvailable()
3564 {
3565 for (auto& id : uiBufferAvailableId_) {
3566 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3567 auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
3568 if (surfaceNode) {
3569 surfaceNode->NotifyUIBufferAvailable();
3570 }
3571 }
3572 uiBufferAvailableId_.clear();
3573 }
3574
CollectSelfDrawingNodeRectInfo(RSSurfaceRenderNode & node)3575 void RSUniRenderVisitor::CollectSelfDrawingNodeRectInfo(RSSurfaceRenderNode& node)
3576 {
3577 auto& monitor = SelfDrawingNodeMonitor::GetInstance();
3578 if (!monitor.IsListeningEnabled()) {
3579 return;
3580 }
3581
3582 if (!node.IsSelfDrawingType()) {
3583 return;
3584 }
3585 auto rect = node.GetRenderProperties().GetBoundsGeometry()->GetAbsRect();
3586 monitor.InsertCurRectMap(node.GetId(), rect);
3587 }
3588
HandleTunnelLayerId(RSSurfaceRenderNode & node)3589 void RSUniRenderVisitor::HandleTunnelLayerId(RSSurfaceRenderNode& node)
3590 {
3591 auto tunnelLayerId = node.GetTunnelLayerId();
3592 if (!tunnelLayerId) {
3593 return;
3594 }
3595 const auto nodeParams = static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
3596 if (nodeParams == nullptr) {
3597 return;
3598 }
3599 nodeParams->SetTunnelLayerId(tunnelLayerId);
3600 RS_LOGI("%{public}s lpp surfaceid:%{public}" PRIu64 ", nodeid:%{public}" PRIu64,
3601 __func__, tunnelLayerId, node.GetId());
3602 RS_TRACE_NAME_FMT("%s lpp surfaceid:%" PRIu64 ", nodeid:%" PRIu64, __func__, tunnelLayerId, node.GetId());
3603 }
3604
UpdateChildBlurBehindWindowAbsMatrix(RSRenderNode & node)3605 void RSUniRenderVisitor::UpdateChildBlurBehindWindowAbsMatrix(RSRenderNode& node)
3606 {
3607 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.shared_from_this());
3608 if (!surfaceNode) {
3609 RS_LOGE("RSUniRenderVisitor::UpdateChildBlurBehindWindowAbsMatrix not surfaceNode");
3610 return;
3611 }
3612 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3613 for (auto& childId : surfaceNode->GetChildBlurBehindWindow()) {
3614 auto child = nodeMap.GetRenderNode<RSRenderNode>(childId);
3615 if (!child) {
3616 RS_LOGE("RSUniRenderVisitor::UpdateChildBlurBehindWindowAbsMatrix child[%{public}" PRIu64 "] nullptr",
3617 childId);
3618 continue;
3619 }
3620 Drawing::Matrix absMatrix;
3621 if (!child->GetAbsMatrixReverse(node, absMatrix)) {
3622 RS_LOGE("RSUniRenderVisitor::UpdateChildBlurBehindWindowAbsMatrix child[%{public}" PRIu64
3623 "] GetAbsMatrixReverse fail", childId);
3624 continue;
3625 }
3626 child->GetRenderProperties().GetBoundsGeometry()->SetAbsMatrix(absMatrix);
3627 }
3628 }
3629 } // namespace Rosen
3630 } // namespace OHOS