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