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 #ifdef RS_ENABLE_OLD_VK
22 #include <vulkan_window.h>
23 #endif
24
25 #include "common/rs_common_def.h"
26 #include "common/rs_common_hook.h"
27 #include "common/rs_obj_abs_geometry.h"
28 #include "common/rs_optional_trace.h"
29 #include "common/rs_singleton.h"
30 #include "common/rs_special_layer_manager.h"
31 #include "feature/opinc/rs_opinc_manager.h"
32 #include "feature/hdr/rs_hdr_util.h"
33 #include "feature/uifirst/rs_sub_thread_manager.h"
34 #include "feature/uifirst/rs_uifirst_manager.h"
35 #include "monitor/self_drawing_node_monitor.h"
36 #ifdef RS_ENABLE_OVERLAY_DISPLAY
37 #include "feature/overlay_display/rs_overlay_display_manager.h"
38 #endif
39 #include "display_engine/rs_luminance_control.h"
40 #include "memory/rs_tag_tracker.h"
41 #include "params/rs_display_render_params.h"
42 #include "params/rs_rcd_render_params.h"
43 #include "pipeline/render_thread/rs_base_render_util.h"
44 #include "pipeline/render_thread/rs_uni_render_util.h"
45 #include "pipeline/render_thread/rs_uni_render_virtual_processor.h"
46 #include "pipeline/rs_base_render_node.h"
47 #include "pipeline/rs_display_render_node.h"
48 #include "pipeline/rs_effect_render_node.h"
49 #include "pipeline/rs_paint_filter_canvas.h"
50 #include "pipeline/rs_pointer_window_manager.h"
51 #include "pipeline/hardware_thread/rs_realtime_refresh_rate_manager.h"
52 #include "pipeline/rs_root_render_node.h"
53 #include "pipeline/rs_surface_render_node.h"
54 #include "platform/common/rs_log.h"
55 #include "platform/common/rs_system_properties.h"
56 #include "property/rs_properties_painter.h"
57 #include "system/rs_system_parameters.h"
58 #include "hgm_core.h"
59 #include "metadata_helper.h"
60 #include <v1_0/buffer_handle_meta_key_type.h>
61 #include <v1_0/cm_color_space.h>
62
63 #include "feature_cfg/graphic_feature_param_manager.h"
64 #include "feature/round_corner_display/rs_rcd_surface_render_node.h"
65 #include "feature/round_corner_display/rs_round_corner_display_manager.h"
66 #include "feature/round_corner_display/rs_message_bus.h"
67
68 #include "rs_profiler.h"
69 #ifdef RS_PROFILER_ENABLED
70 #include "rs_profiler_capture_recorder.h"
71 #endif
72
73 // blur predict
74 #include "rs_frame_blur_predict.h"
75
76 namespace OHOS {
77 namespace Rosen {
78 namespace {
79 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
80 constexpr int MAX_ALPHA = 255;
81 constexpr int TRACE_LEVEL_THREE = 3;
82 constexpr float EPSILON_SCALE = 0.00001f;
83 static const std::string CAPTURE_WINDOW_NAME = "CapsuleWindow";
84 constexpr const char* RELIABLE_GESTURE_BACK_SURFACE_NAME = "SCBGestureBack";
85 constexpr int MIN_OVERLAP = 2;
86 constexpr uint32_t API18 = 18;
87 constexpr uint32_t INVALID_API_COMPATIBLE_VERSION = 0;
88
CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)89 bool CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
90 {
91 if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
92 auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
93 const auto& property = rootNode->GetRenderProperties();
94 if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
95 return true;
96 }
97 }
98 return false;
99 }
100
CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)101 bool CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
102 {
103 if (child != nullptr && child->IsInstanceOf<RSCanvasRenderNode>()) {
104 auto canvasRenderNode = child->ReinterpretCastTo<RSCanvasRenderNode>();
105 const auto& property = canvasRenderNode->GetRenderProperties();
106 if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0) {
107 return true;
108 }
109 }
110 return false;
111 }
112
IsFirstFrameReadyToDraw(const RSSurfaceRenderNode & node)113 bool IsFirstFrameReadyToDraw(const RSSurfaceRenderNode& node)
114 {
115 bool result = false;
116 auto sortedChildren = node.GetSortedChildren();
117 if (node.IsScbScreen() || node.IsSCBNode()) {
118 for (const auto& child : *sortedChildren) {
119 result = CheckScbReadyToDraw(child);
120 }
121 return result;
122 }
123 for (auto& child : *sortedChildren) {
124 result = CheckRootNodeReadyToDraw(child);
125 // when appWindow has abilityComponent node
126 if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>()) {
127 for (const auto& surfaceNodeChild : *child->GetSortedChildren()) {
128 result = CheckRootNodeReadyToDraw(surfaceNodeChild);
129 }
130 }
131 }
132 return result;
133 }
134
VisibleDataToString(const VisibleData & val)135 std::string VisibleDataToString(const VisibleData& val)
136 {
137 std::stringstream ss;
138 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
139 for (const auto& v : val) {
140 auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(v.first);
141 auto name = surfaceNode ? surfaceNode->GetName() : "";
142 ss << "[" << name << ", " << v.first << ", " << v.second << "], ";
143 }
144 return ss.str();
145 }
146 } // namespace
147
RSUniRenderVisitor()148 RSUniRenderVisitor::RSUniRenderVisitor()
149 : rsUniHwcVisitor_(std::make_unique<RSUniHwcVisitor>(*this)),
150 curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
151 {
152 PartialRenderOptionInit();
153 auto mainThread = RSMainThread::Instance();
154 renderEngine_ = mainThread->GetRenderEngine();
155 hasMirrorDisplay_ = mainThread->HasMirrorDisplay();
156 // when occlusion enabled is false, subTree do not skip, but not influence visible region
157 isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
158 isDrawingCacheEnabled_ = RSSystemParameters::GetDrawingCacheEnabled();
159 #ifdef DDGR_ENABLE_FEATURE_OPINC
160 autoCacheEnable_ = RSOpincManager::Instance().GetOPIncSwitch();
161 #endif
162 RSTagTracker::UpdateReleaseResourceEnabled(RSSystemProperties::GetReleaseResourceEnabled());
163 isScreenRotationAnimating_ = RSSystemProperties::GetCacheEnabledForRotation();
164 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
165 if (renderEngine_ && renderEngine_->GetRenderContext()) {
166 auto subThreadManager = RSSubThreadManager::Instance();
167 subThreadManager->Start(renderEngine_->GetRenderContext().get());
168 }
169 #endif
170 isUIFirstDebugEnable_ = RSSystemProperties::GetUIFirstDebugEnabled();
171 isCrossNodeOffscreenOn_ = RSSystemProperties::GetCrossNodeOffScreenStatus();
172 isDumpRsTreeDetailEnabled_ = RSSystemProperties::GetDumpRsTreeDetailEnabled();
173 }
174
PartialRenderOptionInit()175 void RSUniRenderVisitor::PartialRenderOptionInit()
176 {
177 if (auto dirtyRegionParam = std::static_pointer_cast<DirtyRegionParam>(
178 GraphicFeatureParamManager::GetInstance().GetFeatureParam("DirtyRegionConfig"))) {
179 isPartialRenderEnabled_ = dirtyRegionParam->IsDirtyRegionEnable();
180 isAdvancedDirtyRegionEnabled_ = dirtyRegionParam->IsAdvancedDirtyRegionEnable();
181 isDirtyAlignEnabled_ = dirtyRegionParam->IsTileBasedAlignEnable();
182 }
183 if (RSSystemProperties::GetStencilPixelOcclusionCullingEnabled() == StencilPixelOcclusionCullingType::DEFAULT) {
184 if (auto spocParam = std::static_pointer_cast<StencilPixelOcclusionCullingParam>(
185 GraphicFeatureParamManager::GetInstance().GetFeatureParam("SpocConfig"))) {
186 isStencilPixelOcclusionCullingEnabled_ = spocParam->IsStencilPixelOcclusionCullingEnable();
187 }
188 } else {
189 isStencilPixelOcclusionCullingEnabled_ =
190 RSSystemProperties::GetStencilPixelOcclusionCullingEnabled() != StencilPixelOcclusionCullingType::DISABLED;
191 }
192
193 partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
194 isPartialRenderEnabled_ &= (partialRenderType_ > PartialRenderType::DISABLED);
195
196 isCompleteRenderEnabled_ = (partialRenderType_ == PartialRenderType::SET_DAMAGE_BUT_COMPLETE_RENDER);
197 dirtyRegionDebugType_ = RSSystemProperties::GetDirtyRegionDebugType();
198 surfaceRegionDebugType_ = RSSystemProperties::GetSurfaceRegionDfxType();
199 isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_) &&
200 (surfaceRegionDebugType_ == SurfaceRegionDebugType::DISABLED);
201 isTargetUIFirstDfxEnabled_ = RSSystemProperties::GetTargetUIFirstDfxEnabled(dfxUIFirstSurfaceNames_);
202 isRegionDebugEnabled_ = (dirtyRegionDebugType_ != DirtyRegionDebugType::DISABLED) ||
203 (surfaceRegionDebugType_ != SurfaceRegionDebugType::DISABLED) || (dfxTargetSurfaceNames_.size() > 0);
204 isVisibleRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::VISIBLE_REGION);
205 isOpaqueRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::OPAQUE_REGION);
206 isAllSurfaceVisibleDebugEnabled_ = RSSystemProperties::GetAllSurfaceVisibleDebugEnabled();
207 isDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
208 (dirtyRegionDebugType_ == DirtyRegionDebugType::EGL_DAMAGE);
209 isDisplayDirtyDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
210 (dirtyRegionDebugType_ == DirtyRegionDebugType::DISPLAY_DIRTY);
211 isOpDropped_ = isPartialRenderEnabled_ &&
212 (partialRenderType_ != PartialRenderType::SET_DAMAGE) && !isRegionDebugEnabled_;
213 isVirtualDirtyDfxEnabled_ = RSSystemProperties::GetVirtualDirtyDebugEnabled();
214 isVirtualDirtyEnabled_ = RSSystemProperties::GetVirtualDirtyEnabled() &&
215 (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) && !isRegionDebugEnabled_;
216 isExpandScreenDirtyEnabled_ = RSSystemProperties::GetExpandScreenDirtyEnabled();
217 advancedDirtyType_ = isAdvancedDirtyRegionEnabled_ ?
218 RSSystemProperties::GetAdvancedDirtyRegionEnabled() : AdvancedDirtyRegionType::DISABLED;
219 isDirtyAlignEnabled_ &= RSSystemProperties::GetDirtyAlignEnabled() != DirtyAlignType::DISABLED;
220 if (isStencilPixelOcclusionCullingEnabled_) {
221 // SPOC relies on dirty region alignment; when SPOC is enabled, dirty region alignment must also be enabled
222 isDirtyAlignEnabled_ = true;
223 }
224 }
225
RSUniRenderVisitor(const RSUniRenderVisitor & visitor)226 RSUniRenderVisitor::RSUniRenderVisitor(const RSUniRenderVisitor& visitor) : RSUniRenderVisitor()
227 {
228 currentVisitDisplay_ = visitor.currentVisitDisplay_;
229 screenInfo_ = visitor.screenInfo_;
230 specialLayerManager_ = visitor.specialLayerManager_;
231 displaySpecailSurfaceChanged_ = visitor.displaySpecailSurfaceChanged_;
232 hasCaptureWindow_ = visitor.hasCaptureWindow_;
233 hasFingerprint_ = visitor.hasFingerprint_;
234 parentSurfaceNodeMatrix_ = visitor.parentSurfaceNodeMatrix_;
235 curAlpha_ = visitor.curAlpha_;
236 dirtyFlag_ = visitor.dirtyFlag_;
237 curDisplayNode_ = visitor.curDisplayNode_;
238 currentFocusedNodeId_ = visitor.currentFocusedNodeId_;
239 prepareClipRect_ = visitor.prepareClipRect_;
240 isOpDropped_ = visitor.isOpDropped_;
241 isDirtyAlignEnabled_ = visitor.isDirtyAlignEnabled_;
242 isStencilPixelOcclusionCullingEnabled_ = visitor.isStencilPixelOcclusionCullingEnabled_;
243 isPartialRenderEnabled_ = visitor.isPartialRenderEnabled_;
244 isAllSurfaceVisibleDebugEnabled_ = visitor.isAllSurfaceVisibleDebugEnabled_;
245 isHardwareForcedDisabled_ = visitor.isHardwareForcedDisabled_;
246 advancedDirtyType_ = visitor.advancedDirtyType_;
247 doAnimate_ = visitor.doAnimate_;
248 isDirty_ = visitor.isDirty_;
249 layerNum_ = visitor.layerNum_;
250 isDumpRsTreeDetailEnabled_ = visitor.isDumpRsTreeDetailEnabled_;
251 }
252
~RSUniRenderVisitor()253 RSUniRenderVisitor::~RSUniRenderVisitor() {}
254
MergeRemovedChildDirtyRegion(RSRenderNode & node,bool needMap)255 void RSUniRenderVisitor::MergeRemovedChildDirtyRegion(RSRenderNode& node, bool needMap)
256 {
257 if (!node.HasRemovedChild()) {
258 return;
259 }
260 RectI dirtyRect = RSSystemProperties::GetOptimizeParentNodeRegionEnabled() ?
261 node.GetRemovedChildrenRect() : node.GetChildrenRect();
262 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
263 if (dirtyManager == nullptr || dirtyRect.IsEmpty()) {
264 node.ResetHasRemovedChild();
265 return;
266 }
267
268 // [planning] merge removed child's rect instead
269 if (needMap) {
270 if (auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry()) {
271 dirtyRect = geoPtr->MapAbsRect(dirtyRect.ConvertTo<float>());
272 }
273 if (!node.HasChildrenOutOfRect()) {
274 dirtyRect = dirtyRect.IntersectRect(node.GetOldClipRect());
275 }
276 } else {
277 dirtyRect = prepareClipRect_.IntersectRect(node.GetChildrenRect());
278 }
279 dirtyManager->MergeDirtyRect(dirtyRect);
280 RS_OPTIONAL_TRACE_NAME_FMT("MergeRemovedChildDirtyRegion NodeId:%" PRIu64 ", dirty rect:%s",
281 node.GetId(), dirtyRect.ToString().c_str());
282 if (dirtyManager->IsTargetForDfx()) {
283 // since childRect includes multiple rects, defaultly marked as canvas_node
284 dirtyManager->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
285 DirtyRegionType::REMOVE_CHILD_RECT, dirtyRect);
286 }
287 node.ResetHasRemovedChild();
288 }
289
CheckColorSpace(RSSurfaceRenderNode & node)290 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
291 {
292 // currently, P3 is the only supported wide color gamut, this may be modified later.
293 if (node.IsAppWindow() && node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
294 if (!curDisplayNode_) {
295 RS_LOGD("RSUniRenderVisitor::CheckColorSpace: curDisplayNode_ is nullptr");
296 return;
297 }
298 curDisplayNode_->SetColorSpace(GRAPHIC_COLOR_GAMUT_DISPLAY_P3);
299 RS_LOGD("RSUniRenderVisitor::CheckColorSpace: node(%{public}s) set new colorgamut %{public}d",
300 node.GetName().c_str(), static_cast<int>(GRAPHIC_COLOR_GAMUT_DISPLAY_P3));
301 }
302 }
303
CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode & node,GraphicColorGamut & newColorSpace)304 void RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode& node, GraphicColorGamut& newColorSpace)
305 {
306 if (!node.IsOnTheTree()) {
307 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is not on the tree",
308 node.GetName().c_str());
309 return;
310 }
311 if (!node.IsHardwareForcedDisabled()) {
312 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is hardware-enabled",
313 node.GetName().c_str());
314 return;
315 }
316 // currently, P3 is the only supported wide color gamut, this may be modified later.
317 node.UpdateColorSpaceWithMetadata();
318 auto appSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetInstanceRootNode());
319 auto colorGamutFeature = GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[COLOR_GAMUT]);
320 auto colorGamutParam = std::static_pointer_cast<ColorGamutParam>(colorGamutFeature);
321 if (colorGamutParam != nullptr && colorGamutParam->IsCoveredSurfaceCloseP3() && appSurfaceNode
322 && appSurfaceNode->IsMainWindowType() && appSurfaceNode->GetVisibleRegion().IsEmpty() && GetIsOpDropped()) {
323 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) failed to set new color "
324 "gamut %{public}d because the window is blocked", node.GetName().c_str(), newColorSpace);
325 return;
326 }
327
328 if (node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
329 newColorSpace = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
330 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) set new colorgamut %{public}d",
331 node.GetName().c_str(), newColorSpace);
332 }
333 }
334
UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode & node)335 void RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode& node)
336 {
337 auto colorSpace = node.GetColorSpace();
338 if (colorSpace == GRAPHIC_COLOR_GAMUT_DISPLAY_P3) {
339 RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc: newColorSpace is already DISPLAY_P3.");
340 return;
341 }
342 const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
343 for (const auto& selfDrawingNode : selfDrawingNodes) {
344 if (!selfDrawingNode) {
345 RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc selfDrawingNode is nullptr");
346 continue;
347 }
348 auto ancestorNode = selfDrawingNode->GetAncestorDisplayNode().lock();
349 if (!ancestorNode) {
350 RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc ancestorNode is nullptr");
351 continue;
352 }
353 auto ancestorDisplayNode = ancestorNode->ReinterpretCastTo<RSDisplayRenderNode>();
354 if (ancestorDisplayNode != nullptr && node.GetId() == ancestorDisplayNode->GetId()) {
355 CheckColorSpaceWithSelfDrawingNode(*selfDrawingNode, colorSpace);
356 }
357 }
358 node.SetColorSpace(colorSpace);
359 }
360
IsScreenSupportedWideColorGamut(ScreenId id,const sptr<RSScreenManager> & screenManager)361 bool IsScreenSupportedWideColorGamut(ScreenId id, const sptr<RSScreenManager>& screenManager)
362 {
363 std::vector<ScreenColorGamut> supportedColorGamut;
364 if (screenManager->GetScreenSupportedColorGamuts(id, supportedColorGamut) != SUCCESS) {
365 return false;
366 }
367 for (auto item : supportedColorGamut) {
368 if (item == ScreenColorGamut::COLOR_GAMUT_DCI_P3 || item == ScreenColorGamut::COLOR_GAMUT_DISPLAY_P3) {
369 return true;
370 }
371 }
372 return false;
373 }
374
HandleColorGamuts(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)375 void RSUniRenderVisitor::HandleColorGamuts(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
376 {
377 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
378 if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
379 RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen type failed.");
380 return;
381 }
382
383 if (screenType == VIRTUAL_TYPE_SCREEN) {
384 ScreenColorGamut screenColorGamut;
385 if (screenManager->GetScreenColorGamut(node.GetScreenId(), screenColorGamut) != SUCCESS) {
386 RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen color gamut failed.");
387 return;
388 }
389 node.SetColorSpace(static_cast<GraphicColorGamut>(screenColorGamut));
390 }
391 auto colorGamutFeature = GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[COLOR_GAMUT]);
392 auto colorGamutParam = std::static_pointer_cast<ColorGamutParam>(colorGamutFeature);
393 if (colorGamutParam != nullptr && colorGamutParam->IsSLRCloseP3() &&
394 (RSMainThread::Instance()->HasWiredMirrorDisplay() || RSMainThread::Instance()->HasVirtualMirrorDisplay() ||
395 (node.GetScreenId() != 0 && screenType != VIRTUAL_TYPE_SCREEN))) {
396 RS_LOGD("RSUniRenderVisitor::HandleColorGamuts close multi-screen P3.");
397 // wired screen and virtual mirror screen close P3
398 node.SetColorSpace(GRAPHIC_COLOR_GAMUT_SRGB);
399 }
400 }
401
CheckPixelFormat(RSSurfaceRenderNode & node)402 void RSUniRenderVisitor::CheckPixelFormat(RSSurfaceRenderNode& node)
403 {
404 if (hasFingerprint_[currentVisitDisplay_]) {
405 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat hasFingerprint is true.");
406 return;
407 }
408 if (!curDisplayNode_) {
409 RS_LOGE("RSUniRenderVisitor::CheckPixelFormat curDisplayNode is null");
410 return;
411 }
412 if (node.GetFingerprint()) {
413 hasFingerprint_[currentVisitDisplay_] = true;
414 curDisplayNode_->SetPixelFormat(GRAPHIC_PIXEL_FMT_RGBA_1010102);
415 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat pixelFormate is set 1010102 for fingerprint.");
416 return;
417 }
418 if (!RSSystemProperties::GetHdrImageEnabled()) {
419 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat HdrImageEnabled false");
420 return;
421 }
422 if (node.GetHDRPresent()) {
423 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat HDRService SetHDRPresent true, surfaceNode: %{public}" PRIu64 "",
424 node.GetId());
425 curDisplayNode_->SetHasUniRenderHdrSurface(true);
426 curDisplayNode_->CollectHdrStatus(HdrStatus::HDR_PHOTO);
427 RSHdrUtil::SetHDRParam(node, true);
428 if (curDisplayNode_->GetIsLuminanceStatusChange()) {
429 node.SetContentDirty();
430 }
431 }
432 }
433
HandlePixelFormat(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)434 void RSUniRenderVisitor::HandlePixelFormat(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
435 {
436 if (!curDisplayNode_) {
437 RS_LOGE("RSUniRenderVisitor::HandlePixelFormat curDisplayNode is null");
438 return;
439 }
440 SetHdrWhenMultiDisplayChange();
441 RS_LOGD("HDRSwitch isHdrImageEnabled: %{public}d, isHdrVideoEnabled: %{public}d",
442 RSSystemProperties::GetHdrImageEnabled(), RSSystemProperties::GetHdrVideoEnabled());
443 ScreenId screenId = node.GetScreenId();
444 bool hasUniRenderHdrSurface = node.GetHasUniRenderHdrSurface();
445 if (RSLuminanceControl::Get().IsCloseHardwareHdr() && !drmNodes_.empty()) {
446 // Disable hdr when drm videos exist to avoid flicker
447 RSLuminanceControl::Get().SetHdrStatus(screenId, HdrStatus::NO_HDR);
448 } else {
449 RSLuminanceControl::Get().SetHdrStatus(screenId, node.GetDisplayHdrStatus());
450 }
451 bool isHdrOn = RSLuminanceControl::Get().IsHdrOn(screenId);
452 rsHdrCollection_->HandleHdrState(isHdrOn);
453 float brightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0);
454 RS_TRACE_NAME_FMT("HDR:%d, in Unirender:%d brightnessRatio:%f", isHdrOn, hasUniRenderHdrSurface, brightnessRatio);
455 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat HDRService isHdrOn:%{public}d hasUniRenderHdrSurface:%{public}d "
456 "brightnessRatio:%{public}f screenId: %{public}" PRIu64 "", isHdrOn, hasUniRenderHdrSurface,
457 brightnessRatio, screenId);
458 if (!hasUniRenderHdrSurface && !RSLuminanceControl::Get().IsCloseHardwareHdr()) {
459 isHdrOn = false;
460 }
461 node.SetHDRPresent(isHdrOn);
462 hasDisplayHdrOn_ |= isHdrOn;
463 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
464 if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
465 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen type failed.");
466 return;
467 }
468
469 if (screenType == VIRTUAL_TYPE_SCREEN) {
470 auto pixelFormat = node.GetPixelFormat();
471 if (screenManager->GetPixelFormat(node.GetScreenId(), pixelFormat) != SUCCESS) {
472 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen color gamut failed.");
473 } else {
474 node.SetPixelFormat(pixelFormat);
475 }
476 }
477 }
478
ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode & node)479 void RSUniRenderVisitor::ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode& node)
480 {
481 // record current frame mainwindow or leashwindow node
482 if (node.IsMainWindowType() || node.IsLeashWindow()) {
483 curMainAndLeashWindowNodesIds_.push(node.GetId());
484 RSMainThread::Instance()->GetRSVsyncRateReduceManager().PushWindowNodeId(node.GetId());
485 curDisplayNode_->RecordMainAndLeashSurfaces(node.shared_from_this());
486 }
487 // only reset for instance node
488 if (curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetId()) {
489 return;
490 }
491 if (auto directParent = node.GetParent().lock()) {
492 if (auto parentInstance = directParent->GetInstanceRootNode()) {
493 // in case leashwindow is not directParent
494 auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
495 if (surfaceParent && (surfaceParent->IsLeashWindow() || surfaceParent->IsMainWindowType())) {
496 curSurfaceNode_ = surfaceParent;
497 curSurfaceDirtyManager_ = surfaceParent->GetDirtyManager();
498 filterInGlobal_ = surfaceParent->IsTransparent();
499 return;
500 }
501 curSurfaceNode_ = nullptr;
502 curSurfaceDirtyManager_ = nullptr;
503 filterInGlobal_ = true;
504 }
505 }
506 }
507
IsHardwareComposerEnabled()508 bool RSUniRenderVisitor::IsHardwareComposerEnabled()
509 {
510 return !isHardwareForcedDisabled_;
511 }
512
UpdateSpecialLayersRecord(RSSurfaceRenderNode & node)513 void RSUniRenderVisitor::UpdateSpecialLayersRecord(RSSurfaceRenderNode& node)
514 {
515 if (node.ShouldPaint() == false) {
516 return;
517 }
518 auto specialLayerMgr = node.GetMultableSpecialLayerMgr();
519 if (specialLayerMgr.Find(SpecialLayerType::HAS_SECURITY)) {
520 curDisplayNode_->AddSecurityLayer(node.IsLeashWindow() ? node.GetLeashPersistentId() : node.GetId());
521 curDisplayNode_->AddSecurityVisibleLayer(node.GetId());
522 }
523 if (specialLayerMgr.Find(SpecialLayerType::HAS_PROTECTED)) {
524 screenManager_->SetScreenHasProtectedLayer(currentVisitDisplay_, true);
525 RS_TRACE_NAME_FMT("SetScreenHasProtectedLayer: %d", currentVisitDisplay_);
526 }
527 auto specialLayerType = specialLayerMgr.Get();
528 if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
529 specialLayerType &= ~SpecialLayerType::HAS_SKIP;
530 }
531 curDisplayNode_->GetMultableSpecialLayerMgr().AddIds((specialLayerType >> SPECIAL_TYPE_NUM), node.GetId());
532 if (node.IsSpecialLayerChanged()) {
533 displaySpecailSurfaceChanged_[currentVisitDisplay_] = true;
534 }
535 }
536
UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode & node)537 void RSUniRenderVisitor::UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode& node)
538 {
539 if (!node.IsMainWindowType()) {
540 return;
541 }
542 auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
543 if (!geoPtr) {
544 return;
545 }
546 if (RSUniRenderUtil::GetRotationDegreeFromMatrix(geoPtr->GetAbsMatrix()) % RS_ROTATION_90 != 0) {
547 node.SetIsRotating(true);
548 }
549 }
550
IsSubTreeOccluded(RSRenderNode & node) const551 bool RSUniRenderVisitor::IsSubTreeOccluded(RSRenderNode& node) const
552 {
553 if (!isOcclusionEnabled_) {
554 return false;
555 }
556 // step1. apply occlusion info for surfacenode and skip fully covered subtree
557 if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
558 auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
559 if (surfaceNode.IsMainWindowType()) {
560 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::IsSubTreeOccluded node[%s]"
561 "name:[%s] visibleRegionIsEmpty[%d]",
562 std::to_string(node.GetId()).c_str(), surfaceNode.GetName().c_str(),
563 surfaceNode.GetVisibleRegion().IsEmpty());
564 auto isOccluded = hasMirrorDisplay_ ?
565 surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
566 isOccluded = isOccluded && (!RSUifirstManager::Instance().IsSubTreeNeedPrepareForSnapshot(surfaceNode));
567 if (isOccluded && curSurfaceDirtyManager_) {
568 curSurfaceDirtyManager_->Clear();
569 }
570 surfaceNode.AccmulateDirtyInOcclusion(isOccluded);
571 return isOccluded;
572 }
573 }
574 // step2.1 For partial visible surface, intersected region->rects in surface
575 // step2.2 check if clean subtree in occlusion rects
576 return false;
577 }
578
ResetDisplayDirtyRegion()579 void RSUniRenderVisitor::ResetDisplayDirtyRegion()
580 {
581 if (!curDisplayDirtyManager_) {
582 return;
583 }
584 if (curDisplayNode_ == nullptr) {
585 return;
586 }
587 bool ret = CheckScreenPowerChange() ||
588 CheckCurtainScreenUsingStatusChange() ||
589 IsFirstFrameOfPartialRender() ||
590 IsWatermarkFlagChanged() ||
591 zoomStateChange_ ||
592 isCompleteRenderEnabled_ ||
593 curDisplayNode_->GetIsLuminanceStatusChange() ||
594 IsFirstFrameOfOverdrawSwitch() ||
595 IsFirstFrameOfDrawingCacheDfxSwitch() ||
596 IsAccessibilityConfigChanged() ||
597 curDisplayNode_->HasMirroredDisplayChanged();
598
599 #ifdef RS_ENABLE_OVERLAY_DISPLAY
600 ret = ret || RSOverlayDisplayManager::Instance().CheckStatusChanged();
601 #endif
602 if (ret) {
603 curDisplayDirtyManager_->ResetDirtyAsSurfaceSize();
604 RS_LOGD("RSUniRenderVisitor::ResetDisplayDirtyRegion on");
605 }
606 }
607
IsAccessibilityConfigChanged() const608 bool RSUniRenderVisitor::IsAccessibilityConfigChanged() const
609 {
610 return RSMainThread::Instance()->IsAccessibilityConfigChanged();
611 }
612
CheckScreenPowerChange() const613 bool RSUniRenderVisitor::CheckScreenPowerChange() const
614 {
615 if (!RSMainThread::Instance()->GetScreenPowerOnChanged()) {
616 return false;
617 }
618 RS_LOGD("RSUniRenderVisitor::CheckScreenPowerChange changed");
619 return true;
620 }
621
CheckCurtainScreenUsingStatusChange() const622 bool RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange() const
623 {
624 if (!RSMainThread::Instance()->IsCurtainScreenUsingStatusChanged()) {
625 return false;
626 }
627 RS_LOGD("RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange changed");
628 return true;
629 }
630
CheckLuminanceStatusChange(ScreenId id)631 bool RSUniRenderVisitor::CheckLuminanceStatusChange(ScreenId id)
632 {
633 // ExchangeLuminanceChangingStatus will be reset false after called in one frame
634 // Use isLuminanceStatusChange_ if need call this function multiple times in one frame
635 if (!RSMainThread::Instance()->ExchangeLuminanceChangingStatus(id)) {
636 return false;
637 }
638 curDisplayNode_->SetIsLuminanceStatusChange(true);
639 RS_LOGD("RSUniRenderVisitor::CheckLuminanceStatusChange changed");
640 return true;
641 }
642
IsFirstFrameOfPartialRender() const643 bool RSUniRenderVisitor::IsFirstFrameOfPartialRender() const
644 {
645 if (!RSMainThread::Instance()->IsFirstFrameOfPartialRender()) {
646 return false;
647 }
648 RS_LOGD("FirstFrameOfPartialRender");
649 return true;
650 }
651
IsFirstFrameOfDrawingCacheDfxSwitch() const652 bool RSUniRenderVisitor::IsFirstFrameOfDrawingCacheDfxSwitch() const
653 {
654 return RSMainThread::Instance()->IsFirstFrameOfDrawingCacheDFXSwitch();
655 }
656
IsFirstFrameOfOverdrawSwitch() const657 bool RSUniRenderVisitor::IsFirstFrameOfOverdrawSwitch() const
658 {
659 if (!RSMainThread::Instance()->IsFirstFrameOfOverdrawSwitch()) {
660 return false;
661 }
662 RS_LOGD("IsFirstFrameOfOverdrawSwitch");
663 return true;
664 }
665
IsWatermarkFlagChanged() const666 bool RSUniRenderVisitor::IsWatermarkFlagChanged() const
667 {
668 if (RSMainThread::Instance()->IsWatermarkFlagChanged()) {
669 RS_LOGD("FirstOrLastFrameOfWatermark");
670 return true;
671 } else {
672 return false;
673 }
674 }
675
UpdateDisplayZoomState()676 void RSUniRenderVisitor::UpdateDisplayZoomState()
677 {
678 if (!curDisplayNode_) {
679 return;
680 }
681 auto scale = curDisplayNode_->GetRenderProperties().GetScale();
682 bool curZoomState = scale.x_ > 1.f || scale.y_ > 1.f;
683 curDisplayNode_->UpdateZoomState(curZoomState);
684 zoomStateChange_ = curZoomState || curDisplayNode_->IsZoomStateChange();
685 }
686
UpdateVirtualScreenInfo(RSDisplayRenderNode & node)687 void RSUniRenderVisitor::UpdateVirtualScreenInfo(RSDisplayRenderNode& node)
688 {
689 // only for virtual screen
690 if (!(node.IsMirrorDisplay())) {
691 node.ClearSecurityLayerList();
692 node.ClearSecurityVisibleLayerList();
693 return;
694 }
695 auto mirrorNode = node.GetMirrorSource().lock();
696 if (mirrorNode == nullptr || screenManager_ == nullptr) {
697 return;
698 }
699
700 UpdateVirtualScreenSecurityExemption(node, *mirrorNode);
701 UpdateVirtualScreenVisibleRectSecurity(node, *mirrorNode);
702 }
703
UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode & node,RSDisplayRenderNode & mirrorNode)704 void RSUniRenderVisitor::UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode& node,
705 RSDisplayRenderNode& mirrorNode)
706 {
707 auto securityExemptionList = screenManager_->GetVirtualScreenSecurityExemptionList(node.GetScreenId());
708 if (securityExemptionList.size() == 0) {
709 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:false",
710 node.GetId());
711 node.SetSecurityExemption(false);
712 return;
713 }
714 auto securityLayerList = mirrorNode.GetSecurityLayerList();
715 for (const auto& exemptionLayer : securityExemptionList) {
716 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
717 "securityExemption nodeId %{public}" PRIu64 ".", node.GetId(), exemptionLayer);
718 }
719 for (const auto& secLayer : securityLayerList) {
720 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
721 "securityLayer nodeId %{public}" PRIu64 ".", mirrorNode.GetId(), secLayer);
722 }
723 bool isSecurityExemption = false;
724 if (securityExemptionList.size() >= securityLayerList.size()) {
725 isSecurityExemption = true;
726 for (const auto& secLayer : securityLayerList) {
727 if (std::find(securityExemptionList.begin(), securityExemptionList.end(), secLayer) ==
728 securityExemptionList.end()) {
729 isSecurityExemption = false;
730 break;
731 }
732 }
733 }
734 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:%{public}d",
735 node.GetId(), isSecurityExemption);
736 node.SetSecurityExemption(isSecurityExemption);
737 }
738
UpdateVirtualScreenVisibleRectSecurity(RSDisplayRenderNode & node,RSDisplayRenderNode & mirrorNode)739 void RSUniRenderVisitor::UpdateVirtualScreenVisibleRectSecurity(RSDisplayRenderNode& node,
740 RSDisplayRenderNode& mirrorNode)
741 {
742 if (!screenManager_->QueryScreenInfo(node.GetScreenId()).enableVisibleRect) {
743 return;
744 }
745 auto rect = screenManager_->GetMirrorScreenVisibleRect(node.GetScreenId());
746 RectI visibleRect(rect.x, rect.y, rect.w, rect.h);
747 auto securityVisibleLayerList = mirrorNode.GetSecurityVisibleLayerList();
748 bool hasSecLayerInVisibleRect = false;
749 for (const auto& secLayerId : securityVisibleLayerList) {
750 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
751 RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode(secLayerId));
752 if (surfaceNode == nullptr) {
753 continue;
754 }
755 const auto& dstRect = surfaceNode->GetDstRect();
756 if (dstRect.Intersect(visibleRect)) {
757 hasSecLayerInVisibleRect = true;
758 break;
759 }
760 }
761 RS_LOGD("%{public}s: hasSecLayerInVisibleRect:%{public}d.", __func__, hasSecLayerInVisibleRect);
762 node.SetHasSecLayerInVisibleRect(hasSecLayerInVisibleRect);
763 }
764
UpdateCurFrameInfoDetail(RSRenderNode & node,bool subTreeSkipped,bool isPostPrepare)765 void RSUniRenderVisitor::UpdateCurFrameInfoDetail(RSRenderNode& node, bool subTreeSkipped, bool isPostPrepare)
766 {
767 if (GetDumpRsTreeDetailEnabled()) {
768 auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
769 curFrameInfoDetail.curFrameVsyncId = HgmCore::Instance().GetVsyncId();
770 curFrameInfoDetail.curFrameSubTreeSkipped = subTreeSkipped;
771 if (isPostPrepare) {
772 curFrameInfoDetail.curFramePostPrepareSeqNum = IncreasePostPrepareSeq();
773 } else {
774 curFrameInfoDetail.curFramePrepareSeqNum = IncreasePrepareSeq();
775 }
776 }
777 }
778
QuickPrepareDisplayRenderNode(RSDisplayRenderNode & node)779 void RSUniRenderVisitor::QuickPrepareDisplayRenderNode(RSDisplayRenderNode& node)
780 {
781 UpdateCurFrameInfoDetail(node);
782 // 0. init display info
783 RS_TRACE_NAME("RSUniRender:QuickPrepareDisplayRenderNode " + std::to_string(node.GetScreenId()));
784 if (!InitDisplayInfo(node)) {
785 return;
786 }
787 UpdateDisplayZoomState();
788 SendRcdMessage(node);
789 UpdateVirtualScreenInfo(node);
790 ancestorNodeHasAnimation_ = false;
791 displayNodeRotationChanged_ = node.IsRotationChanged();
792 dirtyFlag_ = isDirty_ || displayNodeRotationChanged_ || zoomStateChange_ ||
793 curDisplayDirtyManager_->IsActiveSurfaceRectChanged();
794 prepareClipRect_ = screenRect_;
795 hasAccumulatedClip_ = false;
796
797 globalShouldPaint_ = true;
798 curAlpha_ = 1.0f;
799 globalZOrder_ = 0.0f;
800 appWindowZOrder_ = 0;
801 hasSkipLayer_ = false;
802 curZorderForCalcHwcNodeEnableByFilter_ = 0;
803 node.zOrderForCalcHwcNodeEnableByFilter_ = curZorderForCalcHwcNodeEnableByFilter_++;
804 node.UpdateRotation();
805 if (!(RSMainThread::Instance()->IsRequestedNextVSync() || RSMainThread::Instance()->GetNextDVsyncAnimateFlag())) {
806 RS_OPTIONAL_TRACE_NAME_FMT("do not request next vsync");
807 needRequestNextVsync_ = false;
808 }
809 RSUifirstManager::Instance().SetRotationChanged(displayNodeRotationChanged_ || isScreenRotationAnimating_);
810 if (node.IsSubTreeDirty() || node.IsRotationChanged()) {
811 QuickPrepareChildren(node);
812 TryNotifyUIBufferAvailable();
813 }
814 PostPrepare(node);
815 UpdateHwcNodeEnable();
816 UpdateDisplayRcdRenderNode();
817 UpdateSurfaceDirtyAndGlobalDirty();
818 UpdateSurfaceOcclusionInfo();
819 if (needRecalculateOcclusion_) {
820 // Callback for registered self drawing surfacenode
821 RSMainThread::Instance()->SurfaceOcclusionCallback();
822 }
823 curDisplayNode_->UpdatePartialRenderParams();
824 RSDisplayRenderNode::ScreenRenderParams screenRenderParams;
825 screenRenderParams.screenInfo = std::move(screenInfo_);
826 screenRenderParams.displaySpecailSurfaceChanged = std::move(displaySpecailSurfaceChanged_);
827 screenRenderParams.hasCaptureWindow = std::move(hasCaptureWindow_);
828 curDisplayNode_->SetFingerprint(hasFingerprint_[currentVisitDisplay_]);
829 curDisplayNode_->UpdateScreenRenderParams(screenRenderParams);
830 curDisplayNode_->UpdateOffscreenRenderParams(curDisplayNode_->IsRotationChanged());
831 UpdateColorSpaceAfterHwcCalc(node);
832 RSHdrUtil::UpdatePixelFormatAfterHwcCalc(node);
833 HandleColorGamuts(node, screenManager_);
834 HandlePixelFormat(node, screenManager_);
835 if (UNLIKELY(!SharedTransitionParam::unpairedShareTransitions_.empty())) {
836 ProcessUnpairedSharedTransitionNode();
837 }
838 node.HandleCurMainAndLeashSurfaceNodes();
839 layerNum_ += node.GetSurfaceCountForMultiLayersPerf();
840 node.RenderTraceDebug();
841 containerFilter_.clear();
842 globalFilter_.clear();
843 curSurfaceNoBelowDirtyFilter_.clear();
844 curDisplayNode_->ResetMirroredDisplayChangedFlag();
845 PrepareForMultiScreenViewDisplayNode(node);
846 }
847
CheckFilterCacheNeedForceClearOrSave(RSRenderNode & node)848 void RSUniRenderVisitor::CheckFilterCacheNeedForceClearOrSave(RSRenderNode& node)
849 {
850 if (!node.HasBlurFilter()) {
851 return;
852 }
853 bool rotationChanged = curDisplayNode_ ?
854 curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
855 bool rotationStatusChanged = curDisplayNode_ ?
856 curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
857 node.CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
858 }
859
860 // private method, curDisplayNode_ or curSurfaceNode_ will not be nullptr
CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet & filterSet,bool isGlobalDirty)861 void RSUniRenderVisitor::CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet& filterSet, bool isGlobalDirty)
862 {
863 if (curDisplayNode_ == nullptr) {
864 RS_LOGE("RSUniRenderVisitor::CheckMergeFilterDirtyByIntersectWithDirty: curDisplayNode_ is nullptr");
865 return;
866 }
867 // Recursively traverses until the globalDirty do not change
868 auto dirtyManager = isGlobalDirty ? curDisplayNode_->GetDirtyManager() : curSurfaceNode_->GetDirtyManager();
869 if (dirtyManager == nullptr) {
870 return;
871 }
872 for (auto it = filterSet.begin(); it != filterSet.end();) {
873 auto dirtyRect = dirtyManager->GetCurrentFrameDirtyRegion();
874 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
875 auto dirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
876 auto filterDirtyRegion = filterRegion.And(dirtyRegion);
877 if (!filterDirtyRegion.IsEmpty()) {
878 if (isGlobalDirty) {
879 RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
880 "global dirty %{public}s, add filterRegion %{public}s",
881 dirtyRect.ToString().c_str(), (it->second).ToString().c_str());
882 }
883 dirtyManager->MergeDirtyRect(it->second);
884 it = filterSet.erase(it);
885 if (dirtyRect != dirtyManager->GetCurrentFrameDirtyRegion()) {
886 // When dirtyRegion is changed, collect dirty filter region from begin.
887 // After all filter region is added, the cycle will definitely stop.
888 it = filterSet.begin();
889 }
890 } else {
891 ++it;
892 }
893 }
894 filterSet.clear();
895 }
896
PrepareForSkippedCrossNode(RSSurfaceRenderNode & surfaceNode)897 void RSUniRenderVisitor::PrepareForSkippedCrossNode(RSSurfaceRenderNode& surfaceNode)
898 {
899 // 1. Find the actual surface node of which the coordinates must be recalculated.
900 auto sourceNode = surfaceNode.GetSourceCrossNode().lock();
901 auto sourceSurface = sourceNode ? sourceNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
902 RSSurfaceRenderNode& nodeRef = sourceSurface ? *sourceSurface : surfaceNode;
903 auto geoPtr = nodeRef.GetRenderProperties().GetBoundsGeometry();
904 if (!geoPtr) {
905 return;
906 }
907 // 2. Get the AbsMatrix under current display node. Concatenate current parent matrix and nodeRef relative matrix.
908 Drawing::Matrix nodeAbsMatrix = geoPtr->GetMatrix();
909 if (nodeRef.GetGlobalPositionEnabled()) {
910 nodeAbsMatrix.PostTranslate(-curDisplayNode_->GetDisplayOffsetX(), -curDisplayNode_->GetDisplayOffsetY());
911 }
912 if (auto parent = surfaceNode.GetParent().lock()) {
913 auto parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
914 nodeAbsMatrix.PostConcat(parentGeoPtr ? parentGeoPtr->GetAbsMatrix() : Drawing::Matrix());
915 }
916 // 3. Get the conversion matrix from first display coordinate system to current display coordinate system.
917 // 3.1 Invert AbsMatrix under first display.
918 // 3.2 Apply AbsMatrix under second display.
919 Drawing::Matrix conversionMatrix;
920 if (!geoPtr->GetAbsMatrix().Invert(conversionMatrix)) {
921 curDisplayDirtyManager_->ResetDirtyAsSurfaceSize();
922 RS_LOGW("Cross-Node matrix inverting for %{public}s failed, set full screen dirty.", nodeRef.GetName().c_str());
923 return;
924 }
925 conversionMatrix.PostConcat(nodeAbsMatrix);
926
927 // 4. record this surface node and its position on second display, for global dirty region conversion.
928 curDisplayNode_->RecordMainAndLeashSurfaces(nodeRef.shared_from_this());
929 nodeRef.UpdateCrossNodeSkipDisplayConversionMatrices(curDisplayNode_->GetId(), conversionMatrix);
930 RectI surfaceRect =
931 geoPtr->MapRect(nodeRef.GetOldDirty().ConvertTo<float>(), conversionMatrix).IntersectRect(screenRect_);
932 curDisplayNode_->UpdateSurfaceNodePos(nodeRef.GetId(), surfaceRect);
933 curDisplayNode_->AddSurfaceNodePosByDescZOrder(nodeRef.GetId(), surfaceRect);
934 // 5. record all children surface nodes and their position on second display, for global dirty region conversion.
935 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
936 nodeRef.GetAllSubSurfaceNodes(allSubSurfaceNodes);
937 for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
938 if (auto childPtr = subSurfaceNode.lock()) {
939 curDisplayNode_->RecordMainAndLeashSurfaces(childPtr);
940 childPtr->SetFirstLevelCrossNode(nodeRef.IsFirstLevelCrossNode());
941 childPtr->UpdateCrossNodeSkipDisplayConversionMatrices(curDisplayNode_->GetId(), conversionMatrix);
942 RectI childSurfaceRect = geoPtr->MapRect(
943 childPtr->GetOldDirty().ConvertTo<float>(), conversionMatrix).IntersectRect(screenRect_);
944 curDisplayNode_->UpdateSurfaceNodePos(childPtr->GetId(), childSurfaceRect);
945 curDisplayNode_->AddSurfaceNodePosByDescZOrder(childPtr->GetId(), childSurfaceRect);
946 }
947 }
948 }
949
CheckSkipAndPrepareForCrossNode(RSSurfaceRenderNode & node)950 bool RSUniRenderVisitor::CheckSkipAndPrepareForCrossNode(RSSurfaceRenderNode& node)
951 {
952 auto sourceRenderNode = node.GetSourceCrossNode().lock();
953 RSSurfaceRenderNode::SharedPtr sourceNode = sourceRenderNode ?
954 sourceRenderNode->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
955 // CloneCrossNode must have a source node.
956 if (node.IsCloneCrossNode() && sourceNode == nullptr) {
957 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode source node of clone node %{public}"
958 PRIu64 " is null", node.GetId());
959 return true;
960 }
961
962 // skip CrossNode not on first display
963 if (CheckSkipCrossNode(node)) {
964 // when skip cloneCrossNode prepare, we need switch to record sourceNode dirty info
965 PrepareForSkippedCrossNode(node);
966 return true;
967 }
968
969 // when prepare CloneCrossNode on first display, we need switch to prepare sourceNode.
970 if (node.IsCloneCrossNode()) {
971 isSwitchToSourceCrossNodePrepare_ = true;
972 sourceNode->SetCurCloneNodeParent(node.GetParent().lock());
973 sourceNode->QuickPrepare(shared_from_this());
974 sourceNode->SetCurCloneNodeParent(nullptr);
975 isSwitchToSourceCrossNodePrepare_ = false;
976 return true;
977 }
978 return false;
979 }
980
QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode & node)981 void RSUniRenderVisitor::QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
982 {
983 UpdateCurFrameInfoDetail(node);
984 RS_TRACE_NAME_FMT("RSUniRender::QuickPrepare:[%s] nodeId[%" PRIu64 "] pid[%d] nodeType[%u]"
985 " subTreeDirty[%d], crossDisplay:[%d]", node.GetName().c_str(), node.GetId(), ExtractPid(node.GetId()),
986 static_cast<uint>(node.GetSurfaceNodeType()), node.IsSubTreeDirty(), node.IsFirstLevelCrossNode());
987 RS_LOGD("RSUniRender::QuickPrepareSurfaceRenderNode:[%{public}s] nodeid:[%{public}" PRIu64 "] pid:[%{public}d] "
988 "nodeType:[%{public}d] subTreeDirty[%{public}d] crossDisplay[%{public}d]", node.GetName().c_str(), node.GetId(),
989 ExtractPid(node.GetId()), static_cast<int>(node.GetSurfaceNodeType()), node.IsSubTreeDirty(),
990 node.IsFirstLevelCrossNode());
991
992 if (PrepareForCloneNode(node)) {
993 return;
994 }
995
996 // AppWindow is traversed in reverse order
997 // Prepare operation will be executed first when the node is at the top level
998 // The value of appWindowZOrder_ decreases from 0 to negative
999 if (node.IsAppWindow()) {
1000 node.SetAppWindowZOrder(appWindowZOrder_--);
1001 }
1002
1003 // avoid cross node subtree visited twice or more
1004 UpdateSpecialLayersRecord(node);
1005 if (CheckSkipAndPrepareForCrossNode(node)) {
1006 return;
1007 }
1008 // 0. init curSurface info and check node info
1009 auto curCornerRadius = curCornerRadius_;
1010 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
1011 if (!BeforeUpdateSurfaceDirtyCalc(node)) {
1012 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode BeforeUpdateSurfaceDirtyCalc fail");
1013 RSUifirstManager::Instance().DisableUifirstNode(node);
1014 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1015 return;
1016 }
1017
1018 if (curSurfaceDirtyManager_ == nullptr) {
1019 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
1020 node.GetName().c_str());
1021 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1022 return;
1023 }
1024 curSurfaceDirtyManager_->SetAdvancedDirtyRegionType(advancedDirtyType_);
1025
1026 // 1. Update matrix and collect dirty region
1027 auto dirtyFlag = dirtyFlag_;
1028 auto prepareClipRect = prepareClipRect_;
1029 bool hasAccumulatedClip = hasAccumulatedClip_;
1030 auto prevAlpha = curAlpha_;
1031 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1032 node.SetGlobalAlpha(curAlpha_);
1033 auto preGlobalShouldPaint = globalShouldPaint_;
1034 globalShouldPaint_ &= node.ShouldPaint();
1035 node.SetSelfAndParentShouldPaint(globalShouldPaint_);
1036 CheckFilterCacheNeedForceClearOrSave(node);
1037 node.CheckContainerDirtyStatusAndUpdateDirty(curContainerDirty_);
1038 node.ClearCrossNodeSkipDisplayConversionMatrices();
1039 node.SetPreparedDisplayOffsetX(curDisplayNode_->GetDisplayOffsetX());
1040 node.SetPreparedDisplayOffsetY(curDisplayNode_->GetDisplayOffsetY());
1041 if (node.GetGlobalPositionEnabled()) {
1042 parentSurfaceNodeMatrix_.Translate(
1043 -curDisplayNode_->GetDisplayOffsetX(), -curDisplayNode_->GetDisplayOffsetY());
1044 }
1045
1046 dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
1047 *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix);
1048 auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
1049 if (!geoPtr) {
1050 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1051 globalShouldPaint_ = preGlobalShouldPaint;
1052 return;
1053 }
1054 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
1055 if (!AfterUpdateSurfaceDirtyCalc(node)) {
1056 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode AfterUpdateSurfaceDirtyCalc fail");
1057 RSUifirstManager::Instance().DisableUifirstNode(node);
1058 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1059 globalShouldPaint_ = preGlobalShouldPaint;
1060 return;
1061 }
1062 bool isDimmingOn = RSLuminanceControl::Get().IsDimmingOn(curDisplayNode_->GetScreenId());
1063 if (isDimmingOn) {
1064 bool hasHdrPresent = node.GetHDRPresent();
1065 bool hasHdrVideo = node.GetVideoHdrStatus() != HdrStatus::NO_HDR;
1066 RS_LOGD("HDRDiming IsDimmingOn: %{public}d, GetHDRPresent: %{public}d, GetHdrVideo: %{public}d",
1067 isDimmingOn, hasHdrPresent, hasHdrVideo);
1068 if (hasHdrPresent || hasHdrVideo) {
1069 node.SetContentDirty(); // HDR content is dirty on Dimming status.
1070 }
1071 }
1072 CollectSelfDrawingNodeRectInfo(node);
1073 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1074 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_, IsSubTreeOccluded(node)) ||
1075 ForcePrepareSubTree();
1076 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1077 node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
1078 if (curSurfaceDirtyManager_ == nullptr) {
1079 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager "
1080 "is set to nullptr by QuickPrepareChildren", node.GetName().c_str());
1081 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1082 globalShouldPaint_ = preGlobalShouldPaint;
1083 return;
1084 }
1085 if (!node.IsFirstLevelCrossNode()) {
1086 curSurfaceDirtyManager_->ClipDirtyRectWithinSurface();
1087 }
1088 auto dirtyRect = node.GetDirtyManager()->GetCurrentFrameDirtyRegion();
1089 RS_LOGD("QuickPrepare [%{public}s, %{public}" PRIu64 "] DirtyRect[%{public}d, %{public}d, %{public}d, %{public}d]",
1090 node.GetName().c_str(), node.GetId(), dirtyRect.GetLeft(), dirtyRect.GetTop(), dirtyRect.GetWidth(),
1091 dirtyRect.GetHeight());
1092
1093 // Update whether leash window's visible region is empty after prepare children
1094 UpdateLeashWindowVisibleRegionEmpty(node);
1095
1096 if (node.IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()) {
1097 CheckIsGpuOverDrawBufferOptimizeNode(node);
1098 }
1099 PostPrepare(node, !isSubTreeNeedPrepare);
1100 if (node.IsHardwareEnabledTopSurface() && node.shared_from_this()) {
1101 RSUniRenderUtil::UpdateHwcNodeProperty(node.shared_from_this()->ReinterpretCastTo<RSSurfaceRenderNode>());
1102 }
1103 CalculateOpaqueAndTransparentRegion(node);
1104 CheckMergeFilterDirtyByIntersectWithDirty(curSurfaceNoBelowDirtyFilter_, false);
1105 curAlpha_ = prevAlpha;
1106 globalShouldPaint_ = preGlobalShouldPaint;
1107 prepareClipRect_ = prepareClipRect;
1108 hasAccumulatedClip_ = hasAccumulatedClip;
1109 dirtyFlag_ = dirtyFlag;
1110 PrepareForUIFirstNode(node);
1111 PrepareForCrossNode(node);
1112 node.UpdateInfoForClonedNode(clonedSourceNodeId_);
1113 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1114 ResetCurSurfaceInfoAsUpperSurfaceParent(node);
1115 curCornerRadius_ = curCornerRadius;
1116 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
1117
1118 // [Attention] Only used in PC window resize scene now
1119 windowKeyFrameNodeInf_.PrepareRootNodeOffscreen(node);
1120
1121 node.RenderTraceDebug();
1122 node.SetNeedOffscreen(isScreenRotationAnimating_);
1123 if (node.NeedUpdateDrawableBehindWindow()) {
1124 node.UpdateDrawableBehindWindow();
1125 node.SetOldNeedDrawBehindWindow(node.NeedDrawBehindWindow());
1126 }
1127 if (node.IsUIBufferAvailable()) {
1128 uiBufferAvailableId_.emplace_back(node.GetId());
1129 }
1130 PrepareForMultiScreenViewSurfaceNode(node);
1131 }
1132
PrepareForMultiScreenViewSurfaceNode(RSSurfaceRenderNode & node)1133 void RSUniRenderVisitor::PrepareForMultiScreenViewSurfaceNode(RSSurfaceRenderNode& node)
1134 {
1135 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1136 auto sourceNode = nodeMap.GetRenderNode<RSDisplayRenderNode>(node.GetSourceDisplayRenderNodeId());
1137 if (!sourceNode) {
1138 return;
1139 }
1140 node.SetContentDirty();
1141 sourceNode->SetTargetSurfaceRenderNodeId(node.GetId());
1142 auto sourceNodeDrawable = sourceNode->GetRenderDrawable();
1143 if (!sourceNodeDrawable) {
1144 return;
1145 }
1146 RS_TRACE_NAME_FMT("PrepareForMultiScreenViewSurfaceNode surfaceNodeId: %llu sourceVirtualDisplayId: %llu",
1147 node.GetId(), node.GetSourceDisplayRenderNodeId());
1148 node.SetSourceDisplayRenderNodeDrawable(sourceNodeDrawable);
1149 }
1150
PrepareForMultiScreenViewDisplayNode(RSDisplayRenderNode & node)1151 void RSUniRenderVisitor::PrepareForMultiScreenViewDisplayNode(RSDisplayRenderNode& node)
1152 {
1153 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1154 auto targetNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(node.GetTargetSurfaceRenderNodeId());
1155 if (!targetNode) {
1156 return;
1157 }
1158 auto targetRenderNodeDrawable = targetNode->GetRenderDrawable();
1159 if (!targetRenderNodeDrawable) {
1160 return;
1161 }
1162 RS_TRACE_NAME_FMT("PrepareForMultiScreenViewDisplayNode displayNodeId: %llu targetSurfaceRenderNodeId: %llu",
1163 node.GetId(), node.GetTargetSurfaceRenderNodeId());
1164 node.SetTargetSurfaceRenderNodeDrawable(targetRenderNodeDrawable);
1165 }
1166
PrepareForCloneNode(RSSurfaceRenderNode & node)1167 bool RSUniRenderVisitor::PrepareForCloneNode(RSSurfaceRenderNode& node)
1168 {
1169 if (!node.IsCloneNode() || !node.IsLeashOrMainWindow()) {
1170 return false;
1171 }
1172 RS_LOGD("RSUniRenderVisitor::PrepareForCloneNode %{public}s is cloneNode", node.GetName().c_str());
1173 node.SetIsClonedNodeOnTheTree(false);
1174 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1175 auto clonedNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(node.GetClonedNodeId());
1176 if (clonedNode == nullptr) {
1177 RS_LOGE("RSUniRenderVisitor::PrepareForCloneNode clonedNode is nullptr");
1178 return false;
1179 }
1180 if (!clonedNode->IsMainWindowType()) {
1181 return false;
1182 }
1183 auto clonedNodeRenderDrawable = clonedNode->GetRenderDrawable();
1184 if (clonedNodeRenderDrawable == nullptr) {
1185 RS_LOGE("RSUniRenderVisitor::PrepareForCloneNode clonedNodeRenderDrawable is nullptr");
1186 return false;
1187 }
1188 node.SetIsClonedNodeOnTheTree(clonedNode->IsOnTheTree());
1189 clonedSourceNodeId_ = node.GetClonedNodeId();
1190 node.SetClonedNodeRenderDrawable(clonedNodeRenderDrawable);
1191 node.UpdateRenderParams();
1192 node.AddToPendingSyncList();
1193 return true;
1194 }
1195
PrepareForCrossNode(RSSurfaceRenderNode & node)1196 void RSUniRenderVisitor::PrepareForCrossNode(RSSurfaceRenderNode& node)
1197 {
1198 if (isCrossNodeOffscreenOn_ == CrossNodeOffScreenRenderDebugType::DISABLED) {
1199 return;
1200 }
1201 if (curDisplayNode_ == nullptr) {
1202 RS_LOGE("%{public}s curDisplayNode_ is nullptr", __func__);
1203 return;
1204 }
1205 if (curDisplayNode_->IsFirstVisitCrossNodeDisplay() && node.IsCrossNode()) {
1206 // check surface cache condition, not support ratation, transparent filter situation.
1207 bool needCacheSurface = node.QuerySubAssignable(curDisplayNode_->IsRotationChanged());
1208 if (needCacheSurface) {
1209 node.SetHwcChildrenDisabledState();
1210 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " children disabled by crossNode",
1211 node.GetName().c_str(), node.GetId());
1212 }
1213 node.SetNeedCacheSurface(needCacheSurface);
1214 }
1215 }
1216
CheckSkipCrossNode(RSSurfaceRenderNode & node)1217 bool RSUniRenderVisitor::CheckSkipCrossNode(RSSurfaceRenderNode& node)
1218 {
1219 if (!node.IsCrossNode() || isSwitchToSourceCrossNodePrepare_) {
1220 return false;
1221 }
1222 if (curDisplayNode_ == nullptr) {
1223 RS_LOGE("%{public}s curDisplayNode_ is nullptr", __func__);
1224 return false;
1225 }
1226 node.SetCrossNodeOffScreenStatus(isCrossNodeOffscreenOn_);
1227 curDisplayNode_->SetHasChildCrossNode(true);
1228 if (hasVisitCrossNode_) {
1229 RS_OPTIONAL_TRACE_NAME_FMT("%s cross node[%s] skip", __func__, node.GetName().c_str());
1230 return true;
1231 }
1232 curDisplayNode_->SetIsFirstVisitCrossNodeDisplay(true);
1233 hasVisitCrossNode_ = true;
1234 return false;
1235 }
1236
CollectTopOcclusionSurfacesInfo(RSSurfaceRenderNode & node,bool isParticipateInOcclusion)1237 void RSUniRenderVisitor::CollectTopOcclusionSurfacesInfo(RSSurfaceRenderNode& node, bool isParticipateInOcclusion)
1238 {
1239 if (!isStencilPixelOcclusionCullingEnabled_) {
1240 return;
1241 }
1242 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1243 if (!parent || !parent->IsLeashWindow()) {
1244 return;
1245 }
1246 auto stencilVal = occlusionSurfaceOrder_ * OCCLUSION_ENABLE_SCENE_NUM;
1247 if (!isParticipateInOcclusion) {
1248 if (occlusionSurfaceOrder_ < TOP_OCCLUSION_SURFACES_NUM) {
1249 parent->SetStencilVal(stencilVal);
1250 }
1251 return;
1252 }
1253 parent->SetStencilVal(stencilVal);
1254 if (occlusionSurfaceOrder_ > 0) {
1255 auto opaqueRegionRects = node.GetOpaqueRegion().GetRegionRects();
1256 if (curDisplayNode_ == nullptr) {
1257 RS_LOGE("RSUniRenderVisitor::CollectTopOcclusionSurfacesInfo curDisplayNode_ is nullptr");
1258 return;
1259 }
1260 if (!opaqueRegionRects.empty()) {
1261 auto maxOpaqueRect = std::max_element(opaqueRegionRects.begin(), opaqueRegionRects.end(),
1262 [](Occlusion::Rect a, Occlusion::Rect b) ->bool { return a.Area() < b.Area(); });
1263 curDisplayNode_->RecordTopSurfaceOpaqueRects(*maxOpaqueRect);
1264 parent->SetStencilVal(stencilVal);
1265 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::CollectTopOcclusionSurfacesInfo record name[%s] rect[%s]",
1266 node.GetName().c_str(), (*maxOpaqueRect).GetRectInfo().c_str());
1267 --occlusionSurfaceOrder_;
1268 }
1269 }
1270 }
1271
PrepareForUIFirstNode(RSSurfaceRenderNode & node)1272 void RSUniRenderVisitor::PrepareForUIFirstNode(RSSurfaceRenderNode& node)
1273 {
1274 RSUifirstManager::Instance().MarkSubHighPriorityType(node);
1275 auto isSurface = CheckIfSurfaceForUIFirstDFX(node.GetName());
1276 if (isTargetUIFirstDfxEnabled_) {
1277 auto isTargetUIFirstDfxSurface = CheckIfSurfaceForUIFirstDFX(node.GetName());
1278 if (!node.isTargetUIFirstDfxEnabled_ && isTargetUIFirstDfxSurface) {
1279 RS_LOGD("UIFirstDFX Name[%{public}s] ID[%{public}" PRIu64 "] OpenDebug",
1280 node.GetName().c_str(), node.GetId());
1281 }
1282 node.isTargetUIFirstDfxEnabled_ = isTargetUIFirstDfxSurface;
1283 }
1284 RSUifirstManager::Instance().UpdateUifirstNodes(node, ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation());
1285 }
1286
UpdateNodeVisibleRegion(RSSurfaceRenderNode & node)1287 void RSUniRenderVisitor::UpdateNodeVisibleRegion(RSSurfaceRenderNode& node)
1288 {
1289 if (!curDisplayNode_) {
1290 RS_LOGE("RSUniRenderVisitor::UpdateNodeVisibleRegion curDisplayNode is nullptr");
1291 return;
1292 }
1293 // occlusion - 0. Calculate node visible region considering accumulated opaque region of upper surface nodes.
1294 if (!curDisplayNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) {
1295 RS_LOGD("RSUniRenderVisitor::UpdateNodeVisibleRegion NodeName: %{public}s, NodeId: %{public}" PRIu64 ""
1296 "not paticipate in occlusion when cross node in expand screen", node.GetName().c_str(), node.GetId());
1297 return;
1298 }
1299 Occlusion::Rect selfDrawRect = node.GetSurfaceOcclusionRect(true);
1300 Occlusion::Region selfDrawRegion { selfDrawRect };
1301 needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.CheckIfOcclusionChanged();
1302 if (needRecalculateOcclusion_) {
1303 Occlusion::Region subResult = selfDrawRegion.Sub(accumulatedOcclusionRegion_);
1304 node.SetVisibleRegion(subResult);
1305 Occlusion::Region subResultWithoutSkipLayer = selfDrawRegion.Sub(occlusionRegionWithoutSkipLayer_);
1306 node.SetVisibleRegionInVirtual(subResultWithoutSkipLayer);
1307 }
1308 RS_OPTIONAL_TRACE_NAME_FMT_LEVEL(TRACE_LEVEL_THREE,
1309 "RSUniRenderVisitor::UpdateNodeVisibleRegion name[%s] visibleRegion[%s]",
1310 node.GetName().c_str(), node.GetVisibleRegion().GetRegionInfo().c_str());
1311 }
1312
CalculateOpaqueAndTransparentRegion(RSSurfaceRenderNode & node)1313 void RSUniRenderVisitor::CalculateOpaqueAndTransparentRegion(RSSurfaceRenderNode& node)
1314 {
1315 if (!curDisplayNode_) {
1316 RS_LOGE("RSUniRenderVisitor::CalculateOpaqueAndTransparentRegion curDisplayNode is nullptr");
1317 return;
1318 }
1319 // occlusion - 1. Only non-cross-screen main window surface node participate in occlusion.
1320 if ((!curDisplayNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) ||
1321 !node.IsMainWindowType()) {
1322 RS_LOGD("RSUniRenderVisitor::CalculateOpaqueAndTransparentRegion Node: %{public}s, NodeId: %{public}" PRIu64 ""
1323 "not paticipate in occlusion", node.GetName().c_str(), node.GetId());
1324 return;
1325 }
1326
1327 // occlusion - 2. Calculate opaque/transparent region based on round corner, container window, etc.
1328 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1329 auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
1330 (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
1331 node.CheckAndUpdateOpaqueRegion(screenRect_, curDisplayNode_->GetRotation(), isFocused);
1332 // occlusion - 3. Accumulate opaque region to occlude lower surface nodes (with/without special layer).
1333 hasSkipLayer_ = hasSkipLayer_ || node.GetSpecialLayerMgr().Find(SpecialLayerType::SKIP);
1334 auto mainThread = RSMainThread::Instance();
1335 node.SetOcclusionInSpecificScenes(mainThread->GetIsRegularAnimation());
1336 bool occlusionInAnimation = node.GetOcclusionInSpecificScenes() || !ancestorNodeHasAnimation_;
1337 bool isParticipateInOcclusion = node.CheckParticipateInOcclusion() &&
1338 occlusionInAnimation && !isAllSurfaceVisibleDebugEnabled_;
1339 CollectTopOcclusionSurfacesInfo(node, isParticipateInOcclusion);
1340 if (isParticipateInOcclusion) {
1341 RS_OPTIONAL_TRACE_NAME_FMT("Occlusion: surface node[%s] participate in occlusion with opaque region: [%s]",
1342 node.GetName().c_str(), node.GetOpaqueRegion().GetRegionInfo().c_str());
1343 accumulatedOcclusionRegion_.OrSelf(node.GetOpaqueRegion());
1344 if (IsValidInVirtualScreen(node)) {
1345 occlusionRegionWithoutSkipLayer_.OrSelf(node.GetOpaqueRegion());
1346 }
1347 }
1348 needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.CheckIfOcclusionChanged();
1349 node.SetOcclusionInSpecificScenes(false);
1350 CollectOcclusionInfoForWMS(node);
1351 RSMainThread::Instance()->GetRSVsyncRateReduceManager().CollectSurfaceVsyncInfo(screenInfo_, node);
1352 }
1353
CollectOcclusionInfoForWMS(RSSurfaceRenderNode & node)1354 void RSUniRenderVisitor::CollectOcclusionInfoForWMS(RSSurfaceRenderNode& node)
1355 {
1356 if (!node.IsMainWindowType()) {
1357 return;
1358 }
1359 // collect mainWindow occlusion visibleLevel
1360 Occlusion::Region selfDrawRegion { node.GetSurfaceOcclusionRect(true) };
1361 auto visibleLevel = GetRegionVisibleLevel(node.GetVisibleRegion(), selfDrawRegion);
1362
1363 // wms default all visible about sefdrawing node and AbilityComponent node
1364 auto instanceNode = node.GetInstanceRootNode() ?
1365 node.GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1366 if (instanceNode == nullptr) {
1367 return;
1368 }
1369 if ((node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
1370 !instanceNode->GetVisibleRegion().IsEmpty()) || node.IsAbilityComponent()) {
1371 dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1372 WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1373 return;
1374 }
1375 dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1376 node.GetVisibleLevelForWMS(visibleLevel)));
1377 }
1378
SurfaceOcclusionCallbackToWMS()1379 void RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS()
1380 {
1381 if (RSSystemParameters::GetOcclusionCallBackToWMSDebugType()) {
1382 allDstCurVisVec_.clear();
1383 const auto& curAllSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1384 for (const auto& surfacePtr : curAllSurfaces) {
1385 if (surfacePtr == nullptr) {
1386 continue;
1387 }
1388 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*surfacePtr);
1389 if (surfaceNode.IsMainWindowType()) {
1390 allDstCurVisVec_.emplace_back(std::make_pair(surfacePtr->GetId(),
1391 WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1392 }
1393 }
1394 }
1395 if (allDstCurVisVec_ != allLastVisVec_) {
1396 RSMainThread::Instance()->SurfaceOcclusionChangeCallback(allDstCurVisVec_);
1397 RS_LOGI("OcclusionInfo %{public}s", VisibleDataToString(allDstCurVisVec_).c_str());
1398 allLastVisVec_ = std::move(allDstCurVisVec_);
1399 }
1400 }
1401
GetRegionVisibleLevel(const Occlusion::Region & visibleRegion,const Occlusion::Region & selfDrawRegion)1402 RSVisibleLevel RSUniRenderVisitor::GetRegionVisibleLevel(const Occlusion::Region& visibleRegion,
1403 const Occlusion::Region& selfDrawRegion)
1404 {
1405 if (visibleRegion.IsEmpty()) {
1406 return RSVisibleLevel::RS_INVISIBLE;
1407 } else if (visibleRegion.Area() == selfDrawRegion.Area()) {
1408 return RSVisibleLevel::RS_ALL_VISIBLE;
1409 } else if (static_cast<uint>(visibleRegion.Area()) <
1410 (static_cast<uint>(selfDrawRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
1411 return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
1412 }
1413 return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
1414 }
1415
QuickPrepareEffectRenderNode(RSEffectRenderNode & node)1416 void RSUniRenderVisitor::QuickPrepareEffectRenderNode(RSEffectRenderNode& node)
1417 {
1418 UpdateCurFrameInfoDetail(node);
1419 // 0. check current node need to tranverse
1420 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
1421 if (!dirtyManager) {
1422 RS_LOGE("RSUniRenderVisitor::QuickPrepareEffectRenderNode dirtyManager is nullptr");
1423 return;
1424 }
1425 auto dirtyFlag = dirtyFlag_;
1426 auto prevAlpha = curAlpha_;
1427 auto curCornerRadius = curCornerRadius_;
1428 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1429 UpdateRotationStatusForEffectNode(node);
1430 CheckFilterCacheNeedForceClearOrSave(node);
1431 RectI prepareClipRect = prepareClipRect_;
1432 bool hasAccumulatedClip = hasAccumulatedClip_;
1433 dirtyFlag_ =
1434 node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1435 node.UpdateCurCornerRadius(curCornerRadius_);
1436 // 1. Recursively traverse child nodes
1437 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1438 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
1439 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1440 node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1441
1442 PostPrepare(node, !isSubTreeNeedPrepare);
1443 prepareClipRect_ = prepareClipRect;
1444 hasAccumulatedClip_ = hasAccumulatedClip;
1445 dirtyFlag_ = dirtyFlag;
1446 curAlpha_ = prevAlpha;
1447 curCornerRadius_ = curCornerRadius;
1448 node.RenderTraceDebug();
1449 }
1450
QuickPrepareCanvasRenderNode(RSCanvasRenderNode & node)1451 void RSUniRenderVisitor::QuickPrepareCanvasRenderNode(RSCanvasRenderNode& node)
1452 {
1453 UpdateCurFrameInfoDetail(node);
1454 // 0. check current node need to traverse
1455 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
1456 auto dirtyFlag = dirtyFlag_;
1457 auto prevAlpha = curAlpha_;
1458 auto curCornerRadius = curCornerRadius_;
1459 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1460 const auto& property = node.GetRenderProperties();
1461 auto preIsOffscreen = isOffscreen_;
1462 isOffscreen_ = isOffscreen_ || (property.IsColorBlendApplyTypeOffscreen() && !property.IsColorBlendModeNone());
1463 auto preGlobalShouldPaint = globalShouldPaint_;
1464 globalShouldPaint_ &= node.ShouldPaint();
1465 CheckFilterCacheNeedForceClearOrSave(node);
1466 if (IsAccessibilityConfigChanged()) {
1467 node.SetIsAccessibilityConfigChanged(true);
1468 }
1469 if (isDrawingCacheEnabled_) {
1470 node.UpdateDrawingCacheInfoBeforeChildren(isScreenRotationAnimating_);
1471 }
1472 node.SetIsAccessibilityConfigChanged(false);
1473 node.OpincQuickMarkStableNode(unchangeMarkInApp_, unchangeMarkEnable_,
1474 IsAccessibilityConfigChanged());
1475 RectI prepareClipRect = prepareClipRect_;
1476 bool hasAccumulatedClip = hasAccumulatedClip_;
1477
1478 if (!dirtyManager) {
1479 return;
1480 }
1481 dirtyFlag_ =
1482 node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1483 // update prepare clip before children
1484 UpdatePrepareClip(node);
1485 node.UpdateCurCornerRadius(curCornerRadius_);
1486 // The meaning of first prepared offscreen node is either its colorBlendApplyType is not FAST or
1487 // its colorBlendMode is None
1488 // Node will classified as blnedWithBackground if it is the first prepared offscreen node and
1489 // its colorBlendMode is neither NONE nor SRC_OVER
1490 node.SetBlendWithBackground(!preIsOffscreen && isOffscreen_ && property.IsColorBlendModeValid());
1491 // 1. Recursively traverse child nodes if above curSurfaceNode and subnode need draw
1492 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1493 bool isSubTreeNeedPrepare = !curSurfaceNode_ || node.IsSubTreeNeedPrepare(filterInGlobal_) ||
1494 ForcePrepareSubTree() || node.OpincForcePrepareSubTree(autoCacheEnable_);
1495 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1496 node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1497
1498 PostPrepare(node, !isSubTreeNeedPrepare);
1499 prepareClipRect_ = prepareClipRect;
1500 hasAccumulatedClip_ = hasAccumulatedClip;
1501 dirtyFlag_ = dirtyFlag;
1502 curAlpha_ = prevAlpha;
1503 isOffscreen_ = preIsOffscreen;
1504 curCornerRadius_ = curCornerRadius;
1505 node.OpincUpdateRootFlag(unchangeMarkEnable_);
1506 globalShouldPaint_ = preGlobalShouldPaint;
1507
1508 // [Attention] Only used in PC window resize scene now
1509 NodeId linedRootNodeId = node.GetLinkedRootNodeId();
1510 if (UNLIKELY(linedRootNodeId != INVALID_NODEID)) {
1511 windowKeyFrameNodeInf_.UpdateLinkedNodeId(node.GetId(), linedRootNodeId);
1512 }
1513
1514 node.RenderTraceDebug();
1515 }
1516
UpdateRotationStatusForEffectNode(RSEffectRenderNode & node)1517 void RSUniRenderVisitor::UpdateRotationStatusForEffectNode(RSEffectRenderNode& node)
1518 {
1519 // folding/expanding screen force invalidate cache.
1520 node.SetFoldStatusChanged(doAnimate_ &&
1521 curDisplayNode_->GetScreenId() != node.GetCurrentAttachedScreenId());
1522 node.SetCurrentAttachedScreenId(curDisplayNode_->GetScreenId());
1523 node.SetRotationChanged(curDisplayNode_->IsRotationChanged());
1524 }
1525
UpdatePrepareClip(RSRenderNode & node)1526 void RSUniRenderVisitor::UpdatePrepareClip(RSRenderNode& node)
1527 {
1528 const auto& property = node.GetRenderProperties();
1529 auto& geoPtr = property.GetBoundsGeometry();
1530 if (geoPtr == nullptr) {
1531 return;
1532 }
1533 // Dirty Region use abstract coordinate, property of node use relative coordinate
1534 // BoundsRect(if exists) is mapped to absRect_ of RSObjAbsGeometry.
1535 if (property.GetClipToBounds()) {
1536 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->GetAbsRect());
1537 }
1538 // FrameRect(if exists) is mapped to rect using abstract coordinate explicitly by calling MapAbsRect.
1539 if (property.GetClipToFrame()) {
1540 // MapAbsRect do not handle the translation of OffsetX and OffsetY
1541 RectF frameRect{
1542 property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_X),
1543 property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_Y),
1544 property.GetFrameWidth(), property.GetFrameHeight()};
1545 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(frameRect));
1546 }
1547 if (property.GetClipToRRect()) {
1548 RectF rect = property.GetClipRRect().rect_;
1549 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(rect));
1550 }
1551 }
1552
IsLeashAndHasMainSubNode(RSRenderNode & node) const1553 bool RSUniRenderVisitor::IsLeashAndHasMainSubNode(RSRenderNode& node) const
1554 {
1555 if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
1556 return false;
1557 }
1558 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1559 if (!surfaceNode.IsLeashWindow()) {
1560 return false;
1561 }
1562 // check leashWindow surface has first level mainwindow node
1563 auto children = node.GetSortedChildren();
1564 auto iter = std::find_if((*children).begin(), (*children).end(),
1565 [](const std::shared_ptr<RSRenderNode>& node) {
1566 if (node && node->GetType() == RSRenderNodeType::SURFACE_NODE) {
1567 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*node);
1568 return surfaceNode.IsMainWindowType();
1569 }
1570 return false;
1571 });
1572 return iter != (*children).end();
1573 }
1574
NeedPrepareChindrenInReverseOrder(RSRenderNode & node) const1575 bool RSUniRenderVisitor::NeedPrepareChindrenInReverseOrder(RSRenderNode& node) const
1576 {
1577 if (!curSurfaceNode_ && node.GetType() != RSRenderNodeType::RS_NODE) {
1578 return true;
1579 }
1580 return IsLeashAndHasMainSubNode(node);
1581 }
1582
QuickPrepareChildren(RSRenderNode & node)1583 void RSUniRenderVisitor::QuickPrepareChildren(RSRenderNode& node)
1584 {
1585 MergeRemovedChildDirtyRegion(node, true);
1586 if (node.LastFrameSubTreeSkipped() && curSurfaceDirtyManager_) {
1587 node.ForceMergeSubTreeDirtyRegion(*curSurfaceDirtyManager_, prepareClipRect_);
1588 }
1589 bool animationBackup = ancestorNodeHasAnimation_;
1590 ancestorNodeHasAnimation_ = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
1591 node.ResetChildRelevantFlags();
1592 node.ResetChildUifirstSupportFlag();
1593 auto children = node.GetSortedChildren();
1594 if (NeedPrepareChindrenInReverseOrder(node)) {
1595 auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
1596 curFrameInfoDetail.curFrameReverseChildren = true;
1597 RS_LOGD("RSUniRenderVisitor::%{public}s NeedPrepareChindrenInReverseOrder nodeId: %{public}" PRIu64,
1598 __func__, node.GetId());
1599 std::for_each(
1600 (*children).rbegin(), (*children).rend(), [this, &node](const std::shared_ptr<RSRenderNode>& child) {
1601 if (!child) {
1602 return;
1603 }
1604 auto containerDirty = curContainerDirty_;
1605 curDirty_ = child->IsDirty();
1606 curContainerDirty_ = curContainerDirty_ || child->IsDirty();
1607 child->SetFirstLevelCrossNode(node.IsFirstLevelCrossNode() || child->IsCrossNode());
1608 child->zOrderForCalcHwcNodeEnableByFilter_ = curZorderForCalcHwcNodeEnableByFilter_++;
1609 child->QuickPrepare(shared_from_this());
1610 curContainerDirty_ = containerDirty;
1611 });
1612 } else {
1613 auto& curFrameInfoDetail = node.GetCurFrameInfoDetail();
1614 curFrameInfoDetail.curFrameReverseChildren = false;
1615 std::for_each(
1616 (*children).begin(), (*children).end(), [this, &node](const std::shared_ptr<RSRenderNode>& child) {
1617 if (!child) {
1618 return;
1619 }
1620 curDirty_ = child->IsDirty();
1621 child->SetFirstLevelCrossNode(node.IsFirstLevelCrossNode() || child->IsCrossNode());
1622 child->zOrderForCalcHwcNodeEnableByFilter_ = curZorderForCalcHwcNodeEnableByFilter_++;
1623 child->QuickPrepare(shared_from_this());
1624 });
1625 }
1626 ancestorNodeHasAnimation_ = animationBackup;
1627 node.ResetGeoUpdateDelay();
1628 }
1629
InitDisplayInfo(RSDisplayRenderNode & node)1630 bool RSUniRenderVisitor::InitDisplayInfo(RSDisplayRenderNode& node)
1631 {
1632 // 1 init curDisplay and curDisplayDirtyManager
1633 currentVisitDisplay_ = node.GetScreenId();
1634 displaySpecailSurfaceChanged_.emplace(currentVisitDisplay_, false);
1635 hasCaptureWindow_.emplace(currentVisitDisplay_, false);
1636 hasFingerprint_.emplace(currentVisitDisplay_, false);
1637 curDisplayDirtyManager_ = node.GetDirtyManager();
1638 curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
1639 if (!curDisplayDirtyManager_ || !curDisplayNode_) {
1640 RS_LOGE("RSUniRenderVisitor::InitDisplayInfo dirtyMgr or node ptr is nullptr");
1641 return false;
1642 }
1643 curDisplayDirtyManager_->SetAdvancedDirtyRegionType(advancedDirtyType_);
1644 curDisplayNode_->GetMultableSpecialLayerMgr().Set(HAS_GENERAL_SPECIAL, false);
1645 curDisplayDirtyManager_->Clear();
1646 transparentCleanFilter_.clear();
1647 transparentDirtyFilter_.clear();
1648 transparentHwcCleanFilter_.clear();
1649 transparentHwcDirtyFilter_.clear();
1650 occlusionSurfaceOrder_ = TOP_OCCLUSION_SURFACES_NUM;
1651 node.SetHasChildCrossNode(false);
1652 node.SetIsFirstVisitCrossNodeDisplay(false);
1653 node.SetHasUniRenderHdrSurface(false);
1654 node.SetIsLuminanceStatusChange(false);
1655 CheckLuminanceStatusChange(curDisplayNode_->GetScreenId());
1656 // 2 init screenManager info
1657 screenManager_ = CreateOrGetScreenManager();
1658 if (!screenManager_) {
1659 RS_LOGE("RSUniRenderVisitor::InitDisplayInfo screenManager_ is nullptr");
1660 return false;
1661 }
1662 screenInfo_ = screenManager_->QueryScreenInfo(node.GetScreenId());
1663 screenRect_ = screenInfo_.activeRect.IsEmpty() ? RectI{0, 0, screenInfo_.width, screenInfo_.height} :
1664 screenInfo_.activeRect;
1665 curDisplayDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1666 curDisplayDirtyManager_->SetActiveSurfaceRect(screenInfo_.activeRect);
1667 screenManager_->SetScreenHasProtectedLayer(currentVisitDisplay_, false);
1668 allBlackList_ = screenManager_->GetAllBlackList();
1669 allWhiteList_ = screenManager_->GetAllWhiteList();
1670
1671 // 3 init Occlusion info
1672 needRecalculateOcclusion_ = false;
1673 accumulatedOcclusionRegion_.Reset();
1674 occlusionRegionWithoutSkipLayer_.Reset();
1675 if (!curMainAndLeashWindowNodesIds_.empty()) {
1676 std::queue<NodeId>().swap(curMainAndLeashWindowNodesIds_);
1677 }
1678
1679 // 4. check isHardwareForcedDisabled
1680 auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
1681 if (geoPtr == nullptr) {
1682 RS_LOGE("RSUniRenderVisitor::InitDisplayInfo geoPtr is nullptr");
1683 return false;
1684 }
1685 if (geoPtr->IsNeedClientCompose()) {
1686 isHardwareForcedDisabled_ = true;
1687 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: id:%" PRIu64 " disabled by displayNode rotation", node.GetId());
1688 }
1689
1690 // 5. check compositeType
1691 auto mirrorNode = node.GetMirrorSource().lock();
1692 node.SetIsMirrorScreen(mirrorNode != nullptr);
1693 switch (screenInfo_.state) {
1694 case ScreenState::SOFTWARE_OUTPUT_ENABLE:
1695 node.SetCompositeType(mirrorNode ?
1696 RSDisplayRenderNode::CompositeType::UNI_RENDER_MIRROR_COMPOSITE :
1697 RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE);
1698 break;
1699 case ScreenState::HDI_OUTPUT_ENABLE:
1700 node.SetCompositeType(node.IsForceSoftComposite() ?
1701 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE :
1702 RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE);
1703 break;
1704 default:
1705 return false;
1706 }
1707
1708 // init hdr and color gamut info
1709 node.ResetDisplayHdrStatus();
1710 node.SetPixelFormat(GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_8888);
1711 node.SetColorSpace(GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB);
1712
1713 // [Attention] Only used in PC window resize scene now
1714 windowKeyFrameNodeInf_.ClearLinkedNodeInfo();
1715
1716 return true;
1717 }
1718
BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1719 bool RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1720 {
1721 // 1. init and record surface info
1722 if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
1723 hasCaptureWindow_[currentVisitDisplay_] = true;
1724 }
1725 node.UpdateUIFirstFrameGravity();
1726 if (node.IsMainWindowType() || node.IsLeashWindow()) {
1727 node.SetStencilVal(Drawing::Canvas::INVALID_STENCIL_VAL);
1728 // UpdateCurCornerRadius must process before curSurfaceNode_ update
1729 node.UpdateCurCornerRadius(curCornerRadius_);
1730 curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1731 // dirty manager should not be overrode by cross node in expand screen
1732 curSurfaceDirtyManager_ = (!curDisplayNode_->IsFirstVisitCrossNodeDisplay() && node.IsFirstLevelCrossNode()) ?
1733 std::make_shared<RSDirtyRegionManager>() : node.GetDirtyManager();
1734 if (!curSurfaceDirtyManager_ || !curSurfaceNode_) {
1735 RS_LOGE("RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc %{public}s has invalid"
1736 " SurfaceDirtyManager or node ptr", node.GetName().c_str());
1737 return false;
1738 }
1739 curSurfaceDirtyManager_->Clear();
1740 curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1741 curSurfaceDirtyManager_->SetActiveSurfaceRect(screenInfo_.activeRect);
1742 filterInGlobal_ = curSurfaceNode_->IsTransparent();
1743 // update surfaceNode contentDirty and subTreeDirty flag for UIFirst purging policy
1744 RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1745 curSurfaceNode_->UpdateSurfaceCacheContentStaticFlag(IsAccessibilityConfigChanged());
1746 curSurfaceNode_->UpdateSurfaceSubTreeDirtyFlag();
1747 curSurfaceNode_->SetLeashWindowVisibleRegionEmpty(false);
1748 } else if (node.IsAbilityComponent()) {
1749 if (auto nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>()) {
1750 RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(nodePtr);
1751 nodePtr->UpdateSurfaceCacheContentStaticFlag(IsAccessibilityConfigChanged());
1752 }
1753 }
1754 // 2. update surface info and CheckIfOcclusionReusable
1755 node.SetAncestorDisplayNode(curDisplayNode_); // set for boot animation
1756 node.UpdateAncestorDisplayNodeInRenderParams();
1757 node.CleanDstRectChanged();
1758 // [planning] check node isDirty can be optimized.
1759 needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.IsDirty() ||
1760 node.CheckIfOcclusionReusable(preMainAndLeashWindowNodesIds_);
1761 if (autoCacheEnable_ && node.IsAppWindow()) {
1762 node.OpincSetInAppStateStart(unchangeMarkInApp_);
1763 }
1764 // 3. check pixelFormat and update RelMatrix
1765 CheckPixelFormat(node);
1766 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
1767 node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
1768 }
1769 #ifdef RS_ENABLE_GPU
1770 // 4. collect cursors and check for null
1771 if (node.IsHardwareEnabledTopSurface() && (node.ShouldPaint() || node.GetHardCursorStatus())) {
1772 auto surfaceNodeDrawable =
1773 std::static_pointer_cast<DrawableV2::RSSurfaceRenderNodeDrawable>(node.GetRenderDrawable());
1774 if (surfaceNodeDrawable) {
1775 RSPointerWindowManager::Instance().CollectAllHardCursor(curDisplayNode_->GetId(), node.GetRenderDrawable());
1776 }
1777 }
1778 #endif
1779 node.setQosCal((RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) &&
1780 RSSystemParameters::GetVSyncControlEnabled());
1781 return true;
1782 }
1783
AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1784 bool RSUniRenderVisitor::AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1785 {
1786 // 1. Update surfaceNode info and AppWindow gravity
1787 const auto& property = node.GetRenderProperties();
1788 if (node.IsAppWindow()) {
1789 boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
1790 frameGravity_ = property.GetFrameGravity();
1791 }
1792 auto& geoPtr = property.GetBoundsGeometry();
1793 if (geoPtr == nullptr) {
1794 return false;
1795 }
1796 UpdateDstRect(node, geoPtr->GetAbsRect(), prepareClipRect_);
1797 node.UpdatePositionZ();
1798 if (node.IsHardwareEnabledType() && node.GetZorderChanged() && curSurfaceNode_) {
1799 curSurfaceNode_->SetNeedCollectHwcNode(true);
1800 }
1801 UpdateSurfaceRenderNodeScale(node);
1802 UpdateSurfaceRenderNodeRotate(node);
1803 if (node.IsMainWindowType() || node.IsLeashWindow()) {
1804 curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirtyInSurface());
1805 curDisplayNode_->AddSurfaceNodePosByDescZOrder(node.GetId(), node.GetOldDirtyInSurface());
1806 }
1807 // 2. Update Occlusion info before children preparation
1808 if (node.IsMainWindowType()) {
1809 UpdateNodeVisibleRegion(node);
1810 }
1811 // 3. Update HwcNode Info for appNode
1812 UpdateHwcNodeInfoForAppNode(node);
1813 if (node.IsHardwareEnabledTopSurface()) {
1814 UpdateSrcRect(node, geoPtr->GetAbsMatrix(), geoPtr->GetAbsRect());
1815 }
1816 // 4. Update color gamut for appNode
1817 auto colorGamutFeature = GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[COLOR_GAMUT]);
1818 auto colorGamutParam = std::static_pointer_cast<ColorGamutParam>(colorGamutFeature);
1819 if ((colorGamutParam != nullptr && !colorGamutParam->IsCoveredSurfaceCloseP3()) ||
1820 !node.GetVisibleRegion().IsEmpty() || !GetIsOpDropped()) {
1821 CheckColorSpace(node);
1822 }
1823 return true;
1824 }
1825
UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode & node)1826 void RSUniRenderVisitor::UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode& node)
1827 {
1828 if (!node.IsLeashWindow() || !RSSystemParameters::GetUIFirstOcclusionEnabled()) {
1829 return;
1830 }
1831
1832 auto dirtyManager = node.GetDirtyManager();
1833 if (dirtyManager && dirtyManager->IsCurrentFrameDirty()) {
1834 RS_LOGD("RSUniRenderVisitor::UpdateLeashWindowVisibleRegionEmpty[false] : %{public}s is current frame dirty.",
1835 node.GetName().c_str());
1836 node.SetLeashWindowVisibleRegionEmpty(false);
1837 return;
1838 }
1839
1840 auto sortedChildren = node.GetSortedChildren();
1841 if (sortedChildren == nullptr || sortedChildren->empty()) {
1842 RS_TRACE_NAME_FMT("%s don't have children", node.GetName().c_str());
1843 node.SetLeashWindowVisibleRegionEmpty(true);
1844 return;
1845 }
1846
1847 // leash window's visible region is empty when all child are app windows with empty visible region
1848 for (const auto& child : *sortedChildren) {
1849 const auto childSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1850 if (!childSurfaceNode || !childSurfaceNode->IsAppWindow() ||
1851 !childSurfaceNode->GetVisibleRegion().IsEmpty()) {
1852 node.SetLeashWindowVisibleRegionEmpty(false);
1853 return;
1854 }
1855 }
1856 RS_TRACE_NAME_FMT("visible region of %s's children is empty", node.GetName().c_str());
1857 node.SetLeashWindowVisibleRegionEmpty(true);
1858 }
1859
UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode & node)1860 void RSUniRenderVisitor::UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode& node)
1861 {
1862 // app node
1863 if (node.GetNeedCollectHwcNode()) {
1864 node.ResetChildHardwareEnabledNodes();
1865 node.SetExistTransparentHardwareEnabledNode(false);
1866 }
1867 // hwc node
1868 if (node.IsHardwareEnabledType() && curSurfaceNode_) {
1869 if (curSurfaceNode_->GetNeedCollectHwcNode()) {
1870 curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
1871 }
1872 if (!node.GetHardWareDisabledByReverse()) {
1873 node.SetHardwareForcedDisabledState(node.GetIsHwcPendingDisabled());
1874 if (node.GetIsHwcPendingDisabled()) {
1875 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by IsHwcPendingDisabled",
1876 node.GetName().c_str(), node.GetId());
1877 }
1878 node.SetIsHwcPendingDisabled(false);
1879 }
1880 node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1881 if (!IsHardwareComposerEnabled() || !node.IsDynamicHardwareEnable() ||
1882 curSurfaceNode_->GetVisibleRegion().IsEmpty() ||
1883 !node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1884 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by param/invisible/no buffer, "
1885 "IsHardwareComposerEnabled[%d], IsDynamicHardwareEnable[%d], IsVisibleRegionEmpty[%d], IsNoBuffer[%d]",
1886 node.GetName().c_str(), node.GetId(), IsHardwareComposerEnabled(), node.IsDynamicHardwareEnable(),
1887 curSurfaceNode_->GetVisibleRegion().IsEmpty(),
1888 node.GetRSSurfaceHandler() || node.GetRSSurfaceHandler()->GetBuffer());
1889 #ifdef HIPERF_TRACE_ENABLE
1890 RS_LOGW("hiperf_surface: name:%s disabled by param/invisible/no buffer, "
1891 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", node.GetName().c_str(),
1892 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
1893 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom(),
1894 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
1895 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom());
1896 #endif
1897 node.SetHardwareForcedDisabledState(true);
1898 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
1899 HwcDisabledReasons::DISABLED_BY_INVALID_PARAM, node.GetName());
1900 if (!node.GetFixRotationByUser()) {
1901 return;
1902 }
1903 }
1904 auto& geo = node.GetRenderProperties().GetBoundsGeometry();
1905 if (geo == nullptr) {
1906 return;
1907 }
1908 UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
1909 UpdateHwcNodeByTransform(node, geo->GetAbsMatrix());
1910 UpdateHwcNodeEnableByBackgroundAlpha(node);
1911 UpdateHwcNodeEnableByBufferSize(node);
1912 UpdateHwcNodeEnableBySrcRect(node);
1913 }
1914 }
1915
UpdateSrcRect(RSSurfaceRenderNode & node,const Drawing::Matrix & absMatrix,const RectI & absRect)1916 void RSUniRenderVisitor::UpdateSrcRect(RSSurfaceRenderNode& node,
1917 const Drawing::Matrix& absMatrix, const RectI& absRect)
1918 {
1919 auto canvas = std::make_unique<Rosen::Drawing::Canvas>(screenInfo_.phyWidth, screenInfo_.phyHeight);
1920 canvas->ConcatMatrix(absMatrix);
1921
1922 const auto& dstRect = node.GetDstRect();
1923 Drawing::RectI dst = { std::round(dstRect.GetLeft()), std::round(dstRect.GetTop()), std::round(dstRect.GetRight()),
1924 std::round(dstRect.GetBottom()) };
1925 node.UpdateSrcRect(*canvas.get(), dst);
1926 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
1927 RSUniRenderUtil::UpdateRealSrcRect(node, absRect);
1928 }
1929 }
1930
UpdateDstRect(RSSurfaceRenderNode & node,const RectI & absRect,const RectI & clipRect)1931 void RSUniRenderVisitor::UpdateDstRect(RSSurfaceRenderNode& node, const RectI& absRect, const RectI& clipRect)
1932 {
1933 auto dstRect = absRect;
1934 if (!node.IsHardwareEnabledTopSurface()) {
1935 // If the screen is expanded, intersect the destination rectangle with the screen rectangle
1936 dstRect = dstRect.IntersectRect(RectI(0, 0, screenInfo_.width, screenInfo_.height));
1937 // global positon has been transformd to screen position in absRect
1938 }
1939 // If the node is a hardware-enabled type, intersect its destination rectangle with the prepare clip rectangle
1940 if (node.IsHardwareEnabledType() || node.IsHardwareEnabledTopSurface()) {
1941 dstRect = dstRect.IntersectRect(clipRect);
1942 if (curSurfaceNode_ && (node.GetId() != curSurfaceNode_->GetId())) {
1943 dstRect = dstRect.IntersectRect(curSurfaceNode_->GetDstRect());
1944 }
1945 }
1946 dstRect.left_ = static_cast<int>(std::round(dstRect.left_ * screenInfo_.GetRogWidthRatio()));
1947 dstRect.top_ = static_cast<int>(std::round(dstRect.top_ * screenInfo_.GetRogHeightRatio()));
1948 dstRect.width_ = static_cast<int>(std::round(dstRect.width_ * screenInfo_.GetRogWidthRatio()));
1949 dstRect.height_ = static_cast<int>(std::round(dstRect.height_ * screenInfo_.GetRogHeightRatio()));
1950 // Set the destination rectangle of the node
1951 node.SetDstRect(dstRect);
1952 node.SetDstRectWithoutRenderFit(dstRect);
1953 }
1954
UpdateHwcNodeByTransform(RSSurfaceRenderNode & node,const Drawing::Matrix & totalMatrix)1955 void RSUniRenderVisitor::UpdateHwcNodeByTransform(RSSurfaceRenderNode& node, const Drawing::Matrix& totalMatrix)
1956 {
1957 if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1958 return;
1959 }
1960 node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1961 const uint32_t apiCompatibleVersion = node.GetApiCompatibleVersion();
1962 (apiCompatibleVersion != INVALID_API_COMPATIBLE_VERSION && apiCompatibleVersion < API18) ?
1963 RSUniRenderUtil::DealWithNodeGravityOldVersion(node, screenInfo_) :
1964 RSUniRenderUtil::DealWithNodeGravity(node, totalMatrix);
1965 RSUniRenderUtil::DealWithScalingMode(node, totalMatrix);
1966 RSUniRenderUtil::LayerRotate(node, screenInfo_);
1967 RSUniRenderUtil::LayerCrop(node, screenInfo_);
1968 RSUniRenderUtil::CalcSrcRectByBufferFlip(node, screenInfo_);
1969 node.SetCalcRectInPrepare(true);
1970 }
1971
UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode & node)1972 void RSUniRenderVisitor::UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode& node)
1973 {
1974 if (node.GetAncoForceDoDirect()) {
1975 return;
1976 }
1977 bool bgTransport =
1978 static_cast<uint8_t>(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX;
1979 auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
1980 bool isSolidColorEnbaled = stagingSurfaceParams->GetSelfDrawingNodeType() == SelfDrawingNodeType::XCOM &&
1981 node.GetRenderProperties().GetBackgroundColor() != RgbPalette::Black();
1982 if (bgTransport) {
1983 // use in skip updating hardware state for hwcnode with background alpha in specific situation
1984 if (!RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag() &&
1985 !node.IsHardwareEnableHint()) {
1986 #ifdef HIPERF_TRACE_ENABLE
1987 RS_LOGW("hiperf_surface: name:%s disabled by background color alpha < 1, "
1988 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", node.GetName().c_str(),
1989 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
1990 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom(),
1991 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
1992 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom());
1993 #endif
1994 node.SetHardwareForcedDisabledState(true);
1995 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by background color alpha < 1",
1996 node.GetName().c_str(), node.GetId());
1997 }
1998 curSurfaceNode_->SetExistTransparentHardwareEnabledNode(true);
1999 node.SetNodeHasBackgroundColorAlpha(true);
2000 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2001 HwcDisabledReasons::DISABLED_BY_BACKGROUND_ALPHA, node.GetName());
2002 } else if (RsCommonHook::Instance().GetIsWhiteListForSolidColorLayerFlag() && isSolidColorEnbaled) {
2003 if (!RSSystemParameters::GetSolidLayerHwcEnabled()) {
2004 node.SetHardwareForcedDisabledState(true);
2005 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by solidLayer switch",
2006 node.GetName().c_str(), node.GetId());
2007 return;
2008 }
2009 stagingSurfaceParams->SetIsHwcEnabledBySolidLayer(true);
2010 } else if (!RsCommonHook::Instance().GetIsWhiteListForSolidColorLayerFlag() && isSolidColorEnbaled) {
2011 node.SetHardwareForcedDisabledState(true);
2012 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by solid background color",
2013 node.GetName().c_str(), node.GetId());
2014 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2015 HwcDisabledReasons::DISABLED_BY_SOLID_BACKGROUND_ALPHA, node.GetName());
2016 }
2017 }
2018
UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode & node)2019 void RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode& node)
2020 {
2021 if (!node.IsRosenWeb() || node.IsHardwareForcedDisabled()) {
2022 return;
2023 }
2024 if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
2025 return;
2026 }
2027 const auto& property = node.GetRenderProperties();
2028 auto gravity = property.GetFrameGravity();
2029 if (gravity != Gravity::TOP_LEFT) {
2030 return;
2031 }
2032 auto surfaceHandler = node.GetRSSurfaceHandler();
2033 auto consumer = surfaceHandler->GetConsumer();
2034 if (consumer == nullptr) {
2035 return;
2036 }
2037
2038 auto buffer = surfaceHandler->GetBuffer();
2039 const auto bufferWidth = buffer->GetSurfaceBufferWidth();
2040 const auto bufferHeight = buffer->GetSurfaceBufferHeight();
2041 auto boundsWidth = property.GetBoundsWidth();
2042 auto boundsHeight = property.GetBoundsHeight();
2043
2044 auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
2045 if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
2046 RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize GetSurfaceBufferTransformType failed");
2047 }
2048 if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
2049 transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
2050 std::swap(boundsWidth, boundsHeight);
2051 }
2052 if ((bufferWidth < boundsWidth) || (bufferHeight < boundsHeight)) {
2053 RS_OPTIONAL_TRACE_NAME_FMT(
2054 "hwc debug: name:%s id:%" PRIu64 " buffer:[%d, %d] bounds:[%f, %f] disabled by buffer nonmatching",
2055 node.GetName().c_str(), node.GetId(), bufferWidth, bufferHeight, boundsWidth, boundsHeight);
2056 #ifdef HIPERF_TRACE_ENABLE
2057 RS_LOGW("hiperf_surface: name:%s buffer:[%d, %d] bounds:[%f, %f] disabled by buffer nonmatching, "
2058 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
2059 node.GetName().c_str(), bufferWidth, bufferHeight, boundsWidth, boundsHeight,
2060 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
2061 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom(),
2062 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
2063 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom());
2064 #endif
2065 node.SetHardwareForcedDisabledState(true);
2066 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(
2067 node.GetId(), HwcDisabledReasons::DISABLED_BY_BUFFER_NONMATCH, node.GetName());
2068 }
2069 }
2070
UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode & node)2071 void RSUniRenderVisitor::UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode& node)
2072 {
2073 if (node.IsHardwareForcedDisabled()) {
2074 return;
2075 }
2076 bool hasRotation = false;
2077 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetConsumer()) {
2078 const auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
2079 auto rotation = RSBaseRenderUtil::GetRotateTransform(
2080 RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, node.GetRSSurfaceHandler()->GetBuffer()));
2081 hasRotation = rotation == GRAPHIC_ROTATE_90 || rotation == GRAPHIC_ROTATE_270;
2082 }
2083 node.UpdateHwcDisabledBySrcRect(hasRotation);
2084 if (node.IsHardwareDisabledBySrcRect()) {
2085 #ifdef HIPERF_TRACE_ENABLE
2086 RS_LOGW("hiperf_surface: name:%s disabled by src Rect, surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
2087 node.GetName().c_str(),
2088 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
2089 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom(),
2090 node.GetSrcRect().GetLeft(), node.GetSrcRect().GetRight(),
2091 node.GetSrcRect().GetTop(), node.GetSrcRect().GetBottom());
2092 #endif
2093 node.SetHardwareForcedDisabledState(true);
2094 RS_OPTIONAL_TRACE_NAME_FMT(
2095 "hwc debug: name:%s id:%" PRIu64 " disabled by isYUVBufferFormat and localClip not match bounds",
2096 node.GetName().c_str(), node.GetId());
2097 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2098 HwcDisabledReasons::DISABLED_BY_SRC_PIXEL, node.GetName());
2099 }
2100 }
2101
UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2102 void RSUniRenderVisitor::UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2103 {
2104 auto alpha = hwcNode->GetGlobalAlpha();
2105 auto totalMatrix = hwcNode->GetTotalMatrix();
2106 if (alpha < 1.0f) {
2107 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by accumulated alpha:%f",
2108 hwcNode->GetName().c_str(), hwcNode->GetId(), alpha);
2109 #ifdef HIPERF_TRACE_ENABLE
2110 RS_LOGW("hiperf_surface: name:%s disabled by accumulated alpha:%.2f, "
2111 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", hwcNode->GetName().c_str(), alpha,
2112 hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2113 hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom(),
2114 hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2115 hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom());
2116 #endif
2117 hwcNode->SetHardwareForcedDisabledState(true);
2118 if (!ROSEN_EQ(alpha, 0.f)) {
2119 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2120 HwcDisabledReasons::DISABLED_BY_ACCUMULATED_ALPHA, hwcNode->GetName());
2121 }
2122 return;
2123 }
2124 // [planning] degree only multiples of 90 now
2125 float degree = RSUniRenderUtil::GetFloatRotationDegreeFromMatrix(totalMatrix);
2126 bool hasRotate = !ROSEN_EQ(std::remainder(degree, 90.f), 0.f, EPSILON);
2127 hasRotate = hasRotate || RSUniRenderUtil::HasNonZRotationTransform(totalMatrix);
2128 if (hasRotate) {
2129 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by rotation:%f",
2130 hwcNode->GetName().c_str(), hwcNode->GetId(), degree);
2131 #ifdef HIPERF_TRACE_ENABLE
2132 RS_LOGW("hiperf_surface: name:%s disabled by rotation:%d, surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
2133 hwcNode->GetName().c_str(), degree,
2134 hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2135 hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom(),
2136 hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2137 hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom());
2138 #endif
2139 hwcNode->SetHardwareForcedDisabledState(true);
2140 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2141 HwcDisabledReasons::DISABLED_BY_ROTATION, hwcNode->GetName());
2142 return;
2143 }
2144 }
2145
ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode> & hwcNodePtr,bool & ancoHasGpu)2146 void RSUniRenderVisitor::ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr, bool& ancoHasGpu)
2147 {
2148 if (hwcNodePtr == nullptr) {
2149 return;
2150 }
2151 auto alpha = hwcNodePtr->GetGlobalAlpha();
2152 RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 "src %{public}s dst %{public}s "
2153 "alpha:%{public}.2f", hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(),
2154 hwcNodePtr->GetSrcRect().ToString().c_str(), hwcNodePtr->GetDstRect().ToString().c_str(), alpha);
2155 if (ROSEN_EQ(alpha, 0.0f)) {
2156 return;
2157 }
2158
2159 if (!hwcNodePtr->GetRSSurfaceHandler() || !hwcNodePtr->GetRSSurfaceHandler()->GetBuffer()) {
2160 RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 " handler or buffer is null, skip",
2161 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2162 return;
2163 }
2164 if (hwcNodePtr->IsHardwareForcedDisabled()) {
2165 RS_OPTIONAL_TRACE_NAME_FMT("ProcessAncoNode: name:%s id:%" PRIu64 " hardware force disabled",
2166 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2167 }
2168 ancoHasGpu = (ancoHasGpu || hwcNodePtr->IsHardwareForcedDisabled());
2169 }
2170
UpdateHwcNodeEnable()2171 void RSUniRenderVisitor::UpdateHwcNodeEnable()
2172 {
2173 std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>> ancoNodes;
2174 #ifdef HIPERF_TRACE_ENABLE
2175 int inputHwclayers = 3;
2176 #endif
2177 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2178 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2179 #ifdef HIPERF_TRACE_ENABLE
2180 [this, &inputHwclayers, &ancoNodes](RSBaseRenderNode::SharedPtr& nodePtr) {
2181 #else
2182 [this, &ancoNodes](RSBaseRenderNode::SharedPtr& nodePtr) {
2183 #endif
2184 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2185 if (!surfaceNode) {
2186 return;
2187 }
2188
2189 if (RSSystemProperties::GetHveFilterEnabled()) {
2190 const auto &preHwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2191 for (const auto& preHwcNode : preHwcNodes) {
2192 auto hwcNodePtr = preHwcNode.lock();
2193 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2194 continue;
2195 }
2196 hwcNodePtr->ResetMakeImageState();
2197 }
2198 }
2199
2200 UpdateHwcNodeEnableByGlobalFilter(surfaceNode);
2201 surfaceNode->ResetNeedCollectHwcNode();
2202 const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2203 if (hwcNodes.empty()) {
2204 return;
2205 }
2206 #ifdef HIPERF_TRACE_ENABLE
2207 inputHwclayers += hwcNodes.size();
2208 #endif
2209 std::vector<RectI> hwcRects;
2210 for (const auto& hwcNode : hwcNodes) {
2211 auto hwcNodePtr = hwcNode.lock();
2212 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2213 continue;
2214 }
2215 if (hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2216 drmNodes_.emplace_back(hwcNode);
2217 auto firstLevelNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(
2218 hwcNodePtr->GetFirstLevelNode());
2219 hwcNodePtr->SetForceDisableClipHoleForDRM(firstLevelNode != nullptr &&
2220 firstLevelNode->GetRenderProperties().IsAttractionValid());
2221 }
2222 RSUniRenderUtil::UpdateHwcNodeProperty(hwcNodePtr);
2223 UpdateHwcNodeEnableByRotateAndAlpha(hwcNodePtr);
2224 if ((hwcNodePtr->GetAncoFlags() & static_cast<uint32_t>(AncoFlags::IS_ANCO_NODE)) != 0) {
2225 ancoNodes.insert(hwcNodePtr);
2226 }
2227 }
2228 });
2229 #ifdef HIPERF_TRACE_ENABLE
2230 RS_LOGW("hiperf_surface_counter1 %{public}" PRIu64 " ", static_cast<uint64_t>(inputHwclayers));
2231 #endif
2232 PrevalidateHwcNode();
2233 UpdateHwcNodeEnableByNodeBelow();
2234 UpdateAncoNodeHWCDisabledState(ancoNodes);
2235 }
2236
2237 void RSUniRenderVisitor::UpdateAncoNodeHWCDisabledState(
2238 std::unordered_set<std::shared_ptr<RSSurfaceRenderNode>>& ancoNodes)
2239 {
2240 bool ancoHasGpu = false;
2241 for (auto hwcNodePtr : ancoNodes) {
2242 ProcessAncoNode(hwcNodePtr, ancoHasGpu);
2243 }
2244 if (ancoHasGpu) {
2245 for (const auto& hwcNodePtr : ancoNodes) {
2246 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by anco has gpu",
2247 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2248 hwcNodePtr->SetHardwareForcedDisabledState(true);
2249 }
2250 }
2251 }
2252
2253 void RSUniRenderVisitor::PrevalidateHwcNode()
2254 {
2255 if (!RSUniHwcPrevalidateUtil::GetInstance().IsPrevalidateEnable()) {
2256 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate close");
2257 #ifdef HIPERF_TRACE_ENABLE
2258 RS_LOGW("hiperf_surface_counter2 %{public}" PRIu64 " ", static_cast<uint64_t>(0));
2259 #endif
2260 return;
2261 }
2262 #ifdef HIPERF_TRACE_ENABLE
2263 int shouldPreValidateLayersNum = 3;
2264 #endif
2265 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2266 std::vector<RequestLayerInfo> prevalidLayers;
2267 uint32_t curFps = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(curDisplayNode_->GetScreenId());
2268 uint32_t zOrder = static_cast<uint32_t>(globalZOrder_);
2269 // add surfaceNode layer
2270 RSUniHwcPrevalidateUtil::GetInstance().CollectSurfaceNodeLayerInfo(
2271 prevalidLayers, curMainAndLeashSurfaces, curFps, zOrder, screenInfo_);
2272 RS_TRACE_NAME_FMT("PrevalidateHwcNode hwcLayer: %u", prevalidLayers.size());
2273 if (prevalidLayers.size() == 0) {
2274 RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode no hardware layer");
2275 #ifdef HIPERF_TRACE_ENABLE
2276 RS_LOGW("hiperf_surface_counter2 %{public}" PRIu64 " ", static_cast<uint64_t>(shouldPreValidateLayersNum));
2277 #endif
2278 return;
2279 }
2280 // add display layer
2281 RequestLayerInfo displayLayer;
2282 if (RSUniHwcPrevalidateUtil::GetInstance().CreateDisplayNodeLayerInfo(
2283 zOrder++, curDisplayNode_, screenInfo_, curFps, displayLayer)) {
2284 prevalidLayers.emplace_back(displayLayer);
2285 }
2286 // add rcd layer
2287 RequestLayerInfo rcdLayer;
2288 if (RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
2289 auto topNode = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curDisplayNode_->GetRcdSurfaceNodeTop());
2290 if (topNode &&
2291 RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(topNode, screenInfo_, curFps, rcdLayer)) {
2292 prevalidLayers.emplace_back(rcdLayer);
2293 }
2294 auto bottomNode = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curDisplayNode_->GetRcdSurfaceNodeBottom());
2295 if (bottomNode &&
2296 RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(bottomNode, screenInfo_, curFps, rcdLayer)) {
2297 prevalidLayers.emplace_back(rcdLayer);
2298 }
2299 }
2300 #ifdef HIPERF_TRACE_ENABLE
2301 shouldPreValidateLayersNum = prevalidLayers.size();
2302 RS_LOGW("hiperf_surface_counter2 %{public}" PRIu64 " ", static_cast<uint64_t>(shouldPreValidateLayersNum));
2303 #endif
2304 std::map<uint64_t, RequestCompositionType> strategy;
2305 if (!RSUniHwcPrevalidateUtil::GetInstance().PreValidate(screenInfo_.id, prevalidLayers, strategy)) {
2306 RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate failed");
2307 return;
2308 }
2309 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2310 for (auto it : strategy) {
2311 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode id: %{public}" PRIu64 ","
2312 " result: %{public}d", it.first, it.second);
2313 if (it.second == RequestCompositionType::DEVICE) {
2314 continue;
2315 }
2316 auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(it.first);
2317 if (node == nullptr) {
2318 continue;
2319 }
2320 if (it.second == RequestCompositionType::DEVICE_VSCF) {
2321 node->SetArsrTag(false);
2322 continue;
2323 }
2324 if (node->IsInFixedRotation() || node->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2325 continue;
2326 }
2327 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by prevalidate",
2328 node->GetName().c_str(), node->GetId());
2329 #ifdef HIPERF_TRACE_ENABLE
2330 RS_LOGW("hiperf_surface: name:%s disabled by prevalidate, surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
2331 node->GetName().c_str(),
2332 node->GetSrcRect().GetLeft(), node->GetSrcRect().GetRight(),
2333 node->GetSrcRect().GetTop(), node->GetSrcRect().GetBottom(),
2334 node->GetSrcRect().GetLeft(), node->GetSrcRect().GetRight(),
2335 node->GetSrcRect().GetTop(), node->GetSrcRect().GetBottom());
2336 #endif
2337 node->SetHardwareForcedDisabledState(true);
2338 if (node->GetRSSurfaceHandler()) {
2339 node->GetRSSurfaceHandler()->SetGlobalZOrder(-1.f);
2340 }
2341 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
2342 HwcDisabledReasons::DISABLED_BY_PREVALIDATE, node->GetName());
2343 }
2344 }
2345
2346 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode>& node)
2347 {
2348 const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
2349 if (hwcNodes.empty() || !curDisplayNode_) {
2350 return;
2351 }
2352 std::vector<std::shared_ptr<RSSurfaceRenderNode>> topLayers;
2353 for (auto hwcNode : hwcNodes) {
2354 auto hwcNodePtr = hwcNode.lock();
2355 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2356 continue;
2357 }
2358 auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
2359 if (hwcNodePtr->IsLayerTop()) {
2360 topLayers.emplace_back(hwcNodePtr);
2361 continue;
2362 }
2363 if (IsHdrUseUnirender(curDisplayNode_->GetHasUniRenderHdrSurface(), hwcNodePtr)) {
2364 hwcNodePtr->SetHardwareForcedDisabledState(true);
2365 // DRM will force HDR to use unirender
2366 curDisplayNode_->SetHasUniRenderHdrSurface(curDisplayNode_->GetHasUniRenderHdrSurface() ||
2367 RSHdrUtil::CheckIsHdrSurface(*hwcNodePtr) != HdrStatus::NO_HDR);
2368 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
2369 HwcDisabledReasons::DISABLED_BY_RENDER_HDR_SURFACE, hwcNodePtr->GetName());
2370 }
2371 UpdateHwcNodeDirtyRegionForApp(node, hwcNodePtr);
2372 hwcNodePtr->SetCalcRectInPrepare(false);
2373 hwcNodePtr->SetHardWareDisabledByReverse(false);
2374 surfaceHandler->SetGlobalZOrder(hwcNodePtr->IsHardwareForcedDisabled() &&
2375 !hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED) ? -1.f : globalZOrder_++);
2376 auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(hwcNodePtr->GetStagingRenderParams().get());
2377 if (stagingSurfaceParams->GetIsHwcEnabledBySolidLayer()) {
2378 surfaceHandler->SetGlobalZOrder(globalZOrder_++);
2379 }
2380 auto transform = RSUniRenderUtil::GetLayerTransform(*hwcNodePtr, screenInfo_);
2381 hwcNodePtr->UpdateHwcNodeLayerInfo(transform);
2382 }
2383 curDisplayNode_->SetDisplayGlobalZOrder(globalZOrder_);
2384 if (!topLayers.empty()) {
2385 UpdateTopLayersDirtyStatus(topLayers);
2386 }
2387 }
2388
2389 bool RSUniRenderVisitor::IsHdrUseUnirender(bool hasUniRenderHdrSurface,
2390 std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr)
2391 {
2392 if (hwcNodePtr->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2393 return false;
2394 }
2395 bool isHdrHardwareDisabled = RSLuminanceControl::Get().IsCloseHardwareHdr() &&
2396 (RSHdrUtil::CheckIsHdrSurface(*hwcNodePtr) != HdrStatus::NO_HDR ||
2397 RSLuminanceControl::Get().IsHdrOn(curDisplayNode_->GetScreenId()));
2398 if (hasUniRenderHdrSurface || !drmNodes_.empty() || hasFingerprint_[currentVisitDisplay_] ||
2399 isHdrHardwareDisabled) {
2400 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64
2401 " disabled by having UniRenderHdrSurface/DRM nodes, isHdrHardwareDisabled:%d",
2402 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(), isHdrHardwareDisabled);
2403 return true;
2404 }
2405 return false;
2406 }
2407
2408 void RSUniRenderVisitor::UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode>& pointWindow)
2409 {
2410 if (!pointWindow->IsHardwareEnabledTopSurface() || !pointWindow->ShouldPaint()) {
2411 pointWindow->SetHardCursorStatus(false);
2412 RSPointerWindowManager::Instance().SetIsPointerEnableHwc(false);
2413 return;
2414 }
2415 std::shared_ptr<RSSurfaceHandler> pointSurfaceHandler = pointWindow->GetMutableRSSurfaceHandler();
2416 if (pointSurfaceHandler) {
2417 // globalZOrder_ + 2 is displayNode layer, point window must be at the top.
2418 pointSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 2);
2419 if (!curDisplayNode_) {
2420 return;
2421 }
2422 bool isHardCursor = RSPointerWindowManager::Instance().CheckHardCursorSupport(curDisplayNode_->GetScreenId());
2423 pointWindow->SetHardwareForcedDisabledState(true);
2424 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by pointWindow and pointSurfaceHandler",
2425 pointWindow->GetName().c_str(), pointWindow->GetId());
2426 bool isMirrorMode = RSPointerWindowManager::Instance().HasMirrorDisplay();
2427 RSPointerWindowManager::Instance().SetIsPointerEnableHwc(isHardCursor && !isMirrorMode);
2428 auto transform = RSUniRenderUtil::GetLayerTransform(*pointWindow, screenInfo_);
2429 pointWindow->SetHardCursorStatus(isHardCursor);
2430 pointWindow->UpdateHwcNodeLayerInfo(transform, isHardCursor);
2431 if (isHardCursor) {
2432 RSPointerWindowManager::Instance().UpdatePointerDirtyToGlobalDirty(pointWindow, curDisplayNode_);
2433 }
2434 }
2435 }
2436
2437 void RSUniRenderVisitor::UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& topLayers)
2438 {
2439 for (const auto& topLayer : topLayers) {
2440 std::shared_ptr<RSSurfaceHandler> topLayerSurfaceHandler = topLayer->GetMutableRSSurfaceHandler();
2441 if (topLayerSurfaceHandler) {
2442 topLayerSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 1);
2443 topLayer->SetCalcRectInPrepare(false);
2444 bool hwcDisabled = !IsHardwareComposerEnabled() || !topLayer->ShouldPaint() ||
2445 curDisplayNode_->GetHasUniRenderHdrSurface() || !drmNodes_.empty();
2446 topLayer->SetHardwareForcedDisabledState(hwcDisabled);
2447 if (hwcDisabled) {
2448 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by toplayers dirty status, "
2449 "IsHardwareComposerEnabled[%d],TopLayerShouldPaint[%d],HasUniRenderHdrSurface[%d],DrmNodeEmpty[%d]",
2450 topLayer->GetName().c_str(), topLayer->GetId(), IsHardwareComposerEnabled(),
2451 topLayer->ShouldPaint(), curDisplayNode_->GetHasUniRenderHdrSurface(), drmNodes_.empty());
2452 }
2453 auto transform = RSUniRenderUtil::GetLayerTransform(*topLayer, screenInfo_);
2454 topLayer->UpdateHwcNodeLayerInfo(transform);
2455 }
2456 }
2457 }
2458
2459 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode>& appNode,
2460 std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2461 {
2462 // if current frame hwc enable status not equal with last frame
2463 // or current frame do gpu composition and has buffer consumed,
2464 // we need merge hwc node dst rect to dirty region.
2465 if (!hwcNode->IsHardwareForcedDisabled() != hwcNode->GetIsLastFrameHwcEnabled()) {
2466 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
2467 return;
2468 }
2469 if (!hwcNode->GetRSSurfaceHandler()) {
2470 return;
2471 }
2472 if (hwcNode->IsHardwareForcedDisabled() && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
2473 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetOldDirtyInSurface());
2474 }
2475 if (hasMirrorDisplay_ && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
2476 !appNode->GetVisibleRegion().IsEmpty()) {
2477 // merge hwc node dst rect for virtual screen dirty, in case the main display node skip
2478 curDisplayDirtyManager_->MergeHwcDirtyRect(hwcNode->GetDstRect());
2479 }
2480 }
2481
2482 void RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty()
2483 {
2484 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2485 // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
2486 Occlusion::Region accumulatedDirtyRegion;
2487 bool hasMainAndLeashSurfaceDirty = false;
2488 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2489 [this, &accumulatedDirtyRegion, &hasMainAndLeashSurfaceDirty](RSBaseRenderNode::SharedPtr& nodePtr) {
2490 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2491 if (!surfaceNode) {
2492 RS_LOGE("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surfaceNode is nullptr");
2493 return;
2494 }
2495 auto dirtyManager = surfaceNode->GetDirtyManager();
2496 RSMainThread::Instance()->GetContext().AddPendingSyncNode(nodePtr);
2497 // 0. update hwc node dirty region and create layer
2498 UpdateHwcNodeDirtyRegionAndCreateLayer(surfaceNode);
2499 // cal done node dirtyRegion for uifirst
2500 RSUifirstManager::Instance().MergeOldDirtyToDirtyManager(surfaceNode);
2501 UpdatePointWindowDirtyStatus(surfaceNode);
2502 // 1. calculate abs dirtyrect and update partialRenderParams
2503 // currently only sync visible region info
2504 surfaceNode->UpdatePartialRenderParams();
2505 if (dirtyManager && dirtyManager->IsCurrentFrameDirty() &&
2506 surfaceNode->GetVisibleRegion().IsIntersectWith(dirtyManager->GetCurrentFrameDirtyRegion())) {
2507 hasMainAndLeashSurfaceDirty = true;
2508 }
2509 // 2. check surface node dirtyrect need merge into displayDirtyManager
2510 CheckMergeSurfaceDirtysForDisplay(surfaceNode);
2511 // 3. check merge transparent filter when it intersects with pre-dirty.
2512 CheckMergeDisplayDirtyByTransparentFilter(surfaceNode, accumulatedDirtyRegion);
2513 // 4. for cross-display node, process its filter (which is not collected during prepare).
2514 CollectFilterInCrossDisplayWindow(surfaceNode, accumulatedDirtyRegion);
2515 // 5. accumulate dirty region of this surface.
2516 AccumulateSurfaceDirtyRegion(surfaceNode, accumulatedDirtyRegion);
2517 });
2518 curDisplayNode_->SetMainAndLeashSurfaceDirty(hasMainAndLeashSurfaceDirty);
2519 CheckMergeDebugRectforRefreshRate(curMainAndLeashSurfaces);
2520 CheckMergeDisplayDirtyByRoundCornerDisplay();
2521 CheckMergeGlobalFilterForDisplay(accumulatedDirtyRegion);
2522 ResetDisplayDirtyRegion();
2523 if (curDisplayDirtyManager_) {
2524 curDisplayDirtyManager_->ClipDirtyRectWithinSurface();
2525 if (curDisplayDirtyManager_->IsActiveSurfaceRectChanged()) {
2526 RS_TRACE_NAME_FMT("ActiveSurfaceRectChanged, form %s to %s",
2527 curDisplayDirtyManager_->GetLastActiveSurfaceRect().ToString().c_str(),
2528 curDisplayDirtyManager_->GetActiveSurfaceRect().ToString().c_str());
2529 curDisplayDirtyManager_->MergeDirtyRect(curDisplayDirtyManager_->GetSurfaceRect());
2530 }
2531 }
2532 curDisplayNode_->ClearCurrentSurfacePos();
2533 std::swap(preMainAndLeashWindowNodesIds_, curMainAndLeashWindowNodesIds_);
2534
2535 #ifdef RS_PROFILER_ENABLED
2536 RS_PROFILER_SET_DIRTY_REGION(accumulatedDirtyRegion);
2537 #endif
2538 }
2539
2540 void RSUniRenderVisitor::UpdateDisplayRcdRenderNode()
2541 {
2542 RSSingleton<RoundCornerDisplayManager>::GetInstance().RefreshFlagAndUpdateResource(curDisplayNode_->GetId());
2543 bool isRcdEnabled = RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable();
2544
2545 if (isRcdEnabled) {
2546 if (!curDisplayNode_->GetRcdSurfaceNodeTop()) {
2547 auto node = RSRcdSurfaceRenderNode::Create(
2548 curDisplayNode_->GetId(), RCDSurfaceType::TOP, curDisplayNode_->GetContext());
2549 curDisplayNode_->SetRcdSurfaceNodeTop(node);
2550 }
2551 if (!curDisplayNode_->GetRcdSurfaceNodeBottom()) {
2552 auto node = RSRcdSurfaceRenderNode::Create(
2553 curDisplayNode_->GetId(), RCDSurfaceType::BOTTOM, curDisplayNode_->GetContext());
2554 curDisplayNode_->SetRcdSurfaceNodeBottom(node);
2555 }
2556
2557 auto hardInfo =
2558 RSSingleton<RoundCornerDisplayManager>::GetInstance().PrepareHardwareInfo(curDisplayNode_->GetId());
2559 if (hardInfo.topLayer && hardInfo.bottomLayer) {
2560 auto topNode = std::static_pointer_cast<RSRcdSurfaceRenderNode>(curDisplayNode_->GetRcdSurfaceNodeTop());
2561 auto bottomNode =
2562 std::static_pointer_cast<RSRcdSurfaceRenderNode>(curDisplayNode_->GetRcdSurfaceNodeBottom());
2563
2564 if (hardInfo.resourceChanged) {
2565 topNode->SetRenderDisplayRect(hardInfo.displayRect);
2566 topNode->PrepareHardwareResource(hardInfo.topLayer);
2567 bottomNode->SetRenderDisplayRect(hardInfo.displayRect);
2568 bottomNode->PrepareHardwareResource(hardInfo.bottomLayer);
2569 }
2570
2571 topNode->UpdateRcdRenderParams(hardInfo.resourceChanged, hardInfo.topLayer->curBitmap);
2572 bottomNode->UpdateRcdRenderParams(hardInfo.resourceChanged, hardInfo.bottomLayer->curBitmap);
2573 }
2574 }
2575 }
2576
2577 void RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow()
2578 {
2579 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2580 // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
2581 std::vector<RectI> hwcRects;
2582 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2583 [this, &hwcRects](RSBaseRenderNode::SharedPtr& nodePtr) {
2584 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2585 if (!surfaceNode) {
2586 RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow surfaceNode is nullptr");
2587 return;
2588 }
2589 // use in temporary scheme to realize DSS
2590 auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2591 if (!hwcNodes.empty() && RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag() &&
2592 RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
2593 UpdateHardwareStateByHwcNodeBackgroundAlpha(hwcNodes);
2594 } else if (surfaceNode->ExistTransparentHardwareEnabledNode()) {
2595 UpdateTransparentHwcNodeEnable(hwcNodes);
2596 }
2597 // use end
2598 UpdateChildHwcNodeEnableByHwcNodeBelow(hwcRects, surfaceNode);
2599 });
2600 }
2601
2602 void RSUniRenderVisitor::UpdateTransparentHwcNodeEnable(
2603 const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes)
2604 {
2605 for (size_t index = 1; index < hwcNodes.size(); ++index) {
2606 auto transparentHwcNodeSPtr = hwcNodes[index].lock();
2607 if (!transparentHwcNodeSPtr) {
2608 continue;
2609 }
2610 const bool isTransparentEnableHwcNode = transparentHwcNodeSPtr->IsNodeHasBackgroundColorAlpha() &&
2611 !transparentHwcNodeSPtr->IsHardwareForcedDisabled() && transparentHwcNodeSPtr->IsHardwareEnableHint();
2612 if (!isTransparentEnableHwcNode) {
2613 continue;
2614 }
2615 auto transparentDstRect = transparentHwcNodeSPtr->GetDstRect();
2616 for (size_t lowerIndex = 0; lowerIndex < index; ++lowerIndex) {
2617 // 'lowerHwcNode' means lower device composition layer.
2618 auto lowerHwcNodeSPtr = hwcNodes[lowerIndex].lock();
2619 if (!lowerHwcNodeSPtr || !lowerHwcNodeSPtr->IsHardwareForcedDisabled()) {
2620 continue;
2621 }
2622 auto lowerHwcNodeRect = lowerHwcNodeSPtr->GetDstRect();
2623 bool isIntersect = !transparentDstRect.IntersectRect(lowerHwcNodeRect).IsEmpty();
2624 if (isIntersect) {
2625 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparent hwc node"
2626 " cover other disabled hwc node name:%s id:%" PRIu64,
2627 transparentHwcNodeSPtr->GetName().c_str(), transparentHwcNodeSPtr->GetId(),
2628 lowerHwcNodeSPtr->GetName().c_str(), lowerHwcNodeSPtr->GetId());
2629 transparentHwcNodeSPtr->SetHardwareForcedDisabledState(true);
2630 break;
2631 }
2632 }
2633 }
2634 }
2635
2636 void RSUniRenderVisitor::UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI>& hwcRects,
2637 std::shared_ptr<RSSurfaceRenderNode>& appNode)
2638 {
2639 const auto& hwcNodes = appNode->GetChildHardwareEnabledNodes();
2640 for (auto hwcNode : hwcNodes) {
2641 auto hwcNodePtr = hwcNode.lock();
2642 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2643 continue;
2644 }
2645 UpdateHwcNodeEnableByHwcNodeBelowSelf(hwcRects, hwcNodePtr,
2646 hwcNodePtr->GetIntersectedRoundCornerAABBsSize() != 0);
2647 }
2648 }
2649
2650 void RSUniRenderVisitor::UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,
2651 std::vector<RectI>& hwcRects)
2652 {
2653 if (!hwcNode || !hwcNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2654 return;
2655 }
2656 auto instanceNode = hwcNode->GetInstanceRootNode() ?
2657 hwcNode->GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
2658 if (!instanceNode) {
2659 hwcNode->SetCornerRadiusInfoForDRM({});
2660 return;
2661 }
2662 auto instanceAbsRect = instanceNode->GetAbsDrawRect();
2663 auto instanceCornerRadius = instanceNode->GetGlobalCornerRadius();
2664 if (instanceAbsRect.IsEmpty() || instanceCornerRadius.IsZero() ||
2665 ROSEN_EQ(instanceNode->GetRenderProperties().GetBoundsWidth(), 0.0f)) {
2666 hwcNode->SetCornerRadiusInfoForDRM({});
2667 return;
2668 }
2669 auto hwcGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2670 if (!hwcGeo) {
2671 hwcNode->SetCornerRadiusInfoForDRM({});
2672 return;
2673 }
2674 auto hwcAbsRect = hwcGeo->MapRect(hwcNode->GetSelfDrawRect(), hwcNode->GetTotalMatrix());
2675 hwcAbsRect = hwcAbsRect.IntersectRect(instanceAbsRect);
2676 if (hwcAbsRect.IsEmpty()) {
2677 hwcNode->SetCornerRadiusInfoForDRM({});
2678 return;
2679 }
2680 auto ratio = static_cast<float>(instanceAbsRect.GetWidth()) /
2681 instanceNode->GetRenderProperties().GetBoundsWidth();
2682 std::vector<float> ratioVector = { 0.0f, 0.0f, 0.0f, 0.0f };
2683 bool isIntersectWithRoundCorner =
2684 CheckIfRoundCornerIntersectDRM(ratio, ratioVector, instanceCornerRadius, instanceAbsRect, hwcAbsRect);
2685 // store radius information when drm overlaps with other hwc nodes
2686 if (isIntersectWithRoundCorner) {
2687 for (const auto& rect : hwcRects) {
2688 if (hwcAbsRect.Intersect(rect)) {
2689 std::vector<float> drmCornerRadiusInfo = {
2690 static_cast<float>(hwcAbsRect.GetLeft()), static_cast<float>(hwcAbsRect.GetTop()),
2691 static_cast<float>(hwcAbsRect.GetWidth()), static_cast<float>(hwcAbsRect.GetHeight()),
2692 // get corner radius num by index 0, 1, 2, 3
2693 instanceCornerRadius[0] * ratioVector[0], instanceCornerRadius[1] * ratioVector[1],
2694 instanceCornerRadius[2] * ratioVector[2], instanceCornerRadius[3] * ratioVector[3]};
2695 hwcNode->SetCornerRadiusInfoForDRM(drmCornerRadiusInfo);
2696 return;
2697 }
2698 }
2699 }
2700 hwcNode->SetCornerRadiusInfoForDRM({});
2701 }
2702
2703 bool RSUniRenderVisitor::CheckIfRoundCornerIntersectDRM(const float& ratio, std::vector<float>& ratioVector,
2704 const Vector4f& instanceCornerRadius, const RectI& instanceAbsRect, const RectI& hwcAbsRect)
2705 {
2706 auto maxRadius = *std::max_element(std::begin(instanceCornerRadius.data_),
2707 std::end(instanceCornerRadius.data_)) * ratio;
2708 bool isIntersectWithRoundCorner = false;
2709 static const std::vector<UIPoint> offsetVecs = { UIPoint { 0, 0 }, UIPoint { 1, 0 },
2710 UIPoint { 0, 1 }, UIPoint { 1, 1 } };
2711 UIPoint offset { instanceAbsRect.GetWidth() - maxRadius, instanceAbsRect.GetHeight() - maxRadius };
2712 UIPoint anchorPoint { instanceAbsRect.GetLeft(), instanceAbsRect.GetTop() };
2713 // if round corners intersect drm, update ratioVectors
2714 for (size_t i = 0; i < offsetVecs.size(); i++) {
2715 auto res = anchorPoint + offset * offsetVecs[i];
2716 if (RectI(res.x_, res.y_, maxRadius, maxRadius).Intersect(hwcAbsRect)) {
2717 isIntersectWithRoundCorner = true;
2718 ratioVector[i] = ratio;
2719 }
2720 }
2721 return isIntersectWithRoundCorner;
2722 }
2723
2724 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI>& hwcRects,
2725 std::shared_ptr<RSSurfaceRenderNode>& hwcNode, bool isIntersectWithRoundCorner)
2726 {
2727 if (!curDisplayNode_) {
2728 RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelf curDisplayNode is null");
2729 return;
2730 }
2731 if (hwcNode->IsHardwareForcedDisabled()) {
2732 if (RSHdrUtil::CheckIsHdrSurface(*hwcNode) != HdrStatus::NO_HDR) {
2733 curDisplayNode_->SetHasUniRenderHdrSurface(true);
2734 }
2735 return;
2736 }
2737 auto absBound = RectI();
2738 if (auto geo = hwcNode->GetRenderProperties().GetBoundsGeometry()) {
2739 absBound = geo->GetAbsRect();
2740 } else {
2741 return;
2742 }
2743 if (hwcNode->GetAncoForceDoDirect() || !isIntersectWithRoundCorner) {
2744 hwcRects.emplace_back(absBound);
2745 return;
2746 }
2747 for (const auto& rect : hwcRects) {
2748 for (auto& roundCornerAABB : hwcNode->GetIntersectedRoundCornerAABBs()) {
2749 if (!roundCornerAABB.IntersectRect(rect).IsEmpty()) {
2750 #ifdef HIPERF_TRACE_ENABLE
2751 RS_LOGW("hiperf_surface: name:%s disabled by corner radius + hwc node below, "
2752 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", hwcNode->GetName().c_str(),
2753 hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2754 hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom(),
2755 hwcNode->GetSrcRect().GetLeft(), hwcNode->GetSrcRect().GetRight(),
2756 hwcNode->GetSrcRect().GetTop(), hwcNode->GetSrcRect().GetBottom());
2757 #endif
2758 if (hwcNode->GetSpecialLayerMgr().Find(SpecialLayerType::PROTECTED)) {
2759 continue;
2760 }
2761 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by corner radius + "
2762 "hwc node below, rect:%s", hwcNode->GetName().c_str(), hwcNode->GetId(), rect.ToString().c_str());
2763 hwcNode->SetHardwareForcedDisabledState(true);
2764 if (RSHdrUtil::CheckIsHdrSurface(*hwcNode) != HdrStatus::NO_HDR) {
2765 curDisplayNode_->SetHasUniRenderHdrSurface(true);
2766 }
2767 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2768 HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
2769 return;
2770 }
2771 }
2772 }
2773 hwcRects.emplace_back(absBound);
2774 }
2775
2776 void RSUniRenderVisitor::UpdateSurfaceOcclusionInfo()
2777 {
2778 allDstCurVisVec_.insert(allDstCurVisVec_.end(), dstCurVisVec_.begin(), dstCurVisVec_.end());
2779 dstCurVisVec_.clear();
2780 }
2781
2782 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode& surfaceNode) const
2783 {
2784 // surfaceNode is transparent
2785 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2786 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2787 Occlusion::Region visibleRegion = hasMirrorDisplay_ ?
2788 surfaceNode.GetVisibleRegionInVirtual() : surfaceNode.GetVisibleRegion();
2789 if (surfaceNode.IsMainWindowType() && !visibleRegion.IsIntersectWith(dirtyRect)) {
2790 return;
2791 }
2792 if (surfaceNode.IsTransparent()) {
2793 RectI transparentDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2794 if (!transparentDirtyRect.IsEmpty()) {
2795 RS_LOGD("CheckMergeDisplayDirtyByTransparent global merge transparent dirty "
2796 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2797 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2798 transparentDirtyRect.ToString().c_str());
2799 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(transparentDirtyRect);
2800 }
2801 }
2802 // surfaceNode has transparent regions
2803 CheckMergeDisplayDirtyByTransparentRegions(surfaceNode);
2804 }
2805
2806 void RSUniRenderVisitor::CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode& surfaceNode) const
2807 {
2808 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2809 if (surfaceNode.GetZorderChanged()) {
2810 RS_LOGD("CheckMergeDisplayDirtyByZorderChanged global merge GetZorderChanged "
2811 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2812 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2813 oldDirtyInSurface.ToString().c_str());
2814 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(oldDirtyInSurface);
2815 }
2816 }
2817
2818 void RSUniRenderVisitor::CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode& surfaceNode) const
2819 {
2820 bool isHardCursor = RSPointerWindowManager::Instance().CheckHardCursorSupport(curDisplayNode_->GetScreenId());
2821 if (isHardCursor && surfaceNode.IsHardwareEnabledTopSurface() && surfaceNode.GetHardCursorStatus()) {
2822 return;
2823 }
2824 RectI lastFrameSurfacePos = curDisplayNode_->GetLastFrameSurfacePos(surfaceNode.GetId());
2825 RectI currentFrameSurfacePos = curDisplayNode_->GetCurrentFrameSurfacePos(surfaceNode.GetId());
2826 if (surfaceNode.GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
2827 RS_LOGD("CheckMergeDisplayDirtyByPosChanged global merge surface pos changed "
2828 "%{public}s: global dirty %{public}s, lastFrameRect %{public}s currentFrameRect %{public}s",
2829 surfaceNode.GetName().c_str(),
2830 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2831 lastFrameSurfacePos.ToString().c_str(), currentFrameSurfacePos.ToString().c_str());
2832 if (!lastFrameSurfacePos.IsEmpty()) {
2833 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(lastFrameSurfacePos);
2834 }
2835 if (!currentFrameSurfacePos.IsEmpty()) {
2836 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(currentFrameSurfacePos);
2837 }
2838 }
2839 }
2840
2841 void RSUniRenderVisitor::CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode& surfaceNode) const
2842 {
2843 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2844 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2845 bool isShadowDisappear = !surfaceNode.GetRenderProperties().IsShadowValid() &&
2846 surfaceNode.IsShadowValidLastFrame();
2847 if (surfaceNode.GetRenderProperties().IsShadowValid() || isShadowDisappear) {
2848 RectI shadowDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2849 // There are two situation here:
2850 // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
2851 // dirtyRect == surfaceNode.GetOldDirtyInSurface()
2852 // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
2853 // dirtyRect > surfaceNode.GetOldDirtyInSurface()
2854 // So we should always merge dirtyRect here.
2855 if (!shadowDirtyRect.IsEmpty()) {
2856 RS_LOGD("CheckMergeDisplayDirtyByShadowChanged global merge ShadowValid %{public}s: "
2857 "global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2858 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2859 dirtyRect.ToString().c_str());
2860 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRect);
2861 }
2862 if (isShadowDisappear) {
2863 surfaceNode.SetShadowValidLastFrame(false);
2864 }
2865 }
2866 }
2867
2868 void RSUniRenderVisitor::CheckMergeDisplayDirtyBySurfaceChanged() const
2869 {
2870 std::vector<RectI> surfaceChangedRects = curDisplayNode_->GetSurfaceChangedRects();
2871 for (auto& surfaceChangedRect : surfaceChangedRects) {
2872 if (!surfaceChangedRect.IsEmpty()) {
2873 RS_LOGD("CheckMergeDisplayDirtyBySurfaceChanged global merge Surface closed, global dirty %{public}s,"
2874 "add rect %{public}s",
2875 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2876 surfaceChangedRect.ToString().c_str());
2877 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(surfaceChangedRect);
2878 }
2879 }
2880 }
2881
2882 void RSUniRenderVisitor::CheckMergeDisplayDirtyByAttraction(RSSurfaceRenderNode& surfaceNode) const
2883 {
2884 if (surfaceNode.GetRenderProperties().IsAttractionValid()) {
2885 auto attractionDirtyRect = surfaceNode.GetRenderProperties().GetAttractionEffectCurrentDirtyRegion();
2886 RS_LOGD("CheckMergeDisplayDirtyByAttraction global merge attraction %{public}s: global dirty %{public}s,"
2887 "add rect %{public}s", surfaceNode.GetName().c_str(),
2888 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2889 attractionDirtyRect.ToString().c_str());
2890 auto boundsGeometry = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
2891 if (boundsGeometry) {
2892 Drawing::Rect rect(attractionDirtyRect.GetLeft(), attractionDirtyRect.GetTop(),
2893 attractionDirtyRect.GetRight(), attractionDirtyRect.GetBottom());
2894 Drawing::Rect tempRect;
2895 boundsGeometry->GetMatrix().MapRect(tempRect, rect);
2896 attractionDirtyRect =
2897 RectI(tempRect.GetLeft(), tempRect.GetTop(), tempRect.GetWidth(), tempRect.GetHeight());
2898 }
2899 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(attractionDirtyRect);
2900 }
2901 }
2902
2903 void RSUniRenderVisitor::CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2904 {
2905 if (surfaceNode->GetDirtyManager() == nullptr || curDisplayNode_->GetDirtyManager() == nullptr) {
2906 return;
2907 }
2908 // 1 handle last and curframe surfaces which appear or disappear case
2909 CheckMergeDisplayDirtyBySurfaceChanged();
2910 // 2 if the surface node is cross-display and prepared again, convert its dirty region into global.
2911 if (surfaceNode->IsFirstLevelCrossNode() && !curDisplayNode_->IsFirstVisitCrossNodeDisplay()) {
2912 CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2913 CheckMergeDisplayDirtyByCrossDisplayWindow(*surfaceNode);
2914 return;
2915 }
2916 // 3 Handles the case of transparent surface, merge transparent dirty rect
2917 CheckMergeDisplayDirtyByTransparent(*surfaceNode);
2918 // 4 Zorder changed case, merge surface dest Rect
2919 CheckMergeDisplayDirtyByZorderChanged(*surfaceNode);
2920 // 5 surfacePos chanded case, merge surface lastframe pos or curframe pos
2921 CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2922 // 6 shadow disappear and appear case.
2923 CheckMergeDisplayDirtyByShadowChanged(*surfaceNode);
2924 // 7 handle surface has attraction effect
2925 CheckMergeDisplayDirtyByAttraction(*surfaceNode);
2926 // More: any other display dirty caused by surfaceNode should be added here like CheckMergeDisplayDirtByXXX
2927 }
2928
2929 void RSUniRenderVisitor::CheckMergeDisplayDirtyByCrossDisplayWindow(RSSurfaceRenderNode& surfaceNode) const
2930 {
2931 auto geoPtr = surfaceNode.GetRenderProperties().GetBoundsGeometry();
2932 if (!geoPtr) {
2933 return;
2934 }
2935 // transfer from the display coordinate system during quickprepare into current display coordinate system.
2936 auto dirtyRect = geoPtr->MapRect(surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion().ConvertTo<float>(),
2937 surfaceNode.GetCrossNodeSkipDisplayConversionMatrix(curDisplayNode_->GetId()));
2938 RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeDisplayDirtyByCrossDisplayWindow %s, global dirty %s, add rect %s",
2939 surfaceNode.GetName().c_str(), curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
2940 dirtyRect.ToString().c_str());
2941 curDisplayDirtyManager_->MergeDirtyRect(dirtyRect);
2942 }
2943
2944 void RSUniRenderVisitor::CollectFilterInCrossDisplayWindow(
2945 std::shared_ptr<RSSurfaceRenderNode>& surfaceNode, Occlusion::Region& accumulatedDirtyRegion)
2946 {
2947 auto geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
2948 if (!surfaceNode->IsFirstLevelCrossNode() || curDisplayNode_->IsFirstVisitCrossNodeDisplay() || !geoPtr) {
2949 return;
2950 }
2951 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2952 for (auto& child : surfaceNode->GetVisibleFilterChild()) {
2953 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2954 if (!filterNode) {
2955 continue;
2956 }
2957 auto filterRect = geoPtr->MapRect(filterNode->GetAbsDrawRect().ConvertTo<float>(),
2958 surfaceNode->GetCrossNodeSkipDisplayConversionMatrix(curDisplayNode_->GetId())).IntersectRect(screenRect_);
2959 if (surfaceNode->IsTransparent() && accumulatedDirtyRegion.IsIntersectWith(Occlusion::Rect(filterRect))) {
2960 RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInCrossDisplayWindow [%s] has filter, add [%s] to global dirty",
2961 surfaceNode->GetName().c_str(), filterRect.ToString().c_str());
2962 curDisplayDirtyManager_->MergeDirtyRect(filterRect);
2963 } else {
2964 RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInCrossDisplayWindow [%s] has filter, add [%s] to global filter",
2965 surfaceNode->GetName().c_str(), filterRect.ToString().c_str());
2966 globalFilter_.insert({ filterNode->GetId(), filterRect });
2967 }
2968 }
2969 }
2970
2971 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode& surfaceNode) const
2972 {
2973 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2974 if (surfaceNode.HasContainerWindow()) {
2975 // If a surface's dirty is intersect with container region (which can be considered transparent)
2976 // should be added to display dirty region.
2977 // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
2978 auto containerRegion = surfaceNode.GetContainerRegion();
2979 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2980 auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
2981 if (!containerDirtyRegion.IsEmpty()) {
2982 RS_LOGD("CheckMergeDisplayDirtyByContainer global merge containerDirtyRegion "
2983 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2984 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2985 containerDirtyRegion.GetRegionInfo().c_str());
2986 // plan: we can use surfacenode's absrect as containerRegion's bound
2987 const auto& rect = containerRegion.GetBoundRef();
2988 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(
2989 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2990 }
2991 } else {
2992 // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
2993 // transparent region and opaque region in adjacent frame, may cause displaydirty region incomplete after
2994 // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
2995 // which include transparent region but not counted in display dirtyregion)
2996 if (!surfaceNode.IsNodeDirty()) {
2997 return;
2998 }
2999 auto transparentRegion = surfaceNode.GetTransparentRegion();
3000 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
3001 Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
3002 if (!transparentDirtyRegion.IsEmpty()) {
3003 RS_LOGD("CheckMergeDisplayDirtyByTransparentRegions global merge TransparentDirtyRegion "
3004 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
3005 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3006 transparentDirtyRegion.GetRegionInfo().c_str());
3007 const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
3008 for (const auto& rect : rects) {
3009 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(RectI{ rect.left_, rect.top_,
3010 rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
3011 }
3012 }
3013 }
3014 }
3015
3016 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter(
3017 std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
3018 Occlusion::Region& accumulatedDirtyRegion)
3019 {
3020 auto disappearedSurfaceRegionBelowCurrent =
3021 curDisplayNode_->GetDisappearedSurfaceRegionBelowCurrent(surfaceNode->GetId());
3022 accumulatedDirtyRegion.OrSelf(disappearedSurfaceRegionBelowCurrent);
3023 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3024 auto filterVecIter = transparentCleanFilter_.find(surfaceNode->GetId());
3025 if (filterVecIter != transparentCleanFilter_.end()) {
3026 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter surface:%{public}s "
3027 "has transparentCleanFilter", surfaceNode->GetName().c_str());
3028 // check accumulatedDirtyRegion influence filter nodes which in the current surface
3029 for (auto it = filterVecIter->second.begin(); it != filterVecIter->second.end(); ++it) {
3030 auto filterNode = nodeMap.GetRenderNode(it->first);
3031 if (filterNode == nullptr) {
3032 continue;
3033 }
3034 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
3035 auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
3036 if (!filterDirtyRegion.IsEmpty()) {
3037 if (filterNode->GetRenderProperties().GetBackgroundFilter() ||
3038 filterNode->GetRenderProperties().GetNeedDrawBehindWindow()) {
3039 // backgroundfilter affected by below dirty
3040 filterNode->MarkFilterStatusChanged(false, false);
3041 }
3042 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter global merge filterRegion "
3043 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode->GetName().c_str(),
3044 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3045 it->second.ToString().c_str());
3046 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
3047 if (filterNode->GetRenderProperties().GetFilter()) {
3048 // foregroundfilter affected by below dirty
3049 filterNode->MarkFilterStatusChanged(true, false);
3050 }
3051 } else {
3052 globalFilter_.insert(*it);
3053 }
3054 filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
3055 RsFrameBlurPredict::GetInstance().PredictDrawLargeAreaBlur(*filterNode);
3056 }
3057 }
3058 }
3059
3060 void RSUniRenderVisitor::AccumulateSurfaceDirtyRegion(
3061 std::shared_ptr<RSSurfaceRenderNode>& surfaceNode, Occlusion::Region& accumulatedDirtyRegion) const
3062 {
3063 auto geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
3064 if (!surfaceNode->GetDirtyManager() || !geoPtr) {
3065 return;
3066 }
3067 auto surfaceDirtyRect = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
3068 if (surfaceNode->IsFirstLevelCrossNode() && !curDisplayNode_->IsFirstVisitCrossNodeDisplay()) {
3069 surfaceDirtyRect = geoPtr->MapRect(surfaceDirtyRect.ConvertTo<float>(),
3070 surfaceNode->GetCrossNodeSkipDisplayConversionMatrix(curDisplayNode_->GetId()));
3071 }
3072 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ surfaceDirtyRect } };
3073 accumulatedDirtyRegion.OrSelf(surfaceDirtyRegion);
3074 }
3075
3076 void RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion()
3077 {
3078 if (curDisplayNode_ == nullptr) {
3079 RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion curDisplayNode_ is nullptr");
3080 return;
3081 }
3082 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
3083 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3084 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
3085 [this, &nodeMap](RSBaseRenderNode::SharedPtr& nodePtr) {
3086 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
3087 if (surfaceNode == nullptr) {
3088 RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion surfaceNode is nullptr");
3089 return;
3090 }
3091 if (!surfaceNode->IsMainWindowType()) {
3092 return;
3093 }
3094 Occlusion::Region extendRegion;
3095 if (!surfaceNode->GetVisibleRegion().IsEmpty()) {
3096 ProcessFilterNodeObscured(surfaceNode, extendRegion, nodeMap);
3097 }
3098 surfaceNode->UpdateExtendVisibleRegion(extendRegion);
3099 });
3100 }
3101
3102 void RSUniRenderVisitor::ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
3103 Occlusion::Region& extendRegion, const RSRenderNodeMap& nodeMap)
3104 {
3105 const auto& visibleFilterChild = surfaceNode->GetVisibleFilterChild();
3106 auto visibleRegion = surfaceNode->GetVisibleRegion();
3107 auto currentFrameDirtyRegion = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
3108 auto isTransparent = surfaceNode->IsTransparent();
3109 for (const auto& child : visibleFilterChild) {
3110 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3111 if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
3112 continue;
3113 }
3114 MarkBlurIntersectWithDRM(filterNode);
3115 auto filterRect = filterNode->GetOldDirtyInSurface();
3116 auto visibleRects = visibleRegion.GetRegionRectIs();
3117 auto iter = std::find_if(visibleRects.begin(), visibleRects.end(), [&filterRect](const auto& rect) {
3118 return filterRect.IsInsideOf(rect);
3119 });
3120 if (iter != visibleRects.end()) {
3121 continue;
3122 }
3123 if (!visibleRegion.IsIntersectWith(filterRect)) {
3124 continue;
3125 }
3126 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ filterRect } };
3127 extendRegion = extendRegion.Or(filterRegion);
3128 if (!isTransparent && filterRect.Intersect(currentFrameDirtyRegion)) {
3129 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(filterRect);
3130 }
3131 }
3132 }
3133
3134 void RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
3135 {
3136 if (surfaceNode == nullptr) {
3137 return;
3138 }
3139 if (surfaceNode->HasBlurFilter()) {
3140 surfaceNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
3141 }
3142 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3143 for (auto& child : surfaceNode->GetVisibleFilterChild()) {
3144 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3145 if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
3146 continue;
3147 }
3148 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode "
3149 "surfaceNode: %s, filterNode:[%lld], IsOccludedByFilterCache:%d", surfaceNode->GetName().c_str(),
3150 filterNode->GetId(), surfaceNode->IsOccludedByFilterCache());
3151 filterNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
3152 }
3153 }
3154
3155 void RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay(Occlusion::Region& accumulatedDirtyRegion)
3156 {
3157 // [planning] if not allowed containerNode filter, The following processing logic can be removed
3158 // Recursively traverses container nodes need filter
3159 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3160 for (auto it = containerFilter_.begin(); it != containerFilter_.end(); ++it) {
3161 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(it->first);
3162 if (filterNode == nullptr) {
3163 continue;
3164 }
3165 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
3166 auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
3167 RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeGlobalFilterForDisplay::filternode:%" PRIu64
3168 ", filterRect:%s, dirtyRegion:%s",
3169 filterNode->GetId(), it->second.ToString().c_str(), accumulatedDirtyRegion.GetRegionInfo().c_str());
3170 if (!filterDirtyRegion.IsEmpty()) {
3171 RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
3172 "global dirty %{public}s, add container filterRegion %{public}s",
3173 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3174 (it->second).ToString().c_str());
3175 if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3176 filterNode->MarkFilterStatusChanged(false, false); // background filter affected by below dirty
3177 }
3178 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
3179 if (filterNode->GetRenderProperties().GetFilter()) {
3180 filterNode->MarkFilterStatusChanged(true, false); // foreground filter affected by below dirty
3181 }
3182 } else {
3183 globalFilter_.insert(*it);
3184 }
3185 filterNode->UpdateFilterCacheWithSelfDirty();
3186 filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
3187 }
3188
3189 UpdateDisplayDirtyAndExtendVisibleRegion();
3190 CheckMergeFilterDirtyByIntersectWithDirty(globalFilter_, true);
3191 }
3192
3193 void RSUniRenderVisitor::CollectEffectInfo(RSRenderNode& node)
3194 {
3195 auto nodeParent = node.GetParent().lock();
3196 if (nodeParent == nullptr) {
3197 return;
3198 }
3199 if (node.GetRenderProperties().NeedFilter() || node.ChildHasVisibleFilter()) {
3200 nodeParent->SetChildHasVisibleFilter(true);
3201 nodeParent->UpdateVisibleFilterChild(node);
3202 }
3203 if ((node.GetRenderProperties().GetUseEffect() && node.ShouldPaint())|| node.ChildHasVisibleEffect()) {
3204 nodeParent->SetChildHasVisibleEffect(true);
3205 nodeParent->UpdateVisibleEffectChild(node);
3206 }
3207 if (node.GetSharedTransitionParam() || node.ChildHasSharedTransition()) {
3208 nodeParent->SetChildHasSharedTransition(true);
3209 }
3210 }
3211
3212 void RSUniRenderVisitor::PostPrepare(RSRenderNode& node, bool subTreeSkipped)
3213 {
3214 UpdateCurFrameInfoDetail(node, subTreeSkipped, true);
3215 if (const auto& sharedTransitionParam = node.GetSharedTransitionParam()) {
3216 sharedTransitionParam->GenerateDrawable(node);
3217 }
3218 auto curDirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
3219 if (!curDirtyManager) {
3220 return;
3221 }
3222 auto isOccluded = curSurfaceNode_ ?
3223 curSurfaceNode_->IsMainWindowType() && curSurfaceNode_->GetVisibleRegion().IsEmpty() : false;
3224 if (subTreeSkipped && (!isOccluded || node.IsFirstLevelCrossNode())) {
3225 UpdateHwcNodeRectInSkippedSubTree(node);
3226 CheckFilterNodeInSkippedSubTreeNeedClearCache(node, *curDirtyManager);
3227 UpdateSubSurfaceNodeRectInSkippedSubTree(node);
3228 }
3229 if (node.NeedUpdateDrawableBehindWindow()) {
3230 node.GetMutableRenderProperties().SetNeedDrawBehindWindow(node.NeedDrawBehindWindow());
3231 }
3232 auto globalFilterRect = (node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren()) ?
3233 GetVisibleEffectDirty(node) : node.GetOldDirtyInSurface();
3234 auto globalHwcFilterRect = (node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren()) ?
3235 GetHwcVisibleEffectDirty(node, globalFilterRect) : globalFilterRect;
3236 if (node.NeedDrawBehindWindow()) {
3237 node.CalDrawBehindWindowRegion();
3238 globalFilterRect = node.GetFilterRect();
3239 }
3240 if (node.GetRenderProperties().NeedFilter() || node.IsBlendWithBackground()) {
3241 UpdateHwcNodeEnableByFilterRect(
3242 curSurfaceNode_, node.GetOldDirtyInSurface(), node.GetId(), NeedPrepareChindrenInReverseOrder(node),
3243 node.zOrderForCalcHwcNodeEnableByFilter_);
3244 node.CalVisibleFilterRect(prepareClipRect_);
3245 node.MarkClearFilterCacheIfEffectChildrenChanged();
3246 CollectFilterInfoAndUpdateDirty(node, *curDirtyManager, globalFilterRect, globalHwcFilterRect);
3247 node.SetGlobalAlpha(curAlpha_);
3248 }
3249 CollectEffectInfo(node);
3250 node.MapAndUpdateChildrenRect();
3251 node.UpdateSubTreeInfo(prepareClipRect_);
3252 node.UpdateLocalDrawRect();
3253 node.UpdateAbsDrawRect();
3254 node.ResetChangeState();
3255 node.SetHasUnobscuredUEC();
3256 if (isDrawingCacheEnabled_) {
3257 node.UpdateDrawingCacheInfoAfterChildren();
3258 }
3259 if (auto nodeParent = node.GetParent().lock()) {
3260 nodeParent->UpdateChildUifirstSupportFlag(node.GetUifirstSupportFlag());
3261 nodeParent->OpincUpdateNodeSupportFlag(node.OpincGetNodeSupportFlag());
3262 }
3263 auto& stagingRenderParams = node.GetStagingRenderParams();
3264 if (stagingRenderParams != nullptr) {
3265 if (node.GetSharedTransitionParam() && node.GetRenderProperties().GetSandBox()) {
3266 stagingRenderParams->SetAlpha(curAlpha_);
3267 } else {
3268 stagingRenderParams->SetAlpha(node.GetRenderProperties().GetAlpha());
3269 }
3270 }
3271
3272 // planning: only do this if node is dirty
3273 node.UpdateRenderParams();
3274
3275 // add if node is dirty
3276 node.AddToPendingSyncList();
3277 }
3278
3279 void RSUniRenderVisitor::MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const
3280 {
3281 if (!RSSystemProperties::GetDrmMarkedFilterEnabled()) {
3282 return;
3283 }
3284 static std::vector<std::string> drmKeyWins = { "SCBVolumePanel", "SCBBannerNotification" };
3285 auto appWindowNodeId = node->GetInstanceRootNodeId();
3286 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3287 auto appWindowNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
3288 if (appWindowNode == nullptr) {
3289 return;
3290 }
3291 for (const auto& win : drmKeyWins) {
3292 if (appWindowNode->GetName().find(win) == std::string::npos) {
3293 continue;
3294 }
3295 for (auto& drmNode : drmNodes_) {
3296 auto drmNodePtr = drmNode.lock();
3297 if (drmNodePtr == nullptr) {
3298 continue;
3299 }
3300 bool isIntersect =
3301 drmNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(node->GetFilterRegion());
3302 if (isIntersect) {
3303 node->MarkBlurIntersectWithDRM(true, RSMainThread::Instance()->GetGlobalDarkColorMode());
3304 }
3305 }
3306 }
3307 }
3308
3309 void RSUniRenderVisitor::CheckFilterNodeInSkippedSubTreeNeedClearCache(
3310 const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager)
3311 {
3312 bool rotationChanged = curDisplayNode_ ?
3313 curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
3314 bool rotationStatusChanged = curDisplayNode_ ?
3315 curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
3316 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3317 for (auto& child : rootNode.GetVisibleFilterChild()) {
3318 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3319 if (filterNode == nullptr) {
3320 continue;
3321 }
3322 RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterNodeInSkippedSubTreeNeedClearCache node[%lld]", filterNode->GetId());
3323 if (auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode)) {
3324 UpdateRotationStatusForEffectNode(*effectNode);
3325 }
3326 filterNode->CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
3327 filterNode->MarkClearFilterCacheIfEffectChildrenChanged();
3328 if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3329 filterNode->UpdateFilterCacheWithBelowDirty(dirtyManager, false);
3330 }
3331 RectI filterRect;
3332 filterNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, prepareClipRect_);
3333 UpdateHwcNodeEnableByFilterRect(curSurfaceNode_, filterNode->GetOldDirtyInSurface(), filterNode->GetId());
3334 CollectFilterInfoAndUpdateDirty(*filterNode, dirtyManager, filterRect, filterRect);
3335 }
3336 }
3337
3338 void RSUniRenderVisitor::UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3339 {
3340 if (!curSurfaceNode_ || RS_PROFILER_SHOULD_BLOCK_HWCNODE()) {
3341 return;
3342 }
3343 const auto& hwcNodes = curSurfaceNode_->GetChildHardwareEnabledNodes();
3344 if (hwcNodes.empty()) {
3345 return;
3346 }
3347 for (auto hwcNode : hwcNodes) {
3348 auto hwcNodePtr = hwcNode.lock();
3349 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree() || hwcNodePtr->GetCalcRectInPrepare()) {
3350 continue;
3351 }
3352 const auto& property = hwcNodePtr->GetRenderProperties();
3353 auto geoPtr = property.GetBoundsGeometry();
3354 if (geoPtr == nullptr) {
3355 return;
3356 }
3357 auto originalMatrix = geoPtr->GetMatrix();
3358 auto matrix = Drawing::Matrix();
3359 auto parent = hwcNodePtr->GetCurCloneNodeParent().lock();
3360 if (parent == nullptr) {
3361 parent = hwcNodePtr->GetParent().lock();
3362 }
3363 if (!FindRootAndUpdateMatrix(parent, matrix, rootNode)) {
3364 continue;
3365 }
3366 if (parent) {
3367 const auto& parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
3368 if (parentGeoPtr) {
3369 matrix.PostConcat(parentGeoPtr->GetMatrix());
3370 }
3371 }
3372 RectI clipRect;
3373 UpdateHWCNodeClipRect(hwcNodePtr, clipRect, rootNode);
3374 auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
3375 auto& properties = hwcNodePtr->GetMutableRenderProperties();
3376 auto offset = std::nullopt;
3377 properties.UpdateGeometryByParent(&matrix, offset);
3378 matrix.PreConcat(originalMatrix);
3379 Drawing::Rect bounds = Drawing::Rect(0, 0, properties.GetBoundsWidth(), properties.GetBoundsHeight());
3380 Drawing::Rect absRect;
3381 matrix.MapRect(absRect, bounds);
3382 RectI rect;
3383 rect.left_ = static_cast<int>(std::floor(absRect.GetLeft()));
3384 rect.top_ = static_cast<int>(std::floor(absRect.GetTop()));
3385 rect.width_ = static_cast<int>(std::ceil(absRect.GetRight() - rect.left_));
3386 rect.height_ = static_cast<int>(std::ceil(absRect.GetBottom() - rect.top_));
3387 UpdateDstRect(*hwcNodePtr, rect, clipRect);
3388 UpdateSrcRect(*hwcNodePtr, matrix, rect);
3389 UpdateHwcNodeByTransform(*hwcNodePtr, matrix);
3390 UpdateHwcNodeEnableByBackgroundAlpha(*hwcNodePtr);
3391 UpdateHwcNodeEnableBySrcRect(*hwcNodePtr);
3392 UpdateHwcNodeEnableByBufferSize(*hwcNodePtr);
3393 hwcNodePtr->SetTotalMatrix(matrix);
3394 hwcNodePtr->SetOldDirtyInSurface(geoPtr->MapRect(hwcNodePtr->GetSelfDrawRect(), matrix));
3395 }
3396 }
3397
3398 bool RSUniRenderVisitor::FindRootAndUpdateMatrix(std::shared_ptr<RSRenderNode>& parent, Drawing::Matrix& matrix,
3399 const RSRenderNode& rootNode)
3400 {
3401 bool findInRoot = parent ? parent->GetId() == rootNode.GetId() : false;
3402 while (parent && parent->GetType() != RSRenderNodeType::DISPLAY_NODE) {
3403 if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
3404 matrix.PostConcat(opt.value());
3405 } else {
3406 break;
3407 }
3408 auto cloneNodeParent = parent->GetCurCloneNodeParent().lock();
3409 parent = cloneNodeParent ? cloneNodeParent : parent->GetParent().lock();
3410 if (!parent) {
3411 break;
3412 }
3413 findInRoot = parent->GetId() == rootNode.GetId() ? true : findInRoot;
3414 }
3415 return findInRoot;
3416 }
3417
3418 void RSUniRenderVisitor::UpdateHWCNodeClipRect(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr, RectI& clipRect,
3419 const RSRenderNode& rootNode)
3420 {
3421 // The value here represents an imaginary plane of infinite width and infinite height,
3422 // using values summarized empirically.
3423 constexpr float MAX_FLOAT = std::numeric_limits<float>::max() * 1e-30;
3424 Drawing::Rect childRectMapped(0.0f, 0.0f, MAX_FLOAT, MAX_FLOAT);
3425 RSRenderNode::SharedPtr hwcNodeParent = hwcNodePtr;
3426 while (hwcNodeParent && hwcNodeParent->GetType() != RSRenderNodeType::DISPLAY_NODE &&
3427 hwcNodeParent->GetId() != rootNode.GetId()) {
3428 const auto& parentProperties = hwcNodeParent->GetRenderProperties();
3429 const auto& parentGeoPtr = parentProperties.GetBoundsGeometry();
3430 parentGeoPtr->GetMatrix().MapRect(childRectMapped, childRectMapped);
3431 if (parentProperties.GetClipToBounds()) {
3432 auto selfDrawRectF = hwcNodeParent->GetSelfDrawRect();
3433 Drawing::Rect clipSelfDrawRect(selfDrawRectF.left_, selfDrawRectF.top_,
3434 selfDrawRectF.GetRight(), selfDrawRectF.GetBottom());
3435 Drawing::Rect clipBoundRectMapped;
3436 parentGeoPtr->GetMatrix().MapRect(clipBoundRectMapped, clipSelfDrawRect);
3437 childRectMapped.Intersect(clipBoundRectMapped);
3438 }
3439 if (parentProperties.GetClipToFrame()) {
3440 auto left = parentProperties.GetFrameOffsetX() * parentGeoPtr->GetMatrix().Get(Drawing::Matrix::SCALE_X);
3441 auto top = parentProperties.GetFrameOffsetY() * parentGeoPtr->GetMatrix().Get(Drawing::Matrix::SCALE_Y);
3442 Drawing::Rect clipFrameRect(
3443 left, top, left + parentProperties.GetFrameWidth(), top + parentProperties.GetFrameHeight());
3444 Drawing::Rect clipFrameRectMapped;
3445 parentGeoPtr->GetMatrix().MapRect(clipFrameRectMapped, clipFrameRect);
3446 childRectMapped.Intersect(clipFrameRectMapped);
3447 }
3448 if (parentProperties.GetClipToRRect()) {
3449 RectF rectF = parentProperties.GetClipRRect().rect_;
3450 Drawing::Rect clipRect(rectF.left_, rectF.top_, rectF.GetRight(), rectF.GetBottom());
3451 Drawing::Rect clipRectMapped;
3452 parentGeoPtr->GetMatrix().MapRect(clipRectMapped, clipRect);
3453 childRectMapped.Intersect(clipRectMapped);
3454 }
3455 hwcNodeParent = hwcNodeParent->GetParent().lock();
3456 }
3457 Drawing::Matrix rootNodeAbsMatrix = rootNode.GetRenderProperties().GetBoundsGeometry()->GetAbsMatrix();
3458 Drawing::Rect absClipRect;
3459 rootNodeAbsMatrix.MapRect(absClipRect, childRectMapped);
3460 Drawing::Rect prepareClipRect(prepareClipRect_.left_, prepareClipRect_.top_,
3461 prepareClipRect_.GetRight(), prepareClipRect_.GetBottom());
3462 absClipRect.Intersect(prepareClipRect);
3463 clipRect.left_ = static_cast<int>(std::floor(absClipRect.GetLeft()));
3464 clipRect.top_ = static_cast<int>(std::floor(absClipRect.GetTop()));
3465 clipRect.width_ = static_cast<int>(std::ceil(absClipRect.GetRight() - clipRect.left_));
3466 clipRect.height_ = static_cast<int>(std::ceil(absClipRect.GetBottom() - clipRect.top_));
3467 }
3468
3469 bool RSUniRenderVisitor::IsStencilPixelOcclusionCullingEnable() const
3470 {
3471 static auto stencilPixelOcclusionCullingParam =
3472 GraphicFeatureParamManager::GetInstance().GetFeatureParam("SpocConfig");
3473 auto stencilPixelOcclusionCullingFeature =
3474 std::static_pointer_cast<StencilPixelOcclusionCullingParam>(stencilPixelOcclusionCullingParam);
3475 if (stencilPixelOcclusionCullingFeature == nullptr) {
3476 ROSEN_LOGE("RSUniRenderVisitor::IsStencilPixelOcclusionCullingEnable "
3477 "stencilPixelOcclusionCullingFeature is nullptr");
3478 return false;
3479 }
3480 return stencilPixelOcclusionCullingFeature->IsStencilPixelOcclusionCullingEnable();
3481 }
3482
3483 void RSUniRenderVisitor::UpdateHardwareStateByHwcNodeBackgroundAlpha(
3484 const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes)
3485 {
3486 std::list<RectI> hwcRects;
3487 for (size_t i = 0; i < hwcNodes.size(); i++) {
3488 auto hwcNodePtr = hwcNodes[i].lock();
3489 if (!hwcNodePtr) {
3490 continue;
3491 }
3492 if (!hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled()) {
3493 hwcRects.push_back(hwcNodePtr->GetDstRect());
3494 } else if (hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled() &&
3495 hwcRects.size() != 0) {
3496 continue;
3497 } else {
3498 hwcNodePtr->SetHardwareForcedDisabledState(true);
3499 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by hwc node backgound alpha",
3500 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
3501 }
3502 }
3503 }
3504
3505 bool RSUniRenderVisitor::IsNodeAboveInsideOfNodeBelow(const RectI& rectAbove, std::list<RectI>& hwcNodeRectList)
3506 {
3507 for (auto rectBelow: hwcNodeRectList) {
3508 if (rectAbove.IsInsideOf(rectBelow)) {
3509 return true;
3510 }
3511 }
3512 return false;
3513 }
3514
3515 void RSUniRenderVisitor::CalcHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode>& node,
3516 const RectI& filterRect, NodeId filterNodeId, bool isReverseOrder, int32_t filterZorder)
3517 {
3518 if (!node) {
3519 return;
3520 }
3521 if (filterZorder != 0 && node->zOrderForCalcHwcNodeEnableByFilter_ != 0 &&
3522 node->zOrderForCalcHwcNodeEnableByFilter_ > filterZorder) {
3523 return;
3524 }
3525 auto& geoPtr = node->GetRenderProperties().GetBoundsGeometry();
3526 if (geoPtr == nullptr) {
3527 return;
3528 }
3529 auto bound = geoPtr->GetAbsRect();
3530 bool isIntersect = !bound.IntersectRect(filterRect).IsEmpty();
3531 if (isIntersect) {
3532 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by filter rect, filterId:%" PRIu64,
3533 node->GetName().c_str(), node->GetId(), filterNodeId);
3534 #ifdef HIPERF_TRACE_ENABLE
3535 RS_LOGW("hiperf_surface: name:%s disabled by filter rect, surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]",
3536 node->GetName().c_str(),
3537 node->GetSrcRect().GetLeft(), node->GetSrcRect().GetRight(),
3538 node->GetSrcRect().GetTop(), node->GetSrcRect().GetBottom(),
3539 node->GetSrcRect().GetLeft(), node->GetSrcRect().GetRight(),
3540 node->GetSrcRect().GetTop(), node->GetSrcRect().GetBottom());
3541 #endif
3542 node->SetIsHwcPendingDisabled(true);
3543 node->SetHardwareForcedDisabledState(true);
3544 node->SetHardWareDisabledByReverse(isReverseOrder);
3545 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
3546 HwcDisabledReasons::DISABLED_BY_FLITER_RECT, node->GetName());
3547 }
3548 }
3549
3550 void RSUniRenderVisitor::UpdateHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode>& node,
3551 const RectI& filterRect, NodeId filterNodeId, bool isReverseOrder, int32_t filterZorder)
3552 {
3553 if (filterRect.IsEmpty()) {
3554 return;
3555 }
3556 if (!node) {
3557 const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
3558 if (selfDrawingNodes.empty()) {
3559 return;
3560 }
3561 for (auto hwcNode : selfDrawingNodes) {
3562 CalcHwcNodeEnableByFilterRect(hwcNode, filterRect, filterNodeId, isReverseOrder, filterZorder);
3563 }
3564 } else {
3565 const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
3566 if (hwcNodes.empty()) {
3567 return;
3568 }
3569 for (auto hwcNode : hwcNodes) {
3570 auto hwcNodePtr = hwcNode.lock();
3571 CalcHwcNodeEnableByFilterRect(hwcNodePtr, filterRect, filterNodeId, isReverseOrder, filterZorder);
3572 }
3573 }
3574 }
3575
3576 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode>& node)
3577 {
3578 auto cleanFilter = transparentHwcCleanFilter_.find(node->GetId());
3579 bool cleanFilterFound = (cleanFilter != transparentHwcCleanFilter_.end());
3580 auto dirtyFilter = transparentHwcDirtyFilter_.find(node->GetId());
3581 bool dirtyFilterFound = (dirtyFilter != transparentHwcDirtyFilter_.end());
3582 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
3583 for (auto it = curMainAndLeashSurfaces.rbegin(); it != curMainAndLeashSurfaces.rend(); ++it) {
3584 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
3585 if (surfaceNode == nullptr) {
3586 continue;
3587 }
3588 if (surfaceNode->GetId() == node->GetId()) {
3589 return;
3590 }
3591 const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
3592 if (hwcNodes.empty()) {
3593 continue;
3594 }
3595 for (auto hwcNode : hwcNodes) {
3596 auto hwcNodePtr = hwcNode.lock();
3597 if (!hwcNodePtr || hwcNodePtr->IsHardwareForcedDisabled() ||
3598 !hwcNodePtr->GetRenderProperties().GetBoundsGeometry()) {
3599 continue;
3600 }
3601 if (cleanFilterFound) {
3602 UpdateHwcNodeEnableByGlobalCleanFilter(cleanFilter->second, *hwcNodePtr);
3603 if (hwcNodePtr->IsHardwareForcedDisabled()) {
3604 continue;
3605 }
3606 }
3607 if (!dirtyFilterFound) {
3608 continue;
3609 }
3610 for (auto filter = dirtyFilter->second.begin(); filter != dirtyFilter->second.end(); ++filter) {
3611 if (hwcNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(filter->second)) {
3612 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentDirtyFilter, "
3613 "filterId:%" PRIu64, hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(), filter->first);
3614 #ifdef HIPERF_TRACE_ENABLE
3615 RS_LOGW("hiperf_surface: name:%s disabled by transparentDirtyFilter, "
3616 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", hwcNodePtr->GetName().c_str(),
3617 hwcNodePtr->GetSrcRect().GetLeft(), hwcNodePtr->GetSrcRect().GetRight(),
3618 hwcNodePtr->GetSrcRect().GetTop(), hwcNodePtr->GetSrcRect().GetBottom(),
3619 hwcNodePtr->GetSrcRect().GetLeft(), hwcNodePtr->GetSrcRect().GetRight(),
3620 hwcNodePtr->GetSrcRect().GetTop(), hwcNodePtr->GetSrcRect().GetBottom());
3621 #endif
3622 hwcNodePtr->SetHardwareForcedDisabledState(true);
3623 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
3624 HwcDisabledReasons::DISABLED_BY_TRANSPARENT_DIRTY_FLITER, hwcNodePtr->GetName());
3625 break;
3626 }
3627 }
3628 }
3629 }
3630 }
3631
3632 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalCleanFilter(
3633 const std::vector<std::pair<NodeId, RectI>>& cleanFilter, RSSurfaceRenderNode& hwcNodePtr)
3634 {
3635 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3636 bool intersectedWithAIBar = false;
3637 bool checkDrawAIBar = false;
3638 for (auto filter = cleanFilter.begin(); filter != cleanFilter.end(); ++filter) {
3639 auto geo = hwcNodePtr.GetRenderProperties().GetBoundsGeometry();
3640 if (!geo) {
3641 return;
3642 }
3643 if (!geo->GetAbsRect().IntersectRect(filter->second).IsEmpty()) {
3644 auto& rendernode = nodeMap.GetRenderNode<RSRenderNode>(filter->first);
3645 if (rendernode == nullptr) {
3646 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: rendernode is null");
3647 continue;
3648 }
3649
3650 if (rendernode->IsAIBarFilter()) {
3651 intersectedWithAIBar = true;
3652 if (rendernode->IsAIBarFilterCacheValid()) {
3653 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: skip intersection for using cache");
3654 continue;
3655 } else if (RSSystemProperties::GetHveFilterEnabled()) {
3656 checkDrawAIBar = true;
3657 continue;
3658 }
3659 }
3660 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentCleanFilter, filterId:"
3661 "%" PRIu64, hwcNodePtr.GetName().c_str(), hwcNodePtr.GetId(), filter->first);
3662 #ifdef HIPERF_TRACE_ENABLE
3663 RS_LOGW("hiperf_surface: name:%s disabled by transparentCleanFilter, "
3664 "surfaceRect: [%d, %d, %d, %d]->[%d, %d, %d, %d]", hwcNodePtr.GetName().c_str(),
3665 hwcNodePtr.GetSrcRect().GetLeft(), hwcNodePtr.GetSrcRect().GetRight(),
3666 hwcNodePtr.GetSrcRect().GetTop(), hwcNodePtr.GetSrcRect().GetBottom(),
3667 hwcNodePtr.GetSrcRect().GetLeft(), hwcNodePtr.GetSrcRect().GetRight(),
3668 hwcNodePtr.GetSrcRect().GetTop(), hwcNodePtr.GetSrcRect().GetBottom());
3669 #endif
3670 hwcNodePtr.SetHardwareForcedDisabledState(true);
3671 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr.GetId(),
3672 HwcDisabledReasons::DISABLED_BY_TRANSPARENT_CLEAN_FLITER, hwcNodePtr.GetName());
3673 break;
3674 }
3675 }
3676 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64", checkDrawAIBar:%d, intersectedWithAIBar:%d",
3677 hwcNodePtr.GetName().c_str(), hwcNodePtr.GetId(), checkDrawAIBar, intersectedWithAIBar);
3678 if (checkDrawAIBar) {
3679 hwcNodePtr.SetHardwareNeedMakeImage(checkDrawAIBar);
3680 }
3681 if (intersectedWithAIBar) {
3682 hwcNodePtr.SetIntersectWithAIBar(intersectedWithAIBar);
3683 }
3684 }
3685
3686 inline static void ResetSubSurfaceNodesCalState(
3687 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>>& subSurfaceNodes)
3688 {
3689 for (auto& [id, node] : subSurfaceNodes) {
3690 auto subSurfaceNodePtr = node.lock();
3691 if (!subSurfaceNodePtr) {
3692 continue;
3693 }
3694 subSurfaceNodePtr->SetCalcRectInPrepare(false);
3695 }
3696 }
3697
3698 void RSUniRenderVisitor::UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3699 {
3700 if (!curSurfaceNode_ || !curSurfaceDirtyManager_) {
3701 return;
3702 }
3703 auto rootGeo = rootNode.GetRenderProperties().GetBoundsGeometry();
3704 if (!rootGeo) {
3705 return;
3706 }
3707
3708 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
3709 curSurfaceNode_->GetAllSubSurfaceNodes(allSubSurfaceNodes);
3710 for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
3711 auto subSurfaceNodePtr = subSurfaceNode.lock();
3712 Drawing::Matrix absMatrix;
3713 if (!subSurfaceNodePtr || subSurfaceNodePtr->GetCalcRectInPrepare() ||
3714 !subSurfaceNodePtr->GetAbsMatrixReverse(rootNode, absMatrix)) {
3715 continue;
3716 }
3717
3718 Drawing::RectF absDrawRect;
3719 absMatrix.MapRect(absDrawRect, RSPropertiesPainter::Rect2DrawingRect(subSurfaceNodePtr->GetSelfDrawRect()));
3720 RectI subSurfaceRect = RectI(absDrawRect.GetLeft(), absDrawRect.GetTop(),
3721 absDrawRect.GetWidth(), absDrawRect.GetHeight());
3722
3723 subSurfaceNodePtr->SetOldDirtyInSurface(subSurfaceRect.IntersectRect(prepareClipRect_));
3724 UpdateNodeVisibleRegion(*subSurfaceNodePtr);
3725 UpdateDstRect(*subSurfaceNodePtr, subSurfaceRect, prepareClipRect_);
3726 subSurfaceNodePtr->SetCalcRectInPrepare(true);
3727 if (subSurfaceNodePtr->IsLeashOrMainWindow()) {
3728 curMainAndLeashWindowNodesIds_.push(subSurfaceNodePtr->GetId());
3729 curDisplayNode_->RecordMainAndLeashSurfaces(subSurfaceNodePtr);
3730 curDisplayNode_->UpdateSurfaceNodePos(
3731 subSurfaceNodePtr->GetId(), subSurfaceNodePtr->GetOldDirtyInSurface());
3732 if (auto subSurfaceDirtyManager = subSurfaceNodePtr->GetDirtyManager()) {
3733 subSurfaceDirtyManager->MergeDirtyRect(subSurfaceNodePtr->GetOldDirtyInSurface().IntersectRect(
3734 curSurfaceDirtyManager_->GetCurrentFrameDirtyRegion()));
3735 }
3736 CollectOcclusionInfoForWMS(*subSurfaceNodePtr);
3737 auto& rateReduceManager = RSMainThread::Instance()->GetRSVsyncRateReduceManager();
3738 rateReduceManager.PushWindowNodeId(subSurfaceNodePtr->GetId());
3739 rateReduceManager.CollectSurfaceVsyncInfo(screenInfo_, *subSurfaceNodePtr);
3740 subSurfaceNodePtr->UpdateRenderParams();
3741 }
3742 }
3743 ResetSubSurfaceNodesCalState(allSubSurfaceNodes);
3744 }
3745
3746 RectI RSUniRenderVisitor::GetVisibleEffectDirty(RSRenderNode& node) const
3747 {
3748 RectI childEffectRect;
3749 auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3750 for (auto& nodeId : node.GetVisibleEffectChild()) {
3751 if (auto& subnode = nodeMap.GetRenderNode<RSRenderNode>(nodeId)) {
3752 childEffectRect = childEffectRect.JoinRect(subnode->GetOldDirtyInSurface());
3753 }
3754 }
3755 return childEffectRect;
3756 }
3757
3758 RectI RSUniRenderVisitor::GetHwcVisibleEffectDirty(RSRenderNode& node, const RectI globalFilterRect) const
3759 {
3760 RectI childEffectRect;
3761 if (!globalFilterRect.IsEmpty()) {
3762 childEffectRect = globalFilterRect.JoinRect(node.GetFilterRect());
3763 }
3764 return childEffectRect;
3765 }
3766
3767 void RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty(RSRenderNode& node,
3768 RSDirtyRegionManager& dirtyManager, const RectI& globalFilterRect, const RectI& globalHwcFilterRect)
3769 {
3770 bool isNodeAddedToTransparentCleanFilters = false;
3771 if (curSurfaceNode_) {
3772 bool isIntersect = dirtyManager.GetCurrentFrameDirtyRegion().Intersect(globalFilterRect);
3773 if (isIntersect) {
3774 dirtyManager.MergeDirtyRect(globalHwcFilterRect);
3775 } else {
3776 curSurfaceNoBelowDirtyFilter_.insert({node.GetId(), globalHwcFilterRect});
3777 }
3778 if (node.GetRenderProperties().GetFilter()) {
3779 node.UpdateFilterCacheWithBelowDirty(dirtyManager, true);
3780 }
3781 node.UpdateFilterCacheWithSelfDirty();
3782 if (curSurfaceNode_->IsTransparent()) {
3783 if (!isIntersect || (isIntersect && (node.GetRenderProperties().GetBackgroundFilter() ||
3784 node.GetRenderProperties().GetNeedDrawBehindWindow()) && !node.IsBackgroundInAppOrNodeSelfDirty())) {
3785 // record nodes which has transparent clean filter
3786 RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInfoAndUpdateDirty::surfaceNode:%s, add node[%lld] to "
3787 "transparentCleanFilter", curSurfaceNode_->GetName().c_str(), node.GetId());
3788 transparentCleanFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalHwcFilterRect});
3789 transparentHwcCleanFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalHwcFilterRect});
3790 isNodeAddedToTransparentCleanFilters = true;
3791 }
3792 if (isIntersect) {
3793 transparentDirtyFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalHwcFilterRect});
3794 transparentHwcDirtyFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalHwcFilterRect});
3795 RS_LOGD("RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty global merge transparentDirtyFilter "
3796 "%{public}s, global dirty %{public}s, add rect %{public}s", curSurfaceNode_->GetName().c_str(),
3797 curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
3798 globalHwcFilterRect.ToString().c_str());
3799 curDisplayDirtyManager_->MergeDirtyRect(globalHwcFilterRect);
3800 }
3801 } else {
3802 // record surface nodes and nodes in surface which has clean filter
3803 globalFilter_.insert({node.GetId(), globalHwcFilterRect});
3804 }
3805 } else {
3806 // record container nodes which need filter
3807 containerFilter_.insert({node.GetId(), globalHwcFilterRect});
3808 }
3809 if (curSurfaceNode_ && !isNodeAddedToTransparentCleanFilters) {
3810 node.PostPrepareForBlurFilterNode(dirtyManager, needRequestNextVsync_);
3811 RsFrameBlurPredict::GetInstance().PredictDrawLargeAreaBlur(node);
3812 }
3813 }
3814
3815 void RSUniRenderVisitor::UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode& node)
3816 {
3817 if (!node.IsLeashWindow()) {
3818 return;
3819 }
3820 auto& property = node.GetMutableRenderProperties();
3821 auto& geoPtr = (property.GetBoundsGeometry());
3822 if (geoPtr == nullptr) {
3823 return;
3824 }
3825 auto absMatrix = geoPtr->GetAbsMatrix();
3826 bool isScale = false;
3827 if (RSUifirstManager::Instance().GetUiFirstType() == UiFirstCcmType::MULTI) {
3828 isScale = (!ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_X), 1.f, EPSILON_SCALE) ||
3829 !ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_Y), 1.f, EPSILON_SCALE));
3830 } else {
3831 bool getMinMaxScales = false;
3832 // scaleFactors[0]-minimum scaling factor, scaleFactors[1]-maximum scaling factor
3833 Drawing::scalar scaleFactors[2];
3834 getMinMaxScales = absMatrix.GetMinMaxScales(scaleFactors);
3835 if (getMinMaxScales) {
3836 isScale = !ROSEN_EQ(scaleFactors[0], 1.f, EPSILON_SCALE) || !ROSEN_EQ(scaleFactors[1], 1.f, EPSILON_SCALE);
3837 }
3838 if (!getMinMaxScales) {
3839 RS_LOGD("getMinMaxScales fail, node:%{public}s %{public}" PRIu64 "", node.GetName().c_str(), node.GetId());
3840 const auto& dstRect = node.GetDstRect();
3841 float dstRectWidth = dstRect.GetWidth();
3842 float dstRectHeight = dstRect.GetHeight();
3843 float boundsWidth = property.GetBoundsWidth();
3844 float boundsHeight = property.GetBoundsHeight();
3845 isScale =
3846 !ROSEN_EQ(std::min(dstRectWidth, dstRectHeight), std::min(boundsWidth, boundsHeight), EPSILON_SCALE) ||
3847 !ROSEN_EQ(std::max(dstRectWidth, dstRectHeight), std::max(boundsWidth, boundsHeight), EPSILON_SCALE);
3848 }
3849 }
3850 node.SetIsScaleInPreFrame(node.IsScale());
3851 node.SetIsScale(isScale);
3852 }
3853
3854 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
3855 {
3856 RS_TRACE_NAME_FMT("RSUniRender::PrepareRootRenderNode:node[%" PRIu64 "] pid[%d] subTreeDirty[%d]",
3857 node.GetId(), ExtractPid(node.GetId()), node.IsSubTreeDirty());
3858 bool dirtyFlag = dirtyFlag_;
3859 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
3860 auto prepareClipRect = prepareClipRect_;
3861
3862 auto nodeParent = (node.GetParent().lock());
3863 const auto& property = node.GetRenderProperties();
3864 bool geoDirty = property.IsGeoDirty();
3865 auto& geoPtr = (property.GetBoundsGeometry());
3866 auto prevAlpha = curAlpha_;
3867 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
3868
3869 if (curSurfaceDirtyManager_ == nullptr) {
3870 RS_LOGE("RSUniRenderVisitor::PrepareRootRenderNode curSurfaceDirtyManager is nullptr");
3871 return;
3872 }
3873 dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
3874 *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
3875
3876 if (nodeParent == curSurfaceNode_) {
3877 const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
3878 const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
3879 Drawing::Matrix gravityMatrix;
3880 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
3881 RectF { 0.0f, 0.0f, boundsRect_.GetWidth(), boundsRect_.GetHeight() },
3882 rootWidth, rootHeight, gravityMatrix);
3883 // Only Apply gravityMatrix when rootNode is dirty
3884 if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
3885 geoPtr->ConcatMatrix(gravityMatrix);
3886 }
3887 }
3888
3889 if (geoPtr != nullptr) {
3890 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3891 }
3892
3893 node.EnableWindowKeyFrame(false);
3894
3895 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
3896 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
3897 node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
3898 PostPrepare(node, !isSubTreeNeedPrepare);
3899
3900 curAlpha_ = prevAlpha;
3901 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3902 dirtyFlag_ = dirtyFlag;
3903 prepareClipRect_ = prepareClipRect;
3904 }
3905
3906 void RSUniRenderVisitor::SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams>& renderThreadParams)
3907 {
3908 if (!renderThreadParams) {
3909 RS_LOGE("RSUniRenderVisitor::SetUniRenderThreadParam renderThreadParams is nullptr");
3910 return;
3911 }
3912 renderThreadParams->isPartialRenderEnabled_ = isPartialRenderEnabled_;
3913 renderThreadParams->isRegionDebugEnabled_ = isRegionDebugEnabled_;
3914 renderThreadParams->isDirtyRegionDfxEnabled_ = isDirtyRegionDfxEnabled_;
3915 renderThreadParams->isDisplayDirtyDfxEnabled_ = isDisplayDirtyDfxEnabled_;
3916 renderThreadParams->isOpaqueRegionDfxEnabled_ = isOpaqueRegionDfxEnabled_;
3917 renderThreadParams->isVisibleRegionDfxEnabled_ = isVisibleRegionDfxEnabled_;
3918 renderThreadParams->isAllSurfaceVisibleDebugEnabled_ = isAllSurfaceVisibleDebugEnabled_;
3919 renderThreadParams->isTargetDirtyRegionDfxEnabled_ = isTargetDirtyRegionDfxEnabled_;
3920 renderThreadParams->dirtyRegionDebugType_ = dirtyRegionDebugType_;
3921 renderThreadParams->isOpDropped_ = isOpDropped_;
3922 renderThreadParams->isDirtyAlignEnabled_ = isDirtyAlignEnabled_;
3923 renderThreadParams->isStencilPixelOcclusionCullingEnabled_ = isStencilPixelOcclusionCullingEnabled_;
3924 renderThreadParams->isCrossNodeOffscreenOn_ = isCrossNodeOffscreenOn_;
3925 renderThreadParams->isUIFirstDebugEnable_ = isUIFirstDebugEnable_;
3926 renderThreadParams->dfxTargetSurfaceNames_ = std::move(dfxTargetSurfaceNames_);
3927 renderThreadParams->isVirtualDirtyEnabled_ = isVirtualDirtyEnabled_;
3928 renderThreadParams->isVirtualDirtyDfxEnabled_ = isVirtualDirtyDfxEnabled_;
3929 renderThreadParams->isExpandScreenDirtyEnabled_ = isExpandScreenDirtyEnabled_;
3930 renderThreadParams->advancedDirtyType_ = advancedDirtyType_;
3931 renderThreadParams->hasDisplayHdrOn_ = hasDisplayHdrOn_;
3932 renderThreadParams->hasMirrorDisplay_ = hasMirrorDisplay_;
3933 renderThreadParams->isForceCommitLayer_ |=
3934 RSPointerWindowManager::Instance().IsNeedForceCommitByPointer();
3935 }
3936
3937 void RSUniRenderVisitor::SendRcdMessage(RSDisplayRenderNode& node)
3938 {
3939 if (RoundCornerDisplayManager::CheckRcdRenderEnable(screenInfo_) &&
3940 RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
3941 using rcd_msg = RSSingleton<RsMessageBus>;
3942 uint32_t left = 0; // render region
3943 uint32_t top = 0;
3944 uint32_t width = screenInfo_.width;
3945 uint32_t height = screenInfo_.height;
3946 if (!screenInfo_.activeRect.IsEmpty()) {
3947 left = static_cast<uint32_t>(std::max(0, screenInfo_.activeRect.GetLeft()));
3948 top = static_cast<uint32_t>(std::max(0, screenInfo_.activeRect.GetTop()));
3949 width = static_cast<uint32_t>(std::max(0, screenInfo_.activeRect.GetWidth()));
3950 height = static_cast<uint32_t>(std::max(0, screenInfo_.activeRect.GetHeight()));
3951 }
3952 rcd_msg::GetInstance().SendMsg<NodeId, uint32_t, uint32_t, uint32_t, uint32_t>(TOPIC_RCD_DISPLAY_SIZE,
3953 node.GetId(), left, top, width, height);
3954 rcd_msg::GetInstance().SendMsg<NodeId, ScreenRotation>(TOPIC_RCD_DISPLAY_ROTATION,
3955 node.GetId(), node.GetScreenRotation());
3956 rcd_msg::GetInstance().SendMsg<NodeId, int>(TOPIC_RCD_DISPLAY_NOTCH,
3957 node.GetId(), RSSystemParameters::GetHideNotchStatus());
3958 }
3959 }
3960
3961 void RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode()
3962 {
3963 static auto unpairNode = [](const std::weak_ptr<RSRenderNode>& wptr) {
3964 auto sptr = wptr.lock();
3965 if (sptr == nullptr) {
3966 return;
3967 }
3968 // make sure parent regenerates ChildrenDrawable
3969 auto parent = sptr->GetParent().lock();
3970 if (parent == nullptr) {
3971 return;
3972 }
3973 parent->AddDirtyType(RSModifierType::CHILDREN);
3974 parent->ApplyModifiers();
3975 // avoid changing the paired status or unpairedShareTransitions_
3976 auto param = sptr->GetSharedTransitionParam();
3977 if (param == nullptr) {
3978 ROSEN_LOGE("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: param is null");
3979 return;
3980 }
3981 param->paired_ = false;
3982 SharedTransitionParam::unpairedShareTransitions_.clear();
3983 };
3984 auto unpairedShareTransitions = std::move(SharedTransitionParam::unpairedShareTransitions_);
3985 for (auto& [id, wptr] : unpairedShareTransitions) {
3986 auto sharedTransitionParam = wptr.lock();
3987 // If the unpaired share transition is already deal with, do nothing
3988 if (!sharedTransitionParam) {
3989 continue;
3990 }
3991 sharedTransitionParam->ResetRelation();
3992 if (!sharedTransitionParam->paired_) {
3993 continue;
3994 }
3995 ROSEN_LOGD("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: mark %s as unpaired",
3996 sharedTransitionParam->Dump().c_str());
3997 sharedTransitionParam->paired_ = false;
3998 unpairNode(sharedTransitionParam->inNode_);
3999 unpairNode(sharedTransitionParam->outNode_);
4000 }
4001 }
4002
4003 NodeId RSUniRenderVisitor::FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)
4004 {
4005 if (node == nullptr) {
4006 return INVALID_NODEID;
4007 }
4008 auto nodeParent = node->GetParent().lock();
4009 if (nodeParent == nullptr) {
4010 return INVALID_NODEID;
4011 }
4012 if (nodeParent->GetType() == RSRenderNodeType::DISPLAY_NODE) {
4013 return node->GetId();
4014 } else {
4015 return FindInstanceChildOfDisplay(nodeParent);
4016 }
4017 }
4018
4019 void RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr>& surfaces)
4020 {
4021 // Debug dirtyregion of show current refreshRation
4022 if (RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
4023 if (curDisplayNode_ == nullptr) {
4024 RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate curDisplayNode is nullptr");
4025 return;
4026 }
4027 RectI tempRect = {100, 100, 500, 200}; // setDirtyRegion for RealtimeRefreshRate
4028 bool surfaceNodeSet = false;
4029 bool needMapAbsRect = true;
4030 auto windowContainer = curDisplayNode_->GetWindowContainer();
4031 if (windowContainer) {
4032 if (!ROSEN_EQ(windowContainer->GetRenderProperties().GetScaleX(), 1.0f, EPSILON_SCALE) ||
4033 !ROSEN_EQ(windowContainer->GetRenderProperties().GetScaleY(), 1.0f, EPSILON_SCALE)) {
4034 needMapAbsRect = false;
4035 }
4036 }
4037 for (auto surface : surfaces) {
4038 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surface);
4039 if (surfaceNode == nullptr) {
4040 RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate surfaceNode is nullptr");
4041 continue;
4042 }
4043 if (surfaceNode->GetName().find(RELIABLE_GESTURE_BACK_SURFACE_NAME) != std::string::npos) {
4044 // refresh rate rect for mainwindow
4045 auto& geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
4046 if (!geoPtr) {
4047 break;
4048 }
4049 if (needMapAbsRect) {
4050 tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
4051 }
4052 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
4053 surfaceNodeSet = true;
4054 break;
4055 }
4056 }
4057 if (!surfaceNodeSet) {
4058 auto &geoPtr = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
4059 if (!geoPtr) {
4060 return;
4061 }
4062 if (needMapAbsRect) {
4063 tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
4064 }
4065 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
4066 }
4067 }
4068 }
4069
4070 void RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay() const
4071 {
4072 if (!screenManager_ || !curDisplayNode_) {
4073 RS_LOGE(
4074 "RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay screenmanager or displaynode is nullptr");
4075 return;
4076 }
4077
4078 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
4079 if (screenManager_->GetScreenType(curDisplayNode_->GetScreenId(), screenType) != SUCCESS) {
4080 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay get screen type failed.");
4081 return;
4082 }
4083
4084 if (screenType != EXTERNAL_TYPE_SCREEN) {
4085 return;
4086 }
4087
4088 RectI dirtyRectTop, dirtyRectBottom;
4089 if (RSSingleton<RoundCornerDisplayManager>::GetInstance().HandleRoundCornerDirtyRect(
4090 curDisplayNode_->GetId(), dirtyRectTop, RoundCornerDisplayManager::RCDLayerType::TOP)) {
4091 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay global merge topRcdNode dirty "
4092 "%{public}s, global dirty %{public}s, add rect %{public}s",
4093 std::to_string(curDisplayNode_->GetScreenId()).c_str(),
4094 curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
4095 dirtyRectTop.ToString().c_str());
4096 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRectTop);
4097 }
4098 if (RSSingleton<RoundCornerDisplayManager>::GetInstance().HandleRoundCornerDirtyRect(
4099 curDisplayNode_->GetId(), dirtyRectBottom, RoundCornerDisplayManager::RCDLayerType::BOTTOM)) {
4100 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByRoundCornerDisplay global merge bottomRcdNode dirty "
4101 "%{public}s, global dirty %{public}s, add rect %{public}s",
4102 std::to_string(curDisplayNode_->GetScreenId()).c_str(),
4103 curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
4104 dirtyRectBottom.ToString().c_str());
4105 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRectBottom);
4106 }
4107 }
4108
4109 void RSUniRenderVisitor::CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode& node)
4110 {
4111 bool hasAnim = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
4112 if (!node.IsScale() || hasAnim || curCornerRadius_.IsZero() || curAlpha_ < 1) {
4113 node.SetGpuOverDrawBufferOptimizeNode(false);
4114 return;
4115 }
4116
4117 for (auto& child : *(node.GetChildren())) {
4118 if (!child || !(child->IsInstanceOf<RSSurfaceRenderNode>() &&
4119 RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsLeashOrMainWindow())) {
4120 continue;
4121 }
4122 auto rootNode = child->GetFirstChild();
4123 if (!rootNode) {
4124 break;
4125 }
4126 auto canvasNode = rootNode->GetFirstChild();
4127 if (!canvasNode) {
4128 break;
4129 }
4130 const auto& surfaceProperties = node.GetRenderProperties();
4131 const auto& canvasProperties = canvasNode->GetRenderProperties();
4132 if (canvasProperties.GetAlpha() >= 1
4133 && canvasProperties.GetBackgroundColor().GetAlpha() >= MAX_ALPHA
4134 && canvasProperties.GetFrameWidth() == surfaceProperties.GetFrameWidth()
4135 && canvasProperties.GetFrameHeight() == surfaceProperties.GetFrameHeight()) {
4136 node.SetGpuOverDrawBufferOptimizeNode(true);
4137 node.SetOverDrawBufferNodeCornerRadius(curCornerRadius_);
4138 return;
4139 }
4140 }
4141
4142 node.SetGpuOverDrawBufferOptimizeNode(false);
4143 }
4144
4145 void RSUniRenderVisitor::SetHdrWhenMultiDisplayChange()
4146 {
4147 auto mainThread = RSMainThread::Instance();
4148 if (!mainThread->GetMultiDisplayChange()) {
4149 return;
4150 }
4151 auto isMultiDisplay = mainThread->GetMultiDisplayStatus();
4152 RS_LOGI("RSUniRenderVisitor::SetHdrWhenMultiDisplayChange closeHdrStatus: %{public}d.", isMultiDisplay);
4153 RS_TRACE_NAME_FMT("RSUniRenderVisitor::SetHdrWhenMultiDisplayChange closeHdrStatus: %d", isMultiDisplay);
4154 RSLuminanceControl::Get().ForceCloseHdr(CLOSEHDR_SCENEID::MULTI_DISPLAY, isMultiDisplay);
4155 }
4156
4157 void RSUniRenderVisitor::TryNotifyUIBufferAvailable()
4158 {
4159 for (auto& id : uiBufferAvailableId_) {
4160 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
4161 auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
4162 if (surfaceNode) {
4163 surfaceNode->NotifyUIBufferAvailable();
4164 }
4165 }
4166 uiBufferAvailableId_.clear();
4167 }
4168
4169 void RSUniRenderVisitor::CollectSelfDrawingNodeRectInfo(RSSurfaceRenderNode& node)
4170 {
4171 auto& monitor = SelfDrawingNodeMonitor::GetInstance();
4172 if (!monitor.IsListeningEnabled()) {
4173 return;
4174 }
4175
4176 if (!node.IsSelfDrawingType()) {
4177 return;
4178 }
4179 auto rect = node.GetRenderProperties().GetBoundsGeometry()->GetAbsRect();
4180 std::string nodeName = node.GetName();
4181 monitor.InsertCurRectMap(node.GetId(), nodeName, rect);
4182 }
4183 } // namespace Rosen
4184 } // namespace OHOS
4185