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