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