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 "draw/color.h"
26 #include "recording/recording_canvas.h"
27 #include "skia_adapter/skia_canvas.h"
28
29 #include "src/core/SkCanvasPriv.h"
30
31 #include "common/rs_background_thread.h"
32 #include "common/rs_common_def.h"
33 #include "common/rs_common_hook.h"
34 #include "common/rs_obj_abs_geometry.h"
35 #include "common/rs_optional_trace.h"
36 #include "common/rs_singleton.h"
37 #include "luminance/rs_luminance_control.h"
38 #include "memory/rs_tag_tracker.h"
39 #include "params/rs_display_render_params.h"
40 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
41 #include "pipeline/rs_base_render_node.h"
42 #include "pipeline/rs_base_render_util.h"
43 #include "pipeline/rs_canvas_drawing_render_node.h"
44 #include "pipeline/rs_display_render_node.h"
45 #include "pipeline/rs_draw_cmd.h"
46 #include "pipeline/rs_effect_render_node.h"
47 #include "pipeline/rs_paint_filter_canvas.h"
48 #include "pipeline/rs_processor_factory.h"
49 #include "pipeline/rs_proxy_render_node.h"
50 #include "pipeline/rs_realtime_refresh_rate_manager.h"
51 #include "pipeline/rs_root_render_node.h"
52 #include "pipeline/rs_surface_render_node.h"
53 #include "pipeline/rs_uni_render_listener.h"
54 #include "pipeline/rs_uni_render_virtual_processor.h"
55 #include "pipeline/rs_uni_render_util.h"
56 #include "pipeline/rs_uifirst_manager.h"
57 #include "pipeline/sk_resource_manager.h"
58 #include "platform/common/rs_log.h"
59 #include "platform/common/rs_system_properties.h"
60 #include "platform/ohos/rs_jank_stats.h"
61 #include "platform/ohos/rs_node_stats.h"
62 #include "property/rs_properties_painter.h"
63 #include "property/rs_point_light_manager.h"
64 #include "render/rs_drawing_filter.h"
65 #include "render/rs_skia_filter.h"
66 #include "system/rs_system_parameters.h"
67 #include "scene_board_judgement.h"
68 #include "hgm_core.h"
69 #include "benchmarks/rs_recording_thread.h"
70 #include "scene_board_judgement.h"
71 #include "metadata_helper.h"
72 #include <v1_0/buffer_handle_meta_key_type.h>
73 #include <v1_0/cm_color_space.h>
74
75 #include "pipeline/round_corner_display/rs_round_corner_display.h"
76 #include "pipeline/round_corner_display/rs_message_bus.h"
77
78 #include "rs_profiler.h"
79 #ifdef RS_PROFILER_ENABLED
80 #include "rs_profiler_capture_recorder.h"
81 #endif
82
83 namespace OHOS {
84 namespace Rosen {
85 namespace {
86 constexpr uint32_t PHONE_MAX_APP_WINDOW_NUM = 1;
87 constexpr int32_t CACHE_MAX_UPDATE_TIME = 2;
88 constexpr int32_t VISIBLEAREARATIO_FORQOS = 3;
89 constexpr int MAX_ALPHA = 255;
90 constexpr int TRACE_LEVEL_THREE = 3;
91 constexpr float EPSILON_SCALE = 0.00001f;
92 constexpr float CACHE_FILL_ALPHA = 0.2f;
93 constexpr float CACHE_UPDATE_FILL_ALPHA = 0.8f;
94 static const std::string CAPTURE_WINDOW_NAME = "CapsuleWindow";
95 constexpr const char* CLEAR_GPU_CACHE = "ClearGpuCache";
96 constexpr const char* RELIABLE_GESTURE_BACK_SURFACE_NAME = "SCBGestureBack";
97 constexpr int MIN_OVERLAP = 2;
98 static std::map<NodeId, uint32_t> cacheRenderNodeMap = {};
99 static uint32_t cacheReuseTimes = 0;
100 static std::mutex cacheRenderNodeMapMutex;
101 static const std::map<DirtyRegionType, std::string> DIRTY_REGION_TYPE_MAP {
102 { DirtyRegionType::UPDATE_DIRTY_REGION, "UPDATE_DIRTY_REGION" },
103 { DirtyRegionType::OVERLAY_RECT, "OVERLAY_RECT" },
104 { DirtyRegionType::FILTER_RECT, "FILTER_RECT" },
105 { DirtyRegionType::SHADOW_RECT, "SHADOW_RECT" },
106 { DirtyRegionType::PREPARE_CLIP_RECT, "PREPARE_CLIP_RECT" },
107 { DirtyRegionType::REMOVE_CHILD_RECT, "REMOVE_CHILD_RECT" },
108 { DirtyRegionType::RENDER_PROPERTIES_RECT, "RENDER_PROPERTIES_RECT" },
109 { DirtyRegionType::CANVAS_NODE_SKIP_RECT, "CANVAS_NODE_SKIP_RECT" },
110 { DirtyRegionType::OUTLINE_RECT, "OUTLINE_RECT" },
111 };
112
CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)113 bool CheckRootNodeReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
114 {
115 if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
116 auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
117 const auto& property = rootNode->GetRenderProperties();
118 if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
119 return true;
120 }
121 }
122 return false;
123 }
124
CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode> & child)125 bool CheckScbReadyToDraw(const std::shared_ptr<RSBaseRenderNode>& child)
126 {
127 if (child != nullptr && child->IsInstanceOf<RSCanvasRenderNode>()) {
128 auto canvasRenderNode = child->ReinterpretCastTo<RSCanvasRenderNode>();
129 const auto& property = canvasRenderNode->GetRenderProperties();
130 if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0) {
131 return true;
132 }
133 }
134 return false;
135 }
136
IsFirstFrameReadyToDraw(const RSSurfaceRenderNode & node)137 bool IsFirstFrameReadyToDraw(const RSSurfaceRenderNode& node)
138 {
139 bool result = false;
140 auto sortedChildren = node.GetSortedChildren();
141 if (node.IsScbScreen() || node.IsSCBNode()) {
142 for (const auto& child : *sortedChildren) {
143 result = CheckScbReadyToDraw(child);
144 }
145 return result;
146 }
147 for (auto& child : *sortedChildren) {
148 result = CheckRootNodeReadyToDraw(child);
149 // when appWindow has abilityComponent node
150 if (child != nullptr && child->IsInstanceOf<RSSurfaceRenderNode>()) {
151 for (const auto& surfaceNodeChild : *child->GetSortedChildren()) {
152 result = CheckRootNodeReadyToDraw(surfaceNodeChild);
153 }
154 }
155 }
156 return result;
157 }
158
VisibleDataToString(const VisibleData & val)159 std::string VisibleDataToString(const VisibleData& val)
160 {
161 std::stringstream ss;
162 ss << "VisibleData[name, nodeId, visibleLevel]:";
163 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
164 for (const auto& v : val) {
165 auto surfaceNode = nodeMap.GetRenderNode<RSSurfaceRenderNode>(v.first);
166 auto name = surfaceNode ? surfaceNode->GetName() : "";
167 ss << "[" << name << ", " << v.first << ", " << v.second << "], ";
168 }
169 return ss.str();
170 }
171 } // namespace
172
DoScreenRcdTask(std::shared_ptr<RSProcessor> & processor,std::unique_ptr<RcdInfo> & rcdInfo,ScreenInfo & screenInfo_)173 void DoScreenRcdTask(std::shared_ptr<RSProcessor>& processor, std::unique_ptr<RcdInfo>& rcdInfo,
174 ScreenInfo& screenInfo_)
175 {
176 if (screenInfo_.state != ScreenState::HDI_OUTPUT_ENABLE) {
177 RS_LOGD("DoScreenRcdTask is not at HDI_OUPUT mode");
178 return;
179 }
180 if (RSSingleton<RoundCornerDisplay>::GetInstance().GetRcdEnable()) {
181 RSSingleton<RoundCornerDisplay>::GetInstance().RunHardwareTask(
182 [&processor, &rcdInfo]() {
183 auto hardInfo = RSSingleton<RoundCornerDisplay>::GetInstance().GetHardwareInfo();
184 rcdInfo->processInfo = {processor, hardInfo.topLayer, hardInfo.bottomLayer,
185 hardInfo.resourceChanged};
186 RSRcdRenderManager::GetInstance().DoProcessRenderTask(rcdInfo->processInfo);
187 }
188 );
189 }
190 }
191
RSUniRenderVisitor()192 RSUniRenderVisitor::RSUniRenderVisitor()
193 : curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
194 {
195 PartialRenderOptionInit();
196 auto mainThread = RSMainThread::Instance();
197 renderEngine_ = mainThread->GetRenderEngine();
198 hasMirrorDisplay_ = mainThread->HasMirrorDisplay();
199 quickSkipPrepareType_ = RSSystemParameters::GetQuickSkipPrepareType();
200 // when occlusion enabled is false, subTree do not skip, but not influence visible region
201 isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
202 isQuickSkipPreparationEnabled_ = (quickSkipPrepareType_ != QuickSkipPrepareType::DISABLED);
203 isDrawingCacheEnabled_ = RSSystemParameters::GetDrawingCacheEnabled();
204 #ifdef DDGR_ENABLE_FEATURE_OPINC
205 autoCacheEnable_ = RSSystemProperties::IsDdgrOpincEnable();
206 #endif
207 RSTagTracker::UpdateReleaseResourceEnabled(RSSystemProperties::GetReleaseResourceEnabled());
208 isScreenRotationAnimating_ = RSSystemProperties::GetCacheEnabledForRotation();
209 isSubSurfaceEnabled_ = RSSystemProperties::GetSubSurfaceEnabled() && RSSystemProperties::IsPhoneType();
210 isSkipCanvasNodeOutOfScreen_ = RSSystemParameters::GetSkipCanvasNodeOutofScreenEnabled();
211 if (RSRcdRenderManager::GetInstance().GetRcdRenderEnabled()) {
212 rcdInfo_ = std::make_unique<RcdInfo>();
213 }
214 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
215 if (renderEngine_ && renderEngine_->GetRenderContext()) {
216 auto subThreadManager = RSSubThreadManager::Instance();
217 subThreadManager->Start(renderEngine_->GetRenderContext().get());
218 }
219 #endif
220 isUIFirst_ = RSMainThread::Instance()->IsUIFirstOn();
221 isUIFirstDebugEnable_ = RSSystemProperties::GetUIFirstDebugEnabled();
222 isPhone_ = RSMainThread::Instance()->GetDeviceType() == DeviceType::PHONE;
223 isPc_ = RSMainThread::Instance()->GetDeviceType() == DeviceType::PC;
224 isCurtainScreenOn_ = RSMainThread::Instance()->IsCurtainScreenOn();
225 isPrevalidateHwcNodeEnable_ = RSSystemParameters::GetPrevalidateHwcNodeEnabled() &&
226 RSUniHwcPrevalidateUtil::GetInstance().IsLoadSuccess();
227 isOverdrawDfxOn_ = RSOverdrawController::GetInstance().IsEnabled();
228 }
229
PartialRenderOptionInit()230 void RSUniRenderVisitor::PartialRenderOptionInit()
231 {
232 partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
233 isPartialRenderEnabled_ = (partialRenderType_ != PartialRenderType::DISABLED);
234 isCompleteRenderEnabled_ = (partialRenderType_ == PartialRenderType::SET_DAMAGE_BUT_COMPLETE_RENDER);
235 dirtyRegionDebugType_ = RSSystemProperties::GetDirtyRegionDebugType();
236 surfaceRegionDebugType_ = RSSystemProperties::GetSurfaceRegionDfxType();
237 isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_) &&
238 (surfaceRegionDebugType_ == SurfaceRegionDebugType::DISABLED);
239 isRegionDebugEnabled_ = (dirtyRegionDebugType_ != DirtyRegionDebugType::DISABLED) ||
240 (surfaceRegionDebugType_ != SurfaceRegionDebugType::DISABLED) || (dfxTargetSurfaceNames_.size() > 0);
241 isVisibleRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::VISIBLE_REGION);
242 isOpaqueRegionDfxEnabled_ = (surfaceRegionDebugType_ == SurfaceRegionDebugType::OPAQUE_REGION);
243 isAllSurfaceVisibleDebugEnabled_ = RSSystemProperties::GetAllSurfaceVisibleDebugEnabled();
244 isDirtyRegionDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
245 (dirtyRegionDebugType_ == DirtyRegionDebugType::EGL_DAMAGE);
246 isDisplayDirtyDfxEnabled_ = !isTargetDirtyRegionDfxEnabled_ &&
247 (dirtyRegionDebugType_ == DirtyRegionDebugType::DISPLAY_DIRTY);
248 isCanvasNodeSkipDfxEnabled_ = (dirtyRegionDebugType_ == DirtyRegionDebugType::CANVAS_NODE_SKIP_RECT);
249 isOpDropped_ = isPartialRenderEnabled_ &&
250 (partialRenderType_ != PartialRenderType::SET_DAMAGE) && !isRegionDebugEnabled_;
251 isCacheBlurPartialRenderEnabled_ = RSSystemProperties::GetCachedBlurPartialRenderEnabled();
252 isVirtualDirtyDfxEnabled_ = RSSystemProperties::GetVirtualDirtyDebugEnabled();
253 isVirtualDirtyEnabled_ = RSSystemProperties::GetVirtualDirtyEnabled() &&
254 (RSSystemProperties::GetGpuApiType() != GpuApiType::OPENGL);
255 isExpandScreenDirtyEnabled_ = RSSystemProperties::GetExpandScreenDirtyEnabled();
256 }
257
RSUniRenderVisitor(const RSUniRenderVisitor & visitor)258 RSUniRenderVisitor::RSUniRenderVisitor(const RSUniRenderVisitor& visitor) : RSUniRenderVisitor()
259 {
260 currentVisitDisplay_ = visitor.currentVisitDisplay_;
261 screenInfo_ = visitor.screenInfo_;
262 displayHasSecSurface_ = visitor.displayHasSecSurface_;
263 displayHasSkipSurface_ = visitor.displayHasSkipSurface_;
264 displayHasProtectedSurface_ = visitor.displayHasProtectedSurface_;
265 displaySpecailSurfaceChanged_ = visitor.displaySpecailSurfaceChanged_;
266 hasCaptureWindow_ = visitor.hasCaptureWindow_;
267 parentSurfaceNodeMatrix_ = visitor.parentSurfaceNodeMatrix_;
268 curAlpha_ = visitor.curAlpha_;
269 dirtyFlag_ = visitor.dirtyFlag_;
270 curDisplayNode_ = visitor.curDisplayNode_;
271 currentFocusedNodeId_ = visitor.currentFocusedNodeId_;
272 prepareClipRect_ = visitor.prepareClipRect_;
273 isOpDropped_ = visitor.isOpDropped_;
274 isPartialRenderEnabled_ = visitor.isPartialRenderEnabled_;
275 isAllSurfaceVisibleDebugEnabled_ = visitor.isAllSurfaceVisibleDebugEnabled_;
276 isHardwareForcedDisabled_ = visitor.isHardwareForcedDisabled_;
277 doAnimate_ = visitor.doAnimate_;
278 isDirty_ = visitor.isDirty_;
279 }
280
~RSUniRenderVisitor()281 RSUniRenderVisitor::~RSUniRenderVisitor() {}
282
CopyVisitorInfos(std::shared_ptr<RSUniRenderVisitor> visitor)283 void RSUniRenderVisitor::CopyVisitorInfos(std::shared_ptr<RSUniRenderVisitor> visitor)
284 {
285 std::unique_lock<std::mutex> lock(copyVisitorInfosMutex_);
286 currentVisitDisplay_ = visitor->currentVisitDisplay_;
287 screenInfo_ = visitor->screenInfo_;
288 displayHasSecSurface_ = visitor->displayHasSecSurface_;
289 displayHasSkipSurface_ = visitor->displayHasSkipSurface_;
290 displayHasProtectedSurface_ = visitor->displayHasProtectedSurface_;
291 displaySpecailSurfaceChanged_ = visitor->displaySpecailSurfaceChanged_;
292 hasCaptureWindow_ = visitor->hasCaptureWindow_;
293 parentSurfaceNodeMatrix_ = visitor->parentSurfaceNodeMatrix_;
294 curAlpha_ = visitor->curAlpha_;
295 dirtyFlag_ = visitor->dirtyFlag_;
296 curDisplayNode_ = visitor->curDisplayNode_;
297 currentFocusedNodeId_ = visitor->currentFocusedNodeId_;
298 prepareClipRect_ = visitor->prepareClipRect_;
299 isOpDropped_ = visitor->isOpDropped_;
300 isPartialRenderEnabled_ = visitor->isPartialRenderEnabled_;
301 isAllSurfaceVisibleDebugEnabled_ = visitor->isAllSurfaceVisibleDebugEnabled_;
302 isHardwareForcedDisabled_ = visitor->isHardwareForcedDisabled_;
303 doAnimate_ = visitor->doAnimate_;
304 isDirty_ = visitor->isDirty_;
305 }
306
UpdateSubTreeInCache(const std::shared_ptr<RSRenderNode> & cacheRootNode,const std::vector<RSRenderNode::SharedPtr> & children)307 void RSUniRenderVisitor::UpdateSubTreeInCache(const std::shared_ptr<RSRenderNode>& cacheRootNode,
308 const std::vector<RSRenderNode::SharedPtr>& children)
309 {
310 for (auto& child : children) {
311 if (child == nullptr) {
312 continue;
313 }
314 auto isDirty = child->IsDirty();
315 if (isDirty) {
316 curDirty_ = isDirty;
317 child->Prepare(shared_from_this());
318 continue;
319 }
320 // set flag for surface node whose children contain shared transition node
321 if (child->GetSharedTransitionParam() && curSurfaceNode_) {
322 SetHasSharedTransitionNode(*curSurfaceNode_, true);
323 }
324 // [planning] pay attention to outofparent case
325 if (auto surfaceNode = child->ReinterpretCastTo<RSSurfaceRenderNode>()) {
326 // fully prepare hwcLayer Layer and its subnodes
327 if (surfaceNode->IsHardwareEnabledType()) {
328 PrepareSurfaceRenderNode(*surfaceNode);
329 return;
330 }
331 } else if (auto effectNode = child->ReinterpretCastTo<RSEffectRenderNode>()) {
332 // effectNode need to update effectRegion so effectNode and use-effect child should be updated
333 PrepareEffectNodeIfCacheReuse(cacheRootNode, effectNode);
334 return;
335 }
336 const auto& property = child->GetRenderProperties();
337 if (property.NeedFilter() || property.GetUseEffect()) {
338 child->Update(*curSurfaceDirtyManager_, cacheRootNode, dirtyFlag_, prepareClipRect_);
339 }
340 if (property.NeedFilter()) {
341 UpdateForegroundFilterCacheWithDirty(*child, *curSurfaceDirtyManager_);
342 if (curSurfaceNode_ && curSurfaceNode_->GetId() == child->GetInstanceRootNodeId()) {
343 curSurfaceNode_->UpdateChildrenFilterRects(child, child->GetOldDirtyInSurface(),
344 child->IsFilterCacheValid());
345 }
346 }
347 UpdateSubTreeInCache(child, *child->GetSortedChildren());
348 }
349 }
350
PrepareEffectNodeIfCacheReuse(const std::shared_ptr<RSRenderNode> & cacheRootNode,std::shared_ptr<RSEffectRenderNode> effectNode)351 void RSUniRenderVisitor::PrepareEffectNodeIfCacheReuse(const std::shared_ptr<RSRenderNode>& cacheRootNode,
352 std::shared_ptr<RSEffectRenderNode> effectNode)
353 {
354 if (effectNode == nullptr || curSurfaceDirtyManager_ == nullptr) {
355 return;
356 }
357 // set rotationChanged true when screen is rotating or folding/expanding screen.
358 UpdateRotationStatusForEffectNode(*effectNode);
359 effectNode->SetVisitedFilterCacheStatus(curSurfaceDirtyManager_->IsCacheableFilterRectEmpty());
360 effectNode->Update(*curSurfaceDirtyManager_, cacheRootNode, dirtyFlag_, prepareClipRect_);
361 UpdateSubTreeInCache(effectNode, *effectNode->GetSortedChildren());
362 if (effectNode->GetRenderProperties().NeedFilter()) {
363 UpdateForegroundFilterCacheWithDirty(*effectNode, *curSurfaceDirtyManager_);
364 if (curSurfaceNode_ && curSurfaceNode_->GetId() == effectNode->GetInstanceRootNodeId()) {
365 curSurfaceNode_->UpdateChildrenFilterRects(effectNode, effectNode->GetOldDirtyInSurface(),
366 effectNode->IsFilterCacheValid());
367 }
368 }
369 }
370
PrepareChildren(RSRenderNode & node)371 void RSUniRenderVisitor::PrepareChildren(RSRenderNode& node)
372 {
373 // GetSortedChildren() may remove disappearingChildren_ when transition animation end.
374 // So the judgement whether node has removed child should be executed after this.
375 // NOTE: removal of transition node is moved to RSMainThread::Animate
376 MergeRemovedChildDirtyRegion(node);
377 // backup environment variables.
378 node.ResetChildrenRect();
379 const auto& properties = node.GetRenderProperties();
380
381 if (!isSubNodeOfSurfaceInPrepare_) {
382 Vector4f::Max(properties.GetCornerRadius(), curCornerRadius_, curCornerRadius_);
383 }
384 if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
385 node.SetGlobalCornerRadius(curCornerRadius_);
386 }
387
388 float alpha = curAlpha_;
389 curAlpha_ *= properties.GetAlpha();
390 node.SetGlobalAlpha(curAlpha_);
391 const auto& children = node.GetSortedChildren();
392 // check curSurfaceDirtyManager_ for SubTree updates
393 if (curSurfaceDirtyManager_ != nullptr && isCachedSurfaceReuse_ && !node.HasMustRenewedInfo()) {
394 RS_OPTIONAL_TRACE_NAME_FMT("CachedSurfaceReuse node %llu quickSkip subtree", node.GetId());
395 } else if (curSurfaceDirtyManager_ != nullptr && curDisplayNode_ != nullptr &&
396 (isCachedSurfaceReuse_ || isSurfaceDirtyNodeLimited_ || !UpdateCacheChangeStatus(node))) {
397 RS_OPTIONAL_TRACE_NAME_FMT("UpdateCacheChangeStatus node %llu simply update subtree, isCachedSurfaceReuse_ %d,"
398 " isSurfaceDirtyNodeLimited_ %d, hasUseEffect %d", node.GetId(), isCachedSurfaceReuse_,
399 isSurfaceDirtyNodeLimited_, node.ChildHasVisibleEffect());
400 UpdateSubTreeInCache(node.ReinterpretCastTo<RSRenderNode>(), *children);
401 node.UpdateEffectRegion(effectRegion_,
402 (node.GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE && node.ChildHasVisibleEffect()));
403 } else {
404 // Get delay flag to restore geo changes
405 if (node.GetGeoUpdateDelay()) {
406 dirtyFlag_ = true;
407 }
408 node.SetChildHasVisibleEffect(false);
409 for (auto& child : *children) {
410 SaveCurSurface();
411 curDirty_ = child->IsDirty();
412 child->Prepare(shared_from_this());
413 if (child->ChildHasVisibleEffect()) {
414 node.SetChildHasVisibleEffect(true);
415 }
416 RestoreCurSurface();
417 }
418 // Reset delay flag
419 node.ResetGeoUpdateDelay();
420 SetNodeCacheChangeStatus(node);
421 }
422
423 node.SetSubTreeDirty(false);
424 curAlpha_ = alpha;
425 // restore environment variables
426 }
427
MergeRemovedChildDirtyRegion(RSRenderNode & node,bool needMap)428 void RSUniRenderVisitor::MergeRemovedChildDirtyRegion(RSRenderNode& node, bool needMap)
429 {
430 if (!node.HasRemovedChild()) {
431 return;
432 }
433 RectI dirtyRect = node.GetChildrenRect();
434 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
435 if (dirtyManager == nullptr || dirtyRect.IsEmpty()) {
436 node.ResetHasRemovedChild();
437 return;
438 }
439
440 // [planning] merge removed child's rect instead
441 if (needMap) {
442 if (auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry()) {
443 dirtyRect = geoPtr->MapAbsRect(dirtyRect.ConvertTo<float>());
444 }
445 if (!node.HasChildrenOutOfRect()) {
446 dirtyRect = dirtyRect.IntersectRect(node.GetOldClipRect());
447 }
448 } else {
449 dirtyRect = prepareClipRect_.IntersectRect(node.GetChildrenRect());
450 }
451 dirtyManager->MergeDirtyRect(dirtyRect);
452 RS_OPTIONAL_TRACE_NAME_FMT("MergeRemovedChildDirtyRegion NodeId:%" PRIu64 ", dirty rect:%s",
453 node.GetId(), dirtyRect.ToString().c_str());
454 if (dirtyManager->IsTargetForDfx()) {
455 // since childRect includes multiple rects, defaultly marked as canvas_node
456 dirtyManager->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
457 DirtyRegionType::REMOVE_CHILD_RECT, dirtyRect);
458 }
459 node.ResetHasRemovedChild();
460 }
461
IsDrawingCacheStatic(RSRenderNode & node)462 bool RSUniRenderVisitor::IsDrawingCacheStatic(RSRenderNode& node)
463 {
464 // since this function only called by drawing group root
465 // if cache valid, cacheRenderNodeMapCnt > 0
466 // check all dirtynodes of app instance if there's any in cache subtree
467 if (curContentDirty_ || node.GetDrawingCacheChanged() || !node.IsCacheCompletedSurfaceValid() ||
468 curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetInstanceRootNodeId() ||
469 RSMainThread::Instance()->IsDrawingGroupChanged(node)) {
470 return false;
471 }
472 // skip targeted cache node when first visited node is forced cache
473 if (node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE && firstVisitedCache_ != node.GetId() &&
474 IsFirstVisitedCacheForced()) {
475 return false;
476 }
477 // simplify Cache status reset
478 node.GetFilterRectsInCache(allCacheFilterRects_);
479 node.SetDrawingCacheChanged(false);
480 node.SetGeoUpdateDelay(dirtyFlag_);
481 if (allCacheFilterRects_.count(node.GetId())) {
482 node.SetChildHasVisibleFilter(true);
483 if (const auto directParent = node.GetParent().lock()) {
484 directParent->SetChildHasVisibleFilter(true);
485 }
486 }
487 return true;
488 }
489
UpdateCacheChangeStatus(RSRenderNode & node)490 bool RSUniRenderVisitor::UpdateCacheChangeStatus(RSRenderNode& node)
491 {
492 node.SetChildHasVisibleFilter(false);
493 if (!isDrawingCacheEnabled_) {
494 return true;
495 }
496 node.CheckDrawingCacheType();
497 if (node.GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE && !node.IsStaticCached() &&
498 (!node.ShouldPaint() || isScreenRotationAnimating_)) {
499 node.SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
500 }
501 // skip status check if there is no upper cache mark
502 if (node.GetDrawingCacheType() == RSDrawingCacheType::DISABLED_CACHE && firstVisitedCache_ == INVALID_NODEID) {
503 return true;
504 }
505 // subroot's dirty and cached filter should be count for parent root
506 if (!isDrawingCacheChanged_.empty()) {
507 // Any child node dirty causes cache change
508 RS_OPTIONAL_TRACE_NAME_FMT("UpdateCacheChangeStatus child:%" PRIu64 "", node.GetId());
509 isDrawingCacheChanged_.top() = isDrawingCacheChanged_.top() || curDirty_;
510 }
511 const auto& properties = node.GetRenderProperties();
512 if (!curCacheFilterRects_.empty() && !node.IsInstanceOf<RSEffectRenderNode>() &&
513 (properties.GetBackgroundFilter() || properties.GetUseEffect() ||
514 properties.GetShadowColorStrategy() != SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE)) {
515 curCacheFilterRects_.top().emplace(node.GetId());
516 }
517 // drawing group root node
518 if (node.GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE) {
519 // if firstVisitedCache_ valid, upper cache should be updated so sub cache shouldn't skip
520 // [planning] static subcache could be skip and reuse
521 if ((quickSkipPrepareType_ >= QuickSkipPrepareType::STATIC_CACHE) &&
522 (firstVisitedCache_ == INVALID_NODEID) && IsDrawingCacheStatic(node)) {
523 return false;
524 }
525 // For rootnode, init drawing changes only if there is any content dirty
526 isDrawingCacheChanged_.push(curContentDirty_);
527 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateCacheChangeStatus: cachable node %" PRIu64 ""
528 "contentDirty(cacheChanged): %d", node.GetId(), static_cast<int>(isDrawingCacheChanged_.top()));
529 curCacheFilterRects_.push({});
530 if (firstVisitedCache_ == INVALID_NODEID) {
531 firstVisitedCache_ = node.GetId();
532 }
533 }
534 return true;
535 }
536
DisableNodeCacheInSetting(RSRenderNode & node)537 void RSUniRenderVisitor::DisableNodeCacheInSetting(RSRenderNode& node)
538 {
539 if (node.IsStaticCached()) {
540 return;
541 }
542 // Attention: filter node should be marked. Only enable lowest suggested cached node
543 if (node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
544 auto childrenOutOfRect = node.HasChildrenOutOfRect();
545 auto firstVisitedCacheForced = IsFirstVisitedCacheForced();
546 // if target cached is reused, keep enable -- prepareskip
547 // disable cache if it has outOfParent -- cannot cache right
548 // [planning] if there is dirty subcache, disable upper targetcache
549 // disable targeted cache node when first visited node is forced cache to avoid problem in case with blur
550 if (childrenOutOfRect || (firstVisitedCache_ != node.GetId() && firstVisitedCacheForced)) {
551 node.SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
552 allCacheFilterRects_[firstVisitedCache_].insert(allCacheFilterRects_[node.GetId()].begin(),
553 allCacheFilterRects_[node.GetId()].end());
554 allCacheFilterRects_.erase(node.GetId());
555 RS_OPTIONAL_TRACE_NAME_FMT("Disable cache %llu: outofparent %d, firstVisitedCache_ %llu & cacheforce %d",
556 node.GetId(), childrenOutOfRect, firstVisitedCache_, firstVisitedCacheForced);
557 }
558 }
559 if (firstVisitedCache_ == INVALID_NODEID) {
560 node.SetDrawingCacheType(RSDrawingCacheType::DISABLED_CACHE);
561 std::stack<bool>().swap(isDrawingCacheChanged_);
562 visitedCacheNodeIds_.clear();
563 }
564 }
565
IsFirstVisitedCacheForced() const566 bool RSUniRenderVisitor::IsFirstVisitedCacheForced() const
567 {
568 if (firstVisitedCache_ != INVALID_NODEID) {
569 auto firstVisitedNode = RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode<RSRenderNode>(
570 firstVisitedCache_);
571 if (firstVisitedNode && firstVisitedNode->GetDrawingCacheType() == RSDrawingCacheType::FORCED_CACHE) {
572 return true;
573 }
574 }
575 return false;
576 }
577
SaveCurSurface()578 void RSUniRenderVisitor::SaveCurSurface()
579 {
580 if (!isSubSurfaceEnabled_) {
581 return;
582 }
583 surfaceDirtyManager_.push(curSurfaceDirtyManager_);
584 surfaceNode_.push(curSurfaceNode_);
585 }
586
RestoreCurSurface()587 void RSUniRenderVisitor::RestoreCurSurface()
588 {
589 if (!isSubSurfaceEnabled_) {
590 return;
591 }
592 curSurfaceDirtyManager_ = surfaceDirtyManager_.top();
593 curSurfaceNode_ = surfaceNode_.top();
594 surfaceDirtyManager_.pop();
595 surfaceNode_.pop();
596 }
597
PrepareSubSurfaceNodes(RSSurfaceRenderNode & node)598 void RSUniRenderVisitor::PrepareSubSurfaceNodes(RSSurfaceRenderNode& node)
599 {
600 if (!isSubSurfaceEnabled_) {
601 return;
602 }
603 for (auto &nodes : node.GetSubSurfaceNodes()) {
604 for (auto &node : nodes.second) {
605 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.lock());
606 if (surfaceNode != nullptr) {
607 SaveCurSurface();
608 PrepareSurfaceRenderNode(*surfaceNode);
609 RestoreCurSurface();
610 }
611 }
612 }
613 }
614
ProcessSubSurfaceNodes(RSSurfaceRenderNode & node)615 void RSUniRenderVisitor::ProcessSubSurfaceNodes(RSSurfaceRenderNode& node)
616 {
617 if (!isSubSurfaceEnabled_) {
618 return;
619 }
620 for (auto &nodes : node.GetSubSurfaceNodes()) {
621 for (auto &node : nodes.second) {
622 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.lock());
623 if (surfaceNode != nullptr) {
624 SaveCurSurface();
625 ProcessSurfaceRenderNode(*surfaceNode);
626 RestoreCurSurface();
627 }
628 }
629 }
630 }
631
SetNodeCacheChangeStatus(RSRenderNode & node)632 void RSUniRenderVisitor::SetNodeCacheChangeStatus(RSRenderNode& node)
633 {
634 if (node.ChildHasVisibleFilter()) {
635 auto directParent = node.GetParent().lock();
636 if (directParent != nullptr) {
637 directParent->SetChildHasVisibleFilter(true);
638 }
639 }
640 auto drawingCacheType = node.GetDrawingCacheType();
641 if (!isDrawingCacheEnabled_ ||
642 drawingCacheType == RSDrawingCacheType::DISABLED_CACHE) {
643 return;
644 }
645 if (!curCacheFilterRects_.empty()) {
646 allCacheFilterRects_[node.GetId()].insert(curCacheFilterRects_.top().begin(),
647 curCacheFilterRects_.top().end());
648 node.ResetFilterRectsInCache(allCacheFilterRects_[node.GetId()]);
649 curCacheFilterRects_.pop();
650 }
651 DisableNodeCacheInSetting(node);
652 if (drawingCacheType != RSDrawingCacheType::DISABLED_CACHE) {
653 // update visited cache roots including itself
654 visitedCacheNodeIds_.emplace(node.GetId());
655 node.SetVisitedCacheRootIds(visitedCacheNodeIds_);
656 if (curSurfaceNode_) {
657 curSurfaceNode_->UpdateDrawingCacheNodes(node.ReinterpretCastTo<RSRenderNode>());
658 }
659 }
660 bool isDrawingCacheChanged = isDrawingCacheChanged_.empty() || isDrawingCacheChanged_.top();
661 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::SetNodeCacheChangeStatus: node %" PRIu64 " drawingtype %d, "
662 "staticCache %d, cacheChange %d, childHasVisibleFilter|effect: %d|%d, outofparent: %d, "
663 "visitedCacheNodeIds num: %lu",
664 node.GetId(), static_cast<int>(node.GetDrawingCacheType()), node.IsStaticCached(),
665 static_cast<int>(isDrawingCacheChanged), node.ChildHasVisibleFilter(), node.ChildHasVisibleEffect(),
666 static_cast<int>(node.HasChildrenOutOfRect()), visitedCacheNodeIds_.size());
667 node.SetDrawingCacheChanged(!node.IsStaticCached() && isDrawingCacheChanged);
668 // reset counter after executing the very first marked node
669 if (firstVisitedCache_ == node.GetId()) {
670 std::stack<bool>().swap(isDrawingCacheChanged_);
671 firstVisitedCache_ = INVALID_NODEID;
672 visitedCacheNodeIds_.clear();
673 } else if (!isDrawingCacheChanged_.empty()) {
674 bool isChildChanged = isDrawingCacheChanged_.top();
675 isDrawingCacheChanged_.pop();
676 if (!isDrawingCacheChanged_.empty()) {
677 isDrawingCacheChanged_.top() = isDrawingCacheChanged_.top() || isChildChanged;
678 }
679 }
680 }
681
CheckColorSpace(RSSurfaceRenderNode & node)682 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
683 {
684 // currently, P3 is the only supported wide color gamut, this may be modified later.
685 if (node.IsAppWindow() && node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
686 newColorSpace_ = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
687 RS_LOGD("RSUniRenderVisitor::CheckColorSpace: node(%{public}s) set new colorgamut %{public}d",
688 node.GetName().c_str(), newColorSpace_);
689 }
690 }
691
CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode & node)692 void RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode(RSSurfaceRenderNode& node)
693 {
694 if (!node.IsOnTheTree()) {
695 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is not on the tree",
696 node.GetName().c_str());
697 return;
698 }
699 if (!node.IsHardwareForcedDisabled()) {
700 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) is hardware-enabled",
701 node.GetName().c_str());
702 return;
703 }
704 // currently, P3 is the only supported wide color gamut, this may be modified later.
705 node.UpdateColorSpaceWithMetadata();
706 if (node.GetColorSpace() != GRAPHIC_COLOR_GAMUT_SRGB) {
707 newColorSpace_ = GRAPHIC_COLOR_GAMUT_DISPLAY_P3;
708 RS_LOGD("RSUniRenderVisitor::CheckColorSpaceWithSelfDrawingNode node(%{public}s) set new colorgamut %{public}d",
709 node.GetName().c_str(), newColorSpace_);
710 }
711 }
712
UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode & node)713 void RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc(RSDisplayRenderNode& node)
714 {
715 const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
716 for (const auto& selfDrawingNode : selfDrawingNodes) {
717 if (newColorSpace_ == GRAPHIC_COLOR_GAMUT_DISPLAY_P3) {
718 RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc: newColorSpace is already DISPLAY_P3.");
719 return;
720 }
721 if (!selfDrawingNode || !selfDrawingNode->GetAncestorDisplayNode().lock()) {
722 RS_LOGD("RSUniRenderVisitor::UpdateColorSpaceAfterHwcCalc selfDrawingNode or ancestorNode is nullptr");
723 continue;
724 }
725 auto ancestor = selfDrawingNode->GetAncestorDisplayNode().lock()->ReinterpretCastTo<RSDisplayRenderNode>();
726 if (ancestor != nullptr && node.GetId() == ancestor->GetId()) {
727 CheckColorSpaceWithSelfDrawingNode(*selfDrawingNode);
728 }
729 }
730 }
731
HandleColorGamuts(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)732 void RSUniRenderVisitor::HandleColorGamuts(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
733 {
734 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
735 if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
736 RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen type failed.");
737 return;
738 }
739
740 if (screenType == VIRTUAL_TYPE_SCREEN) {
741 ScreenColorGamut screenColorGamut;
742 if (screenManager->GetScreenColorGamut(node.GetScreenId(), screenColorGamut) != SUCCESS) {
743 RS_LOGD("RSUniRenderVisitor::HandleColorGamuts get screen color gamut failed.");
744 return;
745 }
746 newColorSpace_ = static_cast<GraphicColorGamut>(screenColorGamut);
747 }
748
749 auto stagingDisplayParams = static_cast<RSDisplayRenderParams*>(node.GetStagingRenderParams().get());
750 if (stagingDisplayParams) {
751 stagingDisplayParams->SetNewColorSpace(newColorSpace_);
752 }
753 newColorSpace_ = GRAPHIC_COLOR_GAMUT_SRGB;
754 }
755
CheckPixelFormat(RSSurfaceRenderNode & node)756 void RSUniRenderVisitor::CheckPixelFormat(RSSurfaceRenderNode& node)
757 {
758 if (node.GetHDRPresent()) {
759 RS_LOGD("SetHDRPresent true, surfaceNode: %{public}" PRIu64 "", node.GetId());
760 hasUniRenderHdrSurface_ = true;
761 }
762 if (hasFingerprint_) {
763 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat hasFingerprint is true.");
764 return;
765 }
766 if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
767 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat node(%{public}s) did not have buffer.", node.GetName().c_str());
768 return;
769 }
770
771 const sptr<SurfaceBuffer>& buffer = node.GetRSSurfaceHandler()->GetBuffer();
772
773 if (node.GetFingerprint()) {
774 hasFingerprint_ = true;
775 newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_1010102;
776 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat newPixelFormat_ is set 1010102 for fingerprint.");
777 return;
778 }
779
780 auto bufferPixelFormat = buffer->GetFormat();
781 if ((bufferPixelFormat == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
782 bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCBCR_P010 ||
783 bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCRCB_P010) && !IsHardwareComposerEnabled()) {
784 newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_1010102;
785 RS_LOGD("RSUniRenderVisitor::CheckPixelFormat pixelformat is set to 1010102 for 10bit buffer");
786 }
787 }
788
HandlePixelFormat(RSDisplayRenderNode & node,const sptr<RSScreenManager> & screenManager)789 void RSUniRenderVisitor::HandlePixelFormat(RSDisplayRenderNode& node, const sptr<RSScreenManager>& screenManager)
790 {
791 if (!RSSystemProperties::GetHDRImageEnable()) {
792 hasUniRenderHdrSurface_ = false;
793 }
794 auto stagingDisplayParams = static_cast<RSDisplayRenderParams*>(node.GetStagingRenderParams().get());
795 if (!stagingDisplayParams) {
796 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get StagingRenderParams failed.");
797 return;
798 }
799 ScreenId screenId = stagingDisplayParams->GetScreenId();
800 RSLuminanceControl::Get().SetHdrStatus(screenId, hasUniRenderHdrSurface_);
801 bool isHdrOn = RSLuminanceControl::Get().IsHdrOn(screenId);
802 float brightnessRatio = RSLuminanceControl::Get().GetHdrBrightnessRatio(screenId, 0);
803 RS_TRACE_NAME_FMT("HDR:%d, in Unirender:%d brightnessRatio:%f", isHdrOn, hasUniRenderHdrSurface_, brightnessRatio);
804 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat HDR isHdrOn:%{public}d hasUniRenderHdrSurface:%{public}d "
805 "brightnessRatio:%{public}f", isHdrOn, hasUniRenderHdrSurface_, brightnessRatio);
806 if (!hasUniRenderHdrSurface_) {
807 isHdrOn = false;
808 }
809 node.SetHDRPresent(isHdrOn);
810 RSScreenType screenType = BUILT_IN_TYPE_SCREEN;
811 if (screenManager->GetScreenType(node.GetScreenId(), screenType) != SUCCESS) {
812 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen type failed.");
813 return;
814 }
815
816 if (screenType == VIRTUAL_TYPE_SCREEN) {
817 if (screenManager->GetPixelFormat(node.GetScreenId(), newPixelFormat_) != SUCCESS) {
818 RS_LOGD("RSUniRenderVisitor::HandlePixelFormat get screen color gamut failed.");
819 }
820 }
821 stagingDisplayParams->SetNewPixelFormat(newPixelFormat_);
822 }
823
PrepareDisplayRenderNode(RSDisplayRenderNode & node)824 void RSUniRenderVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode& node)
825 {
826 currentVisitDisplay_ = node.GetScreenId();
827 displayHasSecSurface_.emplace(currentVisitDisplay_, false);
828 displayHasSkipSurface_.emplace(currentVisitDisplay_, false);
829 displayHasProtectedSurface_.emplace(currentVisitDisplay_, false);
830 displaySpecailSurfaceChanged_.emplace(currentVisitDisplay_, false);
831 hasCaptureWindow_.emplace(currentVisitDisplay_, false);
832 node.GetDirtySurfaceNodeMap().clear();
833
834 RS_TRACE_NAME("RSUniRender:PrepareDisplay " + std::to_string(currentVisitDisplay_));
835 curDisplayDirtyManager_ = node.GetDirtyManager();
836 if (!curDisplayDirtyManager_) {
837 return;
838 }
839 // set 1st elem for display dirty
840 accumulatedDirtyRegions_.emplace_back(RectI());
841 curDisplayDirtyManager_->Clear();
842 curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
843
844 dirtyFlag_ = isDirty_;
845 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
846 if (!screenManager) {
847 RS_LOGE("RSUniRenderVisitor::PrepareDisplayRenderNode ScreenManager is nullptr");
848 return;
849 }
850 screenInfo_ = screenManager->QueryScreenInfo(node.GetScreenId());
851 prepareClipRect_.SetAll(0, 0, screenInfo_.width, screenInfo_.height);
852 SendRcdMessage(node);
853 parentSurfaceNodeMatrix_ = Drawing::Matrix();
854 auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
855 if (geoPtr != nullptr) {
856 geoPtr->UpdateByMatrixFromSelf();
857 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
858 if (geoPtr->IsNeedClientCompose()) {
859 isHardwareForcedDisabled_ = true;
860 }
861 }
862 dirtyFlag_ = dirtyFlag_ || node.IsRotationChanged();
863 // when display is in rotation state, occlusion relationship will be ruined,
864 // hence partial-render quick-reject should be disabled.
865 if (node.IsRotationChanged()) {
866 isOpDropped_ = false;
867 RS_TRACE_NAME("ClosePartialRender 1 RotationChanged");
868 }
869 node.UpdateRotation();
870 curAlpha_ = node.GetRenderProperties().GetAlpha();
871 newColorSpace_ = GRAPHIC_COLOR_GAMUT_SRGB;
872 hasFingerprint_ = false;
873 newPixelFormat_ = GRAPHIC_PIXEL_FMT_RGBA_8888;
874 PrepareChildren(node);
875 auto mirrorNode = node.GetMirrorSource().lock();
876 if (mirrorNode) {
877 mirroredDisplays_.insert(mirrorNode->GetScreenId());
878 }
879
880 node.GetCurAllSurfaces(false).clear();
881 node.GetCurAllSurfaces(true).clear();
882 node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(false), true, false);
883 node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(true), true, true);
884
885 HandleColorGamuts(node, screenManager);
886 HandlePixelFormat(node, screenManager);
887 RSRcdRenderManager::GetInstance().DoPrepareRenderTask(rcdInfo_->prepareInfo);
888 }
889
CheckIfSurfaceRenderNodeStatic(RSSurfaceRenderNode & node)890 bool RSUniRenderVisitor::CheckIfSurfaceRenderNodeStatic(RSSurfaceRenderNode& node)
891 {
892 // dirtyFlag_ includes leashWindow dirty
893 // window layout change(e.g. move or zooming) | proxyRenderNode's cmd
894 // temporary cannot deal with leashWindow and scbScreen, restricted to mainwindow
895 if (dirtyFlag_ || node.IsDirty() || !node.IsMainWindowType() || curDisplayNode_ == nullptr) {
896 return false;
897 }
898 if (curDisplayDirtyManager_) {
899 accumulatedDirtyRegions_[0] = curDisplayDirtyManager_->GetCurrentFrameDirtyRegion();
900 }
901 // if node has to be prepared, it's not static
902 bool isClassifyByRootNode = (quickSkipPrepareType_ >= QuickSkipPrepareType::STATIC_APP_INSTANCE);
903 NodeId rootId = node.GetInstanceRootNodeId();
904 if (RSMainThread::Instance()->CheckNodeHasToBePreparedByPid(
905 isClassifyByRootNode ? rootId : node.GetId(), isClassifyByRootNode)) {
906 return false;
907 }
908 // [Attention] node's ability pid could be different but should have same rootId
909 auto abilityNodeIds = node.GetAbilityNodeIds();
910 bool result = isClassifyByRootNode
911 ? RSMainThread::Instance()->CheckNodeHasToBePreparedByPid(rootId, true)
912 : std::any_of(abilityNodeIds.begin(), abilityNodeIds.end(), [&](uint64_t nodeId) {
913 return RSMainThread::Instance()->CheckNodeHasToBePreparedByPid(nodeId, false);
914 });
915 if (result) {
916 return false;
917 }
918 node.UpdateSurfaceCacheContentStatic();
919 RS_OPTIONAL_TRACE_NAME("Skip static surface " + node.GetName() + " nodeid - pid: " +
920 std::to_string(node.GetId()) + " - " + std::to_string(ExtractPid(node.GetId())));
921 // static node's dirty region is empty
922 auto& dirtyManager = node.GetDirtyManager();
923 if (dirtyManager) {
924 dirtyManager->Clear();
925 if (node.IsTransparent()) {
926 dirtyManager->UpdateVisitedDirtyRects(accumulatedDirtyRegions_);
927 }
928 node.UpdateFilterCacheStatusIfNodeStatic(prepareClipRect_, curDisplayNode_->IsRotationChanged());
929 }
930 node.ResetDrawingCacheStatusIfNodeStatic(allCacheFilterRects_);
931 // Attention: curSurface info would be reset as upper surfaceParent if it has
932 ResetCurSurfaceInfoAsUpperSurfaceParent(node);
933 // static surface keeps same position
934 curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), curDisplayNode_->GetLastFrameSurfacePos(node.GetId()));
935 curDisplayNode_->AddSurfaceNodePosByDescZOrder(
936 node.GetId(), curDisplayNode_->GetLastFrameSurfacePos(node.GetId()));
937 return true;
938 }
939
ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode & node)940 void RSUniRenderVisitor::ResetCurSurfaceInfoAsUpperSurfaceParent(RSSurfaceRenderNode& node)
941 {
942 // record current frame mainwindow or leashwindow node
943 if (node.IsMainWindowType() || node.IsLeashWindow()) {
944 curMainAndLeashWindowNodesIds_.push(node.GetId());
945 curDisplayNode_->RecordMainAndLeashSurfaces(node.shared_from_this());
946 }
947 // only reset for instance node
948 if (curSurfaceNode_ == nullptr || curSurfaceNode_->GetId() != node.GetId()) {
949 return;
950 }
951 if (auto directParent = node.GetParent().lock()) {
952 if (auto parentInstance = directParent->GetInstanceRootNode()) {
953 // in case leashwindow is not directParent
954 auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
955 if (surfaceParent && (surfaceParent->IsLeashWindow() || surfaceParent->IsMainWindowType())) {
956 curSurfaceNode_ = surfaceParent;
957 curSurfaceDirtyManager_ = surfaceParent->GetDirtyManager();
958 filterInGlobal_ = surfaceParent->IsTransparent();
959 return;
960 }
961 curSurfaceNode_ = nullptr;
962 curSurfaceDirtyManager_ = nullptr;
963 filterInGlobal_ = true;
964 }
965 }
966 }
967
IsHardwareComposerEnabled()968 bool RSUniRenderVisitor::IsHardwareComposerEnabled()
969 {
970 return !isHardwareForcedDisabled_;
971 }
972
ClearTransparentBeforeSaveLayer()973 void RSUniRenderVisitor::ClearTransparentBeforeSaveLayer()
974 {
975 RS_TRACE_NAME("ClearTransparentBeforeSaveLayer");
976 if (!IsHardwareComposerEnabled()) {
977 return;
978 }
979 for (auto& node : hardwareEnabledNodes_) {
980 if (!node->ShouldPaint()) {
981 continue;
982 }
983 auto dstRect = node->GetDstRect();
984 if (dstRect.IsEmpty()) {
985 continue;
986 }
987 canvas_->Save();
988 canvas_->ClipRect({ static_cast<float>(dstRect.GetLeft()), static_cast<float>(dstRect.GetTop()),
989 static_cast<float>(dstRect.GetRight()), static_cast<float>(dstRect.GetBottom()) },
990 Drawing::ClipOp::INTERSECT, false);
991 canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
992 canvas_->Restore();
993 }
994 }
995
MarkSubHardwareEnableNodeState(RSSurfaceRenderNode & surfaceNode)996 void RSUniRenderVisitor::MarkSubHardwareEnableNodeState(RSSurfaceRenderNode& surfaceNode)
997 {
998 if (!IsHardwareComposerEnabled()) {
999 return;
1000 }
1001
1002 // hardware enabled type case: mark self
1003 if (surfaceNode.IsHardwareEnabledType()) {
1004 surfaceNode.SetHardwareForcedDisabledState(true);
1005 return;
1006 }
1007
1008 if (!surfaceNode.IsAppWindow() && !surfaceNode.IsAbilityComponent() && !surfaceNode.IsLeashWindow()) {
1009 return;
1010 }
1011
1012 // ability component type case: check pid
1013 if (surfaceNode.IsAbilityComponent()) {
1014 pid_t pid = ExtractPid(surfaceNode.GetId());
1015 for (auto& childNode : hardwareEnabledNodes_) {
1016 pid_t childPid = ExtractPid(childNode->GetId());
1017 if (pid == childPid) {
1018 childNode->SetHardwareForcedDisabledState(true);
1019 }
1020 }
1021 return;
1022 }
1023 std::vector<std::weak_ptr<RSSurfaceRenderNode>> hardwareEnabledNodes;
1024 if (surfaceNode.IsAppWindow()) {
1025 hardwareEnabledNodes = surfaceNode.GetChildHardwareEnabledNodes();
1026 } else {
1027 for (auto& child : *surfaceNode.GetChildren()) {
1028 auto appNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
1029 if (appNode && appNode->IsAppWindow()) {
1030 hardwareEnabledNodes = appNode->GetChildHardwareEnabledNodes();
1031 break;
1032 }
1033 }
1034 }
1035 // app window type case: mark all child hardware enabled nodes
1036 for (auto& node : hardwareEnabledNodes) {
1037 auto childNode = node.lock();
1038 if (childNode) {
1039 childNode->SetHardwareForcedDisabledState(true);
1040 }
1041 }
1042 }
1043
CollectAppNodeForHwc(std::shared_ptr<RSSurfaceRenderNode> surfaceNode)1044 void RSUniRenderVisitor::CollectAppNodeForHwc(std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
1045 {
1046 if (!IsHardwareComposerEnabled() || !surfaceNode || surfaceNode->GetChildHardwareEnabledNodes().empty()) {
1047 return;
1048 }
1049 if (surfaceNode->IsHardwareEnabledTopSurface()) {
1050 hardwareEnabledTopNodes_.emplace_back(surfaceNode);
1051 } else {
1052 appWindowNodesInZOrder_.emplace_back(surfaceNode);
1053 }
1054 }
1055
PrepareTypesOfSurfaceRenderNodeBeforeUpdate(RSSurfaceRenderNode & node)1056 void RSUniRenderVisitor::PrepareTypesOfSurfaceRenderNodeBeforeUpdate(RSSurfaceRenderNode& node)
1057 {
1058 // if current surfacenode is a main window type, reset the curSurfaceDirtyManager
1059 // reset leash window's dirtyManager pointer to avoid curSurfaceDirtyManager mis-pointing
1060 if (node.IsLeashOrMainWindow()) {
1061 node.SetFilterCacheFullyCovered(false);
1062 node.ResetFilterNodes();
1063 // [planning] check if it is not reset recursively
1064 firstVisitedCache_ = INVALID_NODEID;
1065 curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1066 RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1067 curSurfaceDirtyManager_ = node.GetDirtyManager();
1068 if (curSurfaceDirtyManager_ == nullptr) {
1069 RS_LOGE("RSUniRenderVisitor::PrepareTypesOfSurfaceRenderNodeBeforeUpdate %{public}s has no"
1070 " SurfaceDirtyManager", node.GetName().c_str());
1071 return;
1072 }
1073 curSurfaceDirtyManager_->Clear();
1074 if (node.IsTransparent()) {
1075 curSurfaceDirtyManager_->UpdateVisitedDirtyRects(accumulatedDirtyRegions_);
1076 }
1077 curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1078 if (isTargetDirtyRegionDfxEnabled_ && CheckIfSurfaceTargetedForDFX(node.GetName())) {
1079 curSurfaceDirtyManager_->MarkAsTargetForDfx();
1080 }
1081 ClassifyUIFirstSurfaceDirtyStatus(node);
1082 }
1083
1084 // collect app window node's child hardware enabled node
1085 if (node.IsHardwareEnabledType() && curSurfaceNode_) {
1086 curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
1087 node.SetLocalZOrder(localZOrder_++);
1088 }
1089 }
1090
ClassifyUIFirstSurfaceDirtyStatus(RSSurfaceRenderNode & node)1091 void RSUniRenderVisitor::ClassifyUIFirstSurfaceDirtyStatus(RSSurfaceRenderNode& node)
1092 {
1093 if (node.IsMainWindowType()) {
1094 isCachedSurfaceReuse_ = (quickSkipPrepareType_ >= QuickSkipPrepareType::STATIC_CACHE_SURFACE) &&
1095 (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) &&
1096 CheckIfUIFirstSurfaceContentReusable(curSurfaceNode_, isSurfaceDirtyNodeLimited_);
1097 // The condition of childHasVisibleFilter in QuerySubAssignable can not be used here
1098 // Because child node's filter is not collected yet, so disable prepare optimization when node is transparent
1099 // [planning]: detect the filter change before prepare, and use the last frame result
1100 isSurfaceDirtyNodeLimited_ = (quickSkipPrepareType_ == QuickSkipPrepareType::CONTENT_DIRTY_CACHE_SURFACE) &&
1101 !node.IsTransparent() && isSurfaceDirtyNodeLimited_ &&
1102 node.IsOnlyBasicGeoTransform() && node.IsContentDirtyNodeLimited();
1103 if (isCachedSurfaceReuse_) {
1104 node.SetGeoUpdateDelay(dirtyFlag_);
1105 }
1106 }
1107 }
1108
CheckIfUIFirstSurfaceContentReusable(std::shared_ptr<RSSurfaceRenderNode> & node,bool & isAssigned)1109 bool RSUniRenderVisitor::CheckIfUIFirstSurfaceContentReusable(std::shared_ptr<RSSurfaceRenderNode>& node,
1110 bool& isAssigned)
1111 {
1112 if (!isUIFirst_ || node == nullptr) {
1113 return false;
1114 }
1115 auto deviceType = RSMainThread::Instance()->GetDeviceType();
1116 if (auto directParent = node->GetParent().lock()) {
1117 if (auto parentInstance = directParent->GetInstanceRootNode()) {
1118 auto surfaceParent = parentInstance->ReinterpretCastTo<RSSurfaceRenderNode>();
1119 if (surfaceParent && surfaceParent->IsLeashWindow()) {
1120 isAssigned =
1121 RSUniRenderUtil::IsNodeAssignSubThread(surfaceParent, curDisplayNode_->IsRotationChanged());
1122 RS_OPTIONAL_TRACE_NAME_FMT("%s CheckIfUIFirstSurfaceContentReusable(leash): %d, isAssigned %d",
1123 surfaceParent->GetName().c_str(), surfaceParent->IsUIFirstCacheReusable(deviceType), isAssigned);
1124 return isAssigned && surfaceParent->IsUIFirstCacheReusable(deviceType);
1125 }
1126 }
1127 }
1128 isAssigned = RSUniRenderUtil::IsNodeAssignSubThread(node, curDisplayNode_->IsRotationChanged());
1129 RS_OPTIONAL_TRACE_NAME_FMT("%s CheckIfUIFirstSurfaceContentReusable(mainwindow): %d, isAssigned %d",
1130 node->GetName().c_str(), node->IsUIFirstCacheReusable(deviceType), isAssigned);
1131 return isAssigned && node->IsUIFirstCacheReusable(deviceType);
1132 }
1133
PrepareTypesOfSurfaceRenderNodeAfterUpdate(RSSurfaceRenderNode & node)1134 void RSUniRenderVisitor::PrepareTypesOfSurfaceRenderNodeAfterUpdate(RSSurfaceRenderNode& node)
1135 {
1136 if (!curSurfaceDirtyManager_) {
1137 return;
1138 }
1139 const auto& properties = node.GetRenderProperties();
1140 if (properties.NeedFilter()) {
1141 UpdateForegroundFilterCacheWithDirty(node, *curSurfaceDirtyManager_);
1142 if (auto parentNode = node.GetParent().lock()) {
1143 parentNode->SetChildHasVisibleFilter(true);
1144 }
1145 if (curSurfaceNode_) {
1146 curSurfaceNode_->UpdateFilterNodes(node.shared_from_this());
1147 }
1148 }
1149 if (node.IsLeashWindow()) {
1150 auto children = node.GetSortedChildren();
1151 for (auto& child : *children) {
1152 if (child->ChildHasVisibleFilter()) {
1153 node.SetChildHasVisibleFilter(true);
1154 break;
1155 }
1156 }
1157 } else if (node.IsMainWindowType()) {
1158 isCachedSurfaceReuse_ = false;
1159 isSurfaceDirtyNodeLimited_ = false;
1160 bool hasFilter = node.IsTransparent() && properties.NeedFilter();
1161 bool hasHardwareNode = !node.GetChildHardwareEnabledNodes().empty();
1162 bool hasAbilityComponent = !node.GetAbilityNodeIds().empty();
1163 auto rsParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1164 if (rsParent && rsParent->IsLeashWindow()) {
1165 rsParent->SetHasFilter(hasFilter);
1166 rsParent->SetHasHardwareNode(hasHardwareNode);
1167 rsParent->SetHasAbilityComponent(hasAbilityComponent);
1168 // [uifirst] leashWindow add or clear abilityNodeId for checking subthread node status
1169 if (hasAbilityComponent) {
1170 rsParent->AddAbilityComponentNodeIds(node.GetAbilityNodeIds());
1171 } else {
1172 rsParent->ResetAbilityNodeIds();
1173 }
1174 } else {
1175 node.SetHasFilter(hasFilter);
1176 node.SetHasHardwareNode(hasHardwareNode);
1177 node.SetHasAbilityComponent(hasAbilityComponent);
1178 }
1179 if (node.IsTransparent() &&
1180 curSurfaceDirtyManager_->IfCacheableFilterRectFullyCover(node.GetOldDirtyInSurface())) {
1181 node.SetFilterCacheFullyCovered(true);
1182 RS_LOGD("SetFilterCacheFullyCovered surfacenode %{public}" PRIu64 " [%{public}s]",
1183 node.GetId(), node.GetName().c_str());
1184 }
1185 node.CalcFilterCacheValidForOcclusion();
1186 RS_OPTIONAL_TRACE_NAME(node.GetName() + " PreparedNodes: " +
1187 std::to_string(preparedCanvasNodeInCurrentSurface_));
1188 preparedCanvasNodeInCurrentSurface_ = 0;
1189 }
1190 // accumulate all visited dirty rects including leash window's shadow dirty
1191 if (node.IsLeashOrMainWindow() && curSurfaceDirtyManager_->IsCurrentFrameDirty()) {
1192 accumulatedDirtyRegions_.emplace_back(curSurfaceDirtyManager_->GetCurrentFrameDirtyRegion());
1193 }
1194 }
1195
UpdateSecuritySkipAndProtectedLayersRecord(RSSurfaceRenderNode & node)1196 void RSUniRenderVisitor::UpdateSecuritySkipAndProtectedLayersRecord(RSSurfaceRenderNode& node)
1197 {
1198 if (node.GetHasSecurityLayer()) {
1199 displayHasSecSurface_[currentVisitDisplay_] = true;
1200 curDisplayNode_->AddSecurityLayer(node.IsLeashWindow() ? node.GetLeashPersistentId() : node.GetId());
1201 }
1202 if (node.GetHasSkipLayer() && node.GetName().find(CAPTURE_WINDOW_NAME) == std::string::npos) {
1203 displayHasSkipSurface_[currentVisitDisplay_] = true;
1204 }
1205 if (node.GetHasProtectedLayer()) {
1206 displayHasProtectedSurface_[currentVisitDisplay_] = true;
1207 }
1208 if (node.IsSpecialLayerChanged()) {
1209 displaySpecailSurfaceChanged_[currentVisitDisplay_] = true;
1210 }
1211 }
1212
UpdateForegroundFilterCacheWithDirty(RSRenderNode & node,RSDirtyRegionManager & dirtyManager,bool isForeground)1213 void RSUniRenderVisitor::UpdateForegroundFilterCacheWithDirty(RSRenderNode& node,
1214 RSDirtyRegionManager& dirtyManager, bool isForeground)
1215 {
1216 node.UpdateFilterCacheWithBelowDirty(dirtyManager, isForeground);
1217 node.UpdateFilterCacheWithSelfDirty();
1218 }
1219
UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode & node)1220 void RSUniRenderVisitor::UpdateSurfaceRenderNodeRotate(RSSurfaceRenderNode& node)
1221 {
1222 if (!node.IsMainWindowType()) {
1223 return;
1224 }
1225 auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
1226 if (!geoPtr) {
1227 return;
1228 }
1229 if (RSUniRenderUtil::GetRotationDegreeFromMatrix(geoPtr->GetAbsMatrix()) % RS_ROTATION_90 != 0) {
1230 node.SetIsRotating(true);
1231 }
1232 }
1233
IsSubTreeOccluded(RSRenderNode & node) const1234 bool RSUniRenderVisitor::IsSubTreeOccluded(RSRenderNode& node) const
1235 {
1236 if (!isOcclusionEnabled_) {
1237 return false;
1238 }
1239 // step1. apply occlusion info for surfacenode and skip fully covered subtree
1240 if (node.GetType() == RSRenderNodeType::SURFACE_NODE) {
1241 auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1242 if (surfaceNode.IsMainWindowType()) {
1243 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::IsSubTreeOccluded node[%s]"
1244 "name:[%s] visibleRegionIsEmpty[%d]",
1245 std::to_string(node.GetId()).c_str(), surfaceNode.GetName().c_str(),
1246 surfaceNode.GetVisibleRegion().IsEmpty());
1247 auto isOccluded = hasMirrorDisplay_ ?
1248 surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
1249 if (isOccluded && curSurfaceDirtyManager_) {
1250 curSurfaceDirtyManager_->Clear();
1251 }
1252 surfaceNode.AccmulateDirtyInOcclusion(isOccluded);
1253 return isOccluded;
1254 }
1255 }
1256 // step2.1 For partial visible surface, intersected region->rects in surface
1257 // step2.2 check if clean subtree in occlusion rects
1258 return false;
1259 }
1260
ResetDisplayDirtyRegion()1261 void RSUniRenderVisitor::ResetDisplayDirtyRegion()
1262 {
1263 if (!curDisplayDirtyManager_) {
1264 return;
1265 }
1266 bool isNeedNotchUpdate = RSSingleton<RoundCornerDisplay>::GetInstance().IsNotchNeedUpdate(
1267 RSSystemParameters::GetHideNotchStatus());
1268 bool ret = CheckScreenPowerChange() ||
1269 CheckColorFilterChange() ||
1270 CheckCurtainScreenUsingStatusChange() ||
1271 IsFirstFrameOfPartialRender() ||
1272 IsWatermarkFlagChanged() ||
1273 zoomStateChange_ ||
1274 isCompleteRenderEnabled_ ||
1275 CheckLuminanceStatusChange() ||
1276 IsFirstFrameOfOverdrawSwitch() ||
1277 isNeedNotchUpdate;
1278 if (ret) {
1279 curDisplayDirtyManager_->ResetDirtyAsSurfaceSize();
1280 RS_LOGD("RSUniRenderVisitor::ResetDisplayDirtyRegion on");
1281 }
1282 }
1283
CheckScreenPowerChange() const1284 bool RSUniRenderVisitor::CheckScreenPowerChange() const
1285 {
1286 if (!RSMainThread::Instance()->GetScreenPowerOnChanged()) {
1287 return false;
1288 }
1289 RS_LOGD("RSUniRenderVisitor::CheckScreenPowerChange changed");
1290 return true;
1291 }
1292
CheckCurtainScreenUsingStatusChange() const1293 bool RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange() const
1294 {
1295 if (!RSMainThread::Instance()->IsCurtainScreenUsingStatusChanged()) {
1296 return false;
1297 }
1298 RS_LOGD("RSUniRenderVisitor::CheckCurtainScreenUsingStatusChange changed");
1299 return true;
1300 }
1301
CheckLuminanceStatusChange()1302 bool RSUniRenderVisitor::CheckLuminanceStatusChange()
1303 {
1304 if (!RSMainThread::Instance()->ExchangeLuminanceChangingStatus()) {
1305 return false;
1306 }
1307 RS_LOGD("RSUniRenderVisitor::CheckLuminanceStatusChange changed");
1308 return true;
1309 }
1310
IsFirstFrameOfPartialRender() const1311 bool RSUniRenderVisitor::IsFirstFrameOfPartialRender() const
1312 {
1313 if (!RSMainThread::Instance()->IsFirstFrameOfPartialRender()) {
1314 return false;
1315 }
1316 RS_LOGD("FirstFrameOfPartialRender");
1317 return true;
1318 }
1319
IsFirstFrameOfOverdrawSwitch() const1320 bool RSUniRenderVisitor::IsFirstFrameOfOverdrawSwitch() const
1321 {
1322 if (!RSMainThread::Instance()->IsFirstFrameOfOverdrawSwitch()) {
1323 return false;
1324 }
1325 RS_LOGD("IsFirstFrameOfOverdrawSwitch");
1326 return true;
1327 }
1328
IsWatermarkFlagChanged() const1329 bool RSUniRenderVisitor::IsWatermarkFlagChanged() const
1330 {
1331 if (RSMainThread::Instance()->IsWatermarkFlagChanged()) {
1332 RS_LOGD("FirstOrLastFrameOfWatermark");
1333 return true;
1334 } else {
1335 return false;
1336 }
1337 }
1338
UpdateDisplayZoomState()1339 void RSUniRenderVisitor::UpdateDisplayZoomState()
1340 {
1341 if (!curDisplayNode_) {
1342 return;
1343 }
1344 auto scale = curDisplayNode_->GetRenderProperties().GetScale();
1345 bool curZoomState = scale.x_ > 1.f || scale.y_ > 1.f;
1346 curDisplayNode_->UpdateZoomState(curZoomState);
1347 zoomStateChange_ = curZoomState || curDisplayNode_->IsZoomStateChange();
1348 }
1349
UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode & node)1350 void RSUniRenderVisitor::UpdateVirtualScreenSecurityExemption(RSDisplayRenderNode& node)
1351 {
1352 // only for virtual screen
1353 if (!(node.IsMirrorDisplay())) {
1354 return;
1355 }
1356 auto mirrorNode = node.GetMirrorSource().lock();
1357 if (mirrorNode == nullptr || screenManager_ == nullptr) {
1358 return;
1359 }
1360 auto securityExemptionList = screenManager_->GetVirtualScreenSecurityExemptionList(node.GetScreenId());
1361 if (securityExemptionList.size() == 0) {
1362 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:false",
1363 node.GetId());
1364 node.SetSecurityExemption(false);
1365 mirrorNode->ClearSecurityLayerList();
1366 return;
1367 }
1368 auto securityLayerList = mirrorNode->GetSecurityLayerList();
1369 for (const auto& exemptionLayer : securityExemptionList) {
1370 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
1371 "securityExemption nodeId %{public}" PRIu64 ".", node.GetId(), exemptionLayer);
1372 }
1373 for (const auto& secLayer : securityLayerList) {
1374 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ""
1375 "securityLayer nodeId %{public}" PRIu64 ".", mirrorNode->GetId(), secLayer);
1376 }
1377 bool isSecurityExemption = false;
1378 if (securityExemptionList.size() >= securityLayerList.size()) {
1379 isSecurityExemption = true;
1380 for (const auto& secLayer : securityLayerList) {
1381 if (std::find(securityExemptionList.begin(), securityExemptionList.end(), secLayer) ==
1382 securityExemptionList.end()) {
1383 isSecurityExemption = false;
1384 break;
1385 }
1386 }
1387 }
1388 RS_LOGD("UpdateVirtualScreenSecurityExemption::node:%{public}" PRIu64 ", isSecurityExemption:%{public}d",
1389 node.GetId(), isSecurityExemption);
1390 node.SetSecurityExemption(isSecurityExemption);
1391 mirrorNode->ClearSecurityLayerList();
1392 }
1393
QuickPrepareDisplayRenderNode(RSDisplayRenderNode & node)1394 void RSUniRenderVisitor::QuickPrepareDisplayRenderNode(RSDisplayRenderNode& node)
1395 {
1396 // 0. init display info
1397 RS_TRACE_NAME("RSUniRender:QuickPrepareDisplayRenderNode " + std::to_string(node.GetScreenId()));
1398 if (!InitDisplayInfo(node)) {
1399 return;
1400 }
1401 UpdateDisplayZoomState();
1402 SendRcdMessage(node);
1403 UpdateVirtualScreenSecurityExemption(node);
1404 ancestorNodeHasAnimation_ = false;
1405 displayNodeRotationChanged_ = node.IsRotationChanged();
1406 dirtyFlag_ = isDirty_ || displayNodeRotationChanged_ || zoomStateChange_;
1407 prepareClipRect_ = screenRect_;
1408 hasAccumulatedClip_ = false;
1409
1410 curAlpha_ = 1.0f;
1411 globalZOrder_ = 0.0f;
1412 hasSkipLayer_ = false;
1413 node.UpdateRotation();
1414 if (!(RSMainThread::Instance()->IsRequestedNextVSync() || RSMainThread::Instance()->GetNextDVsyncAnimateFlag())) {
1415 RS_OPTIONAL_TRACE_NAME_FMT("do not request next vsync");
1416 needRequestNextVsync_ = false;
1417 }
1418 RSUifirstManager::Instance().SetRotationChanged(displayNodeRotationChanged_ || isScreenRotationAnimating_);
1419 if (node.IsSubTreeDirty() || node.IsRotationChanged()) {
1420 QuickPrepareChildren(node);
1421 }
1422 PostPrepare(node);
1423 UpdateHwcNodeEnable();
1424 UpdateSurfaceDirtyAndGlobalDirty();
1425 UpdateSurfaceOcclusionInfo();
1426 if (needRecalculateOcclusion_) {
1427 // Callback for registered self drawing surfacenode
1428 RSMainThread::Instance()->SurfaceOcclusionCallback();
1429 }
1430 //UIFirst layer must be above displayNode, so use zorder + 1
1431 RSUifirstManager::Instance().UpdateUIFirstLayerInfo(screenInfo_, globalZOrder_ + 1);
1432 curDisplayNode_->UpdatePartialRenderParams();
1433 RSDisplayRenderNode::ScreenRenderParams screenRenderParams;
1434 screenRenderParams.screenInfo = std::move(screenInfo_);
1435 screenRenderParams.displayHasSecSurface = std::move(displayHasSecSurface_);
1436 screenRenderParams.displayHasSkipSurface = std::move(displayHasSkipSurface_);
1437 screenRenderParams.displayHasProtectedSurface = std::move(displayHasProtectedSurface_);
1438 screenRenderParams.displaySpecailSurfaceChanged = std::move(displaySpecailSurfaceChanged_);
1439 screenRenderParams.hasCaptureWindow = std::move(hasCaptureWindow_);
1440 curDisplayNode_->UpdateScreenRenderParams(screenRenderParams);
1441 curDisplayNode_->UpdateOffscreenRenderParams(curDisplayNode_->IsRotationChanged());
1442 UpdateColorSpaceAfterHwcCalc(node);
1443 HandleColorGamuts(node, screenManager_);
1444 HandlePixelFormat(node, screenManager_);
1445 if (UNLIKELY(!SharedTransitionParam::unpairedShareTransitions_.empty())) {
1446 ProcessUnpairedSharedTransitionNode();
1447 }
1448 node.RenderTraceDebug();
1449 }
1450
CheckFilterCacheNeedForceClearOrSave(RSRenderNode & node)1451 void RSUniRenderVisitor::CheckFilterCacheNeedForceClearOrSave(RSRenderNode& node)
1452 {
1453 if (!node.HasBlurFilter()) {
1454 return;
1455 }
1456 bool rotationChanged = curDisplayNode_ ?
1457 curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
1458 bool rotationStatusChanged = curDisplayNode_ ?
1459 curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
1460 node.CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
1461 }
1462
1463 // private method, curDisplayNode_ or curSurfaceNode_ will not be nullptr
CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet & filterSet,bool isGlobalDirty)1464 void RSUniRenderVisitor::CheckMergeFilterDirtyByIntersectWithDirty(OcclusionRectISet& filterSet, bool isGlobalDirty)
1465 {
1466 // Recursively traverses until the globalDirty do not change
1467 auto dirtyManager = isGlobalDirty ? curDisplayNode_->GetDirtyManager() : curSurfaceNode_->GetDirtyManager();
1468 if (dirtyManager == nullptr) {
1469 return;
1470 }
1471 for (auto it = filterSet.begin(); it != filterSet.end();) {
1472 auto dirtyRect = dirtyManager->GetCurrentFrameDirtyRegion();
1473 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
1474 auto dirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
1475 auto filterDirtyRegion = filterRegion.And(dirtyRegion);
1476 if (!filterDirtyRegion.IsEmpty()) {
1477 if (isGlobalDirty) {
1478 RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
1479 "global dirty %{public}s, add filterRegion %{public}s",
1480 dirtyRect.ToString().c_str(), (it->second).ToString().c_str());
1481 }
1482 dirtyManager->MergeDirtyRect(it->second);
1483 it = filterSet.erase(it);
1484 if (dirtyRect != dirtyManager->GetCurrentFrameDirtyRegion()) {
1485 // When dirtyRegion is changed, collect dirty filter region from begin.
1486 // After all filter region is added, the cycle will definitely stop.
1487 it = filterSet.begin();
1488 }
1489 } else {
1490 ++it;
1491 }
1492 }
1493 filterSet.clear();
1494 }
1495
QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode & node)1496 void RSUniRenderVisitor::QuickPrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
1497 {
1498 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRender::QuickPrepare:[%s] nodeId[%" PRIu64 "]"
1499 "pid[%d] nodeType[%u] subTreeDirty[%d]", node.GetName().c_str(), node.GetId(), ExtractPid(node.GetId()),
1500 static_cast<uint>(node.GetSurfaceNodeType()), node.IsSubTreeDirty());
1501 RS_LOGD("RSUniRender::QuickPrepareSurfaceRenderNode:[%{public}s] nodeid:[%{public}" PRIu64 "]"
1502 "pid:[%{public}d] nodeType:[%{public}d] subTreeDirty[%{public}d]", node.GetName().c_str(), node.GetId(),
1503 ExtractPid(node.GetId()), static_cast<int>(node.GetSurfaceNodeType()), node.IsSubTreeDirty());
1504
1505 // 0. init curSurface info and check node info
1506 auto curCornerRadius = curCornerRadius_;
1507 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
1508 if (!BeforeUpdateSurfaceDirtyCalc(node)) {
1509 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode BeforeUpdateSurfaceDirtyCalc fail");
1510 RSUifirstManager::Instance().DisableUifirstNode(node);
1511 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1512 return;
1513 }
1514
1515 if (curSurfaceDirtyManager_ == nullptr) {
1516 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
1517 node.GetName().c_str());
1518 return;
1519 }
1520
1521 // 1. Update matrix and collect dirty region
1522 auto dirtyFlag = dirtyFlag_;
1523 auto prepareClipRect = prepareClipRect_;
1524 bool hasAccumulatedClip = hasAccumulatedClip_;
1525 auto prevAlpha = curAlpha_;
1526 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1527 node.SetGlobalAlpha(curAlpha_);
1528 CheckFilterCacheNeedForceClearOrSave(node);
1529 node.CheckContainerDirtyStatusAndUpdateDirty(curContainerDirty_);
1530 dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
1531 *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix);
1532 auto& geoPtr = node.GetRenderProperties().GetBoundsGeometry();
1533 if (!geoPtr) {
1534 return;
1535 }
1536 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
1537 if (!AfterUpdateSurfaceDirtyCalc(node)) {
1538 RS_LOGE("RSUniRenderVisitor::QuickPrepareSurfaceRenderNode AfterUpdateSurfaceDirtyCalc fail");
1539 RSUifirstManager::Instance().DisableUifirstNode(node);
1540 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1541 return;
1542 }
1543 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1544 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_, IsSubTreeOccluded(node)) ||
1545 ForcePrepareSubTree();
1546 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1547 node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
1548
1549 // Update whether leash window's visible region is empty after prepare children
1550 UpdateLeashWindowVisibleRegionEmpty(node);
1551
1552 if (node.IsLeashWindow() && RSSystemProperties::GetGpuOverDrawBufferOptimizeEnabled()) {
1553 CheckIsGpuOverDrawBufferOptimizeNode(node);
1554 }
1555 PostPrepare(node, !isSubTreeNeedPrepare);
1556 CheckMergeFilterDirtyByIntersectWithDirty(curSurfaceNoBelowDirtyFilter_, false);
1557 curAlpha_ = prevAlpha;
1558 prepareClipRect_ = prepareClipRect;
1559 hasAccumulatedClip_ = hasAccumulatedClip;
1560 dirtyFlag_ = dirtyFlag;
1561
1562 PrepareForUIFirstNode(node);
1563 node.OpincSetInAppStateEnd(unchangeMarkInApp_);
1564 ResetCurSurfaceInfoAsUpperSurfaceParent(node);
1565 curCornerRadius_ = curCornerRadius;
1566 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
1567 node.RenderTraceDebug();
1568 node.SetNeedOffscreen(isScreenRotationAnimating_);
1569 }
1570
PrepareForUIFirstNode(RSSurfaceRenderNode & node)1571 void RSUniRenderVisitor::PrepareForUIFirstNode(RSSurfaceRenderNode& node)
1572 {
1573 MultiThreadCacheType lastFlag = node.GetLastFrameUifirstFlag();
1574 RSUifirstManager::Instance().UpdateUifirstNodes(node, ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation());
1575 RSUifirstManager::Instance().UpdateUIFirstNodeUseDma(node, globalSurfaceBounds_);
1576 if (node.GetLastFrameUifirstFlag() == MultiThreadCacheType::LEASH_WINDOW &&
1577 !node.IsHardwareForcedDisabled()) {
1578 if (auto& geo = node.GetRenderProperties().GetBoundsGeometry()) {
1579 UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
1580 }
1581 UpdateHwcNodeByTransform(node);
1582 }
1583 if (RSUifirstManager::Instance().GetUseDmaBuffer(node.GetName()) && curSurfaceDirtyManager_ &&
1584 (node.GetLastFrameUifirstFlag() != lastFlag ||
1585 !node.IsHardwareForcedDisabled() != node.GetIsLastFrameHwcEnabled())) {
1586 curSurfaceDirtyManager_->MergeDirtyRect(node.GetOldDirty());
1587 }
1588 }
1589
UpdateNodeVisibleRegion(RSSurfaceRenderNode & node)1590 void RSUniRenderVisitor::UpdateNodeVisibleRegion(RSSurfaceRenderNode& node)
1591 {
1592 Occlusion::Rect selfDrawRect = node.GetSurfaceOcclusionRect(true);
1593 Occlusion::Region selfDrawRegion { selfDrawRect };
1594 if (needRecalculateOcclusion_) {
1595 Occlusion::Region subResult = selfDrawRegion.Sub(accumulatedOcclusionRegion_);
1596 node.SetVisibleRegion(subResult);
1597 Occlusion::Region subResultWithoutSkipLayer = selfDrawRegion.Sub(occlusionRegionWithoutSkipLayer_);
1598 node.SetVisibleRegionInVirtual(subResultWithoutSkipLayer);
1599 }
1600 RS_OPTIONAL_TRACE_NAME_FMT_LEVEL(TRACE_LEVEL_THREE,
1601 "RSUniRenderVisitor::UpdateNodeVisibleRegion name[%s] visibleRegion[%s]",
1602 node.GetName().c_str(), node.GetVisibleRegion().GetRegionInfo().c_str());
1603 }
1604
CalculateOcclusion(RSSurfaceRenderNode & node)1605 void RSUniRenderVisitor::CalculateOcclusion(RSSurfaceRenderNode& node)
1606 {
1607 if (!curDisplayNode_) {
1608 RS_LOGE("RSUniRenderVisitor::CalculateOcclusion curDisplayNode is nullptr");
1609 return;
1610 }
1611 // CheckAndUpdateOpaqueRegion only in mainWindow
1612 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
1613 auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
1614 (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
1615 node.CheckAndUpdateOpaqueRegion(screenRect_, curDisplayNode_->GetRotation(), isFocused);
1616 if (!needRecalculateOcclusion_) {
1617 needRecalculateOcclusion_ = node.CheckIfOcclusionChanged();
1618 }
1619 // Update node visibleRegion
1620 hasSkipLayer_ = hasSkipLayer_ || node.GetSkipLayer();
1621 UpdateNodeVisibleRegion(node);
1622 auto mainThread = RSMainThread::Instance();
1623 node.SetOcclusionInSpecificScenes(mainThread->GetDeviceType() == DeviceType::PC &&
1624 mainThread->IsPCThreeFingerScenesListScene());
1625 // check current surface Participate In Occlusion
1626 if (node.CheckParticipateInOcclusion() && !isAllSurfaceVisibleDebugEnabled_) {
1627 accumulatedOcclusionRegion_.OrSelf(node.GetOpaqueRegion());
1628 std::unordered_set<NodeId> currentBlackList = GetCurrentBlackList();
1629 if (IsValidInVirtualScreen(node) && currentBlackList.find(node.GetId()) == currentBlackList.end()) {
1630 occlusionRegionWithoutSkipLayer_.OrSelf(node.GetOpaqueRegion());
1631 }
1632 }
1633 node.SetOcclusionInSpecificScenes(false);
1634 CollectOcclusionInfoForWMS(node);
1635 }
1636
CollectOcclusionInfoForWMS(RSSurfaceRenderNode & node)1637 void RSUniRenderVisitor::CollectOcclusionInfoForWMS(RSSurfaceRenderNode& node)
1638 {
1639 if (!node.IsMainWindowType()) {
1640 return;
1641 }
1642 // collect mainWindow occlusion visibleLevel
1643 Occlusion::Region selfDrawRegion { node.GetSurfaceOcclusionRect(true) };
1644 auto visibleLevel = GetRegionVisibleLevel(node.GetVisibleRegion(), selfDrawRegion);
1645 // wms default all visible about sefdrawing node and AbilityComponent node
1646 auto instanceNode = node.GetInstanceRootNode() ?
1647 node.GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
1648 if (instanceNode == nullptr) {
1649 return;
1650 }
1651 if ((node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE &&
1652 !instanceNode->GetVisibleRegion().IsEmpty()) || node.IsAbilityComponent()) {
1653 dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1654 WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1655 return;
1656 }
1657 dstCurVisVec_.emplace_back(std::make_pair(node.GetId(),
1658 node.GetVisibleLevelForWMS(visibleLevel)));
1659 }
1660
SurfaceOcclusionCallbackToWMS()1661 void RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS()
1662 {
1663 if (RSSystemParameters::GetOcclusionCallBackToWMSDebugType()) {
1664 allDstCurVisVec_.clear();
1665 const auto& curAllSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
1666 for (const auto& surfacePtr : curAllSurfaces) {
1667 if (surfacePtr == nullptr) {
1668 continue;
1669 }
1670 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*surfacePtr);
1671 if (surfaceNode.IsMainWindowType()) {
1672 allDstCurVisVec_.emplace_back(std::make_pair(surfacePtr->GetId(),
1673 WINDOW_LAYER_INFO_TYPE::ALL_VISIBLE));
1674 }
1675 }
1676 }
1677 if (allDstCurVisVec_ != allLastVisVec_) {
1678 RSMainThread::Instance()->SurfaceOcclusionChangeCallback(allDstCurVisVec_);
1679 RS_LOGI("RSUniRenderVisitor::SurfaceOcclusionCallbackToWMS %{public}s",
1680 VisibleDataToString(allDstCurVisVec_).c_str());
1681 allLastVisVec_ = std::move(allDstCurVisVec_);
1682 }
1683 }
1684
GetCurrentBlackList() const1685 std::unordered_set<NodeId> RSUniRenderVisitor::GetCurrentBlackList() const
1686 {
1687 if (!screenManager_ || !curDisplayNode_) {
1688 return std::unordered_set<NodeId>();
1689 }
1690
1691 std::unordered_set<NodeId> currentBlackList;
1692 if (screenManager_->GetCastScreenEnableSkipWindow(curDisplayNode_->GetScreenId())) {
1693 screenManager_->GetCastScreenBlackList(currentBlackList);
1694 } else {
1695 currentBlackList = screenManager_->GetVirtualScreenBlackList(curDisplayNode_->GetScreenId());
1696 }
1697 return currentBlackList;
1698 }
1699
GetRegionVisibleLevel(const Occlusion::Region & visibleRegion,const Occlusion::Region & selfDrawRegion)1700 RSVisibleLevel RSUniRenderVisitor::GetRegionVisibleLevel(const Occlusion::Region& visibleRegion,
1701 const Occlusion::Region& selfDrawRegion)
1702 {
1703 if (visibleRegion.IsEmpty()) {
1704 return RSVisibleLevel::RS_INVISIBLE;
1705 } else if (visibleRegion.Area() == selfDrawRegion.Area()) {
1706 return RSVisibleLevel::RS_ALL_VISIBLE;
1707 } else if (static_cast<uint>(visibleRegion.Area()) <
1708 (static_cast<uint>(selfDrawRegion.Area()) >> VISIBLEAREARATIO_FORQOS)) {
1709 return RSVisibleLevel::RS_SEMI_DEFAULT_VISIBLE;
1710 }
1711 return RSVisibleLevel::RS_SEMI_NONDEFAULT_VISIBLE;
1712 }
1713
QuickPrepareEffectRenderNode(RSEffectRenderNode & node)1714 void RSUniRenderVisitor::QuickPrepareEffectRenderNode(RSEffectRenderNode& node)
1715 {
1716 // 0. check current node need to tranverse
1717 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
1718 if (!dirtyManager) {
1719 RS_LOGE("RSUniRenderVisitor::QuickPrepareEffectRenderNode dirtyManager is nullptr");
1720 return;
1721 }
1722 auto dirtyFlag = dirtyFlag_;
1723 auto prevAlpha = curAlpha_;
1724 auto curCornerRadius = curCornerRadius_;
1725 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1726 UpdateRotationStatusForEffectNode(node);
1727 CheckFilterCacheNeedForceClearOrSave(node);
1728 RectI prepareClipRect = prepareClipRect_;
1729 bool hasAccumulatedClip = hasAccumulatedClip_;
1730 dirtyFlag_ =
1731 node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1732 node.UpdateCurCornerRadius(curCornerRadius_);
1733 // 1. Recursively traverse child nodes
1734 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1735 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
1736 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1737 node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1738
1739 PostPrepare(node, !isSubTreeNeedPrepare);
1740 prepareClipRect_ = prepareClipRect;
1741 hasAccumulatedClip_ = hasAccumulatedClip;
1742 dirtyFlag_ = dirtyFlag;
1743 curAlpha_ = prevAlpha;
1744 curCornerRadius_ = curCornerRadius;
1745 node.RenderTraceDebug();
1746 }
1747
QuickPrepareCanvasRenderNode(RSCanvasRenderNode & node)1748 void RSUniRenderVisitor::QuickPrepareCanvasRenderNode(RSCanvasRenderNode& node)
1749 {
1750 // 0. check current node need to traverse
1751 auto dirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
1752 auto dirtyFlag = dirtyFlag_;
1753 auto prevAlpha = curAlpha_;
1754 auto curCornerRadius = curCornerRadius_;
1755 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
1756 CheckFilterCacheNeedForceClearOrSave(node);
1757 if (isDrawingCacheEnabled_) {
1758 node.UpdateDrawingCacheInfoBeforeChildren(isScreenRotationAnimating_);
1759 }
1760 node.OpincQuickMarkStableNode(unchangeMarkInApp_, unchangeMarkEnable_);
1761
1762 RectI prepareClipRect = prepareClipRect_;
1763 bool hasAccumulatedClip = hasAccumulatedClip_;
1764
1765 if (!dirtyManager) {
1766 return;
1767 }
1768 dirtyFlag_ =
1769 node.UpdateDrawRectAndDirtyRegion(*dirtyManager, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
1770 // update prepare clip before children
1771 UpdatePrepareClip(node);
1772 node.UpdateCurCornerRadius(curCornerRadius_);
1773
1774 // 1. Recursively traverse child nodes if above curSurfaceNode and subnode need draw
1775 hasAccumulatedClip_ = node.SetAccumulatedClipFlag(hasAccumulatedClip_);
1776 bool isSubTreeNeedPrepare = !curSurfaceNode_ || node.IsSubTreeNeedPrepare(filterInGlobal_) ||
1777 ForcePrepareSubTree() || node.OpincForcePrepareSubTree();
1778 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
1779 node.SubTreeSkipPrepare(*dirtyManager, curDirty_, dirtyFlag_, prepareClipRect_);
1780
1781 PostPrepare(node, !isSubTreeNeedPrepare);
1782 prepareClipRect_ = prepareClipRect;
1783 hasAccumulatedClip_ = hasAccumulatedClip;
1784 dirtyFlag_ = dirtyFlag;
1785 curAlpha_ = prevAlpha;
1786 curCornerRadius_ = curCornerRadius;
1787 node.OpincUpdateRootFlag(unchangeMarkEnable_);
1788 node.RenderTraceDebug();
1789 }
1790
UpdateRotationStatusForEffectNode(RSEffectRenderNode & node)1791 void RSUniRenderVisitor::UpdateRotationStatusForEffectNode(RSEffectRenderNode& node)
1792 {
1793 // folding/expanding screen force invalidate cache.
1794 node.SetFoldStatusChanged(doAnimate_ &&
1795 curDisplayNode_->GetScreenId() != node.GetCurrentAttachedScreenId());
1796 node.SetCurrentAttachedScreenId(curDisplayNode_->GetScreenId());
1797 node.SetRotationChanged(curDisplayNode_->IsRotationChanged());
1798 }
1799
UpdatePrepareClip(RSRenderNode & node)1800 void RSUniRenderVisitor::UpdatePrepareClip(RSRenderNode& node)
1801 {
1802 const auto& property = node.GetRenderProperties();
1803 auto& geoPtr = property.GetBoundsGeometry();
1804 if (geoPtr == nullptr) {
1805 return;
1806 }
1807 // Dirty Region use abstract coordinate, property of node use relative coordinate
1808 // BoundsRect(if exists) is mapped to absRect_ of RSObjAbsGeometry.
1809 if (property.GetClipToBounds()) {
1810 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->GetAbsRect());
1811 }
1812 // FrameRect(if exists) is mapped to rect using abstract coordinate explicitly by calling MapAbsRect.
1813 if (property.GetClipToFrame()) {
1814 // MapAbsRect do not handle the translation of OffsetX and OffsetY
1815 RectF frameRect{
1816 property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_X),
1817 property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_Y),
1818 property.GetFrameWidth(), property.GetFrameHeight()};
1819 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(frameRect));
1820 }
1821 if (property.GetClipToRRect()) {
1822 RectF rect = property.GetClipRRect().rect_;
1823 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(rect));
1824 }
1825 }
1826
IsLeashAndHasMainSubNode(RSRenderNode & node) const1827 bool RSUniRenderVisitor::IsLeashAndHasMainSubNode(RSRenderNode& node) const
1828 {
1829 if (node.GetType() != RSRenderNodeType::SURFACE_NODE) {
1830 return false;
1831 }
1832 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(node);
1833 if (!surfaceNode.IsLeashWindow()) {
1834 return false;
1835 }
1836 // check leashWindow surface has first level mainwindow node
1837 auto children = node.GetSortedChildren();
1838 auto iter = std::find_if((*children).begin(), (*children).end(),
1839 [](const std::shared_ptr<RSRenderNode>& node) {
1840 if (node && node->GetType() == RSRenderNodeType::SURFACE_NODE) {
1841 const auto& surfaceNode = static_cast<RSSurfaceRenderNode&>(*node);
1842 return surfaceNode.IsMainWindowType();
1843 }
1844 return false;
1845 });
1846 return iter != (*children).end();
1847 }
1848
NeedPrepareChindrenInReverseOrder(RSRenderNode & node) const1849 bool RSUniRenderVisitor::NeedPrepareChindrenInReverseOrder(RSRenderNode& node) const
1850 {
1851 if (!curSurfaceNode_ && node.GetType() != RSRenderNodeType::RS_NODE) {
1852 return true;
1853 }
1854 return IsLeashAndHasMainSubNode(node);
1855 }
1856
QuickPrepareChildren(RSRenderNode & node)1857 void RSUniRenderVisitor::QuickPrepareChildren(RSRenderNode& node)
1858 {
1859 MergeRemovedChildDirtyRegion(node, true);
1860 if (node.LastFrameSubTreeSkipped() && curSurfaceDirtyManager_) {
1861 node.ForceMergeSubTreeDirtyRegion(*curSurfaceDirtyManager_, prepareClipRect_);
1862 }
1863 bool animationBackup = ancestorNodeHasAnimation_;
1864 ancestorNodeHasAnimation_ = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
1865 node.ResetChildRelevantFlags();
1866 node.ResetChildUifirstSupportFlag();
1867 auto children = node.GetSortedChildren();
1868 if (NeedPrepareChindrenInReverseOrder(node)) {
1869 std::for_each((*children).rbegin(), (*children).rend(), [this](const std::shared_ptr<RSRenderNode>& node) {
1870 if (!node) {
1871 return;
1872 }
1873 auto containerDirty = curContainerDirty_;
1874 curDirty_ = node->IsDirty();
1875 curContainerDirty_ = curContainerDirty_ || node->IsDirty();
1876 node->QuickPrepare(shared_from_this());
1877 curContainerDirty_ = containerDirty;
1878 });
1879 } else {
1880 std::for_each((*children).begin(), (*children).end(), [this](const std::shared_ptr<RSRenderNode>& node) {
1881 if (!node) {
1882 return;
1883 }
1884 curDirty_ = node->IsDirty();
1885 node->QuickPrepare(shared_from_this());
1886 });
1887 }
1888 ancestorNodeHasAnimation_ = animationBackup;
1889 node.ResetGeoUpdateDelay();
1890 }
1891
InitDisplayInfo(RSDisplayRenderNode & node)1892 bool RSUniRenderVisitor::InitDisplayInfo(RSDisplayRenderNode& node)
1893 {
1894 // 1 init curDisplay and curDisplayDirtyManager
1895 currentVisitDisplay_ = node.GetScreenId();
1896 displayHasSecSurface_.emplace(currentVisitDisplay_, false);
1897 displayHasSkipSurface_.emplace(currentVisitDisplay_, false);
1898 displayHasProtectedSurface_.emplace(currentVisitDisplay_, false);
1899 displaySpecailSurfaceChanged_.emplace(currentVisitDisplay_, false);
1900 hasCaptureWindow_.emplace(currentVisitDisplay_, false);
1901 curDisplayDirtyManager_ = node.GetDirtyManager();
1902 curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
1903 if (!curDisplayDirtyManager_ || !curDisplayNode_) {
1904 RS_LOGE("RSUniRenderVisitor::InitDisplayInfo dirtyMgr or node ptr is nullptr");
1905 return false;
1906 }
1907 curDisplayDirtyManager_->Clear();
1908 transparentCleanFilter_.clear();
1909 transparentDirtyFilter_.clear();
1910
1911 // 2 init screenManager info
1912 screenManager_ = CreateOrGetScreenManager();
1913 if (!screenManager_) {
1914 RS_LOGE("RSUniRenderVisitor::InitDisplayInfo screenManager_ is nullptr");
1915 return false;
1916 }
1917 screenInfo_ = screenManager_->QueryScreenInfo(node.GetScreenId());
1918 curDisplayDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1919 screenRect_ = RectI{0, 0, screenInfo_.width, screenInfo_.height};
1920
1921 // 3 init Occlusion info
1922 needRecalculateOcclusion_ = false;
1923 accumulatedOcclusionRegion_.Reset();
1924 occlusionRegionWithoutSkipLayer_.Reset();
1925 if (!curMainAndLeashWindowNodesIds_.empty()) {
1926 std::queue<NodeId>().swap(curMainAndLeashWindowNodesIds_);
1927 }
1928
1929 // 4. check isHardwareForcedDisabled
1930 auto& geoPtr = (node.GetRenderProperties().GetBoundsGeometry());
1931 if (geoPtr == nullptr) {
1932 RS_LOGE("RSUniRenderVisitor::InitDisplayInfo geoPtr is nullptr");
1933 return false;
1934 }
1935 if (geoPtr->IsNeedClientCompose()) {
1936 isHardwareForcedDisabled_ = true;
1937 }
1938
1939 // 5. check compositeType
1940 auto mirrorNode = node.GetMirrorSource().lock();
1941 switch (screenInfo_.state) {
1942 case ScreenState::SOFTWARE_OUTPUT_ENABLE:
1943 node.SetCompositeType(mirrorNode ?
1944 RSDisplayRenderNode::CompositeType::UNI_RENDER_MIRROR_COMPOSITE :
1945 RSDisplayRenderNode::CompositeType::UNI_RENDER_EXPAND_COMPOSITE);
1946 break;
1947 case ScreenState::HDI_OUTPUT_ENABLE:
1948 node.SetCompositeType(node.IsForceSoftComposite() ?
1949 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE :
1950 RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE);
1951 break;
1952 default:
1953 return false;
1954 }
1955
1956 return true;
1957 }
1958
BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)1959 bool RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
1960 {
1961 // 1. init and record surface info
1962 if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
1963 hasCaptureWindow_[currentVisitDisplay_] = true;
1964 }
1965 UpdateSecuritySkipAndProtectedLayersRecord(node);
1966 node.UpdateUIFirstFrameGravity();
1967 if (node.IsMainWindowType() || node.IsLeashWindow()) {
1968 // UpdateCurCornerRadius must process before curSurfaceNode_ update
1969 node.UpdateCurCornerRadius(curCornerRadius_);
1970 curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
1971 curSurfaceDirtyManager_ = node.GetDirtyManager();
1972 if (!curSurfaceDirtyManager_ || !curSurfaceNode_) {
1973 RS_LOGE("RSUniRenderVisitor::BeforeUpdateSurfaceDirtyCalc %{public}s has invalid"
1974 " SurfaceDirtyManager or node ptr", node.GetName().c_str());
1975 return false;
1976 }
1977 curSurfaceDirtyManager_->Clear();
1978 curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
1979 filterInGlobal_ = curSurfaceNode_->IsTransparent();
1980 // update surfaceNode contentDirty and subTreeDirty flag for UIFirst purging policy
1981 RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(curSurfaceNode_);
1982 curSurfaceNode_->UpdateSurfaceCacheContentStaticFlag();
1983 curSurfaceNode_->UpdateSurfaceSubTreeDirtyFlag();
1984 curSurfaceNode_->SetLeashWindowVisibleRegionEmpty(false);
1985 } else if (node.IsAbilityComponent()) {
1986 if (auto nodePtr = node.ReinterpretCastTo<RSSurfaceRenderNode>()) {
1987 RSMainThread::Instance()->CheckAndUpdateInstanceContentStaticStatus(nodePtr);
1988 nodePtr->UpdateSurfaceCacheContentStaticFlag();
1989 }
1990 }
1991 // 2. update surface info and CheckIfOcclusionReusable
1992 node.SetAncestorDisplayNode(curDisplayNode_); // set for boot animation
1993 node.UpdateAncestorDisplayNodeInRenderParams();
1994 node.CleanDstRectChanged();
1995 // [planning] check node isDirty can be optimized.
1996 needRecalculateOcclusion_ = needRecalculateOcclusion_ || node.IsDirty() ||
1997 node.CheckIfOcclusionReusable(preMainAndLeashWindowNodesIds_);
1998 if (autoCacheEnable_ && node.IsAppWindow()) {
1999 node.OpincSetInAppStateStart(unchangeMarkInApp_);
2000 }
2001 // 3. check color space pixelFormat and update RelMatrix
2002 CheckColorSpace(node);
2003 CheckPixelFormat(node);
2004 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
2005 node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
2006 }
2007 return true;
2008 }
2009
AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode & node)2010 bool RSUniRenderVisitor::AfterUpdateSurfaceDirtyCalc(RSSurfaceRenderNode& node)
2011 {
2012 // 1. Update surfaceNode info and AppWindow gravity
2013 const auto& property = node.GetRenderProperties();
2014 if (node.IsAppWindow()) {
2015 boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
2016 frameGravity_ = property.GetFrameGravity();
2017 }
2018 auto& geoPtr = property.GetBoundsGeometry();
2019 if (geoPtr == nullptr) {
2020 return false;
2021 }
2022 UpdateDstRect(node, geoPtr->GetAbsRect(), prepareClipRect_);
2023 node.UpdatePositionZ();
2024 if (node.IsHardwareEnabledType() && node.GetZorderChanged() && curSurfaceNode_) {
2025 curSurfaceNode_->SetNeedCollectHwcNode(true);
2026 }
2027 UpdateSurfaceRenderNodeScale(node);
2028 UpdateSurfaceRenderNodeRotate(node);
2029 if (node.IsMainWindowType() || node.IsLeashWindow()) {
2030 curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirtyInSurface());
2031 curDisplayNode_->AddSurfaceNodePosByDescZOrder(node.GetId(), node.GetOldDirtyInSurface());
2032 }
2033 // 2. Update Occlusion info before children preparation
2034 if (node.IsMainWindowType()) {
2035 CalculateOcclusion(node);
2036 if (node.GetFirstLevelNodeId() == node.GetId()) {
2037 globalSurfaceBounds_.emplace_back(node.GetAbsDrawRect());
2038 }
2039 }
2040 // 3. Update HwcNode Info for appNode
2041 UpdateHwcNodeInfoForAppNode(node);
2042 return true;
2043 }
2044
UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode & node)2045 void RSUniRenderVisitor::UpdateLeashWindowVisibleRegionEmpty(RSSurfaceRenderNode& node)
2046 {
2047 if (!node.IsLeashWindow()) {
2048 return;
2049 }
2050 bool isVisibleRegionEmpty = true;
2051 for (const auto& child : *node.GetSortedChildren()) {
2052 const auto childSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child);
2053 if (childSurfaceNode && childSurfaceNode->IsAppWindow()) {
2054 // leash window is visible when child app has visible region
2055 if (!childSurfaceNode->GetVisibleRegion().IsEmpty()) {
2056 isVisibleRegionEmpty = false;
2057 } else {
2058 RS_OPTIONAL_TRACE_NAME_FMT("%s's visible region is empty", childSurfaceNode->GetName().c_str());
2059 }
2060 } else {
2061 // leash window is visible when child is not app window node
2062 isVisibleRegionEmpty = false;
2063 }
2064 if (!isVisibleRegionEmpty) {
2065 break;
2066 }
2067 }
2068 node.SetLeashWindowVisibleRegionEmpty(isVisibleRegionEmpty);
2069 }
2070
UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode & node)2071 void RSUniRenderVisitor::UpdateHwcNodeInfoForAppNode(RSSurfaceRenderNode& node)
2072 {
2073 // app node
2074 if (node.GetNeedCollectHwcNode()) {
2075 node.ResetChildHardwareEnabledNodes();
2076 }
2077 // hwc node
2078 if (node.IsHardwareEnabledType() && curSurfaceNode_) {
2079 if (curSurfaceNode_->GetNeedCollectHwcNode()) {
2080 curSurfaceNode_->AddChildHardwareEnabledNode(node.ReinterpretCastTo<RSSurfaceRenderNode>());
2081 }
2082 if (!node.GetHardWareDisabledByReverse()) {
2083 node.SetHardwareForcedDisabledState(false);
2084 }
2085 node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
2086 if (!IsHardwareComposerEnabled() || !node.IsDynamicHardwareEnable() ||
2087 curSurfaceNode_->GetVisibleRegion().IsEmpty() ||
2088 !node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
2089 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by param/invisible/no buffer",
2090 node.GetName().c_str(), node.GetId());
2091 node.SetHardwareForcedDisabledState(true);
2092 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2093 HwcDisabledReasons::DISABLED_BY_INVALID_PARAM, node.GetName());
2094 if (!node.GetFixRotationByUser()) {
2095 return;
2096 }
2097 }
2098 auto& geo = node.GetRenderProperties().GetBoundsGeometry();
2099 if (geo == nullptr) {
2100 return;
2101 }
2102 UpdateSrcRect(node, geo->GetAbsMatrix(), geo->GetAbsRect());
2103 UpdateHwcNodeByTransform(node);
2104 UpdateHwcNodeEnableByBackgroundAlpha(node);
2105 UpdateHwcNodeEnableByBufferSize(node);
2106 UpdateHwcNodeEnableBySrcRect(node);
2107 }
2108 }
2109
UpdateSrcRect(RSSurfaceRenderNode & node,const Drawing::Matrix & absMatrix,const RectI & absRect)2110 void RSUniRenderVisitor::UpdateSrcRect(RSSurfaceRenderNode& node,
2111 const Drawing::Matrix& absMatrix, const RectI& absRect)
2112 {
2113 auto canvas = std::make_unique<Rosen::Drawing::Canvas>(screenInfo_.phyWidth, screenInfo_.phyHeight);
2114 canvas->ConcatMatrix(absMatrix);
2115
2116 const auto& dstRect = node.GetDstRect();
2117 Drawing::RectI dst = { std::round(dstRect.GetLeft()), std::round(dstRect.GetTop()), std::round(dstRect.GetRight()),
2118 std::round(dstRect.GetBottom()) };
2119 node.UpdateSrcRect(*canvas.get(), dst);
2120 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetBuffer()) {
2121 RSUniRenderUtil::UpdateRealSrcRect(node, absRect);
2122 }
2123 }
2124
UpdateDstRect(RSSurfaceRenderNode & node,const RectI & absRect,const RectI & clipRect)2125 void RSUniRenderVisitor::UpdateDstRect(RSSurfaceRenderNode& node, const RectI& absRect, const RectI& clipRect)
2126 {
2127 auto dstRect = absRect;
2128 // If the screen is expanded, intersect the destination rectangle with the screen rectangle
2129 dstRect = dstRect.IntersectRect(RectI(curDisplayNode_->GetDisplayOffsetX(), curDisplayNode_->GetDisplayOffsetY(),
2130 screenInfo_.width, screenInfo_.height));
2131 // Remove the offset of the screen
2132 dstRect.left_ = dstRect.left_ - curDisplayNode_->GetDisplayOffsetX();
2133 dstRect.top_ = dstRect.top_ - curDisplayNode_->GetDisplayOffsetY();
2134 // If the node is a hardware-enabled type, intersect its destination rectangle with the prepare clip rectangle
2135 if (node.IsHardwareEnabledType()) {
2136 dstRect = dstRect.IntersectRect(clipRect);
2137 if (curSurfaceNode_ && (node.GetId() != curSurfaceNode_->GetId())) {
2138 dstRect = dstRect.IntersectRect(curSurfaceNode_->GetDstRect());
2139 }
2140 }
2141 dstRect.left_ = static_cast<int>(std::round(dstRect.left_ * screenInfo_.GetRogWidthRatio()));
2142 dstRect.top_ = static_cast<int>(std::round(dstRect.top_ * screenInfo_.GetRogHeightRatio()));
2143 dstRect.width_ = static_cast<int>(std::round(dstRect.width_ * screenInfo_.GetRogWidthRatio()));
2144 dstRect.height_ = static_cast<int>(std::round(dstRect.height_ * screenInfo_.GetRogHeightRatio()));
2145 // Set the destination rectangle of the node
2146 node.SetDstRect(dstRect);
2147 }
2148
UpdateHwcNodeByTransform(RSSurfaceRenderNode & node)2149 void RSUniRenderVisitor::UpdateHwcNodeByTransform(RSSurfaceRenderNode& node)
2150 {
2151 if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
2152 return;
2153 }
2154 node.SetInFixedRotation(displayNodeRotationChanged_ || isScreenRotationAnimating_);
2155 RSUniRenderUtil::DealWithNodeGravity(node, screenInfo_);
2156 RSUniRenderUtil::LayerRotate(node, screenInfo_);
2157 RSUniRenderUtil::LayerCrop(node, screenInfo_);
2158 RSUniRenderUtil::DealWithScalingMode(node);
2159 node.SetCalcRectInPrepare(true);
2160 }
2161
UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode & node)2162 void RSUniRenderVisitor::UpdateHwcNodeEnableByBackgroundAlpha(RSSurfaceRenderNode& node)
2163 {
2164 bool bgTransport = !node.GetAncoForceDoDirect() &&
2165 (static_cast<uint8_t>(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX);
2166 if (bgTransport) {
2167 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by background color alpha < 1",
2168 node.GetName().c_str(), node.GetId());
2169 // use in skip updating hardware state for hwcnode with background alpha in specific situation
2170 if (!RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag()) {
2171 node.SetHardwareForcedDisabledState(true);
2172 }
2173 node.SetNodeHasBackgroundColorAlpha(true);
2174 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2175 HwcDisabledReasons::DISABLED_BY_BACKGROUND_ALPHA, node.GetName());
2176 }
2177 }
2178
UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode & node)2179 void RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize(RSSurfaceRenderNode& node)
2180 {
2181 if (!node.IsRosenWeb() || node.IsHardwareForcedDisabled()) {
2182 return;
2183 }
2184 if (!node.GetRSSurfaceHandler() || !node.GetRSSurfaceHandler()->GetBuffer()) {
2185 return;
2186 }
2187 const auto& property = node.GetRenderProperties();
2188 auto gravity = property.GetFrameGravity();
2189 if (gravity != Gravity::TOP_LEFT) {
2190 return;
2191 }
2192 auto surfaceHandler = node.GetRSSurfaceHandler();
2193 auto consumer = surfaceHandler->GetConsumer();
2194 if (consumer == nullptr) {
2195 return;
2196 }
2197
2198 auto buffer = surfaceHandler->GetBuffer();
2199 const auto bufferWidth = buffer->GetSurfaceBufferWidth();
2200 const auto bufferHeight = buffer->GetSurfaceBufferHeight();
2201 auto boundsWidth = property.GetBoundsWidth();
2202 auto boundsHeight = property.GetBoundsHeight();
2203
2204 auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
2205 if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
2206 RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByBufferSize GetSurfaceBufferTransformType failed");
2207 }
2208 if (transformType == GraphicTransformType::GRAPHIC_ROTATE_270 ||
2209 transformType == GraphicTransformType::GRAPHIC_ROTATE_90) {
2210 std::swap(boundsWidth, boundsHeight);
2211 }
2212 if ((bufferWidth < boundsWidth) || (bufferHeight < boundsHeight)) {
2213 RS_OPTIONAL_TRACE_NAME_FMT(
2214 "hwc debug: name:%s id:%" PRIu64 " buffer:[%d, %d] bounds:[%f, %f] disabled by buffer nonmatching",
2215 node.GetName().c_str(), node.GetId(), bufferWidth, bufferHeight, boundsWidth, boundsHeight);
2216 node.SetHardwareForcedDisabledState(true);
2217 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(
2218 node.GetId(), HwcDisabledReasons::DISABLED_BY_BUFFER_NONMATCH, node.GetName());
2219 }
2220 }
2221
UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode & node)2222 void RSUniRenderVisitor::UpdateHwcNodeEnableBySrcRect(RSSurfaceRenderNode& node)
2223 {
2224 if (node.IsHardwareForcedDisabled()) {
2225 return;
2226 }
2227 bool hasRotation = false;
2228 if (node.GetRSSurfaceHandler() && node.GetRSSurfaceHandler()->GetConsumer()) {
2229 const auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
2230 auto rotation = RSBaseRenderUtil::GetRotateTransform(
2231 RSBaseRenderUtil::GetSurfaceBufferTransformType(consumer, node.GetRSSurfaceHandler()->GetBuffer()));
2232 hasRotation = rotation == GRAPHIC_ROTATE_90 || rotation == GRAPHIC_ROTATE_270;
2233 }
2234 node.UpdateHwcDisabledBySrcRect(hasRotation);
2235 if (node.IsHardwareDisabledBySrcRect()) {
2236 node.SetHardwareForcedDisabledState(true);
2237 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node.GetId(),
2238 HwcDisabledReasons::DISABLED_BY_SRC_PIXEL, node.GetName());
2239 }
2240 }
2241
UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2242 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(std::vector<RectI>& hwcRects,
2243 std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2244 {
2245 if (hwcNode->IsHardwareForcedDisabled()) {
2246 return;
2247 }
2248 auto dst = hwcNode->GetDstRect();
2249 if (hwcNode->GetAncoForceDoDirect()) {
2250 hwcRects.emplace_back(dst);
2251 return;
2252 }
2253 for (auto rect : hwcRects) {
2254 if (dst.Intersect(rect) && !RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
2255 if (RsCommonHook::Instance().GetVideoSurfaceFlag() &&
2256 ((dst.GetBottom() - rect.GetTop() <= MIN_OVERLAP && dst.GetBottom() - rect.GetTop() >= 0) ||
2257 (rect.GetBottom() - dst.GetTop() <= MIN_OVERLAP && rect.GetBottom() - dst.GetTop() >= 0))) {
2258 return;
2259 }
2260 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by hwc node above",
2261 hwcNode->GetName().c_str(), hwcNode->GetId());
2262 hwcNode->SetHardwareForcedDisabledState(true);
2263 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2264 HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
2265 return;
2266 }
2267 }
2268 hwcRects.emplace_back(dst);
2269 }
2270
UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)2271 void RSUniRenderVisitor::UpdateHwcNodeProperty(std::shared_ptr<RSSurfaceRenderNode> hwcNode)
2272 {
2273 auto hwcNodeGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2274 if (!hwcNodeGeo) {
2275 RS_LOGE("hwcNode Geometry is not prepared.");
2276 return;
2277 }
2278 bool hasCornerRadius = !hwcNode->GetRenderProperties().GetCornerRadius().IsZero();
2279 std::vector<RectI> currIntersectedRoundCornerAABBs = {};
2280 float alpha = hwcNode->GetRenderProperties().GetAlpha();
2281 Drawing::Matrix totalMatrix = hwcNodeGeo->GetMatrix();
2282 auto hwcNodeRect = hwcNodeGeo->GetAbsRect();
2283 bool isNodeRenderByDrawingCache = false;
2284 RSUniRenderUtil::TraverseParentNodeAndReduce(hwcNode,
2285 [&isNodeRenderByDrawingCache](std::shared_ptr<RSRenderNode> parent) {
2286 if (isNodeRenderByDrawingCache) {
2287 return;
2288 }
2289 // if the parent node of hwcNode is marked freeze or nodegroup, RS closes hardware composer of hwcNode.
2290 isNodeRenderByDrawingCache = isNodeRenderByDrawingCache || parent->IsStaticCached() ||
2291 (parent->GetNodeGroupType() != RSRenderNode::NodeGroupType::NONE);
2292 },
2293 [&alpha](std::shared_ptr<RSRenderNode> parent) {
2294 auto& parentProperty = parent->GetRenderProperties();
2295 alpha *= parentProperty.GetAlpha();
2296 },
2297 [&totalMatrix](std::shared_ptr<RSRenderNode> parent) {
2298 if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
2299 totalMatrix.PostConcat(opt.value());
2300 } else {
2301 return;
2302 }
2303 },
2304 [&currIntersectedRoundCornerAABBs, hwcNodeRect](std::shared_ptr<RSRenderNode> parent) {
2305 auto& parentProperty = parent->GetRenderProperties();
2306 auto cornerRadius = parentProperty.GetCornerRadius();
2307 auto maxCornerRadius = *std::max_element(std::begin(cornerRadius.data_), std::end(cornerRadius.data_));
2308 auto parentGeo = parentProperty.GetBoundsGeometry();
2309 static const std::array offsetVecs {
2310 UIPoint { 0, 0 },
2311 UIPoint { 1, 0 },
2312 UIPoint { 0, 1 },
2313 UIPoint { 1, 1 }
2314 };
2315
2316 // The logic here is to calculate whether the HWC Node affects
2317 // the round corner property of the parent node.
2318 // The method is calculating the rounded AABB of each HWC node
2319 // with respect to all parent nodes above it and storing the results.
2320 // When a HWC node is found below, the AABBs and the HWC node
2321 // are checked for intersection. If there is an intersection,
2322 // the node above it is disabled from taking the HWC pipeline.
2323 auto checkIntersectWithRoundCorner = [&currIntersectedRoundCornerAABBs, hwcNodeRect](
2324 const RectI& rect, float radiusX, float radiusY) {
2325 if (radiusX <= 0 || radiusY <= 0) {
2326 return;
2327 }
2328 UIPoint offset { rect.GetWidth() - radiusX, rect.GetHeight() - radiusY };
2329 UIPoint anchorPoint { rect.GetLeft(), rect.GetTop() };
2330 std::for_each(std::begin(offsetVecs), std::end(offsetVecs),
2331 [&currIntersectedRoundCornerAABBs, hwcNodeRect, offset,
2332 radiusX, radiusY, anchorPoint](auto offsetVec) {
2333 auto res = anchorPoint + offset * offsetVec;
2334 auto roundCornerAABB = RectI(res.x_, res.y_, radiusX, radiusY);
2335 if (!roundCornerAABB.IntersectRect(hwcNodeRect).IsEmpty()) {
2336 currIntersectedRoundCornerAABBs.push_back(roundCornerAABB);
2337 }
2338 }
2339 );
2340 };
2341 if (parentGeo) {
2342 auto parentRect = parentGeo->GetAbsRect();
2343 checkIntersectWithRoundCorner(parentRect, maxCornerRadius, maxCornerRadius);
2344
2345 if (parentProperty.GetClipToRRect()) {
2346 RRect parentClipRRect = parentProperty.GetClipRRect();
2347 RectI parentClipRect = parentGeo->MapAbsRect(parentClipRRect.rect_);
2348 float maxClipRRectCornerRadiusX = 0, maxClipRRectCornerRadiusY = 0;
2349 constexpr size_t radiusVecSize = 4;
2350 for (size_t i = 0; i < radiusVecSize; ++i) {
2351 maxClipRRectCornerRadiusX = std::max(maxClipRRectCornerRadiusX, parentClipRRect.radius_[i].x_);
2352 maxClipRRectCornerRadiusY = std::max(maxClipRRectCornerRadiusY, parentClipRRect.radius_[i].y_);
2353 }
2354 checkIntersectWithRoundCorner(parentClipRect, maxClipRRectCornerRadiusX, maxClipRRectCornerRadiusY);
2355 }
2356 }
2357 }
2358 );
2359 if (isNodeRenderByDrawingCache) {
2360 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by drawing cache",
2361 hwcNode->GetName().c_str(), hwcNode->GetId());
2362 hwcNode->SetHardwareForcedDisabledState(isNodeRenderByDrawingCache);
2363 }
2364 hwcNode->SetTotalMatrix(totalMatrix);
2365 hwcNode->SetGlobalAlpha(alpha);
2366 hwcNode->SetIntersectedRoundCornerAABBs(std::move(currIntersectedRoundCornerAABBs));
2367 }
2368
UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2369 void RSUniRenderVisitor::UpdateHwcNodeEnableByRotateAndAlpha(std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2370 {
2371 auto alpha = hwcNode->GetGlobalAlpha();
2372 auto totalMatrix = hwcNode->GetTotalMatrix();
2373 if (alpha < 1.0f) {
2374 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by accumulated alpha:%.2f",
2375 hwcNode->GetName().c_str(), hwcNode->GetId(), alpha);
2376 hwcNode->SetHardwareForcedDisabledState(true);
2377 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2378 HwcDisabledReasons::DISABLED_BY_ACCUMULATED_ALPHA, hwcNode->GetName());
2379 return;
2380 }
2381 // [planning] degree only multiples of 90 now
2382 int degree = RSUniRenderUtil::GetRotationDegreeFromMatrix(totalMatrix);
2383 bool hasRotate = degree % RS_ROTATION_90 != 0 || RSUniRenderUtil::Is3DRotation(totalMatrix);
2384 if (hasRotate) {
2385 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by rotation:%d",
2386 hwcNode->GetName().c_str(), hwcNode->GetId(), degree);
2387 hwcNode->SetHardwareForcedDisabledState(true);
2388 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2389 HwcDisabledReasons::DISABLED_BY_ROTATION, hwcNode->GetName());
2390 return;
2391 }
2392 }
2393
ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode> & hwcNodePtr)2394 void RSUniRenderVisitor::ProcessAncoNode(std::shared_ptr<RSSurfaceRenderNode>& hwcNodePtr)
2395 {
2396 if ((hwcNodePtr->GetAncoFlags() & static_cast<uint32_t>(AncoFlags::IS_ANCO_NODE)) == 0) {
2397 return;
2398 }
2399 ancoNodes_.insert(hwcNodePtr);
2400 auto alpha = hwcNodePtr->GetGlobalAlpha();
2401 RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 "src %{public}s dst %{public}s "
2402 "alpha:%{public}.2f", hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId(),
2403 hwcNodePtr->GetSrcRect().ToString().c_str(), hwcNodePtr->GetDstRect().ToString().c_str(), alpha);
2404 if (ROSEN_EQ(alpha, 0.0f)) {
2405 return;
2406 }
2407
2408 if (!hwcNodePtr->GetRSSurfaceHandler() || !hwcNodePtr->GetRSSurfaceHandler()->GetBuffer()) {
2409 RS_LOGD("rs debug: name:%{public}s id:%{public}" PRIu64 " handler or buffer is null, skip",
2410 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
2411 return;
2412 }
2413
2414 ancoHasGpu_ = (ancoHasGpu_ || hwcNodePtr->IsHardwareForcedDisabled());
2415 }
2416
InitAncoStatus()2417 void RSUniRenderVisitor::InitAncoStatus()
2418 {
2419 ancoHasGpu_ = false;
2420 ancoNodes_.clear();
2421 }
2422
UpdateHwcNodeEnable()2423 void RSUniRenderVisitor::UpdateHwcNodeEnable()
2424 {
2425 InitAncoStatus();
2426
2427 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2428 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2429 [this](RSBaseRenderNode::SharedPtr& nodePtr) {
2430 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2431 if (!surfaceNode) {
2432 return;
2433 }
2434 UpdateHwcNodeEnableByGlobalFilter(surfaceNode);
2435 surfaceNode->ResetNeedCollectHwcNode();
2436 const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2437 if (hwcNodes.empty()) {
2438 return;
2439 }
2440 std::vector<RectI> hwcRects;
2441 for (const auto& hwcNode : hwcNodes) {
2442 auto hwcNodePtr = hwcNode.lock();
2443 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2444 continue;
2445 }
2446 if (hwcNodePtr->GetProtectedLayer()) {
2447 drmNodes_.emplace_back(hwcNode);
2448 }
2449 UpdateHwcNodeProperty(hwcNodePtr);
2450 UpdateHwcNodeEnableByRotateAndAlpha(hwcNodePtr);
2451 UpdateHwcNodeEnableByHwcNodeBelowSelfInApp(hwcRects, hwcNodePtr);
2452
2453 ProcessAncoNode(hwcNodePtr);
2454 }
2455 });
2456 UpdateAncoNodeHWCDisabledState();
2457 PrevalidateHwcNode();
2458 UpdateHwcNodeEnableByNodeBelow();
2459 }
2460
UpdateAncoNodeHWCDisabledState()2461 void RSUniRenderVisitor::UpdateAncoNodeHWCDisabledState()
2462 {
2463 if (ancoHasGpu_) {
2464 for (const auto& hwcNodePtr : ancoNodes_) {
2465 hwcNodePtr->SetHardwareForcedDisabledState(true);
2466 }
2467 }
2468
2469 InitAncoStatus();
2470 }
2471
PrevalidateHwcNode()2472 void RSUniRenderVisitor::PrevalidateHwcNode()
2473 {
2474 if (!isPrevalidateHwcNodeEnable_) {
2475 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate close");
2476 return;
2477 }
2478 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2479 std::vector<RequestLayerInfo> prevalidLayers;
2480 uint32_t curFps = OHOS::Rosen::HgmCore::Instance().GetScreenCurrentRefreshRate(curDisplayNode_->GetScreenId());
2481 uint32_t zOrder = static_cast<uint32_t>(globalZOrder_);
2482 // add surfaceNode layer
2483 RSUniHwcPrevalidateUtil::GetInstance().CollectSurfaceNodeLayerInfo(
2484 prevalidLayers, curMainAndLeashSurfaces, curFps, zOrder, screenInfo_);
2485 std::vector<RequestLayerInfo> uiFirstLayers;
2486 // collect uifirst layer
2487 // zOrder + 1.f is displayNode, UIFirst layer must be above displayNode(zorder + 2.f)
2488 RSUniHwcPrevalidateUtil::GetInstance().CollectUIFirstLayerInfo(
2489 uiFirstLayers, curFps, static_cast<float>(zOrder) + 2.f, screenInfo_);
2490 RS_TRACE_NAME_FMT("PrevalidateHwcNode hwcLayer: %u, uifirstLayer: %u", prevalidLayers.size(), uiFirstLayers.size());
2491 if (prevalidLayers.size() == 0 && uiFirstLayers.size() == 0) {
2492 RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode no hardware layer");
2493 return;
2494 }
2495 // add display layer
2496 RequestLayerInfo displayLayer;
2497 if (RSUniHwcPrevalidateUtil::GetInstance().CreateDisplayNodeLayerInfo(
2498 zOrder++, curDisplayNode_, screenInfo_, curFps, displayLayer)) {
2499 prevalidLayers.emplace_back(displayLayer);
2500 }
2501 // add uiFirst layer
2502 prevalidLayers.insert(prevalidLayers.end(), uiFirstLayers.begin(), uiFirstLayers.end());
2503 // add rcd layer
2504 RequestLayerInfo rcdLayer;
2505 if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(
2506 RSRcdRenderManager::GetInstance().GetBackgroundSurfaceNode(), screenInfo_, curFps, rcdLayer)) {
2507 prevalidLayers.emplace_back(rcdLayer);
2508 }
2509 if (RSUniHwcPrevalidateUtil::GetInstance().CreateRCDLayerInfo(
2510 RSRcdRenderManager::GetInstance().GetContentSurfaceNode(), screenInfo_, curFps, rcdLayer)) {
2511 prevalidLayers.emplace_back(rcdLayer);
2512 }
2513 std::map<uint64_t, RequestCompositionType> strategy;
2514 if (!RSUniHwcPrevalidateUtil::GetInstance().PreValidate(screenInfo_.id, prevalidLayers, strategy)) {
2515 RS_LOGI_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode prevalidate failed");
2516 return;
2517 }
2518 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
2519 for (auto it : strategy) {
2520 RS_LOGD_IF(DEBUG_PREVALIDATE, "RSUniRenderVisitor::PrevalidateHwcNode id: %{public}" PRIu64 ","
2521 " result: %{public}d", it.first, it.second);
2522 if (it.second == RequestCompositionType::DEVICE) {
2523 continue;
2524 }
2525 auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(it.first);
2526 if (node == nullptr) {
2527 continue;
2528 }
2529 if (it.second == RequestCompositionType::DEVICE_VSCF) {
2530 node->SetArsrTag(false);
2531 continue;
2532 }
2533 if (node->IsInFixedRotation() || node->GetProtectedLayer()) {
2534 continue;
2535 }
2536 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by prevalidate",
2537 node->GetName().c_str(), node->GetId());
2538 node->SetHardwareForcedDisabledState(true);
2539 if (node->GetRSSurfaceHandler()) {
2540 node->GetRSSurfaceHandler()->SetGlobalZOrder(-1.f);
2541 }
2542 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
2543 HwcDisabledReasons::DISABLED_BY_PREVALIDATE, node->GetName());
2544 }
2545 }
2546
UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode> & node)2547 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionAndCreateLayer(std::shared_ptr<RSSurfaceRenderNode>& node)
2548 {
2549 const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
2550 if (hwcNodes.empty()) {
2551 return;
2552 }
2553 std::shared_ptr<RSSurfaceRenderNode> pointWindow;
2554 std::vector<std::shared_ptr<RSSurfaceRenderNode>> topLayers;
2555 for (auto hwcNode : hwcNodes) {
2556 auto hwcNodePtr = hwcNode.lock();
2557 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2558 continue;
2559 }
2560 auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
2561 if (hwcNodePtr->IsLayerTop()) {
2562 topLayers.emplace_back(hwcNodePtr);
2563 continue;
2564 }
2565 if (node->IsHardwareEnabledTopSurface()) {
2566 pointWindow = hwcNodePtr;
2567 continue;
2568 }
2569 if (hasUniRenderHdrSurface_) {
2570 hwcNodePtr->SetHardwareForcedDisabledState(true);
2571 }
2572 UpdateHwcNodeDirtyRegionForApp(node, hwcNodePtr);
2573 hwcNodePtr->SetCalcRectInPrepare(false);
2574 hwcNodePtr->SetHardWareDisabledByReverse(false);
2575 surfaceHandler->SetGlobalZOrder(hwcNodePtr->IsHardwareForcedDisabled() && !hwcNodePtr->GetProtectedLayer()
2576 ? -1.f : globalZOrder_++);
2577 auto transform = RSUniRenderUtil::GetLayerTransform(*hwcNodePtr, screenInfo_);
2578 hwcNodePtr->UpdateHwcNodeLayerInfo(transform);
2579 }
2580 curDisplayNode_->SetDisplayGlobalZOrder(globalZOrder_);
2581 if (!topLayers.empty()) {
2582 UpdateTopLayersDirtyStatus(topLayers);
2583 }
2584 if (pointWindow) {
2585 UpdatePointWindowDirtyStatus(pointWindow);
2586 }
2587 }
2588
UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode> & pointWindow)2589 void RSUniRenderVisitor::UpdatePointWindowDirtyStatus(std::shared_ptr<RSSurfaceRenderNode>& pointWindow)
2590 {
2591 std::shared_ptr<RSSurfaceHandler> pointSurfaceHandler = pointWindow->GetMutableRSSurfaceHandler();
2592 if (pointSurfaceHandler) {
2593 // globalZOrder_ + 2 is displayNode layer, point window must be at the top.
2594 pointSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 2);
2595 pointWindow->SetHardwareForcedDisabledState(!IsHardwareComposerEnabled() || !pointWindow->ShouldPaint() ||
2596 hasUniRenderHdrSurface_);
2597 auto transform = RSUniRenderUtil::GetLayerTransform(*pointWindow, screenInfo_);
2598 pointWindow->UpdateHwcNodeLayerInfo(transform);
2599 }
2600 }
2601
UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>> & topLayers)2602 void RSUniRenderVisitor::UpdateTopLayersDirtyStatus(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& topLayers)
2603 {
2604 for (const auto& topLayer : topLayers) {
2605 std::shared_ptr<RSSurfaceHandler> topLayerSurfaceHandler = topLayer->GetMutableRSSurfaceHandler();
2606 if (topLayerSurfaceHandler) {
2607 topLayerSurfaceHandler->SetGlobalZOrder(globalZOrder_ + 1);
2608 topLayer->SetCalcRectInPrepare(false);
2609 topLayer->SetHardwareForcedDisabledState(!IsHardwareComposerEnabled() || !topLayer->ShouldPaint() ||
2610 hasUniRenderHdrSurface_);
2611 auto transform = RSUniRenderUtil::GetLayerTransform(*topLayer, screenInfo_);
2612 topLayer->UpdateHwcNodeLayerInfo(transform);
2613 }
2614 }
2615 }
2616
UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode> & appNode,std::shared_ptr<RSSurfaceRenderNode> & hwcNode)2617 void RSUniRenderVisitor::UpdateHwcNodeDirtyRegionForApp(std::shared_ptr<RSSurfaceRenderNode>& appNode,
2618 std::shared_ptr<RSSurfaceRenderNode>& hwcNode)
2619 {
2620 // if current frame hwc enable status not equal with last frame
2621 // or current frame do gpu composition and has buffer consumed,
2622 // we need merge hwc node dst rect to dirty region.
2623 if (!hwcNode->IsHardwareForcedDisabled() != hwcNode->GetIsLastFrameHwcEnabled()) {
2624 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
2625 return;
2626 }
2627 if (!hwcNode->GetRSSurfaceHandler()) {
2628 return;
2629 }
2630 if (hwcNode->IsHardwareForcedDisabled() && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) {
2631 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetOldDirtyInSurface());
2632 }
2633 if (hasMirrorDisplay_ && hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed() &&
2634 !appNode->GetVisibleRegion().IsEmpty()) {
2635 // merge hwc node dst rect for virtual screen dirty, in case the main display node skip
2636 curDisplayDirtyManager_->MergeHwcDirtyRect(hwcNode->GetDstRect());
2637 }
2638 }
2639
UpdateSurfaceDirtyAndGlobalDirty()2640 void RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty()
2641 {
2642 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2643 // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order traversal
2644 Occlusion::Region accumulatedDirtyRegion;
2645 bool hasMainAndLeashSurfaceDirty = false;
2646 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2647 [this, &accumulatedDirtyRegion, &hasMainAndLeashSurfaceDirty](RSBaseRenderNode::SharedPtr& nodePtr) {
2648 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2649 if (!surfaceNode) {
2650 RS_LOGE("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surfaceNode is nullptr");
2651 return;
2652 }
2653 auto dirtyManager = surfaceNode->GetDirtyManager();
2654 RSMainThread::Instance()->GetContext().AddPendingSyncNode(nodePtr);
2655 // 0. update hwc node dirty region and create layer
2656 UpdateHwcNodeDirtyRegionAndCreateLayer(surfaceNode);
2657 // 1. calculate abs dirtyrect and update partialRenderParams
2658 // currently only sync visible region info
2659 surfaceNode->UpdatePartialRenderParams();
2660 if (dirtyManager && dirtyManager->IsCurrentFrameDirty()) {
2661 hasMainAndLeashSurfaceDirty = true;
2662 }
2663 if (surfaceNode->IsMainWindowType() && IfSkipInCalcGlobalDirty(*surfaceNode)) {
2664 RS_LOGD("RSUniRenderVisitor::UpdateSurfaceDirtyAndGlobalDirty surface:%{public}s "
2665 "which is occluded don't need to process global dirty", surfaceNode->GetName().c_str());
2666 return;
2667 }
2668 // 2. check surface node dirtyrect need merge into displayDirtyManager
2669 CheckMergeSurfaceDirtysForDisplay(surfaceNode);
2670 // 3. check merge transparent filter when it intersects with pre-dirty
2671 CheckMergeDisplayDirtyByTransparentFilter(surfaceNode, accumulatedDirtyRegion);
2672 });
2673 curDisplayNode_->SetMainAndLeashSurfaceDirty(hasMainAndLeashSurfaceDirty);
2674 CheckMergeDebugRectforRefreshRate(curMainAndLeashSurfaces);
2675 CheckMergeGlobalFilterForDisplay(accumulatedDirtyRegion);
2676 ResetDisplayDirtyRegion();
2677 curDisplayNode_->ClearCurrentSurfacePos();
2678 std::swap(preMainAndLeashWindowNodesIds_, curMainAndLeashWindowNodesIds_);
2679
2680 #ifdef RS_PROFILER_ENABLED
2681 RS_PROFILER_SET_DIRTY_REGION(accumulatedDirtyRegion);
2682 #endif
2683 }
UpdateHwcNodeEnableByNodeBelow()2684 void RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow()
2685 {
2686 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
2687 // this is used to record mainAndLeash surface accumulatedDirtyRegion by Pre-order travelsal
2688 std::vector<RectI> hwcRects;
2689 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
2690 [this, &hwcRects](RSBaseRenderNode::SharedPtr& nodePtr) {
2691 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
2692 if (!surfaceNode) {
2693 RS_LOGE("RSUniRenderVisitor::UpdateHwcNodeEnableByNodeBelow surfaceNode is nullptr");
2694 return;
2695 }
2696 // use in temporary scheme to realize DSS
2697 auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
2698 if (!hwcNodes.empty() && RsCommonHook::Instance().GetHardwareEnabledByBackgroundAlphaFlag() &&
2699 RsCommonHook::Instance().GetHardwareEnabledByHwcnodeBelowSelfInAppFlag()) {
2700 UpdateHardwareStateByHwcNodeBackgroundAlpha(hwcNodes);
2701 }
2702 // use end
2703 // disable hwc node with corner radius if intersects with hwc node below
2704 UpdateChildHwcNodeEnableByHwcNodeBelow(hwcRects, surfaceNode);
2705 });
2706 }
2707
UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & appNode)2708 void RSUniRenderVisitor::UpdateChildHwcNodeEnableByHwcNodeBelow(std::vector<RectI>& hwcRects,
2709 std::shared_ptr<RSSurfaceRenderNode>& appNode)
2710 {
2711 const auto& hwcNodes = appNode->GetChildHardwareEnabledNodes();
2712 for (auto hwcNode : hwcNodes) {
2713 auto hwcNodePtr = hwcNode.lock();
2714 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree()) {
2715 continue;
2716 }
2717 UpdateCornerRadiusInfoForDRM(hwcNodePtr, hwcRects);
2718 UpdateHwcNodeEnableByHwcNodeBelowSelf(hwcRects, hwcNodePtr,
2719 hwcNodePtr->GetIntersectedRoundCornerAABBsSize() != 0);
2720 }
2721 }
2722
UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,std::vector<RectI> & hwcRects)2723 void RSUniRenderVisitor::UpdateCornerRadiusInfoForDRM(std::shared_ptr<RSSurfaceRenderNode> hwcNode,
2724 std::vector<RectI>& hwcRects)
2725 {
2726 if (!hwcNode || !hwcNode->GetProtectedLayer()) {
2727 return;
2728 }
2729 auto instanceNode = hwcNode->GetInstanceRootNode() ?
2730 hwcNode->GetInstanceRootNode()->ReinterpretCastTo<RSSurfaceRenderNode>() : nullptr;
2731 if (!instanceNode) {
2732 hwcNode->SetCornerRadiusInfoForDRM({});
2733 return;
2734 }
2735 auto instanceAbsRect = instanceNode->GetAbsDrawRect();
2736 auto instanceCornerRadius = instanceNode->GetGlobalCornerRadius();
2737 if (instanceAbsRect.IsEmpty() || instanceCornerRadius.IsZero() ||
2738 ROSEN_EQ(instanceNode->GetRenderProperties().GetBoundsWidth(), 0.0f)) {
2739 hwcNode->SetCornerRadiusInfoForDRM({});
2740 return;
2741 }
2742 auto hwcGeo = hwcNode->GetRenderProperties().GetBoundsGeometry();
2743 if (!hwcGeo) {
2744 hwcNode->SetCornerRadiusInfoForDRM({});
2745 return;
2746 }
2747 auto hwcAbsRect = hwcGeo->MapRect(hwcNode->GetSelfDrawRect(), hwcNode->GetTotalMatrix());
2748 hwcAbsRect = hwcAbsRect.IntersectRect(instanceAbsRect);
2749 if (hwcAbsRect.IsEmpty()) {
2750 hwcNode->SetCornerRadiusInfoForDRM({});
2751 return;
2752 }
2753 auto ratio = static_cast<float>(instanceAbsRect.GetWidth()) /
2754 instanceNode->GetRenderProperties().GetBoundsWidth();
2755 std::vector<float> ratioVector = { 0.0f, 0.0f, 0.0f, 0.0f };
2756 bool isIntersectWithRoundCorner =
2757 CheckIfRoundCornerIntersectDRM(ratio, ratioVector, instanceCornerRadius, instanceAbsRect, hwcAbsRect);
2758 // store radius information when drm overlaps with other hwc nodes
2759 if (isIntersectWithRoundCorner) {
2760 for (const auto& rect : hwcRects) {
2761 if (hwcAbsRect.Intersect(rect)) {
2762 std::vector<float> drmCornerRadiusInfo = {
2763 static_cast<float>(hwcAbsRect.GetLeft()), static_cast<float>(hwcAbsRect.GetTop()),
2764 static_cast<float>(hwcAbsRect.GetWidth()), static_cast<float>(hwcAbsRect.GetHeight()),
2765 // get corner radius num by index 0, 1, 2, 3
2766 instanceCornerRadius[0] * ratioVector[0], instanceCornerRadius[1] * ratioVector[1],
2767 instanceCornerRadius[2] * ratioVector[2], instanceCornerRadius[3] * ratioVector[3]};
2768 hwcNode->SetCornerRadiusInfoForDRM(drmCornerRadiusInfo);
2769 return;
2770 }
2771 }
2772 }
2773 hwcNode->SetCornerRadiusInfoForDRM({});
2774 }
2775
CheckIfRoundCornerIntersectDRM(const float & ratio,std::vector<float> & ratioVector,const Vector4f & instanceCornerRadius,const RectI & instanceAbsRect,const RectI & hwcAbsRect)2776 bool RSUniRenderVisitor::CheckIfRoundCornerIntersectDRM(const float& ratio, std::vector<float>& ratioVector,
2777 const Vector4f& instanceCornerRadius, const RectI& instanceAbsRect, const RectI& hwcAbsRect)
2778 {
2779 auto maxRadius = *std::max_element(std::begin(instanceCornerRadius.data_),
2780 std::end(instanceCornerRadius.data_)) * ratio;
2781 bool isIntersectWithRoundCorner = false;
2782 static const std::vector<UIPoint> offsetVecs = { UIPoint { 0, 0 }, UIPoint { 1, 0 },
2783 UIPoint { 0, 1 }, UIPoint { 1, 1 } };
2784 UIPoint offset { instanceAbsRect.GetWidth() - maxRadius, instanceAbsRect.GetHeight() - maxRadius };
2785 UIPoint anchorPoint { instanceAbsRect.GetLeft(), instanceAbsRect.GetTop() };
2786 // if round corners intersect drm, update ratioVectors
2787 for (size_t i = 0; i < offsetVecs.size(); i++) {
2788 auto res = anchorPoint + offset * offsetVecs[i];
2789 if (RectI(res.x_, res.y_, maxRadius, maxRadius).Intersect(hwcAbsRect)) {
2790 isIntersectWithRoundCorner = true;
2791 ratioVector[i] = ratio;
2792 }
2793 }
2794 return isIntersectWithRoundCorner;
2795 }
2796
UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI> & hwcRects,std::shared_ptr<RSSurfaceRenderNode> & hwcNode,bool isIntersectWithRoundCorner)2797 void RSUniRenderVisitor::UpdateHwcNodeEnableByHwcNodeBelowSelf(std::vector<RectI>& hwcRects,
2798 std::shared_ptr<RSSurfaceRenderNode>& hwcNode, bool isIntersectWithRoundCorner)
2799 {
2800 if (hwcNode->IsHardwareForcedDisabled()) {
2801 if (RSMainThread::CheckIsHdrSurface(*hwcNode)) {
2802 hasUniRenderHdrSurface_ = true;
2803 }
2804 return;
2805 }
2806 auto absBound = RectI();
2807 if (auto geo = hwcNode->GetRenderProperties().GetBoundsGeometry()) {
2808 absBound = geo->GetAbsRect();
2809 } else {
2810 return;
2811 }
2812 if (hwcNode->GetAncoForceDoDirect() || !isIntersectWithRoundCorner) {
2813 hwcRects.emplace_back(absBound);
2814 return;
2815 }
2816 for (const auto& rect : hwcRects) {
2817 for (auto& roundCornerAABB : hwcNode->GetIntersectedRoundCornerAABBs()) {
2818 if (!roundCornerAABB.IntersectRect(rect).IsEmpty()) {
2819 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64
2820 " disabled by corner radius + hwc node below",
2821 hwcNode->GetName().c_str(), hwcNode->GetId());
2822 if (hwcNode->GetProtectedLayer()) {
2823 continue;
2824 }
2825 hwcNode->SetHardwareForcedDisabledState(true);
2826 if (RSMainThread::CheckIsHdrSurface(*hwcNode)) {
2827 hasUniRenderHdrSurface_ = true;
2828 }
2829 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNode->GetId(),
2830 HwcDisabledReasons::DISABLED_BY_HWC_NODE_ABOVE, hwcNode->GetName());
2831 return;
2832 }
2833 }
2834 }
2835 hwcRects.emplace_back(absBound);
2836 }
2837
UpdateSurfaceOcclusionInfo()2838 void RSUniRenderVisitor::UpdateSurfaceOcclusionInfo()
2839 {
2840 allDstCurVisVec_.insert(allDstCurVisVec_.end(), dstCurVisVec_.begin(), dstCurVisVec_.end());
2841 dstCurVisVec_.clear();
2842 }
2843
CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode & surfaceNode) const2844 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparent(RSSurfaceRenderNode& surfaceNode) const
2845 {
2846 // surfaceNode is transparent
2847 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2848 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2849 if (surfaceNode.IsTransparent()) {
2850 RectI transparentDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2851 if (!transparentDirtyRect.IsEmpty()) {
2852 RS_LOGD("CheckMergeDisplayDirtyByTransparent global merge transparent dirty "
2853 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2854 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2855 transparentDirtyRect.ToString().c_str());
2856 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(transparentDirtyRect);
2857 }
2858 }
2859 // surfaceNode has transparent regions
2860 CheckMergeDisplayDirtyByTransparentRegions(surfaceNode);
2861 }
2862
CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode & surfaceNode) const2863 void RSUniRenderVisitor::CheckMergeDisplayDirtyByZorderChanged(RSSurfaceRenderNode& surfaceNode) const
2864 {
2865 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2866 if (surfaceNode.GetZorderChanged()) {
2867 RS_LOGD("CheckMergeDisplayDirtyByZorderChanged global merge GetZorderChanged "
2868 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2869 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2870 oldDirtyInSurface.ToString().c_str());
2871 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(oldDirtyInSurface);
2872 }
2873 }
2874
CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode & surfaceNode) const2875 void RSUniRenderVisitor::CheckMergeDisplayDirtyByPosChanged(RSSurfaceRenderNode& surfaceNode) const
2876 {
2877 RectI lastFrameSurfacePos = curDisplayNode_->GetLastFrameSurfacePos(surfaceNode.GetId());
2878 RectI currentFrameSurfacePos = curDisplayNode_->GetCurrentFrameSurfacePos(surfaceNode.GetId());
2879 if (surfaceNode.GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
2880 RS_LOGD("CheckMergeDisplayDirtyByPosChanged global merge surface pos changed "
2881 "%{public}s: global dirty %{public}s, lastFrameRect %{public}s currentFrameRect %{public}s",
2882 surfaceNode.GetName().c_str(),
2883 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2884 lastFrameSurfacePos.ToString().c_str(), currentFrameSurfacePos.ToString().c_str());
2885 if (!lastFrameSurfacePos.IsEmpty()) {
2886 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(lastFrameSurfacePos);
2887 }
2888 if (!currentFrameSurfacePos.IsEmpty()) {
2889 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(currentFrameSurfacePos);
2890 }
2891 }
2892 }
2893
CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode & surfaceNode) const2894 void RSUniRenderVisitor::CheckMergeDisplayDirtyByShadowChanged(RSSurfaceRenderNode& surfaceNode) const
2895 {
2896 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2897 auto oldDirtyInSurface = surfaceNode.GetOldDirtyInSurface();
2898 bool isShadowDisappear = !surfaceNode.GetRenderProperties().IsShadowValid() &&
2899 surfaceNode.IsShadowValidLastFrame();
2900 if (surfaceNode.GetRenderProperties().IsShadowValid() || isShadowDisappear) {
2901 RectI shadowDirtyRect = oldDirtyInSurface.IntersectRect(dirtyRect);
2902 // There are two situation here:
2903 // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
2904 // dirtyRect == surfaceNode.GetOldDirtyInSurface()
2905 // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
2906 // dirtyRect > surfaceNode.GetOldDirtyInSurface()
2907 // So we should always merge dirtyRect here.
2908 if (!shadowDirtyRect.IsEmpty()) {
2909 RS_LOGD("CheckMergeDisplayDirtyByShadowChanged global merge ShadowValid %{public}s: "
2910 "global dirty %{public}s, add rect %{public}s", surfaceNode.GetName().c_str(),
2911 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2912 dirtyRect.ToString().c_str());
2913 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(dirtyRect);
2914 }
2915 if (isShadowDisappear) {
2916 surfaceNode.SetShadowValidLastFrame(false);
2917 }
2918 }
2919 }
2920
CheckMergeDisplayDirtyBySurfaceChanged() const2921 void RSUniRenderVisitor::CheckMergeDisplayDirtyBySurfaceChanged() const
2922 {
2923 std::vector<RectI> surfaceChangedRects = curDisplayNode_->GetSurfaceChangedRects();
2924 for (auto& surfaceChangedRect : surfaceChangedRects) {
2925 if (!surfaceChangedRect.IsEmpty()) {
2926 RS_LOGD("CheckMergeDisplayDirtyBySurfaceChanged global merge Surface closed, global dirty %{public}s,"
2927 "add rect %{public}s",
2928 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2929 surfaceChangedRect.ToString().c_str());
2930 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(surfaceChangedRect);
2931 }
2932 }
2933 }
2934
CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const2935 void RSUniRenderVisitor::CheckMergeSurfaceDirtysForDisplay(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
2936 {
2937 if (surfaceNode->GetDirtyManager() == nullptr || curDisplayNode_->GetDirtyManager() == nullptr) {
2938 return;
2939 }
2940 // 1 Handles the case of transparent surface, merge transparent dirty rect
2941 CheckMergeDisplayDirtyByTransparent(*surfaceNode);
2942 // 2 Zorder changed case, merge surface dest Rect
2943 CheckMergeDisplayDirtyByZorderChanged(*surfaceNode);
2944 // 3 surfacePos chanded case, merge surface lastframe pos or curframe pos
2945 CheckMergeDisplayDirtyByPosChanged(*surfaceNode);
2946 // 4 shadow disappear and appear case.
2947 CheckMergeDisplayDirtyByShadowChanged(*surfaceNode);
2948 // 5 handle last and curframe surfaces which appear or disappear case
2949 CheckMergeDisplayDirtyBySurfaceChanged();
2950 // More: any other display dirty caused by surfaceNode should be added here like CheckMergeDisplayDirtByXXX
2951 }
2952
CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode & surfaceNode) const2953 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentRegions(RSSurfaceRenderNode& surfaceNode) const
2954 {
2955 const auto& dirtyRect = surfaceNode.GetDirtyManager()->GetCurrentFrameDirtyRegion();
2956 if (surfaceNode.HasContainerWindow()) {
2957 // If a surface's dirty is intersect with container region (which can be considered transparent)
2958 // should be added to display dirty region.
2959 // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
2960 auto containerRegion = surfaceNode.GetContainerRegion();
2961 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2962 auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
2963 if (!containerDirtyRegion.IsEmpty()) {
2964 RS_LOGD("CheckMergeDisplayDirtyByContainer global merge containerDirtyRegion "
2965 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2966 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2967 containerDirtyRegion.GetRegionInfo().c_str());
2968 // plan: we can use surfacenode's absrect as containerRegion's bound
2969 const auto& rect = containerRegion.GetBoundRef();
2970 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(
2971 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2972 }
2973 } else {
2974 // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
2975 // transparent region and opaque region in adjacent frame, may cause displaydirty region incomplete after
2976 // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
2977 // which include transparent region but not counted in display dirtyregion)
2978 if (!surfaceNode.IsNodeDirty()) {
2979 return;
2980 }
2981 auto transparentRegion = surfaceNode.GetTransparentRegion();
2982 auto surfaceDirtyRegion = Occlusion::Region{ Occlusion::Rect{ dirtyRect } };
2983 Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
2984 if (!transparentDirtyRegion.IsEmpty()) {
2985 RS_LOGD("CheckMergeDisplayDirtyByTransparentRegions global merge TransparentDirtyRegion "
2986 "%{public}s: global dirty %{public}s, add region %{public}s", surfaceNode.GetName().c_str(),
2987 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
2988 transparentDirtyRegion.GetRegionInfo().c_str());
2989 const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
2990 for (const auto& rect : rects) {
2991 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(RectI{ rect.left_, rect.top_,
2992 rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
2993 }
2994 }
2995 }
2996 }
2997
IfSkipInCalcGlobalDirty(RSSurfaceRenderNode & surfaceNode) const2998 bool RSUniRenderVisitor::IfSkipInCalcGlobalDirty(RSSurfaceRenderNode& surfaceNode) const
2999 {
3000 return hasMirrorDisplay_ ?
3001 surfaceNode.GetVisibleRegionInVirtual().IsEmpty() : surfaceNode.GetVisibleRegion().IsEmpty();
3002 }
3003
CheckMergeDisplayDirtyByTransparentFilter(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & accumulatedDirtyRegion)3004 void RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter(
3005 std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
3006 Occlusion::Region& accumulatedDirtyRegion)
3007 {
3008 auto disappearedSurfaceRegionBelowCurrent =
3009 curDisplayNode_->GetDisappearedSurfaceRegionBelowCurrent(surfaceNode->GetId());
3010 accumulatedDirtyRegion.OrSelf(disappearedSurfaceRegionBelowCurrent);
3011 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3012 auto filterVecIter = transparentCleanFilter_.find(surfaceNode->GetId());
3013 if (filterVecIter != transparentCleanFilter_.end()) {
3014 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter surface:%{public}s "
3015 "has transparentCleanFilter", surfaceNode->GetName().c_str());
3016 // check accumulatedDirtyRegion influence filter nodes which in the current surface
3017 for (auto it = filterVecIter->second.begin(); it != filterVecIter->second.end(); ++it) {
3018 auto filterNode = nodeMap.GetRenderNode(it->first);
3019 if (filterNode == nullptr) {
3020 continue;
3021 }
3022 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
3023 auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
3024 if (!filterDirtyRegion.IsEmpty()) {
3025 if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3026 // backgroundfilter affected by below dirty
3027 filterNode->MarkFilterStatusChanged(false, false);
3028 }
3029 RS_LOGD("RSUniRenderVisitor::CheckMergeDisplayDirtyByTransparentFilter global merge filterRegion "
3030 "%{public}s: global dirty %{public}s, add rect %{public}s", surfaceNode->GetName().c_str(),
3031 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3032 it->second.ToString().c_str());
3033 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
3034 if (filterNode->GetRenderProperties().GetFilter()) {
3035 // foregroundfilter affected by below dirty
3036 filterNode->MarkFilterStatusChanged(true, false);
3037 }
3038 } else {
3039 globalFilter_.insert(*it);
3040 }
3041 filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
3042 }
3043 }
3044 auto surfaceDirtyRegion = Occlusion::Region{
3045 Occlusion::Rect{ surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion() } };
3046 accumulatedDirtyRegion.OrSelf(surfaceDirtyRegion);
3047 }
3048
UpdateDisplayDirtyAndExtendVisibleRegion()3049 void RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion()
3050 {
3051 if (curDisplayNode_ == nullptr) {
3052 RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion curDisplayNode_ is nullptr");
3053 return;
3054 }
3055 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
3056 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3057 std::for_each(curMainAndLeashSurfaces.rbegin(), curMainAndLeashSurfaces.rend(),
3058 [this, &nodeMap](RSBaseRenderNode::SharedPtr& nodePtr) {
3059 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodePtr);
3060 if (surfaceNode == nullptr) {
3061 RS_LOGE("RSUniRenderVisitor::UpdateDisplayDirtyAndExtendVisibleRegion surfaceNode is nullptr");
3062 return;
3063 }
3064 if (!surfaceNode->IsMainWindowType()) {
3065 return;
3066 }
3067 Occlusion::Region extendRegion;
3068 if (!surfaceNode->GetVisibleRegion().IsEmpty()) {
3069 ProcessFilterNodeObscured(surfaceNode, extendRegion, nodeMap);
3070 }
3071 surfaceNode->UpdateExtendVisibleRegion(extendRegion);
3072 });
3073 }
3074
ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode,Occlusion::Region & extendRegion,const RSRenderNodeMap & nodeMap)3075 void RSUniRenderVisitor::ProcessFilterNodeObscured(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode,
3076 Occlusion::Region& extendRegion, const RSRenderNodeMap& nodeMap)
3077 {
3078 const auto& visibleFilterChild = surfaceNode->GetVisibleFilterChild();
3079 auto visibleRegion = surfaceNode->GetVisibleRegion();
3080 auto currentFrameDirtyRegion = surfaceNode->GetDirtyManager()->GetCurrentFrameDirtyRegion();
3081 auto isTransparent = surfaceNode->IsTransparent();
3082 for (const auto& child : visibleFilterChild) {
3083 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3084 if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
3085 continue;
3086 }
3087 MarkBlurIntersectWithDRM(filterNode);
3088 auto filterRect = filterNode->GetOldDirtyInSurface();
3089 auto visibleRects = visibleRegion.GetRegionRectIs();
3090 auto iter = std::find_if(visibleRects.begin(), visibleRects.end(), [&filterRect](const auto& rect) {
3091 return filterRect.IsInsideOf(rect);
3092 });
3093 if (iter != visibleRects.end()) {
3094 continue;
3095 }
3096 if (!visibleRegion.IsIntersectWith(filterRect)) {
3097 continue;
3098 }
3099 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ filterRect } };
3100 extendRegion = extendRegion.Or(filterRegion);
3101 if (!isTransparent && filterRect.Intersect(currentFrameDirtyRegion)) {
3102 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(filterRect);
3103 }
3104 }
3105 }
3106
UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode> & surfaceNode) const3107 void RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode(std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) const
3108 {
3109 if (surfaceNode == nullptr) {
3110 return;
3111 }
3112 if (surfaceNode->HasBlurFilter()) {
3113 surfaceNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
3114 }
3115 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3116 for (auto& child : surfaceNode->GetVisibleFilterChild()) {
3117 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3118 if (filterNode == nullptr || !filterNode->HasBlurFilter()) {
3119 continue;
3120 }
3121 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateOccludedStatusWithFilterNode "
3122 "surfaceNode: %s, filterNode:[%lld], IsOccludedByFilterCache:%d", surfaceNode->GetName().c_str(),
3123 filterNode->GetId(), surfaceNode->IsOccludedByFilterCache());
3124 filterNode->SetOccludedStatus(surfaceNode->IsOccludedByFilterCache());
3125 }
3126 }
3127
CheckMergeGlobalFilterForDisplay(Occlusion::Region & accumulatedDirtyRegion)3128 void RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay(Occlusion::Region& accumulatedDirtyRegion)
3129 {
3130 // [planning] if not allowed containerNode filter, The following processing logic can be removed
3131 // Recursively traverses container nodes need filter
3132 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3133 for (auto it = containerFilter_.begin(); it != containerFilter_.end(); ++it) {
3134 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(it->first);
3135 if (filterNode == nullptr) {
3136 continue;
3137 }
3138 auto filterRegion = Occlusion::Region{ Occlusion::Rect{ it->second } };
3139 auto filterDirtyRegion = filterRegion.And(accumulatedDirtyRegion);
3140 RS_OPTIONAL_TRACE_NAME_FMT("CheckMergeGlobalFilterForDisplay::filternode:%" PRIu64
3141 ", filterRect:%s, dirtyRegion:%s",
3142 filterNode->GetId(), it->second.ToString().c_str(), accumulatedDirtyRegion.GetRegionInfo().c_str());
3143 if (!filterDirtyRegion.IsEmpty()) {
3144 RS_LOGD("RSUniRenderVisitor::CheckMergeGlobalFilterForDisplay global merge, "
3145 "global dirty %{public}s, add container filterRegion %{public}s",
3146 curDisplayNode_->GetDirtyManager()->GetCurrentFrameDirtyRegion().ToString().c_str(),
3147 (it->second).ToString().c_str());
3148 if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3149 filterNode->MarkFilterStatusChanged(false, false); // background filter affected by below dirty
3150 }
3151 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(it->second);
3152 if (filterNode->GetRenderProperties().GetFilter()) {
3153 filterNode->MarkFilterStatusChanged(true, false); // foreground filter affected by below dirty
3154 }
3155 } else {
3156 globalFilter_.insert(*it);
3157 }
3158 filterNode->UpdateFilterCacheWithSelfDirty();
3159 filterNode->PostPrepareForBlurFilterNode(*(curDisplayNode_->GetDirtyManager()), needRequestNextVsync_);
3160 }
3161 UpdateDisplayDirtyAndExtendVisibleRegion();
3162 CheckMergeFilterDirtyByIntersectWithDirty(globalFilter_, true);
3163 }
3164
CollectEffectInfo(RSRenderNode & node)3165 void RSUniRenderVisitor::CollectEffectInfo(RSRenderNode& node)
3166 {
3167 auto nodeParent = node.GetParent().lock();
3168 if (nodeParent == nullptr) {
3169 return;
3170 }
3171 if (node.GetRenderProperties().NeedFilter() || node.ChildHasVisibleFilter()) {
3172 nodeParent->SetChildHasVisibleFilter(true);
3173 nodeParent->UpdateVisibleFilterChild(node);
3174 }
3175 if (node.GetRenderProperties().GetUseEffect() || node.ChildHasVisibleEffect()) {
3176 nodeParent->SetChildHasVisibleEffect(true);
3177 nodeParent->UpdateVisibleEffectChild(node);
3178 }
3179 if (node.GetSharedTransitionParam() || node.ChildHasSharedTransition()) {
3180 nodeParent->SetChildHasSharedTransition(true);
3181 }
3182 }
3183
PostPrepare(RSRenderNode & node,bool subTreeSkipped)3184 void RSUniRenderVisitor::PostPrepare(RSRenderNode& node, bool subTreeSkipped)
3185 {
3186 auto curDirtyManager = curSurfaceNode_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
3187 if (!curDirtyManager) {
3188 return;
3189 }
3190 auto isOccluded = curSurfaceNode_ ?
3191 curSurfaceNode_->IsMainWindowType() && curSurfaceNode_->GetVisibleRegion().IsEmpty() : false;
3192 if (subTreeSkipped && !isOccluded) {
3193 UpdateHwcNodeRectInSkippedSubTree(node);
3194 CheckFilterNodeInSkippedSubTreeNeedClearCache(node, *curDirtyManager);
3195 UpdateSubSurfaceNodeRectInSkippedSubTree(node);
3196 }
3197 if (node.GetRenderProperties().NeedFilter()) {
3198 UpdateHwcNodeEnableByFilterRect(
3199 curSurfaceNode_, node.GetOldDirtyInSurface(), NeedPrepareChindrenInReverseOrder(node));
3200 auto globalFilterRect = (node.IsInstanceOf<RSEffectRenderNode>() && !node.FirstFrameHasEffectChildren()) ?
3201 GetVisibleEffectDirty(node) : node.GetOldDirtyInSurface();
3202 node.CalVisibleFilterRect(prepareClipRect_);
3203 node.MarkClearFilterCacheIfEffectChildrenChanged();
3204 CollectFilterInfoAndUpdateDirty(node, *curDirtyManager, globalFilterRect);
3205 node.SetGlobalAlpha(curAlpha_);
3206 }
3207 CollectEffectInfo(node);
3208 node.MapAndUpdateChildrenRect();
3209 node.UpdateSubTreeInfo(prepareClipRect_);
3210 node.UpdateLocalDrawRect();
3211 node.UpdateAbsDrawRect();
3212 node.ResetChangeState();
3213 if (isDrawingCacheEnabled_) {
3214 node.UpdateDrawingCacheInfoAfterChildren();
3215 }
3216 if (auto nodeParent = node.GetParent().lock()) {
3217 nodeParent->UpdateChildUifirstSupportFlag(node.GetUifirstSupportFlag());
3218 nodeParent->OpincUpdateNodeSupportFlag(node.OpincGetNodeSupportFlag());
3219 }
3220 auto& stagingRenderParams = node.GetStagingRenderParams();
3221 if (stagingRenderParams != nullptr) {
3222 if (node.GetSharedTransitionParam() && node.GetRenderProperties().GetSandBox()) {
3223 stagingRenderParams->SetAlpha(curAlpha_);
3224 } else {
3225 stagingRenderParams->SetAlpha(node.GetRenderProperties().GetAlpha());
3226 }
3227 }
3228
3229 // planning: only do this if node is dirty
3230 node.UpdateRenderParams();
3231
3232 // add if node is dirty
3233 node.AddToPendingSyncList();
3234 }
3235
MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const3236 void RSUniRenderVisitor::MarkBlurIntersectWithDRM(std::shared_ptr<RSRenderNode> node) const
3237 {
3238 if (!RSSystemProperties::GetDrmMarkedFilterEnabled()) {
3239 return;
3240 }
3241 static std::vector<std::string> drmKeyWins = { "SCBVolumePanel", "SCBBannerNotification" };
3242 auto appWindowNodeId = node->GetInstanceRootNodeId();
3243 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3244 auto appWindowNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(nodeMap.GetRenderNode(appWindowNodeId));
3245 if (appWindowNode == nullptr) {
3246 return;
3247 }
3248 for (const auto& win : drmKeyWins) {
3249 if (appWindowNode->GetName().find(win) != std::string::npos) {
3250 for (auto& drmNode : drmNodes_) {
3251 auto drmNodePtr = drmNode.lock();
3252 if (drmNodePtr && drmNodePtr->GetDstRect().Intersect(node->GetFilterRegion())) {
3253 node->MarkBlurIntersectWithDRM(true, RSMainThread::Instance()->GetGlobalDarkColorMode());
3254 }
3255 }
3256 }
3257 }
3258 }
3259
CheckFilterNodeInSkippedSubTreeNeedClearCache(const RSRenderNode & rootNode,RSDirtyRegionManager & dirtyManager)3260 void RSUniRenderVisitor::CheckFilterNodeInSkippedSubTreeNeedClearCache(
3261 const RSRenderNode& rootNode, RSDirtyRegionManager& dirtyManager)
3262 {
3263 bool rotationChanged = curDisplayNode_ ?
3264 curDisplayNode_->IsRotationChanged() || curDisplayNode_->IsLastRotationChanged() : false;
3265 bool rotationStatusChanged = curDisplayNode_ ?
3266 curDisplayNode_->GetPreRotationStatus() != curDisplayNode_->GetCurRotationStatus() : false;
3267 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3268 for (auto& child : rootNode.GetVisibleFilterChild()) {
3269 auto& filterNode = nodeMap.GetRenderNode<RSRenderNode>(child);
3270 if (filterNode == nullptr) {
3271 continue;
3272 }
3273 RS_OPTIONAL_TRACE_NAME_FMT("CheckFilterNodeInSkippedSubTreeNeedClearCache node[%lld]", filterNode->GetId());
3274 if (auto effectNode = RSRenderNode::ReinterpretCast<RSEffectRenderNode>(filterNode)) {
3275 UpdateRotationStatusForEffectNode(*effectNode);
3276 }
3277 filterNode->CheckBlurFilterCacheNeedForceClearOrSave(rotationChanged, rotationStatusChanged);
3278 filterNode->MarkClearFilterCacheIfEffectChildrenChanged();
3279 if (filterNode->GetRenderProperties().GetBackgroundFilter()) {
3280 filterNode->UpdateFilterCacheWithBelowDirty(dirtyManager, false);
3281 }
3282 RectI filterRect;
3283 filterNode->UpdateFilterRegionInSkippedSubTree(dirtyManager, rootNode, filterRect, prepareClipRect_);
3284 UpdateHwcNodeEnableByFilterRect(curSurfaceNode_, filterNode->GetOldDirtyInSurface());
3285 CollectFilterInfoAndUpdateDirty(*filterNode, dirtyManager, filterRect);
3286 }
3287 }
3288
UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode & rootNode)3289 void RSUniRenderVisitor::UpdateHwcNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3290 {
3291 if (RS_PROFILER_SHOULD_BLOCK_HWCNODE()) {
3292 return;
3293 }
3294
3295 if (!curSurfaceNode_) {
3296 return;
3297 }
3298 const auto& hwcNodes = curSurfaceNode_->GetChildHardwareEnabledNodes();
3299 if (hwcNodes.empty()) {
3300 return;
3301 }
3302 for (auto hwcNode : hwcNodes) {
3303 auto hwcNodePtr = hwcNode.lock();
3304 if (!hwcNodePtr || !hwcNodePtr->IsOnTheTree() || hwcNodePtr->GetCalcRectInPrepare()) {
3305 continue;
3306 }
3307 const auto& property = hwcNodePtr->GetRenderProperties();
3308 auto geoPtr = property.GetBoundsGeometry();
3309 if (geoPtr == nullptr) {
3310 return;
3311 }
3312 auto matrix = geoPtr->GetMatrix();
3313 auto parent = hwcNodePtr->GetParent().lock();
3314 bool findInRoot = parent ? parent->GetId() == rootNode.GetId() : false;
3315 while (parent && parent->GetType() != RSRenderNodeType::DISPLAY_NODE) {
3316 if (auto opt = RSUniRenderUtil::GetMatrix(parent)) {
3317 matrix.PostConcat(opt.value());
3318 } else {
3319 break;
3320 }
3321 parent = parent->GetParent().lock();
3322 if (!parent) {
3323 break;
3324 }
3325 findInRoot = parent->GetId() == rootNode.GetId() ? true : findInRoot;
3326 }
3327 if (!findInRoot) {
3328 continue;
3329 }
3330 if (parent) {
3331 const auto& parentGeoPtr = parent->GetRenderProperties().GetBoundsGeometry();
3332 if (parentGeoPtr) {
3333 matrix.PostConcat(parentGeoPtr->GetMatrix());
3334 }
3335 }
3336 auto surfaceHandler = hwcNodePtr->GetMutableRSSurfaceHandler();
3337 const auto& properties = hwcNodePtr->GetRenderProperties();
3338 Drawing::Rect bounds = Drawing::Rect(0, 0, properties.GetBoundsWidth(), properties.GetBoundsHeight());
3339 Drawing::Rect absRect;
3340 matrix.MapRect(absRect, bounds);
3341 RectI rect = {std::round(absRect.left_), std::round(absRect.top_),
3342 std::round(absRect.GetWidth()), std::round(absRect.GetHeight())};
3343 UpdateDstRect(*hwcNodePtr, rect, prepareClipRect_);
3344 UpdateSrcRect(*hwcNodePtr, matrix, rect);
3345 UpdateHwcNodeByTransform(*hwcNodePtr);
3346 UpdateHwcNodeEnableBySrcRect(*hwcNodePtr);
3347 UpdateHwcNodeEnableByBufferSize(*hwcNodePtr);
3348 hwcNodePtr->SetTotalMatrix(matrix);
3349 }
3350 }
3351
UpdateHardwareStateByHwcNodeBackgroundAlpha(const std::vector<std::weak_ptr<RSSurfaceRenderNode>> & hwcNodes)3352 void RSUniRenderVisitor::UpdateHardwareStateByHwcNodeBackgroundAlpha(
3353 const std::vector<std::weak_ptr<RSSurfaceRenderNode>>& hwcNodes)
3354 {
3355 std::list<RectI> hwcRects;
3356 for (size_t i = 0; i < hwcNodes.size(); i++) {
3357 auto hwcNodePtr = hwcNodes[i].lock();
3358 if (!hwcNodePtr) {
3359 continue;
3360 }
3361 if (!hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled()) {
3362 hwcRects.push_back(hwcNodePtr->GetDstRect());
3363 } else if (hwcNodePtr->IsNodeHasBackgroundColorAlpha() && !hwcNodePtr->IsHardwareForcedDisabled() &&
3364 hwcRects.size() != 0 && IsNodeAboveInsideOfNodeBelow(hwcNodePtr->GetDstRect(), hwcRects)) {
3365 continue;
3366 } else {
3367 hwcNodePtr->SetHardwareForcedDisabledState(true);
3368 }
3369 }
3370 }
3371
IsNodeAboveInsideOfNodeBelow(const RectI & rectAbove,std::list<RectI> & hwcNodeRectList)3372 bool RSUniRenderVisitor::IsNodeAboveInsideOfNodeBelow(const RectI& rectAbove, std::list<RectI>& hwcNodeRectList)
3373 {
3374 for (auto rectBelow: hwcNodeRectList) {
3375 if (rectAbove.IsInsideOf(rectBelow)) {
3376 return true;
3377 }
3378 }
3379 return false;
3380 }
3381
CalcHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode> & node,const RectI & filterRect,bool isReverseOrder)3382 void RSUniRenderVisitor::CalcHwcNodeEnableByFilterRect(
3383 std::shared_ptr<RSSurfaceRenderNode>& node, const RectI& filterRect, bool isReverseOrder)
3384 {
3385 if (!node) {
3386 return;
3387 }
3388 auto dstRect = node->GetDstRect();
3389 bool isIntersect = !dstRect.IntersectRect(filterRect).IsEmpty();
3390 if (isIntersect) {
3391 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by filter rect",
3392 node->GetName().c_str(), node->GetId());
3393 node->SetHardwareForcedDisabledState(true);
3394 node->SetHardWareDisabledByReverse(isReverseOrder);
3395 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(node->GetId(),
3396 HwcDisabledReasons::DISABLED_BY_FLITER_RECT, node->GetName());
3397 }
3398 }
3399
UpdateHwcNodeEnableByFilterRect(std::shared_ptr<RSSurfaceRenderNode> & node,const RectI & filterRect,bool isReverseOrder)3400 void RSUniRenderVisitor::UpdateHwcNodeEnableByFilterRect(
3401 std::shared_ptr<RSSurfaceRenderNode>& node, const RectI& filterRect, bool isReverseOrder)
3402 {
3403 if (filterRect.IsEmpty()) {
3404 return;
3405 }
3406 if (!node) {
3407 const auto& selfDrawingNodes = RSMainThread::Instance()->GetSelfDrawingNodes();
3408 if (selfDrawingNodes.empty()) {
3409 return;
3410 }
3411 for (auto hwcNode : selfDrawingNodes) {
3412 CalcHwcNodeEnableByFilterRect(hwcNode, filterRect, isReverseOrder);
3413 }
3414 } else {
3415 const auto& hwcNodes = node->GetChildHardwareEnabledNodes();
3416 if (hwcNodes.empty()) {
3417 return;
3418 }
3419 for (auto hwcNode : hwcNodes) {
3420 auto hwcNodePtr = hwcNode.lock();
3421 CalcHwcNodeEnableByFilterRect(hwcNodePtr, filterRect, isReverseOrder);
3422 }
3423 }
3424 }
3425
UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode> & node)3426 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalFilter(std::shared_ptr<RSSurfaceRenderNode>& node)
3427 {
3428 auto cleanFilter = transparentCleanFilter_.find(node->GetId());
3429 bool cleanFilterFound = (cleanFilter != transparentCleanFilter_.end());
3430 auto dirtyFilter = transparentDirtyFilter_.find(node->GetId());
3431 bool dirtyFilterFound = (dirtyFilter != transparentDirtyFilter_.end());
3432 auto& curMainAndLeashSurfaces = curDisplayNode_->GetAllMainAndLeashSurfaces();
3433 for (auto it = curMainAndLeashSurfaces.rbegin(); it != curMainAndLeashSurfaces.rend(); ++it) {
3434 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
3435 if (surfaceNode == nullptr) {
3436 continue;
3437 }
3438 if (surfaceNode->GetId() == node->GetId()) {
3439 return;
3440 }
3441 const auto& hwcNodes = surfaceNode->GetChildHardwareEnabledNodes();
3442 if (hwcNodes.empty()) {
3443 continue;
3444 }
3445 for (auto hwcNode : hwcNodes) {
3446 auto hwcNodePtr = hwcNode.lock();
3447 if (!hwcNodePtr || hwcNodePtr->IsHardwareForcedDisabled()) {
3448 continue;
3449 }
3450 if (cleanFilterFound) {
3451 UpdateHwcNodeEnableByGlobalCleanFilter(cleanFilter->second, *hwcNodePtr);
3452 if (hwcNodePtr->IsHardwareForcedDisabled()) {
3453 ProcessAncoNode(hwcNodePtr);
3454 continue;
3455 }
3456 }
3457 if (!dirtyFilterFound) {
3458 continue;
3459 }
3460 for (auto filter = dirtyFilter->second.begin(); filter != dirtyFilter->second.end(); ++filter) {
3461 if (hwcNodePtr->GetDstRect().Intersect(filter->second)) {
3462 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentDirtyFilter",
3463 hwcNodePtr->GetName().c_str(), hwcNodePtr->GetId());
3464 hwcNodePtr->SetHardwareForcedDisabledState(true);
3465 ProcessAncoNode(hwcNodePtr);
3466 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr->GetId(),
3467 HwcDisabledReasons::DISABLED_BY_TRANSPARENT_DIRTY_FLITER, hwcNodePtr->GetName());
3468 break;
3469 }
3470 }
3471 }
3472 }
3473 }
3474
UpdateHwcNodeEnableByGlobalCleanFilter(const std::vector<std::pair<NodeId,RectI>> & cleanFilter,RSSurfaceRenderNode & hwcNodePtr)3475 void RSUniRenderVisitor::UpdateHwcNodeEnableByGlobalCleanFilter(
3476 const std::vector<std::pair<NodeId, RectI>>& cleanFilter, RSSurfaceRenderNode& hwcNodePtr)
3477 {
3478 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3479 for (auto filter = cleanFilter.begin(); filter != cleanFilter.end(); ++filter) {
3480 if (hwcNodePtr.GetDstRect().Intersect(filter->second)) {
3481 auto& rendernode = nodeMap.GetRenderNode<RSRenderNode>(filter->first);
3482 if (rendernode == nullptr) {
3483 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: rendernode is null");
3484 continue;
3485 }
3486
3487 if (rendernode->IsAIBarFilterCacheValid()) {
3488 ROSEN_LOGD("RSUniRenderVisitor::UpdateHwcNodeByFilter: skip intersection for using cache");
3489 continue;
3490 }
3491 RS_OPTIONAL_TRACE_NAME_FMT("hwc debug: name:%s id:%" PRIu64 " disabled by transparentCleanFilter",
3492 hwcNodePtr.GetName().c_str(), hwcNodePtr.GetId());
3493 hwcNodePtr.SetHardwareForcedDisabledState(true);
3494 hwcDisabledReasonCollection_.UpdateHwcDisabledReasonForDFX(hwcNodePtr.GetId(),
3495 HwcDisabledReasons::DISABLED_BY_TRANSPARENT_CLEAN_FLITER, hwcNodePtr.GetName());
3496 break;
3497 }
3498 }
3499 }
3500
ResetSubSurfaceNodesCalState(std::vector<std::pair<NodeId,std::weak_ptr<RSSurfaceRenderNode>>> & subSurfaceNodes)3501 inline static void ResetSubSurfaceNodesCalState(
3502 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>>& subSurfaceNodes)
3503 {
3504 for (auto& [id, node] : subSurfaceNodes) {
3505 auto subSurfaceNodePtr = node.lock();
3506 if (!subSurfaceNodePtr) {
3507 continue;
3508 }
3509 subSurfaceNodePtr->SetCalcRectInPrepare(false);
3510 }
3511 }
3512
UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode & rootNode)3513 void RSUniRenderVisitor::UpdateSubSurfaceNodeRectInSkippedSubTree(const RSRenderNode& rootNode)
3514 {
3515 if (!curSurfaceNode_) {
3516 return;
3517 }
3518 auto rootGeo = rootNode.GetRenderProperties().GetBoundsGeometry();
3519 if (!rootGeo) {
3520 return;
3521 }
3522
3523 std::vector<std::pair<NodeId, std::weak_ptr<RSSurfaceRenderNode>>> allSubSurfaceNodes;
3524 curSurfaceNode_->GetAllSubSurfaceNodes(allSubSurfaceNodes);
3525 for (auto& [_, subSurfaceNode] : allSubSurfaceNodes) {
3526 auto subSurfaceNodePtr = subSurfaceNode.lock();
3527 Drawing::Matrix absMatrix;
3528 if (!subSurfaceNodePtr || subSurfaceNodePtr->GetCalcRectInPrepare() ||
3529 !subSurfaceNodePtr->GetAbsMatrixReverse(rootNode, absMatrix)) {
3530 continue;
3531 }
3532
3533 Drawing::RectF absDrawRect;
3534 absMatrix.MapRect(absDrawRect, RSPropertiesPainter::Rect2DrawingRect(subSurfaceNodePtr->GetSelfDrawRect()));
3535 RectI subSurfaceRect = RectI(absDrawRect.GetLeft(), absDrawRect.GetTop(),
3536 absDrawRect.GetWidth(), absDrawRect.GetHeight());
3537
3538 subSurfaceNodePtr->SetOldDirtyInSurface(subSurfaceRect.IntersectRect(prepareClipRect_));
3539 UpdateNodeVisibleRegion(*subSurfaceNodePtr);
3540 UpdateDstRect(*subSurfaceNodePtr, subSurfaceRect, prepareClipRect_);
3541 subSurfaceNodePtr->SetCalcRectInPrepare(true);
3542 if (subSurfaceNodePtr->IsLeashOrMainWindow()) {
3543 curMainAndLeashWindowNodesIds_.push(subSurfaceNodePtr->GetId());
3544 curDisplayNode_->RecordMainAndLeashSurfaces(subSurfaceNodePtr);
3545 CollectOcclusionInfoForWMS(*subSurfaceNodePtr);
3546 }
3547 }
3548 ResetSubSurfaceNodesCalState(allSubSurfaceNodes);
3549 }
3550
GetVisibleEffectDirty(RSRenderNode & node) const3551 RectI RSUniRenderVisitor::GetVisibleEffectDirty(RSRenderNode& node) const
3552 {
3553 RectI childEffectRect;
3554 auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
3555 for (auto& nodeId : node.GetVisibleEffectChild()) {
3556 if (auto& subnode = nodeMap.GetRenderNode<RSRenderNode>(nodeId)) {
3557 childEffectRect = childEffectRect.JoinRect(subnode->GetOldDirtyInSurface());
3558 }
3559 }
3560 return childEffectRect;
3561 }
3562
CollectFilterInfoAndUpdateDirty(RSRenderNode & node,RSDirtyRegionManager & dirtyManager,const RectI & globalFilterRect)3563 void RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty(RSRenderNode& node,
3564 RSDirtyRegionManager& dirtyManager, const RectI& globalFilterRect)
3565 {
3566 bool isNodeAddedToTransparentCleanFilters = false;
3567 if (curSurfaceNode_) {
3568 bool isIntersect = dirtyManager.GetCurrentFrameDirtyRegion().Intersect(globalFilterRect);
3569 if (isIntersect) {
3570 dirtyManager.MergeDirtyRect(globalFilterRect);
3571 } else {
3572 curSurfaceNoBelowDirtyFilter_.insert({node.GetId(), globalFilterRect});
3573 }
3574 if (node.GetRenderProperties().GetFilter()) {
3575 node.UpdateFilterCacheWithBelowDirty(dirtyManager, true);
3576 }
3577 node.UpdateFilterCacheWithSelfDirty();
3578 if (curSurfaceNode_->IsTransparent()) {
3579 globalFilterRects_.emplace_back(globalFilterRect);
3580 if (!isIntersect || (isIntersect && node.GetRenderProperties().GetBackgroundFilter() &&
3581 !node.IsBackgroundInAppOrNodeSelfDirty())) {
3582 // record nodes which has transparent clean filter
3583 RS_OPTIONAL_TRACE_NAME_FMT("CollectFilterInfoAndUpdateDirty::surfaceNode:%s, add node[%lld] to "
3584 "transparentCleanFilter", curSurfaceNode_->GetName().c_str(), node.GetId());
3585 transparentCleanFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalFilterRect});
3586 isNodeAddedToTransparentCleanFilters = true;
3587 }
3588 if (isIntersect) {
3589 transparentDirtyFilter_[curSurfaceNode_->GetId()].push_back({node.GetId(), globalFilterRect});
3590 RS_LOGD("RSUniRenderVisitor::CollectFilterInfoAndUpdateDirty global merge transparentDirtyFilter "
3591 "%{public}s, global dirty %{public}s, add rect %{public}s", curSurfaceNode_->GetName().c_str(),
3592 curDisplayDirtyManager_->GetCurrentFrameDirtyRegion().ToString().c_str(),
3593 globalFilterRect.ToString().c_str());
3594 curDisplayDirtyManager_->MergeDirtyRect(globalFilterRect);
3595 }
3596 } else {
3597 // record surface nodes and nodes in surface which has clean filter
3598 globalFilter_.insert({node.GetId(), globalFilterRect});
3599 }
3600 } else {
3601 globalFilterRects_.emplace_back(globalFilterRect);
3602 // record container nodes which need filter
3603 containerFilter_.insert({node.GetId(), globalFilterRect});
3604 }
3605 if (curSurfaceNode_ && !isNodeAddedToTransparentCleanFilters) {
3606 node.PostPrepareForBlurFilterNode(dirtyManager, needRequestNextVsync_);
3607 }
3608 }
3609
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)3610 void RSUniRenderVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
3611 {
3612 auto nodeId = node.GetId();
3613 RS_OPTIONAL_TRACE_NAME("RSUniRender::Prepare:[" + node.GetName() + "] nodeid: " +
3614 std::to_string(nodeId) + " pid: " + std::to_string(ExtractPid(nodeId)) +
3615 ", nodeType " + std::to_string(static_cast<uint>(node.GetSurfaceNodeType())));
3616 if (curDisplayNode_ == nullptr) {
3617 ROSEN_LOGE("RSUniRenderVisitor::PrepareSurfaceRenderNode, curDisplayNode_ is nullptr.");
3618 return;
3619 }
3620 // avoid EntryView upload texture while screen rotation
3621 if (node.GetName() == "EntryView") {
3622 node.SetStaticCached(curDisplayNode_->IsRotationChanged());
3623 }
3624 node.UpdatePositionZ();
3625 if (node.GetName().find(CAPTURE_WINDOW_NAME) != std::string::npos) {
3626 hasCaptureWindow_[currentVisitDisplay_] = true;
3627 node.SetContentDirty(); // screen recording capsule force mark dirty
3628 }
3629
3630 node.SetAncestorDisplayNode(curDisplayNode_);
3631 node.UpdateAncestorDisplayNodeInRenderParams();
3632 CheckColorSpace(node);
3633 CheckPixelFormat(node);
3634 // only need collect first level node's security & skip layer info
3635 if (nodeId == node.GetFirstLevelNodeId()) {
3636 UpdateSecuritySkipAndProtectedLayersRecord(node);
3637 }
3638 // stop traversal if node keeps static
3639 if (isQuickSkipPreparationEnabled_ && CheckIfSurfaceRenderNodeStatic(node)) {
3640 // node type is mainwindow.
3641 PrepareSubSurfaceNodes(node);
3642 return;
3643 }
3644 // Attension: Updateinfo before info reset
3645 node.StoreMustRenewedInfo();
3646 SetHasSharedTransitionNode(node, false);
3647 node.CleanDstRectChanged();
3648 if (node.IsHardwareEnabledTopSurface()) {
3649 node.ResetSubNodeShouldPaint();
3650 node.ResetChildHardwareEnabledNodes();
3651 }
3652 curContentDirty_ = node.IsContentDirty();
3653 bool dirtyFlag = dirtyFlag_;
3654
3655 RectI prepareClipRect = prepareClipRect_;
3656 bool isQuickSkipPreparationEnabled = isQuickSkipPreparationEnabled_;
3657
3658 // update geoptr with ContextMatrix
3659 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
3660 auto& property = node.GetMutableRenderProperties();
3661 auto& geoPtr = (property.GetBoundsGeometry());
3662 if (geoPtr == nullptr) {
3663 return;
3664 }
3665 // before node update, prepare node's setting by types
3666 PrepareTypesOfSurfaceRenderNodeBeforeUpdate(node);
3667
3668 if (curSurfaceDirtyManager_ == nullptr) {
3669 RS_LOGE("RSUniRenderVisitor::PrepareSurfaceRenderNode %{public}s curSurfaceDirtyManager is nullptr",
3670 node.GetName().c_str());
3671 return;
3672 }
3673
3674 if (node.GetRSSurfaceHandler()->GetBuffer() != nullptr) {
3675 node.SetBufferRelMatrix(RSUniRenderUtil::GetMatrixOfBufferToRelRect(node));
3676 }
3677
3678 auto skipNodeMap = RSMainThread::Instance()->GetCacheCmdSkippedNodes();
3679 // Update node properties, including position (dstrect), OldDirty()
3680 auto parentNode = node.GetParent().lock();
3681 auto rsParent = (parentNode);
3682 if (skipNodeMap.count(nodeId) != 0) {
3683 dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent, dirtyFlag_, prepareClipRect_);
3684 dirtyFlag_ = dirtyFlag;
3685 RS_TRACE_NAME(node.GetName() + " PreparedNodes cacheCmdSkiped");
3686 return;
3687 }
3688
3689 auto rsSurfaceParent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(parentNode);
3690 if (node.IsAppWindow() && rsSurfaceParent && rsSurfaceParent->IsLeashWindow()
3691 && rsSurfaceParent->GetDstRect().IsEmpty()) {
3692 prepareClipRect_ = RectI {0, 0, 0, 0};
3693 }
3694 dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent, dirtyFlag_, prepareClipRect_);
3695
3696 // Calculate the absolute destination rectangle of the node, initialize with absolute bounds rect
3697 auto dstRect = geoPtr->GetAbsRect();
3698 // If the screen is expanded, intersect the destination rectangle with the screen rectangle
3699 dstRect = dstRect.IntersectRect(RectI(curDisplayNode_->GetDisplayOffsetX(), curDisplayNode_->GetDisplayOffsetY(),
3700 screenInfo_.width, screenInfo_.height));
3701 // Remove the offset of the screen
3702 dstRect = RectI(dstRect.left_ - curDisplayNode_->GetDisplayOffsetX(),
3703 dstRect.top_ - curDisplayNode_->GetDisplayOffsetY(), dstRect.GetWidth(), dstRect.GetHeight());
3704 // If the node is a hardware-enabled type, intersect its destination rectangle with the prepare clip rectangle
3705 if (node.IsHardwareEnabledType()) {
3706 dstRect = dstRect.IntersectRect(prepareClipRect_);
3707 }
3708 // Set the destination rectangle of the node
3709 node.SetDstRect(dstRect);
3710
3711 if (node.IsLeashOrMainWindow()) {
3712 // record visible node position for display render node dirtyManager
3713 if (node.ShouldPaint()) {
3714 curDisplayNode_->UpdateSurfaceNodePos(nodeId, node.GetOldDirty());
3715 }
3716
3717 if (node.IsAppWindow()) {
3718 // if update appwindow, its children should not skip
3719 localZOrder_ = 0.0f;
3720 isQuickSkipPreparationEnabled_ = false;
3721 if (isSubSurfaceEnabled_) {
3722 isQuickSkipPreparationEnabled_ = true;
3723 }
3724 node.ResetChildHardwareEnabledNodes();
3725 boundsRect_ = Drawing::Rect(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
3726 frameGravity_ = property.GetFrameGravity();
3727 }
3728 }
3729
3730 // [planning] Remove this after skia is upgraded, the clipRegion is supported
3731 // reset childrenFilterRects
3732 node.ResetChildrenFilterRects();
3733
3734 dirtyFlag_ = dirtyFlag_ || node.GetDstRectChanged();
3735 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3736 if (RSUniRenderUtil::GetRotationDegreeFromMatrix(parentSurfaceNodeMatrix_) % RS_ROTATION_90 != 0) {
3737 isSurfaceRotationChanged_ = true;
3738 doAnimate_ = true;
3739 node.SetAnimateState();
3740 }
3741
3742 bool isSubNodeOfSurfaceInPrepare = isSubNodeOfSurfaceInPrepare_;
3743 if (node.IsLeashOrMainWindow()) {
3744 isSubNodeOfSurfaceInPrepare_ = true;
3745 }
3746 node.UpdateChildrenOutOfRectFlag(false);
3747 // [planning] ShouldPrepareSubnodes would be applied again if condition constraint ensures
3748 PrepareChildren(node);
3749 node.UpdateParentChildrenRect(rsParent);
3750
3751 // restore flags
3752 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3753 dirtyFlag_ = dirtyFlag;
3754 isQuickSkipPreparationEnabled_ = isQuickSkipPreparationEnabled;
3755 prepareClipRect_ = prepareClipRect;
3756 if (node.IsLeashOrMainWindow()) {
3757 isSubNodeOfSurfaceInPrepare_ = isSubNodeOfSurfaceInPrepare;
3758 }
3759
3760 PrepareTypesOfSurfaceRenderNodeAfterUpdate(node);
3761 if (node.GetDstRectChanged() || (node.GetDirtyManager() && node.GetDirtyManager()->IsCurrentFrameDirty())) {
3762 curDisplayNode_->GetDirtySurfaceNodeMap().emplace(nodeId, node.ReinterpretCastTo<RSSurfaceRenderNode>());
3763 }
3764 UpdateSurfaceRenderNodeScale(node);
3765 // Due to the alpha is updated in PrepareChildren, so PrepareChildren
3766 // needs to be done before CheckOpaqueRegionBaseInfo
3767 auto screenRotation = curDisplayNode_->GetRotation();
3768 auto screenRect = RectI(0, 0, screenInfo_.width, screenInfo_.height);
3769 Vector4f cornerRadius;
3770 Vector4f::Max(node.GetWindowCornerRadius(), node.GetGlobalCornerRadius(), cornerRadius);
3771 Vector4<int> dstCornerRadius(static_cast<int>(std::round(cornerRadius.x_)),
3772 static_cast<int>(std::round(cornerRadius.y_)),
3773 static_cast<int>(std::round(cornerRadius.z_)),
3774 static_cast<int>(std::round(cornerRadius.w_)));
3775 auto parent = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node.GetParent().lock());
3776 auto isFocused = node.IsFocusedNode(currentFocusedNodeId_) ||
3777 (parent && parent->IsLeashWindow() && parent->IsFocusedNode(focusedLeashWindowId_));
3778 auto absRect = node.GetDstRect().IntersectRect(node.GetOldDirtyInSurface());
3779 if (!node.CheckOpaqueRegionBaseInfo(
3780 screenRect, absRect, screenRotation, isFocused, dstCornerRadius)
3781 && node.GetSurfaceNodeType() != RSSurfaceNodeType::SELF_DRAWING_NODE) {
3782 node.ResetSurfaceOpaqueRegion(screenRect, absRect, screenRotation, isFocused, dstCornerRadius);
3783 }
3784 node.SetOpaqueRegionBaseInfo(screenRect, absRect, screenRotation, isFocused, dstCornerRadius);
3785 if (node.IsMainWindowType()) {
3786 // Attention: curSurface info would be reset as upper surfaceParent if it has
3787 ResetCurSurfaceInfoAsUpperSurfaceParent(node);
3788 }
3789 }
3790
UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode & node)3791 void RSUniRenderVisitor::UpdateSurfaceRenderNodeScale(RSSurfaceRenderNode& node)
3792 {
3793 if (!node.IsLeashWindow()) {
3794 return;
3795 }
3796 auto& property = node.GetMutableRenderProperties();
3797 auto& geoPtr = (property.GetBoundsGeometry());
3798 if (geoPtr == nullptr) {
3799 return;
3800 }
3801 auto absMatrix = geoPtr->GetAbsMatrix();
3802 bool isScale = false;
3803 if (RSMainThread::Instance()->GetDeviceType() == DeviceType::PC) {
3804 isScale = (!ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_X), 1.f, EPSILON_SCALE) ||
3805 !ROSEN_EQ(absMatrix.Get(Drawing::Matrix::SCALE_Y), 1.f, EPSILON_SCALE));
3806 } else {
3807 bool getMinMaxScales = false;
3808 // scaleFactors[0]-minimum scaling factor, scaleFactors[1]-maximum scaling factor
3809 Drawing::scalar scaleFactors[2];
3810 getMinMaxScales = absMatrix.GetMinMaxScales(scaleFactors);
3811 if (getMinMaxScales) {
3812 isScale = !ROSEN_EQ(scaleFactors[0], 1.f, EPSILON_SCALE) || !ROSEN_EQ(scaleFactors[1], 1.f, EPSILON_SCALE);
3813 }
3814 if (!getMinMaxScales) {
3815 RS_LOGD("getMinMaxScales fail, node:%{public}s %{public}" PRIu64 "", node.GetName().c_str(), node.GetId());
3816 const auto& dstRect = node.GetDstRect();
3817 float dstRectWidth = dstRect.GetWidth();
3818 float dstRectHeight = dstRect.GetHeight();
3819 float boundsWidth = property.GetBoundsWidth();
3820 float boundsHeight = property.GetBoundsHeight();
3821 isScale =
3822 !ROSEN_EQ(std::min(dstRectWidth, dstRectHeight), std::min(boundsWidth, boundsHeight), EPSILON_SCALE) ||
3823 !ROSEN_EQ(std::max(dstRectWidth, dstRectHeight), std::max(boundsWidth, boundsHeight), EPSILON_SCALE);
3824 }
3825 }
3826 node.SetIsScaleInPreFrame(node.IsScale());
3827 node.SetIsScale(isScale);
3828 }
3829
PrepareProxyRenderNode(RSProxyRenderNode & node)3830 void RSUniRenderVisitor::PrepareProxyRenderNode(RSProxyRenderNode& node)
3831 {
3832 // alpha is not affected by dirty flag, always update
3833 node.SetContextAlpha(curAlpha_);
3834 // skip matrix & clipRegion update if not dirty
3835 if (!dirtyFlag_) {
3836 return;
3837 }
3838 auto rsParent = (node.GetParent().lock());
3839 if (rsParent == nullptr) {
3840 return;
3841 }
3842 auto& property = rsParent->GetMutableRenderProperties();
3843 auto& geoPtr = (property.GetBoundsGeometry());
3844
3845 // Context matrix should be relative to the parent surface node, so we need to revert the parentSurfaceNodeMatrix_.
3846 Drawing::Matrix invertMatrix;
3847 Drawing::Matrix contextMatrix = geoPtr->GetAbsMatrix();
3848
3849 if (parentSurfaceNodeMatrix_.Invert(invertMatrix)) {
3850 contextMatrix.PreConcat(invertMatrix);
3851 } else {
3852 ROSEN_LOGE("RSUniRenderVisitor::PrepareProxyRenderNode, invert parentSurfaceNodeMatrix_ failed");
3853 }
3854 node.SetContextMatrix(contextMatrix);
3855
3856 // For now, we only set the clipRegion if the parent node has ClipToBounds set to true.
3857 if (!property.GetClipToBounds()) {
3858 node.SetContextClipRegion(std::nullopt);
3859 } else {
3860 // Maybe we should use prepareClipRect_ and make the clipRegion in device coordinate, but it will be more
3861 // complex to calculate the intersect, and it will make app developers confused.
3862 auto rect = property.GetBoundsRect();
3863 // Context clip region is in the parent node coordinate, so we don't need to map it.
3864 node.SetContextClipRegion(Drawing::Rect(
3865 rect.GetLeft(), rect.GetTop(), rect.GetWidth() + rect.GetLeft(), rect.GetHeight() + rect.GetTop()));
3866 }
3867
3868 // prepare children
3869 PrepareChildren(node);
3870 }
3871
PrepareRootRenderNode(RSRootRenderNode & node)3872 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
3873 {
3874 RS_TRACE_NAME_FMT("RSUniRender::PrepareRootRenderNode:node[%" PRIu64 "] pid[%d] subTreeDirty[%d]",
3875 node.GetId(), ExtractPid(node.GetId()), node.IsSubTreeDirty());
3876 bool dirtyFlag = dirtyFlag_;
3877 auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
3878 auto prepareClipRect = prepareClipRect_;
3879
3880 auto nodeParent = (node.GetParent().lock());
3881 const auto& property = node.GetRenderProperties();
3882 bool geoDirty = property.IsGeoDirty();
3883 auto& geoPtr = (property.GetBoundsGeometry());
3884 auto prevAlpha = curAlpha_;
3885 curAlpha_ *= std::clamp(node.GetRenderProperties().GetAlpha(), 0.f, 1.f);
3886
3887 if (curSurfaceDirtyManager_ == nullptr) {
3888 RS_LOGE("RSUniRenderVisitor::PrepareRootRenderNode curSurfaceDirtyManager is nullptr");
3889 return;
3890 }
3891
3892 if (RSSystemProperties::GetQuickPrepareEnabled()) {
3893 dirtyFlag_ = node.UpdateDrawRectAndDirtyRegion(
3894 *curSurfaceDirtyManager_, dirtyFlag_, prepareClipRect_, parentSurfaceNodeMatrix_);
3895 } else {
3896 dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, nodeParent, dirtyFlag_, prepareClipRect_);
3897 }
3898
3899 if (nodeParent == curSurfaceNode_) {
3900 const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
3901 const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
3902 Drawing::Matrix gravityMatrix;
3903 (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
3904 RectF { 0.0f, 0.0f, boundsRect_.GetWidth(), boundsRect_.GetHeight() },
3905 rootWidth, rootHeight, gravityMatrix);
3906 // Only Apply gravityMatrix when rootNode is dirty
3907 if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
3908 geoPtr->ConcatMatrix(gravityMatrix);
3909 }
3910 }
3911
3912 if (geoPtr != nullptr) {
3913 parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
3914 }
3915
3916 if (RSSystemProperties::GetQuickPrepareEnabled()) {
3917 bool isSubTreeNeedPrepare = node.IsSubTreeNeedPrepare(filterInGlobal_) || ForcePrepareSubTree();
3918 isSubTreeNeedPrepare ? QuickPrepareChildren(node) :
3919 node.SubTreeSkipPrepare(*curSurfaceDirtyManager_, curDirty_, dirtyFlag_, prepareClipRect_);
3920 PostPrepare(node, !isSubTreeNeedPrepare);
3921 } else {
3922 node.UpdateChildrenOutOfRectFlag(false);
3923 PrepareChildren(node);
3924 node.UpdateParentChildrenRect(nodeParent);
3925 }
3926
3927 curAlpha_ = prevAlpha;
3928 parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
3929 dirtyFlag_ = dirtyFlag;
3930 prepareClipRect_ = prepareClipRect;
3931 }
3932
PrepareCanvasRenderNode(RSCanvasRenderNode & node)3933 void RSUniRenderVisitor::PrepareCanvasRenderNode(RSCanvasRenderNode &node)
3934 {
3935 preparedCanvasNodeInCurrentSurface_++;
3936 curContentDirty_ = node.IsContentDirty();
3937 bool dirtyFlag = dirtyFlag_;
3938 RectI prepareClipRect = prepareClipRect_;
3939
3940 auto nodeParent = node.GetParent().lock();
3941 while (nodeParent && nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>() &&
3942 nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>()->GetSurfaceNodeType() ==
3943 RSSurfaceNodeType::SELF_DRAWING_NODE) {
3944 nodeParent = nodeParent->GetParent().lock();
3945 }
3946 if (LIKELY(nodeParent)) {
3947 node.SetIsAncestorDirty(nodeParent->IsDirty() || nodeParent->IsAncestorDirty());
3948 auto parentSurfaceNode = nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>();
3949 if (parentSurfaceNode && parentSurfaceNode->IsLeashWindow()) {
3950 node.SetParentLeashWindow();
3951 }
3952 if (parentSurfaceNode && parentSurfaceNode->IsScbScreen()) {
3953 node.SetParentScbScreen();
3954 }
3955 }
3956 if (curSurfaceDirtyManager_ == nullptr && curDisplayDirtyManager_ == nullptr) {
3957 RS_LOGE("RSUniRenderVisitor::PrepareCanvasRenderNode curXDirtyManager is nullptr");
3958 return;
3959 }
3960 if (node.GetSharedTransitionParam()) {
3961 node.GetMutableRenderProperties().UpdateSandBoxMatrix(parentSurfaceNodeMatrix_);
3962 }
3963 if (isSubNodeOfSurfaceInPrepare_ && curSurfaceNode_ &&
3964 curSurfaceNode_->IsHardwareEnabledTopSurface() && node.ShouldPaint()) {
3965 curSurfaceNode_->SetSubNodeShouldPaint();
3966 }
3967 // if canvasNode is not sub node of surfaceNode, merge the dirtyRegion to curDisplayDirtyManager_
3968 auto& dirtyManager = isSubNodeOfSurfaceInPrepare_ ? curSurfaceDirtyManager_ : curDisplayDirtyManager_;
3969 dirtyFlag_ = node.Update(*dirtyManager, nodeParent, dirtyFlag_, prepareClipRect_);
3970
3971 const auto& property = node.GetRenderProperties();
3972 auto& geoPtr = (property.GetBoundsGeometry());
3973 if (geoPtr == nullptr) {
3974 return;
3975 }
3976 // Dirty Region use abstract coordinate, property of node use relative coordinate
3977 // BoundsRect(if exists) is mapped to absRect_ of RSObjAbsGeometry.
3978 if (property.GetClipToBounds()) {
3979 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->GetAbsRect());
3980 }
3981 // FrameRect(if exists) is mapped to rect using abstract coordinate explicitly by calling MapAbsRect.
3982 if (property.GetClipToFrame()) {
3983 // MapAbsRect do not handle the translation of OffsetX and OffsetY
3984 RectF frameRect{
3985 property.GetFrameOffsetX() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_X),
3986 property.GetFrameOffsetY() * geoPtr->GetAbsMatrix().Get(Drawing::Matrix::SCALE_Y),
3987 property.GetFrameWidth(), property.GetFrameHeight()};
3988 prepareClipRect_ = prepareClipRect_.IntersectRect(geoPtr->MapAbsRect(frameRect));
3989 }
3990
3991 node.UpdateChildrenOutOfRectFlag(false);
3992
3993 if (isSkipCanvasNodeOutOfScreen_ && !isSubNodeOfSurfaceInPrepare_ && !node.HasSubSurface() &&
3994 IsOutOfScreenRegion(geoPtr->GetAbsRect())) {
3995 return;
3996 }
3997
3998 PrepareChildren(node);
3999 // attention: accumulate direct parent's childrenRect
4000 node.UpdateParentChildrenRect(nodeParent);
4001 if (property.GetUseEffect()) {
4002 if (auto directParent = node.GetParent().lock()) {
4003 directParent->SetChildHasVisibleEffect(true);
4004 }
4005 }
4006
4007 node.UpdateEffectRegion(effectRegion_);
4008 if (property.NeedFilter()) {
4009 // filterRects_ is used in RSUniRenderVisitor::CalcDirtyFilterRegion
4010 // When oldDirtyRect of node with filter has intersect with any surfaceNode or displayNode dirtyRegion,
4011 // the whole oldDirtyRect should be render in this vsync.
4012 // Partial rendering of node with filter would cause display problem.
4013 if (auto directParent = node.GetParent().lock()) {
4014 directParent->SetChildHasVisibleFilter(true);
4015 }
4016 if (curSurfaceDirtyManager_ && curSurfaceDirtyManager_->IsTargetForDfx()) {
4017 curSurfaceDirtyManager_->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
4018 DirtyRegionType::FILTER_RECT, node.GetOldDirtyInSurface());
4019 }
4020 if (curSurfaceNode_) {
4021 curSurfaceNode_->UpdateChildrenFilterRects(node.shared_from_this(), node.GetOldDirtyInSurface(),
4022 node.IsFilterCacheValid());
4023 curSurfaceNode_->UpdateFilterNodes(node.shared_from_this());
4024 }
4025 UpdateForegroundFilterCacheWithDirty(node, *dirtyManager);
4026 }
4027 dirtyFlag_ = dirtyFlag;
4028 prepareClipRect_ = prepareClipRect;
4029 #ifdef RS_ENABLE_STACK_CULLING
4030 if (RSSystemProperties::GetViewOcclusionCullingEnabled()) {
4031 node.SetFullSurfaceOpaqueMarks(curSurfaceNode_);
4032 }
4033 #endif
4034 }
4035
PrepareEffectRenderNode(RSEffectRenderNode & node)4036 void RSUniRenderVisitor::PrepareEffectRenderNode(RSEffectRenderNode& node)
4037 {
4038 bool dirtyFlag = dirtyFlag_;
4039 RectI prepareClipRect = prepareClipRect_;
4040 auto effectRegion = effectRegion_;
4041 effectRegion_ = node.InitializeEffectRegion();
4042
4043 UpdateRotationStatusForEffectNode(node);
4044 auto parentNode = node.GetParent().lock();
4045 node.SetVisitedFilterCacheStatus(curSurfaceDirtyManager_->IsCacheableFilterRectEmpty());
4046 dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, parentNode, dirtyFlag_, prepareClipRect_);
4047
4048 node.UpdateChildrenOutOfRectFlag(false);
4049 PrepareChildren(node);
4050 node.UpdateParentChildrenRect(node.GetParent().lock());
4051 node.SetEffectRegion(effectRegion_);
4052
4053 if (node.GetRenderProperties().NeedFilter()) {
4054 // filterRects_ is used in RSUniRenderVisitor::CalcDirtyFilterRegion
4055 // When oldDirtyRect of node with filter has intersect with any surfaceNode or displayNode dirtyRegion,
4056 // the whole oldDirtyRect should be render in this vsync.
4057 // Partial rendering of node with filter would cause display problem.
4058 if (parentNode) {
4059 parentNode->SetChildHasVisibleFilter(true);
4060 }
4061 if (curSurfaceDirtyManager_->IsTargetForDfx()) {
4062 curSurfaceDirtyManager_->UpdateDirtyRegionInfoForDfx(node.GetId(), RSRenderNodeType::CANVAS_NODE,
4063 DirtyRegionType::FILTER_RECT, node.GetOldDirtyInSurface());
4064 }
4065 if (curSurfaceNode_ && effectRegion_.has_value() && !effectRegion_->IsEmpty()) {
4066 RectI filterRect(effectRegion_->GetLeft(), effectRegion_->GetTop(),
4067 effectRegion_->GetWidth(), effectRegion_->GetHeight());
4068 curSurfaceNode_->UpdateChildrenFilterRects(node.shared_from_this(), filterRect,
4069 node.IsFilterCacheValid());
4070 curSurfaceNode_->UpdateFilterNodes(node.shared_from_this());
4071 }
4072 UpdateForegroundFilterCacheWithDirty(node, *curSurfaceDirtyManager_);
4073 }
4074
4075 effectRegion_ = effectRegion;
4076 dirtyFlag_ = dirtyFlag;
4077 prepareClipRect_ = prepareClipRect;
4078 }
4079
DrawDirtyRectForDFX(const RectI & dirtyRect,const Drawing::Color color,const RSPaintStyle fillType,float alpha,int edgeWidth=6,std::string extra)4080 void RSUniRenderVisitor::DrawDirtyRectForDFX(const RectI& dirtyRect, const Drawing::Color color,
4081 const RSPaintStyle fillType, float alpha, int edgeWidth = 6, std::string extra)
4082 {
4083 if (dirtyRect.width_ <= 0 || dirtyRect.height_ <= 0) {
4084 ROSEN_LOGD("DrawDirtyRectForDFX dirty rect is invalid.");
4085 return;
4086 }
4087 ROSEN_LOGD("DrawDirtyRectForDFX current dirtyRect = %{public}s", dirtyRect.ToString().c_str());
4088 auto rect = Drawing::Rect(dirtyRect.left_, dirtyRect.top_,
4089 dirtyRect.left_ + dirtyRect.width_, dirtyRect.top_ + dirtyRect.height_);
4090 std::string position = std::to_string(dirtyRect.left_) + ',' + std::to_string(dirtyRect.top_) + ',' +
4091 std::to_string(dirtyRect.width_) + ',' + std::to_string(dirtyRect.height_) + extra;
4092 const int defaultTextOffsetX = edgeWidth;
4093 const int defaultTextOffsetY = 30; // text position has 30 pixelSize under the Rect
4094 Drawing::Pen rectPen;
4095 Drawing::Brush rectBrush;
4096 std::shared_ptr<Drawing::Typeface> typeFace = nullptr;
4097 // font size: 24
4098 std::shared_ptr<Drawing::TextBlob> textBlob =
4099 Drawing::TextBlob::MakeFromString(position.c_str(), Drawing::Font(typeFace, 24.0f, 1.0f, 0.0f));
4100 if (fillType == RSPaintStyle::STROKE) {
4101 rectPen.SetColor(color);
4102 rectPen.SetAntiAlias(true);
4103 rectPen.SetAlphaF(alpha);
4104 rectPen.SetWidth(edgeWidth);
4105 rectPen.SetJoinStyle(Drawing::Pen::JoinStyle::ROUND_JOIN);
4106 canvas_->AttachPen(rectPen);
4107 } else {
4108 rectBrush.SetColor(color);
4109 rectBrush.SetAntiAlias(true);
4110 rectBrush.SetAlphaF(alpha);
4111 canvas_->AttachBrush(rectBrush);
4112 }
4113 canvas_->DrawRect(rect);
4114 canvas_->DetachPen();
4115 canvas_->DetachBrush();
4116 canvas_->AttachBrush(Drawing::Brush());
4117 canvas_->DrawTextBlob(textBlob.get(), dirtyRect.left_ + defaultTextOffsetX, dirtyRect.top_ + defaultTextOffsetY);
4118 canvas_->DetachBrush();
4119 }
4120
DrawDirtyRegionForDFX(std::vector<RectI> dirtyRects)4121 void RSUniRenderVisitor::DrawDirtyRegionForDFX(std::vector<RectI> dirtyRects)
4122 {
4123 const float fillAlpha = 0.2;
4124 for (const auto& subRect : dirtyRects) {
4125 DrawDirtyRectForDFX(subRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::FILL, fillAlpha);
4126 }
4127 }
4128
DrawCacheRegionForDFX(std::map<NodeId,RectI> & cacheRects)4129 void RSUniRenderVisitor::DrawCacheRegionForDFX(std::map<NodeId, RectI>& cacheRects)
4130 {
4131 for (const auto& [nodeId, subRect] : cacheRects) {
4132 auto iter = cacheRenderNodeIsUpdateMap_.find(nodeId);
4133 if ((iter != cacheRenderNodeIsUpdateMap_.end()) && (iter->second)) {
4134 DrawDirtyRectForDFX(subRect, Drawing::Color::COLOR_RED, RSPaintStyle::FILL, CACHE_UPDATE_FILL_ALPHA);
4135 } else {
4136 DrawDirtyRectForDFX(subRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::FILL, CACHE_FILL_ALPHA);
4137 }
4138 }
4139 }
4140
DrawHwcRegionForDFX(std::vector<std::shared_ptr<RSSurfaceRenderNode>> & hwcNodes)4141 void RSUniRenderVisitor::DrawHwcRegionForDFX(std::vector<std::shared_ptr<RSSurfaceRenderNode>>& hwcNodes)
4142 {
4143 const float fillAlpha = 0.3f;
4144 for (const auto& node : hwcNodes) {
4145 if (node->IsHardwareForcedDisabled() || !IsHardwareComposerEnabled()) {
4146 RSUniRenderUtil::DrawRectForDfx(*canvas_, node->GetDstRect(), Drawing::Color::COLOR_RED, fillAlpha,
4147 node->GetName());
4148 } else {
4149 RSUniRenderUtil::DrawRectForDfx(*canvas_, node->GetDstRect(), Drawing::Color::COLOR_BLUE, fillAlpha,
4150 node->GetName());
4151 }
4152 }
4153 }
4154
DrawAllSurfaceDirtyRegionForDFX(RSDisplayRenderNode & node,const Occlusion::Region & region)4155 void RSUniRenderVisitor::DrawAllSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node, const Occlusion::Region& region)
4156 {
4157 const auto& visibleDirtyRects = region.GetRegionRects();
4158 std::vector<RectI> rects;
4159 for (auto& rect : visibleDirtyRects) {
4160 rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
4161 }
4162 DrawDirtyRegionForDFX(rects);
4163
4164 // draw display dirtyregion with red color
4165 RectI dirtySurfaceRect = node.GetDirtyManager()->GetDirtyRegion();
4166 const float fillAlpha = 0.2;
4167 DrawDirtyRectForDFX(dirtySurfaceRect, Drawing::Color::COLOR_RED, RSPaintStyle::STROKE, fillAlpha);
4168 }
4169
DrawAllSurfaceOpaqueRegionForDFX(RSDisplayRenderNode & node)4170 void RSUniRenderVisitor::DrawAllSurfaceOpaqueRegionForDFX(RSDisplayRenderNode& node)
4171 {
4172 for (auto& it : node.GetCurAllSurfaces()) {
4173 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(it);
4174 if (surfaceNode && surfaceNode->IsMainWindowType()) {
4175 DrawSurfaceOpaqueRegionForDFX(*surfaceNode);
4176 }
4177 }
4178 }
4179
DrawTargetSurfaceVisibleRegionForDFX(RSDisplayRenderNode & node)4180 void RSUniRenderVisitor::DrawTargetSurfaceVisibleRegionForDFX(RSDisplayRenderNode& node)
4181 {
4182 for (auto it = node.GetCurAllSurfaces().rbegin(); it != node.GetCurAllSurfaces().rend(); ++it) {
4183 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4184 if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
4185 continue;
4186 }
4187 if (CheckIfSurfaceTargetedForDFX(surfaceNode->GetName())) {
4188 const auto& visibleRegions = surfaceNode->GetVisibleRegion().GetRegionRects();
4189 std::vector<RectI> rects;
4190 for (auto& rect : visibleRegions) {
4191 rects.emplace_back(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
4192 }
4193 DrawDirtyRegionForDFX(rects);
4194 }
4195 }
4196 }
4197
DrawEffectRenderNodeForDFX()4198 void RSUniRenderVisitor::DrawEffectRenderNodeForDFX()
4199 {
4200 if (effectNodeMapForDfx_.empty()) {
4201 return;
4202 }
4203 const float strokeAlpha = 0.8;
4204 const int strokeWidth = 12;
4205 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
4206 for (const auto& effectNode : effectNodeMapForDfx_) {
4207 auto node = nodeMap.GetRenderNode<RSRenderNode>(effectNode.first);
4208 if (!node) {
4209 continue;
4210 }
4211 auto& geoPtr = node->GetRenderProperties().GetBoundsGeometry();
4212 if (geoPtr == nullptr) {
4213 continue;
4214 }
4215 RectI absRect = geoPtr->GetAbsRect();
4216 // draw effectNode
4217 DrawDirtyRectForDFX(absRect, Drawing::Color::COLOR_BLUE, RSPaintStyle::STROKE, strokeAlpha, strokeWidth);
4218 // draw useEffect nodes
4219 const auto& useEffectRects = effectNode.second.first;
4220 for (const auto& rect : useEffectRects) {
4221 DrawDirtyRectForDFX(rect, Drawing::Color::COLOR_GREEN, RSPaintStyle::STROKE, strokeAlpha, strokeWidth);
4222 }
4223
4224 // draw fallback nodes
4225 const auto fallbackRects = effectNode.second.second;
4226 for (const auto& rect : fallbackRects) {
4227 DrawDirtyRectForDFX(rect, Drawing::Color::COLOR_RED, RSPaintStyle::STROKE, strokeAlpha, strokeWidth);
4228 }
4229 }
4230 }
4231
DrawCurrentRefreshRate(uint32_t currentRefreshRate,uint32_t realtimeRefreshRate,RSDisplayRenderNode & node)4232 void RSUniRenderVisitor::DrawCurrentRefreshRate(
4233 uint32_t currentRefreshRate, uint32_t realtimeRefreshRate, RSDisplayRenderNode& node)
4234 {
4235 std::string info = std::to_string(currentRefreshRate) + " " + std::to_string(realtimeRefreshRate);
4236 auto color = currentRefreshRate <= 60 ? SK_ColorRED : SK_ColorGREEN;
4237 std::shared_ptr<Drawing::Typeface> tf = Drawing::Typeface::MakeFromName("HarmonyOS Sans SC", Drawing::FontStyle());
4238 Drawing::Font font;
4239 font.SetSize(100); // 100:Scalar of setting font size
4240 font.SetTypeface(tf);
4241 std::shared_ptr<Drawing::TextBlob> textBlob = Drawing::TextBlob::MakeFromString(info.c_str(), font);
4242
4243 Drawing::Brush brush;
4244 brush.SetColor(color);
4245 brush.SetAntiAlias(true);
4246 canvas_->AttachBrush(brush);
4247 auto rotation = node.GetScreenRotation();
4248 if (RSSystemProperties::IsFoldScreenFlag() && node.GetScreenId() == 0) {
4249 if (rotation == ScreenRotation::ROTATION_270) {
4250 rotation = ScreenRotation::ROTATION_0;
4251 } else {
4252 rotation = static_cast<ScreenRotation>(static_cast<int>(rotation) + 1);
4253 }
4254 }
4255 if (rotation != ScreenRotation::ROTATION_0) {
4256 auto screenManager = CreateOrGetScreenManager();
4257 auto mainScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
4258 if (rotation == ScreenRotation::ROTATION_90) {
4259 canvas_->Rotate(-RS_ROTATION_90, 0, 0);
4260 canvas_->Translate(-(static_cast<float>(mainScreenInfo.height)), 0);
4261 } else if (rotation == ScreenRotation::ROTATION_180) {
4262 canvas_->Rotate(-RS_ROTATION_180, static_cast<float>(mainScreenInfo.width) / 2, // half of screen width
4263 static_cast<float>(mainScreenInfo.height) / 2); // half of screen height
4264 } else if (rotation == ScreenRotation::ROTATION_270) {
4265 canvas_->Rotate(-RS_ROTATION_270, 0, 0);
4266 canvas_->Translate(0, -(static_cast<float>(mainScreenInfo.width)));
4267 } else {
4268 return;
4269 }
4270 }
4271 canvas_->DrawTextBlob(
4272 textBlob.get(), 100.f, 200.f); // 100.f:Scalar x of drawing TextBlob; 200.f:Scalar y of drawing TextBlob
4273 canvas_->DetachBrush();
4274 }
4275
DrawAndTraceSingleDirtyRegionTypeForDFX(RSSurfaceRenderNode & node,DirtyRegionType dirtyType,bool isDrawn)4276 void RSUniRenderVisitor::DrawAndTraceSingleDirtyRegionTypeForDFX(RSSurfaceRenderNode& node,
4277 DirtyRegionType dirtyType, bool isDrawn)
4278 {
4279 auto dirtyManager = node.GetDirtyManager();
4280 auto matchType = DIRTY_REGION_TYPE_MAP.find(dirtyType);
4281 if (dirtyManager == nullptr || matchType == DIRTY_REGION_TYPE_MAP.end()) {
4282 return;
4283 }
4284 std::map<NodeId, RectI> dirtyInfo;
4285 float fillAlpha = 0.2;
4286 std::map<RSRenderNodeType, std::pair<std::string, SkColor>> nodeConfig = {
4287 {RSRenderNodeType::CANVAS_NODE, std::make_pair("canvas", SK_ColorRED)},
4288 {RSRenderNodeType::SURFACE_NODE, std::make_pair("surface", SK_ColorGREEN)},
4289 };
4290
4291 std::string subInfo;
4292 for (const auto& [nodeType, info] : nodeConfig) {
4293 dirtyManager->GetDirtyRegionInfo(dirtyInfo, nodeType, dirtyType);
4294 subInfo += (" " + info.first + "node amount: " + std::to_string(dirtyInfo.size()));
4295 for (const auto& [nid, rect] : dirtyInfo) {
4296 if (isDrawn) {
4297 DrawDirtyRectForDFX(rect, info.second, RSPaintStyle::STROKE, fillAlpha);
4298 }
4299 }
4300 }
4301 RS_TRACE_NAME("DrawAndTraceSingleDirtyRegionTypeForDFX target surface node " + node.GetName() + " - id[" +
4302 std::to_string(node.GetId()) + "] has dirtytype " + matchType->second + subInfo);
4303 ROSEN_LOGD("DrawAndTraceSingleDirtyRegionTypeForDFX target surface node %{public}s, id[%{public}" PRIu64 "]"
4304 "has dirtytype %{public}s%{public}s",
4305 node.GetName().c_str(), node.GetId(), matchType->second.c_str(), subInfo.c_str());
4306 }
4307
DrawDetailedTypesOfDirtyRegionForDFX(RSSurfaceRenderNode & node)4308 bool RSUniRenderVisitor::DrawDetailedTypesOfDirtyRegionForDFX(RSSurfaceRenderNode& node)
4309 {
4310 if (dirtyRegionDebugType_ < DirtyRegionDebugType::CUR_DIRTY_DETAIL_ONLY_TRACE) {
4311 return false;
4312 }
4313 if (dirtyRegionDebugType_ == DirtyRegionDebugType::CUR_DIRTY_DETAIL_ONLY_TRACE) {
4314 auto i = DirtyRegionType::UPDATE_DIRTY_REGION;
4315 for (; i < DirtyRegionType::TYPE_AMOUNT; i = (DirtyRegionType)(i + 1)) {
4316 DrawAndTraceSingleDirtyRegionTypeForDFX(node, i, false);
4317 }
4318 return true;
4319 }
4320 const std::map<DirtyRegionDebugType, DirtyRegionType> DIRTY_REGION_DEBUG_TYPE_MAP {
4321 { DirtyRegionDebugType::UPDATE_DIRTY_REGION, DirtyRegionType::UPDATE_DIRTY_REGION },
4322 { DirtyRegionDebugType::OVERLAY_RECT, DirtyRegionType::OVERLAY_RECT },
4323 { DirtyRegionDebugType::FILTER_RECT, DirtyRegionType::FILTER_RECT },
4324 { DirtyRegionDebugType::SHADOW_RECT, DirtyRegionType::SHADOW_RECT },
4325 { DirtyRegionDebugType::PREPARE_CLIP_RECT, DirtyRegionType::PREPARE_CLIP_RECT },
4326 { DirtyRegionDebugType::REMOVE_CHILD_RECT, DirtyRegionType::REMOVE_CHILD_RECT },
4327 { DirtyRegionDebugType::RENDER_PROPERTIES_RECT, DirtyRegionType::RENDER_PROPERTIES_RECT },
4328 { DirtyRegionDebugType::CANVAS_NODE_SKIP_RECT, DirtyRegionType::CANVAS_NODE_SKIP_RECT },
4329 { DirtyRegionDebugType::OUTLINE_RECT, DirtyRegionType::OUTLINE_RECT },
4330 };
4331 auto matchType = DIRTY_REGION_DEBUG_TYPE_MAP.find(dirtyRegionDebugType_);
4332 if (matchType != DIRTY_REGION_DEBUG_TYPE_MAP.end()) {
4333 DrawAndTraceSingleDirtyRegionTypeForDFX(node, matchType->second);
4334 }
4335 return true;
4336 }
4337
DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderNode & node)4338 void RSUniRenderVisitor::DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderNode& node)
4339 {
4340 const auto& opaqueRegionRects = node.GetOpaqueRegion().GetRegionRects();
4341 for (const auto &subRect: opaqueRegionRects) {
4342 DrawDirtyRectForDFX(subRect.ToRectI(), Drawing::Color::COLOR_GREEN,
4343 RSPaintStyle::FILL, 0.2f, 0);
4344 }
4345 }
4346
ProcessShadowFirst(RSRenderNode & node,bool inSubThread)4347 void RSUniRenderVisitor::ProcessShadowFirst(RSRenderNode& node, bool inSubThread)
4348 {
4349 if (node.GetRenderProperties().GetUseShadowBatching()) {
4350 auto children = node.GetSortedChildren();
4351 for (auto& child : *children) {
4352 if (auto node = child->ReinterpretCastTo<RSCanvasRenderNode>()) {
4353 node->ProcessShadowBatching(*canvas_);
4354 }
4355 }
4356 }
4357 }
4358
CheckSkipRepeatShadow(RSRenderNode & node,const bool resetStatus)4359 void RSUniRenderVisitor::CheckSkipRepeatShadow(RSRenderNode& node, const bool resetStatus)
4360 {
4361 // In normal process, if shadow has drawn in drawCacheWithBlur, no need to draw again in children node
4362 // not comming from drawCacheWithBlur and updateCacheProcess, child has shadow,skip draw shadow child later
4363 if (!drawCacheWithBlur_ && !notRunCheckAndSetNodeCacheType_ && !allCacheFilterRects_[node.GetId()].empty() &&
4364 node.ChildHasVisibleFilter() && updateCacheProcessCnt_ == 0) {
4365 if (resetStatus) {
4366 RS_TRACE_NAME("status reset");
4367 noNeedTodrawShadowAgain_ = false;
4368 return;
4369 }
4370 noNeedTodrawShadowAgain_ = true;
4371 }
4372 }
4373
SetNodeSkipShadow(std::shared_ptr<RSRenderNode> node,const bool resetStatus)4374 void RSUniRenderVisitor::SetNodeSkipShadow(std::shared_ptr<RSRenderNode> node, const bool resetStatus)
4375 {
4376 // skip shadow drawing in updateCacheProcess,it will draw in drawCacheWithBlur
4377 // and skip shadow repeat drawing in normal process
4378 if (!drawCacheWithBlur_ && node->GetRenderProperties().GetShadowColorStrategy() !=
4379 SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE &&
4380 (updateCacheProcessCnt_ != 0 || noNeedTodrawShadowAgain_)) {
4381 ROSEN_LOGD("skip draw shadow and text repeatly");
4382 if (resetStatus) {
4383 node->GetMutableRenderProperties().SetNeedSkipShadow(false);
4384 return;
4385 }
4386 node->GetMutableRenderProperties().SetNeedSkipShadow(true);
4387 }
4388 }
4389
ProcessChildren(RSRenderNode & node)4390 void RSUniRenderVisitor::ProcessChildren(RSRenderNode& node)
4391 {
4392 RS_LOGE("It is update to DrawableV2 to process node now!!");
4393 }
4394
ProcessChildrenForScreenRecordingOptimization(RSDisplayRenderNode & node,NodeId rootIdOfCaptureWindow)4395 void RSUniRenderVisitor::ProcessChildrenForScreenRecordingOptimization(
4396 RSDisplayRenderNode& node, NodeId rootIdOfCaptureWindow)
4397 {
4398 RS_LOGE("It is update to DrawableV2 to process node now!!");
4399 }
4400
ProcessChildInner(RSRenderNode & node,const RSRenderNode::SharedPtr child)4401 void RSUniRenderVisitor::ProcessChildInner(RSRenderNode& node, const RSRenderNode::SharedPtr child)
4402 {
4403 RS_LOGE("It is update to DrawableV2 to process node now!!");
4404 }
4405
UpdateVirtualScreenWhiteListRootId(const RSRenderNode::SharedPtr & node)4406 void RSUniRenderVisitor::UpdateVirtualScreenWhiteListRootId(const RSRenderNode::SharedPtr& node)
4407 {
4408 if (node->GetType() == RSRenderNodeType::SURFACE_NODE && virtualScreenWhiteListRootId_ == INVALID_NODEID &&
4409 screenInfo_.whiteList.find(node->GetId()) != screenInfo_.whiteList.end()) {
4410 // limit surface node is to reduce whiteList set times
4411 // don't update if node's parent is in whiteList
4412 virtualScreenWhiteListRootId_ = node->GetId();
4413 } else if (virtualScreenWhiteListRootId_ == node->GetId()) {
4414 // restore virtualScreenWhiteListRootId_ only by itself
4415 virtualScreenWhiteListRootId_ = INVALID_NODEID;
4416 }
4417 }
4418
ProcessDisplayRenderNode(RSDisplayRenderNode & node)4419 void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node)
4420 {
4421 RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
4422 }
4423
SwitchColorFilterDrawing(int currentSaveCount)4424 void RSUniRenderVisitor::SwitchColorFilterDrawing(int currentSaveCount)
4425 {
4426 ColorFilterMode colorFilterMode = renderEngine_->GetColorFilterMode();
4427 if (colorFilterMode >= ColorFilterMode::INVERT_COLOR_ENABLE_MODE &&
4428 colorFilterMode <= ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE) {
4429 RS_LOGD("RsDebug RSBaseRenderEngine::SetColorFilterModeToPaint mode:%{public}d",
4430 static_cast<int32_t>(colorFilterMode));
4431 Drawing::Brush brush;
4432 RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, brush);
4433 #if defined (RS_ENABLE_GL) || defined (RS_ENABLE_VK)
4434 #ifdef NEW_RENDER_CONTEXT
4435 RSTagTracker tagTracker(
4436 renderEngine_->GetDrawingContext()->GetDrawingContext(),
4437 RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
4438 #else
4439 RSTagTracker tagTracker(
4440 renderEngine_->GetRenderContext()->GetDrGPUContext(),
4441 RSTagTracker::TAG_SAVELAYER_COLOR_FILTER);
4442 #endif
4443 #endif
4444 Drawing::SaveLayerOps slr(nullptr, &brush, Drawing::SaveLayerOps::INIT_WITH_PREVIOUS);
4445 canvas_->SaveLayer(slr);
4446 canvas_->RestoreToCount(currentSaveCount);
4447 }
4448 }
4449
AssignGlobalZOrderAndCreateLayer(std::vector<std::shared_ptr<RSSurfaceRenderNode>> & nodesInZOrder)4450 void RSUniRenderVisitor::AssignGlobalZOrderAndCreateLayer(
4451 std::vector<std::shared_ptr<RSSurfaceRenderNode>>& nodesInZOrder)
4452 {
4453 if (!IsHardwareComposerEnabled()) {
4454 return;
4455 }
4456 if (hardwareEnabledNodes_.empty()) {
4457 return;
4458 }
4459 for (auto& appWindowNode : nodesInZOrder) {
4460 // first, sort app window node's child surfaceView by local zOrder
4461 auto& childHardwareEnabledNodes =
4462 const_cast<std::vector<std::weak_ptr<RSSurfaceRenderNode>>&>(appWindowNode->GetChildHardwareEnabledNodes());
4463 for (auto iter = childHardwareEnabledNodes.begin(); iter != childHardwareEnabledNodes.end();) {
4464 auto childNode = iter->lock();
4465 if (!childNode || !childNode->IsOnTheTree()) {
4466 iter = childHardwareEnabledNodes.erase(iter);
4467 continue;
4468 }
4469 auto surfaceHandler = childNode->GetMutableRSSurfaceHandler();
4470 if (surfaceHandler->GetBuffer() != nullptr &&
4471 (!childNode->IsHardwareForcedDisabled() || childNode->GetProtectedLayer())) {
4472 // SetGlobalZOrder here to ensure zOrder committed to composer is continuous
4473 surfaceHandler->SetGlobalZOrder(globalZOrder_++);
4474 RS_LOGD("createLayer: %{public}" PRIu64 "", childNode->GetId());
4475 processor_->ProcessSurface(*childNode);
4476 }
4477 ++iter;
4478 }
4479 }
4480 }
4481
AddOverDrawListener(std::unique_ptr<RSRenderFrame> & renderFrame,std::shared_ptr<RSCanvasListener> & overdrawListener)4482 void RSUniRenderVisitor::AddOverDrawListener(std::unique_ptr<RSRenderFrame>& renderFrame,
4483 std::shared_ptr<RSCanvasListener>& overdrawListener)
4484 {
4485 if (renderFrame == nullptr) {
4486 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: renderFrame is nullptr");
4487 return;
4488 }
4489 #if defined(NEW_RENDER_CONTEXT)
4490 auto renderSurface = renderFrame->GetSurface();
4491 if (renderSurface == nullptr) {
4492 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: renderSurface is nullptr");
4493 return;
4494 }
4495 RS_OPTIONAL_TRACE_BEGIN("RSUniRender::GetSurface");
4496 auto drSurface = renderSurface->GetSurface();
4497 RS_OPTIONAL_TRACE_END();
4498 if (drSurface == nullptr) {
4499 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: drSurface is null");
4500 return;
4501 }
4502 if (drSurface->GetCanvas() == nullptr) {
4503 ROSEN_LOGE("drSurface.getCanvas is null.");
4504 return;
4505 }
4506 #else
4507 if (renderFrame->GetFrame() == nullptr) {
4508 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: RSSurfaceFrame is nullptr");
4509 return;
4510 }
4511 RS_OPTIONAL_TRACE_BEGIN("RSUniRender::GetSurface");
4512 auto drSurface = renderFrame->GetFrame()->GetSurface();
4513 RS_OPTIONAL_TRACE_END();
4514 if (drSurface == nullptr) {
4515 RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: drSurface is null");
4516 return;
4517 }
4518 if (drSurface->GetCanvas() == nullptr) {
4519 ROSEN_LOGE("drSurface.getCanvas is null.");
4520 return;
4521 }
4522 #endif
4523 canvas_ = std::make_shared<RSPaintFilterCanvas>(drSurface.get());
4524 }
4525
IsNotDirtyHardwareEnabledTopSurface(std::shared_ptr<RSSurfaceRenderNode> & node) const4526 bool RSUniRenderVisitor::IsNotDirtyHardwareEnabledTopSurface(std::shared_ptr<RSSurfaceRenderNode>& node) const
4527 {
4528 if (!node->IsHardwareEnabledTopSurface()) {
4529 return false;
4530 }
4531 // If the pointer is dirty in last frame but not in current, when gpu -> hardware composer.
4532 // It should also calc global dirty in current frame.
4533 node->SetNodeDirty(isHardwareForcedDisabled_ || node->HasSubNodeShouldPaint() ||
4534 !node->IsLastFrameHardwareEnabled());
4535 return !node->IsNodeDirty();
4536 }
4537
ClipRegion(std::shared_ptr<Drawing::Canvas> canvas,const Drawing::Region & region) const4538 void RSUniRenderVisitor::ClipRegion(std::shared_ptr<Drawing::Canvas> canvas, const Drawing::Region& region) const
4539 {
4540 if (region.IsEmpty()) {
4541 // [planning] Remove this after frame buffer can cancel
4542 canvas->ClipRect(Drawing::Rect());
4543 } else if (region.IsRect()) {
4544 canvas->ClipRegion(region);
4545 } else {
4546 RS_TRACE_NAME("RSUniRenderVisitor: clipPath");
4547 #ifdef RS_ENABLE_VK
4548 if (RSSystemProperties::IsUseVulkan()) {
4549 canvas->ClipRegion(region);
4550 } else {
4551 Drawing::Path dirtyPath;
4552 region.GetBoundaryPath(&dirtyPath);
4553 canvas->ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
4554 }
4555 #else
4556 Drawing::Path dirtyPath;
4557 region.GetBoundaryPath(&dirtyPath);
4558 canvas->ClipPath(dirtyPath, Drawing::ClipOp::INTERSECT, true);
4559 #endif
4560 }
4561 }
4562
CalcDirtyDisplayRegion(std::shared_ptr<RSDisplayRenderNode> & node)4563 void RSUniRenderVisitor::CalcDirtyDisplayRegion(std::shared_ptr<RSDisplayRenderNode>& node)
4564 {
4565 RS_OPTIONAL_TRACE_FUNC();
4566 auto displayDirtyManager = node->GetDirtyManager();
4567 for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
4568 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4569 if (surfaceNode == nullptr) {
4570 continue;
4571 }
4572 if (IsNotDirtyHardwareEnabledTopSurface(surfaceNode)) {
4573 continue;
4574 }
4575 auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
4576 if (isUIFirst_ && surfaceDirtyManager->IsCurrentFrameDirty()) {
4577 curDisplayNode_->GetDirtySurfaceNodeMap().emplace(
4578 surfaceNode->GetId(), surfaceNode->ReinterpretCastTo<RSSurfaceRenderNode>());
4579 }
4580 RectI surfaceDirtyRect = surfaceDirtyManager->GetCurrentFrameDirtyRegion();
4581 if (surfaceNode->IsTransparent()) {
4582 // Handles the case of transparent surface, merge transparent dirty rect
4583 RectI transparentDirtyRect = surfaceNode->GetDstRect().IntersectRect(surfaceDirtyRect);
4584 if (!transparentDirtyRect.IsEmpty()) {
4585 RS_OPTIONAL_TRACE_NAME_FMT("CalcDirtyDisplayRegion merge transparent dirty rect %s rect %s",
4586 surfaceNode->GetName().c_str(), transparentDirtyRect.ToString().c_str());
4587 displayDirtyManager->MergeDirtyRect(transparentDirtyRect);
4588 }
4589 }
4590
4591 if (surfaceNode->GetZorderChanged()) {
4592 // Zorder changed case, merge surface dest Rect
4593 RS_LOGD("CalcDirtyDisplayRegion merge GetZorderChanged %{public}s rect %{public}s",
4594 surfaceNode->GetName().c_str(), surfaceNode->GetDstRect().ToString().c_str());
4595 displayDirtyManager->MergeDirtyRect(surfaceNode->GetDstRect());
4596 }
4597
4598 RectI lastFrameSurfacePos = node->GetLastFrameSurfacePos(surfaceNode->GetId());
4599 RectI currentFrameSurfacePos = node->GetCurrentFrameSurfacePos(surfaceNode->GetId());
4600 if (surfaceNode->GetAnimateState() || lastFrameSurfacePos != currentFrameSurfacePos) {
4601 RS_LOGD("CalcDirtyDisplayRegion merge surface pos changed %{public}s lastFrameRect %{public}s"
4602 " currentFrameRect %{public}s", surfaceNode->GetName().c_str(), lastFrameSurfacePos.ToString().c_str(),
4603 currentFrameSurfacePos.ToString().c_str());
4604 if (!lastFrameSurfacePos.IsEmpty()) {
4605 displayDirtyManager->MergeDirtyRect(lastFrameSurfacePos);
4606 }
4607 if (!currentFrameSurfacePos.IsEmpty()) {
4608 displayDirtyManager->MergeDirtyRect(currentFrameSurfacePos);
4609 }
4610 }
4611
4612 bool isShadowDisappear =
4613 !surfaceNode->GetRenderProperties().IsShadowValid() && surfaceNode->IsShadowValidLastFrame();
4614 if (surfaceNode->GetRenderProperties().IsShadowValid() || isShadowDisappear) {
4615 RectI shadowDirtyRect = surfaceNode->GetOldDirtyInSurface().IntersectRect(surfaceDirtyRect);
4616 // There are two situation here:
4617 // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
4618 // surfaceDirtyRect == surfaceNode->GetOldDirtyInSurface()
4619 // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
4620 // surfaceDirtyRect > surfaceNode->GetOldDirtyInSurface()
4621 // So we should always merge surfaceDirtyRect here.
4622 if (!shadowDirtyRect.IsEmpty()) {
4623 displayDirtyManager->MergeDirtyRect(surfaceDirtyRect);
4624 RS_LOGD("CalcDirtyDisplayRegion merge ShadowValid %{public}s rect %{public}s",
4625 surfaceNode->GetName().c_str(), surfaceDirtyRect.ToString().c_str());
4626 }
4627 if (isShadowDisappear) {
4628 surfaceNode->SetShadowValidLastFrame(false);
4629 }
4630 }
4631 }
4632 std::vector<RectI> surfaceChangedRects = node->GetSurfaceChangedRects();
4633 for (auto& surfaceChangedRect : surfaceChangedRects) {
4634 RS_LOGD("CalcDirtyDisplayRegion merge Surface closed %{public}s", surfaceChangedRect.ToString().c_str());
4635 if (!surfaceChangedRect.IsEmpty()) {
4636 displayDirtyManager->MergeDirtyRect(surfaceChangedRect);
4637 }
4638 }
4639 if (RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
4640 RectI tempRect = {100, 100, 500, 200}; // setDirtyRegion for RealtimeRefreshRate
4641 displayDirtyManager->MergeDirtyRect(tempRect, true); // true:debugRect for dislplayNode skip
4642 }
4643
4644 #ifdef RS_PROFILER_ENABLED
4645 RS_LOGD("CalcDirtyRegion RSSystemProperties::GetFullDirtyScreenEnabled()");
4646 auto resolution = RSCaptureRecorder::GetInstance().GetDirtyRect(screenInfo_.width, screenInfo_.height);
4647 displayDirtyManager->MergeDirtyRect(RectI { 0, 0, resolution.first, resolution.second });
4648 #endif
4649 }
4650
MergeDirtyRectIfNeed(std::shared_ptr<RSSurfaceRenderNode> appNode,std::shared_ptr<RSSurfaceRenderNode> hwcNode)4651 void RSUniRenderVisitor::MergeDirtyRectIfNeed(std::shared_ptr<RSSurfaceRenderNode> appNode,
4652 std::shared_ptr<RSSurfaceRenderNode> hwcNode)
4653 {
4654 if ((hwcNode->IsLastFrameHardwareEnabled() || hwcNode->GetRSSurfaceHandler()->IsCurrentFrameBufferConsumed()) &&
4655 appNode && appNode->GetDirtyManager()) {
4656 appNode->GetDirtyManager()->MergeDirtyRect(hwcNode->GetDstRect());
4657 curDisplayNode_->GetDirtySurfaceNodeMap().emplace(appNode->GetId(), appNode);
4658 }
4659 }
4660
UpdateHardwareEnableList(std::vector<RectI> & filterRects,std::vector<SurfaceDirtyMgrPair> & validHwcNodes)4661 RectI RSUniRenderVisitor::UpdateHardwareEnableList(std::vector<RectI>& filterRects,
4662 std::vector<SurfaceDirtyMgrPair>& validHwcNodes)
4663 {
4664 if (validHwcNodes.empty() || filterRects.empty()) {
4665 return RectI();
4666 }
4667 // remove invisible surface since occlusion
4668 // check intersected parts
4669 RectI filterDirty;
4670 for (auto iter = validHwcNodes.begin(); iter != validHwcNodes.end(); ++iter) {
4671 auto childNode = iter->first;
4672 auto childDirtyRect = childNode->GetDstRect();
4673 bool isIntersected = false;
4674 // remove invisible surface since occlusion
4675 for (auto& filterRect : filterRects) {
4676 if (!childDirtyRect.IntersectRect(filterRect).IsEmpty()) {
4677 filterDirty = filterDirty.JoinRect(filterRect);
4678 isIntersected = true;
4679 }
4680 }
4681 if (isIntersected) {
4682 childNode->SetHardwareForcedDisabledStateByFilter(true);
4683 auto node = iter->second;
4684 MergeDirtyRectIfNeed(iter->second, childNode);
4685 iter = validHwcNodes.erase(iter);
4686 iter--;
4687 }
4688 }
4689 return filterDirty;
4690 }
4691
UpdateHardwareChildNodeStatus(std::shared_ptr<RSSurfaceRenderNode> & node,std::vector<SurfaceDirtyMgrPair> & curHwcEnabledNodes)4692 void RSUniRenderVisitor::UpdateHardwareChildNodeStatus(std::shared_ptr<RSSurfaceRenderNode>& node,
4693 std::vector<SurfaceDirtyMgrPair>& curHwcEnabledNodes)
4694 {
4695 // remove invisible surface since occlusion
4696 auto visibleRegion = node->GetVisibleRegion();
4697 for (auto subNode : node->GetChildHardwareEnabledNodes()) {
4698 auto childNode = subNode.lock();
4699 if (!childNode) {
4700 continue;
4701 }
4702 // recover disabled state before update
4703 childNode->SetHardwareForcedDisabledStateByFilter(false);
4704 if (!visibleRegion.IsIntersectWith(Occlusion::Rect(childNode->GetOldDirtyInSurface()))) {
4705 continue;
4706 }
4707 bool isIntersected = false;
4708 if (!isPhone_ || childNode->GetAncoForceDoDirect()) {
4709 curHwcEnabledNodes.emplace_back(std::make_pair(subNode, node));
4710 continue;
4711 }
4712 for (auto &hwcNode: curHwcEnabledNodes) {
4713 if (childNode->GetDstRect().Intersect(hwcNode.first->GetDstRect())) {
4714 childNode->SetHardwareForcedDisabledStateByFilter(true);
4715 isIntersected = true;
4716 break;
4717 }
4718 }
4719 if (!isIntersected) {
4720 curHwcEnabledNodes.emplace_back(std::make_pair(subNode, node));
4721 }
4722 }
4723 }
4724
UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode> & node,std::vector<SurfaceDirtyMgrPair> & prevHwcEnabledNodes,std::shared_ptr<RSDirtyRegionManager> & displayDirtyManager)4725 void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode>& node,
4726 std::vector<SurfaceDirtyMgrPair>& prevHwcEnabledNodes,
4727 std::shared_ptr<RSDirtyRegionManager>& displayDirtyManager)
4728 {
4729 if (!IsHardwareComposerEnabled()) {
4730 return;
4731 }
4732 if (node == nullptr || !node->IsAppWindow() || node->GetDirtyManager() == nullptr ||
4733 displayDirtyManager == nullptr) {
4734 return;
4735 }
4736 auto dirtyManager = node->GetDirtyManager();
4737 auto filterRects = node->GetChildrenNeedFilterRectsWithoutCacheValid();
4738 // collect valid hwc surface which is not intersected with filterRects
4739 std::vector<SurfaceDirtyMgrPair> curHwcEnabledNodes;
4740 UpdateHardwareChildNodeStatus(node, curHwcEnabledNodes);
4741
4742 // Within App: disable hwc if intersect with filterRects
4743 dirtyManager->MergeDirtyRect(UpdateHardwareEnableList(filterRects, curHwcEnabledNodes));
4744 // Among App: disable lower hwc layers if intersect with upper transparent appWindow
4745 if (node->IsTransparent()) {
4746 if (node->GetRenderProperties().NeedFilter()) {
4747 // Attention: if transparent appwindow needs filter, only need to check itself
4748 filterRects = {node->GetDstRect()};
4749 }
4750 // In case of transparent window, filterRects need hwc surface's content
4751 RectI globalTransDirty = UpdateHardwareEnableList(filterRects, prevHwcEnabledNodes);
4752 displayDirtyManager->MergeDirtyRect(globalTransDirty);
4753 dirtyManager->MergeDirtyRect(globalTransDirty);
4754 }
4755 // erase from curHwcEnabledNodes if app node has no container window and its hwc node intersects with hwc below
4756 if (!node->HasContainerWindow() && !curHwcEnabledNodes.empty() && !prevHwcEnabledNodes.empty()) {
4757 for (auto iter = curHwcEnabledNodes.begin(); iter != curHwcEnabledNodes.end(); ++iter) {
4758 for (auto& prevNode : prevHwcEnabledNodes) {
4759 if (!iter->first->GetDstRect().IntersectRect(prevNode.first->GetDstRect()).IsEmpty()) {
4760 iter->first->SetHardwareForcedDisabledStateByFilter(true);
4761 MergeDirtyRectIfNeed(iter->second, iter->first);
4762 iter = curHwcEnabledNodes.erase(iter);
4763 iter--;
4764 break;
4765 }
4766 }
4767 }
4768 }
4769 if (!curHwcEnabledNodes.empty()) {
4770 prevHwcEnabledNodes.insert(prevHwcEnabledNodes.end(), curHwcEnabledNodes.begin(), curHwcEnabledNodes.end());
4771 }
4772 }
4773
CalcDirtyRegionForFilterNode(const RectI & filterRect,std::shared_ptr<RSSurfaceRenderNode> & currentSurfaceNode,std::shared_ptr<RSDisplayRenderNode> & displayNode)4774 void RSUniRenderVisitor::CalcDirtyRegionForFilterNode(const RectI& filterRect,
4775 std::shared_ptr<RSSurfaceRenderNode>& currentSurfaceNode,
4776 std::shared_ptr<RSDisplayRenderNode>& displayNode)
4777 {
4778 auto displayDirtyManager = displayNode->GetDirtyManager();
4779 auto currentSurfaceDirtyManager = currentSurfaceNode->GetDirtyManager();
4780 if (displayDirtyManager == nullptr || currentSurfaceDirtyManager == nullptr) {
4781 return;
4782 }
4783
4784 RectI displayDirtyRect = displayDirtyManager->GetCurrentFrameDirtyRegion();
4785 RectI currentSurfaceDirtyRect = currentSurfaceDirtyManager->GetCurrentFrameDirtyRegion();
4786 bool displayDirtyIntersectRectFilter = !displayDirtyRect.IntersectRect(filterRect).IsEmpty();
4787 bool surfaceDirtyIntersectRectFilter = !currentSurfaceDirtyRect.IntersectRect(filterRect).IsEmpty();
4788 if (displayDirtyIntersectRectFilter || surfaceDirtyIntersectRectFilter) {
4789 currentSurfaceDirtyManager->MergeDirtyRect(filterRect);
4790 if (!currentSurfaceNode->IsTransparent()) {
4791 Occlusion::Region filterRegion(Occlusion::Rect(filterRect.GetLeft(), filterRect.GetTop(),
4792 filterRect.GetRight(), filterRect.GetBottom()));
4793 if (!filterRegion.Sub(currentSurfaceNode->GetOpaqueRegion()).IsEmpty()) {
4794 displayDirtyManager->MergeDirtyRect(filterRect);
4795 return;
4796 }
4797 }
4798 }
4799
4800 if (currentSurfaceNode->IsTransparent()) {
4801 if (displayDirtyIntersectRectFilter) {
4802 displayDirtyManager->MergeDirtyRect(filterRect);
4803 return;
4804 }
4805 // If currentSurfaceNode is transparent and displayDirtyRect is not intersect with filterRect,
4806 // We should check whether window below currentSurfaceNode has dirtyRect intersect with filterRect.
4807 for (auto belowSurface = displayNode->GetCurAllSurfaces().begin();
4808 belowSurface != displayNode->GetCurAllSurfaces().end(); ++belowSurface) {
4809 auto belowSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*belowSurface);
4810 if (belowSurfaceNode == currentSurfaceNode) {
4811 break;
4812 }
4813 if (belowSurfaceNode == nullptr || !belowSurfaceNode->IsAppWindow()) {
4814 continue;
4815 }
4816 auto belowSurfaceDirtyManager = belowSurfaceNode->GetDirtyManager();
4817 RectI belowDirtyRect =
4818 belowSurfaceDirtyManager ? belowSurfaceDirtyManager->GetCurrentFrameDirtyRegion() : RectI{0, 0, 0, 0};
4819 if (belowDirtyRect.IsEmpty()) {
4820 continue;
4821 }
4822 // To minimize dirtyRect, only filterRect has intersect with both visibleRegion and dirtyRect
4823 // of window below, we add filterRect to displayDirtyRect and currentSurfaceDirtyRect.
4824 if (belowSurfaceNode->GetVisibleRegion().IsIntersectWith(filterRect) &&
4825 !belowDirtyRect.IntersectRect(filterRect).IsEmpty()) {
4826 displayDirtyManager->MergeDirtyRect(filterRect);
4827 currentSurfaceDirtyManager->MergeDirtyRect(filterRect);
4828 break;
4829 }
4830 }
4831 }
4832 }
4833
CalcChildFilterNodeDirtyRegion(std::shared_ptr<RSSurfaceRenderNode> & currentSurfaceNode,std::shared_ptr<RSDisplayRenderNode> & displayNode)4834 void RSUniRenderVisitor::CalcChildFilterNodeDirtyRegion(std::shared_ptr<RSSurfaceRenderNode>& currentSurfaceNode,
4835 std::shared_ptr<RSDisplayRenderNode>& displayNode)
4836 {
4837 if (currentSurfaceNode == nullptr || displayNode == nullptr) {
4838 return;
4839 }
4840 auto filterRects = currentSurfaceNode->GetChildrenNeedFilterRects();
4841 auto filterNodes = currentSurfaceNode->GetChildrenFilterNodes();
4842 if (currentSurfaceNode->IsAppWindow() && !filterRects.empty()) {
4843 needFilter_ = needFilter_ || !currentSurfaceNode->IsStaticCached();
4844 for (size_t i = 0; i < filterNodes.size(); i++) {
4845 auto filterRectsCacheValidNow = filterNodes[i]->IsFilterCacheValid();
4846 // if child filter node has filter cache, no need to be added into dirtyregion
4847 // only support background filter cache valid and no pixelstretch node now
4848 if (isCacheBlurPartialRenderEnabled_ && filterRectsCacheValidNow &&
4849 !filterNodes[i]->GetRenderProperties().GetPixelStretch().has_value()) {
4850 continue;
4851 }
4852 CalcDirtyRegionForFilterNode(filterRects[i], currentSurfaceNode, displayNode);
4853 }
4854 }
4855 }
4856
CalcSurfaceFilterNodeDirtyRegion(std::shared_ptr<RSSurfaceRenderNode> & currentSurfaceNode,std::shared_ptr<RSDisplayRenderNode> & displayNode)4857 void RSUniRenderVisitor::CalcSurfaceFilterNodeDirtyRegion(std::shared_ptr<RSSurfaceRenderNode>& currentSurfaceNode,
4858 std::shared_ptr<RSDisplayRenderNode>& displayNode)
4859 {
4860 if (currentSurfaceNode == nullptr || displayNode == nullptr) {
4861 return;
4862 }
4863 if (currentSurfaceNode->GetRenderProperties().NeedFilter()) {
4864 needFilter_ = needFilter_ || !currentSurfaceNode->IsStaticCached();
4865 CalcDirtyRegionForFilterNode(
4866 currentSurfaceNode->GetOldDirtyInSurface(), currentSurfaceNode, displayNode);
4867 }
4868 }
4869
UpdateHardwareNodeStatusBasedOnFilterRegion(RSDisplayRenderNode & displayNode)4870 void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilterRegion(RSDisplayRenderNode& displayNode)
4871 {
4872 std::vector<std::shared_ptr<RSSurfaceRenderNode>> prevHwcEnabledNodes;
4873 for (auto it = displayNode.GetCurAllSurfaces().begin(); it != displayNode.GetCurAllSurfaces().end(); ++it) {
4874 auto currentSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4875 if (currentSurfaceNode != nullptr) {
4876 UpdateHardwareNodeStatusBasedOnFilter(currentSurfaceNode, prevHwcEnabledNodes);
4877 }
4878 }
4879 }
4880
UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode> & node,std::vector<std::shared_ptr<RSSurfaceRenderNode>> & prevHwcEnabledNodes)4881 void RSUniRenderVisitor::UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode>& node,
4882 std::vector<std::shared_ptr<RSSurfaceRenderNode>>& prevHwcEnabledNodes)
4883 {
4884 if (!IsHardwareComposerEnabled()) {
4885 return;
4886 }
4887 if (node == nullptr || !node->IsAppWindow()) {
4888 return;
4889 }
4890 auto filterRects = node->GetChildrenNeedFilterRects();
4891 // collect valid hwc surface which is not intersected with filterRects
4892 std::vector<std::shared_ptr<RSSurfaceRenderNode>> curHwcEnabledNodes;
4893 for (auto subNode : node->GetChildHardwareEnabledNodes()) {
4894 auto childNode = subNode.lock();
4895 if (!childNode) {
4896 continue;
4897 }
4898 childNode->SetHardwareForcedDisabledStateByFilter(false);
4899 bool isIntersected = false;
4900 if (isPhone_) {
4901 for (auto &hwcNode: curHwcEnabledNodes) {
4902 if (childNode->GetDstRect().Intersect(hwcNode->GetDstRect())) {
4903 childNode->SetHardwareForcedDisabledStateByFilter(true);
4904 isIntersected = true;
4905 break;
4906 }
4907 }
4908 }
4909 if (!isPhone_ || !isIntersected) {
4910 curHwcEnabledNodes.emplace_back(childNode);
4911 }
4912 }
4913 // Within App: disable hwc if intersect with filterRects
4914 UpdateHardwareEnableList(filterRects, curHwcEnabledNodes);
4915 // Among App: disable lower hwc layers if intersect with upper transparent appWindow
4916 if (node->IsTransparent()) {
4917 if (node->GetRenderProperties().NeedFilter()) {
4918 // Attention: if transparent appwindow needs filter, only need to check itself
4919 filterRects = {node->GetDstRect()};
4920 }
4921 // In case of transparent window, filterRects need hwc surface's content
4922 UpdateHardwareEnableList(filterRects, prevHwcEnabledNodes);
4923 }
4924 if (!curHwcEnabledNodes.empty()) {
4925 prevHwcEnabledNodes.insert(prevHwcEnabledNodes.end(), curHwcEnabledNodes.begin(), curHwcEnabledNodes.end());
4926 }
4927 }
4928
UpdateHardwareEnableList(std::vector<RectI> & filterRects,std::vector<std::shared_ptr<RSSurfaceRenderNode>> & validHwcNodes)4929 void RSUniRenderVisitor::UpdateHardwareEnableList(std::vector<RectI>& filterRects,
4930 std::vector<std::shared_ptr<RSSurfaceRenderNode>>& validHwcNodes)
4931 {
4932 if (validHwcNodes.empty() || filterRects.empty()) {
4933 return;
4934 }
4935 for (auto iter = validHwcNodes.begin(); iter != validHwcNodes.end(); ++iter) {
4936 auto childDirtyRect = (*iter)->GetDstRect();
4937 bool isIntersected = false;
4938 for (auto& filterRect : filterRects) {
4939 if (!childDirtyRect.IntersectRect(filterRect).IsEmpty()) {
4940 isIntersected = true;
4941 }
4942 }
4943 if (isIntersected) {
4944 (*iter)->SetHardwareForcedDisabledStateByFilter(true);
4945 iter = validHwcNodes.erase(iter);
4946 iter--;
4947 }
4948 }
4949 }
4950
CalcDirtyFilterRegion(std::shared_ptr<RSDisplayRenderNode> & displayNode)4951 void RSUniRenderVisitor::CalcDirtyFilterRegion(std::shared_ptr<RSDisplayRenderNode>& displayNode)
4952 {
4953 if (displayNode == nullptr || displayNode->GetDirtyManager() == nullptr) {
4954 return;
4955 }
4956 auto displayDirtyManager = displayNode->GetDirtyManager();
4957 std::vector<SurfaceDirtyMgrPair> prevHwcEnabledNodes;
4958 for (auto it = displayNode->GetCurAllSurfaces().begin(); it != displayNode->GetCurAllSurfaces().end(); ++it) {
4959 auto currentSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4960 if (currentSurfaceNode) {
4961 // [planning] Update hwc surface dirty status at the same time
4962 UpdateHardwareNodeStatusBasedOnFilter(currentSurfaceNode, prevHwcEnabledNodes, displayDirtyManager);
4963 }
4964 }
4965
4966 for (auto it = displayNode->GetCurAllSurfaces().begin(); it != displayNode->GetCurAllSurfaces().end();) {
4967 auto currentSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4968 if (currentSurfaceNode == nullptr) {
4969 ++it;
4970 continue;
4971 }
4972 if (currentSurfaceNode->GetVisibleRegion().IsEmpty()) {
4973 ++it;
4974 continue;
4975 }
4976 auto lastDisplayDirtyRegion = displayDirtyManager->GetCurrentFrameDirtyRegion();
4977 // child node (component) has filter
4978 CalcChildFilterNodeDirtyRegion(currentSurfaceNode, displayNode);
4979 // surfaceNode self has filter
4980 CalcSurfaceFilterNodeDirtyRegion(currentSurfaceNode, displayNode);
4981 if (lastDisplayDirtyRegion != displayDirtyManager->GetCurrentFrameDirtyRegion()) {
4982 // When DisplayDirtyRegion is changed, collect dirty filter region from begin.
4983 // After all filter region is added, the cycle will definitely stop. there is no risk of a dead cycle.
4984 it = displayNode->GetCurAllSurfaces().begin();
4985 } else {
4986 ++it;
4987 }
4988 }
4989 }
4990
AddContainerDirtyToGlobalDirty(std::shared_ptr<RSDisplayRenderNode> & node) const4991 void RSUniRenderVisitor::AddContainerDirtyToGlobalDirty(std::shared_ptr<RSDisplayRenderNode>& node) const
4992 {
4993 RS_OPTIONAL_TRACE_FUNC();
4994 auto displayDirtyManager = node->GetDirtyManager();
4995 for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
4996 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
4997 if (surfaceNode == nullptr) {
4998 continue;
4999 }
5000 if (!surfaceNode->IsNodeDirty()) {
5001 continue;
5002 }
5003 auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
5004 if (surfaceDirtyManager == nullptr) {
5005 continue;
5006 }
5007 RectI surfaceDirtyRect = surfaceDirtyManager->GetCurrentFrameDirtyRegion();
5008 auto surfaceDirtyRegion = Occlusion::Region{Occlusion::Rect{surfaceDirtyRect}};
5009 if (surfaceNode->HasContainerWindow()) {
5010 // If a surface's dirty is intersect with container region (which can be considered transparent)
5011 // should be added to display dirty region.
5012 // Note: we use containerRegion rather transparentRegion to bypass inner corner dirty problem.
5013 auto containerRegion = surfaceNode->GetContainerRegion();
5014 auto containerDirtyRegion = containerRegion.And(surfaceDirtyRegion);
5015 if (!containerDirtyRegion.IsEmpty()) {
5016 RS_LOGD("CalcDirtyDisplayRegion merge containerDirtyRegion %{public}s region %{public}s",
5017 surfaceNode->GetName().c_str(), containerDirtyRegion.GetRegionInfo().c_str());
5018 // plan: we can use surfacenode's absrect as containerRegion's bound
5019 const auto& rect = containerRegion.GetBoundRef();
5020 displayDirtyManager->MergeDirtyRect(
5021 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
5022 continue;
5023 }
5024 }
5025 // warning: if a surfacenode has transparent region and opaque region, and its dirty pattern appears in
5026 // transparent region and opaque region in adjacent frame, may cause displaydirty region incomplete after
5027 // merge history (as surfacenode's dirty region merging opaque region will enlarge surface dirty region
5028 // which include transparent region but not counted in display dirtyregion)
5029 auto transparentRegion = surfaceNode->GetTransparentRegion();
5030 Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
5031 if (!transparentDirtyRegion.IsEmpty()) {
5032 RS_LOGD("CalcDirtyDisplayRegion merge TransparentDirtyRegion %{public}s region %{public}s",
5033 surfaceNode->GetName().c_str(), transparentDirtyRegion.GetRegionInfo().c_str());
5034 const std::vector<Occlusion::Rect>& rects = transparentDirtyRegion.GetRegionRects();
5035 for (const auto& rect : rects) {
5036 displayDirtyManager->MergeDirtyRect(
5037 RectI{ rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
5038 }
5039 }
5040 }
5041 }
5042
CheckAndSetNodeCacheType(RSRenderNode & node)5043 void RSUniRenderVisitor::CheckAndSetNodeCacheType(RSRenderNode& node)
5044 {
5045 if (node.IsStaticCached()) {
5046 if (node.GetCacheType() != CacheType::CONTENT) {
5047 node.SetCacheType(CacheType::CONTENT);
5048 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5049 }
5050
5051 if (!node.GetCompletedCacheSurface(threadIndex_, true) && UpdateCacheSurface(node)) {
5052 node.UpdateCompletedCacheSurface();
5053 }
5054 } else if (isDrawingCacheEnabled_ && GenerateNodeContentCache(node)) {
5055 UpdateCacheRenderNodeMapWithBlur(node);
5056 } else {
5057 if (node.GetCacheType() != CacheType::NONE) {
5058 node.SetCacheType(CacheType::NONE);
5059 if (node.GetCompletedCacheSurface(threadIndex_, false)) {
5060 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5061 }
5062 }
5063 // label this frame not run CheckAndSetNodeCacheType, means not run drawCacheWithBlur
5064 notRunCheckAndSetNodeCacheType_ = true;
5065 }
5066 }
5067
UpdateCacheSurface(RSRenderNode & node)5068 bool RSUniRenderVisitor::UpdateCacheSurface(RSRenderNode& node)
5069 {
5070 RS_TRACE_NAME_FMT("UpdateCacheSurface: [%llu]", node.GetId());
5071 CacheType cacheType = node.GetCacheType();
5072 if (cacheType == CacheType::NONE) {
5073 return false;
5074 }
5075
5076 if (!node.GetCacheSurface(threadIndex_, true)) {
5077 RSRenderNode::ClearCacheSurfaceFunc func = &RSUniRenderUtil::ClearNodeCacheSurface;
5078 node.InitCacheSurface(canvas_ ? canvas_->GetGPUContext().get() : nullptr, func, threadIndex_);
5079 }
5080 auto surface = node.GetCacheSurface(threadIndex_, true);
5081 if (!surface) {
5082 RS_LOGE("Get CacheSurface failed");
5083 return false;
5084 }
5085 auto cacheCanvas = std::make_shared<RSPaintFilterCanvas>(surface.get());
5086 if (!cacheCanvas) {
5087 return false;
5088 }
5089
5090 // copy current canvas properties into cacheCanvas
5091 if (renderEngine_) {
5092 cacheCanvas->SetHighContrast(renderEngine_->IsHighContrastEnabled());
5093 }
5094 if (canvas_) {
5095 cacheCanvas->CopyConfigurationToOffscreenCanvas(*canvas_);
5096 }
5097 // Using filter cache in multi-thread environment may cause GPU memory leak or invalid textures, so we explicitly
5098 // disable it in sub-thread.
5099 cacheCanvas->SetDisableFilterCache(isSubThread_);
5100
5101 // When drawing CacheSurface, all child node should be drawn.
5102 // So set isOpDropped_ = false here.
5103 bool isOpDropped = isOpDropped_;
5104 isOpDropped_ = false;
5105 isUpdateCachedSurface_ = true;
5106
5107 cacheCanvas->Clear(Drawing::Color::COLOR_TRANSPARENT);
5108
5109 swap(cacheCanvas, canvas_);
5110 // When cacheType == CacheType::ANIMATE_PROPERTY,
5111 // we should draw AnimateProperty on cacheCanvas
5112 const auto& property = node.GetRenderProperties();
5113 if (cacheType == CacheType::ANIMATE_PROPERTY) {
5114 if (property.IsShadowValid()
5115 && !property.IsSpherizeValid()) {
5116 canvas_->Save();
5117 canvas_->Translate(node.GetShadowRectOffsetX(), node.GetShadowRectOffsetY());
5118 }
5119 node.ProcessAnimatePropertyBeforeChildren(*canvas_);
5120 }
5121 if (node.IsNodeGroupIncludeProperty()) {
5122 node.ProcessAnimatePropertyBeforeChildren(*canvas_);
5123 }
5124 if (node.GetDrawingCacheType() != RSDrawingCacheType::DISABLED_CACHE) {
5125 node.SetDrawingCacheRootId(node.GetId());
5126 }
5127
5128 node.ProcessRenderContents(*canvas_);
5129 // Set a count to label the ProcessChildren in updateCacheProcess
5130 updateCacheProcessCnt_++;
5131 ProcessChildren(node);
5132 updateCacheProcessCnt_--;
5133
5134 if (cacheType == CacheType::ANIMATE_PROPERTY) {
5135 if (node.GetRenderProperties().IsShadowValid()
5136 && !node.GetRenderProperties().IsSpherizeValid()) {
5137 canvas_->Restore();
5138 }
5139 node.ProcessAnimatePropertyAfterChildren(*canvas_);
5140 }
5141 swap(cacheCanvas, canvas_);
5142
5143 isUpdateCachedSurface_ = false;
5144 isOpDropped_ = isOpDropped;
5145
5146 // To get all FreezeNode
5147 // execute: "param set rosen.dumpsurfacetype.enabled 2 && setenforce 0"
5148 // To get specific FreezeNode
5149 // execute: "param set rosen.dumpsurfacetype.enabled 1 && setenforce 0 && "
5150 // "param set rosen.dumpsurfaceid "NodeId" "
5151 // Png file could be found in /data
5152 RSBaseRenderUtil::WriteCacheRenderNodeToPng(node);
5153 return true;
5154 }
5155
DrawSpherize(RSRenderNode & node)5156 void RSUniRenderVisitor::DrawSpherize(RSRenderNode& node)
5157 {
5158 if (node.GetCacheType() != CacheType::ANIMATE_PROPERTY) {
5159 node.SetCacheType(CacheType::ANIMATE_PROPERTY);
5160 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5161 }
5162 if (!node.GetCompletedCacheSurface(threadIndex_, true) && UpdateCacheSurface(node)) {
5163 node.UpdateCompletedCacheSurface();
5164 }
5165 node.ProcessTransitionBeforeChildren(*canvas_);
5166 RSPropertiesPainter::DrawSpherize(
5167 node.GetRenderProperties(), *canvas_, node.GetCompletedCacheSurface(threadIndex_, true));
5168 node.ProcessTransitionAfterChildren(*canvas_);
5169 }
5170
DrawBlurInCache(RSRenderNode & node)5171 bool RSUniRenderVisitor::DrawBlurInCache(RSRenderNode& node)
5172 {
5173 if (LIKELY(curCacheFilterRects_.empty())) {
5174 return false;
5175 }
5176 const auto& property = node.GetRenderProperties();
5177 if (curCacheFilterRects_.top().count(node.GetId())) {
5178 if (curGroupedNodes_.empty()) {
5179 // draw filter before drawing cached surface
5180 curCacheFilterRects_.top().erase(node.GetId());
5181 if (curCacheFilterRects_.empty() || !node.ChildHasVisibleFilter()) {
5182 // no filter to draw, return
5183 return true;
5184 }
5185 } else if (property.GetShadowColorStrategy() !=
5186 SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE) {
5187 // clear hole while generating cache surface
5188 Drawing::AutoCanvasRestore arc(*canvas_.get(), true);
5189 RectI shadowRect;
5190 auto rrect = property.GetRRect();
5191 RSPropertiesPainter::GetShadowDirtyRect(shadowRect, property, &rrect, false, false);
5192 std::shared_ptr<Drawing::CoreCanvasImpl> coreCanvas = canvas_->GetCanvasData();
5193 auto skiaCanvas = static_cast<Drawing::SkiaCanvas *>(coreCanvas.get());
5194 SkCanvasPriv::ResetClip(skiaCanvas->ExportSkCanvas());
5195 canvas_->ClipRect(Drawing::Rect(shadowRect.left_, shadowRect.top_,
5196 shadowRect.width_ + shadowRect.left_, shadowRect.height_ + shadowRect.top_));
5197 canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
5198 } else if (property.GetBackgroundFilter() || property.GetUseEffect()) {
5199 // clear hole while generating cache surface
5200 Drawing::AutoCanvasRestore arc(*canvas_, true);
5201 if (property.GetClipBounds() != nullptr) {
5202 canvas_->ClipRect(RSPropertiesPainter::Rect2DrawingRect(property.GetBoundsRect()),
5203 Drawing::ClipOp::INTERSECT, false);
5204 } else {
5205 canvas_->ClipRoundRect(RSPropertiesPainter::RRect2DrawingRRect(property.GetRRect()),
5206 Drawing::ClipOp::INTERSECT, false);
5207 }
5208 canvas_->Clear(Drawing::Color::COLOR_TRANSPARENT);
5209 }
5210 } else if (curGroupedNodes_.empty() && !node.ChildHasVisibleFilter()) {
5211 // no filter to draw, return
5212 return true;
5213 }
5214 return false;
5215 }
5216
DrawChildCanvasRenderNode(RSRenderNode & node)5217 void RSUniRenderVisitor::DrawChildCanvasRenderNode(RSRenderNode& node)
5218 {
5219 if (node.GetCacheType() == CacheType::NONE) {
5220 if (node.IsPureContainer()) {
5221 processedPureContainerNode_++;
5222 node.ApplyBoundsGeometry(*canvas_);
5223 goto process;
5224 } else if (node.IsContentNode()) {
5225 node.ApplyBoundsGeometry(*canvas_);
5226 node.ApplyAlpha(*canvas_);
5227 node.ProcessRenderContents(*canvas_);
5228 process:
5229 ProcessChildren(node);
5230 node.RSRenderNode::ProcessTransitionAfterChildren(*canvas_);
5231 return;
5232 }
5233 }
5234 DrawChildRenderNode(node);
5235 }
5236
DrawChildRenderNode(RSRenderNode & node)5237 void RSUniRenderVisitor::DrawChildRenderNode(RSRenderNode& node)
5238 {
5239 CacheType cacheType = node.GetCacheType();
5240 node.ProcessTransitionBeforeChildren(*canvas_);
5241 switch (cacheType) {
5242 case CacheType::NONE: {
5243 auto preCache = canvas_->GetCacheType();
5244 if (node.HasCacheableAnim() && isDrawingCacheEnabled_) {
5245 canvas_->SetCacheType(RSPaintFilterCanvas::CacheType::ENABLED);
5246 }
5247 node.ProcessAnimatePropertyBeforeChildren(*canvas_);
5248 node.ProcessRenderContents(*canvas_);
5249 ProcessChildren(node);
5250 node.ProcessAnimatePropertyAfterChildren(*canvas_);
5251 if (node.HasCacheableAnim() && isDrawingCacheEnabled_) {
5252 canvas_->SetCacheType(preCache);
5253 }
5254 break;
5255 }
5256 case CacheType::CONTENT: {
5257 if (node.IsNodeGroupIncludeProperty()) {
5258 node.ProcessAnimatePropertyBeforeChildren(*canvas_, false);
5259 } else {
5260 node.ProcessAnimatePropertyBeforeChildren(*canvas_);
5261 }
5262 node.DrawCacheSurface(*canvas_, threadIndex_, false);
5263 node.ProcessAnimatePropertyAfterChildren(*canvas_);
5264 cacheRenderNodeMapRects_[node.GetId()] = node.GetOldDirtyInSurface();
5265 break;
5266 }
5267 case CacheType::ANIMATE_PROPERTY: {
5268 node.DrawCacheSurface(*canvas_, threadIndex_, false);
5269 break;
5270 }
5271 default:
5272 break;
5273 }
5274 node.ProcessTransitionAfterChildren(*canvas_);
5275 }
5276
CheckIfSurfaceRenderNodeNeedProcess(RSSurfaceRenderNode & node,bool & keepFilterCache)5277 bool RSUniRenderVisitor::CheckIfSurfaceRenderNodeNeedProcess(RSSurfaceRenderNode& node, bool& keepFilterCache)
5278 {
5279 if (isSubThread_) {
5280 return true;
5281 }
5282 if (RSMainThread::Instance()->GetCacheCmdSkippedNodes().count(node.GetId()) != 0) {
5283 return true;
5284 }
5285 if (isSecurityDisplay_ && node.GetSkipLayer()) {
5286 RS_PROCESS_TRACE(isPhone_, node.GetName() + " SkipLayer Skip");
5287 return false;
5288 }
5289 if (!node.ShouldPaint()) {
5290 MarkSubHardwareEnableNodeState(node);
5291 RS_OPTIONAL_TRACE_NAME(node.GetName() + " Node should not paint Skip");
5292 RS_LOGD("RSUniRenderVisitor::IfSurfaceRenderNodeNeedProcess node: %{public}" PRIu64 " invisible",
5293 node.GetId());
5294 return false;
5295 }
5296 if (!node.GetOcclusionVisible() && isOcclusionEnabled_ && !isSecurityDisplay_) {
5297 MarkSubHardwareEnableNodeState(node);
5298 if (!node.GetVisibleRegionForCallBack().IsEmpty()) {
5299 keepFilterCache = true;
5300 }
5301 RS_PROCESS_TRACE(isPhone_, node.GetName() + " Occlusion Skip");
5302 return false;
5303 }
5304 if (node.IsAbilityComponent() && node.GetDstRect().IsEmpty() && curGroupedNodes_.empty()) {
5305 RS_PROCESS_TRACE(isPhone_, node.GetName() + " Empty AbilityComponent Skip");
5306 return false;
5307 }
5308 std::vector<std::shared_ptr<RSSurfaceRenderNode>> appNodes;
5309 if (node.LeashWindowRelatedAppWindowOccluded(appNodes) && !isSecurityDisplay_) {
5310 for (const auto& appNode : appNodes) {
5311 if (appNode) {
5312 MarkSubHardwareEnableNodeState(*appNode);
5313 }
5314 }
5315 RS_PROCESS_TRACE(isPhone_, node.GetName() + " App Occluded Leashwindow Skip");
5316 return false;
5317 }
5318 if (!screenInfo_.whiteList.empty() && virtualScreenWhiteListRootId_ == INVALID_NODEID) {
5319 RS_PROCESS_TRACE(isPhone_, node.GetName() + " skip because it isn't filtered App");
5320 RS_LOGD("RSUniRenderVisitor::CheckIfSurfaceRenderNodeNeedProcess:\
5321 %{public}s skip because it isn't filtered App", node.GetName().c_str());
5322 return false;
5323 }
5324 return true;
5325 }
5326
ForceHardwareComposer(RSSurfaceRenderNode & node) const5327 bool RSUniRenderVisitor::ForceHardwareComposer(RSSurfaceRenderNode& node) const
5328 {
5329 auto bufferPixelFormat = node.GetRSSurfaceHandler()->GetBuffer()->GetFormat();
5330 return (bufferPixelFormat == GRAPHIC_PIXEL_FMT_RGBA_1010102 ||
5331 bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCBCR_P010 ||
5332 bufferPixelFormat == GRAPHIC_PIXEL_FMT_YCRCB_P010) && !node.IsHardwareForcedDisabledByFilter() &&
5333 !isUpdateCachedSurface_;
5334 }
5335
UpdateSrcRectForHwcNode(RSSurfaceRenderNode & node,bool isProtected)5336 bool RSUniRenderVisitor::UpdateSrcRectForHwcNode(RSSurfaceRenderNode& node, bool isProtected)
5337 {
5338 Drawing::AutoCanvasRestore acr(*canvas_.get(), true);
5339
5340 if (displayNodeMatrix_.has_value()) {
5341 auto& displayNodeMatrix = displayNodeMatrix_.value();
5342 auto matrix = canvas_->GetTotalMatrix();
5343 matrix.PostConcat(displayNodeMatrix);
5344 canvas_->SetMatrix(matrix);
5345 }
5346 node.SetTotalMatrix(canvas_->GetTotalMatrix());
5347
5348 auto dstRect = node.GetDstRect();
5349 Drawing::RectI dst = { dstRect.GetLeft(), dstRect.GetTop(), dstRect.GetRight(),
5350 dstRect.GetBottom() };
5351 bool hasRotation = false;
5352 if (node.GetRSSurfaceHandler()->GetConsumer() != nullptr) {
5353 auto rotation = RSBaseRenderUtil::GetRotateTransform(RSBaseRenderUtil::GetSurfaceBufferTransformType(
5354 node.GetRSSurfaceHandler()->GetConsumer(), node.GetRSSurfaceHandler()->GetBuffer()));
5355 hasRotation = rotation == GRAPHIC_ROTATE_90 || rotation == GRAPHIC_ROTATE_270;
5356 }
5357 node.UpdateSrcRect(*canvas_, dst, hasRotation);
5358 return isProtected ? true : !node.IsHardwareDisabledBySrcRect();
5359 }
5360
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)5361 void RSUniRenderVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
5362 {
5363 RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5364 }
5365
ProcessProxyRenderNode(RSProxyRenderNode & node)5366 void RSUniRenderVisitor::ProcessProxyRenderNode(RSProxyRenderNode& node)
5367 {
5368 RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5369 }
5370
ProcessRootRenderNode(RSRootRenderNode & node)5371 void RSUniRenderVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
5372 {
5373 RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5374 }
5375
GenerateNodeContentCache(RSRenderNode & node)5376 bool RSUniRenderVisitor::GenerateNodeContentCache(RSRenderNode& node)
5377 {
5378 // Node cannot have cache.
5379 if (node.GetDrawingCacheType() == RSDrawingCacheType::DISABLED_CACHE) {
5380 if (node.cacheCnt_ > 0) {
5381 node.SetCacheType(CacheType::NONE);
5382 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5383 node.cacheCnt_ = -1;
5384 }
5385 return false;
5386 }
5387
5388 // The node goes down the tree to clear the cache.
5389 if (node.GetCacheType() == CacheType::NONE && node.cacheCnt_ > 0) {
5390 node.cacheCnt_ = -1;
5391 }
5392 return true;
5393 }
5394
ClearRenderGroupCache()5395 void RSUniRenderVisitor::ClearRenderGroupCache()
5396 {
5397 std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
5398 cacheRenderNodeMap.clear();
5399 }
5400
InitNodeCache(RSRenderNode & node)5401 bool RSUniRenderVisitor::InitNodeCache(RSRenderNode& node)
5402 {
5403 if (node.GetDrawingCacheType() == RSDrawingCacheType::FORCED_CACHE ||
5404 node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
5405 if (node.cacheCnt_ == -1 || (!node.IsStaticCached() && node.NeedInitCacheCompletedSurface())) {
5406 RenderParam val { node.shared_from_this(), canvas_->GetCanvasStatus() };
5407 curGroupedNodes_.push(val);
5408 node.SetCacheType(CacheType::CONTENT);
5409 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5410 if (UpdateCacheSurface(node)) {
5411 node.UpdateCompletedCacheSurface();
5412 node.cacheCnt_++;
5413 cacheReuseTimes = 0;
5414 node.ResetDrawingCacheNeedUpdate();
5415 }
5416 curGroupedNodes_.pop();
5417 return true;
5418 }
5419 }
5420 return false;
5421 }
5422
ChangeCacheRenderNodeMap(RSRenderNode & node,const uint32_t count)5423 void RSUniRenderVisitor::ChangeCacheRenderNodeMap(RSRenderNode& node, const uint32_t count)
5424 {
5425 std::lock_guard<std::mutex> lock(cacheRenderNodeMapMutex);
5426 cacheRenderNodeMap[node.GetId()] = count;
5427 }
5428
UpdateCacheRenderNodeMapWithBlur(RSRenderNode & node)5429 void RSUniRenderVisitor::UpdateCacheRenderNodeMapWithBlur(RSRenderNode& node)
5430 {
5431 curCacheFilterRects_.push(allCacheFilterRects_[node.GetId()]);
5432 auto canvasType = canvas_->GetCacheType();
5433 canvas_->SetCacheType(RSPaintFilterCanvas::CacheType::OFFSCREEN);
5434 UpdateCacheRenderNodeMap(node);
5435 canvas_->SetCacheType(canvasType);
5436 RS_TRACE_NAME_FMT("Draw cache with blur [%llu]", node.GetId());
5437 Drawing::AutoCanvasRestore arc(*canvas_, true);
5438 auto nodeType = node.GetCacheType();
5439 node.SetCacheType(CacheType::NONE);
5440 bool isOpDropped = isOpDropped_;
5441 isOpDropped_ = false;
5442 // Label the ProcessChildren in drawCacheWithBlur
5443 drawCacheWithBlur_ = true;
5444 DrawChildRenderNode(node);
5445 isOpDropped_ = isOpDropped;
5446 drawCacheWithBlur_ = false;
5447 node.SetCacheType(nodeType);
5448 curCacheFilterRects_.pop();
5449 }
5450
UpdateCacheRenderNodeMap(RSRenderNode & node)5451 void RSUniRenderVisitor::UpdateCacheRenderNodeMap(RSRenderNode& node)
5452 {
5453 if (InitNodeCache(node)) {
5454 RS_OPTIONAL_TRACE_NAME_FMT("RSUniRenderVisitor::UpdateCacheRenderNodeMap, generate the node cache for the first"
5455 "time, NodeId: %" PRIu64 " ", node.GetId());
5456 return;
5457 }
5458 cacheRenderNodeIsUpdateMap_[node.GetId()] = node.GetDrawingCacheChanged();
5459 if (node.GetDrawingCacheType() == RSDrawingCacheType::FORCED_CACHE) {
5460 // Regardless of the number of consecutive refreshes, the current cache is forced to be updated.
5461 if (node.GetDrawingCacheChanged()) {
5462 RenderParam val { node.shared_from_this(), canvas_->GetCanvasStatus() };
5463 curGroupedNodes_.push(val);
5464 node.SetCacheType(CacheType::CONTENT);
5465 if (UpdateCacheSurface(node)) {
5466 node.UpdateCompletedCacheSurface();
5467 node.cacheCnt_++;
5468 cacheReuseTimes = 0;
5469 node.ResetDrawingCacheNeedUpdate();
5470 }
5471 curGroupedNodes_.pop();
5472 return;
5473 }
5474 }
5475 if (node.GetDrawingCacheType() == RSDrawingCacheType::TARGETED_CACHE) {
5476 // If the number of consecutive refreshes exceeds CACHE_MAX_UPDATE_TIME times, the cache is cleaned,
5477 // otherwise the cache is updated.
5478 if (node.GetDrawingCacheChanged()) {
5479 node.cacheCnt_++;
5480 if (node.cacheCnt_ >= CACHE_MAX_UPDATE_TIME) {
5481 node.SetCacheType(CacheType::NONE);
5482 node.MarkNodeGroup(RSRenderNode::GROUPED_BY_UI, false, false);
5483 node.MarkNodeGroup(RSRenderNode::GROUPED_BY_ANIM, false, false);
5484 RSUniRenderUtil::ClearCacheSurface(node, threadIndex_);
5485 node.cacheCnt_ = -1;
5486 cacheReuseTimes = 0;
5487 return;
5488 }
5489 node.SetCacheType(CacheType::CONTENT);
5490 if (UpdateCacheSurface(node)) {
5491 node.UpdateCompletedCacheSurface();
5492 cacheReuseTimes = 0;
5493 node.ResetDrawingCacheNeedUpdate();
5494 }
5495 curGroupedNodes_.pop();
5496 return;
5497 }
5498 }
5499 // The cache is not refreshed continuously.
5500 node.cacheCnt_ = 0;
5501 cacheReuseTimes++;
5502 RS_OPTIONAL_TRACE_NAME("RSUniRenderVisitor::UpdateCacheRenderNodeMap ,NodeId: " + std::to_string(node.GetId()) +
5503 " ,CacheRenderNodeMapCnt: " + std::to_string(cacheReuseTimes));
5504 }
5505
ProcessCanvasRenderNode(RSCanvasRenderNode & node)5506 void RSUniRenderVisitor::ProcessCanvasRenderNode(RSCanvasRenderNode& node)
5507 {
5508 RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5509 }
5510
ProcessEffectRenderNode(RSEffectRenderNode & node)5511 void RSUniRenderVisitor::ProcessEffectRenderNode(RSEffectRenderNode& node)
5512 {
5513 RS_LOGE("RSUniRenderVisitor::%{public}s is upgraded to DrawableV2", __func__);
5514 }
5515
ClosePartialRenderWhenAnimatingWindows(std::shared_ptr<RSDisplayRenderNode> & node)5516 void RSUniRenderVisitor::ClosePartialRenderWhenAnimatingWindows(std::shared_ptr<RSDisplayRenderNode>& node)
5517 {
5518 if (!doAnimate_) {
5519 return;
5520 }
5521 if (appWindowNum_ > PHONE_MAX_APP_WINDOW_NUM) {
5522 node->GetDirtyManager()->MergeSurfaceRect();
5523 } else {
5524 isPartialRenderEnabled_ = false;
5525 isOpDropped_ = false;
5526 RS_TRACE_NAME("ClosePartialRender 0 Window Animation");
5527 }
5528 }
5529
SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams> & renderThreadParams)5530 void RSUniRenderVisitor::SetUniRenderThreadParam(std::unique_ptr<RSRenderThreadParams>& renderThreadParams)
5531 {
5532 if (!renderThreadParams) {
5533 RS_LOGE("RSUniRenderVisitor::SetUniRenderThreadParam renderThreadParams is nullptr");
5534 return;
5535 }
5536 renderThreadParams->isPartialRenderEnabled_ = isPartialRenderEnabled_;
5537 renderThreadParams->isRegionDebugEnabled_ = isRegionDebugEnabled_;
5538 renderThreadParams->isDirtyRegionDfxEnabled_ = isDirtyRegionDfxEnabled_;
5539 renderThreadParams->isDisplayDirtyDfxEnabled_ = isDisplayDirtyDfxEnabled_;
5540 renderThreadParams->isOpaqueRegionDfxEnabled_ = isOpaqueRegionDfxEnabled_;
5541 renderThreadParams->isVisibleRegionDfxEnabled_ = isVisibleRegionDfxEnabled_;
5542 renderThreadParams->isAllSurfaceVisibleDebugEnabled_ = isAllSurfaceVisibleDebugEnabled_;
5543 renderThreadParams->isTargetDirtyRegionDfxEnabled_ = isTargetDirtyRegionDfxEnabled_;
5544 renderThreadParams->dirtyRegionDebugType_ = dirtyRegionDebugType_;
5545 renderThreadParams->isOpDropped_ = isOpDropped_;
5546 renderThreadParams->isUIFirstDebugEnable_ = isUIFirstDebugEnable_;
5547 renderThreadParams->dfxTargetSurfaceNames_ = std::move(dfxTargetSurfaceNames_);
5548 renderThreadParams->isVirtualDirtyEnabled_ = isVirtualDirtyEnabled_;
5549 renderThreadParams->isVirtualDirtyDfxEnabled_ = isVirtualDirtyDfxEnabled_;
5550 renderThreadParams->isExpandScreenDirtyEnabled_ = isExpandScreenDirtyEnabled_;
5551 renderThreadParams->hasMirrorDisplay_ = hasMirrorDisplay_;
5552 }
5553
SetHardwareEnabledNodes(const std::vector<std::shared_ptr<RSSurfaceRenderNode>> & hardwareEnabledNodes)5554 void RSUniRenderVisitor::SetHardwareEnabledNodes(
5555 const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& hardwareEnabledNodes)
5556 {
5557 hardwareEnabledNodes_ = hardwareEnabledNodes;
5558 }
5559
DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode)5560 bool RSUniRenderVisitor::DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode)
5561 {
5562 auto children = rootNode->GetChildren();
5563 if (!IsHardwareComposerEnabled() || children->empty()) {
5564 RS_LOGD("RSUniRenderVisitor::DoDirectComposition HardwareComposer disabled");
5565 return false;
5566 }
5567 RS_TRACE_NAME("DoDirectComposition");
5568 auto& child = children->front();
5569 if (child == nullptr || !child->IsInstanceOf<RSDisplayRenderNode>()) {
5570 RS_LOGE("RSUniRenderVisitor::DoDirectComposition child type not match");
5571 return false;
5572 }
5573 auto displayNode = child->ReinterpretCastTo<RSDisplayRenderNode>();
5574 if (!displayNode ||
5575 displayNode->GetCompositeType() != RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE) {
5576 RS_LOGE("RSUniRenderVisitor::DoDirectComposition displayNode state error");
5577 return false;
5578 }
5579 sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
5580 screenInfo_ = screenManager->QueryScreenInfo(displayNode->GetScreenId());
5581 if (screenInfo_.state != ScreenState::HDI_OUTPUT_ENABLE) {
5582 RS_LOGE("RSUniRenderVisitor::DoDirectComposition: ScreenState error!");
5583 return false;
5584 }
5585 processor_ = RSProcessorFactory::CreateProcessor(displayNode->GetCompositeType());
5586 if (processor_ == nullptr || renderEngine_ == nullptr) {
5587 RS_LOGE("RSUniRenderVisitor::DoDirectComposition: RSProcessor or renderEngine is null!");
5588 return false;
5589 }
5590
5591 if (!processor_->Init(*displayNode, displayNode->GetDisplayOffsetX(), displayNode->GetDisplayOffsetY(),
5592 INVALID_SCREEN_ID, renderEngine_)) {
5593 RS_LOGE("RSUniRenderVisitor::DoDirectComposition: processor init failed!");
5594 return false;
5595 }
5596
5597 if (!RSMainThread::Instance()->WaitHardwareThreadTaskExecute()) {
5598 RS_LOGW("RSUniRenderVisitor::DoDirectComposition: hardwareThread task has too many to Execute");
5599 }
5600 if (!RSMainThread::Instance()->CheckIsHardwareEnabledBufferUpdated()) {
5601 for (auto& surfaceNode: hardwareEnabledNodes_) {
5602 if (!surfaceNode->IsHardwareForcedDisabled()) {
5603 surfaceNode->MarkCurrentFrameHardwareEnabled();
5604 }
5605 }
5606 RS_TRACE_NAME("DoDirectComposition skip commit");
5607 return true;
5608 }
5609 processor_->ProcessDisplaySurface(*displayNode);
5610 for (auto& node: hardwareEnabledNodes_) {
5611 if (!node->IsHardwareForcedDisabled()) {
5612 processor_->ProcessSurface(*node);
5613 }
5614 }
5615 DoScreenRcdTask(processor_, rcdInfo_, screenInfo_);
5616 processor_->PostProcess();
5617 RS_LOGD("RSUniRenderVisitor::DoDirectComposition end");
5618 return true;
5619 }
5620
DrawWatermarkIfNeed(RSDisplayRenderNode & node,bool isMirror)5621 void RSUniRenderVisitor::DrawWatermarkIfNeed(RSDisplayRenderNode& node, bool isMirror)
5622 {
5623 if (RSMainThread::Instance()->GetWatermarkFlag()) {
5624 auto screenManager = CreateOrGetScreenManager();
5625 auto mainScreenInfo = screenManager->QueryScreenInfo(node.GetScreenId());
5626 auto mainWidth = static_cast<float>(mainScreenInfo.width);
5627 auto mainHeight = static_cast<float>(mainScreenInfo.height);
5628 if (RSSystemProperties::IsFoldScreenFlag() && node.GetScreenId() == 0 && isMirror) {
5629 std::swap(mainWidth, mainHeight);
5630 }
5631 std::shared_ptr<Drawing::Image> drImage = RSMainThread::Instance()->GetWatermarkImg();
5632 if (drImage == nullptr) {
5633 return;
5634 }
5635
5636 Drawing::SaveLayerOps slr(nullptr, nullptr, Drawing::SaveLayerOps::INIT_WITH_PREVIOUS);
5637 canvas_->SaveLayer(slr); // avoid abnormal dsicard
5638 Drawing::Brush rectPaint;
5639 canvas_->AttachBrush(rectPaint);
5640 auto srcRect = Drawing::Rect(0, 0, drImage->GetWidth(), drImage->GetHeight());
5641 auto dstRect = Drawing::Rect(0, 0, mainWidth, mainHeight);
5642 canvas_->DrawImageRect(*drImage, srcRect, dstRect, Drawing::SamplingOptions(),
5643 Drawing::SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT);
5644 canvas_->DetachBrush();
5645 canvas_->Restore();
5646 }
5647 }
5648
SetAppWindowNum(uint32_t num)5649 void RSUniRenderVisitor::SetAppWindowNum(uint32_t num)
5650 {
5651 appWindowNum_ = num;
5652 }
5653
5654 #ifdef ENABLE_RECORDING_DCL
tryCapture(float width,float height)5655 void RSUniRenderVisitor::tryCapture(float width, float height)
5656 {
5657 if (!RSSystemProperties::GetRecordingEnabled()) {
5658 #ifdef RS_PROFILER_ENABLED
5659 if (auto canvas = RSCaptureRecorder::GetInstance().TryInstantCapture(width, height)) {
5660 canvas_->AddCanvas(canvas);
5661 }
5662 #endif
5663 return;
5664 }
5665 recordingCanvas_ = std::make_unique<ExtendRecordingCanvas>(width, height);
5666 RS_TRACE_NAME("RSUniRender:Recording begin");
5667 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
5668 auto renderContext = RSMainThread::Instance()->GetRenderEngine()->GetRenderContext();
5669 recordingCanvas_->SetGrRecordingContext(renderContext->GetSharedDrGPUContext());
5670 #endif
5671 canvas_->AddCanvas(recordingCanvas_.get());
5672 RSRecordingThread::Instance(renderEngine_->GetRenderContext().get()).CheckAndRecording();
5673 }
5674
endCapture() const5675 void RSUniRenderVisitor::endCapture() const
5676 {
5677 if (!RSRecordingThread::Instance(renderEngine_->GetRenderContext().get()).GetRecordingEnabled()) {
5678 #ifdef RS_PROFILER_ENABLED
5679 RSCaptureRecorder::GetInstance().EndInstantCapture();
5680 #endif
5681 return;
5682 }
5683 auto drawCmdList = recordingCanvas_->GetDrawCmdList();
5684 RS_TRACE_NAME("RSUniRender:RecordingToFile curFrameNum = " +
5685 std::to_string(RSRecordingThread::Instance(renderEngine_->GetRenderContext().get()).GetCurDumpFrame()));
5686 RSRecordingThread::Instance(renderEngine_->GetRenderContext().get()).RecordingToFile(drawCmdList);
5687 }
5688 #endif
5689
RotateMirrorCanvasIfNeed(RSDisplayRenderNode & node,bool canvasRotation)5690 void RSUniRenderVisitor::RotateMirrorCanvasIfNeed(RSDisplayRenderNode& node, bool canvasRotation)
5691 {
5692 auto mirrorNode = node.GetMirrorSource().lock();
5693 if ((canvasRotation && (RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0)) ||
5694 (!canvasRotation && !(RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0))) {
5695 return;
5696 }
5697 auto screenManager = CreateOrGetScreenManager();
5698 auto mainScreenInfo = screenManager->QueryScreenInfo(mirrorNode->GetScreenId());
5699 auto mainWidth = static_cast<float>(mainScreenInfo.width);
5700 auto mainHeight = static_cast<float>(mainScreenInfo.height);
5701 auto rotation = mirrorNode->GetScreenRotation();
5702 if (RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) {
5703 if (rotation == ScreenRotation::ROTATION_0 || rotation == ScreenRotation::ROTATION_180) {
5704 std::swap(mainWidth, mainHeight);
5705 }
5706 auto oriRotation = node.GetOriginScreenRotation();
5707 rotation = static_cast<ScreenRotation>((static_cast<int>(oriRotation) -
5708 static_cast<int>(rotation) + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
5709 }
5710 if (rotation != ScreenRotation::ROTATION_0) {
5711 if (rotation == ScreenRotation::ROTATION_90) {
5712 canvas_->Rotate(90, 0, 0);
5713 canvas_->Translate(0, -mainHeight);
5714 } else if (rotation == ScreenRotation::ROTATION_180) {
5715 canvas_->Rotate(180, mainWidth / 2, mainHeight / 2);
5716 } else if (rotation == ScreenRotation::ROTATION_270) {
5717 canvas_->Rotate(270, 0, 0);
5718 canvas_->Translate(-mainWidth, 0);
5719 }
5720 }
5721 }
5722
ScaleMirrorIfNeed(RSDisplayRenderNode & node,bool canvasRotation)5723 void RSUniRenderVisitor::ScaleMirrorIfNeed(RSDisplayRenderNode& node, bool canvasRotation)
5724 {
5725 auto screenManager = CreateOrGetScreenManager();
5726 auto mirrorNode = node.GetMirrorSource().lock();
5727 if (!screenManager || !mirrorNode) {
5728 RS_LOGE("RSUniRenderVisitor::ScaleMirrorIfNeed screenManager or mirrorNode is nullptr");
5729 return;
5730 }
5731 auto mainScreenInfo = screenManager->QueryScreenInfo(mirrorNode->GetScreenId());
5732 auto mainWidth = static_cast<float>(mainScreenInfo.width);
5733 auto mainHeight = static_cast<float>(mainScreenInfo.height);
5734 auto mirrorWidth = node.GetRenderProperties().GetBoundsWidth();
5735 auto mirrorHeight = node.GetRenderProperties().GetBoundsHeight();
5736 auto scaleMode = screenManager->GetScaleMode(node.GetScreenId());
5737 if (canvasRotation) {
5738 if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) ||
5739 mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_90 ||
5740 mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_270) {
5741 std::swap(mainWidth, mainHeight);
5742 }
5743 } else {
5744 if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0)) {
5745 auto oriRotation = node.GetOriginScreenRotation();
5746 auto curRotation = node.GetScreenRotation();
5747 auto rotation = static_cast<ScreenRotation>((static_cast<int>(oriRotation) -
5748 static_cast<int>(curRotation) + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
5749 if (rotation == ScreenRotation::ROTATION_0 ||
5750 rotation == ScreenRotation::ROTATION_180) {
5751 std::swap(mainWidth, mainHeight);
5752 }
5753 } else {
5754 if ((node.GetOriginScreenRotation() == ScreenRotation::ROTATION_90 ||
5755 node.GetOriginScreenRotation() == ScreenRotation::ROTATION_270)) {
5756 std::swap(mirrorWidth, mirrorHeight);
5757 }
5758 }
5759 }
5760 // If the width and height not match the main screen, calculate the dstRect.
5761 if (mainWidth != mirrorWidth || mainHeight != mirrorHeight) {
5762 canvas_->Clear(SK_ColorBLACK);
5763 auto processor = std::static_pointer_cast<RSUniRenderVirtualProcessor>(processor_);
5764 if (!processor) {
5765 RS_LOGE("RSUniRenderVisitor::ScaleMirrorIfNeed processor is nullptr!");
5766 return;
5767 }
5768 if (scaleMode == ScreenScaleMode::FILL_MODE) {
5769 processor->Fill(*canvas_, mainWidth, mainHeight, mirrorWidth, mirrorHeight);
5770 } else if (scaleMode == ScreenScaleMode::UNISCALE_MODE) {
5771 processor->UniScale(*canvas_, mainWidth, mainHeight, mirrorWidth, mirrorHeight);
5772 }
5773 }
5774 }
5775
SendRcdMessage(RSDisplayRenderNode & node)5776 void RSUniRenderVisitor::SendRcdMessage(RSDisplayRenderNode& node)
5777 {
5778 if ((screenInfo_.state == ScreenState::HDI_OUTPUT_ENABLE) &&
5779 RSSingleton<RoundCornerDisplay>::GetInstance().GetRcdEnable()) {
5780 using rcd_msg = RSSingleton<RsMessageBus>;
5781 rcd_msg::GetInstance().SendMsg<uint32_t, uint32_t>(TOPIC_RCD_DISPLAY_SIZE,
5782 screenInfo_.width, screenInfo_.height);
5783 rcd_msg::GetInstance().SendMsg<ScreenRotation>(TOPIC_RCD_DISPLAY_ROTATION,
5784 node.GetScreenRotation());
5785 rcd_msg::GetInstance().SendMsg<int>(TOPIC_RCD_DISPLAY_NOTCH,
5786 RSSystemParameters::GetHideNotchStatus());
5787 }
5788 }
5789
RotateMirrorCanvasIfNeedForWiredScreen(RSDisplayRenderNode & node)5790 void RSUniRenderVisitor::RotateMirrorCanvasIfNeedForWiredScreen(RSDisplayRenderNode& node)
5791 {
5792 auto mirrorNode = node.GetMirrorSource().lock();
5793 auto rotation = mirrorNode->GetScreenRotation();
5794 if (RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) {
5795 if (rotation == ScreenRotation::ROTATION_270) {
5796 rotation = ScreenRotation::ROTATION_0;
5797 } else {
5798 rotation = static_cast<ScreenRotation>(static_cast<int>(rotation) + 1);
5799 }
5800 }
5801 if (rotation != ScreenRotation::ROTATION_0) {
5802 auto screenManager = CreateOrGetScreenManager();
5803 auto mainScreenInfo = screenManager->QueryScreenInfo(mirrorNode->GetScreenId());
5804 if (rotation == ScreenRotation::ROTATION_90) {
5805 canvas_->Rotate(RS_ROTATION_90, 0, 0);
5806 canvas_->Translate(0, -(static_cast<float>(mainScreenInfo.height)));
5807 } else if (rotation == ScreenRotation::ROTATION_180) {
5808 float ratio = 0.5f;
5809 canvas_->Rotate(RS_ROTATION_180, static_cast<float>(mainScreenInfo.width) * ratio,
5810 static_cast<float>(mainScreenInfo.height) * ratio);
5811 } else if (rotation == ScreenRotation::ROTATION_270) {
5812 canvas_->Rotate(RS_ROTATION_270, 0, 0);
5813 canvas_->Translate(-(static_cast<float>(mainScreenInfo.width)), 0);
5814 }
5815 }
5816 }
5817
ScaleMirrorIfNeedForWiredScreen(RSDisplayRenderNode & node,bool canvasRotation)5818 void RSUniRenderVisitor::ScaleMirrorIfNeedForWiredScreen(RSDisplayRenderNode& node, bool canvasRotation)
5819 {
5820 auto screenManager = CreateOrGetScreenManager();
5821 auto mirrorNode = node.GetMirrorSource().lock();
5822 auto mainScreenInfo = screenManager->QueryScreenInfo(mirrorNode->GetScreenId());
5823 float mainWidth = static_cast<float>(mainScreenInfo.width);
5824 float mainHeight = static_cast<float>(mainScreenInfo.height);
5825 if (canvasRotation) {
5826 if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) ||
5827 mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_90 ||
5828 mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_270) {
5829 std::swap(mainWidth, mainHeight);
5830 }
5831 } else {
5832 if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0) ||
5833 node.GetOriginScreenRotation() == ScreenRotation::ROTATION_90 ||
5834 node.GetOriginScreenRotation() == ScreenRotation::ROTATION_270) {
5835 std::swap(mainWidth, mainHeight);
5836 }
5837 if ((RSSystemProperties::IsFoldScreenFlag() && mirrorNode->GetScreenId() == 0 &&
5838 (mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_90 ||
5839 mirrorNode->GetScreenRotation() == ScreenRotation::ROTATION_270)) || mirrorAutoRotate_) {
5840 std::swap(mainWidth, mainHeight);
5841 }
5842 }
5843 float boundsWidth = node.GetRenderProperties().GetBoundsWidth();
5844 float boundsHeight = node.GetRenderProperties().GetBoundsHeight();
5845 // If the width and height not match the main screen, calculate the dstRect.
5846 if ((mainWidth != boundsWidth || mainHeight != boundsHeight) &&
5847 (mainWidth > 0 && mainHeight > 0)) {
5848 canvas_->Clear(SK_ColorBLACK);
5849 float mirrorScale = 1.0f; // 1 for init scale
5850 float startX = 0.0f;
5851 float startY = 0.0f;
5852 float mirrorScaleX = boundsWidth / mainWidth;
5853 float mirrorScaleY = boundsHeight / mainHeight;
5854 float ratio = 0.5f;
5855 if (mirrorScaleY < mirrorScaleX) {
5856 mirrorScale = mirrorScaleY;
5857 startX = (boundsWidth - (mirrorScale * mainWidth)) * ratio;
5858 } else {
5859 mirrorScale = mirrorScaleX;
5860 startY = (boundsHeight - (mirrorScale * mainHeight)) * ratio;
5861 }
5862 canvas_->Translate(startX, startY);
5863 canvas_->Scale(mirrorScale, mirrorScale);
5864 }
5865 }
5866
SetHasSharedTransitionNode(RSSurfaceRenderNode & surfaceNode,bool hasSharedTransitionNode)5867 void RSUniRenderVisitor::SetHasSharedTransitionNode(RSSurfaceRenderNode& surfaceNode, bool hasSharedTransitionNode)
5868 {
5869 // only allow change hasSharedTransitionNode in leash window's child
5870 if (surfaceNode.GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
5871 return;
5872 }
5873 surfaceNode.SetHasSharedTransitionNode(hasSharedTransitionNode);
5874 // sync the change to parent leash window
5875 auto leashNode =
5876 RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surfaceNode.GetParent().lock());
5877 if (leashNode && leashNode->GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
5878 leashNode->SetHasSharedTransitionNode(hasSharedTransitionNode);
5879 }
5880 }
5881
ProcessUnpairedSharedTransitionNode()5882 void RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode()
5883 {
5884 static auto unpairNode = [](const std::weak_ptr<RSRenderNode>& wptr) {
5885 auto sptr = wptr.lock();
5886 if (sptr == nullptr) {
5887 return;
5888 }
5889 // make sure parent regenerates ChildrenDrawable
5890 auto parent = sptr->GetParent().lock();
5891 if (parent == nullptr) {
5892 return;
5893 }
5894 parent->AddDirtyType(RSModifierType::CHILDREN);
5895 parent->ApplyModifiers();
5896 // avoid changing the paired status or unpairedShareTransitions_
5897 auto param = sptr->GetSharedTransitionParam();
5898 if (param == nullptr) {
5899 ROSEN_LOGE("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: param is null");
5900 return;
5901 }
5902 param->paired_ = false;
5903 SharedTransitionParam::unpairedShareTransitions_.clear();
5904 };
5905 auto unpairedShareTransitions = std::move(SharedTransitionParam::unpairedShareTransitions_);
5906 for (auto& [id, wptr] : unpairedShareTransitions) {
5907 auto sharedTransitionParam = wptr.lock();
5908 // If the unpaired share transition is already deal with, do nothing
5909 if (!sharedTransitionParam) {
5910 continue;
5911 }
5912 if (!sharedTransitionParam->paired_) {
5913 sharedTransitionParam->ResetRelation();
5914 continue;
5915 }
5916 ROSEN_LOGD("RSUniRenderVisitor::ProcessUnpairedSharedTransitionNode: mark %s as unpaired",
5917 sharedTransitionParam->Dump().c_str());
5918 sharedTransitionParam->paired_ = false;
5919 unpairNode(sharedTransitionParam->inNode_);
5920 unpairNode(sharedTransitionParam->outNode_);
5921 sharedTransitionParam->ResetRelation();
5922 }
5923 }
5924
FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)5925 NodeId RSUniRenderVisitor::FindInstanceChildOfDisplay(std::shared_ptr<RSRenderNode> node)
5926 {
5927 if (node == nullptr) {
5928 return INVALID_NODEID;
5929 }
5930 auto nodeParent = node->GetParent().lock();
5931 if (nodeParent == nullptr) {
5932 return INVALID_NODEID;
5933 }
5934 if (nodeParent->GetType() == RSRenderNodeType::DISPLAY_NODE) {
5935 return node->GetId();
5936 } else {
5937 return FindInstanceChildOfDisplay(nodeParent);
5938 }
5939 }
5940
CheckIfNeedResetRotate()5941 bool RSUniRenderVisitor::CheckIfNeedResetRotate()
5942 {
5943 if (canvas_ == nullptr) {
5944 return true;
5945 }
5946 auto matrix = canvas_->GetTotalMatrix();
5947 if (displayNodeMatrix_.has_value()) {
5948 matrix.PreConcat(displayNodeMatrix_.value());
5949 }
5950 int angle = RSUniRenderUtil::GetRotationFromMatrix(matrix);
5951 return angle != 0 && angle % RS_ROTATION_90 == 0;
5952 }
5953
IsOutOfScreenRegion(RectI rect)5954 bool RSUniRenderVisitor::IsOutOfScreenRegion(RectI rect)
5955 {
5956 if (!canvas_) {
5957 return false;
5958 }
5959
5960 auto deviceClipBounds = canvas_->GetDeviceClipBounds();
5961
5962 if (rect.GetRight() <= deviceClipBounds.GetLeft() ||
5963 rect.GetLeft() >= deviceClipBounds.GetRight() ||
5964 rect.GetBottom() <= deviceClipBounds.GetTop() ||
5965 rect.GetTop() >= deviceClipBounds.GetBottom()) {
5966 return true;
5967 }
5968
5969 return false;
5970 }
5971
DrawCurtainScreen()5972 void RSUniRenderVisitor::DrawCurtainScreen()
5973 {
5974 if (!isCurtainScreenOn_ || !canvas_) {
5975 return;
5976 }
5977 float screenWidth = static_cast<float>(screenInfo_.width);
5978 float screenHeight = static_cast<float>(screenInfo_.height);
5979 Drawing::Brush brush;
5980 brush.SetARGB(MAX_ALPHA, 0, 0, 0); // not transparent black
5981 canvas_->AttachBrush(brush);
5982 canvas_->DrawRect(Drawing::Rect(0, 0, screenWidth, screenHeight));
5983 canvas_->DetachBrush();
5984 }
5985
CheckColorFilterChange() const5986 bool RSUniRenderVisitor::CheckColorFilterChange() const
5987 {
5988 if (!RSMainThread::Instance()->IsAccessibilityConfigChanged()) {
5989 return false;
5990 }
5991 RS_LOGD("RSUniRenderVisitor::CheckColorFilterChange changed");
5992 return true;
5993 }
5994
CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr> & surfaces)5995 void RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate(std::vector<RSBaseRenderNode::SharedPtr>& surfaces)
5996 {
5997 // Debug dirtyregion of show current refreshRation
5998 if (RSRealtimeRefreshRateManager::Instance().GetShowRefreshRateEnabled()) {
5999 RectI tempRect = {100, 100, 500, 200}; // setDirtyRegion for RealtimeRefreshRate
6000 bool surfaceNodeSet = false;
6001 for (auto surface : surfaces) {
6002 auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(surface);
6003 if (surfaceNode == nullptr) {
6004 RS_LOGE("RSUniRenderVisitor::CheckMergeDebugRectforRefreshRate surfaceNode is nullptr");
6005 continue;
6006 }
6007 if (surfaceNode->GetName().find(RELIABLE_GESTURE_BACK_SURFACE_NAME) != std::string::npos) {
6008 // refresh rate rect for mainwindow
6009 auto& geoPtr = surfaceNode->GetRenderProperties().GetBoundsGeometry();
6010 if (!geoPtr) {
6011 break;
6012 }
6013 tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
6014 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
6015 surfaceNodeSet = true;
6016 break;
6017 }
6018 }
6019 if (!surfaceNodeSet) {
6020 auto &geoPtr = curDisplayNode_->GetRenderProperties().GetBoundsGeometry();
6021 if (!geoPtr) {
6022 return;
6023 }
6024 tempRect = geoPtr->MapAbsRect(tempRect.ConvertTo<float>());
6025 curDisplayNode_->GetDirtyManager()->MergeDirtyRect(tempRect, true);
6026 }
6027 }
6028 }
6029
CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode & node)6030 void RSUniRenderVisitor::CheckIsGpuOverDrawBufferOptimizeNode(RSSurfaceRenderNode& node)
6031 {
6032 bool hasAnim = ancestorNodeHasAnimation_ || node.GetCurFrameHasAnimation();
6033 if (!node.IsScale() || hasAnim || curCornerRadius_.IsZero() || curAlpha_ < 1) {
6034 node.SetGpuOverDrawBufferOptimizeNode(false);
6035 return;
6036 }
6037
6038 for (auto& child : *(node.GetChildren())) {
6039 if (!child || !(child->IsInstanceOf<RSSurfaceRenderNode>() &&
6040 RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(child)->IsLeashOrMainWindow())) {
6041 continue;
6042 }
6043 auto rootNode = child->GetFirstChild();
6044 if (!rootNode) {
6045 break;
6046 }
6047 auto canvasNode = rootNode->GetFirstChild();
6048 if (!canvasNode) {
6049 break;
6050 }
6051 const auto& surfaceProperties = node.GetRenderProperties();
6052 const auto& canvasProperties = canvasNode->GetRenderProperties();
6053 if (canvasProperties.GetAlpha() >= 1
6054 && canvasProperties.GetBackgroundColor().GetAlpha() >= MAX_ALPHA
6055 && canvasProperties.GetFrameWidth() == surfaceProperties.GetFrameWidth()
6056 && canvasProperties.GetFrameHeight() == surfaceProperties.GetFrameHeight()) {
6057 node.SetGpuOverDrawBufferOptimizeNode(true);
6058 node.SetOverDrawBufferNodeCornerRadius(curCornerRadius_);
6059 return;
6060 }
6061 }
6062
6063 node.SetGpuOverDrawBufferOptimizeNode(false);
6064 }
6065
6066 } // namespace Rosen
6067 } // namespace OHOS
6068