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