• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #ifndef RENDER_SERVICE_CORE_PIPELINE_RS_UNI_RENDER_VISITOR_H
16 #define RENDER_SERVICE_CORE_PIPELINE_RS_UNI_RENDER_VISITOR_H
17 
18 #include <cstdint>
19 #include <list>
20 #include <memory>
21 #include <mutex>
22 #include <optional>
23 #include <parameters.h>
24 #include <set>
25 
26 #include "rs_base_render_engine.h"
27 
28 #include "hgm_frame_rate_manager.h"
29 #include "pipeline/driven_render/rs_driven_render_manager.h"
30 #include "pipeline/rs_dirty_region_manager.h"
31 #include "pipeline/rs_processor.h"
32 #include "platform/ohos/overdraw/rs_cpu_overdraw_canvas_listener.h"
33 #include "platform/ohos/overdraw/rs_gpu_overdraw_canvas_listener.h"
34 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
35 #include "screen_manager/rs_screen_manager.h"
36 #include "system/rs_system_parameters.h"
37 #include "visitor/rs_node_visitor.h"
38 
39 class SkPicture;
40 namespace OHOS {
41 namespace Rosen {
42 class RSPaintFilterCanvas;
43 class RSUniRenderVisitor : public RSNodeVisitor {
44 public:
45     using SurfaceDirtyMgrPair = std::pair<std::shared_ptr<RSSurfaceRenderNode>, std::shared_ptr<RSSurfaceRenderNode>>;
46     RSUniRenderVisitor();
47     RSUniRenderVisitor(std::shared_ptr<RSPaintFilterCanvas> canvas, uint32_t surfaceIndex);
48     explicit RSUniRenderVisitor(const RSUniRenderVisitor& visitor);
49     ~RSUniRenderVisitor() override;
50 
51     void PrepareChildren(RSRenderNode& node) override;
52     void PrepareCanvasRenderNode(RSCanvasRenderNode& node) override;
53     void PrepareDisplayRenderNode(RSDisplayRenderNode& node) override;
54     void PrepareProxyRenderNode(RSProxyRenderNode& node) override;
55     void PrepareRootRenderNode(RSRootRenderNode& node) override;
56     void PrepareSurfaceRenderNode(RSSurfaceRenderNode& node) override;
57     void PrepareEffectRenderNode(RSEffectRenderNode& node) override;
58 
59     void ProcessChildren(RSRenderNode& node) override;
60     void ProcessCanvasRenderNode(RSCanvasRenderNode& node) override;
61     void ProcessDisplayRenderNode(RSDisplayRenderNode& node) override;
62     void ProcessProxyRenderNode(RSProxyRenderNode& node) override;
63     void ProcessRootRenderNode(RSRootRenderNode& node) override;
64     void ProcessSurfaceRenderNode(RSSurfaceRenderNode& node) override;
65     void ProcessEffectRenderNode(RSEffectRenderNode& node) override;
66 
67     bool DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode);
68     bool ParallelComposition(const std::shared_ptr<RSBaseRenderNode> rootNode);
69     void ChangeCacheRenderNodeMap(RSRenderNode& node, const uint32_t count = 0);
70     void UpdateCacheRenderNodeMap(RSRenderNode& node);
71     bool GenerateNodeContentCache(RSRenderNode& node);
72     bool InitNodeCache(RSRenderNode& node);
73     void CopyVisitorInfos(std::shared_ptr<RSUniRenderVisitor> visitor);
SetProcessorRenderEngine(std::shared_ptr<RSBaseRenderEngine> renderEngine)74     void SetProcessorRenderEngine(std::shared_ptr<RSBaseRenderEngine> renderEngine)
75     {
76         renderEngine_ = renderEngine;
77     }
78 
SetAnimateState(bool doAnimate)79     void SetAnimateState(bool doAnimate)
80     {
81         doAnimate_ = doAnimate;
82     }
83 
SetDirtyFlag(bool isDirty)84     void SetDirtyFlag(bool isDirty)
85     {
86         isDirty_ = isDirty;
87     }
88 
SetFocusedNodeId(uint64_t nodeId)89     void SetFocusedNodeId(uint64_t nodeId)
90     {
91         currentFocusedNodeId_ = nodeId;
92     }
93 
SetSubThreadConfig(uint32_t threadIndex)94     void SetSubThreadConfig(uint32_t threadIndex)
95     {
96         isSubThread_ = true;
97         isHardwareForcedDisabled_ = true;
98         threadIndex_ = threadIndex;
99     }
100 
101     void DrawSurfaceLayer(const std::shared_ptr<RSDisplayRenderNode>& displayNode,
102         const std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes) const;
103 
GetAnimateState()104     bool GetAnimateState() const
105     {
106         return doAnimate_;
107     }
108 
MarkHardwareForcedDisabled()109     void MarkHardwareForcedDisabled()
110     {
111         isHardwareForcedDisabled_ = true;
112     }
113 
SetDrivenRenderFlag(bool hasDrivenNodeOnUniTree,bool hasDrivenNodeMarkRender)114     void SetDrivenRenderFlag(bool hasDrivenNodeOnUniTree, bool hasDrivenNodeMarkRender)
115     {
116         if (!drivenInfo_) {
117             return;
118         }
119         drivenInfo_->prepareInfo.hasDrivenNodeOnUniTree = hasDrivenNodeOnUniTree;
120         drivenInfo_->hasDrivenNodeMarkRender = hasDrivenNodeMarkRender;
121     }
122 
123     void SetHardwareEnabledNodes(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& hardwareEnabledNodes);
124     void AssignGlobalZOrderAndCreateLayer();
125 
126     void CopyForParallelPrepare(std::shared_ptr<RSUniRenderVisitor> visitor);
127     // Some properties defined before ProcessSurfaceRenderNode() may be used in
128     // ProcessSurfaceRenderNode() method. We should copy these properties in parallel render.
129     void CopyPropertyForParallelVisitor(RSUniRenderVisitor *mainVisitor);
GetIsPartialRenderEnabled()130     bool GetIsPartialRenderEnabled() const
131     {
132         return isPartialRenderEnabled_;
133     }
GetIsOpDropped()134     bool GetIsOpDropped() const
135     {
136         return isOpDropped_;
137     }
138     // Use in vulkan parallel rendering
GetColorGamut()139     GraphicColorGamut GetColorGamut() const
140     {
141         return newColorSpace_;
142     }
143 
GetProcessor()144     std::shared_ptr<RSProcessor> GetProcessor() const
145     {
146         return processor_;
147     }
148 
SetRenderFrame(std::unique_ptr<RSRenderFrame> renderFrame)149     void SetRenderFrame(std::unique_ptr<RSRenderFrame> renderFrame)
150     {
151         renderFrame_ = std::move(renderFrame);
152     }
153     void SetAppWindowNum(uint32_t num);
154 
GetFrameRateRangeData()155     FrameRateRangeData GetFrameRateRangeData()
156     {
157         return frameRateRangeData_;
158     }
159     void CollectFrameRateRange(RSRenderNode& node);
160 
161 #ifndef USE_ROSEN_DRAWING
162     using RenderParam = std::tuple<std::shared_ptr<RSRenderNode>, float, std::optional<SkMatrix>>;
163 #else
164     using RenderParam = std::tuple<std::shared_ptr<RSRenderNode>, float, std::optional<Drawing::Matrix>>;
165 #endif
166 private:
167     void DrawWatermarkIfNeed();
168 #ifndef USE_ROSEN_DRAWING
169     void DrawDirtyRectForDFX(const RectI& dirtyRect, const SkColor color,
170         const SkPaint::Style fillType, float alpha, int edgeWidth);
171 #else
172     enum class RSPaintStyle {
173         FILL,
174         STROKE
175     };
176     void DrawDirtyRectForDFX(const RectI& dirtyRect, const Drawing::Color color,
177         const RSPaintStyle fillType, float alpha, int edgeWidth);
178 #endif
179     void DrawDirtyRegionForDFX(std::vector<RectI> dirtyRects);
180     void DrawCacheRegionForDFX(std::vector<RectI> cacheRects);
181     void DrawAllSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node, const Occlusion::Region& region);
182     void DrawTargetSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node);
183     void DrawAllSurfaceOpaqueRegionForDFX(RSDisplayRenderNode& node);
184     void DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderNode& node);
185     // check if surface name is in dfx target list
CheckIfSurfaceTargetedForDFX(std::string nodeName)186     inline bool CheckIfSurfaceTargetedForDFX(std::string nodeName)
187     {
188         return (std::find(dfxTargetSurfaceNames_.begin(), dfxTargetSurfaceNames_.end(),
189             nodeName) != dfxTargetSurfaceNames_.end());
190     }
191 
192     bool DrawDetailedTypesOfDirtyRegionForDFX(RSSurfaceRenderNode& node);
193     void DrawAndTraceSingleDirtyRegionTypeForDFX(RSSurfaceRenderNode& node,
194         DirtyRegionType dirtyType, bool isDrawn = true);
195 
196     std::vector<RectI> GetDirtyRects(const Occlusion::Region &region);
197     /* calculate display/global (between windows) level dirty region, current include:
198      * 1. window move/add/remove 2. transparent dirty region
199      * when process canvas culling, canvas intersect with surface's visibledirty region or
200      * global dirty region will be skipped
201      */
202     void CalcDirtyDisplayRegion(std::shared_ptr<RSDisplayRenderNode>& node);
203     void CalcDirtyRegionForFilterNode(const RectI filterRect,
204         std::shared_ptr<RSSurfaceRenderNode>& currentSurfaceNode,
205         std::shared_ptr<RSDisplayRenderNode>& displayNode);
206     void CalcDirtyFilterRegion(std::shared_ptr<RSDisplayRenderNode>& node);
207     /* Disable visible hwc surface if it intersects with filter region
208      * Save rest validNodes in prevHwcEnabledNodes
209      * [planning] Update hwc surface dirty status at the same time
210      */
211     void UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode>& node,
212         std::vector<SurfaceDirtyMgrPair>& prevHwcEnabledNodes,
213         std::shared_ptr<RSDirtyRegionManager>& displayDirtyManager);
214     /* Disable hwc surface intersect with filter rects and merge dirty filter region
215      * [planning] If invisible filterRects could be removed
216      */
217     RectI UpdateHardwareEnableList(std::vector<RectI>& filterRects,
218         std::vector<SurfaceDirtyMgrPair>& validHwcNodes);
219     void MergeDirtyRectIfNeed(std::shared_ptr<RSSurfaceRenderNode> appNode,
220         std::shared_ptr<RSSurfaceRenderNode> hwcNode);
221     void AddContainerDirtyToGlobalDirty(std::shared_ptr<RSDisplayRenderNode>& node) const;
222 
223     // set global dirty region to each surface node
224     void SetSurfaceGlobalDirtyRegion(std::shared_ptr<RSDisplayRenderNode>& node);
225     void SetSurfaceGlobalAlignedDirtyRegion(std::shared_ptr<RSDisplayRenderNode>& node,
226         const Occlusion::Region alignedDirtyRegion);
227     void AlignGlobalAndSurfaceDirtyRegions(std::shared_ptr<RSDisplayRenderNode>& node);
228 
229     void CheckAndSetNodeCacheType(RSRenderNode& node);
230     bool UpdateCacheSurface(RSRenderNode& node);
231     void DrawSpherize(RSRenderNode& node);
232     void DrawChildRenderNode(RSRenderNode& node);
233     void DrawChildCanvasRenderNode(RSRenderNode& node);
234 
235     void CheckColorSpace(RSSurfaceRenderNode& node);
236     void AddOverDrawListener(std::unique_ptr<RSRenderFrame>& renderFrame,
237         std::shared_ptr<RSCanvasListener>& overdrawListener);
238     /* Judge if surface render node could skip preparation:
239      * 1. not leash window
240      * 2. parent not dirty
241      * 3. no processWithCommands_ of node's corresponding pid
242      * If so, reset status flag and stop traversal
243      */
244     bool CheckIfSurfaceRenderNodeStatic(RSSurfaceRenderNode& node);
245     void PrepareTypesOfSurfaceRenderNodeBeforeUpdate(RSSurfaceRenderNode& node);
246     void PrepareTypesOfSurfaceRenderNodeAfterUpdate(RSSurfaceRenderNode& node);
247     // judge if node's cache changes
248     void UpdateCacheChangeStatus(RSBaseRenderNode& node);
249     // set node cacheable animation after checking whold child tree
250     void SetNodeCacheChangeStatus(RSBaseRenderNode& node, int markedCachedNodeCnt);
251     // update rendernode's cache status and collect valid cache rect
252     void UpdateForegroundFilterCacheWithDirty(RSRenderNode& node);
253 
254     bool IsHardwareComposerEnabled();
255 
256     bool CheckIfSurfaceRenderNodeNeedProcess(RSSurfaceRenderNode& node);
257 
258     void ClearTransparentBeforeSaveLayer();
259     // mark surfaceNode's child surfaceView nodes hardware forced disabled
260     void MarkSubHardwareEnableNodeState(RSSurfaceRenderNode& surfaceNode);
261     // adjust local zOrder if surfaceNode's child surfaceView nodes skipped by dirty region
262     void AdjustLocalZOrder(std::shared_ptr<RSSurfaceRenderNode> surfaceNode);
263 
264     void RecordAppWindowNodeAndPostTask(RSSurfaceRenderNode& node, float width, float height);
265     // offscreen render related
266     void PrepareOffscreenRender(RSRenderNode& node);
267     void FinishOffscreenRender();
268     void ParallelPrepareDisplayRenderNodeChildrens(RSDisplayRenderNode& node);
269     bool AdaptiveSubRenderThreadMode(bool doParallel);
270     void ParallelRenderEnableHardwareComposer(RSSurfaceRenderNode& node);
271     // close partialrender when perform window animation
272     void ClosePartialRenderWhenAnimatingWindows(std::shared_ptr<RSDisplayRenderNode>& node);
273     int32_t GetNodePreferred(std::vector<HgmModifierProfile> hgmModifierProfileList) const;
274 
275     bool DrawBlurInCache(RSRenderNode& node);
276     void UpdateCacheRenderNodeMapWithBlur(RSRenderNode& node);
277 
278 #ifndef USE_ROSEN_DRAWING
279     sk_sp<SkSurface> offscreenSurface_;                 // temporary holds offscreen surface
280 #else
281     std::shared_ptr<Drawing::Surface> offscreenSurface_;                 // temporary holds offscreen surface
282 #endif
283     std::shared_ptr<RSPaintFilterCanvas> canvasBackup_; // backup current canvas before offscreen render
284 
285     // Use in vulkan parallel rendering
286     void ProcessParallelDisplayRenderNode(RSDisplayRenderNode& node);
287 
288     ScreenInfo screenInfo_;
289     std::shared_ptr<RSDirtyRegionManager> curSurfaceDirtyManager_;
290     std::shared_ptr<RSRenderNode> curRootNode_;
291     std::shared_ptr<RSSurfaceRenderNode> curSurfaceNode_;
292     float curAlpha_ = 1.f;
293     bool dirtyFlag_ { false };
294     std::unique_ptr<RSRenderFrame> renderFrame_;
295     std::shared_ptr<RSPaintFilterCanvas> canvas_;
296     std::map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> dirtySurfaceNodeMap_;
297     std::vector<RectI> cacheRenderNodeMapRects_;
298 #ifndef USE_ROSEN_DRAWING
299     SkRect boundsRect_ {};
300 #else
301     Drawing::Rect boundsRect_ {};
302 #endif
303     Gravity frameGravity_ = Gravity::DEFAULT;
304 
305     int32_t offsetX_ { 0 };
306     int32_t offsetY_ { 0 };
307     std::shared_ptr<RSProcessor> processor_;
308 #ifndef USE_ROSEN_DRAWING
309     SkMatrix parentSurfaceNodeMatrix_;
310 #else
311     Drawing::Matrix parentSurfaceNodeMatrix_;
312 #endif
313 
314     ScreenId currentVisitDisplay_ = INVALID_SCREEN_ID;
315     std::map<ScreenId, int> displayHasSecSurface_;
316     std::set<ScreenId> mirroredDisplays_;
317     bool isSecurityDisplay_ = false;
318 
319     bool hasFingerprint_ = false;
320 
321     std::shared_ptr<RSBaseRenderEngine> renderEngine_;
322 
323     std::shared_ptr<RSDirtyRegionManager> curDisplayDirtyManager_;
324     std::shared_ptr<RSDisplayRenderNode> curDisplayNode_;
325     bool doAnimate_ = false;
326     bool isSurfaceRotationChanged_ = false;
327     bool isPartialRenderEnabled_ = false;
328     bool isOpDropped_ = false;
329     bool isDirtyRegionDfxEnabled_ = false; // dirtyRegion DFX visualization
330     bool isTargetDirtyRegionDfxEnabled_ = false;
331     bool isOpaqueRegionDfxEnabled_ = false;
332     bool isQuickSkipPreparationEnabled_ = false;
333     bool isHardwareComposerEnabled_ = false;
334     bool isOcclusionEnabled_ = false;
335     std::vector<std::string> dfxTargetSurfaceNames_;
336     PartialRenderType partialRenderType_;
337     QuickSkipPrepareType quickSkipPrepareType_;
338     DirtyRegionDebugType dirtyRegionDebugType_;
339     bool isDirty_ = false;
340     // added for judge if drawing cache changes
341     bool isDrawingCacheEnabled_ = false;
342     bool isDrawingCacheChanged_ = false;
343     bool childHasSurface_ = false;
344     int markedCachedNodes_ = 0;
345     std::vector<RectI> accumulatedDirtyRegions_ = {};
346 
347     bool needFilter_ = false;
348     GraphicColorGamut newColorSpace_ = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
349     std::vector<ScreenColorGamut> colorGamutModes_;
350     uint64_t currentFocusedNodeId_ = 0;
351 
352     bool isSubThread_ = false;
353     bool isUIFirst_ = false;
354     uint32_t threadIndex_ = UNI_MAIN_THREAD_INDEX;
355 
356     bool needColdStartThread_ = false; // flag used for cold start app window
357 
358     bool isDirtyRegionAlignedEnable_ = false;
359     std::shared_ptr<std::mutex> surfaceNodePrepareMutex_;
360     uint32_t parallelRenderVisitorIndex_ = 0;
361     ParallelRenderingType parallelRenderType_;
362 
363     RectI prepareClipRect_{0, 0, 0, 0}; // renderNode clip rect used in Prepare
364     bool isClipBoundDirty_ = false; // if node is clipbound dirty, its dirtyregion merge can be skipped
365 
366     // count prepared and processed canvasnode numbers per app
367     // unirender visitor resets every frame, no overflow risk here
368     unsigned int preparedCanvasNodeInCurrentSurface_ = 0;
369     unsigned int processedCanvasNodeInCurrentSurface_ = 0;
370     unsigned int processedPureContainerNode_ = 0;
371 
372     float globalZOrder_ = 0.0f;
373     bool isUpdateCachedSurface_ = false;
374     bool isHardwareForcedDisabled_ = false; // indicates if hardware composer is totally disabled
375     std::vector<std::shared_ptr<RSSurfaceRenderNode>> hardwareEnabledNodes_;
376     // vector of all app window nodes with surfaceView, sorted by zOrder
377     std::vector<std::shared_ptr<RSSurfaceRenderNode>> appWindowNodesInZOrder_;
378     float localZOrder_ = 0.0f; // local zOrder for surfaceView under same app window node
379 
380     // driven render
381     std::unique_ptr<DrivenInfo> drivenInfo_ = nullptr;
382 
383     std::unordered_map<NodeId, RenderParam> unpairedTransitionNodes_;
384     std::stack<RenderParam> curGroupedNodes_;
385     // return true if we should prepare/process, false if we should skip.
386     bool PrepareSharedTransitionNode(RSBaseRenderNode& node);
387     bool ProcessSharedTransitionNode(RSBaseRenderNode& node);
388 
389     std::weak_ptr<RSBaseRenderNode> logicParentNode_;
390 
391     bool isCalcCostEnable_ = false;
392     // adapt to sceneboard, mark if the canvasNode within the scope of surfaceNode
393     bool isSubNodeOfSurfaceInPrepare_ = false;
394     bool isSubNodeOfSurfaceInProcess_ = false;
395 
396     uint32_t appWindowNum_ = 0;
397 
398     bool isParallel_ = false;
399     bool doParallelComposition_ = false;
400     bool doParallelRender_ = false;
401     // displayNodeMatrix only used in offScreen render case to ensure correct composer layer info when with rotation,
402     // displayNodeMatrix indicates display node's matrix info
403 #ifndef USE_ROSEN_DRAWING
404     std::optional<SkMatrix> displayNodeMatrix_;
405 #else
406     std::optional<Drawing::Matrix> displayNodeMatrix_;
407 #endif
408     mutable std::mutex copyVisitorInfosMutex_;
409 #ifndef USE_ROSEN_DRAWING
410     sk_sp<SkImage> cacheImgForCapture_ = nullptr;
411 #else
412     std::shared_ptr<Drawing::Image> cacheImgForCapture_ = nullptr;
413 #endif
414     bool resetRotate_ = false;
415     bool needCacheImg_ = false;
416     uint32_t captureWindowZorder_ = 0;
417 #ifndef USE_ROSEN_DRAWING
418     std::optional<SkPath> effectRegion_ = std::nullopt;
419 #else
420     std::optional<Drawing::Path> effectRegion_ = std::nullopt;
421 #endif
422     bool curDirty_ = false;
423     bool curContentDirty_ = false;
424 
425     // calculate preferred fps
426     FrameRateRangeData frameRateRangeData_;
427 
428     std::unordered_map<NodeId, std::unordered_map<NodeId, RectI>> allCacheFilterRects_ = {};
429     std::stack<std::unordered_map<NodeId, RectI>> curCacheFilterRects_ = {};
430 };
431 } // namespace Rosen
432 } // namespace OHOS
433 
434 #endif // RENDER_SERVICE_CORE_PIPELINE_RS_UNI_RENDER_VISITOR_H
435