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_DRAWABLE_RS_RENDER_NODE_DRAWABLE_H
17 #define RENDER_SERVICE_DRAWABLE_RS_RENDER_NODE_DRAWABLE_H
18 
19 #include <memory>
20 #include <vector>
21 
22 #include "common/rs_common_def.h"
23 #include "draw/canvas.h"
24 #include "draw/surface.h"
25 #include "drawable/rs_render_node_drawable_adapter.h"
26 #include "image/gpu_context.h"
27 #include "pipeline/rs_render_node.h"
28 
29 #ifdef RS_ENABLE_VK
30 #include "platform/ohos/backend/native_buffer_utils.h"
31 #endif
32 #include "pipeline/rs_paint_filter_canvas.h"
33 
34 namespace OHOS::Rosen {
35 class RSRenderNode;
36 class RSRenderParams;
37 class RSPaintFilterCanvas;
38 namespace NativeBufferUtils {
39 class VulkanCleanupHelper;
40 }
41 namespace DrawableV2 {
42 // Used by RSUniRenderThread and RSChildrenDrawable
43 class RSRenderNodeDrawable : public RSRenderNodeDrawableAdapter {
44 public:
45     ~RSRenderNodeDrawable() override;
46 
47     static RSRenderNodeDrawable::Ptr OnGenerate(std::shared_ptr<const RSRenderNode> node);
48 
49     void Draw(Drawing::Canvas& canvas) override;
50     virtual void OnDraw(Drawing::Canvas& canvas);
51     virtual void OnCapture(Drawing::Canvas& canvas);
52 
53     // deprecated
GetRenderNode()54     inline std::shared_ptr<const RSRenderNode> GetRenderNode()
55     {
56         return renderNode_.lock();
57     }
58 
GetOpDropped()59     inline bool GetOpDropped() const
60     {
61         return isOpDropped_;
62     }
63 
64     bool ShouldPaint() const;
65 
66     // opinc switch
67     bool IsOpincRenderCacheEnable();
68     bool IsOpincRealDrawCacheEnable();
69     bool IsAutoCacheDebugEnable();
70 
71     void OpincCalculateBefore(Drawing::Canvas& canvas,
72         const RSRenderParams& params, bool& isOpincDropNodeExt);
73     void OpincCalculateAfter(Drawing::Canvas& canvas, bool& isOpincDropNodeExt);
74     void BeforeDrawCache(NodeStrategyType& cacheStragy, Drawing::Canvas& canvas, RSRenderParams& params,
75         bool& isOpincDropNodeExt);
76     void AfterDrawCache(NodeStrategyType& cacheStragy, Drawing::Canvas& canvas, RSRenderParams& params,
77         bool& isOpincDropNodeExt, int& opincRootTotalCount);
78 
79     bool DrawAutoCache(RSPaintFilterCanvas& canvas, Drawing::Image& image,
80         const Drawing::SamplingOptions& samplingOption, Drawing::SrcRectConstraint constraint);
81     void DrawAutoCacheDfx(RSPaintFilterCanvas& canvas,
82         std::vector<std::pair<RectI, std::string>>& autoCacheRenderNodeInfos);
83     void DrawableCacheStateReset(RSRenderParams& params);
84     bool PreDrawableCacheState(RSRenderParams& params, bool& isOpincDropNodeExt);
85     void OpincCanvasUnionTranslate(RSPaintFilterCanvas& canvas);
86     void ResumeOpincCanvasTranslate(RSPaintFilterCanvas& canvas);
87 
88     static int GetTotalProcessedNodeCount();
89     static void TotalProcessedNodeCountInc();
90     static void ClearTotalProcessedNodeCount();
91 
92     // opinc dfx
93     std::string GetNodeDebugInfo();
94 
95     bool IsOpListDrawAreaEnable();
96     bool IsTranslate(Drawing::Matrix& mat);
97 
GetOpListUnionArea()98     const Drawing::Rect& GetOpListUnionArea()
99     {
100         return opListDrawAreas_.GetOpInfo().unionRect;
101     }
102 
IsComputeDrawAreaSucc()103     bool IsComputeDrawAreaSucc()
104     {
105         return isDrawAreaEnable_ == DrawAreaEnableState::DRAW_AREA_ENABLE;
106     }
107 
108     // opinc root state
IsOpincRootNode()109     bool IsOpincRootNode()
110     {
111         return isOpincRootNode_;
112     }
113 
114     void SetCacheImageByCapture(std::shared_ptr<Drawing::Image> image);
115 
116     std::shared_ptr<Drawing::Image> GetCacheImageByCapture() const;
117 
118     // dfx
119     static void InitDfxForCacheInfo();
120     static void DrawDfxForCacheInfo(RSPaintFilterCanvas& canvas);
121 
122 protected:
123     explicit RSRenderNodeDrawable(std::shared_ptr<const RSRenderNode>&& node);
124     using Registrar = RenderNodeDrawableRegistrar<RSRenderNodeType::RS_NODE, OnGenerate>;
125     static Registrar instance_;
126 
127     // Only use in RSRenderNode::DrawCacheSurface to calculate scale factor
128     float boundsWidth_ = 0.0f;
129     float boundsHeight_ = 0.0f;
130 
131     void GenerateCacheIfNeed(Drawing::Canvas& canvas, RSRenderParams& params);
132     void CheckCacheTypeAndDraw(Drawing::Canvas& canvas, const RSRenderParams& params, bool isInCapture = false);
133 
134     static inline bool isDrawingCacheEnabled_ = false;
135     static inline bool isDrawingCacheDfxEnabled_ = false;
136     static inline std::mutex drawingCacheInfoMutex_;
137     static inline std::unordered_map<NodeId, std::pair<RectI, int32_t>> drawingCacheInfos_; // (id, <rect, updateTimes>)
138     static inline std::unordered_map<NodeId, bool> cacheUpdatedNodeMap_;
139 
140     // opinc global state
141     static inline bool autoCacheEnable_ = false;
142     static inline bool autoCacheDrawingEnable_ = false;
143     thread_local static inline NodeStrategyType nodeCacheType_ = NodeStrategyType::CACHE_NONE;
144     static inline std::vector<std::pair<RectI, std::string>> autoCacheRenderNodeInfos_;
145     thread_local static inline bool isOpincDropNodeExt_ = true;
146     thread_local static inline int opincRootTotalCount_ = 0;
147     static inline RectI screenRectInfo_ = {0, 0, 0, 0};
148 
149     // used for render group cache
150     void SetCacheType(DrawableCacheType cacheType);
151     DrawableCacheType GetCacheType() const;
152     void UpdateCacheInfoForDfx(Drawing::Canvas& canvas, const Drawing::Rect& rect, NodeId id);
153 
154     std::shared_ptr<Drawing::Surface> GetCachedSurface(pid_t threadId) const;
155     void InitCachedSurface(Drawing::GPUContext* gpuContext, const Vector2f& cacheSize, pid_t threadId,
156         bool isHdrOn = false);
157     bool NeedInitCachedSurface(const Vector2f& newSize);
158     std::shared_ptr<Drawing::Image> GetCachedImage(RSPaintFilterCanvas& canvas);
159     void DrawCachedImage(RSPaintFilterCanvas& canvas, const Vector2f& boundSize,
160     const std::shared_ptr<RSFilter>& rsFilter = nullptr);
161     void ClearCachedSurface();
162 
163     bool CheckIfNeedUpdateCache(RSRenderParams& params, int32_t& updateTimes);
164     void UpdateCacheSurface(Drawing::Canvas& canvas, const RSRenderParams& params);
165     void TraverseSubTreeAndDrawFilterWithClip(Drawing::Canvas& canvas, const RSRenderParams& params);
166 
167     static int GetProcessedNodeCount();
168     static void ProcessedNodeCountInc();
169     static void ClearProcessedNodeCount();
170     static thread_local bool drawBlurForCache_;
171 
172 private:
173     std::atomic<DrawableCacheType> cacheType_ = DrawableCacheType::NONE;
174     mutable std::recursive_mutex cacheMutex_;
175     mutable std::mutex freezeByCaptureMutex_;
176     std::shared_ptr<Drawing::Surface> cachedSurface_ = nullptr;
177     std::shared_ptr<Drawing::Image> cachedImage_ = nullptr;
178     std::shared_ptr<Drawing::Image> cachedImageByCapture_ = nullptr;
179 #if defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK)
180     Drawing::BackendTexture cachedBackendTexture_;
181 #ifdef RS_ENABLE_VK
182     NativeBufferUtils::VulkanCleanupHelper* vulkanCleanupHelper_ = nullptr;
183 #endif
184 #endif
185     // surface thread id, cachedImage_ will update context when image can be reused.
186     std::atomic<pid_t> cacheThreadId_;
187 
188     static inline std::mutex drawingCacheMapMutex_;
189     static inline std::unordered_map<NodeId, int32_t> drawingCacheUpdateTimeMap_;
190 
191     static thread_local bool isOpDropped_;
192     static inline std::atomic<int> totalProcessedNodeCount_ = 0;
193     static inline std::atomic<int> processedNodeCount_ = 0;
194     // used foe render group cache
195 
196     // opinc cache state
197     void NodeCacheStateDisable();
198     bool BeforeDrawCacheProcessChildNode(NodeStrategyType& cacheStragy, RSRenderParams& params);
199     void BeforeDrawCacheFindRootNode(Drawing::Canvas& canvas, const RSRenderParams& params, bool& isOpincDropNodeExt);
200     void DrawWithoutNodeGroupCache(
201         Drawing::Canvas& canvas, const RSRenderParams& params, DrawableCacheType originalCacheType);
202     void DrawWithNodeGroupCache(Drawing::Canvas& canvas, const RSRenderParams& params);
203 
204     void CheckRegionAndDrawWithoutFilter(
205         const std::vector<FilterNodeInfo>& filterInfoVec, Drawing::Canvas& canvas, const RSRenderParams& params);
206     void CheckRegionAndDrawWithFilter(std::vector<FilterNodeInfo>::const_iterator& begin,
207         const std::vector<FilterNodeInfo>& filterInfoVec, Drawing::Canvas& canvas, const RSRenderParams& params);
208     bool IsIntersectedWithFilter(std::vector<FilterNodeInfo>::const_iterator& begin,
209         const std::vector<FilterNodeInfo>& filterInfoVec,
210         Drawing::RectI& dstRect);
211     NodeRecordState recordState_ = NodeRecordState::RECORD_NONE;
212     NodeStrategyType rootNodeStragyType_ = NodeStrategyType::CACHE_NONE;
213     NodeStrategyType temNodeStragyType_ = NodeStrategyType::CACHE_NONE;
214     DrawAreaEnableState isDrawAreaEnable_ = DrawAreaEnableState::DRAW_AREA_INIT;
215     Drawing::OpListHandle opListDrawAreas_;
216     bool opCanCache_ = false;
217     int64_t reuseCount_ = 0;
218     bool isOpincRootNode_ = false;
219     bool isOpincDropNodeExtTemp_ = true;
220     bool isOpincCaculateStart_ = false;
OpincGetCachedMark()221     bool OpincGetCachedMark() const
222     {
223         return isOpincMarkCached_;
224     }
225     static thread_local bool isOffScreenWithClipHole_;
226     bool isOpincMarkCached_ = false;
227     bool IsOpincNodeInScreenRect(RSRenderParams& params);
228 };
229 } // namespace DrawableV2
230 } // namespace OHOS::Rosen
231 #endif // RENDER_SERVICE_DRAWABLE_RS_RENDER_NODE_DRAWABLE_H
232