• 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 "drawable/rs_surface_render_node_drawable.h"
25 #include "pipeline/rs_processor.h"
26 #include "pipeline/main_thread/rs_main_thread.h"
27 #include "pipeline/rs_surface_render_node.h"
28 #include "transaction/rs_render_service_client.h"
29 
30 namespace OHOS::Rosen {
31 class RSUifirstManager {
32 public:
33     // planning: move to display node
34     static RSUifirstManager& Instance();
35 
36     typedef enum {
37         STATE_NEED_SKIP,
38         STATE_NOT_SKIP,
39         STATE_NEED_CHECK,
40     } SkipSyncState;
41 
42     struct EventInfo {
43         int64_t startTime = 0;
44         int64_t stopTime = 0;
45         int64_t uniqueId = 0;
46         int32_t appPid = -1;
47         std::string sceneId;
48         std::set<NodeId> disableNodes;
49     };
50 
51     void AddProcessDoneNode(NodeId id);
52     void AddProcessSkippedNode(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     bool NeedNextDrawForSkippedNode();
59 
60     CacheProcessStatus GetNodeStatus(NodeId id);
61     // judge if surfacenode satisfies async subthread rendering condtions for Uifirst
62     void UpdateUifirstNodes(RSSurfaceRenderNode& node, bool ancestorNodeHasAnimation);
63     void UpdateUIFirstNodeUseDma(RSSurfaceRenderNode& node, const std::vector<RectI>& rects);
64     void PostUifistSubTasks();
65     void ProcessSubDoneNode();
66     bool CollectSkipSyncNode(const std::shared_ptr<RSRenderNode> &node);
67     void ForceClearSubthreadRes();
68     void ProcessForceUpdateNode();
69     bool ForceUpdateUifirstNodes(RSSurfaceRenderNode& node);
70 
71     // event process
72     void OnProcessEventResponse(DataBaseRs& info);
73     void OnProcessEventComplete(DataBaseRs& info);
74     void PrepareCurrentFrameEvent();
75 
76     // animate procss
77     void OnProcessAnimateScene(SystemAnimatedScenes systemAnimatedScene);
78 
79     bool NodeIsInCardWhiteList(RSRenderNode& node);
GetCurrentFrameSkipFirstWait()80     bool GetCurrentFrameSkipFirstWait() const
81     {
82         return currentFrameCanSkipFirstWait_.load();
83     }
84     bool CheckIfAppWindowHasAnimation(RSSurfaceRenderNode& node);
85     void DisableUifirstNode(RSSurfaceRenderNode& node);
86     static void ProcessTreeStateChange(RSSurfaceRenderNode& node);
87 
GetUiFirstSwitch()88     bool GetUiFirstSwitch() const
89     {
90         return isUiFirstOn_;
91     }
92 
SetUiFirstSwitch(bool uiFirstSwitch)93     void SetUiFirstSwitch(bool uiFirstSwitch)
94     {
95         isUiFirstOn_ = uiFirstSwitch;
96     }
97 
SetCardUiFirstSwitch(bool cardUiFirstSwitch)98     void SetCardUiFirstSwitch(bool cardUiFirstSwitch)
99     {
100         isCardUiFirstOn_ = cardUiFirstSwitch;
101     }
102 
GetUiFirstType()103     UiFirstCcmType GetUiFirstType() const
104     {
105         return uifirstType_;
106     }
107 
108     void SetUiFirstType(int type);
109 
SetPurgeEnable(bool purgeEnable)110     void SetPurgeEnable(bool purgeEnable)
111     {
112         purgeEnable_ = purgeEnable;
113     }
114 
SetNodeNeedForceUpdateFlag(bool flag)115     void SetNodeNeedForceUpdateFlag(bool flag)
116     {
117         hasForceUpdateNode_ = flag;
118     }
119 
HasForceUpdateNode()120     bool HasForceUpdateNode()
121     {
122         return hasForceUpdateNode_;
123     }
124 
125     void MergeOldDirty(NodeId id);
126     void MergeOldDirtyToDirtyManager(std::shared_ptr<RSSurfaceRenderNode>& node);
127 
SetRotationChanged(bool rotationChanged)128     void SetRotationChanged(bool rotationChanged)
129     {
130         rotationChanged_ = rotationChanged;
131     }
132 
IsRecentTaskScene()133     bool IsRecentTaskScene() const
134     {
135         return isRecentTaskScene_.load();
136     }
137 
138     void AddCapturedNodes(NodeId id);
139 
AddCardNodes(NodeId id,MultiThreadCacheType currentFrameCacheType)140     void AddCardNodes(NodeId id, MultiThreadCacheType currentFrameCacheType)
141     {
142         if (currentFrameCacheType != MultiThreadCacheType::ARKTS_CARD) {
143             return;
144         }
145         collectedCardNodes_.insert(id);
146     }
147 
RemoveCardNodes(NodeId id)148     void RemoveCardNodes(NodeId id)
149     {
150         if (!collectedCardNodes_.count(id)) {
151             return;
152         }
153         collectedCardNodes_.erase(id);
154     }
155 
GetPendingPostNodes()156     std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> GetPendingPostNodes()
157     {
158         return pendingPostNodes_;
159     }
160 
161     void PostReleaseCacheSurfaceSubTasks();
162     void PostReleaseCacheSurfaceSubTask(NodeId id);
163     void TryReleaseTextureForIdleThread();
164 
SetFreeMultiWindowStatus(bool enable)165     void SetFreeMultiWindowStatus(bool enable)
166     {
167         isFreeMultiWindowEnabled_ = enable;
168     }
169     UiFirstModeType GetUiFirstMode();
170     void ReadUIFirstCcmParam();
171     // only use in mainThread & RT onsync
UifirstCurStateClear()172     inline void UifirstCurStateClear()
173     {
174         uifirstCacheState_.clear();
175     }
176 
177     bool IsSubTreeNeedPrepareForSnapshot(RSSurfaceRenderNode& node);
178     bool IsSubHighPriorityType(RSSurfaceRenderNode& node) const;
179     void CheckHwcChildrenType(RSSurfaceRenderNode& node, SurfaceHwcNodeType& enabledType);
180     void MarkSubHighPriorityType(RSSurfaceRenderNode& node);
181 private:
182     RSUifirstManager() = default;
183     ~RSUifirstManager() = default;
184     RSUifirstManager(const RSUifirstManager&);
185     RSUifirstManager(const RSUifirstManager&&);
186     RSUifirstManager& operator=(const RSUifirstManager&);
187     RSUifirstManager& operator=(const RSUifirstManager&&);
188 
189     void PostSubTask(NodeId id);
190     void UpdateCompletedSurface(NodeId id);
191 
192     std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> GetSurfaceDrawableByID(NodeId id);
193     bool SetUifirstNodeEnableParam(RSSurfaceRenderNode& node, MultiThreadCacheType type);
194     void RenderGroupUpdate(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable);
195     bool IsInLeashWindowTree(RSSurfaceRenderNode& node, NodeId instanceRootId);
196 
197     void ProcessResetNode();
198     void ProcessSkippedNode();
199     void ProcessDoneNode();
200     void ProcessDoneNodeInner();
201     void UpdateSkipSyncNode();
202     void RestoreSkipSyncNode();
203     void ClearSubthreadRes();
204     void ResetUifirstNode(std::shared_ptr<RSSurfaceRenderNode>& nodePtr);
205     bool CheckVisibleDirtyRegionIsEmpty(const std::shared_ptr<RSSurfaceRenderNode>& node);
206     bool CurSurfaceHasVisibleDirtyRegion(const std::shared_ptr<RSSurfaceRenderNode>& node);
207     void DoPurgePendingPostNodes(std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>& pendingNode);
208     void PurgePendingPostNodes();
209     void SetNodePriorty(std::list<NodeId>& result,
210         std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>& pendingNode);
211     void SortSubThreadNodesPriority();
212     static bool IsArkTsCardCache(RSSurfaceRenderNode& node, bool animation);
213     static bool IsLeashWindowCache(RSSurfaceRenderNode& node, bool animation);
214     void SyncHDRDisplayParam(std::shared_ptr<DrawableV2::RSSurfaceRenderNodeDrawable> drawable,
215         const GraphicColorGamut& colorGamut);
216     static bool IsNonFocusWindowCache(RSSurfaceRenderNode& node, bool animation);
217 
218     void UifirstStateChange(RSSurfaceRenderNode& node, MultiThreadCacheType currentFrameCacheType);
219     NodeId LeashWindowContainMainWindowAndStarting(RSSurfaceRenderNode& node);
220     void NotifyUIStartingWindow(NodeId id, bool wait);
221     void UpdateChildrenDirtyRect(RSSurfaceRenderNode& node);
222     bool EventsCanSkipFirstWait(std::vector<EventInfo>& events);
223     bool IsCardSkipFirstWaitScene(std::string& scene, int32_t appPid);
224     void EventDisableLeashWindowCache(NodeId id, EventInfo& info);
225     void ConvertPendingNodeToDrawable();
226     void CheckCurrentFrameHasCardNodeReCreate(const RSSurfaceRenderNode& node);
227     void ResetCurrentFrameDeletedCardNodes();
228     bool IsPreFirstLevelNodeDoingAndTryClear(std::shared_ptr<RSRenderNode> node);
229     SkipSyncState CollectSkipSyncNodeWithDrawableState(const std::shared_ptr<RSRenderNode> &node);
230     CacheProcessStatus& GetUifirstCachedState(NodeId id);
231     bool IsVMSurfaceName(std::string surfaceName);
232 
233     bool IsToSubByAppAnimation() const;
234     bool QuerySubAssignable(RSSurfaceRenderNode& node, bool isRotation);
235     bool GetSubNodeIsTransparent(RSSurfaceRenderNode& node, std::string& dfxMsg);
236 
237     bool rotationChanged_ = false;
238     bool isUiFirstOn_ = false;
239     bool purgeEnable_ = false;
240     bool isCardUiFirstOn_ = false;
241     UiFirstCcmType uifirstType_ = UiFirstCcmType::SINGLE;
242     bool hasForceUpdateNode_ = false;
243     bool isFreeMultiWindowEnabled_ = false;
244     std::atomic<bool> currentFrameCanSkipFirstWait_ = false;
245     // for recents scene
246     std::atomic<bool> isRecentTaskScene_ = false;
247     std::atomic<bool> isCurrentFrameHasCardNodeReCreate_ = false;
248     static constexpr int CLEAR_RES_THRESHOLD = 3; // 3 frames  to clear resource
249     int32_t scbPid_ = 0;
250     std::atomic<int> noUifirstNodeFrameCount_ = 0;
251     NodeId entryViewNodeId_ = INVALID_NODEID; // desktop surfaceNode ID
252     NodeId negativeScreenNodeId_ = INVALID_NODEID; // negativeScreen surfaceNode ID
253     RSMainThread* mainThread_ = nullptr;
254     // only use in mainThread & RT onsync
255     std::vector<NodeId> pendingForceUpdateNode_;
256     std::vector<std::shared_ptr<RSRenderNode>> markForceUpdateByUifirst_;
257 
258     std::map<NodeId, CacheProcessStatus> uifirstCacheState_;
259 
260     // only use in RT
261     std::unordered_map<NodeId, std::shared_ptr<DrawableV2::RSRenderNodeDrawableAdapter>> subthreadProcessingNode_;
262     std::set<NodeId> processingNodeSkipSync_;
263     std::set<NodeId> processingNodePartialSync_;
264     std::set<NodeId> processingCardNodeSkipSync_;
265     // (instanceId, vector<needsync_node>)
266     std::unordered_map<NodeId, std::vector<std::shared_ptr<RSRenderNode>>> pendingSyncForSkipBefore_;
267 
268     // use in RT & subThread
269     std::mutex childernDrawableMutex_;
270     std::vector<NodeId> subthreadProcessDoneNode_;
271     std::mutex skippedNodeMutex_;
272     std::unordered_set<NodeId> subthreadProcessSkippedNode_;
273 
274     // pending post node: collect in main, use&clear in RT
275     std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> pendingPostNodes_;
276     std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> pendingPostCardNodes_;
277     std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> pendingResetNodes_;
278     std::list<NodeId> sortedSubThreadNodeIds_;
279     std::vector<std::shared_ptr<RSSurfaceRenderNode>> pindingResetWindowCachedNodes_;
280 
281     std::set<NodeId> reuseNodes_;
282     std::set<NodeId> collectedCardNodes_;
283     // event list
284     std::mutex globalFrameEventMutex_;
285     std::vector<EventInfo> globalFrameEvent_; // <time, data>
286     std::vector<EventInfo> currentFrameEvent_;
287     // scene in scb
288     const std::vector<std::string> cardCanSkipFirstWaitScene_ = {
289         { "INTO_HOME_ANI" }, // unlock to desktop
290         { "FINGERPRINT_UNLOCK_ANI" }, // finger unlock to desktop
291         { "SCREEN_OFF_FINGERPRINT_UNLOCK_ANI" }, // aod finger unlock
292         { "PASSWORD_UNLOCK_ANI" }, // password unlock to desktop
293         { "FACIAL_FLING_UNLOCK_ANI" }, // facial unlock to desktop
294         { "FACIAL_UNLOCK_ANI" }, // facial unlock to desktop
295         { "APP_SWIPER_SCROLL" }, // desktop swipe
296         { "APP_SWIPER_FLING" }, // desktop swipe
297         { "LAUNCHER_SCROLL" }, // desktop swipe
298         { "SCROLL_2_AA" }, // desktop to negativeScreen
299     };
300     const std::vector<std::string> toSubByAppAnimation_ = {
301         { "WINDOW_TITLE_BAR_MINIMIZED" },
302         { "LAUNCHER_APP_LAUNCH_FROM_DOCK" },
303     };
304 
305     const std::vector<std::string> vmAppNameSet_ = {
306         { "ohvm" },
307         { "win_emulator" },
308         { "hongyunvd" },
309         { "ecoengine" },
310     };
311 
312     std::vector<NodeId> capturedNodes_;
313     std::vector<NodeId> currentFrameDeletedCardNodes_;
314 };
315 class RSB_EXPORT RSUiFirstProcessStateCheckerHelper {
316 public:
RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId,NodeId curUifirstRootNodeId,NodeId curNodeId)317     RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId, NodeId curUifirstRootNodeId, NodeId curNodeId)
318     {
319         isCurUifirstRootNodeId_ = curNodeId == curUifirstRootNodeId;
320         isCurFirsLevelNodeId_ = curNodeId == curFirsLevelNodeId;
321         if (isCurUifirstRootNodeId_) {
322             curUifirstRootNodeId_ = curUifirstRootNodeId;
323         }
324         if (isCurFirsLevelNodeId_) {
325             curFirstLevelNodeId_ = curFirsLevelNodeId;
326         }
327     }
328 
329     // If a subnode is delivered directly
330     // record the firstLevelNodeId in the delivered subnode as the real one.
RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId,NodeId curUifirstRootNodeId)331     RSUiFirstProcessStateCheckerHelper(NodeId curFirsLevelNodeId, NodeId curUifirstRootNodeId)
332     {
333         isCurUifirstRootNodeId_ = true;
334         isCurFirsLevelNodeId_ = true;
335         curUifirstRootNodeId_ = curUifirstRootNodeId;
336         curFirstLevelNodeId_ = curFirsLevelNodeId;
337     }
338 
~RSUiFirstProcessStateCheckerHelper()339     ~RSUiFirstProcessStateCheckerHelper()
340     {
341         if (isCurUifirstRootNodeId_) {
342             curUifirstRootNodeId_ = INVALID_NODEID;
343         }
344         if (isCurFirsLevelNodeId_) {
345             curFirstLevelNodeId_ = INVALID_NODEID;
346         }
347     }
348     // return false when timeout
NotifyAll(std::function<void ()> condChange)349     static inline void NotifyAll(std::function<void()> condChange)
350     {
351         if (LIKELY(condChange)) {
352             std::unique_lock<std::mutex> lock(notifyMutex_);
353             condChange();
354         }
355         notifyCv_.notify_all();
356     }
357     static bool CheckMatchAndWaitNotify(const RSRenderParams& params, bool checkMatch = true);
358 private:
359     static bool IsCurFirstLevelMatch(const RSRenderParams& params);
360     static bool CheckAndWaitPreFirstLevelDrawableNotify(const RSRenderParams& params);
361 
362     static inline std::mutex notifyMutex_;
363     static inline std::condition_variable notifyCv_;
364 
365     static inline thread_local NodeId curUifirstRootNodeId_ = INVALID_NODEID;
366     static inline thread_local NodeId curFirstLevelNodeId_ = INVALID_NODEID;
367 
368     bool isCurUifirstRootNodeId_ = false;
369     bool isCurFirsLevelNodeId_ = false;
370 };
371 }
372 #endif // RS_UIFIRST_MANAGER_H
373