• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_PIPELINE_NG_UI_TASK_SCHEDULER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_PIPELINE_NG_UI_TASK_SCHEDULER_H
18 
19 #include <cstdint>
20 #include <functional>
21 #include <list>
22 #include <map>
23 #include <queue>
24 #include <set>
25 
26 #include "base/log/frame_info.h"
27 #include "base/memory/referenced.h"
28 #include "base/utils/macros.h"
29 #include "core/common/ace_application_info.h"
30 
31 namespace OHOS::Ace::NG {
32 
33 class CustomNode;
34 class FrameNode;
35 
36 using TaskThread = uint32_t;
37 constexpr TaskThread PLATFORM_TASK = 0;
38 constexpr TaskThread MAIN_TASK = 1;
39 constexpr TaskThread BACKGROUND_TASK = 1 << 1;
40 constexpr TaskThread UNDEFINED_TASK = 1 << 2;
41 
42 class UITask {
43 public:
UITask(std::function<void ()> && task)44     explicit UITask(std::function<void()>&& task) : task_(std::move(task)) {}
45 
UITask(std::function<void ()> && task,TaskThread taskThread)46     UITask(std::function<void()>&& task, TaskThread taskThread) : task_(std::move(task)), taskThread_(taskThread) {}
47 
48     ~UITask() = default;
49 
SetTaskThreadType(TaskThread taskThread)50     void SetTaskThreadType(TaskThread taskThread)
51     {
52         taskThread_ = taskThread;
53     }
54 
GetTaskThreadType()55     TaskThread GetTaskThreadType() const
56     {
57         return taskThread_;
58     }
59 
operator()60     void operator()() const
61     {
62         if (task_) {
63             task_();
64         }
65     }
66 
67 private:
68     std::function<void()> task_;
69     TaskThread taskThread_ = MAIN_TASK;
70 };
71 
72 class ACE_EXPORT UITaskScheduler final {
73 public:
74     using PredictTask = std::function<void(int64_t, bool)>;
75     UITaskScheduler();
76     ~UITaskScheduler();
77 
78     // Called on Main Thread.
79     void AddDirtyLayoutNode(const RefPtr<FrameNode>& dirty);
80     void AddLayoutNode(const RefPtr<FrameNode>& layoutNode);
81     void AddDirtyRenderNode(const RefPtr<FrameNode>& dirty);
82     void AddPredictTask(PredictTask&& task);
83     void AddAfterLayoutTask(std::function<void()>&& task, bool isFlushInImplicitAnimationTask = false);
84     void AddAfterRenderTask(std::function<void()>&& task);
85     void AddPersistAfterLayoutTask(std::function<void()>&& task);
86 
87     void FlushLayoutTask(bool forceUseMainThread = false);
88     void FlushRenderTask(bool forceUseMainThread = false);
89     void FlushTask();
90     void FlushTaskWithCheck(bool triggeredByImplicitAnimation = false);
91     void FlushPredictTask(int64_t deadline, bool canUseLongPredictTask = false);
92     void FlushAfterLayoutTask();
93     void FlushAfterLayoutCallbackInImplicitAnimationTask();
94     void FlushAfterRenderTask();
95     void FlushPersistAfterLayoutTask();
96     void ExpandSafeArea();
97 
98     void FlushDelayJsActive();
99 
UpdateCurrentPageId(uint32_t id)100     void UpdateCurrentPageId(uint32_t id)
101     {
102         currentPageId_ = id;
103     }
104 
105     void CleanUp();
106 
107     bool isEmpty();
108 
109     bool IsPredictTaskEmpty();
110 
StartRecordFrameInfo(FrameInfo * info)111     void StartRecordFrameInfo(FrameInfo* info)
112     {
113         frameInfo_ = info;
114     }
115 
FinishRecordFrameInfo()116     void FinishRecordFrameInfo()
117     {
118         frameInfo_ = nullptr;
119     }
120 
GetFrameId()121     static uint64_t GetFrameId()
122     {
123         return frameId_;
124     }
125 
IsLayouting()126     bool IsLayouting() const
127     {
128         return isLayouting_;
129     }
130 
131     void AddSingleNodeToFlush(const RefPtr<FrameNode>& dirtyNode);
132 
133     bool RequestFrameOnLayoutCountExceeds();
134 
135     void SetJSViewActive(bool active, WeakPtr<CustomNode> custom);
136 
IsDirtyLayoutNodesEmpty()137     bool IsDirtyLayoutNodesEmpty()
138     {
139         return dirtyLayoutNodes_.empty();
140     }
141 
AddSyncGeometryNodeTask(std::function<void ()> && task)142     void AddSyncGeometryNodeTask(std::function<void()>&& task)
143     {
144         syncGeometryNodeTasks_.emplace_back(task);
145     }
146 
147     void AddSafeAreaPaddingProcessTask(FrameNode* node);
148     void RemoveSafeAreaPaddingProcessTask(FrameNode* node);
149     void FlushSafeAreaPaddingProcess();
150 
SetIsLayouting(bool layouting)151     void SetIsLayouting(bool layouting)
152     {
153         isLayouting_ = layouting;
154     }
155 
156     void FlushSyncGeometryNodeTasks();
157 
158 private:
159     bool NeedAdditionalLayout();
160     void FlushAllSingleNodeTasks();
161     void SetLayoutNodeRect();
162 
163     template<typename T>
164     struct NodeCompare {
operatorNodeCompare165         bool operator()(const T& nodeLeft, const T& nodeRight) const
166         {
167             if (!nodeLeft || !nodeRight) {
168                 return false;
169             }
170             if (nodeLeft->GetLayoutPriority() != nodeRight->GetLayoutPriority()) {
171                 return nodeLeft->GetLayoutPriority() > nodeRight->GetLayoutPriority();
172             }
173             if (nodeLeft->GetPageId() != nodeRight->GetPageId()) {
174                 return nodeLeft->GetPageId() < nodeRight->GetPageId();
175             }
176             if (nodeLeft->GetDepth() != nodeRight->GetDepth()) {
177                 return nodeLeft->GetDepth() < nodeRight->GetDepth();
178             }
179             return nodeLeft < nodeRight;
180         }
181     };
182 
183     using PageDirtySet = std::set<RefPtr<FrameNode>, NodeCompare<RefPtr<FrameNode>>>;
184     using LayoutNodesSet = std::set<RefPtr<FrameNode>, NodeCompare<RefPtr<FrameNode>>>;
185     using RootDirtyMap = std::map<uint32_t, PageDirtySet>;
186 
187     std::list<RefPtr<FrameNode>> dirtyLayoutNodes_;
188     std::list<RefPtr<FrameNode>> layoutNodes_;
189     RootDirtyMap dirtyRenderNodes_;
190     std::list<PredictTask> predictTask_;
191     std::list<std::function<void()>> afterLayoutTasks_;
192     std::list<std::function<void()>> afterLayoutCallbacksInImplicitAnimationTask_;
193     std::list<std::function<void()>> afterRenderTasks_;
194     std::list<std::function<void()>> persistAfterLayoutTasks_;
195     std::list<std::function<void()>> syncGeometryNodeTasks_;
196     std::set<FrameNode*, NodeCompare<FrameNode*>> safeAreaPaddingProcessTasks_;
197     std::set<RefPtr<FrameNode>> singleDirtyNodesToFlush_;
198     std::queue<bool> layoutWithImplicitAnimation_;
199 
200     uint32_t currentPageId_ = 0;
201     bool is64BitSystem_ = false;
202     bool isLayouting_ = false;
203     int32_t multiLayoutCount_ = 0;
204 
205     FrameInfo* frameInfo_ = nullptr;
206 
207     static uint64_t frameId_;
208 
209     ACE_DISALLOW_COPY_AND_MOVE(UITaskScheduler);
210 };
211 
212 } // namespace OHOS::Ace::NG
213 
214 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_PIPELINE_NG_UI_TASK_SCHEDULER_H
215