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/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 "luminance/rs_luminance_control.h"
31 #include "memory/rs_tag_tracker.h"
32 #include "params/rs_display_render_params.h"
33 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
34 #include "pipeline/rs_base_render_node.h"
35 #include "pipeline/rs_base_render_util.h"
36 #include "pipeline/rs_display_render_node.h"
37 #include "pipeline/rs_effect_render_node.h"
38 #include "pipeline/rs_paint_filter_canvas.h"
39 #include "pipeline/rs_realtime_refresh_rate_manager.h"
40 #include "pipeline/rs_root_render_node.h"
41 #include "pipeline/rs_surface_render_node.h"
42 #include "pipeline/rs_uni_render_virtual_processor.h"
43 #include "pipeline/rs_uni_render_util.h"
44 #include "pipeline/rs_uifirst_manager.h"
45 #include "platform/common/rs_log.h"
46 #include "platform/common/rs_system_properties.h"
47 #include "property/rs_properties_painter.h"
48 #include "system/rs_system_parameters.h"
49 #include "hgm_core.h"
50 #include "metadata_helper.h"
51 #include <v1_0/buffer_handle_meta_key_type.h>
52 #include <v1_0/cm_color_space.h>
53
54 #include "pipeline/round_corner_display/rs_round_corner_display_manager.h"
55 #include "pipeline/round_corner_display/rs_message_bus.h"
56
57 #include "rs_profiler.h"
58 #ifdef RS_PROFILER_ENABLED
59 #include "rs_profiler_capture_recorder.h"
60 #endif
61
62 namespace OHOS {
63 namespace Rosen {
64 namespace {
65 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
66 constexpr int MAX_ALPHA = 255;
67 constexpr int TRACE_LEVEL_THREE = 3;
68 constexpr float EPSILON_SCALE = 0.00001f;
69 static const std::string CAPTURE_WINDOW_NAME = "CapsuleWindow";
70 constexpr const char* RELIABLE_GESTURE_BACK_SURFACE_NAME = "SCBGestureBack";
71 constexpr int MIN_OVERLAP = 2;
72 static std::map<NodeId, uint32_t> cacheRenderNodeMap = {};
73 static uint32_t g_cacheReuseTimes = 0;
74 static std::mutex cacheRenderNodeMapMutex;
75
CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)76 bool CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
77 {
78 if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
79 auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
80 const auto& property = rootNode->GetRenderProperties();
81 if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
82 return true;
83 }
84 }
85 return false;
86 }
87
CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)88 bool CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
89 {
90 if (child != nullptr && child->IsInstanceOf<RSCanvasRenderNode>()) {
91 auto canvasRenderNode = child->ReinterpretCastTo<RSCanvasRenderNode>();
92 const auto& property = canvasRenderNode->GetRenderProperties();
93 if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0) {
94 return true;
95 }
96 }
97 return false;
98 }
99
IsFirstFrameReadyToDraw(const RSSurfaceRenderNode & node)100 bool IsFirstFrameReadyToDraw(const RSSurfaceRenderNode& node)
101 {
102 bool result = false;
103 auto sortedChildren = node.GetSortedChildren();
104 if (node.IsScbScreen() || node.IsSCBNode()) {
105 for (const auto& child : *sortedChildren) {
106 result = CheckScbReadyToDraw(child);
107 }
108 return result;
109 }
110 for (auto& child : *sortedChildren) {
111 result = CheckRootNodeReadyToDraw(child);
112 // when appWindow has abilityComponent node
113 if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>()) {
114 for (const auto& surfaceNodeChild : *child->GetSortedChildren()) {
115 result = CheckRootNodeReadyToDraw(surfaceNodeChild);
116 }
117 }
118 }
119 return result;
120 }
121
VisibleDataToString(const VisibleData & val)122 std::string VisibleDataToString(const VisibleData& val)
123 {
124 std::stringstream ss;
125 ss << "VisibleData[name, nodeId, visibleLevel]:";
126 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
127 for (const auto& v : val) {
128 auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(v.first);
129 auto name = surfaceNode ? surfaceNode->GetName() : "";
130 ss << "[" << name << ", " << v.first << ", " << v.second << "], ";
131 }
132 return ss.str();
133 }
134 } // namespace
135
RSUniRenderVisitor()136 RSUniRenderVisitor::RSUniRenderVisitor()
137 : curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
138 {
139 PartialRenderOptionInit();
140 auto mainThread = RSMainThread::Instance();
141 renderEngine_ = mainThread->GetRenderEngine();
142 hasMirrorDisplay_ = mainThread->HasMirrorDisplay();
143 // when occlusion enabled is false, subTree do not skip, but not influence visible region
144 isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
145 isDrawingCacheEnabled_ = RSSystemParameters::GetDrawingCacheEnabled();
146 #ifdef DDGR_ENABLE_FEATURE_OPINC
147 autoCacheEnable_ = RSSystemProperties::IsDdgrOpincEnable();
148 #endif
149 RSTagTracker::UpdateReleaseResourceEnabled(RSSystemProperties::GetReleaseResourceEnabled());
150 isScreenRotationAnimating_ = RSSystemProperties::GetCacheEnabledForRotation();
151 isSkipCanvasNodeOutOfScreen_ = RSSystemParameters::GetSkipCanvasNodeOutofScreenEnabled();
152 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
153 if (renderEngine_ && renderEngine_->GetRenderContext()) {
154 auto subThreadManager = RSSubThreadManager::Instance();
155 subThreadManager->Start(renderEngine_->GetRenderContext().get());
156 }
157 #endif
158 isUIFirstDebugEnable_ = RSSystemProperties::GetUIFirstDebugEnabled();
159 isPrevalidateHwcNodeEnable_ = RSSystemParameters::GetPrevalidateHwcNodeEnabled() &&
160 RSUniHwcPrevalidateUtil::GetInstance().IsLoadSuccess();
161 }
162
PartialRenderOptionInit()163 void RSUniRenderVisitor::PartialRenderOptionInit()
164 {
165 partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
166 isPartialRenderEnabled_ = (partialRenderType_ != PartialRenderType::DISABLED);
167 isCompleteRenderEnabled_ = (partialRenderType_ == PartialRenderType::SET_DAMAGE_BUT_COMPLETE_RENDER);
168 dirtyRegionDebugType_ = RSSystemProperties::GetDirtyRegionDebugType();
169 surfaceRegionDebugType_ = RSSystemProperties::GetSurfaceRegionDfxType();
170 isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_) &&
171 (surfaceRegionDebugType_ == SurfaceRegionDebugType::DISABLED);
172 isRegionDebugEnabled_ = (dirtyRegionDebugType_ != DirtyRegionDebugType::DISABLED) ||
173 (surfaceRegionDebugType_ != SurfaceRegionDebugType::DISABLED) || (dfxTargetSurfaceNames_.size() > 0);
174 isVisibleRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::VISIBLE_REGION);
175 isOpaqueRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::OPAQUE_REGION);
176 isAllSurfaceVisibleDebugEnabled_ = RSSystemProperties::GetAllSurfaceVisibleDebugEnabled();
177 isDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
178 (dirtyRegionDebugType_ == DirtyRegionDebugType::EGL_DAMAGE);
179 isDisplayDirtyDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
180 (dirtyRegionDebugType_ == DirtyRegionDebugType::DISPLAY_DIRTY);
181 isCanvasNodeSkipDfxEnabled_ = (dirtyRegionDebugType_ == DirtyRegionDebugType::CANVAS_NODE_SKIP_RECT);
182 isOpDropped_ = isPartialRenderEnabled_ &&
183 (partialRenderType_ != PartialRenderType::SET_DAMAGE) && !isRegionDebugEnabled_;
184 isVirtualDirtyDfxEnabled_ = RSSystemProperties::GetVirtualDirtyDebugEnabled();
185 isVirtualDirtyEnabled_ = RSSystemProperties::GetVirtualDirtyEnabled() &&
186 (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL) && !isRegionDebugEnabled_;
187 isExpandScreenDirtyEnabled_ = RSSystemProperties::GetExpandScreenDirtyEnabled();
188 }
189
RSUniRenderVisitor(const RSUniRenderVisitor & visitor)190 RSUniRenderVisitor::RSUniRenderVisitor(const RSUniRenderVisitor& visitor) : RSUniRenderVisitor()
191 {
192 currentVisitDisplay_ = visitor.currentVisitDisplay_;
193 screenInfo_ = visitor.screenInfo_;
194 displayHasSecSurface_ = visitor.displayHasSecSurface_;
195 displayHasSkipSurface_ = visitor.displayHasSkipSurface_;
196 displayHasSnapshotSkipSurface_ = visitor.displayHasSnapshotSkipSurface_;
197 displayHasProtectedSurface_ = visitor.displayHasProtectedSurface_;
198 displaySpecailSurfaceChanged_ = visitor.displaySpecailSurfaceChanged_;
199 hasCaptureWindow_ = visitor.hasCaptureWindow_;
200 parentSurfaceNodeMatrix_ = visitor.parentSurfaceNodeMatrix_;
201 curAlpha_ = visitor.curAlpha_;
202 dirtyFlag_ = visitor.dirtyFlag_;
203 curDisplayNode_ = visitor.curDisplayNode_;
204 currentFocusedNodeId_ = visitor.currentFocusedNodeId_;
205 prepareClipRect_ = visitor.prepareClipRect_;
206 isOpDropped_ = visitor.isOpDropped_;
207 isPartialRenderEnabled_ = visitor.isPartialRenderEnabled_;
208 isAllSurfaceVisibleDebugEnabled_ = visitor.isAllSurfaceVisibleDebugEnabled_;
209 isHardwareForcedDisabled_ = visitor.isHardwareForcedDisabled_;
210 doAnimate_ = visitor.doAnimate_;
211 isDirty_ = visitor.isDirty_;
212 }
213
~RSUniRenderVisitor()214 RSUniRenderVisitor::~RSUniRenderVisitor() {}
215
MergeRemovedChildDirtyRegion(RSRenderNode & node,bool needMap)216 void RSUniRenderVisitor::MergeRemovedChildDirtyRegion(RSRenderNode& node, bool needMap)
217 {
218 if (!node.HasRemovedChild()) {
219 return;
220 }
221 RectI dirtyRect = node.GetChildrenRect();
222 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
223 if (dirtyManager == nullptr || dirtyRect.IsEmpty()) {
224 node.ResetHasRemovedChild();
225 return;
226 }
227
228 // [planning] merge removed child's rect instead
229 if (needMap) {
230 if (auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry()) {
231 dirtyRect = geoPtr->MapAbsRect(dirtyRect.ConvertTo<float>());
232 }
233 if (!node.HasChildrenOutOfRect()) {
234 dirtyRect = dirtyRect.IntersectRect(node.GetOldClipRect());
235 }
236 } else {
237 dirtyRect = prepareClipRect_.IntersectRect(node.GetChildrenRect());
238 }
239 dirtyManager->MergeDirtyRect(dirtyRect);
240 RS_OPTIONAL_TRACE_NAME_FMT("MergeRemovedChildDirtyRegion NodeId:%" PRIu64 ", dirty rect:%s",
241 node.GetId(), dirtyRect.ToString().c_str());
242 if (dirtyManager->IsTargetForDfx()) {
243 // since childRect includes multiple rects, defaultly marked as canvas_node
244 dirtyManager->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
245 DirtyRegionType::REMOVE_CHILD_RECT, dirtyRect);
246 }
247 node.ResetHasRemovedChild();
248 }
249
CheckColorSpace(RSSurfaceRenderNode & node)250 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
251 {
252 // currently, P3 is the only supported wide color gamut, this may be modified later.
253 if (node.IsAppWindow() && node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
254 newColorSpace_ = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
255 RS_LOGD("RSUniRenderVisitor::CheckColorSpace: node(%{public}s) set new colorgamut %{public}d",
256 node.GetName().c_str(), newColorSpace_);
257 }
258 }
259
CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode & node)260 void RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode& node)
261 {
262 if (!node.IsOnTheTree()) {
263 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is not on the tree",
264 node.GetName().c_str());
265 return;
266 }
267 if (!node.IsHardwareForcedDisabled()) {
268 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is hardware-enabled",
269 node.GetName().c_str());
270 return;
271 }
272 // currently, P3 is the only supported wide color gamut, this may be modified later.
273 node.UpdateColorSpaceWithMetadata();
274 if (node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
275 newColorSpace_ = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
276 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) set new colorgamut %{public}d",
277 node.GetName().c_str(), newColorSpace_);
278 }
279 }
280
UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode & node)281 void RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode& node)
282 {
283 const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
284 for (const auto& selfDrawingNode : selfDrawingNodes) {
285 if (newColorSpace_ == GRAPHIC_COLOR_GAMUT_DISPLAY_P3) {
286 RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc: newColorSpace is already DISPLAY_P3.");
287 return;
288 }
289 if (!selfDrawingNode || !selfDrawingNode->GetAncestorDisplayNode().lock()) {
290 RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc selfDrawingNode or ancestorNode is nullptr");
291 continue;
292 }
293 auto ancestor = selfDrawingNode->GetAncestorDisplayNode().lock()->ReinterpretCastTo<RSDisplayRenderNode>();
294 if (ancestor != nullptr && node.GetId() == ancestor->GetId()) {
295 CheckColorSpaceWithSelfDrawingNode(*selfDrawingNode);
296 }
297 }
298 }
299
HandleColorGamuts(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)300 void RSUniRenderVisitor::HandleColorGamuts(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
301 {
302 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
303 if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
304 RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen type failed.");
305 return;
306 }
307
308 if (screenType == VIRTUAL_TYPE_SCREEN) {
309 ScreenColorGamut screenColorGamut;
310 if (screenManager->GetScreenColorGamut(node.GetScreenId(), screenColorGamut) != SUCCESS) {
311 RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen color gamut failed.");
312 return;
313 }
314 newColorSpace_ = static_cast<GraphicColorGamut>(screenColorGamut);
315 }
316
317 node.SetColorSpace(newColorSpace_);
318 newColorSpace_ = GRAPHIC_COLOR_GAMUT_SRGB;
319 }
320
CheckPixelFormat(RSSurfaceRenderNode & node)321 void RSUniRenderVisitor::CheckPixelFormat(RSSurfaceRenderNode& node)
322 {
323 if (node.GetHDRPresent()) {
324 RS_LOGD("SetHDRPresent true, surfaceNode: %{public}" PRIu64 "", node.GetId());
325 hasUniRenderHdrSurface_ = true;
326 }
327 if (hasFingerprint_) {
328 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat hasFingerprint is true.");
329 return;
330 }
331 if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
332 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat node(%{public}s) did not have buffer.", node.GetName().c_str());
333 return;
334 }
335
336 const sptr<SurfaceBuffer>& buffer = node.GetRSSurfaceHandler()->GetBuffer();
337
338 if (node.GetFingerprint()) {
339 hasFingerprint_ = true;
340 newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_1010102;
341 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat newPixelFormat_ is set 1010102 for fingerprint.");
342 return;
343 }
344
345 auto bufferPixelFormat = buffer->GetFormat();
346 if ((bufferPixelFormat == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
347 bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCBCR_P010 ||
348 bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCRCB_P010) && !IsHardwareComposerEnabled()) {
349 newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_1010102;
350 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat pixelformat is set to 1010102 for 10bit buffer");
351 }
352 }
353
HandlePixelFormat(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)354 void RSUniRenderVisitor::HandlePixelFormat(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
355 {
356 if (!RSSystemProperties::GetHDRImageEnable()) {
357 hasUniRenderHdrSurface_ = false;
358 }
359 auto stagingDisplayParams = static_cast<RSDisplayRenderParams*>(node.GetStagingRenderParams().get());
360 if (!stagingDisplayParams) {
361 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get StagingRenderParams failed.");
362 return;
363 }
364 SetHdrWhenMultiDisplayChangeInPC();
365 ScreenId screenId = stagingDisplayParams->GetScreenId();
366 RSLuminanceControl::Get().SetHdrStatus(screenId, hasUniRenderHdrSurface_);
367 bool isHdrOn = RSLuminanceControl::Get().IsHdrOn(screenId);
368 float brightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0);
369 RS_TRACE_NAME_FMT("HDR:%d, in Unirender:%d brightnessRatio:%f", isHdrOn, hasUniRenderHdrSurface_, brightnessRatio);
370 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat HDR isHdrOn:%{public}d hasUniRenderHdrSurface:%{public}d "
371 "brightnessRatio:%{public}f", isHdrOn, hasUniRenderHdrSurface_, brightnessRatio);
372 if (!hasUniRenderHdrSurface_) {
373 isHdrOn = false;
374 }
375 node.SetHDRPresent(isHdrOn);
376 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
377 if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
378 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen type failed.");
379 return;
380 }
381
382 if (screenType == VIRTUAL_TYPE_SCREEN) {
383 if (screenManager->GetPixelFormat(node.GetScreenId(), newPixelFormat_) != SUCCESS) {
384 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen color gamut failed.");
385 }
386 }
387 stagingDisplayParams->SetNewPixelFormat(newPixelFormat_);
388 }
389
ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode & node)390 void RSUniRenderVisitor::ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode& node)
391 {
392 // record current frame mainwindow or leashwindow node
393 if (node.IsMainWindowType() || node.IsLeashWindow()) {
394 curMainAndLeashWindowNodesIds_.push(node.GetId());
395 curDisplayNode_->RecordMainAndLeashSurfaces(node.shared_from_this());
396 }
397 // only reset for instance node
398 if (curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetId()) {
399 return;
400 }
401 if (auto directParent = node.GetParent().lock()) {
402 if (auto parentInstance = directParent->GetInstanceRootNode()) {
403 // in case leashwindow is not directParent
404 auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
405 if (surfaceParent && (surfaceParent->IsLeashWindow() || surfaceParent->IsMainWindowType())) {
406 curSurfaceNode_ = surfaceParent;
407 curSurfaceDirtyManager_ = surfaceParent->GetDirtyManager();
408 filterInGlobal_ = surfaceParent->IsTransparent();
409 return;
410 }
411 curSurfaceNode_ = nullptr;
412 curSurfaceDirtyManager_ = nullptr;
413 filterInGlobal_ = true;
414 }
415 }
416 }
417
IsHardwareComposerEnabled()418 bool RSUniRenderVisitor::IsHardwareComposerEnabled()
419 {
420 return !isHardwareForcedDisabled_;
421 }
422
UpdateSecuritySkipAndProtectedLayersRecord(RSSurfaceRenderNode & node)423 void RSUniRenderVisitor::UpdateSecuritySkipAndProtectedLayersRecord(RSSurfaceRenderNode& node)
424 {
425 if (node.GetHasSecurityLayer()) {
426 displayHasSecSurface_[currentVisitDisplay_] = true;
427 curDisplayNode_->AddSecurityLayer(node.IsLeashWindow() ? node.GetLeashPersistentId() : node.GetId());
428 }
429 if (node.GetHasSkipLayer() && node.GetName().find(CAPTURE_WINDOW_NAME) == std::string::npos) {
430 displayHasSkipSurface_[currentVisitDisplay_] = true;
431 }
432 if (node.GetHasSnapshotSkipLayer()) {
433 displayHasSnapshotSkipSurface_[currentVisitDisplay_] = true;
434 }
435 if (node.GetHasProtectedLayer()) {
436 displayHasProtectedSurface_[currentVisitDisplay_] = true;
437 }
438 if (node.IsSpecialLayerChanged()) {
439 displaySpecailSurfaceChanged_[currentVisitDisplay_] = true;
440 }
441 }
442
UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode & node)443 void RSUniRenderVisitor::UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode& node)
444 {
445 if (!node.IsMainWindowType()) {
446 return;
447 }
448 auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
449 if (!geoPtr) {
450 return;
451 }
452 if (RSUniRenderUtil::GetRotationDegreeFromMatrix(geoPtr->GetAbsMatrix()) % RS_ROTATION_90 != 0) {
453 node.SetIsRotating(true);
454 }
455 }
456
IsSubTreeOccluded(RSRenderNode & node) const457 bool RSUniRenderVisitor::IsSubTreeOccluded(RSRenderNode& node) const
458 {
459 if (!isOcclusionEnabled_) {
460 return false;
461 }
462 // step1. apply occlusion info for surfacenode and skip fully covered subtree
463 if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
464 auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
465 if (surfaceNode.IsMainWindowType()) {
466 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::IsSubTreeOccluded node[%s]"
467 "name:[%s] visibleRegionIsEmpty[%d]",
468 std::to_string(node.GetId()).c_str(), surfaceNode.GetName().c_str(),
469 surfaceNode.GetVisibleRegion().IsEmpty());
470 auto isOccluded = hasMirrorDisplay_ ?
471 surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
472 isOccluded = isOccluded && (!RSUifirstManager::Instance().IsSubTreeNeedPrepareForSnapshot(surfaceNode));
473 if (isOccluded && curSurfaceDirtyManager_) {
474 curSurfaceDirtyManager_->Clear();
475 }
476 surfaceNode.AccmulateDirtyInOcclusion(isOccluded);
477 return isOccluded;
478 }
479 }
480 // step2.1 For partial visible surface, intersected region->rects in surface
481 // step2.2 check if clean subtree in occlusion rects
482 return false;
483 }
484
ResetDisplayDirtyRegion()485 void RSUniRenderVisitor::ResetDisplayDirtyRegion()
486 {
487 if (!curDisplayDirtyManager_) {
488 return;
489 }
490 if (curDisplayNode_ == nullptr) {
491 return;
492 }
493 bool isNeedNotchUpdate = RSSingleton<RoundCornerDisplayManager>::GetInstance().IsNotchNeedUpdate(
494 curDisplayNode_->GetId(), RSSystemParameters::GetHideNotchStatus());
495 bool ret = CheckScreenPowerChange() ||
496 CheckColorFilterChange() ||
497 CheckCurtainScreenUsingStatusChange() ||
498 IsFirstFrameOfPartialRender() ||
499 IsWatermarkFlagChanged() ||
500 zoomStateChange_ ||
501 isCompleteRenderEnabled_ ||
502 CheckLuminanceStatusChange() ||
503 IsFirstFrameOfOverdrawSwitch() ||
504 IsFirstFrameOfDrawingCacheDfxSwitch() ||
505 isNeedNotchUpdate ||
506 curDisplayNode_->HasMirroredDisplayChanged();
507 if (ret) {
508 curDisplayDirtyManager_->ResetDirtyAsSurfaceSize();
509 RS_LOGD("RSUniRenderVisitor::ResetDisplayDirtyRegion on");
510 }
511 }
512
CheckScreenPowerChange() const513 bool RSUniRenderVisitor::CheckScreenPowerChange() const
514 {
515 if (!RSMainThread::Instance()->GetScreenPowerOnChanged()) {
516 return false;
517 }
518 RS_LOGD("RSUniRenderVisitor::CheckScreenPowerChange changed");
519 return true;
520 }
521
CheckCurtainScreenUsingStatusChange() const522 bool RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange() const
523 {
524 if (!RSMainThread::Instance()->IsCurtainScreenUsingStatusChanged()) {
525 return false;
526 }
527 RS_LOGD("RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange changed");
528 return true;
529 }
530
CheckLuminanceStatusChange()531 bool RSUniRenderVisitor::CheckLuminanceStatusChange()
532 {
533 if (!RSMainThread::Instance()->ExchangeLuminanceChangingStatus()) {
534 return false;
535 }
536 RS_LOGD("RSUniRenderVisitor::CheckLuminanceStatusChange changed");
537 return true;
538 }
539
IsFirstFrameOfPartialRender() const540 bool RSUniRenderVisitor::IsFirstFrameOfPartialRender() const
541 {
542 if (!RSMainThread::Instance()->IsFirstFrameOfPartialRender()) {
543 return false;
544 }
545 RS_LOGD("FirstFrameOfPartialRender");
546 return true;
547 }
548
IsFirstFrameOfDrawingCacheDfxSwitch() const549 bool RSUniRenderVisitor::IsFirstFrameOfDrawingCacheDfxSwitch() const
550 {
551 return RSMainThread::Instance()->IsFirstFrameOfDrawingCacheDFXSwitch();
552 }
553
IsFirstFrameOfOverdrawSwitch() const554 bool RSUniRenderVisitor::IsFirstFrameOfOverdrawSwitch() const
555 {
556 if (!RSMainThread::Instance()->IsFirstFrameOfOverdrawSwitch()) {
557 return false;
558 }
559 RS_LOGD("IsFirstFrameOfOverdrawSwitch");
560 return true;
561 }
562
IsWatermarkFlagChanged() const563 bool RSUniRenderVisitor::IsWatermarkFlagChanged() const
564 {
565 if (RSMainThread::Instance()->IsWatermarkFlagChanged()) {
566 RS_LOGD("FirstOrLastFrameOfWatermark");
567 return true;
568 } else {
569 return false;
570 }
571 }
572
UpdateDisplayZoomState()573 void RSUniRenderVisitor::UpdateDisplayZoomState()
574 {
575 if (!curDisplayNode_) {
576 return;
577 }
578 auto scale = curDisplayNode_->GetRenderProperties().GetScale();
579 bool curZoomState = scale.x_ > 1.f || scale.y_ > 1.f;
580 curDisplayNode_->UpdateZoomState(curZoomState);
581 zoomStateChange_ = curZoomState || curDisplayNode_->IsZoomStateChange();
582 }
583
UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode & node)584 void RSUniRenderVisitor::UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode& node)
585 {
586 // only for virtual screen
587 if (!(node.IsMirrorDisplay())) {
588 return;
589 }
590 auto mirrorNode = node.GetMirrorSource().lock();
591 if (mirrorNode == nullptr || screenManager_ == nullptr) {
592 return;
593 }
594 auto securityExemptionList = screenManager_->GetVirtualScreenSecurityExemptionList(node.GetScreenId());
595 if (securityExemptionList.size() == 0) {
596 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:false",
597 node.GetId());
598 node.SetSecurityExemption(false);
599 mirrorNode->ClearSecurityLayerList();
600 return;
601 }
602 auto securityLayerList = mirrorNode->GetSecurityLayerList();
603 for (const auto& exemptionLayer : securityExemptionList) {
604 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
605 "securityExemption nodeId %{public}" PRIu64 ".", node.GetId(), exemptionLayer);
606 }
607 for (const auto& secLayer : securityLayerList) {
608 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
609 "securityLayer nodeId %{public}" PRIu64 ".", mirrorNode->GetId(), secLayer);
610 }
611 bool isSecurityExemption = false;
612 if (securityExemptionList.size() >= securityLayerList.size()) {
613 isSecurityExemption = true;
614 for (const auto& secLayer : securityLayerList) {
615 if (std::find(securityExemptionList.begin(), securityExemptionList.end(), secLayer) ==
616 securityExemptionList.end()) {
617 isSecurityExemption = false;
618 break;
619 }
620 }
621 }
622 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:%{public}d",
623 node.GetId(), isSecurityExemption);
624 node.SetSecurityExemption(isSecurityExemption);
625 mirrorNode->ClearSecurityLayerList();
626 }
627
QuickPrepareDisplayRenderNode(RSDisplayRenderNode & node)628 void RSUniRenderVisitor::QuickPrepareDisplayRenderNode(RSDisplayRenderNode& node)
629 {
630 // 0. init display info
631 RS_TRACE_NAME("RSUniRender:QuickPrepareDisplayRenderNode " + std::to_string(node.GetScreenId()));
632 if (!InitDisplayInfo(node)) {
633 return;
634 }
635 UpdateDisplayZoomState();
636 SendRcdMessage(node);
637 UpdateVirtualScreenSecurityExemption(node);
638 ancestorNodeHasAnimation_ = false;
639 displayNodeRotationChanged_ = node.IsRotationChanged();
640 dirtyFlag_ = isDirty_ || displayNodeRotationChanged_ || zoomStateChange_ ||
641 curDisplayDirtyManager_->IsActiveSurfaceRectChanged();
642 prepareClipRect_ = screenRect_;
643 hasAccumulatedClip_ = false;
644
645 globalShouldPaint_ = true;
646 curAlpha_ = 1.0f;
647 globalZOrder_ = 0.0f;
648 hasSkipLayer_ = false;
649 node.UpdateRotation();
650 if (!(RSMainThread::Instance()->IsRequestedNextVSync() || RSMainThread::Instance()->GetNextDVsyncAnimateFlag())) {
651 RS_OPTIONAL_TRACE_NAME_FMT("do not request next vsync");
652 needRequestNextVsync_ = false;
653 }
654 RSUifirstManager::Instance().SetRotationChanged(displayNodeRotationChanged_ || isScreenRotationAnimating_);
655 if (node.IsSubTreeDirty() || node.IsRotationChanged()) {
656 QuickPrepareChildren(node);
657 TryNotifyUIBufferAvailable();
658 }
659 PostPrepare(node);
660 UpdateHwcNodeEnable();
661 UpdateSurfaceDirtyAndGlobalDirty();
662 UpdateSurfaceOcclusionInfo();
663 if (needRecalculateOcclusion_) {
664 // Callback for registered self drawing surfacenode
665 RSMainThread::Instance()->SurfaceOcclusionCallback();
666 }
667 //UIFirst layer must be above displayNode, so use zorder + 1
668 RSUifirstManager::Instance().UpdateUIFirstLayerInfo(screenInfo_, globalZOrder_ + 1);
669 curDisplayNode_->UpdatePartialRenderParams();
670 RSDisplayRenderNode::ScreenRenderParams screenRenderParams;
671 screenRenderParams.screenInfo = std::move(screenInfo_);
672 screenRenderParams.displayHasSecSurface = std::move(displayHasSecSurface_);
673 screenRenderParams.displayHasSkipSurface = std::move(displayHasSkipSurface_);
674 screenRenderParams.displayHasSnapshotSkipSurface = std::move(displayHasSnapshotSkipSurface_);
675 screenRenderParams.displayHasProtectedSurface = std::move(displayHasProtectedSurface_);
676 screenRenderParams.displaySpecailSurfaceChanged = std::move(displaySpecailSurfaceChanged_);
677 screenRenderParams.hasCaptureWindow = std::move(hasCaptureWindow_);
678 curDisplayNode_->UpdateScreenRenderParams(screenRenderParams);
679 curDisplayNode_->UpdateOffscreenRenderParams(curDisplayNode_->IsRotationChanged());
680 UpdateColorSpaceAfterHwcCalc(node);
681 HandleColorGamuts(node, screenManager_);
682 HandlePixelFormat(node, screenManager_);
683 if (UNLIKELY(!SharedTransitionParam::unpairedShareTransitions_.empty())) {
684 ProcessUnpairedSharedTransitionNode();
685 }
686 node.RenderTraceDebug();
687 curDisplayNode_->ResetMirroredDisplayChangedFlag();
688 }
689
CheckFilterCacheNeedForceClearOrSave(RSRenderNode & node)690 void RSUniRenderVisitor::CheckFilterCacheNeedForceClearOrSave(RSRenderNode& node)
691 {
692 if (!node.HasBlurFilter()) {
693 return;
694 }
695 bool rotationChanged = curDisplayNode_ ?
696 curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
697 bool rotationStatusChanged = curDisplayNode_ ?
698 curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
699 node.CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
700 }
701
702 // private method, curDisplayNode_ or curSurfaceNode_ will not be nullptr
CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet & filterSet,bool isGlobalDirty)703 void RSUniRenderVisitor::CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet& filterSet, bool isGlobalDirty)
704 {
705 // Recursively traverses until the globalDirty do not change
706 auto dirtyManager = isGlobalDirty ? curDisplayNode_->GetDirtyManager() : curSurfaceNode_->GetDirtyManager();
707 if (dirtyManager == nullptr) {
708 return;
709 }
710 for (auto it = filterSet.begin(); it != filterSet.end();) {
711 auto dirtyRect = dirtyManager->GetCurrentFrameDirtyRegion();
712 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
713 auto dirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
714 auto filterDirtyRegion = filterRegion.And(dirtyRegion);
715 if (!filterDirtyRegion.IsEmpty()) {
716 if (isGlobalDirty) {
717 RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
718 "global dirty %{public}s, add filterRegion %{public}s",
719 dirtyRect.ToString().c_str(), (it->second).ToString().c_str());
720 }
721 dirtyManager->MergeDirtyRect(it->second);
722 it = filterSet.erase(it);
723 if (dirtyRect != dirtyManager->GetCurrentFrameDirtyRegion()) {
724 // When dirtyRegion is changed, collect dirty filter region from begin.
725 // After all filter region is added, the cycle will definitely stop.
726 it = filterSet.begin();
727 }
728 } else {
729 ++it;
730 }
731 }
732 filterSet.clear();
733 }
734
QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode & node)735 void RSUniRenderVisitor::QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
736 {
737 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRender::QuickPrepare:[%s] nodeId[%" PRIu64 "]"
738 "pid[%d] nodeType[%u] subTreeDirty[%d]", node.GetName().c_str(), node.GetId(), ExtractPid(node.GetId()),
739 static_cast<uint>(node.GetSurfaceNodeType()), node.IsSubTreeDirty());
740 RS_LOGD("RSUniRender::QuickPrepareSurfaceRenderNode:[%{public}s] nodeid:[%{public}" PRIu64 "]"
741 "pid:[%{public}d] nodeType:[%{public}d] subTreeDirty[%{public}d]", node.GetName().c_str(), node.GetId(),
742 ExtractPid(node.GetId()), static_cast<int>(node.GetSurfaceNodeType()), node.IsSubTreeDirty());
743
744 // 0. init curSurface info and check node info
745 auto curCornerRadius = curCornerRadius_;
746 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
747 if (!BeforeUpdateSurfaceDirtyCalc(node)) {
748 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode BeforeUpdateSurfaceDirtyCalc fail");
749 RSUifirstManager::Instance().DisableUifirstNode(node);
750 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
751 return;
752 }
753
754 if (curSurfaceDirtyManager_ == nullptr) {
755 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
756 node.GetName().c_str());
757 return;
758 }
759
760 // 1. Update matrix and collect dirty region
761 auto dirtyFlag = dirtyFlag_;
762 auto prepareClipRect = prepareClipRect_;
763 bool hasAccumulatedClip = hasAccumulatedClip_;
764 auto prevAlpha = curAlpha_;
765 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
766 node.SetGlobalAlpha(curAlpha_);
767 auto preGlobalShouldPaint = globalShouldPaint_;
768 globalShouldPaint_ &= node.ShouldPaint();
769 node.SetSelfAndParentShouldPaint(globalShouldPaint_);
770 CheckFilterCacheNeedForceClearOrSave(node);
771 node.CheckContainerDirtyStatusAndUpdateDirty(curContainerDirty_);
772 dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
773 *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix);
774 auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
775 if (!geoPtr) {
776 globalShouldPaint_ = preGlobalShouldPaint;
777 return;
778 }
779 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
780 if (!AfterUpdateSurfaceDirtyCalc(node)) {
781 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode AfterUpdateSurfaceDirtyCalc fail");
782 RSUifirstManager::Instance().DisableUifirstNode(node);
783 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
784 globalShouldPaint_ = preGlobalShouldPaint;
785 return;
786 }
787 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
788 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_, IsSubTreeOccluded(node)) ||
789 ForcePrepareSubTree();
790 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
791 node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
792 if (curSurfaceDirtyManager_ == nullptr) {
793 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager "
794 "is set to nullptr by QuickPrepareChildren", node.GetName().c_str());
795 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
796 globalShouldPaint_ = preGlobalShouldPaint;
797 return;
798 }
799 curSurfaceDirtyManager_->ClipDirtyRectWithinSurface();
800
801 // Update whether leash window's visible region is empty after prepare children
802 UpdateLeashWindowVisibleRegionEmpty(node);
803
804 if (node.IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()) {
805 CheckIsGpuOverDrawBufferOptimizeNode(node);
806 }
807 PostPrepare(node, !isSubTreeNeedPrepare);
808 CheckMergeFilterDirtyByIntersectWithDirty(curSurfaceNoBelowDirtyFilter_, false);
809 curAlpha_ = prevAlpha;
810 globalShouldPaint_ = preGlobalShouldPaint;
811 prepareClipRect_ = prepareClipRect;
812 hasAccumulatedClip_ = hasAccumulatedClip;
813 dirtyFlag_ = dirtyFlag;
814
815 PrepareForUIFirstNode(node);
816 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
817 ResetCurSurfaceInfoAsUpperSurfaceParent(node);
818 curCornerRadius_ = curCornerRadius;
819 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
820 node.RenderTraceDebug();
821 node.SetNeedOffscreen(isScreenRotationAnimating_);
822 if (node.NeedUpdateDrawableBehindWindow()) {
823 RSMainThread::Instance()->RequestNextVSync("drawBehindWindow");
824 }
825 if (node.IsUIBufferAvailable()) {
826 uiBufferAvailableId_.emplace_back(node.GetId());
827 }
828 }
829
PrepareForUIFirstNode(RSSurfaceRenderNode & node)830 void RSUniRenderVisitor::PrepareForUIFirstNode(RSSurfaceRenderNode& node)
831 {
832 MultiThreadCacheType lastFlag = node.GetLastFrameUifirstFlag();
833 RSUifirstManager::Instance().UpdateUifirstNodes(node, ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation());
834 RSUifirstManager::Instance().UpdateUIFirstNodeUseDma(node, globalSurfaceBounds_);
835 if (node.GetLastFrameUifirstFlag() == MultiThreadCacheType::LEASH_WINDOW &&
836 !node.IsHardwareForcedDisabled()) {
837 if (auto& geo = node.GetRenderProperties().GetBoundsGeometry()) {
838 UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
839 }
840 UpdateHwcNodeByTransform(node);
841 }
842 if (RSUifirstManager::Instance().GetUseDmaBuffer(node.GetName()) && curSurfaceDirtyManager_ &&
843 (node.GetLastFrameUifirstFlag() != lastFlag ||
844 !node.IsHardwareForcedDisabled() != node.GetIsLastFrameHwcEnabled())) {
845 curSurfaceDirtyManager_->MergeDirtyRect(node.GetOldDirty());
846 }
847 }
848
UpdateNodeVisibleRegion(RSSurfaceRenderNode & node)849 void RSUniRenderVisitor::UpdateNodeVisibleRegion(RSSurfaceRenderNode& node)
850 {
851 Occlusion::Rect selfDrawRect = node.GetSurfaceOcclusionRect(true);
852 Occlusion::Region selfDrawRegion { selfDrawRect };
853 if (needRecalculateOcclusion_) {
854 Occlusion::Region subResult = selfDrawRegion.Sub(accumulatedOcclusionRegion_);
855 node.SetVisibleRegion(subResult);
856 Occlusion::Region subResultWithoutSkipLayer = selfDrawRegion.Sub(occlusionRegionWithoutSkipLayer_);
857 node.SetVisibleRegionInVirtual(subResultWithoutSkipLayer);
858 }
859 RS_OPTIONAL_TRACE_NAME_FMT_LEVEL(TRACE_LEVEL_THREE,
860 "RSUniRenderVisitor::UpdateNodeVisibleRegion name[%s] visibleRegion[%s]",
861 node.GetName().c_str(), node.GetVisibleRegion().GetRegionInfo().c_str());
862 }
863
CalculateOcclusion(RSSurfaceRenderNode & node)864 void RSUniRenderVisitor::CalculateOcclusion(RSSurfaceRenderNode& node)
865 {
866 if (!curDisplayNode_) {
867 RS_LOGE("RSUniRenderVisitor::CalculateOcclusion curDisplayNode is nullptr");
868 return;
869 }
870 // CheckAndUpdateOpaqueRegion only in mainWindow
871 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
872 auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
873 (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
874 node.CheckAndUpdateOpaqueRegion(screenRect_, curDisplayNode_->GetRotation(), isFocused);
875 if (!needRecalculateOcclusion_) {
876 needRecalculateOcclusion_ = node.CheckIfOcclusionChanged();
877 }
878 // Update node visibleRegion
879 hasSkipLayer_ = hasSkipLayer_ || node.GetSkipLayer();
880 UpdateNodeVisibleRegion(node);
881 auto mainThread = RSMainThread::Instance();
882 node.SetOcclusionInSpecificScenes(mainThread->GetDeviceType() == DeviceType::PC &&
883 mainThread->IsPCThreeFingerScenesListScene());
884 // check current surface Participate In Occlusion
885 bool occlusionInAnimation = node.GetOcclusionInSpecificScenes() || !ancestorNodeHasAnimation_;
886 if (node.CheckParticipateInOcclusion() && occlusionInAnimation && !isAllSurfaceVisibleDebugEnabled_) {
887 accumulatedOcclusionRegion_.OrSelf(node.GetOpaqueRegion());
888 if (IsValidInVirtualScreen(node)) {
889 occlusionRegionWithoutSkipLayer_.OrSelf(node.GetOpaqueRegion());
890 }
891 }
892 node.SetOcclusionInSpecificScenes(false);
893 CollectOcclusionInfoForWMS(node);
894 }
895
CollectOcclusionInfoForWMS(RSSurfaceRenderNode & node)896 void RSUniRenderVisitor::CollectOcclusionInfoForWMS(RSSurfaceRenderNode& node)
897 {
898 if (!node.IsMainWindowType()) {
899 return;
900 }
901 // collect mainWindow occlusion visibleLevel
902 Occlusion::Region selfDrawRegion { node.GetSurfaceOcclusionRect(true) };
903 auto visibleLevel = GetRegionVisibleLevel(node.GetVisibleRegion(), selfDrawRegion);
904 // wms default all visible about sefdrawing node and AbilityComponent node
905 auto instanceNode = node.GetInstanceRootNode() ?
906 node.GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
907 if (instanceNode == nullptr) {
908 return;
909 }
910 if ((node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
911 !instanceNode->GetVisibleRegion().IsEmpty()) || node.IsAbilityComponent()) {
912 dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
913 WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
914 return;
915 }
916 dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
917 node.GetVisibleLevelForWMS(visibleLevel)));
918 }
919
SurfaceOcclusionCallbackToWMS()920 void RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS()
921 {
922 if (RSSystemParameters::GetOcclusionCallBackToWMSDebugType()) {
923 allDstCurVisVec_.clear();
924 const auto& curAllSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
925 for (const auto& surfacePtr : curAllSurfaces) {
926 if (surfacePtr == nullptr) {
927 continue;
928 }
929 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*surfacePtr);
930 if (surfaceNode.IsMainWindowType()) {
931 allDstCurVisVec_.emplace_back(std::make_pair(surfacePtr->GetId(),
932 WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
933 }
934 }
935 }
936 if (allDstCurVisVec_ != allLastVisVec_) {
937 RSMainThread::Instance()->SurfaceOcclusionChangeCallback(allDstCurVisVec_);
938 RS_LOGI("RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS %{public}s",
939 VisibleDataToString(allDstCurVisVec_).c_str());
940 allLastVisVec_ = std::move(allDstCurVisVec_);
941 }
942 }
943
GetRegionVisibleLevel(const Occlusion::Region & visibleRegion,const Occlusion::Region & selfDrawRegion)944 RSVisibleLevel RSUniRenderVisitor::GetRegionVisibleLevel(const Occlusion::Region& visibleRegion,
945 const Occlusion::Region& selfDrawRegion)
946 {
947 if (visibleRegion.IsEmpty()) {
948 return RSVisibleLevel::RS_INVISIBLE;
949 } else if (visibleRegion.Area() == selfDrawRegion.Area()) {
950 return RSVisibleLevel::RS_ALL_VISIBLE;
951 } else if (static_cast<uint>(visibleRegion.Area()) <
952 (static_cast<uint>(selfDrawRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
953 return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
954 }
955 return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
956 }
957
QuickPrepareEffectRenderNode(RSEffectRenderNode & node)958 void RSUniRenderVisitor::QuickPrepareEffectRenderNode(RSEffectRenderNode& node)
959 {
960 // 0. check current node need to tranverse
961 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
962 if (!dirtyManager) {
963 RS_LOGE("RSUniRenderVisitor::QuickPrepareEffectRenderNode dirtyManager is nullptr");
964 return;
965 }
966 auto dirtyFlag = dirtyFlag_;
967 auto prevAlpha = curAlpha_;
968 auto curCornerRadius = curCornerRadius_;
969 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
970 UpdateRotationStatusForEffectNode(node);
971 CheckFilterCacheNeedForceClearOrSave(node);
972 RectI prepareClipRect = prepareClipRect_;
973 bool hasAccumulatedClip = hasAccumulatedClip_;
974 dirtyFlag_ =
975 node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
976 node.UpdateCurCornerRadius(curCornerRadius_);
977 // 1. Recursively traverse child nodes
978 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
979 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
980 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
981 node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
982
983 PostPrepare(node, !isSubTreeNeedPrepare);
984 prepareClipRect_ = prepareClipRect;
985 hasAccumulatedClip_ = hasAccumulatedClip;
986 dirtyFlag_ = dirtyFlag;
987 curAlpha_ = prevAlpha;
988 curCornerRadius_ = curCornerRadius;
989 node.RenderTraceDebug();
990 }
991
QuickPrepareCanvasRenderNode(RSCanvasRenderNode & node)992 void RSUniRenderVisitor::QuickPrepareCanvasRenderNode(RSCanvasRenderNode& node)
993 {
994 // 0. check current node need to traverse
995 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
996 auto dirtyFlag = dirtyFlag_;
997 auto prevAlpha = curAlpha_;
998 auto preGlobalShouldPaint = globalShouldPaint_;
999 globalShouldPaint_ &= node.ShouldPaint();
1000 auto curCornerRadius = curCornerRadius_;
1001 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1002 CheckFilterCacheNeedForceClearOrSave(node);
1003 if (isDrawingCacheEnabled_) {
1004 node.UpdateDrawingCacheInfoBeforeChildren(isScreenRotationAnimating_);
1005 }
1006 node.OpincQuickMarkStableNode(unchangeMarkInApp_, unchangeMarkEnable_,
1007 RSMainThread::Instance()->IsAccessibilityConfigChanged());
1008
1009 RectI prepareClipRect = prepareClipRect_;
1010 bool hasAccumulatedClip = hasAccumulatedClip_;
1011
1012 if (!dirtyManager) {
1013 return;
1014 }
1015 dirtyFlag_ =
1016 node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1017 // update prepare clip before children
1018 UpdatePrepareClip(node);
1019 node.UpdateCurCornerRadius(curCornerRadius_);
1020
1021 // 1. Recursively traverse child nodes if above curSurfaceNode and subnode need draw
1022 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1023 bool isSubTreeNeedPrepare = !curSurfaceNode_ || node.IsSubTreeNeedPrepare(filterInGlobal_) ||
1024 ForcePrepareSubTree() || node.OpincForcePrepareSubTree();
1025 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1026 node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1027
1028 PostPrepare(node, !isSubTreeNeedPrepare);
1029 prepareClipRect_ = prepareClipRect;
1030 hasAccumulatedClip_ = hasAccumulatedClip;
1031 dirtyFlag_ = dirtyFlag;
1032 curAlpha_ = prevAlpha;
1033 curCornerRadius_ = curCornerRadius;
1034 node.OpincUpdateRootFlag(unchangeMarkEnable_);
1035 globalShouldPaint_ = preGlobalShouldPaint;
1036 node.RenderTraceDebug();
1037 }
1038
UpdateRotationStatusForEffectNode(RSEffectRenderNode & node)1039 void RSUniRenderVisitor::UpdateRotationStatusForEffectNode(RSEffectRenderNode& node)
1040 {
1041 // folding/expanding screen force invalidate cache.
1042 node.SetFoldStatusChanged(doAnimate_ &&
1043 curDisplayNode_->GetScreenId() != node.GetCurrentAttachedScreenId());
1044 node.SetCurrentAttachedScreenId(curDisplayNode_->GetScreenId());
1045 node.SetRotationChanged(curDisplayNode_->IsRotationChanged());
1046 }
1047
UpdatePrepareClip(RSRenderNode & node)1048 void RSUniRenderVisitor::UpdatePrepareClip(RSRenderNode& node)
1049 {
1050 const auto& property = node.GetRenderProperties();
1051 auto& geoPtr = property.GetBoundsGeometry();
1052 if (geoPtr == nullptr) {
1053 return;
1054 }
1055 // Dirty Region use abstract coordinate, property of node use relative coordinate
1056 // BoundsRect(if exists) is mapped to absRect_ of RSObjAbsGeometry.
1057 if (property.GetClipToBounds()) {
1058 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->GetAbsRect());
1059 }
1060 // FrameRect(if exists) is mapped to rect using abstract coordinate explicitly by calling MapAbsRect.
1061 if (property.GetClipToFrame()) {
1062 // MapAbsRect do not handle the translation of OffsetX and OffsetY
1063 RectF frameRect{
1064 property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_X),
1065 property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_Y),
1066 property.GetFrameWidth(), property.GetFrameHeight()};
1067 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(frameRect));
1068 }
1069 if (property.GetClipToRRect()) {
1070 RectF rect = property.GetClipRRect().rect_;
1071 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(rect));
1072 }
1073 }
1074
IsLeashAndHasMainSubNode(RSRenderNode & node) const1075 bool RSUniRenderVisitor::IsLeashAndHasMainSubNode(RSRenderNode& node) const
1076 {
1077 if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
1078 return false;
1079 }
1080 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1081 if (!surfaceNode.IsLeashWindow()) {
1082 return false;
1083 }
1084 // check leashWindow surface has first level mainwindow node
1085 auto children = node.GetSortedChildren();
1086 auto iter = std::find_if((*children).begin(), (*children).end(),
1087 [](const std::shared_ptr<RSRenderNode>& node) {
1088 if (node && node->GetType() == RSRenderNodeType::SURFACE_NODE) {
1089 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*node);
1090 return surfaceNode.IsMainWindowType();
1091 }
1092 return false;
1093 });
1094 return iter != (*children).end();
1095 }
1096
NeedPrepareChindrenInReverseOrder(RSRenderNode & node) const1097 bool RSUniRenderVisitor::NeedPrepareChindrenInReverseOrder(RSRenderNode& node) const
1098 {
1099 if (!curSurfaceNode_ && node.GetType() != RSRenderNodeType::RS_NODE) {
1100 return true;
1101 }
1102 return IsLeashAndHasMainSubNode(node);
1103 }
1104
QuickPrepareChildren(RSRenderNode & node)1105 void RSUniRenderVisitor::QuickPrepareChildren(RSRenderNode& node)
1106 {
1107 MergeRemovedChildDirtyRegion(node, true);
1108 if (node.LastFrameSubTreeSkipped() && curSurfaceDirtyManager_) {
1109 node.ForceMergeSubTreeDirtyRegion(*curSurfaceDirtyManager_, prepareClipRect_);
1110 }
1111 bool animationBackup = ancestorNodeHasAnimation_;
1112 ancestorNodeHasAnimation_ = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
1113 node.ResetChildRelevantFlags();
1114 node.ResetChildUifirstSupportFlag();
1115 auto children = node.GetSortedChildren();
1116 if (NeedPrepareChindrenInReverseOrder(node)) {
1117 std::for_each((*children).rbegin(), (*children).rend(), [this](const std::shared_ptr<RSRenderNode>& node) {
1118 if (!node) {
1119 return;
1120 }
1121 auto containerDirty = curContainerDirty_;
1122 curDirty_ = node->IsDirty();
1123 curContainerDirty_ = curContainerDirty_ || node->IsDirty();
1124 node->QuickPrepare(shared_from_this());
1125 curContainerDirty_ = containerDirty;
1126 });
1127 } else {
1128 std::for_each((*children).begin(), (*children).end(), [this](const std::shared_ptr<RSRenderNode>& node) {
1129 if (!node) {
1130 return;
1131 }
1132 curDirty_ = node->IsDirty();
1133 node->QuickPrepare(shared_from_this());
1134 });
1135 }
1136 ancestorNodeHasAnimation_ = animationBackup;
1137 node.ResetGeoUpdateDelay();
1138 }
1139
InitDisplayInfo(RSDisplayRenderNode & node)1140 bool RSUniRenderVisitor::InitDisplayInfo(RSDisplayRenderNode& node)
1141 {
1142 // 1 init curDisplay and curDisplayDirtyManager
1143 currentVisitDisplay_ = node.GetScreenId();
1144 displayHasSecSurface_.emplace(currentVisitDisplay_, false);
1145 displayHasSkipSurface_.emplace(currentVisitDisplay_, false);
1146 displayHasSnapshotSkipSurface_.emplace(currentVisitDisplay_, false);
1147 displayHasProtectedSurface_.emplace(currentVisitDisplay_, false);
1148 displaySpecailSurfaceChanged_.emplace(currentVisitDisplay_, false);
1149 hasCaptureWindow_.emplace(currentVisitDisplay_, false);
1150 curDisplayDirtyManager_ = node.GetDirtyManager();
1151 curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
1152 if (!curDisplayDirtyManager_ || !curDisplayNode_) {
1153 RS_LOGE("RSUniRenderVisitor::InitDisplayInfo dirtyMgr or node ptr is nullptr");
1154 return false;
1155 }
1156 curDisplayDirtyManager_->Clear();
1157 transparentCleanFilter_.clear();
1158 transparentDirtyFilter_.clear();
1159
1160 // 2 init screenManager info
1161 screenManager_ = CreateOrGetScreenManager();
1162 if (!screenManager_) {
1163 RS_LOGE("RSUniRenderVisitor::InitDisplayInfo screenManager_ is nullptr");
1164 return false;
1165 }
1166 screenInfo_ = screenManager_->QueryScreenInfo(node.GetScreenId());
1167 screenRect_ = screenInfo_.activeRect.IsEmpty() ? RectI{0, 0, screenInfo_.width, screenInfo_.height} :
1168 screenInfo_.activeRect;
1169 curDisplayDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1170 curDisplayDirtyManager_->SetActiveSurfaceRect(screenInfo_.activeRect);
1171 allBlackList_ = screenManager_->GetAllBlackList();
1172 allWhiteList_ = screenManager_->GetAllWhiteList();
1173
1174 // 3 init Occlusion info
1175 needRecalculateOcclusion_ = false;
1176 accumulatedOcclusionRegion_.Reset();
1177 occlusionRegionWithoutSkipLayer_.Reset();
1178 if (!curMainAndLeashWindowNodesIds_.empty()) {
1179 std::queue<NodeId>().swap(curMainAndLeashWindowNodesIds_);
1180 }
1181
1182 // 4. check isHardwareForcedDisabled
1183 auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
1184 if (geoPtr == nullptr) {
1185 RS_LOGE("RSUniRenderVisitor::InitDisplayInfo geoPtr is nullptr");
1186 return false;
1187 }
1188 if (geoPtr->IsNeedClientCompose()) {
1189 isHardwareForcedDisabled_ = true;
1190 }
1191
1192 // 5. check compositeType
1193 auto mirrorNode = node.GetMirrorSource().lock();
1194 node.SetIsMirrorScreen(mirrorNode != nullptr);
1195 switch (screenInfo_.state) {
1196 case ScreenState::PRODUCER_SURFACE_ENABLE:
1197 node.SetCompositeType(mirrorNode ?
1198 RSDisplayRenderNode::CompositeType::UNI_RENDER_MIRROR_COMPOSITE :
1199 RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE);
1200 break;
1201 case ScreenState::HDI_OUTPUT_ENABLE:
1202 node.SetCompositeType(node.IsForceSoftComposite() ?
1203 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE :
1204 RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE);
1205 break;
1206 default:
1207 return false;
1208 }
1209
1210 return true;
1211 }
1212
BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1213 bool RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1214 {
1215 // 1. init and record surface info
1216 if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
1217 hasCaptureWindow_[currentVisitDisplay_] = true;
1218 }
1219 UpdateSecuritySkipAndProtectedLayersRecord(node);
1220 node.UpdateUIFirstFrameGravity();
1221 if (node.IsMainWindowType() || node.IsLeashWindow()) {
1222 // UpdateCurCornerRadius must process before curSurfaceNode_ update
1223 node.UpdateCurCornerRadius(curCornerRadius_);
1224 curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1225 curSurfaceDirtyManager_ = node.GetDirtyManager();
1226 if (!curSurfaceDirtyManager_ || !curSurfaceNode_) {
1227 RS_LOGE("RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc %{public}s has invalid"
1228 " SurfaceDirtyManager or node ptr", node.GetName().c_str());
1229 return false;
1230 }
1231 curSurfaceDirtyManager_->Clear();
1232 curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1233 curSurfaceDirtyManager_->SetActiveSurfaceRect(screenInfo_.activeRect);
1234 filterInGlobal_ = curSurfaceNode_->IsTransparent();
1235 // update surfaceNode contentDirty and subTreeDirty flag for UIFirst purging policy
1236 RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1237 curSurfaceNode_->UpdateSurfaceCacheContentStaticFlag();
1238 curSurfaceNode_->UpdateSurfaceSubTreeDirtyFlag();
1239 curSurfaceNode_->SetLeashWindowVisibleRegionEmpty(false);
1240 } else if (node.IsAbilityComponent()) {
1241 if (auto nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>()) {
1242 RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(nodePtr);
1243 nodePtr->UpdateSurfaceCacheContentStaticFlag();
1244 }
1245 }
1246 // 2. update surface info and CheckIfOcclusionReusable
1247 node.SetAncestorDisplayNode(curDisplayNode_); // set for boot animation
1248 node.UpdateAncestorDisplayNodeInRenderParams();
1249 node.CleanDstRectChanged();
1250 // [planning] check node isDirty can be optimized.
1251 needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.IsDirty() ||
1252 node.CheckIfOcclusionReusable(preMainAndLeashWindowNodesIds_);
1253 if (autoCacheEnable_ && node.IsAppWindow()) {
1254 node.OpincSetInAppStateStart(unchangeMarkInApp_);
1255 }
1256 // 3. check color space pixelFormat and update RelMatrix
1257 CheckColorSpace(node);
1258 CheckPixelFormat(node);
1259 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
1260 node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
1261 }
1262 return true;
1263 }
1264
AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1265 bool RSUniRenderVisitor::AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1266 {
1267 // 1. Update surfaceNode info and AppWindow gravity
1268 const auto& property = node.GetRenderProperties();
1269 if (node.IsAppWindow()) {
1270 boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
1271 frameGravity_ = property.GetFrameGravity();
1272 }
1273 auto& geoPtr = property.GetBoundsGeometry();
1274 if (geoPtr == nullptr) {
1275 return false;
1276 }
1277 UpdateDstRect(node, geoPtr->GetAbsRect(), prepareClipRect_);
1278 node.UpdatePositionZ();
1279 if (node.IsHardwareEnabledType() && node.GetZorderChanged() && curSurfaceNode_) {
1280 curSurfaceNode_->SetNeedCollectHwcNode(true);
1281 }
1282 UpdateSurfaceRenderNodeScale(node);
1283 UpdateSurfaceRenderNodeRotate(node);
1284 if (node.IsMainWindowType() || node.IsLeashWindow()) {
1285 curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirtyInSurface());
1286 curDisplayNode_->AddSurfaceNodePosByDescZOrder(node.GetId(), node.GetOldDirtyInSurface());
1287 }
1288 // 2. Update Occlusion info before children preparation
1289 if (node.IsMainWindowType()) {
1290 CalculateOcclusion(node);
1291 if (node.GetFirstLevelNodeId() == node.GetId()) {
1292 globalSurfaceBounds_.emplace_back(node.GetAbsDrawRect());
1293 }
1294 }
1295 // 3. Update HwcNode Info for appNode
1296 UpdateHwcNodeInfoForAppNode(node);
1297 return true;
1298 }
1299
UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode & node)1300 void RSUniRenderVisitor::UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode& node)
1301 {
1302 if (!node.IsLeashWindow()) {
1303 return;
1304 }
1305 bool isVisibleRegionEmpty = true;
1306 for (const auto& child : *node.GetSortedChildren()) {
1307 const auto childSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1308 if (childSurfaceNode && childSurfaceNode->IsAppWindow()) {
1309 // leash window is visible when child app has visible region
1310 if (!childSurfaceNode->GetVisibleRegion().IsEmpty()) {
1311 isVisibleRegionEmpty = false;
1312 } else {
1313 RS_OPTIONAL_TRACE_NAME_FMT("%s's visible region is empty", childSurfaceNode->GetName().c_str());
1314 }
1315 } else {
1316 // leash window is visible when child is not app window node
1317 isVisibleRegionEmpty = false;
1318 }
1319 if (!isVisibleRegionEmpty) {
1320 break;
1321 }
1322 }
1323 node.SetLeashWindowVisibleRegionEmpty(isVisibleRegionEmpty);
1324 }
1325
UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode & node)1326 void RSUniRenderVisitor::UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode& node)
1327 {
1328 // app node
1329 if (node.GetNeedCollectHwcNode()) {
1330 node.ResetChildHardwareEnabledNodes();
1331 }
1332 // hwc node
1333 if (node.IsHardwareEnabledType() && curSurfaceNode_) {
1334 if (curSurfaceNode_->GetNeedCollectHwcNode()) {
1335 curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
1336 }
1337 if (!node.GetHardWareDisabledByReverse()) {
1338 node.SetHardwareForcedDisabledState(node.GetIsHwcPendingDisabled());
1339 node.SetIsHwcPendingDisabled(false);
1340 }
1341 node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1342 if (!IsHardwareComposerEnabled() || !node.IsDynamicHardwareEnable() ||
1343 curSurfaceNode_->GetVisibleRegion().IsEmpty() ||
1344 !node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1345 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by param/invisible/no buffer",
1346 node.GetName().c_str(), node.GetId());
1347 node.SetHardwareForcedDisabledState(true);
1348 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
1349 HwcDisabledReasons::DISABLED_BY_INVALID_PARAM, node.GetName());
1350 if (!node.GetFixRotationByUser()) {
1351 return;
1352 }
1353 }
1354 auto& geo = node.GetRenderProperties().GetBoundsGeometry();
1355 if (geo == nullptr) {
1356 return;
1357 }
1358 UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
1359 UpdateHwcNodeByTransform(node);
1360 UpdateHwcNodeEnableByBackgroundAlpha(node);
1361 UpdateHwcNodeEnableByBufferSize(node);
1362 UpdateHwcNodeEnableBySrcRect(node);
1363 }
1364 }
1365
UpdateSrcRect(RSSurfaceRenderNode & node,const Drawing::Matrix & absMatrix,const RectI & absRect)1366 void RSUniRenderVisitor::UpdateSrcRect(RSSurfaceRenderNode& node,
1367 const Drawing::Matrix& absMatrix, const RectI& absRect)
1368 {
1369 auto canvas = std::make_unique<Rosen::Drawing::Canvas>(screenInfo_.phyWidth, screenInfo_.phyHeight);
1370 canvas->ConcatMatrix(absMatrix);
1371
1372 const auto& dstRect = node.GetDstRect();
1373 Drawing::RectI dst = { std::round(dstRect.GetLeft()), std::round(dstRect.GetTop()), std::round(dstRect.GetRight()),
1374 std::round(dstRect.GetBottom()) };
1375 node.UpdateSrcRect(*canvas.get(), dst);
1376 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
1377 RSUniRenderUtil::UpdateRealSrcRect(node, absRect);
1378 }
1379 }
1380
UpdateDstRect(RSSurfaceRenderNode & node,const RectI & absRect,const RectI & clipRect)1381 void RSUniRenderVisitor::UpdateDstRect(RSSurfaceRenderNode& node, const RectI& absRect, const RectI& clipRect)
1382 {
1383 auto dstRect = absRect;
1384 // If the screen is expanded, intersect the destination rectangle with the screen rectangle
1385 dstRect = dstRect.IntersectRect(RectI(curDisplayNode_->GetDisplayOffsetX(), curDisplayNode_->GetDisplayOffsetY(),
1386 screenInfo_.width, screenInfo_.height));
1387 // Remove the offset of the screen
1388 dstRect.left_ = dstRect.left_ - curDisplayNode_->GetDisplayOffsetX();
1389 dstRect.top_ = dstRect.top_ - curDisplayNode_->GetDisplayOffsetY();
1390 // If the node is a hardware-enabled type, intersect its destination rectangle with the prepare clip rectangle
1391 if (node.IsHardwareEnabledType()) {
1392 dstRect = dstRect.IntersectRect(clipRect);
1393 if (curSurfaceNode_ && (node.GetId() != curSurfaceNode_->GetId())) {
1394 dstRect = dstRect.IntersectRect(curSurfaceNode_->GetDstRect());
1395 }
1396 }
1397 dstRect.left_ = static_cast<int>(std::round(dstRect.left_ * screenInfo_.GetRogWidthRatio()));
1398 dstRect.top_ = static_cast<int>(std::round(dstRect.top_ * screenInfo_.GetRogHeightRatio()));
1399 dstRect.width_ = static_cast<int>(std::round(dstRect.width_ * screenInfo_.GetRogWidthRatio()));
1400 dstRect.height_ = static_cast<int>(std::round(dstRect.height_ * screenInfo_.GetRogHeightRatio()));
1401 // Set the destination rectangle of the node
1402 node.SetDstRect(dstRect);
1403 }
1404
UpdateHwcNodeByTransform(RSSurfaceRenderNode & node)1405 void RSUniRenderVisitor::UpdateHwcNodeByTransform(RSSurfaceRenderNode& node)
1406 {
1407 if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1408 return;
1409 }
1410 node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1411 RSUniRenderUtil::DealWithNodeGravity(node, screenInfo_);
1412 RSUniRenderUtil::LayerRotate(node, screenInfo_);
1413 RSUniRenderUtil::LayerCrop(node, screenInfo_);
1414 RSUniRenderUtil::DealWithScalingMode(node, screenInfo_);
1415 node.SetCalcRectInPrepare(true);
1416 }
1417
UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode & node)1418 void RSUniRenderVisitor::UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode& node)
1419 {
1420 bool bgTransport = !node.GetAncoForceDoDirect() &&
1421 (static_cast<uint8_t>(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX);
1422 auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(node.GetStagingRenderParams().get());
1423 bool isSolidColorEnbaled = stagingSurfaceParams->GetSelfDrawingNodeType() == SelfDrawingNodeType::XCOM &&
1424 node.GetRenderProperties().GetBackgroundColor() != RgbPalette::Black();
1425 if (bgTransport) {
1426 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by background color alpha < 1",
1427 node.GetName().c_str(), node.GetId());
1428 // use in skip updating hardware state for hwcnode with background alpha in specific situation
1429 if (!RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag()) {
1430 node.SetHardwareForcedDisabledState(true);
1431 }
1432 node.SetNodeHasBackgroundColorAlpha(true);
1433 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
1434 HwcDisabledReasons::DISABLED_BY_BACKGROUND_ALPHA, node.GetName());
1435 } else if (RsCommonHook::Instance().GetIsWhiteListForSolidColorLayerFlag() && isSolidColorEnbaled) {
1436 if (!RSSystemParameters::GetSolidLayerHwcEnabled()) {
1437 node.SetHardwareForcedDisabledState(true);
1438 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by solidLayer switch",
1439 node.GetName().c_str(), node.GetId());
1440 return;
1441 }
1442 stagingSurfaceParams->SetIsHwcEnabledBySolidLayer(true);
1443 } else if (!RsCommonHook::Instance().GetIsWhiteListForSolidColorLayerFlag() && isSolidColorEnbaled) {
1444 node.SetHardwareForcedDisabledState(true);
1445 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by solid background color",
1446 node.GetName().c_str(), node.GetId());
1447 }
1448 }
1449
UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode & node)1450 void RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode& node)
1451 {
1452 if (!node.IsRosenWeb() || node.IsHardwareForcedDisabled()) {
1453 return;
1454 }
1455 if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
1456 return;
1457 }
1458 const auto& property = node.GetRenderProperties();
1459 auto gravity = property.GetFrameGravity();
1460 if (gravity != Gravity::TOP_LEFT) {
1461 return;
1462 }
1463 auto surfaceHandler = node.GetRSSurfaceHandler();
1464 auto consumer = surfaceHandler->GetConsumer();
1465 if (consumer == nullptr) {
1466 return;
1467 }
1468
1469 auto buffer = surfaceHandler->GetBuffer();
1470 const auto bufferWidth = buffer->GetSurfaceBufferWidth();
1471 const auto bufferHeight = buffer->GetSurfaceBufferHeight();
1472 auto boundsWidth = property.GetBoundsWidth();
1473 auto boundsHeight = property.GetBoundsHeight();
1474
1475 auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
1476 if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
1477 RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize GetSurfaceBufferTransformType failed");
1478 }
1479 if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
1480 transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
1481 std::swap(boundsWidth, boundsHeight);
1482 }
1483 if ((bufferWidth < boundsWidth) || (bufferHeight < boundsHeight)) {
1484 RS_OPTIONAL_TRACE_NAME_FMT(
1485 "hwc debug: name:%s id:%" PRIu64 " buffer:[%d, %d] bounds:[%f, %f] disabled by buffer nonmatching",
1486 node.GetName().c_str(), node.GetId(), bufferWidth, bufferHeight, boundsWidth, boundsHeight);
1487 node.SetHardwareForcedDisabledState(true);
1488 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(
1489 node.GetId(), HwcDisabledReasons::DISABLED_BY_BUFFER_NONMATCH, node.GetName());
1490 }
1491 }
1492
UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode & node)1493 void RSUniRenderVisitor::UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode& node)
1494 {
1495 if (node.IsHardwareForcedDisabled()) {
1496 return;
1497 }
1498 bool hasRotation = false;
1499 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetConsumer()) {
1500 const auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
1501 auto rotation = RSBaseRenderUtil::GetRotateTransform(
1502 RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, node.GetRSSurfaceHandler()->GetBuffer()));
1503 hasRotation = rotation == GRAPHIC_ROTATE_90 || rotation == GRAPHIC_ROTATE_270;
1504 }
1505 node.UpdateHwcDisabledBySrcRect(hasRotation);
1506 if (node.IsHardwareDisabledBySrcRect()) {
1507 node.SetHardwareForcedDisabledState(true);
1508 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
1509 HwcDisabledReasons::DISABLED_BY_SRC_PIXEL, node.GetName());
1510 }
1511 }
1512
UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)1513 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(std::vector<RectI>& hwcRects,
1514 std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
1515 {
1516 if (hwcNode->IsHardwareForcedDisabled()) {
1517 return;
1518 }
1519 auto dst = hwcNode->GetDstRect();
1520 if (hwcNode->GetAncoForceDoDirect()) {
1521 hwcRects.emplace_back(dst);
1522 return;
1523 }
1524 for (auto rect : hwcRects) {
1525 if (dst.Intersect(rect) && !RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
1526 if (RsCommonHook::Instance().GetVideoSurfaceFlag() &&
1527 ((dst.GetBottom() - rect.GetTop() <= MIN_OVERLAP && dst.GetBottom() - rect.GetTop() >= 0) ||
1528 (rect.GetBottom() - dst.GetTop() <= MIN_OVERLAP && rect.GetBottom() - dst.GetTop() >= 0))) {
1529 return;
1530 }
1531 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by hwc node above",
1532 hwcNode->GetName().c_str(), hwcNode->GetId());
1533 hwcNode->SetHardwareForcedDisabledState(true);
1534 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
1535 HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
1536 return;
1537 }
1538 }
1539 hwcRects.emplace_back(dst);
1540 }
1541
UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)1542 void RSUniRenderVisitor::UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)
1543 {
1544 auto hwcNodeGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
1545 if (!hwcNodeGeo) {
1546 RS_LOGE("hwcNode Geometry is not prepared.");
1547 return;
1548 }
1549 bool hasCornerRadius = !hwcNode->GetRenderProperties().GetCornerRadius().IsZero();
1550 std::vector<RectI> currIntersectedRoundCornerAABBs = {};
1551 float alpha = hwcNode->GetRenderProperties().GetAlpha();
1552 Drawing::Matrix totalMatrix = hwcNodeGeo->GetMatrix();
1553 auto hwcNodeRect = hwcNodeGeo->GetAbsRect();
1554 bool isNodeRenderByDrawingCache = false;
1555 hwcNode->SetAbsRotation(hwcNode->GetRenderProperties().GetRotation());
1556 RSUniRenderUtil::TraverseParentNodeAndReduce(
1557 hwcNode,
1558 [&isNodeRenderByDrawingCache](std::shared_ptr<RSRenderNode> parent) {
1559 if (isNodeRenderByDrawingCache) {
1560 return;
1561 }
1562 // if the parent node of hwcNode is marked freeze or nodegroup, RS closes hardware composer of hwcNode.
1563 isNodeRenderByDrawingCache = isNodeRenderByDrawingCache || parent->IsStaticCached() ||
1564 (parent->GetNodeGroupType() != RSRenderNode::NodeGroupType::NONE);
1565 },
1566 [&alpha](std::shared_ptr<RSRenderNode> parent) {
1567 auto& parentProperty = parent->GetRenderProperties();
1568 alpha *= parentProperty.GetAlpha();
1569 },
1570 [&totalMatrix](std::shared_ptr<RSRenderNode> parent) {
1571 if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
1572 totalMatrix.PostConcat(opt.value());
1573 } else {
1574 return;
1575 }
1576 },
1577 [&currIntersectedRoundCornerAABBs, hwcNodeRect](std::shared_ptr<RSRenderNode> parent) {
1578 auto& parentProperty = parent->GetRenderProperties();
1579 auto cornerRadius = parentProperty.GetCornerRadius();
1580 auto maxCornerRadius = *std::max_element(std::begin(cornerRadius.data_), std::end(cornerRadius.data_));
1581 auto parentGeo = parentProperty.GetBoundsGeometry();
1582 static const std::array offsetVecs {
1583 UIPoint { 0, 0 },
1584 UIPoint { 1, 0 },
1585 UIPoint { 0, 1 },
1586 UIPoint { 1, 1 }
1587 };
1588
1589 // The logic here is to calculate whether the HWC Node affects
1590 // the round corner property of the parent node.
1591 // The method is calculating the rounded AABB of each HWC node
1592 // with respect to all parent nodes above it and storing the results.
1593 // When a HWC node is found below, the AABBs and the HWC node
1594 // are checked for intersection. If there is an intersection,
1595 // the node above it is disabled from taking the HWC pipeline.
1596 auto checkIntersectWithRoundCorner = [&currIntersectedRoundCornerAABBs, hwcNodeRect](
1597 const RectI& rect, float radiusX, float radiusY) {
1598 if (radiusX <= 0 || radiusY <= 0) {
1599 return;
1600 }
1601 UIPoint offset { rect.GetWidth() - radiusX, rect.GetHeight() - radiusY };
1602 UIPoint anchorPoint { rect.GetLeft(), rect.GetTop() };
1603 std::for_each(std::begin(offsetVecs), std::end(offsetVecs),
1604 [&currIntersectedRoundCornerAABBs, hwcNodeRect, offset,
1605 radiusX, radiusY, anchorPoint](auto offsetVec) {
1606 auto res = anchorPoint + offset * offsetVec;
1607 auto roundCornerAABB = RectI(res.x_, res.y_, radiusX, radiusY);
1608 if (!roundCornerAABB.IntersectRect(hwcNodeRect).IsEmpty()) {
1609 currIntersectedRoundCornerAABBs.push_back(roundCornerAABB);
1610 }
1611 }
1612 );
1613 };
1614 if (parentGeo) {
1615 auto parentRect = parentGeo->GetAbsRect();
1616 checkIntersectWithRoundCorner(parentRect, maxCornerRadius, maxCornerRadius);
1617
1618 if (parentProperty.GetClipToRRect()) {
1619 RRect parentClipRRect = parentProperty.GetClipRRect();
1620 RectI parentClipRect = parentGeo->MapAbsRect(parentClipRRect.rect_);
1621 float maxClipRRectCornerRadiusX = 0, maxClipRRectCornerRadiusY = 0;
1622 constexpr size_t radiusVecSize = 4;
1623 for (size_t i = 0; i < radiusVecSize; ++i) {
1624 maxClipRRectCornerRadiusX = std::max(maxClipRRectCornerRadiusX, parentClipRRect.radius_[i].x_);
1625 maxClipRRectCornerRadiusY = std::max(maxClipRRectCornerRadiusY, parentClipRRect.radius_[i].y_);
1626 }
1627 checkIntersectWithRoundCorner(parentClipRect, maxClipRRectCornerRadiusX, maxClipRRectCornerRadiusY);
1628 }
1629 }
1630 },
1631 [hwcNode](std::shared_ptr<RSRenderNode> parent) {
1632 hwcNode->SetAbsRotation(hwcNode->GetAbsRotation() + parent->GetRenderProperties().GetRotation());
1633 });
1634 if (isNodeRenderByDrawingCache) {
1635 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by drawing cache",
1636 hwcNode->GetName().c_str(), hwcNode->GetId());
1637 hwcNode->SetHardwareForcedDisabledState(isNodeRenderByDrawingCache);
1638 }
1639 hwcNode->SetTotalMatrix(totalMatrix);
1640 hwcNode->SetGlobalAlpha(alpha);
1641 hwcNode->SetIntersectedRoundCornerAABBs(std::move(currIntersectedRoundCornerAABBs));
1642 }
1643
UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode> & hwcNode)1644 void RSUniRenderVisitor::UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
1645 {
1646 auto alpha = hwcNode->GetGlobalAlpha();
1647 auto totalMatrix = hwcNode->GetTotalMatrix();
1648 if (alpha < 1.0f) {
1649 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by accumulated alpha:%.2f",
1650 hwcNode->GetName().c_str(), hwcNode->GetId(), alpha);
1651 hwcNode->SetHardwareForcedDisabledState(true);
1652 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
1653 HwcDisabledReasons::DISABLED_BY_ACCUMULATED_ALPHA, hwcNode->GetName());
1654 return;
1655 }
1656 // [planning] degree only multiples of 90 now
1657 float degree = RSUniRenderUtil::GetFloatRotationDegreeFromMatrix(totalMatrix);
1658 bool hasRotate = !ROSEN_EQ(std::remainder(degree, 90.f), 0.f, EPSILON);
1659 hasRotate = hasRotate || RSUniRenderUtil::Is3DRotation(totalMatrix);
1660 if (hasRotate) {
1661 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by rotation:%d",
1662 hwcNode->GetName().c_str(), hwcNode->GetId(), degree);
1663 hwcNode->SetHardwareForcedDisabledState(true);
1664 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
1665 HwcDisabledReasons::DISABLED_BY_ROTATION, hwcNode->GetName());
1666 return;
1667 }
1668 }
1669
ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode> & hwcNodePtr)1670 void RSUniRenderVisitor::ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr)
1671 {
1672 if ((hwcNodePtr->GetAncoFlags() & static_cast<uint32_t>(AncoFlags::IS_ANCO_NODE)) == 0) {
1673 return;
1674 }
1675 ancoNodes_.insert(hwcNodePtr);
1676 auto alpha = hwcNodePtr->GetGlobalAlpha();
1677 RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 "src %{public}s dst %{public}s "
1678 "alpha:%{public}.2f", hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(),
1679 hwcNodePtr->GetSrcRect().ToString().c_str(), hwcNodePtr->GetDstRect().ToString().c_str(), alpha);
1680 if (ROSEN_EQ(alpha, 0.0f)) {
1681 return;
1682 }
1683
1684 if (!hwcNodePtr->GetRSSurfaceHandler() || !hwcNodePtr->GetRSSurfaceHandler()->GetBuffer()) {
1685 RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 " handler or buffer is null, skip",
1686 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
1687 return;
1688 }
1689
1690 ancoHasGpu_ = (ancoHasGpu_ || hwcNodePtr->IsHardwareForcedDisabled());
1691 }
1692
InitAncoStatus()1693 void RSUniRenderVisitor::InitAncoStatus()
1694 {
1695 ancoHasGpu_ = false;
1696 ancoNodes_.clear();
1697 }
1698
UpdateHwcNodeEnable()1699 void RSUniRenderVisitor::UpdateHwcNodeEnable()
1700 {
1701 InitAncoStatus();
1702
1703 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1704 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
1705 [this](RSBaseRenderNode::SharedPtr& nodePtr) {
1706 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
1707 if (!surfaceNode) {
1708 return;
1709 }
1710
1711 if (RSSystemProperties::GetHveFilterEnabled()) {
1712 const auto &preHwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
1713 for (const auto& preHwcNode : preHwcNodes) {
1714 auto hwcNodePtr = preHwcNode.lock();
1715 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
1716 continue;
1717 }
1718 hwcNodePtr->ResetMakeImageState();
1719 }
1720 }
1721
1722 UpdateHwcNodeEnableByGlobalFilter(surfaceNode);
1723 surfaceNode->ResetNeedCollectHwcNode();
1724 const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
1725 if (hwcNodes.empty()) {
1726 return;
1727 }
1728 std::vector<RectI> hwcRects;
1729 for (const auto& hwcNode : hwcNodes) {
1730 auto hwcNodePtr = hwcNode.lock();
1731 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
1732 continue;
1733 }
1734 if (hwcNodePtr->GetProtectedLayer()) {
1735 drmNodes_.emplace_back(hwcNode);
1736 }
1737 UpdateHwcNodeProperty(hwcNodePtr);
1738 UpdateHwcNodeEnableByRotateAndAlpha(hwcNodePtr);
1739 UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(hwcRects, hwcNodePtr);
1740
1741 ProcessAncoNode(hwcNodePtr);
1742 }
1743 });
1744 UpdateAncoNodeHWCDisabledState();
1745 PrevalidateHwcNode();
1746 UpdateHwcNodeEnableByNodeBelow();
1747 }
1748
UpdateAncoNodeHWCDisabledState()1749 void RSUniRenderVisitor::UpdateAncoNodeHWCDisabledState()
1750 {
1751 if (ancoHasGpu_) {
1752 for (const auto& hwcNodePtr : ancoNodes_) {
1753 hwcNodePtr->SetHardwareForcedDisabledState(true);
1754 }
1755 }
1756
1757 InitAncoStatus();
1758 }
1759
PrevalidateHwcNode()1760 void RSUniRenderVisitor::PrevalidateHwcNode()
1761 {
1762 if (!isPrevalidateHwcNodeEnable_) {
1763 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate close");
1764 return;
1765 }
1766 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1767 std::vector<RequestLayerInfo> prevalidLayers;
1768 uint32_t curFps = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(curDisplayNode_->GetScreenId());
1769 uint32_t zOrder = static_cast<uint32_t>(globalZOrder_);
1770 // add surfaceNode layer
1771 RSUniHwcPrevalidateUtil::GetInstance().CollectSurfaceNodeLayerInfo(
1772 prevalidLayers, curMainAndLeashSurfaces, curFps, zOrder, screenInfo_);
1773 std::vector<RequestLayerInfo> uiFirstLayers;
1774 // collect uifirst layer
1775 // zOrder + 1.f is displayNode, UIFirst layer must be above displayNode(zorder + 2.f)
1776 RSUniHwcPrevalidateUtil::GetInstance().CollectUIFirstLayerInfo(
1777 uiFirstLayers, curFps, static_cast<float>(zOrder) + 2.f, screenInfo_);
1778 RS_TRACE_NAME_FMT("PrevalidateHwcNode hwcLayer: %u, uifirstLayer: %u", prevalidLayers.size(), uiFirstLayers.size());
1779 if (prevalidLayers.size() == 0 && uiFirstLayers.size() == 0) {
1780 RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode no hardware layer");
1781 return;
1782 }
1783 // add display layer
1784 RequestLayerInfo displayLayer;
1785 if (RSUniHwcPrevalidateUtil::GetInstance().CreateDisplayNodeLayerInfo(
1786 zOrder++, curDisplayNode_, screenInfo_, curFps, displayLayer)) {
1787 prevalidLayers.emplace_back(displayLayer);
1788 }
1789 // add uiFirst layer
1790 prevalidLayers.insert(prevalidLayers.end(), uiFirstLayers.begin(), uiFirstLayers.end());
1791 // add rcd layer
1792 RequestLayerInfo rcdLayer;
1793 if (RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
1794 auto rcdSurface = RSRcdRenderManager::GetInstance().GetBottomSurfaceNode(curDisplayNode_->GetId());
1795 if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(rcdSurface, screenInfo_, curFps, rcdLayer)) {
1796 prevalidLayers.emplace_back(rcdLayer);
1797 }
1798 rcdSurface = RSRcdRenderManager::GetInstance().GetTopSurfaceNode(curDisplayNode_->GetId());
1799 if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(rcdSurface, screenInfo_, curFps, rcdLayer)) {
1800 prevalidLayers.emplace_back(rcdLayer);
1801 }
1802 }
1803 std::map<uint64_t, RequestCompositionType> strategy;
1804 if (!RSUniHwcPrevalidateUtil::GetInstance().PreValidate(screenInfo_.id, prevalidLayers, strategy)) {
1805 RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate failed");
1806 return;
1807 }
1808 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
1809 for (auto it : strategy) {
1810 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode id: %{public}" PRIu64 ","
1811 " result: %{public}d", it.first, it.second);
1812 if (it.second == RequestCompositionType::DEVICE) {
1813 continue;
1814 }
1815 auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(it.first);
1816 if (node == nullptr) {
1817 continue;
1818 }
1819 if (it.second == RequestCompositionType::DEVICE_VSCF) {
1820 node->SetArsrTag(false);
1821 continue;
1822 }
1823 if (node->IsInFixedRotation() || node->GetProtectedLayer()) {
1824 continue;
1825 }
1826 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by prevalidate",
1827 node->GetName().c_str(), node->GetId());
1828 node->SetHardwareForcedDisabledState(true);
1829 if (node->GetRSSurfaceHandler()) {
1830 node->GetRSSurfaceHandler()->SetGlobalZOrder(-1.f);
1831 }
1832 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
1833 HwcDisabledReasons::DISABLED_BY_PREVALIDATE, node->GetName());
1834 }
1835 }
1836
UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode> & node)1837 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode>& node)
1838 {
1839 const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
1840 if (hwcNodes.empty()) {
1841 return;
1842 }
1843 std::shared_ptr<RSSurfaceRenderNode> pointWindow;
1844 std::vector<std::shared_ptr<RSSurfaceRenderNode>> topLayers;
1845 for (auto hwcNode : hwcNodes) {
1846 auto hwcNodePtr = hwcNode.lock();
1847 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
1848 continue;
1849 }
1850 auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
1851 if (hwcNodePtr->IsLayerTop()) {
1852 topLayers.emplace_back(hwcNodePtr);
1853 continue;
1854 }
1855 if (node->IsHardwareEnabledTopSurface()) {
1856 pointWindow = hwcNodePtr;
1857 continue;
1858 }
1859 if ((hasUniRenderHdrSurface_ || !drmNodes_.empty()) && !hwcNodePtr->GetProtectedLayer()) {
1860 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64
1861 " disabled by having UniRenderHdrSurface/DRM nodes",
1862 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
1863 hwcNodePtr->SetHardwareForcedDisabledState(true);
1864 // DRM will force HDR to use unirender
1865 hasUniRenderHdrSurface_ = hasUniRenderHdrSurface_ || RSMainThread::CheckIsHdrSurface(*hwcNodePtr);
1866 }
1867 UpdateHwcNodeDirtyRegionForApp(node, hwcNodePtr);
1868 hwcNodePtr->SetCalcRectInPrepare(false);
1869 hwcNodePtr->SetHardWareDisabledByReverse(false);
1870 surfaceHandler->SetGlobalZOrder(hwcNodePtr->IsHardwareForcedDisabled() && !hwcNodePtr->GetProtectedLayer()
1871 ? -1.f : globalZOrder_++);
1872 auto stagingSurfaceParams = static_cast<RSSurfaceRenderParams*>(hwcNodePtr->GetStagingRenderParams().get());
1873 if (stagingSurfaceParams->GetIsHwcEnabledBySolidLayer()) {
1874 surfaceHandler->SetGlobalZOrder(globalZOrder_++);
1875 }
1876 auto transform = RSUniRenderUtil::GetLayerTransform(*hwcNodePtr, screenInfo_);
1877 hwcNodePtr->UpdateHwcNodeLayerInfo(transform);
1878 }
1879 curDisplayNode_->SetDisplayGlobalZOrder(globalZOrder_);
1880 if (!topLayers.empty()) {
1881 UpdateTopLayersDirtyStatus(topLayers);
1882 }
1883 if (pointWindow) {
1884 UpdatePointWindowDirtyStatus(pointWindow);
1885 }
1886 }
1887
UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode> & pointWindow)1888 void RSUniRenderVisitor::UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode>& pointWindow)
1889 {
1890 std::shared_ptr<RSSurfaceHandler> pointSurfaceHandler = pointWindow->GetMutableRSSurfaceHandler();
1891 if (pointSurfaceHandler) {
1892 // globalZOrder_ + 2 is displayNode layer, point window must be at the top.
1893 pointSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 2);
1894 pointWindow->SetHardwareForcedDisabledState(!IsHardwareComposerEnabled() || !pointWindow->ShouldPaint() ||
1895 hasUniRenderHdrSurface_);
1896 auto transform = RSUniRenderUtil::GetLayerTransform(*pointWindow, screenInfo_);
1897 pointWindow->UpdateHwcNodeLayerInfo(transform);
1898 }
1899 }
1900
UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>> & topLayers)1901 void RSUniRenderVisitor::UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& topLayers)
1902 {
1903 for (const auto& topLayer : topLayers) {
1904 std::shared_ptr<RSSurfaceHandler> topLayerSurfaceHandler = topLayer->GetMutableRSSurfaceHandler();
1905 if (topLayerSurfaceHandler) {
1906 topLayerSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 1);
1907 topLayer->SetCalcRectInPrepare(false);
1908 topLayer->SetHardwareForcedDisabledState(!IsHardwareComposerEnabled() || !topLayer->ShouldPaint() ||
1909 hasUniRenderHdrSurface_ || !drmNodes_.empty());
1910 auto transform = RSUniRenderUtil::GetLayerTransform(*topLayer, screenInfo_);
1911 topLayer->UpdateHwcNodeLayerInfo(transform);
1912 }
1913 }
1914 }
1915
UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode> & appNode,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)1916 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode>& appNode,
1917 std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
1918 {
1919 // if current frame hwc enable status not equal with last frame
1920 // or current frame do gpu composition and has buffer consumed,
1921 // we need merge hwc node dst rect to dirty region.
1922 if (!hwcNode->IsHardwareForcedDisabled() != hwcNode->GetIsLastFrameHwcEnabled()) {
1923 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
1924 return;
1925 }
1926 if (!hwcNode->GetRSSurfaceHandler()) {
1927 return;
1928 }
1929 if (hwcNode->IsHardwareForcedDisabled() && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
1930 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetOldDirtyInSurface());
1931 }
1932 if (hasMirrorDisplay_ && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
1933 !appNode->GetVisibleRegion().IsEmpty()) {
1934 // merge hwc node dst rect for virtual screen dirty, in case the main display node skip
1935 curDisplayDirtyManager_->MergeHwcDirtyRect(hwcNode->GetDstRect());
1936 }
1937 }
1938
UpdateSurfaceDirtyAndGlobalDirty()1939 void RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty()
1940 {
1941 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1942 // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
1943 Occlusion::Region accumulatedDirtyRegion;
1944 bool hasMainAndLeashSurfaceDirty = false;
1945 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
1946 [this, &accumulatedDirtyRegion, &hasMainAndLeashSurfaceDirty](RSBaseRenderNode::SharedPtr& nodePtr) {
1947 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
1948 if (!surfaceNode) {
1949 RS_LOGE("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surfaceNode is nullptr");
1950 return;
1951 }
1952 auto dirtyManager = surfaceNode->GetDirtyManager();
1953 RSMainThread::Instance()->GetContext().AddPendingSyncNode(nodePtr);
1954 // 0. update hwc node dirty region and create layer
1955 UpdateHwcNodeDirtyRegionAndCreateLayer(surfaceNode);
1956 // 1. calculate abs dirtyrect and update partialRenderParams
1957 // currently only sync visible region info
1958 surfaceNode->UpdatePartialRenderParams();
1959 if (dirtyManager && dirtyManager->IsCurrentFrameDirty()) {
1960 hasMainAndLeashSurfaceDirty = true;
1961 }
1962 // 2. check surface node dirtyrect need merge into displayDirtyManager
1963 CheckMergeSurfaceDirtysForDisplay(surfaceNode);
1964 // 3. check merge transparent filter when it intersects with pre-dirty
1965 CheckMergeDisplayDirtyByTransparentFilter(surfaceNode, accumulatedDirtyRegion);
1966 });
1967 curDisplayNode_->SetMainAndLeashSurfaceDirty(hasMainAndLeashSurfaceDirty);
1968 CheckMergeDebugRectforRefreshRate(curMainAndLeashSurfaces);
1969 CheckMergeGlobalFilterForDisplay(accumulatedDirtyRegion);
1970 ResetDisplayDirtyRegion();
1971 if (curDisplayDirtyManager_) {
1972 curDisplayDirtyManager_->ClipDirtyRectWithinSurface();
1973 if (curDisplayDirtyManager_->IsActiveSurfaceRectChanged()) {
1974 RS_TRACE_NAME_FMT("ActiveSurfaceRectChanged, form %s to %s",
1975 curDisplayDirtyManager_->GetLastActiveSurfaceRect().ToString().c_str(),
1976 curDisplayDirtyManager_->GetActiveSurfaceRect().ToString().c_str());
1977 curDisplayDirtyManager_->MergeDirtyRect(curDisplayDirtyManager_->GetSurfaceRect());
1978 }
1979 }
1980 curDisplayNode_->ClearCurrentSurfacePos();
1981 std::swap(preMainAndLeashWindowNodesIds_, curMainAndLeashWindowNodesIds_);
1982
1983 #ifdef RS_PROFILER_ENABLED
1984 RS_PROFILER_SET_DIRTY_REGION(accumulatedDirtyRegion);
1985 #endif
1986 }
UpdateHwcNodeEnableByNodeBelow()1987 void RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow()
1988 {
1989 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1990 // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order travelsal
1991 std::vector<RectI> hwcRects;
1992 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
1993 [this, &hwcRects](RSBaseRenderNode::SharedPtr& nodePtr) {
1994 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
1995 if (!surfaceNode) {
1996 RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow surfaceNode is nullptr");
1997 return;
1998 }
1999 // use in temporary scheme to realize DSS
2000 auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2001 if (!hwcNodes.empty() && RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag() &&
2002 RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
2003 UpdateHardwareStateByHwcNodeBackgroundAlpha(hwcNodes);
2004 }
2005 // use end
2006 // disable hwc node with corner radius if intersects with hwc node below
2007 UpdateChildHwcNodeEnableByHwcNodeBelow(hwcRects, surfaceNode);
2008 });
2009 }
2010
UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & appNode)2011 void RSUniRenderVisitor::UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI>& hwcRects,
2012 std::shared_ptr<RSSurfaceRenderNode>& appNode)
2013 {
2014 const auto& hwcNodes = appNode->GetChildHardwareEnabledNodes();
2015 for (auto hwcNode : hwcNodes) {
2016 auto hwcNodePtr = hwcNode.lock();
2017 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2018 continue;
2019 }
2020 UpdateHwcNodeEnableByHwcNodeBelowSelf(hwcRects, hwcNodePtr,
2021 hwcNodePtr->GetIntersectedRoundCornerAABBsSize() != 0);
2022 }
2023 }
2024
UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,std::vector<RectI> & hwcRects)2025 void RSUniRenderVisitor::UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,
2026 std::vector<RectI>& hwcRects)
2027 {
2028 if (!hwcNode || !hwcNode->GetProtectedLayer()) {
2029 return;
2030 }
2031 auto instanceNode = hwcNode->GetInstanceRootNode() ?
2032 hwcNode->GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
2033 if (!instanceNode) {
2034 hwcNode->SetCornerRadiusInfoForDRM({});
2035 return;
2036 }
2037 auto instanceAbsRect = instanceNode->GetAbsDrawRect();
2038 auto instanceCornerRadius = instanceNode->GetGlobalCornerRadius();
2039 if (instanceAbsRect.IsEmpty() || instanceCornerRadius.IsZero() ||
2040 ROSEN_EQ(instanceNode->GetRenderProperties().GetBoundsWidth(), 0.0f)) {
2041 hwcNode->SetCornerRadiusInfoForDRM({});
2042 return;
2043 }
2044 auto hwcGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2045 if (!hwcGeo) {
2046 hwcNode->SetCornerRadiusInfoForDRM({});
2047 return;
2048 }
2049 auto hwcAbsRect = hwcGeo->MapRect(hwcNode->GetSelfDrawRect(), hwcNode->GetTotalMatrix());
2050 hwcAbsRect = hwcAbsRect.IntersectRect(instanceAbsRect);
2051 if (hwcAbsRect.IsEmpty()) {
2052 hwcNode->SetCornerRadiusInfoForDRM({});
2053 return;
2054 }
2055 auto ratio = static_cast<float>(instanceAbsRect.GetWidth()) /
2056 instanceNode->GetRenderProperties().GetBoundsWidth();
2057 std::vector<float> ratioVector = { 0.0f, 0.0f, 0.0f, 0.0f };
2058 bool isIntersectWithRoundCorner =
2059 CheckIfRoundCornerIntersectDRM(ratio, ratioVector, instanceCornerRadius, instanceAbsRect, hwcAbsRect);
2060 // store radius information when drm overlaps with other hwc nodes
2061 if (isIntersectWithRoundCorner) {
2062 for (const auto& rect : hwcRects) {
2063 if (hwcAbsRect.Intersect(rect)) {
2064 std::vector<float> drmCornerRadiusInfo = {
2065 static_cast<float>(hwcAbsRect.GetLeft()), static_cast<float>(hwcAbsRect.GetTop()),
2066 static_cast<float>(hwcAbsRect.GetWidth()), static_cast<float>(hwcAbsRect.GetHeight()),
2067 // get corner radius num by index 0, 1, 2, 3
2068 instanceCornerRadius[0] * ratioVector[0], instanceCornerRadius[1] * ratioVector[1],
2069 instanceCornerRadius[2] * ratioVector[2], instanceCornerRadius[3] * ratioVector[3]};
2070 hwcNode->SetCornerRadiusInfoForDRM(drmCornerRadiusInfo);
2071 return;
2072 }
2073 }
2074 }
2075 hwcNode->SetCornerRadiusInfoForDRM({});
2076 }
2077
CheckIfRoundCornerIntersectDRM(const float & ratio,std::vector<float> & ratioVector,const Vector4f & instanceCornerRadius,const RectI & instanceAbsRect,const RectI & hwcAbsRect)2078 bool RSUniRenderVisitor::CheckIfRoundCornerIntersectDRM(const float& ratio, std::vector<float>& ratioVector,
2079 const Vector4f& instanceCornerRadius, const RectI& instanceAbsRect, const RectI& hwcAbsRect)
2080 {
2081 auto maxRadius = *std::max_element(std::begin(instanceCornerRadius.data_),
2082 std::end(instanceCornerRadius.data_)) * ratio;
2083 bool isIntersectWithRoundCorner = false;
2084 static const std::vector<UIPoint> offsetVecs = { UIPoint { 0, 0 }, UIPoint { 1, 0 },
2085 UIPoint { 0, 1 }, UIPoint { 1, 1 } };
2086 UIPoint offset { instanceAbsRect.GetWidth() - maxRadius, instanceAbsRect.GetHeight() - maxRadius };
2087 UIPoint anchorPoint { instanceAbsRect.GetLeft(), instanceAbsRect.GetTop() };
2088 // if round corners intersect drm, update ratioVectors
2089 for (size_t i = 0; i < offsetVecs.size(); i++) {
2090 auto res = anchorPoint + offset * offsetVecs[i];
2091 if (RectI(res.x_, res.y_, maxRadius, maxRadius).Intersect(hwcAbsRect)) {
2092 isIntersectWithRoundCorner = true;
2093 ratioVector[i] = ratio;
2094 }
2095 }
2096 return isIntersectWithRoundCorner;
2097 }
2098
UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & hwcNode,bool isIntersectWithRoundCorner)2099 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI>& hwcRects,
2100 std::shared_ptr<RSSurfaceRenderNode>& hwcNode, bool isIntersectWithRoundCorner)
2101 {
2102 if (hwcNode->IsHardwareForcedDisabled()) {
2103 if (RSMainThread::CheckIsHdrSurface(*hwcNode)) {
2104 hasUniRenderHdrSurface_ = true;
2105 }
2106 return;
2107 }
2108 auto absBound = RectI();
2109 if (auto geo = hwcNode->GetRenderProperties().GetBoundsGeometry()) {
2110 absBound = geo->GetAbsRect();
2111 } else {
2112 return;
2113 }
2114 if (hwcNode->GetAncoForceDoDirect() || !isIntersectWithRoundCorner) {
2115 hwcRects.emplace_back(absBound);
2116 return;
2117 }
2118 for (const auto& rect : hwcRects) {
2119 for (auto& roundCornerAABB : hwcNode->GetIntersectedRoundCornerAABBs()) {
2120 if (!roundCornerAABB.IntersectRect(rect).IsEmpty()) {
2121 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64
2122 " disabled by corner radius + hwc node below",
2123 hwcNode->GetName().c_str(), hwcNode->GetId());
2124 if (hwcNode->GetProtectedLayer()) {
2125 continue;
2126 }
2127 hwcNode->SetHardwareForcedDisabledState(true);
2128 if (RSMainThread::CheckIsHdrSurface(*hwcNode)) {
2129 hasUniRenderHdrSurface_ = true;
2130 }
2131 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2132 HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
2133 return;
2134 }
2135 }
2136 }
2137 hwcRects.emplace_back(absBound);
2138 }
2139
UpdateSurfaceOcclusionInfo()2140 void RSUniRenderVisitor::UpdateSurfaceOcclusionInfo()
2141 {
2142 allDstCurVisVec_.insert(allDstCurVisVec_.end(), dstCurVisVec_.begin(), dstCurVisVec_.end());
2143 dstCurVisVec_.clear();
2144 }
2145
CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode & surfaceNode) const2146 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode& surfaceNode) const
2147 {
2148 // surfaceNode is transparent
2149 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2150 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2151 Occlusion::Region visibleRegion = hasMirrorDisplay_ ?
2152 surfaceNode.GetVisibleRegionInVirtual() : surfaceNode.GetVisibleRegion();
2153 if (surfaceNode.IsMainWindowType() && !visibleRegion.IsIntersectWith(dirtyRect)) {
2154 return;
2155 }
2156 if (surfaceNode.IsTransparent()) {
2157 RectI transparentDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2158 if (!transparentDirtyRect.IsEmpty()) {
2159 RS_LOGD("CheckMergeDisplayDirtyByTransparent global merge transparent dirty "
2160 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2161 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2162 transparentDirtyRect.ToString().c_str());
2163 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(transparentDirtyRect);
2164 }
2165 }
2166 // surfaceNode has transparent regions
2167 CheckMergeDisplayDirtyByTransparentRegions(surfaceNode);
2168 }
2169
CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode & surfaceNode) const2170 void RSUniRenderVisitor::CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode& surfaceNode) const
2171 {
2172 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2173 if (surfaceNode.GetZorderChanged()) {
2174 RS_LOGD("CheckMergeDisplayDirtyByZorderChanged global merge GetZorderChanged "
2175 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2176 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2177 oldDirtyInSurface.ToString().c_str());
2178 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(oldDirtyInSurface);
2179 }
2180 }
2181
CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode & surfaceNode) const2182 void RSUniRenderVisitor::CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode& surfaceNode) const
2183 {
2184 RectI lastFrameSurfacePos = curDisplayNode_->GetLastFrameSurfacePos(surfaceNode.GetId());
2185 RectI currentFrameSurfacePos = curDisplayNode_->GetCurrentFrameSurfacePos(surfaceNode.GetId());
2186 if (surfaceNode.GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
2187 RS_LOGD("CheckMergeDisplayDirtyByPosChanged global merge surface pos changed "
2188 "%{public}s: global dirty %{public}s, lastFrameRect %{public}s currentFrameRect %{public}s",
2189 surfaceNode.GetName().c_str(),
2190 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2191 lastFrameSurfacePos.ToString().c_str(), currentFrameSurfacePos.ToString().c_str());
2192 if (!lastFrameSurfacePos.IsEmpty()) {
2193 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(lastFrameSurfacePos);
2194 }
2195 if (!currentFrameSurfacePos.IsEmpty()) {
2196 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(currentFrameSurfacePos);
2197 }
2198 }
2199 }
2200
CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode & surfaceNode) const2201 void RSUniRenderVisitor::CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode& surfaceNode) const
2202 {
2203 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2204 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2205 bool isShadowDisappear = !surfaceNode.GetRenderProperties().IsShadowValid() &&
2206 surfaceNode.IsShadowValidLastFrame();
2207 if (surfaceNode.GetRenderProperties().IsShadowValid() || isShadowDisappear) {
2208 RectI shadowDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2209 // There are two situation here:
2210 // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
2211 // dirtyRect == surfaceNode.GetOldDirtyInSurface()
2212 // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
2213 // dirtyRect > surfaceNode.GetOldDirtyInSurface()
2214 // So we should always merge dirtyRect here.
2215 if (!shadowDirtyRect.IsEmpty()) {
2216 RS_LOGD("CheckMergeDisplayDirtyByShadowChanged global merge ShadowValid %{public}s: "
2217 "global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2218 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2219 dirtyRect.ToString().c_str());
2220 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRect);
2221 }
2222 if (isShadowDisappear) {
2223 surfaceNode.SetShadowValidLastFrame(false);
2224 }
2225 }
2226 }
2227
CheckMergeDisplayDirtyBySurfaceChanged() const2228 void RSUniRenderVisitor::CheckMergeDisplayDirtyBySurfaceChanged() const
2229 {
2230 std::vector<RectI> surfaceChangedRects = curDisplayNode_->GetSurfaceChangedRects();
2231 for (auto& surfaceChangedRect : surfaceChangedRects) {
2232 if (!surfaceChangedRect.IsEmpty()) {
2233 RS_LOGD("CheckMergeDisplayDirtyBySurfaceChanged global merge Surface closed, global dirty %{public}s,"
2234 "add rect %{public}s",
2235 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2236 surfaceChangedRect.ToString().c_str());
2237 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(surfaceChangedRect);
2238 }
2239 }
2240 }
2241
CheckMergeDisplayDirtyByAttractionChanged(RSSurfaceRenderNode & surfaceNode) const2242 void RSUniRenderVisitor::CheckMergeDisplayDirtyByAttractionChanged(RSSurfaceRenderNode& surfaceNode) const
2243 {
2244 if (surfaceNode.GetRenderProperties().IsAttractionValid()) {
2245 auto attractionDirtyRect = surfaceNode.GetRenderProperties().GetAttractionEffectCurrentDirtyRegion();
2246 RS_LOGD("CheckMergeDisplayDirtyByAttraction global merge attraction %{public}s: global dirty %{public}s,"
2247 "add rect %{public}s", surfaceNode.GetName().c_str(),
2248 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2249 attractionDirtyRect.ToString().c_str());
2250 auto boundsGeometry = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
2251 if (boundsGeometry) {
2252 Drawing::Rect rect(attractionDirtyRect.GetLeft(), attractionDirtyRect.GetTop(),
2253 attractionDirtyRect.GetRight(), attractionDirtyRect.GetBottom());
2254 Drawing::Rect tempRect;
2255 boundsGeometry->GetMatrix().MapRect(tempRect, rect);
2256 attractionDirtyRect =
2257 RectI(tempRect.GetLeft(), tempRect.GetTop(), tempRect.GetWidth(), tempRect.GetHeight());
2258 }
2259 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(attractionDirtyRect);
2260 }
2261 }
2262
CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2263 void RSUniRenderVisitor::CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2264 {
2265 if (surfaceNode->GetDirtyManager() == nullptr || curDisplayNode_->GetDirtyManager() == nullptr) {
2266 return;
2267 }
2268 // 1 Handles the case of transparent surface, merge transparent dirty rect
2269 CheckMergeDisplayDirtyByTransparent(*surfaceNode);
2270 // 2 Zorder changed case, merge surface dest Rect
2271 CheckMergeDisplayDirtyByZorderChanged(*surfaceNode);
2272 // 3 surfacePos chanded case, merge surface lastframe pos or curframe pos
2273 CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2274 // 4 shadow disappear and appear case.
2275 CheckMergeDisplayDirtyByShadowChanged(*surfaceNode);
2276 // 5 handle last and curframe surfaces which appear or disappear case
2277 CheckMergeDisplayDirtyBySurfaceChanged();
2278 // 6 handle attraction effect which appear or disappear case
2279 CheckMergeDisplayDirtyByAttractionChanged(*surfaceNode);
2280 // More: any other display dirty caused by surfaceNode should be added here like CheckMergeDisplayDirtByXXX
2281 }
2282
CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode & surfaceNode) const2283 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode& surfaceNode) const
2284 {
2285 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2286 if (surfaceNode.HasContainerWindow()) {
2287 // If a surface's dirty is intersect with container region (which can be considered transparent)
2288 // should be added to display dirty region.
2289 // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
2290 auto containerRegion = surfaceNode.GetContainerRegion();
2291 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2292 auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
2293 if (!containerDirtyRegion.IsEmpty()) {
2294 RS_LOGD("CheckMergeDisplayDirtyByContainer global merge containerDirtyRegion "
2295 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2296 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2297 containerDirtyRegion.GetRegionInfo().c_str());
2298 // plan: we can use surfacenode's absrect as containerRegion's bound
2299 const auto& rect = containerRegion.GetBoundRef();
2300 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(
2301 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2302 }
2303 } else {
2304 // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
2305 // transparent region and opaque region in adjacent frame, may cause displaydirty region incomplete after
2306 // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
2307 // which include transparent region but not counted in display dirtyregion)
2308 if (!surfaceNode.IsNodeDirty()) {
2309 return;
2310 }
2311 auto transparentRegion = surfaceNode.GetTransparentRegion();
2312 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2313 Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
2314 if (!transparentDirtyRegion.IsEmpty()) {
2315 RS_LOGD("CheckMergeDisplayDirtyByTransparentRegions global merge TransparentDirtyRegion "
2316 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2317 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2318 transparentDirtyRegion.GetRegionInfo().c_str());
2319 const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
2320 for (const auto& rect : rects) {
2321 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(RectI{ rect.left_, rect.top_,
2322 rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2323 }
2324 }
2325 }
2326 }
2327
CheckMergeDisplayDirtyByTransparentFilter(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedDirtyRegion)2328 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter(
2329 std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2330 Occlusion::Region& accumulatedDirtyRegion)
2331 {
2332 auto disappearedSurfaceRegionBelowCurrent =
2333 curDisplayNode_->GetDisappearedSurfaceRegionBelowCurrent(surfaceNode->GetId());
2334 accumulatedDirtyRegion.OrSelf(disappearedSurfaceRegionBelowCurrent);
2335 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2336 auto filterVecIter = transparentCleanFilter_.find(surfaceNode->GetId());
2337 if (filterVecIter != transparentCleanFilter_.end()) {
2338 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter surface:%{public}s "
2339 "has transparentCleanFilter", surfaceNode->GetName().c_str());
2340 // check accumulatedDirtyRegion influence filter nodes which in the current surface
2341 for (auto it = filterVecIter->second.begin(); it != filterVecIter->second.end(); ++it) {
2342 auto filterNode = nodeMap.GetRenderNode(it->first);
2343 if (filterNode == nullptr) {
2344 continue;
2345 }
2346 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
2347 auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
2348 if (!filterDirtyRegion.IsEmpty()) {
2349 if (filterNode->GetRenderProperties().GetBackgroundFilter() ||
2350 filterNode->GetRenderProperties().GetNeedDrawBehindWindow()) {
2351 // backgroundfilter affected by below dirty
2352 filterNode->MarkFilterStatusChanged(false, false);
2353 }
2354 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter global merge filterRegion "
2355 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode->GetName().c_str(),
2356 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2357 it->second.ToString().c_str());
2358 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
2359 if (filterNode->GetRenderProperties().GetFilter()) {
2360 // foregroundfilter affected by below dirty
2361 filterNode->MarkFilterStatusChanged(true, false);
2362 }
2363 } else {
2364 globalFilter_.insert(*it);
2365 }
2366 filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
2367 }
2368 }
2369 auto surfaceDirtyRegion = Occlusion::Region{
2370 Occlusion::Rect{ surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion() } };
2371 accumulatedDirtyRegion.OrSelf(surfaceDirtyRegion);
2372 }
2373
UpdateDisplayDirtyAndExtendVisibleRegion()2374 void RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion()
2375 {
2376 if (curDisplayNode_ == nullptr) {
2377 RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion curDisplayNode_ is nullptr");
2378 return;
2379 }
2380 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2381 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2382 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2383 [this, &nodeMap](RSBaseRenderNode::SharedPtr& nodePtr) {
2384 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2385 if (surfaceNode == nullptr) {
2386 RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion surfaceNode is nullptr");
2387 return;
2388 }
2389 if (!surfaceNode->IsMainWindowType()) {
2390 return;
2391 }
2392 Occlusion::Region extendRegion;
2393 if (!surfaceNode->GetVisibleRegion().IsEmpty()) {
2394 ProcessFilterNodeObscured(surfaceNode, extendRegion, nodeMap);
2395 }
2396 surfaceNode->UpdateExtendVisibleRegion(extendRegion);
2397 });
2398 }
2399
ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & extendRegion,const RSRenderNodeMap & nodeMap)2400 void RSUniRenderVisitor::ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
2401 Occlusion::Region& extendRegion, const RSRenderNodeMap& nodeMap)
2402 {
2403 const auto& visibleFilterChild = surfaceNode->GetVisibleFilterChild();
2404 auto visibleRegion = surfaceNode->GetVisibleRegion();
2405 auto currentFrameDirtyRegion = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
2406 auto isTransparent = surfaceNode->IsTransparent();
2407 for (const auto& child : visibleFilterChild) {
2408 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2409 if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
2410 continue;
2411 }
2412 MarkBlurIntersectWithDRM(filterNode);
2413 auto filterRect = filterNode->GetOldDirtyInSurface();
2414 auto visibleRects = visibleRegion.GetRegionRectIs();
2415 auto iter = std::find_if(visibleRects.begin(), visibleRects.end(), [&filterRect](const auto& rect) {
2416 return filterRect.IsInsideOf(rect);
2417 });
2418 if (iter != visibleRects.end()) {
2419 continue;
2420 }
2421 if (!visibleRegion.IsIntersectWith(filterRect)) {
2422 continue;
2423 }
2424 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ filterRect } };
2425 extendRegion = extendRegion.Or(filterRegion);
2426 if (!isTransparent && filterRect.Intersect(currentFrameDirtyRegion)) {
2427 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(filterRect);
2428 }
2429 }
2430 }
2431
UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2432 void RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2433 {
2434 if (surfaceNode == nullptr) {
2435 return;
2436 }
2437 if (surfaceNode->HasBlurFilter()) {
2438 surfaceNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
2439 }
2440 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2441 for (auto& child : surfaceNode->GetVisibleFilterChild()) {
2442 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2443 if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
2444 continue;
2445 }
2446 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode "
2447 "surfaceNode: %s, filterNode:[%lld], IsOccludedByFilterCache:%d", surfaceNode->GetName().c_str(),
2448 filterNode->GetId(), surfaceNode->IsOccludedByFilterCache());
2449 filterNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
2450 }
2451 }
2452
CheckMergeGlobalFilterForDisplay(Occlusion::Region & accumulatedDirtyRegion)2453 void RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay(Occlusion::Region& accumulatedDirtyRegion)
2454 {
2455 // [planning] if not allowed containerNode filter, The following processing logic can be removed
2456 // Recursively traverses container nodes need filter
2457 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2458 for (auto it = containerFilter_.begin(); it != containerFilter_.end(); ++it) {
2459 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(it->first);
2460 if (filterNode == nullptr) {
2461 continue;
2462 }
2463 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
2464 auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
2465 RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeGlobalFilterForDisplay::filternode:%" PRIu64
2466 ", filterRect:%s, dirtyRegion:%s",
2467 filterNode->GetId(), it->second.ToString().c_str(), accumulatedDirtyRegion.GetRegionInfo().c_str());
2468 if (!filterDirtyRegion.IsEmpty()) {
2469 RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
2470 "global dirty %{public}s, add container filterRegion %{public}s",
2471 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2472 (it->second).ToString().c_str());
2473 if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
2474 filterNode->MarkFilterStatusChanged(false, false); // background filter affected by below dirty
2475 }
2476 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
2477 if (filterNode->GetRenderProperties().GetFilter()) {
2478 filterNode->MarkFilterStatusChanged(true, false); // foreground filter affected by below dirty
2479 }
2480 } else {
2481 globalFilter_.insert(*it);
2482 }
2483 filterNode->UpdateFilterCacheWithSelfDirty();
2484 filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
2485 }
2486 UpdateDisplayDirtyAndExtendVisibleRegion();
2487 CheckMergeFilterDirtyByIntersectWithDirty(globalFilter_, true);
2488 }
2489
CollectEffectInfo(RSRenderNode & node)2490 void RSUniRenderVisitor::CollectEffectInfo(RSRenderNode& node)
2491 {
2492 auto nodeParent = node.GetParent().lock();
2493 if (nodeParent == nullptr) {
2494 return;
2495 }
2496 if (node.GetRenderProperties().NeedFilter() || node.ChildHasVisibleFilter()) {
2497 nodeParent->SetChildHasVisibleFilter(true);
2498 nodeParent->UpdateVisibleFilterChild(node);
2499 }
2500 if (node.GetRenderProperties().GetUseEffect() || node.ChildHasVisibleEffect()) {
2501 nodeParent->SetChildHasVisibleEffect(true);
2502 nodeParent->UpdateVisibleEffectChild(node);
2503 }
2504 if (node.GetSharedTransitionParam() || node.ChildHasSharedTransition()) {
2505 nodeParent->SetChildHasSharedTransition(true);
2506 }
2507 }
2508
PostPrepare(RSRenderNode & node,bool subTreeSkipped)2509 void RSUniRenderVisitor::PostPrepare(RSRenderNode& node, bool subTreeSkipped)
2510 {
2511 auto curDirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
2512 if (!curDirtyManager) {
2513 return;
2514 }
2515 auto isOccluded = curSurfaceNode_ ?
2516 curSurfaceNode_->IsMainWindowType() && curSurfaceNode_->GetVisibleRegion().IsEmpty() : false;
2517 if (subTreeSkipped && !isOccluded) {
2518 UpdateHwcNodeRectInSkippedSubTree(node);
2519 CheckFilterNodeInSkippedSubTreeNeedClearCache(node, *curDirtyManager);
2520 UpdateSubSurfaceNodeRectInSkippedSubTree(node);
2521 }
2522 if (node.GetRenderProperties().NeedFilter()) {
2523 UpdateHwcNodeEnableByFilterRect(
2524 curSurfaceNode_, node.GetOldDirtyInSurface(), NeedPrepareChindrenInReverseOrder(node));
2525 auto globalFilterRect = (node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren()) ?
2526 GetVisibleEffectDirty(node) : node.GetOldDirtyInSurface();
2527 node.CalVisibleFilterRect(prepareClipRect_);
2528 node.MarkClearFilterCacheIfEffectChildrenChanged();
2529 CollectFilterInfoAndUpdateDirty(node, *curDirtyManager, globalFilterRect);
2530 node.SetGlobalAlpha(curAlpha_);
2531 }
2532 CollectEffectInfo(node);
2533 node.MapAndUpdateChildrenRect();
2534 node.UpdateSubTreeInfo(prepareClipRect_);
2535 node.UpdateLocalDrawRect();
2536 node.UpdateAbsDrawRect();
2537 node.ResetChangeState();
2538 if (isDrawingCacheEnabled_) {
2539 node.UpdateDrawingCacheInfoAfterChildren();
2540 }
2541 if (auto nodeParent = node.GetParent().lock()) {
2542 nodeParent->UpdateChildUifirstSupportFlag(node.GetUifirstSupportFlag());
2543 nodeParent->OpincUpdateNodeSupportFlag(node.OpincGetNodeSupportFlag());
2544 }
2545 auto& stagingRenderParams = node.GetStagingRenderParams();
2546 if (stagingRenderParams != nullptr) {
2547 if (node.GetSharedTransitionParam() && node.GetRenderProperties().GetSandBox()) {
2548 stagingRenderParams->SetAlpha(curAlpha_);
2549 } else {
2550 stagingRenderParams->SetAlpha(node.GetRenderProperties().GetAlpha());
2551 }
2552 }
2553
2554 // planning: only do this if node is dirty
2555 node.UpdateRenderParams();
2556
2557 // add if node is dirty
2558 node.AddToPendingSyncList();
2559 }
2560
MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const2561 void RSUniRenderVisitor::MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const
2562 {
2563 if (!RSSystemProperties::GetDrmMarkedFilterEnabled()) {
2564 return;
2565 }
2566 static std::vector<std::string> drmKeyWins = { "SCBVolumePanel", "SCBBannerNotification" };
2567 auto appWindowNodeId = node->GetInstanceRootNodeId();
2568 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2569 auto appWindowNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
2570 if (appWindowNode == nullptr) {
2571 return;
2572 }
2573 for (const auto& win : drmKeyWins) {
2574 if (appWindowNode->GetName().find(win) == std::string::npos) {
2575 continue;
2576 }
2577 for (auto& drmNode : drmNodes_) {
2578 auto drmNodePtr = drmNode.lock();
2579 if (drmNodePtr == nullptr) {
2580 continue;
2581 }
2582 bool isIntersect =
2583 drmNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(node->GetFilterRegion());
2584 if (isIntersect) {
2585 node->MarkBlurIntersectWithDRM(true, RSMainThread::Instance()->GetGlobalDarkColorMode());
2586 }
2587 }
2588 }
2589 }
2590
CheckFilterNodeInSkippedSubTreeNeedClearCache(const RSRenderNode & rootNode,RSDirtyRegionManager & dirtyManager)2591 void RSUniRenderVisitor::CheckFilterNodeInSkippedSubTreeNeedClearCache(
2592 const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager)
2593 {
2594 bool rotationChanged = curDisplayNode_ ?
2595 curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
2596 bool rotationStatusChanged = curDisplayNode_ ?
2597 curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
2598 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2599 for (auto& child : rootNode.GetVisibleFilterChild()) {
2600 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
2601 if (filterNode == nullptr) {
2602 continue;
2603 }
2604 RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterNodeInSkippedSubTreeNeedClearCache node[%lld]", filterNode->GetId());
2605 if (auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode)) {
2606 UpdateRotationStatusForEffectNode(*effectNode);
2607 }
2608 filterNode->CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
2609 filterNode->MarkClearFilterCacheIfEffectChildrenChanged();
2610 if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
2611 filterNode->UpdateFilterCacheWithBelowDirty(dirtyManager, false);
2612 }
2613 RectI filterRect;
2614 filterNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, prepareClipRect_);
2615 UpdateHwcNodeEnableByFilterRect(curSurfaceNode_, filterNode->GetOldDirtyInSurface());
2616 CollectFilterInfoAndUpdateDirty(*filterNode, dirtyManager, filterRect);
2617 }
2618 }
2619
UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode & rootNode)2620 void RSUniRenderVisitor::UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
2621 {
2622 if (!curSurfaceNode_ || RS_PROFILER_SHOULD_BLOCK_HWCNODE()) {
2623 return;
2624 }
2625 const auto& hwcNodes = curSurfaceNode_->GetChildHardwareEnabledNodes();
2626 if (hwcNodes.empty()) {
2627 return;
2628 }
2629 for (auto hwcNode : hwcNodes) {
2630 auto hwcNodePtr = hwcNode.lock();
2631 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree() || hwcNodePtr->GetCalcRectInPrepare()) {
2632 continue;
2633 }
2634 const auto& property = hwcNodePtr->GetRenderProperties();
2635 auto geoPtr = property.GetBoundsGeometry();
2636 if (geoPtr == nullptr) {
2637 return;
2638 }
2639 auto originalMatrix = geoPtr->GetMatrix();
2640 auto matrix = Drawing::Matrix();
2641 auto parent = hwcNodePtr->GetParent().lock();
2642 bool findInRoot = parent ? parent->GetId() == rootNode.GetId() : false;
2643 while (parent && parent->GetType() != RSRenderNodeType::DISPLAY_NODE) {
2644 if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
2645 matrix.PostConcat(opt.value());
2646 } else {
2647 break;
2648 }
2649 parent = parent->GetParent().lock();
2650 if (!parent) {
2651 break;
2652 }
2653 findInRoot = parent->GetId() == rootNode.GetId() ? true : findInRoot;
2654 }
2655 if (!findInRoot) {
2656 continue;
2657 }
2658 if (parent) {
2659 const auto& parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
2660 if (parentGeoPtr) {
2661 matrix.PostConcat(parentGeoPtr->GetMatrix());
2662 }
2663 }
2664 auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
2665 auto& properties = hwcNodePtr->GetMutableRenderProperties();
2666 auto offset = std::nullopt;
2667 properties.UpdateGeometryByParent(&matrix, offset);
2668 matrix.PreConcat(originalMatrix);
2669 Drawing::Rect bounds = Drawing::Rect(0, 0, properties.GetBoundsWidth(), properties.GetBoundsHeight());
2670 Drawing::Rect absRect;
2671 matrix.MapRect(absRect, bounds);
2672 RectI rect = {std::round(absRect.left_), std::round(absRect.top_),
2673 std::round(absRect.GetWidth()), std::round(absRect.GetHeight())};
2674 UpdateDstRect(*hwcNodePtr, rect, prepareClipRect_);
2675 UpdateSrcRect(*hwcNodePtr, matrix, rect);
2676 UpdateHwcNodeByTransform(*hwcNodePtr);
2677 UpdateHwcNodeEnableBySrcRect(*hwcNodePtr);
2678 UpdateHwcNodeEnableByBufferSize(*hwcNodePtr);
2679 hwcNodePtr->SetTotalMatrix(matrix);
2680 hwcNodePtr->SetOldDirtyInSurface(geoPtr->MapRect(hwcNodePtr->GetSelfDrawRect(), matrix));
2681 }
2682 }
2683
UpdateHardwareStateByHwcNodeBackgroundAlpha(const std::vector<std::weak_ptr<RSSurfaceRenderNode>> & hwcNodes)2684 void RSUniRenderVisitor::UpdateHardwareStateByHwcNodeBackgroundAlpha(
2685 const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes)
2686 {
2687 std::list<RectI> hwcRects;
2688 for (size_t i = 0; i < hwcNodes.size(); i++) {
2689 auto hwcNodePtr = hwcNodes[i].lock();
2690 if (!hwcNodePtr) {
2691 continue;
2692 }
2693 if (!hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled()) {
2694 hwcRects.push_back(hwcNodePtr->GetDstRect());
2695 } else if (hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled() &&
2696 hwcRects.size() != 0 && IsNodeAboveInsideOfNodeBelow(hwcNodePtr->GetDstRect(), hwcRects)) {
2697 continue;
2698 } else {
2699 hwcNodePtr->SetHardwareForcedDisabledState(true);
2700 }
2701 }
2702 }
2703
IsNodeAboveInsideOfNodeBelow(const RectI & rectAbove,std::list<RectI> & hwcNodeRectList)2704 bool RSUniRenderVisitor::IsNodeAboveInsideOfNodeBelow(const RectI& rectAbove, std::list<RectI>& hwcNodeRectList)
2705 {
2706 for (auto rectBelow: hwcNodeRectList) {
2707 if (rectAbove.IsInsideOf(rectBelow)) {
2708 return true;
2709 }
2710 }
2711 return false;
2712 }
2713
CalcHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode> & node,const RectI & filterRect,bool isReverseOrder)2714 void RSUniRenderVisitor::CalcHwcNodeEnableByFilterRect(
2715 std::shared_ptr<RSSurfaceRenderNode>& node, const RectI& filterRect, bool isReverseOrder)
2716 {
2717 if (!node) {
2718 return;
2719 }
2720 auto dstRect = node->GetDstRect();
2721 bool isIntersect = !dstRect.IntersectRect(filterRect).IsEmpty();
2722 if (isIntersect) {
2723 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by filter rect",
2724 node->GetName().c_str(), node->GetId());
2725 node->SetIsHwcPendingDisabled(true);
2726 node->SetHardwareForcedDisabledState(true);
2727 node->SetHardWareDisabledByReverse(isReverseOrder);
2728 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
2729 HwcDisabledReasons::DISABLED_BY_FLITER_RECT, node->GetName());
2730 }
2731 }
2732
UpdateHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode> & node,const RectI & filterRect,bool isReverseOrder)2733 void RSUniRenderVisitor::UpdateHwcNodeEnableByFilterRect(
2734 std::shared_ptr<RSSurfaceRenderNode>& node, const RectI& filterRect, bool isReverseOrder)
2735 {
2736 if (filterRect.IsEmpty()) {
2737 return;
2738 }
2739 if (!node) {
2740 const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
2741 if (selfDrawingNodes.empty()) {
2742 return;
2743 }
2744 for (auto hwcNode : selfDrawingNodes) {
2745 CalcHwcNodeEnableByFilterRect(hwcNode, filterRect, isReverseOrder);
2746 }
2747 } else {
2748 const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
2749 if (hwcNodes.empty()) {
2750 return;
2751 }
2752 for (auto hwcNode : hwcNodes) {
2753 auto hwcNodePtr = hwcNode.lock();
2754 CalcHwcNodeEnableByFilterRect(hwcNodePtr, filterRect, isReverseOrder);
2755 }
2756 }
2757 }
2758
UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode> & node)2759 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode>& node)
2760 {
2761 auto cleanFilter = transparentCleanFilter_.find(node->GetId());
2762 bool cleanFilterFound = (cleanFilter != transparentCleanFilter_.end());
2763 auto dirtyFilter = transparentDirtyFilter_.find(node->GetId());
2764 bool dirtyFilterFound = (dirtyFilter != transparentDirtyFilter_.end());
2765 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2766 for (auto it = curMainAndLeashSurfaces.rbegin(); it != curMainAndLeashSurfaces.rend(); ++it) {
2767 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
2768 if (surfaceNode == nullptr) {
2769 continue;
2770 }
2771 if (surfaceNode->GetId() == node->GetId()) {
2772 return;
2773 }
2774 const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2775 if (hwcNodes.empty()) {
2776 continue;
2777 }
2778 for (auto hwcNode : hwcNodes) {
2779 auto hwcNodePtr = hwcNode.lock();
2780 if (!hwcNodePtr || hwcNodePtr->IsHardwareForcedDisabled() ||
2781 !hwcNodePtr->GetRenderProperties().GetBoundsGeometry()) {
2782 continue;
2783 }
2784 if (cleanFilterFound) {
2785 UpdateHwcNodeEnableByGlobalCleanFilter(cleanFilter->second, *hwcNodePtr);
2786 if (hwcNodePtr->IsHardwareForcedDisabled()) {
2787 ProcessAncoNode(hwcNodePtr);
2788 continue;
2789 }
2790 }
2791 if (!dirtyFilterFound) {
2792 continue;
2793 }
2794 for (auto filter = dirtyFilter->second.begin(); filter != dirtyFilter->second.end(); ++filter) {
2795 if (hwcNodePtr->GetRenderProperties().GetBoundsGeometry()->GetAbsRect().Intersect(filter->second)) {
2796 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentDirtyFilter",
2797 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2798 hwcNodePtr->SetHardwareForcedDisabledState(true);
2799 ProcessAncoNode(hwcNodePtr);
2800 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
2801 HwcDisabledReasons::DISABLED_BY_TRANSPARENT_DIRTY_FLITER, hwcNodePtr->GetName());
2802 break;
2803 }
2804 }
2805 }
2806 }
2807 }
2808
UpdateHwcNodeEnableByGlobalCleanFilter(const std::vector<std::pair<NodeId,RectI>> & cleanFilter,RSSurfaceRenderNode & hwcNodePtr)2809 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalCleanFilter(
2810 const std::vector<std::pair<NodeId, RectI>>& cleanFilter, RSSurfaceRenderNode& hwcNodePtr)
2811 {
2812 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2813 bool intersectedWithAIBar = false;
2814 bool checkDrawAIBar = false;
2815 for (auto filter = cleanFilter.begin(); filter != cleanFilter.end(); ++filter) {
2816 auto geo = hwcNodePtr.GetRenderProperties().GetBoundsGeometry();
2817 if (!geo) {
2818 return;
2819 }
2820 if (!geo->GetAbsRect().IntersectRect(filter->second).IsEmpty()) {
2821 auto& rendernode = nodeMap.GetRenderNode<RSRenderNode>(filter->first);
2822 if (rendernode == nullptr) {
2823 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: rendernode is null");
2824 continue;
2825 }
2826
2827 if (rendernode->IsAIBarFilter()) {
2828 intersectedWithAIBar = true;
2829 if (rendernode->IsAIBarFilterCacheValid()) {
2830 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: skip intersection for using cache");
2831 continue;
2832 } else if (RSSystemProperties::GetHveFilterEnabled()) {
2833 checkDrawAIBar = true;
2834 continue;
2835 }
2836 }
2837
2838 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentCleanFilter",
2839 hwcNodePtr.GetName().c_str(), hwcNodePtr.GetId());
2840 hwcNodePtr.SetHardwareForcedDisabledState(true);
2841 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr.GetId(),
2842 HwcDisabledReasons::DISABLED_BY_TRANSPARENT_CLEAN_FLITER, hwcNodePtr.GetName());
2843 break;
2844 }
2845 }
2846 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64", checkDrawAIBar:%d, intersectedWithAIBar:%d",
2847 hwcNodePtr.GetName().c_str(), hwcNodePtr.GetId(), checkDrawAIBar, intersectedWithAIBar);
2848 if (checkDrawAIBar) {
2849 hwcNodePtr.SetHardwareNeedMakeImage(checkDrawAIBar);
2850 }
2851 if (intersectedWithAIBar) {
2852 hwcNodePtr.SetIntersectWithAIBar(intersectedWithAIBar);
2853 }
2854 }
2855
ResetSubSurfaceNodesCalState(std::vector<std::pair<NodeId,std::weak_ptr<RSSurfaceRenderNode>>> & subSurfaceNodes)2856 inline static void ResetSubSurfaceNodesCalState(
2857 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>>& subSurfaceNodes)
2858 {
2859 for (auto& [id, node] : subSurfaceNodes) {
2860 auto subSurfaceNodePtr = node.lock();
2861 if (!subSurfaceNodePtr) {
2862 continue;
2863 }
2864 subSurfaceNodePtr->SetCalcRectInPrepare(false);
2865 }
2866 }
2867
UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode & rootNode)2868 void RSUniRenderVisitor::UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
2869 {
2870 if (!curSurfaceNode_ || !curSurfaceDirtyManager_) {
2871 return;
2872 }
2873 auto rootGeo = rootNode.GetRenderProperties().GetBoundsGeometry();
2874 if (!rootGeo) {
2875 return;
2876 }
2877
2878 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
2879 curSurfaceNode_->GetAllSubSurfaceNodes(allSubSurfaceNodes);
2880 for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
2881 auto subSurfaceNodePtr = subSurfaceNode.lock();
2882 Drawing::Matrix absMatrix;
2883 if (!subSurfaceNodePtr || subSurfaceNodePtr->GetCalcRectInPrepare() ||
2884 !subSurfaceNodePtr->GetAbsMatrixReverse(rootNode, absMatrix)) {
2885 continue;
2886 }
2887
2888 Drawing::RectF absDrawRect;
2889 absMatrix.MapRect(absDrawRect, RSPropertiesPainter::Rect2DrawingRect(subSurfaceNodePtr->GetSelfDrawRect()));
2890 RectI subSurfaceRect = RectI(absDrawRect.GetLeft(), absDrawRect.GetTop(),
2891 absDrawRect.GetWidth(), absDrawRect.GetHeight());
2892
2893 subSurfaceNodePtr->SetOldDirtyInSurface(subSurfaceRect.IntersectRect(prepareClipRect_));
2894 UpdateNodeVisibleRegion(*subSurfaceNodePtr);
2895 UpdateDstRect(*subSurfaceNodePtr, subSurfaceRect, prepareClipRect_);
2896 subSurfaceNodePtr->SetCalcRectInPrepare(true);
2897 if (subSurfaceNodePtr->IsLeashOrMainWindow()) {
2898 curMainAndLeashWindowNodesIds_.push(subSurfaceNodePtr->GetId());
2899 curDisplayNode_->RecordMainAndLeashSurfaces(subSurfaceNodePtr);
2900 curDisplayNode_->UpdateSurfaceNodePos(
2901 subSurfaceNodePtr->GetId(), subSurfaceNodePtr->GetOldDirtyInSurface());
2902 if (auto subSurfaceDirtyManager = subSurfaceNodePtr->GetDirtyManager()) {
2903 subSurfaceDirtyManager->MergeDirtyRect(subSurfaceNodePtr->GetOldDirtyInSurface().IntersectRect(
2904 curSurfaceDirtyManager_->GetCurrentFrameDirtyRegion()));
2905 }
2906 CollectOcclusionInfoForWMS(*subSurfaceNodePtr);
2907 subSurfaceNodePtr->UpdateRenderParams();
2908 }
2909 }
2910 ResetSubSurfaceNodesCalState(allSubSurfaceNodes);
2911 }
2912
GetVisibleEffectDirty(RSRenderNode & node) const2913 RectI RSUniRenderVisitor::GetVisibleEffectDirty(RSRenderNode& node) const
2914 {
2915 RectI childEffectRect;
2916 auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2917 for (auto& nodeId : node.GetVisibleEffectChild()) {
2918 if (auto& subnode = nodeMap.GetRenderNode<RSRenderNode>(nodeId)) {
2919 childEffectRect = childEffectRect.JoinRect(subnode->GetOldDirtyInSurface());
2920 }
2921 }
2922 return childEffectRect;
2923 }
2924
CollectFilterInfoAndUpdateDirty(RSRenderNode & node,RSDirtyRegionManager & dirtyManager,const RectI & globalFilterRect)2925 void RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty(RSRenderNode& node,
2926 RSDirtyRegionManager& dirtyManager, const RectI& globalFilterRect)
2927 {
2928 bool isNodeAddedToTransparentCleanFilters = false;
2929 if (curSurfaceNode_) {
2930 bool isIntersect = dirtyManager.GetCurrentFrameDirtyRegion().Intersect(globalFilterRect);
2931 if (isIntersect) {
2932 dirtyManager.MergeDirtyRect(globalFilterRect);
2933 } else {
2934 curSurfaceNoBelowDirtyFilter_.insert({node.GetId(), globalFilterRect});
2935 }
2936 if (node.GetRenderProperties().GetFilter()) {
2937 node.UpdateFilterCacheWithBelowDirty(dirtyManager, true);
2938 }
2939 node.UpdateFilterCacheWithSelfDirty();
2940 if (curSurfaceNode_->IsTransparent()) {
2941 globalFilterRects_.emplace_back(globalFilterRect);
2942 if (!isIntersect || (isIntersect && (node.GetRenderProperties().GetBackgroundFilter() ||
2943 node.GetRenderProperties().GetNeedDrawBehindWindow()) && !node.IsBackgroundInAppOrNodeSelfDirty())) {
2944 // record nodes which has transparent clean filter
2945 RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInfoAndUpdateDirty::surfaceNode:%s, add node[%lld] to "
2946 "transparentCleanFilter", curSurfaceNode_->GetName().c_str(), node.GetId());
2947 transparentCleanFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalFilterRect});
2948 isNodeAddedToTransparentCleanFilters = true;
2949 }
2950 if (isIntersect) {
2951 transparentDirtyFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalFilterRect});
2952 RS_LOGD("RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty global merge transparentDirtyFilter "
2953 "%{public}s, global dirty %{public}s, add rect %{public}s", curSurfaceNode_->GetName().c_str(),
2954 curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
2955 globalFilterRect.ToString().c_str());
2956 curDisplayDirtyManager_->MergeDirtyRect(globalFilterRect);
2957 }
2958 } else {
2959 // record surface nodes and nodes in surface which has clean filter
2960 globalFilter_.insert({node.GetId(), globalFilterRect});
2961 }
2962 } else {
2963 globalFilterRects_.emplace_back(globalFilterRect);
2964 // record container nodes which need filter
2965 containerFilter_.insert({node.GetId(), globalFilterRect});
2966 }
2967 if (curSurfaceNode_ && !isNodeAddedToTransparentCleanFilters) {
2968 node.PostPrepareForBlurFilterNode(dirtyManager, needRequestNextVsync_);
2969 }
2970 }
2971
UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode & node)2972 void RSUniRenderVisitor::UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode& node)
2973 {
2974 if (!node.IsLeashWindow()) {
2975 return;
2976 }
2977 auto& property = node.GetMutableRenderProperties();
2978 auto& geoPtr = (property.GetBoundsGeometry());
2979 if (geoPtr == nullptr) {
2980 return;
2981 }
2982 auto absMatrix = geoPtr->GetAbsMatrix();
2983 bool isScale = false;
2984 if (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) {
2985 isScale = (!ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_X), 1.f, EPSILON_SCALE) ||
2986 !ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_Y), 1.f, EPSILON_SCALE));
2987 } else {
2988 bool getMinMaxScales = false;
2989 // scaleFactors[0]-minimum scaling factor, scaleFactors[1]-maximum scaling factor
2990 Drawing::scalar scaleFactors[2];
2991 getMinMaxScales = absMatrix.GetMinMaxScales(scaleFactors);
2992 if (getMinMaxScales) {
2993 isScale = !ROSEN_EQ(scaleFactors[0], 1.f, EPSILON_SCALE) || !ROSEN_EQ(scaleFactors[1], 1.f, EPSILON_SCALE);
2994 }
2995 if (!getMinMaxScales) {
2996 RS_LOGD("getMinMaxScales fail, node:%{public}s %{public}" PRIu64 "", node.GetName().c_str(), node.GetId());
2997 const auto& dstRect = node.GetDstRect();
2998 float dstRectWidth = dstRect.GetWidth();
2999 float dstRectHeight = dstRect.GetHeight();
3000 float boundsWidth = property.GetBoundsWidth();
3001 float boundsHeight = property.GetBoundsHeight();
3002 isScale =
3003 !ROSEN_EQ(std::min(dstRectWidth, dstRectHeight), std::min(boundsWidth, boundsHeight), EPSILON_SCALE) ||
3004 !ROSEN_EQ(std::max(dstRectWidth, dstRectHeight), std::max(boundsWidth, boundsHeight), EPSILON_SCALE);
3005 }
3006 }
3007 node.SetIsScaleInPreFrame(node.IsScale());
3008 node.SetIsScale(isScale);
3009 }
3010
PrepareRootRenderNode(RSRootRenderNode & node)3011 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
3012 {
3013 RS_TRACE_NAME_FMT("RSUniRender::PrepareRootRenderNode:node[%" PRIu64 "] pid[%d] subTreeDirty[%d]",
3014 node.GetId(), ExtractPid(node.GetId()), node.IsSubTreeDirty());
3015 bool dirtyFlag = dirtyFlag_;
3016 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
3017 auto prepareClipRect = prepareClipRect_;
3018
3019 auto nodeParent = (node.GetParent().lock());
3020 const auto& property = node.GetRenderProperties();
3021 bool geoDirty = property.IsGeoDirty();
3022 auto& geoPtr = (property.GetBoundsGeometry());
3023 auto prevAlpha = curAlpha_;
3024 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
3025
3026 if (curSurfaceDirtyManager_ == nullptr) {
3027 RS_LOGE("RSUniRenderVisitor::PrepareRootRenderNode curSurfaceDirtyManager is nullptr");
3028 return;
3029 }
3030
3031 dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
3032 *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
3033
3034 if (nodeParent == curSurfaceNode_) {
3035 const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
3036 const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
3037 Drawing::Matrix gravityMatrix;
3038 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
3039 RectF { 0.0f, 0.0f, boundsRect_.GetWidth(), boundsRect_.GetHeight() },
3040 rootWidth, rootHeight, gravityMatrix);
3041 // Only Apply gravityMatrix when rootNode is dirty
3042 if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
3043 geoPtr->ConcatMatrix(gravityMatrix);
3044 }
3045 }
3046
3047 if (geoPtr != nullptr) {
3048 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3049 }
3050
3051 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
3052 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
3053 node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
3054 PostPrepare(node, !isSubTreeNeedPrepare);
3055
3056 curAlpha_ = prevAlpha;
3057 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3058 dirtyFlag_ = dirtyFlag;
3059 prepareClipRect_ = prepareClipRect;
3060 }
3061
ClearRenderGroupCache()3062 void RSUniRenderVisitor::ClearRenderGroupCache()
3063 {
3064 std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
3065 cacheRenderNodeMap.clear();
3066 }
3067
SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams> & renderThreadParams)3068 void RSUniRenderVisitor::SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams>& renderThreadParams)
3069 {
3070 if (!renderThreadParams) {
3071 RS_LOGE("RSUniRenderVisitor::SetUniRenderThreadParam renderThreadParams is nullptr");
3072 return;
3073 }
3074 renderThreadParams->isPartialRenderEnabled_ = isPartialRenderEnabled_;
3075 renderThreadParams->isRegionDebugEnabled_ = isRegionDebugEnabled_;
3076 renderThreadParams->isDirtyRegionDfxEnabled_ = isDirtyRegionDfxEnabled_;
3077 renderThreadParams->isDisplayDirtyDfxEnabled_ = isDisplayDirtyDfxEnabled_;
3078 renderThreadParams->isOpaqueRegionDfxEnabled_ = isOpaqueRegionDfxEnabled_;
3079 renderThreadParams->isVisibleRegionDfxEnabled_ = isVisibleRegionDfxEnabled_;
3080 renderThreadParams->isAllSurfaceVisibleDebugEnabled_ = isAllSurfaceVisibleDebugEnabled_;
3081 renderThreadParams->isTargetDirtyRegionDfxEnabled_ = isTargetDirtyRegionDfxEnabled_;
3082 renderThreadParams->dirtyRegionDebugType_ = dirtyRegionDebugType_;
3083 renderThreadParams->isOpDropped_ = isOpDropped_;
3084 renderThreadParams->isUIFirstDebugEnable_ = isUIFirstDebugEnable_;
3085 renderThreadParams->dfxTargetSurfaceNames_ = std::move(dfxTargetSurfaceNames_);
3086 renderThreadParams->isVirtualDirtyEnabled_ = isVirtualDirtyEnabled_;
3087 renderThreadParams->isVirtualDirtyDfxEnabled_ = isVirtualDirtyDfxEnabled_;
3088 renderThreadParams->isExpandScreenDirtyEnabled_ = isExpandScreenDirtyEnabled_;
3089 renderThreadParams->hasMirrorDisplay_ = hasMirrorDisplay_;
3090 }
3091
SetAppWindowNum(uint32_t num)3092 void RSUniRenderVisitor::SetAppWindowNum(uint32_t num)
3093 {
3094 appWindowNum_ = num;
3095 }
3096
SendRcdMessage(RSDisplayRenderNode & node)3097 void RSUniRenderVisitor::SendRcdMessage(RSDisplayRenderNode& node)
3098 {
3099 if ((screenInfo_.state == ScreenState::HDI_OUTPUT_ENABLE) &&
3100 RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
3101 RSRcdRenderManager::GetInstance().CheckRenderTargetNode(RSMainThread::Instance()->GetContext());
3102 RSSingleton<RoundCornerDisplayManager>::GetInstance().AddRoundCornerDisplay(node.GetId());
3103 using rcd_msg = RSSingleton<RsMessageBus>;
3104 rcd_msg::GetInstance().SendMsg<NodeId, uint32_t, uint32_t>(TOPIC_RCD_DISPLAY_SIZE,
3105 node.GetId(), screenInfo_.width, screenInfo_.height);
3106 rcd_msg::GetInstance().SendMsg<NodeId, ScreenRotation>(TOPIC_RCD_DISPLAY_ROTATION,
3107 node.GetId(), node.GetScreenRotation());
3108 rcd_msg::GetInstance().SendMsg<NodeId, int>(TOPIC_RCD_DISPLAY_NOTCH,
3109 node.GetId(), RSSystemParameters::GetHideNotchStatus());
3110 }
3111 }
3112
ProcessUnpairedSharedTransitionNode()3113 void RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode()
3114 {
3115 static auto unpairNode = [](const std::weak_ptr<RSRenderNode>& wptr) {
3116 auto sptr = wptr.lock();
3117 if (sptr == nullptr) {
3118 return;
3119 }
3120 // make sure parent regenerates ChildrenDrawable
3121 auto parent = sptr->GetParent().lock();
3122 if (parent == nullptr) {
3123 return;
3124 }
3125 parent->AddDirtyType(RSModifierType::CHILDREN);
3126 parent->ApplyModifiers();
3127 // avoid changing the paired status or unpairedShareTransitions_
3128 auto param = sptr->GetSharedTransitionParam();
3129 if (param == nullptr) {
3130 ROSEN_LOGE("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: param is null");
3131 return;
3132 }
3133 param->paired_ = false;
3134 SharedTransitionParam::unpairedShareTransitions_.clear();
3135 };
3136 auto unpairedShareTransitions = std::move(SharedTransitionParam::unpairedShareTransitions_);
3137 for (auto& [id, wptr] : unpairedShareTransitions) {
3138 auto sharedTransitionParam = wptr.lock();
3139 // If the unpaired share transition is already deal with, do nothing
3140 if (!sharedTransitionParam) {
3141 continue;
3142 }
3143 if (!sharedTransitionParam->paired_) {
3144 sharedTransitionParam->ResetRelation();
3145 continue;
3146 }
3147 ROSEN_LOGD("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: mark %s as unpaired",
3148 sharedTransitionParam->Dump().c_str());
3149 sharedTransitionParam->paired_ = false;
3150 unpairNode(sharedTransitionParam->inNode_);
3151 unpairNode(sharedTransitionParam->outNode_);
3152 sharedTransitionParam->ResetRelation();
3153 }
3154 }
3155
FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)3156 NodeId RSUniRenderVisitor::FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)
3157 {
3158 if (node == nullptr) {
3159 return INVALID_NODEID;
3160 }
3161 auto nodeParent = node->GetParent().lock();
3162 if (nodeParent == nullptr) {
3163 return INVALID_NODEID;
3164 }
3165 if (nodeParent->GetType() == RSRenderNodeType::DISPLAY_NODE) {
3166 return node->GetId();
3167 } else {
3168 return FindInstanceChildOfDisplay(nodeParent);
3169 }
3170 }
3171
CheckColorFilterChange() const3172 bool RSUniRenderVisitor::CheckColorFilterChange() const
3173 {
3174 if (!RSMainThread::Instance()->IsAccessibilityConfigChanged()) {
3175 return false;
3176 }
3177 RS_LOGD("RSUniRenderVisitor::CheckColorFilterChange changed");
3178 return true;
3179 }
3180
CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr> & surfaces)3181 void RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr>& surfaces)
3182 {
3183 // Debug dirtyregion of show current refreshRation
3184 if (RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
3185 RectI tempRect = {100, 100, 500, 200}; // setDirtyRegion for RealtimeRefreshRate
3186 bool surfaceNodeSet = false;
3187 for (auto surface : surfaces) {
3188 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surface);
3189 if (surfaceNode == nullptr) {
3190 RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate surfaceNode is nullptr");
3191 continue;
3192 }
3193 if (surfaceNode->GetName().find(RELIABLE_GESTURE_BACK_SURFACE_NAME) != std::string::npos) {
3194 // refresh rate rect for mainwindow
3195 auto& geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
3196 if (!geoPtr) {
3197 break;
3198 }
3199 tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
3200 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
3201 surfaceNodeSet = true;
3202 break;
3203 }
3204 }
3205 if (!surfaceNodeSet) {
3206 auto &geoPtr = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
3207 if (!geoPtr) {
3208 return;
3209 }
3210 tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
3211 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
3212 }
3213 }
3214 }
3215
CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode & node)3216 void RSUniRenderVisitor::CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode& node)
3217 {
3218 bool hasAnim = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
3219 if (!node.IsScale() || hasAnim || curCornerRadius_.IsZero() || curAlpha_ < 1) {
3220 node.SetGpuOverDrawBufferOptimizeNode(false);
3221 return;
3222 }
3223
3224 for (auto& child : *(node.GetChildren())) {
3225 if (!child || !(child->IsInstanceOf<RSSurfaceRenderNode>() &&
3226 RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsLeashOrMainWindow())) {
3227 continue;
3228 }
3229 auto rootNode = child->GetFirstChild();
3230 if (!rootNode) {
3231 break;
3232 }
3233 auto canvasNode = rootNode->GetFirstChild();
3234 if (!canvasNode) {
3235 break;
3236 }
3237 const auto& surfaceProperties = node.GetRenderProperties();
3238 const auto& canvasProperties = canvasNode->GetRenderProperties();
3239 if (canvasProperties.GetAlpha() >= 1
3240 && canvasProperties.GetBackgroundColor().GetAlpha() >= MAX_ALPHA
3241 && canvasProperties.GetFrameWidth() == surfaceProperties.GetFrameWidth()
3242 && canvasProperties.GetFrameHeight() == surfaceProperties.GetFrameHeight()) {
3243 node.SetGpuOverDrawBufferOptimizeNode(true);
3244 node.SetOverDrawBufferNodeCornerRadius(curCornerRadius_);
3245 return;
3246 }
3247 }
3248
3249 node.SetGpuOverDrawBufferOptimizeNode(false);
3250 }
3251
SetHdrWhenMultiDisplayChangeInPC()3252 void RSUniRenderVisitor::SetHdrWhenMultiDisplayChangeInPC()
3253 {
3254 if (RSMainThread::Instance()->GetDeviceType() != DeviceType::PC) {
3255 return;
3256 }
3257 auto mainThread = RSMainThread::Instance();
3258 if (!mainThread->GetMultiDisplayChange()) {
3259 return;
3260 }
3261 auto isMultiDisplay = mainThread->GetMultiDisplayStatus();
3262 RS_LOGI("RSUniRenderVisitor::SetHdrWhenMultiDisplayChangeInPC closeHdrStatus: %{public}d.", isMultiDisplay);
3263 RS_TRACE_NAME_FMT("RSUniRenderVisitor::SetHdrWhenMultiDisplayChangeInPC closeHdrStatus: %d", isMultiDisplay);
3264 RSLuminanceControl::Get().ForceCloseHdr(CLOSEHDR_SCENEID::MULTI_DISPLAY, isMultiDisplay);
3265 }
3266
TryNotifyUIBufferAvailable()3267 void RSUniRenderVisitor::TryNotifyUIBufferAvailable()
3268 {
3269 for (auto& id : uiBufferAvailableId_) {
3270 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3271 auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
3272 if (surfaceNode) {
3273 surfaceNode->NotifyUIBufferAvailable();
3274 }
3275 }
3276 uiBufferAvailableId_.clear();
3277 }
3278 } // namespace Rosen
3279 } // namespace OHOS
3280