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