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