• 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 
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