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 RS_UIFIRST_MANAGER_H 17 #define RS_UIFIRST_MANAGER_H 18 19 #include <condition_variable> 20 #include <map> 21 #include <set> 22 #include <vector> 23 24 #include "drawable/rs_surface_render_node_drawable.h" 25 #include "pipeline/rs_processor.h" 26 #include "pipeline/main_thread/rs_main_thread.h" 27 #include "pipeline/rs_surface_render_node.h" 28 #include "transaction/rs_render_service_client.h" 29 30 namespace OHOS::Rosen { 31 class RSUifirstManager { 32 public: 33 // planning: move to display node 34 static RSUifirstManager& Instance(); 35 36 typedef enum { 37 STATE_NEED_SKIP, 38 STATE_NOT_SKIP, 39 STATE_NEED_CHECK, 40 } SkipSyncState; 41 42 struct EventInfo { 43 int64_t startTime = 0; 44 int64_t stopTime = 0; 45 int64_t uniqueId = 0; 46 int32_t appPid = -1; 47 std::string sceneId; 48 std::set<NodeId> disableNodes; 49 }; 50 51 void AddProcessDoneNode(NodeId id); 52 void AddProcessSkippedNode(NodeId id); 53 void AddPendingPostNode(NodeId id, std::shared_ptr<RSSurfaceRenderNode>& node, 54 MultiThreadCacheType cacheType); 55 void AddPendingResetNode(NodeId id, std::shared_ptr<RSSurfaceRenderNode>& node); 56 void AddReuseNode(NodeId id); 57 58 bool NeedNextDrawForSkippedNode(); 59 60 CacheProcessStatus GetNodeStatus(NodeId id); 61 // judge if surfacenode satisfies async subthread rendering condtions for Uifirst 62 void UpdateUifirstNodes(RSSurfaceRenderNode& node, bool ancestorNodeHasAnimation); 63 void UpdateUIFirstNodeUseDma(RSSurfaceRenderNode& node, const std::vector<RectI>& rects); 64 void PostUifistSubTasks(); 65 void ProcessSubDoneNode(); 66 bool CollectSkipSyncNode(const std::shared_ptr<RSRenderNode> &node); 67 void ForceClearSubthreadRes(); 68 void ProcessForceUpdateNode(); 69 bool ForceUpdateUifirstNodes(RSSurfaceRenderNode& node); 70 71 // event process 72 void OnProcessEventResponse(DataBaseRs& info); 73 void OnProcessEventComplete(DataBaseRs& info); 74 void PrepareCurrentFrameEvent(); 75 76 // animate procss 77 void OnProcessAnimateScene(SystemAnimatedScenes systemAnimatedScene); 78 79 bool NodeIsInCardWhiteList(RSRenderNode& node); GetCurrentFrameSkipFirstWait()80 bool GetCurrentFrameSkipFirstWait() const 81 { 82 return currentFrameCanSkipFirstWait_.load(); 83 } 84 bool CheckIfAppWindowHasAnimation(RSSurfaceRenderNode& node); 85 void DisableUifirstNode(RSSurfaceRenderNode& node); 86 static void ProcessTreeStateChange(RSSurfaceRenderNode& node); 87 GetUiFirstSwitch()88 bool GetUiFirstSwitch() const 89 { 90 return isUiFirstOn_; 91 } 92 SetUiFirstSwitch(bool uiFirstSwitch)93 void SetUiFirstSwitch(bool uiFirstSwitch) 94 { 95 isUiFirstOn_ = uiFirstSwitch; 96 } 97 SetCardUiFirstSwitch(bool cardUiFirstSwitch)98 void SetCardUiFirstSwitch(bool cardUiFirstSwitch) 99 { 100 isCardUiFirstOn_ = cardUiFirstSwitch; 101 } 102 GetUiFirstType()103 UiFirstCcmType GetUiFirstType() const 104 { 105 return uifirstType_; 106 } 107 108 void SetUiFirstType(int type); 109 SetPurgeEnable(bool purgeEnable)110 void SetPurgeEnable(bool purgeEnable) 111 { 112 purgeEnable_ = purgeEnable; 113 } 114 SetNodeNeedForceUpdateFlag(bool flag)115 void SetNodeNeedForceUpdateFlag(bool flag) 116 { 117 hasForceUpdateNode_ = flag; 118 } 119 HasForceUpdateNode()120 bool HasForceUpdateNode() 121 { 122 return hasForceUpdateNode_; 123 } 124 125 void MergeOldDirty(NodeId id); 126 void MergeOldDirtyToDirtyManager(std::shared_ptr<RSSurfaceRenderNode>& node); 127 SetRotationChanged(bool rotationChanged)128 void SetRotationChanged(bool rotationChanged) 129 { 130 rotationChanged_ = rotationChanged; 131 } 132 IsRecentTaskScene()133 bool IsRecentTaskScene() const 134 { 135 return isRecentTaskScene_.load(); 136 } 137 138 void AddCapturedNodes(NodeId id); 139 AddCardNodes(NodeId id,MultiThreadCacheType currentFrameCacheType)140 void AddCardNodes(NodeId id, MultiThreadCacheType currentFrameCacheType) 141 { 142 if (currentFrameCacheType != MultiThreadCacheType::ARKTS_CARD) { 143 return; 144 } 145 collectedCardNodes_.insert(id); 146 } 147 RemoveCardNodes(NodeId id)148 void RemoveCardNodes(NodeId id) 149 { 150 if (!collectedCardNodes_.count(id)) { 151 return; 152 } 153 collectedCardNodes_.erase(id); 154 } 155 GetPendingPostNodes()156 std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> GetPendingPostNodes() 157 { 158 return pendingPostNodes_; 159 } 160 161 void PostReleaseCacheSurfaceSubTasks(); 162 void PostReleaseCacheSurfaceSubTask(NodeId id); 163 void TryReleaseTextureForIdleThread(); 164 SetFreeMultiWindowStatus(bool enable)165 void SetFreeMultiWindowStatus(bool enable) 166 { 167 isFreeMultiWindowEnabled_ = enable; 168 } 169 UiFirstModeType GetUiFirstMode(); 170 void ReadUIFirstCcmParam(); 171 // only use in mainThread & RT onsync UifirstCurStateClear()172 inline void UifirstCurStateClear() 173 { 174 uifirstCacheState_.clear(); 175 } 176 177 bool IsSubTreeNeedPrepareForSnapshot(RSSurfaceRenderNode& node); 178 bool IsSubHighPriorityType(RSSurfaceRenderNode& node) const; 179 void CheckHwcChildrenType(RSSurfaceRenderNode& node, SurfaceHwcNodeType& enabledType); 180 void MarkSubHighPriorityType(RSSurfaceRenderNode& node); 181 private: 182 RSUifirstManager() = default; 183 ~RSUifirstManager() = default; 184 RSUifirstManager(const RSUifirstManager&); 185 RSUifirstManager(const RSUifirstManager&&); 186 RSUifirstManager& operator=(const RSUifirstManager&); 187 RSUifirstManager& operator=(const RSUifirstManager&&); 188 189 void PostSubTask(NodeId id); 190 void UpdateCompletedSurface(NodeId id); 191 192 std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> GetSurfaceDrawableByID(NodeId id); 193 bool SetUifirstNodeEnableParam(RSSurfaceRenderNode& node, MultiThreadCacheType type); 194 void RenderGroupUpdate(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable); 195 bool IsInLeashWindowTree(RSSurfaceRenderNode& node, NodeId instanceRootId); 196 197 void ProcessResetNode(); 198 void ProcessSkippedNode(); 199 void ProcessDoneNode(); 200 void ProcessDoneNodeInner(); 201 void UpdateSkipSyncNode(); 202 void RestoreSkipSyncNode(); 203 void ClearSubthreadRes(); 204 void ResetUifirstNode(std::shared_ptr<RSSurfaceRenderNode>& nodePtr); 205 bool CheckVisibleDirtyRegionIsEmpty(const std::shared_ptr<RSSurfaceRenderNode>& node); 206 bool CurSurfaceHasVisibleDirtyRegion(const std::shared_ptr<RSSurfaceRenderNode>& node); 207 void DoPurgePendingPostNodes(std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>& pendingNode); 208 void PurgePendingPostNodes(); 209 void SetNodePriorty(std::list<NodeId>& result, 210 std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>& pendingNode); 211 void SortSubThreadNodesPriority(); 212 static bool IsArkTsCardCache(RSSurfaceRenderNode& node, bool animation); 213 static bool IsLeashWindowCache(RSSurfaceRenderNode& node, bool animation); 214 void SyncHDRDisplayParam(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable, 215 const GraphicColorGamut& colorGamut); 216 static bool IsNonFocusWindowCache(RSSurfaceRenderNode& node, bool animation); 217 218 void UifirstStateChange(RSSurfaceRenderNode& node, MultiThreadCacheType currentFrameCacheType); 219 NodeId LeashWindowContainMainWindowAndStarting(RSSurfaceRenderNode& node); 220 void NotifyUIStartingWindow(NodeId id, bool wait); 221 void UpdateChildrenDirtyRect(RSSurfaceRenderNode& node); 222 bool EventsCanSkipFirstWait(std::vector<EventInfo>& events); 223 bool IsCardSkipFirstWaitScene(std::string& scene, int32_t appPid); 224 void EventDisableLeashWindowCache(NodeId id, EventInfo& info); 225 void ConvertPendingNodeToDrawable(); 226 void CheckCurrentFrameHasCardNodeReCreate(const RSSurfaceRenderNode& node); 227 void ResetCurrentFrameDeletedCardNodes(); 228 bool IsPreFirstLevelNodeDoingAndTryClear(std::shared_ptr<RSRenderNode> node); 229 SkipSyncState CollectSkipSyncNodeWithDrawableState(const std::shared_ptr<RSRenderNode> &node); 230 CacheProcessStatus& GetUifirstCachedState(NodeId id); 231 bool IsVMSurfaceName(std::string surfaceName); 232 233 bool IsToSubByAppAnimation() const; 234 bool QuerySubAssignable(RSSurfaceRenderNode& node, bool isRotation); 235 bool GetSubNodeIsTransparent(RSSurfaceRenderNode& node, std::string& dfxMsg); 236 237 bool rotationChanged_ = false; 238 bool isUiFirstOn_ = false; 239 bool purgeEnable_ = false; 240 bool isCardUiFirstOn_ = false; 241 UiFirstCcmType uifirstType_ = UiFirstCcmType::SINGLE; 242 bool hasForceUpdateNode_ = false; 243 bool isFreeMultiWindowEnabled_ = false; 244 std::atomic<bool> currentFrameCanSkipFirstWait_ = false; 245 // for recents scene 246 std::atomic<bool> isRecentTaskScene_ = false; 247 std::atomic<bool> isCurrentFrameHasCardNodeReCreate_ = false; 248 static constexpr int CLEAR_RES_THRESHOLD = 3; // 3 frames to clear resource 249 int32_t scbPid_ = 0; 250 std::atomic<int> noUifirstNodeFrameCount_ = 0; 251 NodeId entryViewNodeId_ = INVALID_NODEID; // desktop surfaceNode ID 252 NodeId negativeScreenNodeId_ = INVALID_NODEID; // negativeScreen surfaceNode ID 253 RSMainThread* mainThread_ = nullptr; 254 // only use in mainThread & RT onsync 255 std::vector<NodeId> pendingForceUpdateNode_; 256 std::vector<std::shared_ptr<RSRenderNode>> markForceUpdateByUifirst_; 257 258 std::map<NodeId, CacheProcessStatus> uifirstCacheState_; 259 260 // only use in RT 261 std::unordered_map<NodeId, std::shared_ptr<DrawableV2::RSRenderNodeDrawableAdapter>> subthreadProcessingNode_; 262 std::set<NodeId> processingNodeSkipSync_; 263 std::set<NodeId> processingNodePartialSync_; 264 std::set<NodeId> processingCardNodeSkipSync_; 265 // (instanceId, vector<needsync_node>) 266 std::unordered_map<NodeId, std::vector<std::shared_ptr<RSRenderNode>>> pendingSyncForSkipBefore_; 267 268 // use in RT & subThread 269 std::mutex childernDrawableMutex_; 270 std::vector<NodeId> subthreadProcessDoneNode_; 271 std::mutex skippedNodeMutex_; 272 std::unordered_set<NodeId> subthreadProcessSkippedNode_; 273 274 // pending post node: collect in main, use&clear in RT 275 std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> pendingPostNodes_; 276 std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> pendingPostCardNodes_; 277 std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> pendingResetNodes_; 278 std::list<NodeId> sortedSubThreadNodeIds_; 279 std::vector<std::shared_ptr<RSSurfaceRenderNode>> pindingResetWindowCachedNodes_; 280 281 std::set<NodeId> reuseNodes_; 282 std::set<NodeId> collectedCardNodes_; 283 // event list 284 std::mutex globalFrameEventMutex_; 285 std::vector<EventInfo> globalFrameEvent_; // <time, data> 286 std::vector<EventInfo> currentFrameEvent_; 287 // scene in scb 288 const std::vector<std::string> cardCanSkipFirstWaitScene_ = { 289 { "INTO_HOME_ANI" }, // unlock to desktop 290 { "FINGERPRINT_UNLOCK_ANI" }, // finger unlock to desktop 291 { "SCREEN_OFF_FINGERPRINT_UNLOCK_ANI" }, // aod finger unlock 292 { "PASSWORD_UNLOCK_ANI" }, // password unlock to desktop 293 { "FACIAL_FLING_UNLOCK_ANI" }, // facial unlock to desktop 294 { "FACIAL_UNLOCK_ANI" }, // facial unlock to desktop 295 { "APP_SWIPER_SCROLL" }, // desktop swipe 296 { "APP_SWIPER_FLING" }, // desktop swipe 297 { "LAUNCHER_SCROLL" }, // desktop swipe 298 { "SCROLL_2_AA" }, // desktop to negativeScreen 299 }; 300 const std::vector<std::string> toSubByAppAnimation_ = { 301 { "WINDOW_TITLE_BAR_MINIMIZED" }, 302 { "LAUNCHER_APP_LAUNCH_FROM_DOCK" }, 303 }; 304 305 const std::vector<std::string> vmAppNameSet_ = { 306 { "ohvm" }, 307 { "win_emulator" }, 308 { "hongyunvd" }, 309 { "ecoengine" }, 310 }; 311 312 std::vector<NodeId> capturedNodes_; 313 std::vector<NodeId> currentFrameDeletedCardNodes_; 314 }; 315 class RSB_EXPORT RSUiFirstProcessStateCheckerHelper { 316 public: RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId,NodeId curUifirstRootNodeId,NodeId curNodeId)317 RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId, NodeId curUifirstRootNodeId, NodeId curNodeId) 318 { 319 isCurUifirstRootNodeId_ = curNodeId == curUifirstRootNodeId; 320 isCurFirsLevelNodeId_ = curNodeId == curFirsLevelNodeId; 321 if (isCurUifirstRootNodeId_) { 322 curUifirstRootNodeId_ = curUifirstRootNodeId; 323 } 324 if (isCurFirsLevelNodeId_) { 325 curFirstLevelNodeId_ = curFirsLevelNodeId; 326 } 327 } 328 329 // If a subnode is delivered directly 330 // record the firstLevelNodeId in the delivered subnode as the real one. RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId,NodeId curUifirstRootNodeId)331 RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId, NodeId curUifirstRootNodeId) 332 { 333 isCurUifirstRootNodeId_ = true; 334 isCurFirsLevelNodeId_ = true; 335 curUifirstRootNodeId_ = curUifirstRootNodeId; 336 curFirstLevelNodeId_ = curFirsLevelNodeId; 337 } 338 ~RSUiFirstProcessStateCheckerHelper()339 ~RSUiFirstProcessStateCheckerHelper() 340 { 341 if (isCurUifirstRootNodeId_) { 342 curUifirstRootNodeId_ = INVALID_NODEID; 343 } 344 if (isCurFirsLevelNodeId_) { 345 curFirstLevelNodeId_ = INVALID_NODEID; 346 } 347 } 348 // return false when timeout NotifyAll(std::function<void ()> condChange)349 static inline void NotifyAll(std::function<void()> condChange) 350 { 351 if (LIKELY(condChange)) { 352 std::unique_lock<std::mutex> lock(notifyMutex_); 353 condChange(); 354 } 355 notifyCv_.notify_all(); 356 } 357 static bool CheckMatchAndWaitNotify(const RSRenderParams& params, bool checkMatch = true); 358 private: 359 static bool IsCurFirstLevelMatch(const RSRenderParams& params); 360 static bool CheckAndWaitPreFirstLevelDrawableNotify(const RSRenderParams& params); 361 362 static inline std::mutex notifyMutex_; 363 static inline std::condition_variable notifyCv_; 364 365 static inline thread_local NodeId curUifirstRootNodeId_ = INVALID_NODEID; 366 static inline thread_local NodeId curFirstLevelNodeId_ = INVALID_NODEID; 367 368 bool isCurUifirstRootNodeId_ = false; 369 bool isCurFirsLevelNodeId_ = false; 370 }; 371 } 372 #endif // RS_UIFIRST_MANAGER_H 373