• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_RENDER_NODE_DRAWABLE_ADAPTER_H
17 #define RENDER_SERVICE_BASE_DRAWABLE_RS_RENDER_NODE_DRAWABLE_ADAPTER_H
18 
19 #include <memory>
20 #include <map>
21 #include <mutex>
22 #include <unordered_map>
23 #include <unordered_set>
24 #include <vector>
25 
26 #include "common/rs_common_def.h"
27 #include "common/rs_macros.h"
28 #include "common/rs_rect.h"
29 #include "drawable/rs_property_drawable.h"
30 #include "pipeline/rs_paint_filter_canvas.h"
31 #include "recording/recording_canvas.h"
32 #include "utils/rect.h"
33 
34 #ifndef ROSEN_CROSS_PLATFORM
35 #include <iconsumer_surface.h>
36 #endif
37 
38 namespace OHOS::Rosen {
39 class RSRenderNode;
40 class RSRenderParams;
41 class RSScreenRenderNode;
42 class RSSurfaceRenderNode;
43 class RSSurfaceHandler;
44 class RSContext;
45 class RSDirtyRegionManager;
46 class RSDrawWindowCache;
47 class RSRenderNodeGC;
48 #ifdef SUBTREE_PARALLEL_ENABLE
49 class RSParallelRBPolicy;
50 struct RSSubtreeDrawElement;
51 #endif
52 
53 namespace Drawing {
54 class Canvas;
55 }
56 namespace ModifierNG {
57 class RSUseEffectRenderModifier;
58 }
59 
60 struct DrawCmdIndex {
61     int8_t transitionIndex_            = -1;
62     int8_t envForeGroundColorIndex_    = -1;
63     int8_t shadowIndex_                = -1;
64     int8_t renderGroupBeginIndex_      = -1;
65     int8_t foregroundFilterBeginIndex_ = -1;
66     int8_t bgSaveBoundsIndex_          = -1;
67     int8_t clipToBoundsIndex_          = -1;
68     int8_t backgroundColorIndex_       = -1;
69     int8_t backgroundImageIndex_       = -1;
70     int8_t backgroundFilterIndex_      = -1;
71     int8_t useEffectIndex_             = -1;
72     int8_t backgroudStyleIndex_        = -1;
73     int8_t envForegroundColorStrategyIndex_ = -1;
74     int8_t bgRestoreBoundsIndex_       = -1;
75     int8_t frameOffsetIndex_           = -1;
76     int8_t clipToFrameIndex_           = -1;
77     int8_t customClipToFrameIndex_     = -1;
78     int8_t backgroundEndIndex_         = -1;
79     int8_t childrenIndex_              = -1;
80     int8_t contentIndex_               = -1;
81     int8_t foregroundBeginIndex_       = -1;
82     int8_t renderGroupEndIndex_        = -1;
83     int8_t foregroundFilterEndIndex_   = -1;
84     int8_t endIndex_                   = -1;
85 };
86 namespace DrawableV2 {
87 enum class SkipType : uint8_t {
88     NONE = 0,
89     SKIP_SHADOW = 1,
90     SKIP_BACKGROUND_COLOR = 2
91 };
92 
93 enum class DrawSkipType : uint8_t {
94     NONE = 0,
95     SHOULD_NOT_PAINT = 1,
96     CANVAS_NULL = 2,
97     RENDER_THREAD_PARAMS_NULL = 3,
98     RENDER_PARAMS_NULL = 4,
99     SURFACE_PARAMS_SKIP_DRAW = 5,
100     RENDER_ENGINE_NULL = 6,
101     FILTERCACHE_OCCLUSION_SKIP = 7,
102     OCCLUSION_SKIP = 8,
103     UI_FIRST_CACHE_SKIP = 9,
104     PARALLEL_CANVAS_SKIP = 10,
105     INIT_SURFACE_FAIL = 11,
106     RENDER_PARAMS_OR_UNI_PARAMS_NULL = 12,
107     SCREEN_OFF = 13,
108     SCREEN_MANAGER_NULL = 14,
109     SKIP_FRAME = 15,
110     CREATE_PROCESSOR_FAIL = 16,
111     INIT_FOR_RENDER_THREAD_FAIL = 17,
112     WIRED_SCREEN_PROJECTION = 18,
113     EXPAND_PROCESSOR_NULL = 19,
114     MIRROR_DRAWABLE_SKIP = 20,
115     SCREEN_NODE_SKIP = 21,
116     REQUEST_FRAME_FAIL = 22,
117     SURFACE_NULL = 23,
118     GENERATE_EFFECT_DATA_ON_DEMAND_FAIL = 24,
119     RENDER_SKIP_IF_SCREEN_OFF = 25,
120     HARD_CURSOR_ENAbLED = 26,
121     CHECK_MATCH_AND_WAIT_NOTIFY_FAIL = 27,
122     DEAL_WITH_CACHED_WINDOW = 28,
123     MULTI_ACCESS = 29,
124     RENDER_SKIP_IF_SCREEN_SWITCHING = 30,
125     UI_FIRST_CACHE_FAIL = 31,
126     SURFACE_SKIP_IN_MIRROR = 32,
127     NO_DISPLAY_NODE = 33,
128     HARDWARE_HDR_CACHE_SKIP = 34,
129     SCREEN_STATE_INVALID = 35,
130     SCREEN_FREEZE = 36,
131 };
132 
133 class RSB_EXPORT RSRenderNodeDrawableAdapter : public std::enable_shared_from_this<RSRenderNodeDrawableAdapter> {
134 public:
135     explicit RSRenderNodeDrawableAdapter(std::shared_ptr<const RSRenderNode>&& node);
136     virtual ~RSRenderNodeDrawableAdapter();
137 
138     // delete
139     RSRenderNodeDrawableAdapter(const RSRenderNodeDrawableAdapter&) = delete;
140     RSRenderNodeDrawableAdapter(const RSRenderNodeDrawableAdapter&&) = delete;
141     RSRenderNodeDrawableAdapter& operator=(const RSRenderNodeDrawableAdapter&) = delete;
142     RSRenderNodeDrawableAdapter& operator=(const RSRenderNodeDrawableAdapter&&) = delete;
143 
144     using Ptr = RSRenderNodeDrawableAdapter*;
145     using SharedPtr = std::shared_ptr<RSRenderNodeDrawableAdapter>;
146     using WeakPtr = std::weak_ptr<RSRenderNodeDrawableAdapter>;
147 
148     virtual void Draw(Drawing::Canvas& canvas) = 0;
149     virtual void DumpDrawableTree(int32_t depth, std::string& out, const RSContext& context) const;
150 
151 #ifdef SUBTREE_PARALLEL_ENABLE
152     void DrawQuickImpl(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
153 #endif
154     static SharedPtr OnGenerate(const std::shared_ptr<const RSRenderNode>& node);
155     static SharedPtr GetDrawableById(NodeId id);
156     static std::vector<RSRenderNodeDrawableAdapter::SharedPtr> GetDrawableVectorById(
157         const std::unordered_set<NodeId>& ids);
158     static SharedPtr OnGenerateShadowDrawable(
159         const std::shared_ptr<const RSRenderNode>& node, const std::shared_ptr<RSRenderNodeDrawableAdapter>& drawable);
160 
161     static void ClearResource();
162     using DrawableVec = std::vector<std::shared_ptr<RSRenderNodeDrawableAdapter>>;
163     static void AddToClearDrawables(DrawableVec &vec);
164     using CmdListVec = std::vector<std::shared_ptr<Drawing::DrawCmdList>>;
165     static void AddToClearCmdList(CmdListVec &vec);
GetRenderParams()166     inline const std::unique_ptr<RSRenderParams>& GetRenderParams() const
167     {
168         return renderParams_;
169     }
170 
GetUifirstRenderParams()171     inline const std::unique_ptr<RSRenderParams>& GetUifirstRenderParams() const
172     {
173         return uifirstRenderParams_;
174     }
175 
GetId()176     inline NodeId GetId() const
177     {
178         return nodeId_;
179     }
GetNodeType()180     inline RSRenderNodeType GetNodeType() const
181     {
182         return nodeType_;
183     }
GetSyncDirtyManager()184     virtual std::shared_ptr<RSDirtyRegionManager> GetSyncDirtyManager() const
185     {
186         return nullptr;
187     }
188 
189     using ClearSurfaceTask = std::function<void()>;
190     void RegisterClearSurfaceFunc(ClearSurfaceTask task);
191     void ResetClearSurfaceFunc();
192     void TryClearSurfaceOnSync();
193 
194 #ifndef ROSEN_CROSS_PLATFORM
RegisterDeleteBufferListenerOnSync(sptr<IConsumerSurface> consumer)195     virtual void RegisterDeleteBufferListenerOnSync(sptr<IConsumerSurface> consumer) {}
196 #endif
197 
IsNeedDraw()198     virtual bool IsNeedDraw() const
199     {
200         return false;
201     }
SetNeedDraw(bool flag)202     virtual void SetNeedDraw(bool flag) {}
SetSkip(SkipType type)203     void SetSkip(SkipType type) { skipType_ = type; }
GetSkipType()204     SkipType GetSkipType() { return skipType_; }
205 
206     void SetSkipCacheLayer(bool hasSkipCacheLayer);
207     void SetChildInBlackList(bool hasChildInBlackList);
208 
209     bool IsFilterCacheValidForOcclusion() const;
210     const RectI GetFilterCachedRegion() const;
211 
GetFilterNodeSize()212     size_t GetFilterNodeSize() const
213     {
214         return filterNodeSize_;
215     }
ReduceFilterNodeSize()216     void ReduceFilterNodeSize()
217     {
218         if (filterNodeSize_ > 0) {
219             --filterNodeSize_;
220         }
221     }
222     struct FilterNodeInfo {
FilterNodeInfoFilterNodeInfo223         FilterNodeInfo(NodeId nodeId, Drawing::Matrix matrix, std::vector<Drawing::RectI> rectVec)
224             : nodeId_(nodeId), matrix_(matrix), rectVec_(rectVec) {};
225         NodeId nodeId_ = 0;
226         // Here, matrix_ and rectVec_ represent the transformation and FilterRect of the node relative to the off-screen
227         Drawing::Matrix matrix_;
228         std::vector<Drawing::RectI> rectVec_;
229     };
230 
GetfilterInfoVec()231     const std::vector<FilterNodeInfo>& GetfilterInfoVec() const
232     {
233         return filterInfoVec_;
234     }
GetWithoutFilterMatrixMap()235     const std::unordered_map<NodeId, Drawing::Matrix>& GetWithoutFilterMatrixMap() const
236     {
237         return withoutFilterMatrixMap_;
238     }
239 
GetUnobscuredUECMatrixMap()240     const std::unordered_map<NodeId, Drawing::Matrix>& GetUnobscuredUECMatrixMap() const
241     {
242         return unobscuredUECMatrixMap_;
243     }
244 
SetLastDrawnFilterNodeId(NodeId nodeId)245     void SetLastDrawnFilterNodeId(NodeId nodeId)
246     {
247         lastDrawnFilterNodeId_ = nodeId;
248     }
249 
GetLastDrawnFilterNodeId()250     NodeId GetLastDrawnFilterNodeId() const
251     {
252         return lastDrawnFilterNodeId_;
253     }
254 
255 
SetUIExtensionNeedToDraw(bool needToDraw)256     virtual void SetUIExtensionNeedToDraw(bool needToDraw) {}
257 
UIExtensionNeedToDraw()258     virtual bool UIExtensionNeedToDraw() const
259     {
260         return false;
261     }
262 
SetDrawSkipType(DrawSkipType type)263     void SetDrawSkipType(DrawSkipType type) {
264         drawSkipType_.store(type);
265     }
266 
GetDrawSkipType()267     DrawSkipType GetDrawSkipType() {
268         return drawSkipType_.load();
269     }
270 
Purge()271     virtual void Purge()
272     {
273         if (purgeFunc_) {
274             purgeFunc_();
275         }
276     }
277 
DrawableTryLockForDraw()278     inline bool DrawableTryLockForDraw()
279     {
280         bool expected = false;
281         return isOnDraw_.compare_exchange_strong(expected, true);
282     }
283 
DrawableResetLock()284     inline void DrawableResetLock()
285     {
286         isOnDraw_.store(false);
287     }
288 
Snapshot()289     virtual std::shared_ptr<Drawing::Image> Snapshot() const
290     {
291         return nullptr;
292     }
293 
GetDrawableType()294     virtual RSRenderNodeDrawableType GetDrawableType() const
295     {
296         return RSRenderNodeDrawableType::UNKNOW;
297     }
298 
299 protected:
300     // Util functions
301     std::string DumpDrawableVec(const std::shared_ptr<RSRenderNode>& renderNode) const;
302     bool QuickReject(Drawing::Canvas& canvas, const RectF& localDrawRect);
303     bool HasFilterOrEffect() const;
304     int ClipHoleForCacheSize(const RSRenderParams& params) const;
305 
306     // Draw functions
307     void DrawAll(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
308     void DrawUifirstContentChildren(Drawing::Canvas& canvas, const Drawing::Rect& rect);
309     void DrawBackground(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
310     void DrawLeashWindowBackground(Drawing::Canvas& canvas, const Drawing::Rect& rect,
311         bool isStencilPixelOcclusionCullingEnabled = false, int64_t stencilVal = -1) const;
312     void DrawContent(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
313     void DrawChildren(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
314     void DrawForeground(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
315     void ApplyForegroundColorIfNeed(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
316 
317     // used for foreground filter
318     void DrawBeforeCacheWithForegroundFilter(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
319     void DrawCacheWithForegroundFilter(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
320     void DrawAfterCacheWithForegroundFilter(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
321 
322     // used for render group
323     void DrawBackgroundWithoutFilterAndEffect(Drawing::Canvas& canvas, const RSRenderParams& params);
324     void CheckShadowRectAndDrawBackground(Drawing::Canvas& canvas, const RSRenderParams& params);
325     void DrawCacheWithProperty(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
326     void DrawBeforeCacheWithProperty(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
327     void DrawAfterCacheWithProperty(Drawing::Canvas& canvas, const Drawing::Rect& rect) const;
328     void CollectInfoForNodeWithoutFilter(Drawing::Canvas& canvas);
329     void CollectInfoForUnobscuredUEC(Drawing::Canvas& canvas);
330 
331     // Note, the start is included, the end is excluded, so the range is [start, end)
332     void DrawRangeImpl(Drawing::Canvas& canvas, const Drawing::Rect& rect, int8_t start, int8_t end) const;
333     void DrawImpl(Drawing::Canvas& canvas, const Drawing::Rect& rect, int8_t index) const;
334 
335     // Register utils
336     using Generator = Ptr (*)(std::shared_ptr<const RSRenderNode>);
337     template<RSRenderNodeType type, Generator generator>
338     class RenderNodeDrawableRegistrar {
339     public:
RenderNodeDrawableRegistrar()340         RenderNodeDrawableRegistrar()
341         {
342             RSRenderNodeDrawableAdapter::GeneratorMap.emplace(type, generator);
343         }
344     };
345 
346     const RSRenderNodeType nodeType_;
347     // deprecated
348     std::weak_ptr<const RSRenderNode> renderNode_;
349     NodeId nodeId_;
350 
351     DrawCmdIndex uifirstDrawCmdIndex_;
352     DrawCmdIndex drawCmdIndex_;
353     std::unique_ptr<RSRenderParams> renderParams_;
354     static std::unordered_map<NodeId, Drawing::Matrix> unobscuredUECMatrixMap_;
355     std::shared_ptr<std::unordered_set<NodeId>> UECChildrenIds_ = std::make_shared<std::unordered_set<NodeId>>();
356     std::unique_ptr<RSRenderParams> uifirstRenderParams_;
357     std::vector<Drawing::RecordingCanvas::DrawFunc> uifirstDrawCmdList_;
358     std::vector<Drawing::RecordingCanvas::DrawFunc> drawCmdList_;
359     std::vector<FilterNodeInfo> filterInfoVec_;
360     std::unordered_map<NodeId, Drawing::Matrix> withoutFilterMatrixMap_;
361     size_t filterNodeSize_ = 0;
362     std::shared_ptr<DrawableV2::RSFilterDrawable> backgroundFilterDrawable_ = nullptr;
363     std::shared_ptr<DrawableV2::RSFilterDrawable> compositingFilterDrawable_ = nullptr;
364     std::function<void()> purgeFunc_;
365 #ifdef ROSEN_OHOS
366     static thread_local RSRenderNodeDrawableAdapter* curDrawingCacheRoot_;
367 #else
368     static RSRenderNodeDrawableAdapter* curDrawingCacheRoot_;
369 #endif
370     // if the node needs to avoid drawing cache because of some layers, such as the security layer...
371     bool hasSkipCacheLayer_ = false;
372     bool hasChildInBlackList_ = false;
373 
374     ClearSurfaceTask clearSurfaceTask_ = nullptr;
375 private:
376     static void InitRenderParams(const std::shared_ptr<const RSRenderNode>& node,
377                             std::shared_ptr<RSRenderNodeDrawableAdapter>& sharedPtr);
378     static std::map<RSRenderNodeType, Generator> GeneratorMap;
379     static std::map<NodeId, WeakPtr> RenderNodeDrawableCache_;
380     static inline std::mutex cacheMapMutex_;
381     static DrawableVec toClearDrawableVec_;
382     static CmdListVec toClearCmdListVec_;
383     SkipType skipType_ = SkipType::NONE;
384     int8_t GetSkipIndex() const;
385     std::atomic<DrawSkipType> drawSkipType_ = DrawSkipType::NONE;
386     static void RemoveDrawableFromCache(const NodeId nodeId);
387     void UpdateFilterInfoForNodeGroup(RSPaintFilterCanvas* curCanvas);
388     NodeId lastDrawnFilterNodeId_ = 0;
389     std::atomic<bool> isOnDraw_ = false;
390 
391     friend class OHOS::Rosen::RSRenderNode;
392     friend class OHOS::Rosen::RSScreenRenderNode;
393     friend class OHOS::Rosen::RSSurfaceRenderNode;
394     friend class RSRenderNodeShadowDrawable;
395     friend class RSUseEffectDrawable;
396     friend class RSRenderNodeDrawable;
397     friend class OHOS::Rosen::RSDrawWindowCache;
398     friend class ModifierNG::RSUseEffectRenderModifier;
399     friend class OHOS::Rosen::RSRenderNodeGC;
400 #ifdef SUBTREE_PARALLEL_ENABLE
401     friend class OHOS::Rosen::RSParallelRBPolicy;
402     friend struct OHOS::Rosen::RSSubtreeDrawElement;
403 #endif
404 };
405 
406 // RSRenderNodeSingleDrawableLocker: tool class that ensures drawable is exclusively used at the same time.
407 class RSB_EXPORT RSRenderNodeSingleDrawableLocker {
408 public:
409     RSRenderNodeSingleDrawableLocker() = delete;
RSRenderNodeSingleDrawableLocker(RSRenderNodeDrawableAdapter * drawable)410     inline RSRenderNodeSingleDrawableLocker(RSRenderNodeDrawableAdapter* drawable)
411         : drawable_(drawable), locked_(LIKELY(drawable != nullptr) && drawable->DrawableTryLockForDraw())
412     {}
~RSRenderNodeSingleDrawableLocker()413     inline ~RSRenderNodeSingleDrawableLocker()
414     {
415         if (LIKELY(locked_)) {
416             drawable_->DrawableResetLock();
417         }
418     }
IsLocked()419     inline bool IsLocked() const
420     {
421         return LIKELY(locked_);
422     }
423     struct MultiAccessReportInfo {
424         bool drawableNotNull = false;
425         bool paramNotNull = false;
426         RSRenderNodeType nodeType = RSRenderNodeType::UNKNOW;
427         NodeId nodeId = INVALID_NODEID;
428         NodeId uifirstRootNodeId = INVALID_NODEID;
429         NodeId firstLevelNodeId = INVALID_NODEID;
430     };
431     void DrawableOnDrawMultiAccessEventReport(const std::string& func) const;
432 private:
433     RSRenderNodeDrawableAdapter* drawable_;
434     const bool locked_;
435 };
436 } // namespace DrawableV2
437 } // namespace OHOS::Rosen
438 #endif // RENDER_SERVICE_BASE_DRAWABLE_RS_RENDER_NODE_DRAWABLE_ADAPTER_H
439