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