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