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