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