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