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