• 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 #include "core/pipeline_ng/ui_task_scheduler.h"
17 
18 #include "base/log/frame_report.h"
19 #include "base/memory/referenced.h"
20 #include "base/thread/background_task_executor.h"
21 #include "base/thread/cancelable_callback.h"
22 #include "base/utils/utils.h"
23 #include "core/common/thread_checker.h"
24 #include "core/components_ng/base/frame_node.h"
25 
26 namespace OHOS::Ace::NG {
27 
28 UITaskScheduler::~UITaskScheduler() = default;
29 
AddDirtyLayoutNode(const RefPtr<FrameNode> & dirty)30 void UITaskScheduler::AddDirtyLayoutNode(const RefPtr<FrameNode>& dirty)
31 {
32     CHECK_RUN_ON(UI);
33     CHECK_NULL_VOID(dirty);
34     dirtyLayoutNodes_[dirty->GetPageId()].emplace(dirty);
35 }
36 
AddDirtyRenderNode(const RefPtr<FrameNode> & dirty)37 void UITaskScheduler::AddDirtyRenderNode(const RefPtr<FrameNode>& dirty)
38 {
39     CHECK_RUN_ON(UI);
40     CHECK_NULL_VOID(dirty);
41     auto result = dirtyRenderNodes_[dirty->GetPageId()].emplace(dirty);
42     if (!result.second) {
43         LOGW("fail to emplace %{public}s render node", dirty->GetTag().c_str());
44     }
45 }
46 
FlushLayoutTask(bool forceUseMainThread)47 void UITaskScheduler::FlushLayoutTask(bool forceUseMainThread)
48 {
49     CHECK_RUN_ON(UI);
50     ACE_FUNCTION_TRACE();
51     if (FrameReport::GetInstance().GetEnable()) {
52         FrameReport::GetInstance().BeginFlushRender();
53     }
54     auto dirtyLayoutNodes = std::move(dirtyLayoutNodes_);
55     // Priority task creation
56     for (auto&& pageNodes : dirtyLayoutNodes) {
57         for (auto&& node : pageNodes.second) {
58             if (!node) {
59                 continue;
60             }
61             if (node->IsInDestroying()) {
62                 continue;
63             }
64             auto task = node->CreateLayoutTask(forceUseMainThread);
65             if (task) {
66                 if (forceUseMainThread || (task->GetTaskThreadType() == MAIN_TASK)) {
67                     (*task)();
68                 } else {
69                     LOGW("need to use multithread feature");
70                 }
71             }
72         }
73     }
74 }
75 
FlushRenderTask(bool forceUseMainThread)76 void UITaskScheduler::FlushRenderTask(bool forceUseMainThread)
77 {
78     CHECK_RUN_ON(UI);
79     ACE_FUNCTION_TRACE();
80     if (FrameReport::GetInstance().GetEnable()) {
81         FrameReport::GetInstance().BeginFlushRender();
82     }
83     auto dirtyRenderNodes = std::move(dirtyRenderNodes_);
84     // Priority task creation
85     for (auto&& pageNodes : dirtyRenderNodes) {
86         for (auto&& node : pageNodes.second) {
87             if (!node) {
88                 continue;
89             }
90             if (node->IsInDestroying()) {
91                 continue;
92             }
93             auto task = node->CreateRenderTask(forceUseMainThread);
94             if (task) {
95                 if (forceUseMainThread || (task->GetTaskThreadType() == MAIN_TASK)) {
96                     (*task)();
97                 } else {
98                     LOGW("need to use multithread feature");
99                 }
100             }
101         }
102     }
103 }
104 
FlushTask()105 void UITaskScheduler::FlushTask()
106 {
107     CHECK_RUN_ON(UI);
108     ACE_SCOPED_TRACE("UITaskScheduler::FlushTask");
109     FlushLayoutTask();
110     if (!afterLayoutTasks_.empty()) {
111         FlushAfterLayoutTask();
112     }
113     FlushRenderTask();
114 }
115 
AddPredictTask(PredictTask && task)116 void UITaskScheduler::AddPredictTask(PredictTask&& task)
117 {
118     predictTask_.push_back(std::move(task));
119 }
120 
FlushPredictTask(int64_t deadline)121 void UITaskScheduler::FlushPredictTask(int64_t deadline)
122 {
123     decltype(predictTask_) tasks(std::move(predictTask_));
124     for (const auto& task : tasks) {
125         if (task) {
126             task(deadline);
127         }
128     }
129 }
130 
CleanUp()131 void UITaskScheduler::CleanUp()
132 {
133     dirtyLayoutNodes_.clear();
134     dirtyRenderNodes_.clear();
135 }
136 
isEmpty()137 bool UITaskScheduler::isEmpty()
138 {
139     if (dirtyLayoutNodes_.empty() && dirtyRenderNodes_.empty()) {
140         return true;
141     }
142     return false;
143 }
144 
AddAfterLayoutTask(std::function<void ()> && task)145 void UITaskScheduler::AddAfterLayoutTask(std::function<void()>&& task)
146 {
147     afterLayoutTasks_.emplace_back(std::move(task));
148 }
149 
FlushAfterLayoutTask()150 void UITaskScheduler::FlushAfterLayoutTask()
151 {
152     decltype(afterLayoutTasks_) tasks(std::move(afterLayoutTasks_));
153     for (const auto& task : tasks) {
154         if (task) {
155             task();
156         }
157     }
158 }
159 
160 } // namespace OHOS::Ace::NG
161