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 FrameNode; 32 33 using TaskThread = uint32_t; 34 constexpr TaskThread PLATFORM_TASK = 0; 35 constexpr TaskThread MAIN_TASK = 1; 36 constexpr TaskThread BACKGROUND_TASK = 1 << 1; 37 constexpr TaskThread UNDEFINED_TASK = 1 << 2; 38 39 class UITask { 40 public: UITask(std::function<void ()> && task)41 explicit UITask(std::function<void()>&& task) : task_(std::move(task)) {} 42 UITask(std::function<void ()> && task,TaskThread taskThread)43 UITask(std::function<void()>&& task, TaskThread taskThread) : task_(std::move(task)), taskThread_(taskThread) {} 44 45 ~UITask() = default; 46 SetTaskThreadType(TaskThread taskThread)47 void SetTaskThreadType(TaskThread taskThread) 48 { 49 taskThread_ = taskThread; 50 } 51 GetTaskThreadType()52 TaskThread GetTaskThreadType() const 53 { 54 return taskThread_; 55 } 56 operator()57 void operator()() const 58 { 59 if (task_) { 60 task_(); 61 } 62 } 63 64 private: 65 std::function<void()> task_; 66 TaskThread taskThread_ = MAIN_TASK; 67 }; 68 69 class ACE_EXPORT UITaskScheduler final { 70 public: 71 using PredictTask = std::function<void(int64_t, bool)>; 72 UITaskScheduler() = default; 73 ~UITaskScheduler(); 74 75 // Called on Main Thread. 76 void AddDirtyLayoutNode(const RefPtr<FrameNode>& dirty); 77 void AddDirtyRenderNode(const RefPtr<FrameNode>& dirty); 78 void AddPredictTask(PredictTask&& task); 79 void AddAfterLayoutTask(std::function<void()>&& task); 80 void AddAfterRenderTask(std::function<void()>&& task); 81 82 void FlushLayoutTask(bool forceUseMainThread = false); 83 void FlushRenderTask(bool forceUseMainThread = false); 84 void FlushTask(); 85 void FlushPredictTask(int64_t deadline, bool canUseLongPredictTask = false); 86 void FlushAfterLayoutTask(); 87 void FlushAfterRenderTask(); 88 UpdateCurrentPageId(uint32_t id)89 void UpdateCurrentPageId(uint32_t id) 90 { 91 currentPageId_ = id; 92 } 93 94 void CleanUp(); 95 96 bool isEmpty(); 97 StartRecordFrameInfo(FrameInfo * info)98 void StartRecordFrameInfo(FrameInfo* info) 99 { 100 frameInfo_ = info; 101 } 102 FinishRecordFrameInfo()103 void FinishRecordFrameInfo() 104 { 105 frameInfo_ = nullptr; 106 } 107 GetFrameId()108 static uint64_t GetFrameId() 109 { 110 return frameId_; 111 } 112 IsLayouting()113 bool IsLayouting() const 114 { 115 return isLayouting_; 116 } 117 118 private: 119 bool NeedAdditionalLayout(); 120 121 template<typename T> 122 struct NodeCompare { operatorNodeCompare123 bool operator()(const T& nodeLeft, const T& nodeRight) const 124 { 125 if (!nodeLeft || !nodeRight) { 126 return false; 127 } 128 if (nodeLeft->GetLayoutPriority() != nodeRight->GetLayoutPriority()) { 129 return nodeLeft->GetLayoutPriority() > nodeRight->GetLayoutPriority(); 130 } 131 if (nodeLeft->GetPageId() != nodeRight->GetPageId()) { 132 return nodeLeft->GetPageId() < nodeRight->GetPageId(); 133 } 134 if (nodeLeft->GetDepth() != nodeRight->GetDepth()) { 135 return nodeLeft->GetDepth() < nodeRight->GetDepth(); 136 } 137 return nodeLeft < nodeRight; 138 } 139 }; 140 141 using PageDirtySet = std::set<RefPtr<FrameNode>, NodeCompare<RefPtr<FrameNode>>>; 142 using RootDirtyMap = std::map<uint32_t, PageDirtySet>; 143 144 std::list<RefPtr<FrameNode>> dirtyLayoutNodes_; 145 RootDirtyMap dirtyRenderNodes_; 146 std::list<PredictTask> predictTask_; 147 std::list<std::function<void()>> afterLayoutTasks_; 148 std::list<std::function<void()>> afterRenderTasks_; 149 150 uint32_t currentPageId_ = 0; 151 bool isLayouting_ = false; 152 153 FrameInfo* frameInfo_ = nullptr; 154 155 static uint64_t frameId_; 156 157 ACE_DISALLOW_COPY_AND_MOVE(UITaskScheduler); 158 }; 159 160 } // namespace OHOS::Ace::NG 161 162 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_PIPELINE_NG_UI_TASK_SCHEDULER_H 163