• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     bool CurSurfaceHasVisibleDirtyRegion(const std::shared_ptr<RSSurfaceRenderNode>& node);
186     void DoPurgePendingPostNodes(std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>& pendingNode);
187     void PurgePendingPostNodes();
188     void SetNodePriorty(std::list<NodeId>& result,
189         std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>& pendingNode);
190     void SortSubThreadNodesPriority();
191     static bool IsArkTsCardCache(RSSurfaceRenderNode& node, bool animation);
192     static bool IsLeashWindowCache(RSSurfaceRenderNode& node, bool animation);
193     static bool IsNonFocusWindowCache(RSSurfaceRenderNode& node, bool animation);
194     void SyncHDRDisplayParam(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable);
195 
196     void UifirstStateChange(RSSurfaceRenderNode& node, MultiThreadCacheType currentFrameCacheType);
197     NodeId LeashWindowContainMainWindowAndStarting(RSSurfaceRenderNode& node);
198     void NotifyUIStartingWindow(NodeId id, bool wait);
199     void UpdateChildrenDirtyRect(RSSurfaceRenderNode& node);
200     bool EventsCanSkipFirstWait(std::vector<EventInfo>& events);
201     bool IsCardSkipFirstWaitScene(std::string& scene, int32_t appPid);
202     void EventDisableLeashWindowCache(NodeId id, EventInfo& info);
203     void ConvertPendingNodeToDrawable();
204     void CheckCurrentFrameHasCardNodeReCreate(const RSSurfaceRenderNode& node);
205     void ResetCurrentFrameDeletedCardNodes();
206     bool IsPreFirstLevelNodeDoingAndTryClear(std::shared_ptr<RSRenderNode> node);
207     SkipSyncState CollectSkipSyncNodeWithDrawableState(const std::shared_ptr<RSRenderNode> &node);
208     CacheProcessStatus& GetUifirstCachedState(NodeId id);
209 
210     // only use in mainThread & RT onsync
211     std::vector<NodeId> pendingForceUpdateNode_;
212     std::vector<std::shared_ptr<RSRenderNode>> markForceUpdateByUifirst_;
213     bool rotationChanged_ = false;
214 
215     std::map<NodeId, CacheProcessStatus> uifirstCacheState_;
216 
217     // only use in RT
218     std::unordered_map<NodeId, std::shared_ptr<DrawableV2::RSRenderNodeDrawableAdapter>> subthreadProcessingNode_;
219     std::set<NodeId> processingNodeSkipSync_;
220     std::set<NodeId> processingNodePartialSync_;
221     std::set<NodeId> processingCardNodeSkipSync_;
222     // (instanceId, vector<needsync_node>)
223     std::unordered_map<NodeId, std::vector<std::shared_ptr<RSRenderNode>>> pendingSyncForSkipBefore_;
224 
225     // use in RT & subThread
226     std::mutex childernDrawableMutex_;
227     std::vector<NodeId> subthreadProcessDoneNode_;
228 
229     // pending post node: collect in main, use&clear in RT
230     std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> pendingPostNodes_;
231     std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> pendingPostCardNodes_;
232     std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> pendingResetNodes_;
233     std::vector<std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable>> pendingPostDrawables_;
234     bool isUiFirstOn_ = false;
235     std::list<NodeId> sortedSubThreadNodeIds_;
236     std::vector<std::shared_ptr<RSSurfaceRenderNode>>  pindingResetWindowCachedNodes_;
237 
238     std::set<NodeId> reuseNodes_;
239     std::set<NodeId> collectedCardNodes_;
240     static constexpr int CLEAR_RES_THRESHOLD = 3; // 3 frames  to clear resource
241     std::atomic<int> noUifirstNodeFrameCount_ = 0;
242     bool hasDoneNode_ = false;
243     // event list
244     std::mutex globalFrameEventMutex_;
245     std::vector<EventInfo> globalFrameEvent_; // <time, data>
246     std::vector<EventInfo> currentFrameEvent_;
247     std::atomic<bool> currentFrameCanSkipFirstWait_ = false;
248     NodeId entryViewNodeId_ = INVALID_NODEID; // desktop surfaceNode ID
249     NodeId negativeScreenNodeId_ = INVALID_NODEID; // negativeScreen surfaceNode ID
250     int32_t scbPid_ = 0;
251     RSMainThread* mainThread_ = nullptr;
252     // scene in scb
253     const std::vector<std::string> cardCanSkipFirstWaitScene_ = {
254         { "INTO_HOME_ANI" }, // unlock to desktop
255         { "FINGERPRINT_UNLOCK_ANI" }, // finger unlock to desktop
256         { "SCREEN_OFF_FINGERPRINT_UNLOCK_ANI" }, // aod finger unlock
257         { "PASSWORD_UNLOCK_ANI" }, // password unlock to desktop
258         { "FACIAL_FLING_UNLOCK_ANI" }, // facial unlock to desktop
259         { "FACIAL_UNLOCK_ANI" }, // facial unlock to desktop
260         { "APP_SWIPER_SCROLL" }, // desktop swipe
261         { "APP_SWIPER_FLING" }, // desktop swipe
262         { "LAUNCHER_SCROLL" }, // desktop swipe
263         { "SCROLL_2_AA" }, // desktop to negativeScreen
264     };
265     const std::vector<std::string> screenshotAnimation_ = {
266         { "SCREENSHOT_SCALE_ANIMATION" },
267         { "SCREENSHOT_DISMISS_ANIMATION" },
268     };
269 
270     // use in MainThread & RT & subThread
271     std::mutex useDmaBufferMutex_;
272     bool useDmaBuffer_ = false;
273     // for recents scene
274     std::atomic<bool> isRecentTaskScene_ = false;
275     std::vector<NodeId> capturedNodes_;
276     std::vector<NodeId> currentFrameDeletedCardNodes_;
277     std::atomic<bool> isCurrentFrameHasCardNodeReCreate_ = false;
278 };
279 
280 // If a subnode is delivered directly
281 // record the firstLevelNodeId in the delivered subnode as the real one.
282 class RSB_EXPORT RSUiFirstProcessStateCheckerHelper {
283 public:
RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId,NodeId curUifirstRootNodeId,NodeId curNodeId)284     RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId, NodeId curUifirstRootNodeId, NodeId curNodeId)
285     {
286         isCurUifirstRootNodeId_ = curNodeId == curUifirstRootNodeId;
287         isCurFirsLevelNodeId_ = curNodeId == curFirsLevelNodeId;
288         if (isCurUifirstRootNodeId_) {
289             curUifirstRootNodeId_ = curUifirstRootNodeId;
290         }
291         if (isCurFirsLevelNodeId_) {
292             curFirstLevelNodeId_ = curFirsLevelNodeId;
293         }
294     }
295 
RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId,NodeId curUifirstRootNodeId)296     RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId, NodeId curUifirstRootNodeId)
297     {
298         isCurUifirstRootNodeId_ = true;
299         isCurFirsLevelNodeId_  = true;
300         curUifirstRootNodeId_ = curUifirstRootNodeId;
301         curFirstLevelNodeId_ = curFirsLevelNodeId;
302     }
303 
~RSUiFirstProcessStateCheckerHelper()304     ~RSUiFirstProcessStateCheckerHelper()
305     {
306         if (isCurUifirstRootNodeId_) {
307             curUifirstRootNodeId_ = INVALID_NODEID;
308         }
309         if (isCurFirsLevelNodeId_) {
310             curFirstLevelNodeId_ = INVALID_NODEID;
311         }
312     }
313     // return false when timeout
NotifyAll()314     static void NotifyAll()
315     {
316         notifyCv_.notify_all();
317     }
318     static bool CheckMatchAndWaitNotify(const RSRenderParams& params, bool checkMatch = true);
319 private:
320     static bool IsCurFirstLevelMatch(const RSRenderParams& params);
321     static bool CheckAndWaitPreFirstLevelDrawableNotify(const RSRenderParams& params);
322 
323     static inline std::mutex notifyMutex_;
324     static inline std::condition_variable notifyCv_;
325 
326     static inline thread_local NodeId curUifirstRootNodeId_ = INVALID_NODEID;
327     static inline thread_local NodeId curFirstLevelNodeId_ = INVALID_NODEID;
328 
329     bool isCurUifirstRootNodeId_ = false;
330     bool isCurFirsLevelNodeId_ = false;
331 };
332 }
333 #endif // RS_UIFIRST_MANAGER_H
334