• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 #include "include/core/SkRegion.h"
19 #include "include/core/SkTextBlob.h"
20 #include "rs_trace.h"
21 
22 #include "common/rs_common_def.h"
23 #include "common/rs_obj_abs_geometry.h"
24 #include "pipeline/rs_base_render_node.h"
25 #include "pipeline/rs_base_render_util.h"
26 #include "pipeline/rs_cold_start_thread.h"
27 #include "pipeline/rs_display_render_node.h"
28 #include "pipeline/rs_main_thread.h"
29 #include "pipeline/rs_paint_filter_canvas.h"
30 #include "pipeline/rs_processor_factory.h"
31 #include "pipeline/rs_proxy_render_node.h"
32 #include "pipeline/rs_recording_canvas.h"
33 #include "pipeline/rs_root_render_node.h"
34 #include "pipeline/rs_surface_render_node.h"
35 #include "pipeline/rs_uni_render_listener.h"
36 #include "pipeline/rs_uni_render_mirror_processor.h"
37 #include "pipeline/rs_uni_render_util.h"
38 #include "platform/common/rs_log.h"
39 #include "platform/common/rs_system_properties.h"
40 #include "property/rs_properties_painter.h"
41 #include "render/rs_skia_filter.h"
42 
43 namespace OHOS {
44 namespace Rosen {
45 namespace {
46 constexpr uint32_t USE_CACHE_SURFACE_NUM = 7;
47 
IsFirstFrameReadyToDraw(RSSurfaceRenderNode & node)48 bool IsFirstFrameReadyToDraw(RSSurfaceRenderNode& node)
49 {
50     for (auto& child : node.GetSortedChildren()) {
51         if (child != nullptr && child->IsInstanceOf<RSRootRenderNode>()) {
52             auto rootNode = child->ReinterpretCastTo<RSRootRenderNode>();
53             const auto& property = rootNode->GetRenderProperties();
54             if (property.GetFrameWidth() > 0 && property.GetFrameHeight() > 0 && rootNode->GetEnableRender()) {
55                 return true;
56             }
57         }
58     }
59     return false;
60 }
61 }
RSUniRenderVisitor()62 RSUniRenderVisitor::RSUniRenderVisitor()
63     : curSurfaceDirtyManager_(std::make_shared<RSDirtyRegionManager>())
64 {
65     auto mainThread = RSMainThread::Instance();
66     renderEngine_ = mainThread->GetRenderEngine();
67     partialRenderType_ = RSSystemProperties::GetUniPartialRenderEnabled();
68     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
69     auto screenNum = screenManager->GetAllScreenIds().size();
70     isOcclusionEnabled_ = RSSystemProperties::GetOcclusionEnabled();
71     isPartialRenderEnabled_ = (screenNum <= 1) && (partialRenderType_ != PartialRenderType::DISABLED);
72     isDirtyRegionDfxEnabled_ = (RSSystemProperties::GetDirtyRegionDebugType() == DirtyRegionDebugType::EGL_DAMAGE);
73     isTargetDirtyRegionDfxEnabled_ = RSSystemProperties::GetTargetDirtyRegionDfxEnabled(dfxTargetSurfaceNames_);
74     if (isDirtyRegionDfxEnabled_ && isTargetDirtyRegionDfxEnabled_) {
75         isDirtyRegionDfxEnabled_ = false;
76     }
77     isOpDropped_ = isPartialRenderEnabled_ && (partialRenderType_ != PartialRenderType::SET_DAMAGE)
78         && (!isDirtyRegionDfxEnabled_ && !isTargetDirtyRegionDfxEnabled_);
79     // this config may downgrade the calcOcclusion performance when windows number become huge (i.e. > 30), keep it now
80     containerWindowConfig_ = RSSystemProperties::GetContainerWindowConfig();
81 }
~RSUniRenderVisitor()82 RSUniRenderVisitor::~RSUniRenderVisitor() {}
83 
PrepareBaseRenderNode(RSBaseRenderNode & node)84 void RSUniRenderVisitor::PrepareBaseRenderNode(RSBaseRenderNode& node)
85 {
86     node.ClearPaintOutOfParentRect();
87     node.UpdateChildrenOutOfRectFlag(false);
88     node.ResetSortedChildren();
89     for (auto& child : node.GetChildren()) {
90         if (auto renderChild = RSBaseRenderNode::ReinterpretCast<RSRenderNode>(child.lock())) {
91             renderChild->ApplyModifiers();
92         }
93     }
94     const auto& children = node.GetSortedChildren();
95 
96     // GetSortedChildren() may remove disappearingChildren_ when transition animation end.
97     // So the judgement whether node has removed child should be executed after this.
98     // merge last childRect as dirty if any child has been removed
99     if (curSurfaceDirtyManager_ && node.HasRemovedChild()) {
100         curSurfaceDirtyManager_->MergeDirtyRect(node.GetChildrenRect());
101         node.ResetHasRemovedChild();
102     }
103 
104     // reset childRect before prepare children
105     node.ResetChildrenRect();
106     for (auto& child : children) {
107         child->Prepare(shared_from_this());
108     }
109     SetPaintOutOfParentFlag(node);
110 }
111 
SetPaintOutOfParentFlag(RSBaseRenderNode & node)112 void RSUniRenderVisitor::SetPaintOutOfParentFlag(RSBaseRenderNode& node)
113 {
114     if (!isPartialRenderEnabled_) {
115         return;
116     }
117     if (node.GetType() != RSRenderNodeType::CANVAS_NODE && node.GetType() != RSRenderNodeType::SURFACE_NODE) {
118         RS_LOGD("Other types do not need to processed %d", node.GetType());
119         return;
120     }
121     auto nodeParent = node.GetParent().lock();
122     std::shared_ptr<RSRenderNode> rsParent = nullptr;
123     if (nodeParent == nullptr) {
124         return;
125     }
126     rsParent = nodeParent->ReinterpretCastTo<RSRenderNode>();
127     auto& property = node.shared_from_this()->ReinterpretCastTo<RSRenderNode>()->GetMutableRenderProperties();
128     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(property.GetBoundsGeometry());
129     RectI rect;
130     if (geoPtr != nullptr) {
131         rect = geoPtr->GetAbsRect();
132         rect = rect.JoinRect(node.ReinterpretCastTo<RSRenderNode>()->GetOldDirty());
133     }
134     RectI parentRect;
135     auto& parentProperty = rsParent->GetMutableRenderProperties();
136     auto parentGeoPtr = std::static_pointer_cast<RSObjAbsGeometry>(parentProperty.GetBoundsGeometry());
137     if (parentGeoPtr != nullptr) {
138         parentRect = parentGeoPtr->GetAbsRect();
139         parentRect = parentRect.JoinRect(rsParent->GetOldDirty());
140     }
141     if (node.HasChildrenOutOfRect()) {
142         if (!node.GetPaintOutOfParentRect().IsInsideOf(parentRect) || parentRect.IsEmpty()) {
143             nodeParent->UpdateChildrenOutOfRectFlag(true);
144             nodeParent->UpdatePaintOutOfParentRect(node.GetPaintOutOfParentRect());
145         }
146     } else {
147         if (!rect.IsInsideOf(parentRect) || parentRect.IsEmpty()) {
148             nodeParent->UpdateChildrenOutOfRectFlag(true);
149             nodeParent->UpdatePaintOutOfParentRect(rect);
150         }
151     }
152 }
153 
CheckColorSpace(RSSurfaceRenderNode & node)154 void RSUniRenderVisitor::CheckColorSpace(RSSurfaceRenderNode& node)
155 {
156     if (node.IsAppWindow()) {
157         auto surfaceNodeColorSpace = node.GetColorSpace();
158         if (surfaceNodeColorSpace != ColorGamut::COLOR_GAMUT_SRGB) {
159             ROSEN_LOGD("RSUniRenderVisitor::CheckColorSpace: node (%s) set new colorspace %d",
160                 node.GetName().c_str(), surfaceNodeColorSpace);
161             if (std::find(colorGamutmodes_.begin(), colorGamutmodes_.end(),
162                 static_cast<ScreenColorGamut>(surfaceNodeColorSpace)) != colorGamutmodes_.end()) {
163                 newColorSpace_ = surfaceNodeColorSpace;
164             } else {
165                 RS_LOGD("RSUniRenderVisitor::CheckColorSpace: colorSpace is not supported on current screen");
166             }
167         }
168     } else {
169         if (node.GetSortedChildren().size() > 0) {
170             auto surfaceNodePtr = node.GetSortedChildren().front()->ReinterpretCastTo<RSSurfaceRenderNode>();
171             if (!surfaceNodePtr) {
172                 return;
173             }
174             CheckColorSpace(*surfaceNodePtr);
175         }
176     }
177 }
178 
PrepareDisplayRenderNode(RSDisplayRenderNode & node)179 void RSUniRenderVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode& node)
180 {
181     currentVisitDisplay_ = node.GetScreenId();
182     displayHasSecSurface_.emplace(currentVisitDisplay_, false);
183     dirtySurfaceNodeMap_.clear();
184 
185     RS_TRACE_NAME("RSUniRender:PrepareDisplay " + std::to_string(currentVisitDisplay_));
186     curDisplayDirtyManager_ = node.GetDirtyManager();
187     curDisplayDirtyManager_->Clear();
188     curDisplayNode_ = node.shared_from_this()->ReinterpretCastTo<RSDisplayRenderNode>();
189 
190     dirtyFlag_ = isDirty_;
191 
192     node.ApplyModifiers();
193     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
194     if (!screenManager) {
195         RS_LOGE("RSUniRenderVisitor::PrepareDisplayRenderNode ScreenManager is nullptr");
196         return;
197     }
198     screenInfo_ = screenManager->QueryScreenInfo(node.GetScreenId());
199     screenManager->GetScreenSupportedColorGamuts(node.GetScreenId(), colorGamutmodes_);
200     for (auto& child : node.GetSortedChildren()) {
201         auto surfaceNodePtr = child->ReinterpretCastTo<RSSurfaceRenderNode>();
202         if (!surfaceNodePtr) {
203             RS_LOGE("RSUniRenderVisitor::PrepareDisplayRenderNode ReinterpretCastTo fail");
204             return;
205         }
206         CheckColorSpace(*surfaceNodePtr);
207     }
208     parentSurfaceNodeMatrix_ = SkMatrix::I();
209     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(node.GetRenderProperties().GetBoundsGeometry());
210     if (geoPtr != nullptr) {
211         geoPtr->UpdateByMatrixFromSelf();
212         parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
213     }
214     dirtyFlag_ = dirtyFlag_ || node.IsRotationChanged();
215     // when display is in rotation state, occlusion relationship will be ruined,
216     // hence partialrender quickreject should be disabled.
217     if(node.IsRotationChanged()) {
218         isOpDropped_ = false;
219     }
220     node.UpdateRotation();
221     curAlpha_ = node.GetRenderProperties().GetAlpha();
222     PrepareBaseRenderNode(node);
223     auto mirrorNode = node.GetMirrorSource().lock();
224     if (mirrorNode) {
225         mirroredDisplays_.insert(mirrorNode->GetScreenId());
226     }
227 
228     node.GetCurAllSurfaces().clear();
229     node.CollectSurface(node.shared_from_this(), node.GetCurAllSurfaces(), true);
230 }
231 
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)232 void RSUniRenderVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
233 {
234     if (node.GetSecurityLayer()) {
235         displayHasSecSurface_[currentVisitDisplay_] = true;
236     }
237     // avoid mouse error
238     if (node.GetName() == "pointer window") {
239         isOpDropped_ = false;
240         isPartialRenderEnabled_ = false;
241     }
242     node.CleanDstRectChanged();
243     node.ApplyModifiers();
244     bool dirtyFlag = dirtyFlag_;
245     bool isCustomizedDirtyRect = false;
246 
247     // update geoptr with ContextMatrix
248     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
249     auto& property = node.GetMutableRenderProperties();
250     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(property.GetBoundsGeometry());
251     float alpha = curAlpha_;
252     curAlpha_ *= (property.GetAlpha() * node.GetContextAlpha());
253     node.SetGlobalAlpha(curAlpha_);
254 
255     // prepare the surfaceRenderNode whose child is rootRenderNode
256     if (node.IsAppWindow() || node.GetSurfaceNodeType() == RSSurfaceNodeType::STARTING_WINDOW_NODE) {
257         curSurfaceDirtyManager_ = node.GetDirtyManager();
258         curSurfaceDirtyManager_->Clear();
259         curSurfaceDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
260         if (auto parentNode = node.GetParent().lock()) {
261             auto rsParent = RSBaseRenderNode::ReinterpretCast<RSRenderNode>(parentNode);
262             dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, &(rsParent->GetRenderProperties()), dirtyFlag_);
263         } else {
264             dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, nullptr, dirtyFlag_);
265         }
266         geoPtr->ConcatMatrix(node.GetContextMatrix());
267         node.SetDstRect(geoPtr->GetAbsRect().IntersectRect(RectI(0, 0, screenInfo_.width, screenInfo_.height)));
268         curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), node.GetOldDirtyInSurface());
269         if (node.IsAppWindow()) {
270             curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
271             boundsRect_ = SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight());
272             frameGravity_ = property.GetFrameGravity();
273         }
274     } else {
275         RSUniRenderUtil::UpdateRenderNodeDstRect(node, node.GetContextMatrix());
276         node.SetDstRect(geoPtr->GetAbsRect().IntersectRect(RectI(0, 0, screenInfo_.width, screenInfo_.height)));
277         if (node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE) {
278             curSurfaceDirtyManager_ = node.GetDirtyManager();
279             curSurfaceDirtyManager_->Clear();
280             curDisplayNode_->UpdateSurfaceNodePos(node.GetId(), node.GetDstRect());
281         }
282         if (node.GetBuffer() != nullptr) {
283             auto& surfaceHandler = static_cast<RSSurfaceHandler&>(node);
284             if (surfaceHandler.IsCurrentFrameBufferConsumed()) {
285                 curSurfaceDirtyManager_->MergeDirtyRect(node.GetDstRect());
286             }
287         }
288         isCustomizedDirtyRect = true;
289     }
290     // [planning] Remove this after skia is upgraded, the clipRegion is supported
291     if (node.GetRenderProperties().NeedFilter() && !node.IsAppFreeze()) {
292         needFilter_ = true;
293     }
294     dirtyFlag_ = dirtyFlag_ || node.GetDstRectChanged();
295     parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
296     node.ResetSurfaceOpaqueRegion(RectI(0, 0, screenInfo_.width, screenInfo_.height), geoPtr->GetAbsRect(),
297         containerWindowConfig_, node.IsFocusedWindow(currentFocusedPid_));
298 
299     PrepareBaseRenderNode(node);
300     // [planning] apply dirty rect instead of customized rect
301     node.UpdateParentChildrenRect(node.GetParent().lock(), isCustomizedDirtyRect, node.GetDstRect());
302     // restore flags
303     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
304     curAlpha_ = alpha;
305     dirtyFlag_ = dirtyFlag;
306     if (node.GetDstRectChanged() || (node.GetDirtyManager() && node.GetDirtyManager()->IsDirty())) {
307         dirtySurfaceNodeMap_.emplace(node.GetId(), node.ReinterpretCastTo<RSSurfaceRenderNode>());
308     }
309 }
310 
PrepareProxyRenderNode(RSProxyRenderNode & node)311 void RSUniRenderVisitor::PrepareProxyRenderNode(RSProxyRenderNode& node)
312 {
313     auto rsParent = RSBaseRenderNode::ReinterpretCast<RSRenderNode>(node.GetParent().lock());
314     if (rsParent == nullptr) {
315         return;
316     }
317     auto& property = rsParent->GetMutableRenderProperties();
318     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(property.GetBoundsGeometry());
319     SkMatrix invertMatrix;
320     SkMatrix contextMatrix = geoPtr->GetAbsMatrix();
321 
322     if (parentSurfaceNodeMatrix_.invert(&invertMatrix)) {
323         contextMatrix.preConcat(invertMatrix);
324     } else {
325         ROSEN_LOGE("RSUniRenderVisitor::PrepareProxyRenderNode, invertMatrix failed");
326     }
327     node.SetContextMatrix(contextMatrix);
328     node.SetContextAlpha(curAlpha_);
329 
330     PrepareBaseRenderNode(node);
331 }
332 
PrepareRootRenderNode(RSRootRenderNode & node)333 void RSUniRenderVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
334 {
335     node.ApplyModifiers();
336     bool dirtyFlag = dirtyFlag_;
337     float alpha = curAlpha_;
338     auto parentSurfaceNodeMatrix = parentSurfaceNodeMatrix_;
339 
340     auto rsParent = RSBaseRenderNode::ReinterpretCast<RSRenderNode>(node.GetParent().lock());
341     const auto& property = node.GetRenderProperties();
342     bool geoDirty = property.IsGeoDirty();
343     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(property.GetBoundsGeometry());
344 
345     dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent ? &(rsParent->GetRenderProperties()) : nullptr,
346         dirtyFlag_);
347     curAlpha_ *= property.GetAlpha();
348     if (rsParent == curSurfaceNode_) {
349         const float rootWidth = property.GetFrameWidth() * property.GetScaleX();
350         const float rootHeight = property.GetFrameHeight() * property.GetScaleY();
351         SkMatrix gravityMatrix;
352         (void)RSPropertiesPainter::GetGravityMatrix(frameGravity_,
353             RectF { 0.0f, 0.0f, boundsRect_.width(), boundsRect_.height() }, rootWidth, rootHeight, gravityMatrix);
354         // Only Apply gravityMatrix when rootNode is dirty
355         if (geoPtr != nullptr && (dirtyFlag || geoDirty)) {
356             geoPtr->ConcatMatrix(gravityMatrix);
357         }
358     }
359 
360     if (geoPtr != nullptr) {
361         parentSurfaceNodeMatrix_ = geoPtr->GetAbsMatrix();
362     }
363     PrepareBaseRenderNode(node);
364 
365     parentSurfaceNodeMatrix_ = parentSurfaceNodeMatrix;
366     curAlpha_ = alpha;
367     dirtyFlag_ = dirtyFlag;
368 }
369 
PrepareCanvasRenderNode(RSCanvasRenderNode & node)370 void RSUniRenderVisitor::PrepareCanvasRenderNode(RSCanvasRenderNode &node)
371 {
372     node.ApplyModifiers();
373     bool dirtyFlag = dirtyFlag_;
374     auto nodeParent = node.GetParent().lock();
375     while (nodeParent && nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>() &&
376         nodeParent->ReinterpretCastTo<RSSurfaceRenderNode>()->GetSurfaceNodeType() ==
377         RSSurfaceNodeType::SELF_DRAWING_NODE) {
378         nodeParent = nodeParent->GetParent().lock();
379     }
380     std::shared_ptr<RSRenderNode> rsParent = nullptr;
381     if (nodeParent != nullptr) {
382         rsParent = nodeParent->ReinterpretCastTo<RSRenderNode>();
383     }
384     dirtyFlag_ = node.Update(*curSurfaceDirtyManager_, rsParent ? &(rsParent->GetRenderProperties()) : nullptr,
385         dirtyFlag_);
386     float alpha = curAlpha_;
387     curAlpha_ *= node.GetRenderProperties().GetAlpha();
388 
389     PrepareBaseRenderNode(node);
390     // attention: accumulate direct parent's childrenRect
391     node.UpdateParentChildrenRect(node.GetParent().lock());
392 
393     // [planning] Remove this after skia is upgraded, the clipRegion is supported
394     if (node.GetRenderProperties().NeedFilter() && curSurfaceNode_) {
395         if (!curSurfaceNode_->IsAppFreeze()) {
396             needFilter_ = true;
397         }
398         filterRects_[curSurfaceNode_->GetId()].push_back(node.GetOldDirtyInSurface());
399     }
400     curAlpha_ = alpha;
401     dirtyFlag_ = dirtyFlag;
402 }
403 
DrawDirtyRectForDFX(const RectI & dirtyRect,const SkColor color,const SkPaint::Style fillType,float alpha)404 void RSUniRenderVisitor::DrawDirtyRectForDFX(const RectI& dirtyRect, const SkColor color,
405     const SkPaint::Style fillType, float alpha)
406 {
407     ROSEN_LOGD("DrawDirtyRectForDFX current dirtyRect = [%d, %d, %d, %d]", dirtyRect.left_, dirtyRect.top_,
408         dirtyRect.width_, dirtyRect.height_);
409     if (dirtyRect.width_ <= 0 || dirtyRect.height_ <= 0) {
410         ROSEN_LOGD("DrawDirtyRectForDFX dirty rect is invalid.");
411         return;
412     }
413     auto skRect = SkRect::MakeXYWH(dirtyRect.left_, dirtyRect.top_, dirtyRect.width_, dirtyRect.height_);
414     std::string position = std::to_string(dirtyRect.left_) + ',' + std::to_string(dirtyRect.top_) + ',' +
415         std::to_string(dirtyRect.width_) + ',' + std::to_string(dirtyRect.height_);
416     const int defaultEdgeWidth = 6;
417     const int defaultTextOffsetX = defaultEdgeWidth;
418     const int defaultTextOffsetY = 30; // text position has 30 pixelSize under the skRect
419     SkPaint rectPaint;
420     // font size: 24
421     sk_sp<SkTextBlob> SkTextBlob = SkTextBlob::MakeFromString(position.c_str(), SkFont(nullptr, 24.0f, 1.0f, 0.0f));
422     rectPaint.setColor(color);
423     rectPaint.setAntiAlias(true);
424     rectPaint.setAlphaf(alpha);
425     rectPaint.setStyle(fillType);
426     rectPaint.setStrokeWidth(defaultEdgeWidth);
427     if (fillType == SkPaint::kFill_Style) {
428         rectPaint.setStrokeJoin(SkPaint::kRound_Join);
429     }
430     canvas_->drawRect(skRect, rectPaint);
431     canvas_->drawTextBlob(SkTextBlob, dirtyRect.left_ + defaultTextOffsetX,
432         dirtyRect.top_ + defaultTextOffsetY, SkPaint());
433 }
434 
DrawDirtyRegionForDFX(std::vector<RectI> dirtyRects)435 void RSUniRenderVisitor::DrawDirtyRegionForDFX(std::vector<RectI> dirtyRects)
436 {
437     const float fillAlpha = 0.2;
438     for (const auto& subRect : dirtyRects) {
439         DrawDirtyRectForDFX(subRect, SK_ColorBLUE, SkPaint::kStroke_Style, fillAlpha);
440     }
441 }
442 
DrawAllSurfaceDirtyRegionForDFX(RSDisplayRenderNode & node,const Occlusion::Region & region)443 void RSUniRenderVisitor::DrawAllSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node, const Occlusion::Region& region)
444 {
445     RectI dirtySurfaceRect = node.GetDirtyManager()->GetDirtyRegion();
446     std::vector<Occlusion::Rect> visibleDirtyRects = region.GetRegionRects();
447     std::vector<RectI> rects;
448     rects.emplace_back(dirtySurfaceRect);
449     for (auto rect : visibleDirtyRects) {
450         rects.emplace_back(RectI(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_));
451     }
452     DrawDirtyRegionForDFX(rects);
453 }
454 
DrawTargetSurfaceDirtyRegionForDFX(RSDisplayRenderNode & node)455 void RSUniRenderVisitor::DrawTargetSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node)
456 {
457     for (auto it = node.GetCurAllSurfaces().rbegin(); it != node.GetCurAllSurfaces().rend(); ++it) {
458         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
459         if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
460             continue;
461         }
462         if (std::find(dfxTargetSurfaceNames_.begin(), dfxTargetSurfaceNames_.end(),
463             surfaceNode->GetName()) != dfxTargetSurfaceNames_.end()) {
464             auto visibleDirtyRegions = surfaceNode->GetVisibleDirtyRegion().GetRegionRects();
465             std::vector<RectI> rects;
466             for (auto rect : visibleDirtyRegions) {
467                 rects.emplace_back(RectI(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_));
468             }
469             auto visibleRegions = surfaceNode->GetVisibleRegion().GetRegionRects();
470             auto displayDirtyRegion = node.GetDirtyManager()->GetDirtyRegion();
471             for (auto rect : visibleRegions) {
472                 auto visibleRect = RectI(rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_);
473                 auto intersectRegion = displayDirtyRegion.IntersectRect(visibleRect);
474                 rects.emplace_back(intersectRegion);
475             }
476             DrawDirtyRegionForDFX(rects);
477         }
478     }
479 }
480 
ProcessBaseRenderNode(RSBaseRenderNode & node)481 void RSUniRenderVisitor::ProcessBaseRenderNode(RSBaseRenderNode& node)
482 {
483     for (auto& child : node.GetSortedChildren()) {
484         child->Process(shared_from_this());
485     }
486     // clear SortedChildren, it will be generated again in next frame
487     node.ResetSortedChildren();
488 }
489 
ProcessDisplayRenderNode(RSDisplayRenderNode & node)490 void RSUniRenderVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode& node)
491 {
492     RS_TRACE_NAME("ProcessDisplayRenderNode[" + std::to_string(node.GetScreenId()) + "]" +
493         node.GetDirtyManager()->GetDirtyRegion().ToString().c_str());
494     RS_LOGD("RSUniRenderVisitor::ProcessDisplayRenderNode node: %" PRIu64 ", child size:%u", node.GetId(),
495         node.GetChildrenCount());
496     sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
497     if (!screenManager) {
498         RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode ScreenManager is nullptr");
499         return;
500     }
501     screenInfo_ = screenManager->QueryScreenInfo(node.GetScreenId());
502     isSecurityDisplay_ = node.GetSecurityDisplay();
503     switch (screenInfo_.state) {
504         case ScreenState::PRODUCER_SURFACE_ENABLE:
505             node.SetCompositeType(RSDisplayRenderNode::CompositeType::UNI_RENDER_MIRROR_COMPOSITE);
506             break;
507         case ScreenState::HDI_OUTPUT_ENABLE:
508             node.SetCompositeType(node.IsForceSoftComposite() ?
509                 RSDisplayRenderNode::CompositeType::SOFTWARE_COMPOSITE :
510                 RSDisplayRenderNode::CompositeType::UNI_RENDER_COMPOSITE);
511             break;
512         default:
513             RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode ScreenState unsupported");
514             return;
515     }
516     offsetX_ = node.GetDisplayOffsetX();
517     offsetY_ = node.GetDisplayOffsetY();
518     processor_ = RSProcessorFactory::CreateProcessor(node.GetCompositeType());
519     if (processor_ == nullptr) {
520         RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode: RSProcessor is null!");
521         return;
522     }
523     auto mirrorNode = node.GetMirrorSource().lock();
524     if (!processor_->Init(node, node.GetDisplayOffsetX(), node.GetDisplayOffsetY(),
525         mirrorNode ? mirrorNode->GetScreenId() : INVALID_SCREEN_ID)) {
526         RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode: processor init failed!");
527         return;
528     }
529     std::shared_ptr<RSBaseRenderNode> nodePtr = node.shared_from_this();
530     auto displayNodePtr = nodePtr->ReinterpretCastTo<RSDisplayRenderNode>();
531     if (!displayNodePtr) {
532         RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode ReinterpretCastTo fail");
533         return;
534     }
535     if (!node.IsSurfaceCreated()) {
536         sptr<IBufferConsumerListener> listener = new RSUniRenderListener(displayNodePtr);
537         if (!node.CreateSurface(listener)) {
538             RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode CreateSurface failed");
539             return;
540         }
541     }
542 
543     if (mirrorNode) {
544         auto processor = std::static_pointer_cast<RSUniRenderMirrorProcessor>(processor_);
545         if (displayHasSecSurface_[mirrorNode->GetScreenId()] && mirrorNode->GetSecurityDisplay() != isSecurityDisplay_
546             && processor) {
547             canvas_ = processor->GetCanvas();
548             ProcessBaseRenderNode(*mirrorNode);
549         } else {
550             processor_->ProcessDisplaySurface(*mirrorNode);
551         }
552     } else {
553 #ifdef RS_ENABLE_EGLQUERYSURFACE
554         if (isPartialRenderEnabled_) {
555             curDisplayDirtyManager_->SetSurfaceSize(screenInfo_.width, screenInfo_.height);
556             CalcDirtyDisplayRegion(displayNodePtr);
557             CalcDirtyRegionForFilterNode(displayNodePtr);
558             displayNodePtr->ClearCurrentSurfacePos();
559         }
560         if (isOpDropped_ && dirtySurfaceNodeMap_.empty() && !curDisplayDirtyManager_->IsDirty()) {
561             RS_LOGD("DisplayNode skip");
562             return;
563         }
564 #endif
565         auto rsSurface = node.GetRSSurface();
566         if (rsSurface == nullptr) {
567             RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode No RSSurface found");
568             return;
569         }
570         rsSurface->SetColorSpace(newColorSpace_);
571         // we should request a framebuffer whose size is equals to the physical screen size.
572         RS_TRACE_BEGIN("RSUniRender:RequestFrame");
573         auto renderFrame = renderEngine_->RequestFrame(std::static_pointer_cast<RSSurfaceOhos>(rsSurface),
574             RSBaseRenderUtil::GetFrameBufferRequestConfig(screenInfo_, true));
575         RS_TRACE_END();
576         if (renderFrame == nullptr) {
577             RS_LOGE("RSUniRenderVisitor Request Frame Failed");
578             return;
579         }
580         std::shared_ptr<RSCanvasListener> overdrawListener = nullptr;
581         AddOverDrawListener(renderFrame, overdrawListener);
582 
583         if (canvas_ == nullptr) {
584             RS_LOGE("RSUniRenderVisitor::ProcessDisplayRenderNode: failed to create canvas");
585             return;
586         }
587         int saveLayerCnt = 0;
588         SkRegion region;
589         Occlusion::Region dirtyRegionTest;
590 #ifdef RS_ENABLE_EGLQUERYSURFACE
591         // Get displayNode buffer age in order to merge visible dirty region for displayNode.
592         // And then set egl damage region to improve uni_render efficiency.
593         if (isPartialRenderEnabled_) {
594             // Early history buffer Merging will have impact on Overdraw display, so we need to
595             // set the full screen dirty to avoid this impact.
596             if (RSOverdrawController::GetInstance().IsEnabled()) {
597                 node.GetDirtyManager()->ResetDirtyAsSurfaceSize();
598             }
599             int bufferAge = renderFrame->GetBufferAge();
600             RSUniRenderUtil::MergeDirtyHistory(displayNodePtr, bufferAge);
601             auto dirtyRegion = RSUniRenderUtil::MergeVisibleDirtyRegion(displayNodePtr);
602             dirtyRegionTest = dirtyRegion;
603             SetSurfaceGlobalDirtyRegion(displayNodePtr);
604             std::vector<RectI> rects = GetDirtyRects(dirtyRegion);
605             RectI rect = node.GetDirtyManager()->GetDirtyRegionFlipWithinSurface();
606             if (!rect.IsEmpty()) {
607                 rects.emplace_back(rect);
608             }
609             auto disH = screenInfo_.GetRotatedHeight();
610             for (auto& r : rects) {
611                 region.op(SkIRect::MakeXYWH(r.left_, disH - r.GetBottom(), r.width_, r.height_), SkRegion::kUnion_Op);
612                 RS_LOGD("SetDamageRegion %s", r.ToString().c_str());
613             }
614             // SetDamageRegion and opDrop will be disabled for dirty region DFX visualization
615             if (!isDirtyRegionDfxEnabled_ && !isTargetDirtyRegionDfxEnabled_) {
616                 renderFrame->SetDamageRegion(rects);
617             }
618         }
619         if (isOpDropped_) {
620             if (region.isEmpty()) {
621                 // [planning] Remove this after frame buffer can cancel
622                 canvas_->clipRect(SkRect::MakeEmpty());
623             } else if (region.isRect()) {
624                 canvas_->clipRegion(region);
625             } else {
626                 SkPath dirtyPath;
627                 region.getBoundaryPath(&dirtyPath);
628                 canvas_->clipPath(dirtyPath, true);
629                 // [planning] Remove this after skia is upgraded, the clipRegion is supported
630                 if (!needFilter_) {
631                     saveLayerCnt = canvas_->saveLayer(SkRect::MakeWH(screenInfo_.width, screenInfo_.height), nullptr);
632                 }
633             }
634         }
635 #endif
636         int saveCount = canvas_->save();
637         canvas_->SetHighContrast(renderEngine_->IsHighContrastEnabled());
638         RSPropertiesPainter::SetBgAntiAlias(true);
639         auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(node.GetRenderProperties().GetBoundsGeometry());
640         if (geoPtr != nullptr) {
641             canvas_->concat(geoPtr->GetMatrix());
642             // enable cache if screen rotation is not times of 90 degree
643             canvas_->SetCacheEnabled(geoPtr->IsNeedClientCompose());
644         }
645         canvas_->SetCacheEnabled(canvas_->isCacheEnabled() || node.GetCurAllSurfaces().size() > USE_CACHE_SURFACE_NUM);
646         if (canvas_->isCacheEnabled()) {
647             // we are doing rotation animation, try offscreen render if capable
648             PrepareOffscreenRender(node);
649             ProcessBaseRenderNode(node);
650             FinishOffscreenRender();
651         } else {
652             // render directly
653             ProcessBaseRenderNode(node);
654         }
655         canvas_->restoreToCount(saveCount);
656 
657         if (saveLayerCnt > 0) {
658             RS_TRACE_NAME("RSUniRender:RestoreLayer");
659             canvas_->restoreToCount(saveLayerCnt);
660         }
661 
662         if (overdrawListener != nullptr) {
663             overdrawListener->Draw();
664         }
665         // the following code makes DirtyRegion visible, enable this method by turning on the dirtyregiondebug property
666         if (isPartialRenderEnabled_) {
667             if (isDirtyRegionDfxEnabled_) {
668                 DrawAllSurfaceDirtyRegionForDFX(node, dirtyRegionTest);
669             }
670             if (isTargetDirtyRegionDfxEnabled_) {
671                 DrawTargetSurfaceDirtyRegionForDFX(node);
672             }
673         }
674         RS_TRACE_BEGIN("RSUniRender:FlushFrame");
675         renderFrame->Flush();
676         RS_TRACE_END();
677         RS_TRACE_BEGIN("RSUniRender:WaitUtilUniRenderFinished");
678         RSMainThread::Instance()->WaitUtilUniRenderFinished();
679         RS_TRACE_END();
680         processor_->ProcessDisplaySurface(node);
681     }
682     processor_->PostProcess();
683 
684     // We should release DisplayNode's surface buffer after PostProcess(),
685     // since the buffer's releaseFence was set in PostProcess().
686     auto& surfaceHandler = static_cast<RSSurfaceHandler&>(node);
687     (void)RSUniRenderUtil::ReleaseBuffer(surfaceHandler);
688     RS_LOGD("RSUniRenderVisitor::ProcessDisplayRenderNode end");
689 }
690 
AddOverDrawListener(std::unique_ptr<RSRenderFrame> & renderFrame,std::shared_ptr<RSCanvasListener> & overdrawListener)691 void RSUniRenderVisitor::AddOverDrawListener(std::unique_ptr<RSRenderFrame>& renderFrame,
692     std::shared_ptr<RSCanvasListener>& overdrawListener)
693 {
694     if (renderFrame->GetFrame() == nullptr) {
695         RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: RSSurfaceFrame is null");
696         return;
697     }
698     auto skSurface = renderFrame->GetFrame()->GetSurface();
699     if (skSurface == nullptr) {
700         RS_LOGE("RSUniRenderVisitor::AddOverDrawListener: skSurface is null");
701         return;
702     }
703     if (skSurface->getCanvas() == nullptr) {
704         ROSEN_LOGE("skSurface.getCanvas is null.");
705         return;
706     }
707     // if listenedCanvas is nullptr, that means disabled or listen failed
708     std::shared_ptr<RSListenedCanvas> listenedCanvas = nullptr;
709 
710     if (RSOverdrawController::GetInstance().IsEnabled()) {
711         auto &oc = RSOverdrawController::GetInstance();
712         listenedCanvas = std::make_shared<RSListenedCanvas>(skSurface.get());
713         overdrawListener = oc.CreateListener<RSGPUOverdrawCanvasListener>(listenedCanvas.get());
714         if (overdrawListener == nullptr) {
715             overdrawListener = oc.CreateListener<RSCPUOverdrawCanvasListener>(listenedCanvas.get());
716         }
717 
718         if (overdrawListener != nullptr) {
719             listenedCanvas->SetListener(overdrawListener);
720         } else {
721             // create listener failed
722             listenedCanvas = nullptr;
723         }
724     }
725 
726     if (listenedCanvas != nullptr) {
727         canvas_ = listenedCanvas;
728     } else {
729         canvas_ = std::make_shared<RSPaintFilterCanvas>(skSurface.get());
730     }
731 }
732 
CalcDirtyDisplayRegion(std::shared_ptr<RSDisplayRenderNode> & node) const733 void RSUniRenderVisitor::CalcDirtyDisplayRegion(std::shared_ptr<RSDisplayRenderNode>& node) const
734 {
735     RS_TRACE_FUNC();
736     auto displayDirtyManager = node->GetDirtyManager();
737     for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
738         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
739         if (surfaceNode == nullptr) {
740             continue;
741         }
742         auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
743         RectI surfaceDirtyRect = surfaceDirtyManager->GetDirtyRegion();
744         if (surfaceNode->IsTransparent()) {
745             // Handles the case of transparent surface, merge transparent dirty rect
746             RectI transparentDirtyRect = surfaceNode->GetDstRect().IntersectRect(surfaceDirtyRect);
747             if (!transparentDirtyRect.IsEmpty()) {
748                 RS_LOGD("CalcDirtyDisplayRegion merge transparent dirty rect %s rect %s",
749                     surfaceNode->GetName().c_str(), transparentDirtyRect.ToString().c_str());
750                 displayDirtyManager->MergeDirtyRect(transparentDirtyRect);
751             }
752         }
753 
754         if (surfaceNode->GetZorderChanged()) {
755             // Zorder changed case, merge surface dest Rect
756             RS_LOGD("CalcDirtyDisplayRegion merge GetZorderChanged %s rect %s", surfaceNode->GetName().c_str(),
757                 surfaceNode->GetDstRect().ToString().c_str());
758             displayDirtyManager->MergeDirtyRect(surfaceNode->GetDstRect());
759         }
760 
761         RectI lastFrameSurfacePos = node->GetLastFrameSurfacePos(surfaceNode->GetId());
762         RectI currentFrameSurfacePos = node->GetCurrentFrameSurfacePos(surfaceNode->GetId());
763         if (lastFrameSurfacePos != currentFrameSurfacePos) {
764             RS_LOGD("CalcDirtyDisplayRegion merge surface pos changed %s lastFrameRect %s currentFrameRect %s",
765                 surfaceNode->GetName().c_str(), lastFrameSurfacePos.ToString().c_str(),
766                 currentFrameSurfacePos.ToString().c_str());
767             if (!lastFrameSurfacePos.IsEmpty()) {
768                 displayDirtyManager->MergeDirtyRect(lastFrameSurfacePos);
769             }
770             if (!currentFrameSurfacePos.IsEmpty()) {
771                 displayDirtyManager->MergeDirtyRect(currentFrameSurfacePos);
772             }
773         }
774 
775         bool isShadowDisappear = !surfaceNode->GetRenderProperties().IsShadowValid() && surfaceNode->IsShadowValidLastFrame();
776         if (surfaceNode->GetRenderProperties().IsShadowValid() || isShadowDisappear) {
777             RectI shadowDirtyRect = surfaceNode->GetOldDirtyInSurface().IntersectRect(surfaceDirtyRect);
778             RS_LOGD("CalcDirtyDisplayRegion merge ShadowValid %s rect %s",
779                 surfaceNode->GetName().c_str(), surfaceNode->GetOldDirtyInSurface().ToString().c_str());
780             // There are two situation here:
781             // 1. SurfaceNode first has shadow or shadow radius is larger than the last frame,
782             // surfaceDirtyRect == surfaceNode->GetOldDirtyInSurface()
783             // 2. SurfaceNode remove shadow or shadow radius is smaller than the last frame,
784             // surfaceDirtyRect > surfaceNode->GetOldDirtyInSurface()
785             // So we should always merge surfaceDirtyRect here.
786             if (!shadowDirtyRect.IsEmpty()) {
787                 displayDirtyManager->MergeDirtyRect(surfaceDirtyRect);
788             }
789             if (isShadowDisappear) {
790                 surfaceNode->SetShadowValidLastFrame(false);
791             }
792         }
793         auto transparentRegion = surfaceNode->GetTransparentRegion();
794         Occlusion::Rect tmpRect = Occlusion::Rect { surfaceDirtyRect.left_, surfaceDirtyRect.top_,
795             surfaceDirtyRect.GetRight(), surfaceDirtyRect.GetBottom() };
796         Occlusion::Region surfaceDirtyRegion { tmpRect };
797         Occlusion::Region transparentDirtyRegion = transparentRegion.And(surfaceDirtyRegion);
798         std::vector<Occlusion::Rect> rects = transparentDirtyRegion.GetRegionRects();
799         for (const auto& rect : rects) {
800             displayDirtyManager->MergeDirtyRect(RectI
801                 { rect.left_, rect.top_, rect.right_ - rect.left_, rect.bottom_ - rect.top_ });
802         }
803     }
804     std::vector<RectI> surfaceChangedRects = node->GetSurfaceChangedRects();
805     for (auto& surfaceChangedRect : surfaceChangedRects) {
806         RS_LOGD("CalcDirtyDisplayRegion merge Surface closed %s", surfaceChangedRect.ToString().c_str());
807         if (!surfaceChangedRect.IsEmpty()) {
808             displayDirtyManager->MergeDirtyRect(surfaceChangedRect);
809         }
810     }
811 }
812 
CalcDirtyRegionForFilterNode(std::shared_ptr<RSDisplayRenderNode> & node) const813 void RSUniRenderVisitor::CalcDirtyRegionForFilterNode(std::shared_ptr<RSDisplayRenderNode>& node) const
814 {
815     auto displayDirtyManager = node->GetDirtyManager();
816     RectI displayDirtyRect = displayDirtyManager ? displayDirtyManager->GetDirtyRegion() : RectI{0, 0, 0, 0};
817     for (auto it = node->GetCurAllSurfaces().begin(); it != node->GetCurAllSurfaces().end(); ++it) {
818         auto currentSurfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
819         if (currentSurfaceNode == nullptr) {
820             continue;
821         }
822         auto currentSurfaceDirtyManager = currentSurfaceNode->GetDirtyManager();
823         RectI currentSurfaceDirtyRect = currentSurfaceDirtyManager->GetDirtyRegion();
824         NodeId currentSurfaceNodeId = currentSurfaceNode->GetId();
825 
826         // child node (component) has filter
827         if (filterRects_.find(currentSurfaceNodeId) != filterRects_.end()) {
828             auto rectVec = filterRects_.find(currentSurfaceNodeId)->second;
829             for (auto rectIt = rectVec.begin(); rectIt != rectVec.end(); ++rectIt) {
830                 if (!displayDirtyRect.IntersectRect(*rectIt).IsEmpty()) {
831                     if (currentSurfaceNode->IsTransparent()) {
832                         displayDirtyManager->MergeDirtyRect(*rectIt);
833                     }
834                     currentSurfaceDirtyManager->MergeDirtyRect(*rectIt);
835                 } else if (!currentSurfaceDirtyRect.IntersectRect(*rectIt).IsEmpty()) {
836                     currentSurfaceDirtyManager->MergeDirtyRect(*rectIt);
837                 }
838             }
839         }
840 
841         // surfaceNode self has filter
842         if (currentSurfaceNode->GetRenderProperties().NeedFilter()) {
843             if (!displayDirtyRect.IntersectRect(currentSurfaceNode->GetOldDirtyInSurface()).IsEmpty() ||
844                 !currentSurfaceDirtyRect.IntersectRect(currentSurfaceNode->GetOldDirtyInSurface()).IsEmpty()) {
845                 currentSurfaceDirtyManager->MergeDirtyRect(currentSurfaceNode->GetOldDirtyInSurface());
846             }
847 
848             if (currentSurfaceNode->IsTransparent()) {
849                 for (auto iter = node->GetCurAllSurfaces().begin(); iter != node->GetCurAllSurfaces().end(); ++iter) {
850                     auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*iter);
851                     if (surfaceNode == nullptr) {
852                         continue;
853                     }
854                     if (!surfaceNode->GetDirtyManager()->GetDirtyRegion().IntersectRect(
855                         currentSurfaceNode->GetOldDirtyInSurface()).IsEmpty()) {
856                         currentSurfaceDirtyManager->MergeDirtyRect(currentSurfaceNode->GetOldDirtyInSurface());
857                         displayDirtyManager->MergeDirtyRect(currentSurfaceNode->GetOldDirtyInSurface());
858                         break;
859                     }
860                 }
861             }
862         }
863     }
864 }
865 
SetSurfaceGlobalDirtyRegion(std::shared_ptr<RSDisplayRenderNode> & node)866 void RSUniRenderVisitor::SetSurfaceGlobalDirtyRegion(std::shared_ptr<RSDisplayRenderNode>& node)
867 {
868     RS_TRACE_FUNC();
869     for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
870         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
871         if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
872             continue;
873         }
874         // set display dirty region to surfaceNode
875         surfaceNode->SetGloblDirtyRegion(node->GetDirtyManager()->GetDirtyRegion());
876     }
877     Occlusion::Region curVisibleDirtyRegion;
878     for (auto it = node->GetCurAllSurfaces().begin(); it != node->GetCurAllSurfaces().end(); ++it) {
879         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
880         if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
881             continue;
882         }
883         // set display dirty region to surfaceNode
884         surfaceNode->SetDirtyRegionBelowCurrentLayer(curVisibleDirtyRegion);
885         auto visibleDirtyRegion = surfaceNode->GetVisibleDirtyRegion();
886         curVisibleDirtyRegion = curVisibleDirtyRegion.Or(visibleDirtyRegion);
887     }
888 }
889 
890 #ifdef RS_ENABLE_EGLQUERYSURFACE
GetDirtyRects(const Occlusion::Region & region)891 std::vector<RectI> RSUniRenderVisitor::GetDirtyRects(const Occlusion::Region &region)
892 {
893     std::vector<Occlusion::Rect> rects = region.GetRegionRects();
894     std::vector<RectI> retRects;
895     for (const Occlusion::Rect& rect : rects) {
896         // origin transformation
897         retRects.emplace_back(RectI(rect.left_, screenInfo_.GetRotatedHeight() - rect.bottom_,
898             rect.right_ - rect.left_, rect.bottom_ - rect.top_));
899     }
900     RS_LOGD("GetDirtyRects size %d %s", region.GetSize(), region.GetRegionInfo().c_str());
901     return retRects;
902 }
903 #endif
904 
InitCacheSurface(RSSurfaceRenderNode & node,int width,int height)905 void RSUniRenderVisitor::InitCacheSurface(RSSurfaceRenderNode& node, int width, int height)
906 {
907 #if (defined RS_ENABLE_GL) && (defined RS_ENABLE_EGLIMAGE)
908     SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
909     node.SetCacheSurface(SkSurface::MakeRenderTarget(canvas_->getGrContext(), SkBudgeted::kYes, info));
910 #else
911     node.SetCacheSurface(SkSurface::MakeRasterN32Premul(width, height));
912 #endif
913 }
914 
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)915 void RSUniRenderVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
916 {
917     RS_TRACE_NAME("RSUniRender::Process:[" + node.GetName() + "]" + node.GetDstRect().ToString());
918     RS_LOGD("RSUniRenderVisitor::ProcessSurfaceRenderNode node: %" PRIu64 ", child size:%u %s", node.GetId(),
919         node.GetChildrenCount(), node.GetName().c_str());
920     node.UpdatePositionZ();
921     if (isSecurityDisplay_ && node.GetSecurityLayer()) {
922         RS_TRACE_NAME("SecurityLayer Skip");
923         return;
924     }
925     if (node.GetSurfaceNodeType() == RSSurfaceNodeType::STARTING_WINDOW_NODE && !needDrawStartingWindow_) {
926         RS_LOGD("RSUniRenderVisitor::ProcessSurfaceRenderNode skip startingWindow");
927         return;
928     }
929     const auto& property = node.GetRenderProperties();
930     if (!node.ShouldPaint()) {
931         RS_LOGD("RSUniRenderVisitor::ProcessSurfaceRenderNode node: %" PRIu64 " invisible", node.GetId());
932         return;
933     }
934     if (!node.GetOcclusionVisible() && !doAnimate_ && isOcclusionEnabled_ && !isSecurityDisplay_) {
935         RS_TRACE_NAME("Occlusion Skip");
936         return;
937     }
938 #ifdef RS_ENABLE_EGLQUERYSURFACE
939     // skip clean surface node
940     if (isOpDropped_ && node.IsAppWindow()) {
941         if (!node.SubNodeNeedDraw(node.GetOldDirtyInSurface(), partialRenderType_)) {
942             RS_TRACE_NAME("QuickReject Skip");
943             RS_LOGD("RSUniRenderVisitor::ProcessSurfaceRenderNode skip: %s", node.GetName().c_str());
944             return;
945         }
946     }
947     if (node.IsAppWindow()) {
948         curSurfaceNode_ = node.ReinterpretCastTo<RSSurfaceRenderNode>();
949     }
950 #endif
951 
952     if (!canvas_) {
953         RS_LOGE("RSUniRenderVisitor::ProcessSurfaceRenderNode, canvas is nullptr");
954         return;
955     }
956     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(property.GetBoundsGeometry());
957     if (!geoPtr) {
958         RS_LOGE("RSUniRenderVisitor::ProcessSurfaceRenderNode node:%" PRIu64 ", get geoPtr failed", node.GetId());
959         return;
960     }
961 
962 #ifdef RS_ENABLE_EGLQUERYSURFACE
963     // when display is in rotation state, occlusion relationship will be ruined,
964     // hence visibleRegions cannot be used.
965     if (isOpDropped_ && node.IsAppWindow()) {
966         auto visibleRegions = node.GetVisibleRegion().GetRegionRects();
967         if (visibleRegions.size() == 1) {
968             canvas_->SetVisibleRect(SkRect::MakeLTRB(
969                 visibleRegions[0].left_, visibleRegions[0].top_, visibleRegions[0].right_, visibleRegions[0].bottom_));
970         }
971     }
972 #endif
973 
974     if (node.GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
975         needDrawStartingWindow_ = true; // reset to default value
976         needColdStartThread_ = RSSystemProperties::GetColdStartThreadEnabled() &&
977                                !node.IsStartAnimationFinished() && doAnimate_;
978         needCheckFirstFrame_ = node.GetChildrenCount() > 1; // childCount > 1 means startingWindow and appWindow
979     }
980 
981     if (node.IsAppWindow() && needColdStartThread_ && needCheckFirstFrame_ &&
982         !RSColdStartManager::Instance().IsColdStartThreadRunning(node.GetId())) {
983         if (!IsFirstFrameReadyToDraw(node)) {
984             return;
985         }
986         auto nodePtr = node.shared_from_this();
987         RSColdStartManager::Instance().StartColdStartThreadIfNeed(nodePtr->ReinterpretCastTo<RSSurfaceRenderNode>());
988         RecordAppWindowNodeAndPostTask(node, property.GetBoundsWidth(), property.GetBoundsHeight());
989         return;
990     }
991 
992     auto savedState = canvas_->SaveCanvasAndAlpha();
993     auto bgAntiAliasState = RSPropertiesPainter::GetBgAntiAlias();
994     if (doAnimate_ && (!ROSEN_EQ(geoPtr->GetScaleX(), 1.f) || !ROSEN_EQ(geoPtr->GetScaleY(), 1.f))) {
995         // disable background antialias when surfacenode has scale animation
996         RSPropertiesPainter::SetBgAntiAlias(false);
997     }
998 
999     canvas_->MultiplyAlpha(property.GetAlpha());
1000     canvas_->MultiplyAlpha(node.GetContextAlpha());
1001 
1002     bool isSelfDrawingSurface = node.GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE;
1003     if (isSelfDrawingSurface) {
1004         canvas_->save();
1005     }
1006 
1007     canvas_->concat(geoPtr->GetMatrix());
1008 
1009     const RectF absBounds = {0, 0, property.GetBoundsWidth(), property.GetBoundsHeight()};
1010     RRect absClipRRect = RRect(absBounds, property.GetCornerRadius());
1011     RSPropertiesPainter::DrawShadow(property, *canvas_, &absClipRRect);
1012 
1013     if (isSelfDrawingSurface) {
1014         canvas_->save();
1015     }
1016 
1017     if (node.GetSurfaceNodeType() != RSSurfaceNodeType::LEASH_WINDOW_NODE) {
1018         if (!property.GetCornerRadius().IsZero()) {
1019             canvas_->clipRRect(RSPropertiesPainter::RRect2SkRRect(absClipRRect), true);
1020         } else {
1021             canvas_->clipRect(SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight()));
1022         }
1023     }
1024 
1025     RSPropertiesPainter::DrawBackground(property, *canvas_);
1026     RSPropertiesPainter::DrawMask(property, *canvas_);
1027     auto filter = std::static_pointer_cast<RSSkiaFilter>(property.GetBackgroundFilter());
1028     if (filter != nullptr) {
1029         auto skRectPtr = std::make_unique<SkRect>();
1030         skRectPtr->setXYWH(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
1031         RSPropertiesPainter::DrawFilter(property, *canvas_, filter, skRectPtr, canvas_->GetSurface());
1032     }
1033 
1034     if (isSelfDrawingSurface) {
1035         canvas_->restore();
1036     }
1037 
1038     node.SetTotalMatrix(canvas_->getTotalMatrix());
1039 
1040     if (!node.IsAppWindow() && node.GetBuffer() != nullptr) {
1041         node.NotifyRTBufferAvailable();
1042         node.SetGlobalAlpha(1.0f);
1043         auto params = RSUniRenderUtil::CreateBufferDrawParam(node, false);
1044         renderEngine_->DrawSurfaceNodeWithParams(*canvas_, node, params);
1045     }
1046 
1047     if (isSelfDrawingSurface) {
1048         canvas_->restore();
1049     }
1050 
1051     if (node.IsAppWindow() &&
1052         (!needColdStartThread_ || !RSColdStartManager::Instance().IsColdStartThreadRunning(node.GetId()))) {
1053         if (RSColdStartManager::Instance().IsColdStartThreadRunning(node.GetId())) {
1054             node.ClearCachedImage();
1055             RSColdStartManager::Instance().StopColdStartThread(node.GetId());
1056         }
1057         if (needCheckFirstFrame_ && IsFirstFrameReadyToDraw(node)) {
1058             node.NotifyUIBufferAvailable();
1059             needDrawStartingWindow_ = false;
1060         }
1061         if (!node.IsAppFreeze()) {
1062             ProcessBaseRenderNode(node);
1063             node.ClearCacheSurface();
1064         } else if (node.GetCacheSurface()) {
1065             RSUniRenderUtil::DrawCachedSurface(node, *canvas_, node.GetCacheSurface());
1066         } else {
1067             InitCacheSurface(node, property.GetBoundsWidth(), property.GetBoundsHeight());
1068             if (node.GetCacheSurface()) {
1069                 auto cacheCanvas = std::make_shared<RSPaintFilterCanvas>(node.GetCacheSurface().get());
1070 
1071                 swap(cacheCanvas, canvas_);
1072                 ProcessBaseRenderNode(node);
1073                 swap(cacheCanvas, canvas_);
1074 
1075                 RSUniRenderUtil::DrawCachedSurface(node, *canvas_, node.GetCacheSurface());
1076             } else {
1077                 RS_LOGE("RSUniRenderVisitor::ProcessSurfaceRenderNode %s Create CacheSurface failed",
1078                     node.GetName().c_str());
1079             }
1080         }
1081     } else if (node.IsAppWindow()) { // use skSurface drawn by cold start thread
1082         if (node.GetCachedImage() != nullptr) {
1083             needDrawStartingWindow_ = false;
1084             RSUniRenderUtil::DrawCachedImage(node, *canvas_, node.GetCachedImage());
1085         }
1086         RecordAppWindowNodeAndPostTask(node, property.GetBoundsWidth(), property.GetBoundsHeight());
1087     } else {
1088         ProcessBaseRenderNode(node);
1089     }
1090 
1091     if (node.GetSurfaceNodeType() == RSSurfaceNodeType::LEASH_WINDOW_NODE) {
1092         // reset to default value
1093         needColdStartThread_ = false;
1094         needCheckFirstFrame_ = false;
1095     }
1096 
1097     filter = std::static_pointer_cast<RSSkiaFilter>(property.GetFilter());
1098     if (filter != nullptr) {
1099         auto skRectPtr = std::make_unique<SkRect>();
1100         skRectPtr->setXYWH(0, 0, property.GetBoundsWidth(), property.GetBoundsHeight());
1101         RSPropertiesPainter::DrawFilter(property, *canvas_, filter, skRectPtr, canvas_->GetSurface());
1102     }
1103 
1104     RSPropertiesPainter::SetBgAntiAlias(bgAntiAliasState);
1105     canvas_->RestoreCanvasAndAlpha(savedState);
1106     if (node.IsAppWindow()) {
1107         canvas_->SetVisibleRect(SkRect::MakeLTRB(0, 0, 0, 0));
1108     }
1109 }
1110 
ProcessProxyRenderNode(RSProxyRenderNode & node)1111 void RSUniRenderVisitor::ProcessProxyRenderNode(RSProxyRenderNode& node)
1112 {
1113     ProcessBaseRenderNode(node);
1114 }
1115 
ProcessRootRenderNode(RSRootRenderNode & node)1116 void RSUniRenderVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
1117 {
1118     RS_LOGD("RSUniRenderVisitor::ProcessRootRenderNode node: %" PRIu64 ", child size:%u", node.GetId(),
1119         node.GetChildrenCount());
1120     if (!node.ShouldPaint()) {
1121         RS_LOGD("RSUniRenderVisitor::ProcessRootRenderNode, no need process");
1122         return;
1123     }
1124     if (!canvas_) {
1125         RS_LOGE("RSUniRenderVisitor::ProcessRootRenderNode, canvas is nullptr");
1126         return;
1127     }
1128 
1129     ColorFilterMode colorFilterMode = renderEngine_->GetColorFilterMode();
1130     int saveCount;
1131     if (colorFilterMode >= ColorFilterMode::INVERT_COLOR_ENABLE_MODE &&
1132         colorFilterMode <= ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE) {
1133         RS_LOGD("RsDebug RSBaseRenderEngine::SetColorFilterModeToPaint mode:%d", static_cast<int32_t>(colorFilterMode));
1134         SkPaint paint;
1135         RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode, paint);
1136         saveCount = canvas_->saveLayer(nullptr, &paint);
1137     } else {
1138         saveCount = canvas_->save();
1139     }
1140     ProcessCanvasRenderNode(node);
1141     canvas_->restoreToCount(saveCount);
1142 }
1143 
ProcessCanvasRenderNode(RSCanvasRenderNode & node)1144 void RSUniRenderVisitor::ProcessCanvasRenderNode(RSCanvasRenderNode& node)
1145 {
1146     if (!node.ShouldPaint()) {
1147         RS_LOGD("RSUniRenderVisitor::ProcessCanvasRenderNode, no need process");
1148         return;
1149     }
1150 #ifdef RS_ENABLE_EGLQUERYSURFACE
1151     if (isOpDropped_ && curSurfaceNode_ &&
1152         !curSurfaceNode_->SubNodeNeedDraw(node.GetOldDirtyInSurface(), partialRenderType_) &&
1153         !node.HasChildrenOutOfRect()) {
1154         return;
1155     }
1156 #endif
1157     if (!canvas_) {
1158         RS_LOGE("RSUniRenderVisitor::ProcessCanvasRenderNode, canvas is nullptr");
1159         return;
1160     }
1161     node.ProcessRenderBeforeChildren(*canvas_);
1162     ProcessBaseRenderNode(node);
1163     node.ProcessRenderAfterChildren(*canvas_);
1164 }
1165 
RecordAppWindowNodeAndPostTask(RSSurfaceRenderNode & node,float width,float height)1166 void RSUniRenderVisitor::RecordAppWindowNodeAndPostTask(RSSurfaceRenderNode& node, float width, float height)
1167 {
1168     RSRecordingCanvas canvas(width, height);
1169 #ifdef RS_ENABLE_GL
1170     canvas.SetGrContext(canvas_->getGrContext()); // SkImage::MakeFromCompressed need GrContext
1171 #endif
1172     auto recordingCanvas = std::make_shared<RSPaintFilterCanvas>(&canvas);
1173     swap(canvas_, recordingCanvas);
1174     ProcessBaseRenderNode(node);
1175     swap(canvas_, recordingCanvas);
1176     RSColdStartManager::Instance().PostPlayBackTask(node.GetId(), canvas.GetDrawCmdList(), width, height);
1177 }
1178 
PrepareOffscreenRender(RSRenderNode & node)1179 void RSUniRenderVisitor::PrepareOffscreenRender(RSRenderNode& node)
1180 {
1181     // cleanup
1182     canvasBackup_ = nullptr;
1183     offscreenSurface_ = nullptr;
1184     // check offscreen size and hardware renderer
1185     int32_t offscreenWidth = node.GetRenderProperties().GetFrameWidth();
1186     int32_t offscreenHeight = node.GetRenderProperties().GetFrameHeight();
1187     if (offscreenWidth <= 0 || offscreenHeight <= 0) {
1188         RS_LOGD("RSUniRenderVisitor::PrepareOffscreenRender, offscreenWidth or offscreenHeight is invalid");
1189         return;
1190     }
1191     if (canvas_->GetSurface() == nullptr) {
1192         canvas_->clipRect(SkRect::MakeWH(offscreenWidth, offscreenHeight));
1193         RS_LOGD("RSUniRenderVisitor::PrepareOffscreenRender, current surface is nullptr (software renderer?)");
1194         return;
1195     }
1196     // create offscreen surface and canvas
1197     auto offscreenInfo = SkImageInfo::Make(offscreenWidth, offscreenHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType,
1198         canvas_->GetSurface()->imageInfo().refColorSpace());
1199     offscreenSurface_ = canvas_->GetSurface()->makeSurface(offscreenInfo);
1200     if (offscreenSurface_ == nullptr) {
1201         RS_LOGD("RSUniRenderVisitor::PrepareOffscreenRender, offscreenSurface is nullptr");
1202         canvas_->clipRect(SkRect::MakeWH(offscreenWidth, offscreenHeight));
1203         return;
1204     }
1205     auto offscreenCanvas = std::make_shared<RSPaintFilterCanvas>(offscreenSurface_.get());
1206     // backup current canvas and replace with offscreen canvas
1207     canvasBackup_ = std::move(canvas_);
1208     canvas_ = std::move(offscreenCanvas);
1209 }
1210 
FinishOffscreenRender()1211 void RSUniRenderVisitor::FinishOffscreenRender()
1212 {
1213     if (canvasBackup_ == nullptr) {
1214         RS_LOGD("RSUniRenderVisitor::FinishOffscreenRender, canvasBackup_ is nullptr");
1215         return;
1216     }
1217     // flush offscreen canvas, maybe unnecessary
1218     canvas_->flush();
1219     // draw offscreen surface to current canvas
1220     SkPaint paint;
1221     paint.setAntiAlias(true);
1222     canvasBackup_->drawImage(offscreenSurface_->makeImageSnapshot(), 0, 0, &paint);
1223     // restore current canvas and cleanup
1224     offscreenSurface_ = nullptr;
1225     canvas_ = std::move(canvasBackup_);
1226 }
1227 } // namespace Rosen
1228 } // namespace OHOS
1229