1 /* 2 * Copyright (c) 2022-2023 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 #ifndef RENDER_SERVICE_CORE_PIPELINE_RS_UNI_RENDER_VISITOR_H 16 #define RENDER_SERVICE_CORE_PIPELINE_RS_UNI_RENDER_VISITOR_H 17 18 #include <cstdint> 19 #include <list> 20 #include <memory> 21 #include <mutex> 22 #include <optional> 23 #include <parameters.h> 24 #include <set> 25 26 #include "rs_base_render_engine.h" 27 28 #include "hgm_frame_rate_manager.h" 29 #include "pipeline/driven_render/rs_driven_render_manager.h" 30 #include "pipeline/rs_dirty_region_manager.h" 31 #include "pipeline/rs_processor.h" 32 #include "platform/ohos/overdraw/rs_cpu_overdraw_canvas_listener.h" 33 #include "platform/ohos/overdraw/rs_gpu_overdraw_canvas_listener.h" 34 #include "platform/ohos/overdraw/rs_overdraw_controller.h" 35 #include "screen_manager/rs_screen_manager.h" 36 #include "system/rs_system_parameters.h" 37 #include "visitor/rs_node_visitor.h" 38 39 class SkPicture; 40 namespace OHOS { 41 namespace Rosen { 42 class RSPaintFilterCanvas; 43 class RSUniRenderVisitor : public RSNodeVisitor { 44 public: 45 using SurfaceDirtyMgrPair = std::pair<std::shared_ptr<RSSurfaceRenderNode>, std::shared_ptr<RSSurfaceRenderNode>>; 46 RSUniRenderVisitor(); 47 RSUniRenderVisitor(std::shared_ptr<RSPaintFilterCanvas> canvas, uint32_t surfaceIndex); 48 explicit RSUniRenderVisitor(const RSUniRenderVisitor& visitor); 49 ~RSUniRenderVisitor() override; 50 51 void PrepareChildren(RSRenderNode& node) override; 52 void PrepareCanvasRenderNode(RSCanvasRenderNode& node) override; 53 void PrepareDisplayRenderNode(RSDisplayRenderNode& node) override; 54 void PrepareProxyRenderNode(RSProxyRenderNode& node) override; 55 void PrepareRootRenderNode(RSRootRenderNode& node) override; 56 void PrepareSurfaceRenderNode(RSSurfaceRenderNode& node) override; 57 void PrepareEffectRenderNode(RSEffectRenderNode& node) override; 58 59 void ProcessChildren(RSRenderNode& node) override; 60 void ProcessCanvasRenderNode(RSCanvasRenderNode& node) override; 61 void ProcessDisplayRenderNode(RSDisplayRenderNode& node) override; 62 void ProcessProxyRenderNode(RSProxyRenderNode& node) override; 63 void ProcessRootRenderNode(RSRootRenderNode& node) override; 64 void ProcessSurfaceRenderNode(RSSurfaceRenderNode& node) override; 65 void ProcessEffectRenderNode(RSEffectRenderNode& node) override; 66 67 bool DoDirectComposition(std::shared_ptr<RSBaseRenderNode> rootNode); 68 bool ParallelComposition(const std::shared_ptr<RSBaseRenderNode> rootNode); 69 void ChangeCacheRenderNodeMap(RSRenderNode& node, const uint32_t count = 0); 70 void UpdateCacheRenderNodeMap(RSRenderNode& node); 71 bool GenerateNodeContentCache(RSRenderNode& node); 72 bool InitNodeCache(RSRenderNode& node); 73 void CopyVisitorInfos(std::shared_ptr<RSUniRenderVisitor> visitor); SetProcessorRenderEngine(std::shared_ptr<RSBaseRenderEngine> renderEngine)74 void SetProcessorRenderEngine(std::shared_ptr<RSBaseRenderEngine> renderEngine) 75 { 76 renderEngine_ = renderEngine; 77 } 78 SetAnimateState(bool doAnimate)79 void SetAnimateState(bool doAnimate) 80 { 81 doAnimate_ = doAnimate; 82 } 83 SetDirtyFlag(bool isDirty)84 void SetDirtyFlag(bool isDirty) 85 { 86 isDirty_ = isDirty; 87 } 88 SetFocusedNodeId(uint64_t nodeId)89 void SetFocusedNodeId(uint64_t nodeId) 90 { 91 currentFocusedNodeId_ = nodeId; 92 } 93 SetSubThreadConfig(uint32_t threadIndex)94 void SetSubThreadConfig(uint32_t threadIndex) 95 { 96 isSubThread_ = true; 97 isHardwareForcedDisabled_ = true; 98 threadIndex_ = threadIndex; 99 } 100 101 void DrawSurfaceLayer(const std::shared_ptr<RSDisplayRenderNode>& displayNode, 102 const std::list<std::shared_ptr<RSSurfaceRenderNode>>& subThreadNodes) const; 103 GetAnimateState()104 bool GetAnimateState() const 105 { 106 return doAnimate_; 107 } 108 MarkHardwareForcedDisabled()109 void MarkHardwareForcedDisabled() 110 { 111 isHardwareForcedDisabled_ = true; 112 } 113 SetDrivenRenderFlag(bool hasDrivenNodeOnUniTree,bool hasDrivenNodeMarkRender)114 void SetDrivenRenderFlag(bool hasDrivenNodeOnUniTree, bool hasDrivenNodeMarkRender) 115 { 116 if (!drivenInfo_) { 117 return; 118 } 119 drivenInfo_->prepareInfo.hasDrivenNodeOnUniTree = hasDrivenNodeOnUniTree; 120 drivenInfo_->hasDrivenNodeMarkRender = hasDrivenNodeMarkRender; 121 } 122 123 void SetHardwareEnabledNodes(const std::vector<std::shared_ptr<RSSurfaceRenderNode>>& hardwareEnabledNodes); 124 void AssignGlobalZOrderAndCreateLayer(); 125 126 void CopyForParallelPrepare(std::shared_ptr<RSUniRenderVisitor> visitor); 127 // Some properties defined before ProcessSurfaceRenderNode() may be used in 128 // ProcessSurfaceRenderNode() method. We should copy these properties in parallel render. 129 void CopyPropertyForParallelVisitor(RSUniRenderVisitor *mainVisitor); GetIsPartialRenderEnabled()130 bool GetIsPartialRenderEnabled() const 131 { 132 return isPartialRenderEnabled_; 133 } GetIsOpDropped()134 bool GetIsOpDropped() const 135 { 136 return isOpDropped_; 137 } 138 // Use in vulkan parallel rendering GetColorGamut()139 GraphicColorGamut GetColorGamut() const 140 { 141 return newColorSpace_; 142 } 143 GetProcessor()144 std::shared_ptr<RSProcessor> GetProcessor() const 145 { 146 return processor_; 147 } 148 SetRenderFrame(std::unique_ptr<RSRenderFrame> renderFrame)149 void SetRenderFrame(std::unique_ptr<RSRenderFrame> renderFrame) 150 { 151 renderFrame_ = std::move(renderFrame); 152 } 153 void SetAppWindowNum(uint32_t num); 154 GetFrameRateRangeData()155 FrameRateRangeData GetFrameRateRangeData() 156 { 157 return frameRateRangeData_; 158 } 159 void CollectFrameRateRange(RSRenderNode& node); 160 161 #ifndef USE_ROSEN_DRAWING 162 using RenderParam = std::tuple<std::shared_ptr<RSRenderNode>, float, std::optional<SkMatrix>>; 163 #else 164 using RenderParam = std::tuple<std::shared_ptr<RSRenderNode>, float, std::optional<Drawing::Matrix>>; 165 #endif 166 private: 167 void DrawWatermarkIfNeed(); 168 #ifndef USE_ROSEN_DRAWING 169 void DrawDirtyRectForDFX(const RectI& dirtyRect, const SkColor color, 170 const SkPaint::Style fillType, float alpha, int edgeWidth); 171 #else 172 enum class RSPaintStyle { 173 FILL, 174 STROKE 175 }; 176 void DrawDirtyRectForDFX(const RectI& dirtyRect, const Drawing::Color color, 177 const RSPaintStyle fillType, float alpha, int edgeWidth); 178 #endif 179 void DrawDirtyRegionForDFX(std::vector<RectI> dirtyRects); 180 void DrawCacheRegionForDFX(std::vector<RectI> cacheRects); 181 void DrawAllSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node, const Occlusion::Region& region); 182 void DrawTargetSurfaceDirtyRegionForDFX(RSDisplayRenderNode& node); 183 void DrawAllSurfaceOpaqueRegionForDFX(RSDisplayRenderNode& node); 184 void DrawSurfaceOpaqueRegionForDFX(RSSurfaceRenderNode& node); 185 // check if surface name is in dfx target list CheckIfSurfaceTargetedForDFX(std::string nodeName)186 inline bool CheckIfSurfaceTargetedForDFX(std::string nodeName) 187 { 188 return (std::find(dfxTargetSurfaceNames_.begin(), dfxTargetSurfaceNames_.end(), 189 nodeName) != dfxTargetSurfaceNames_.end()); 190 } 191 192 bool DrawDetailedTypesOfDirtyRegionForDFX(RSSurfaceRenderNode& node); 193 void DrawAndTraceSingleDirtyRegionTypeForDFX(RSSurfaceRenderNode& node, 194 DirtyRegionType dirtyType, bool isDrawn = true); 195 196 std::vector<RectI> GetDirtyRects(const Occlusion::Region ®ion); 197 /* calculate display/global (between windows) level dirty region, current include: 198 * 1. window move/add/remove 2. transparent dirty region 199 * when process canvas culling, canvas intersect with surface's visibledirty region or 200 * global dirty region will be skipped 201 */ 202 void CalcDirtyDisplayRegion(std::shared_ptr<RSDisplayRenderNode>& node); 203 void CalcDirtyRegionForFilterNode(const RectI filterRect, 204 std::shared_ptr<RSSurfaceRenderNode>& currentSurfaceNode, 205 std::shared_ptr<RSDisplayRenderNode>& displayNode); 206 void CalcDirtyFilterRegion(std::shared_ptr<RSDisplayRenderNode>& node); 207 /* Disable visible hwc surface if it intersects with filter region 208 * Save rest validNodes in prevHwcEnabledNodes 209 * [planning] Update hwc surface dirty status at the same time 210 */ 211 void UpdateHardwareNodeStatusBasedOnFilter(std::shared_ptr<RSSurfaceRenderNode>& node, 212 std::vector<SurfaceDirtyMgrPair>& prevHwcEnabledNodes, 213 std::shared_ptr<RSDirtyRegionManager>& displayDirtyManager); 214 /* Disable hwc surface intersect with filter rects and merge dirty filter region 215 * [planning] If invisible filterRects could be removed 216 */ 217 RectI UpdateHardwareEnableList(std::vector<RectI>& filterRects, 218 std::vector<SurfaceDirtyMgrPair>& validHwcNodes); 219 void MergeDirtyRectIfNeed(std::shared_ptr<RSSurfaceRenderNode> appNode, 220 std::shared_ptr<RSSurfaceRenderNode> hwcNode); 221 void AddContainerDirtyToGlobalDirty(std::shared_ptr<RSDisplayRenderNode>& node) const; 222 223 // set global dirty region to each surface node 224 void SetSurfaceGlobalDirtyRegion(std::shared_ptr<RSDisplayRenderNode>& node); 225 void SetSurfaceGlobalAlignedDirtyRegion(std::shared_ptr<RSDisplayRenderNode>& node, 226 const Occlusion::Region alignedDirtyRegion); 227 void AlignGlobalAndSurfaceDirtyRegions(std::shared_ptr<RSDisplayRenderNode>& node); 228 229 void CheckAndSetNodeCacheType(RSRenderNode& node); 230 bool UpdateCacheSurface(RSRenderNode& node); 231 void DrawSpherize(RSRenderNode& node); 232 void DrawChildRenderNode(RSRenderNode& node); 233 void DrawChildCanvasRenderNode(RSRenderNode& node); 234 235 void CheckColorSpace(RSSurfaceRenderNode& node); 236 void AddOverDrawListener(std::unique_ptr<RSRenderFrame>& renderFrame, 237 std::shared_ptr<RSCanvasListener>& overdrawListener); 238 /* Judge if surface render node could skip preparation: 239 * 1. not leash window 240 * 2. parent not dirty 241 * 3. no processWithCommands_ of node's corresponding pid 242 * If so, reset status flag and stop traversal 243 */ 244 bool CheckIfSurfaceRenderNodeStatic(RSSurfaceRenderNode& node); 245 void PrepareTypesOfSurfaceRenderNodeBeforeUpdate(RSSurfaceRenderNode& node); 246 void PrepareTypesOfSurfaceRenderNodeAfterUpdate(RSSurfaceRenderNode& node); 247 // judge if node's cache changes 248 void UpdateCacheChangeStatus(RSBaseRenderNode& node); 249 // set node cacheable animation after checking whold child tree 250 void SetNodeCacheChangeStatus(RSBaseRenderNode& node, int markedCachedNodeCnt); 251 // update rendernode's cache status and collect valid cache rect 252 void UpdateForegroundFilterCacheWithDirty(RSRenderNode& node); 253 254 bool IsHardwareComposerEnabled(); 255 256 bool CheckIfSurfaceRenderNodeNeedProcess(RSSurfaceRenderNode& node); 257 258 void ClearTransparentBeforeSaveLayer(); 259 // mark surfaceNode's child surfaceView nodes hardware forced disabled 260 void MarkSubHardwareEnableNodeState(RSSurfaceRenderNode& surfaceNode); 261 // adjust local zOrder if surfaceNode's child surfaceView nodes skipped by dirty region 262 void AdjustLocalZOrder(std::shared_ptr<RSSurfaceRenderNode> surfaceNode); 263 264 void RecordAppWindowNodeAndPostTask(RSSurfaceRenderNode& node, float width, float height); 265 // offscreen render related 266 void PrepareOffscreenRender(RSRenderNode& node); 267 void FinishOffscreenRender(); 268 void ParallelPrepareDisplayRenderNodeChildrens(RSDisplayRenderNode& node); 269 bool AdaptiveSubRenderThreadMode(bool doParallel); 270 void ParallelRenderEnableHardwareComposer(RSSurfaceRenderNode& node); 271 // close partialrender when perform window animation 272 void ClosePartialRenderWhenAnimatingWindows(std::shared_ptr<RSDisplayRenderNode>& node); 273 int32_t GetNodePreferred(std::vector<HgmModifierProfile> hgmModifierProfileList) const; 274 275 bool DrawBlurInCache(RSRenderNode& node); 276 void UpdateCacheRenderNodeMapWithBlur(RSRenderNode& node); 277 278 #ifndef USE_ROSEN_DRAWING 279 sk_sp<SkSurface> offscreenSurface_; // temporary holds offscreen surface 280 #else 281 std::shared_ptr<Drawing::Surface> offscreenSurface_; // temporary holds offscreen surface 282 #endif 283 std::shared_ptr<RSPaintFilterCanvas> canvasBackup_; // backup current canvas before offscreen render 284 285 // Use in vulkan parallel rendering 286 void ProcessParallelDisplayRenderNode(RSDisplayRenderNode& node); 287 288 ScreenInfo screenInfo_; 289 std::shared_ptr<RSDirtyRegionManager> curSurfaceDirtyManager_; 290 std::shared_ptr<RSRenderNode> curRootNode_; 291 std::shared_ptr<RSSurfaceRenderNode> curSurfaceNode_; 292 float curAlpha_ = 1.f; 293 bool dirtyFlag_ { false }; 294 std::unique_ptr<RSRenderFrame> renderFrame_; 295 std::shared_ptr<RSPaintFilterCanvas> canvas_; 296 std::map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> dirtySurfaceNodeMap_; 297 std::vector<RectI> cacheRenderNodeMapRects_; 298 #ifndef USE_ROSEN_DRAWING 299 SkRect boundsRect_ {}; 300 #else 301 Drawing::Rect boundsRect_ {}; 302 #endif 303 Gravity frameGravity_ = Gravity::DEFAULT; 304 305 int32_t offsetX_ { 0 }; 306 int32_t offsetY_ { 0 }; 307 std::shared_ptr<RSProcessor> processor_; 308 #ifndef USE_ROSEN_DRAWING 309 SkMatrix parentSurfaceNodeMatrix_; 310 #else 311 Drawing::Matrix parentSurfaceNodeMatrix_; 312 #endif 313 314 ScreenId currentVisitDisplay_ = INVALID_SCREEN_ID; 315 std::map<ScreenId, int> displayHasSecSurface_; 316 std::set<ScreenId> mirroredDisplays_; 317 bool isSecurityDisplay_ = false; 318 319 bool hasFingerprint_ = false; 320 321 std::shared_ptr<RSBaseRenderEngine> renderEngine_; 322 323 std::shared_ptr<RSDirtyRegionManager> curDisplayDirtyManager_; 324 std::shared_ptr<RSDisplayRenderNode> curDisplayNode_; 325 bool doAnimate_ = false; 326 bool isSurfaceRotationChanged_ = false; 327 bool isPartialRenderEnabled_ = false; 328 bool isOpDropped_ = false; 329 bool isDirtyRegionDfxEnabled_ = false; // dirtyRegion DFX visualization 330 bool isTargetDirtyRegionDfxEnabled_ = false; 331 bool isOpaqueRegionDfxEnabled_ = false; 332 bool isQuickSkipPreparationEnabled_ = false; 333 bool isHardwareComposerEnabled_ = false; 334 bool isOcclusionEnabled_ = false; 335 std::vector<std::string> dfxTargetSurfaceNames_; 336 PartialRenderType partialRenderType_; 337 QuickSkipPrepareType quickSkipPrepareType_; 338 DirtyRegionDebugType dirtyRegionDebugType_; 339 bool isDirty_ = false; 340 // added for judge if drawing cache changes 341 bool isDrawingCacheEnabled_ = false; 342 bool isDrawingCacheChanged_ = false; 343 bool childHasSurface_ = false; 344 int markedCachedNodes_ = 0; 345 std::vector<RectI> accumulatedDirtyRegions_ = {}; 346 347 bool needFilter_ = false; 348 GraphicColorGamut newColorSpace_ = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB; 349 std::vector<ScreenColorGamut> colorGamutModes_; 350 uint64_t currentFocusedNodeId_ = 0; 351 352 bool isSubThread_ = false; 353 bool isUIFirst_ = false; 354 uint32_t threadIndex_ = UNI_MAIN_THREAD_INDEX; 355 356 bool needColdStartThread_ = false; // flag used for cold start app window 357 358 bool isDirtyRegionAlignedEnable_ = false; 359 std::shared_ptr<std::mutex> surfaceNodePrepareMutex_; 360 uint32_t parallelRenderVisitorIndex_ = 0; 361 ParallelRenderingType parallelRenderType_; 362 363 RectI prepareClipRect_{0, 0, 0, 0}; // renderNode clip rect used in Prepare 364 bool isClipBoundDirty_ = false; // if node is clipbound dirty, its dirtyregion merge can be skipped 365 366 // count prepared and processed canvasnode numbers per app 367 // unirender visitor resets every frame, no overflow risk here 368 unsigned int preparedCanvasNodeInCurrentSurface_ = 0; 369 unsigned int processedCanvasNodeInCurrentSurface_ = 0; 370 unsigned int processedPureContainerNode_ = 0; 371 372 float globalZOrder_ = 0.0f; 373 bool isUpdateCachedSurface_ = false; 374 bool isHardwareForcedDisabled_ = false; // indicates if hardware composer is totally disabled 375 std::vector<std::shared_ptr<RSSurfaceRenderNode>> hardwareEnabledNodes_; 376 // vector of all app window nodes with surfaceView, sorted by zOrder 377 std::vector<std::shared_ptr<RSSurfaceRenderNode>> appWindowNodesInZOrder_; 378 float localZOrder_ = 0.0f; // local zOrder for surfaceView under same app window node 379 380 // driven render 381 std::unique_ptr<DrivenInfo> drivenInfo_ = nullptr; 382 383 std::unordered_map<NodeId, RenderParam> unpairedTransitionNodes_; 384 std::stack<RenderParam> curGroupedNodes_; 385 // return true if we should prepare/process, false if we should skip. 386 bool PrepareSharedTransitionNode(RSBaseRenderNode& node); 387 bool ProcessSharedTransitionNode(RSBaseRenderNode& node); 388 389 std::weak_ptr<RSBaseRenderNode> logicParentNode_; 390 391 bool isCalcCostEnable_ = false; 392 // adapt to sceneboard, mark if the canvasNode within the scope of surfaceNode 393 bool isSubNodeOfSurfaceInPrepare_ = false; 394 bool isSubNodeOfSurfaceInProcess_ = false; 395 396 uint32_t appWindowNum_ = 0; 397 398 bool isParallel_ = false; 399 bool doParallelComposition_ = false; 400 bool doParallelRender_ = false; 401 // displayNodeMatrix only used in offScreen render case to ensure correct composer layer info when with rotation, 402 // displayNodeMatrix indicates display node's matrix info 403 #ifndef USE_ROSEN_DRAWING 404 std::optional<SkMatrix> displayNodeMatrix_; 405 #else 406 std::optional<Drawing::Matrix> displayNodeMatrix_; 407 #endif 408 mutable std::mutex copyVisitorInfosMutex_; 409 #ifndef USE_ROSEN_DRAWING 410 sk_sp<SkImage> cacheImgForCapture_ = nullptr; 411 #else 412 std::shared_ptr<Drawing::Image> cacheImgForCapture_ = nullptr; 413 #endif 414 bool resetRotate_ = false; 415 bool needCacheImg_ = false; 416 uint32_t captureWindowZorder_ = 0; 417 #ifndef USE_ROSEN_DRAWING 418 std::optional<SkPath> effectRegion_ = std::nullopt; 419 #else 420 std::optional<Drawing::Path> effectRegion_ = std::nullopt; 421 #endif 422 bool curDirty_ = false; 423 bool curContentDirty_ = false; 424 425 // calculate preferred fps 426 FrameRateRangeData frameRateRangeData_; 427 428 std::unordered_map<NodeId, std::unordered_map<NodeId, RectI>> allCacheFilterRects_ = {}; 429 std::stack<std::unordered_map<NodeId, RectI>> curCacheFilterRects_ = {}; 430 }; 431 } // namespace Rosen 432 } // namespace OHOS 433 434 #endif // RENDER_SERVICE_CORE_PIPELINE_RS_UNI_RENDER_VISITOR_H 435