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