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 "rs_parallel_task_manager.h"
17 #include <memory>
18 #include "rs_parallel_render_manager.h"
19 #include "rs_parallel_render_ext.h"
20 #include "rs_trace.h"
21 #include "platform/common/rs_log.h"
22 #include "rs_node_cost_manager.h"
23
24 namespace OHOS {
25 namespace Rosen {
26
RSParallelTaskManager()27 RSParallelTaskManager::RSParallelTaskManager()
28 : threadNum_(0),
29 taskNum_(0),
30 isParallelRenderExtEnabled_(RSParallelRenderExt::OpenParallelRenderExt())
31 {
32 if (isParallelRenderExtEnabled_ && (RSParallelRenderExt::initParallelRenderLBFunc_ != nullptr)) {
33 auto initParallelRenderExt = reinterpret_cast<int*(*)()>(RSParallelRenderExt::initParallelRenderLBFunc_);
34 loadBalance_ = initParallelRenderExt();
35 if (loadBalance_ == nullptr) {
36 isParallelRenderExtEnabled_ = false;
37 RS_LOGE("init parallel render load balance failed!!!");
38 }
39 } else {
40 RS_LOGE("open graphic 2d extension failed!!!");
41 }
42 }
43
~RSParallelTaskManager()44 RSParallelTaskManager::~RSParallelTaskManager()
45 {
46 if (isParallelRenderExtEnabled_ && (RSParallelRenderExt::freeParallelRenderLBFunc_ != nullptr)) {
47 auto freeParallelRenderExt = reinterpret_cast<void (*)(int*)>(RSParallelRenderExt::freeParallelRenderLBFunc_);
48 if (freeParallelRenderExt) {
49 freeParallelRenderExt(loadBalance_);
50 }
51 }
52 RSParallelRenderExt::CloseParallelRenderExt();
53 }
54
Initialize(uint32_t threadNum)55 void RSParallelTaskManager::Initialize(uint32_t threadNum)
56 {
57 threadNum_ = threadNum;
58 if (isParallelRenderExtEnabled_ && (RSParallelRenderExt::setSubRenderThreadNumFunc_ != nullptr)) {
59 auto parallelRenderExtSetThreadNumCall = reinterpret_cast<void(*)(int*, uint32_t)>(
60 RSParallelRenderExt::setSubRenderThreadNumFunc_);
61 parallelRenderExtSetThreadNumCall(loadBalance_, threadNum);
62 }
63 }
64
PushRenderTask(std::unique_ptr<RSRenderTask> renderTask)65 void RSParallelTaskManager::PushRenderTask(std::unique_ptr<RSRenderTask> renderTask)
66 {
67 if (isParallelRenderExtEnabled_ && (RSParallelRenderExt::addRenderLoadFunc_ != nullptr)) {
68 auto parallelRenderExtAddRenderLoad = reinterpret_cast<void(*)(int*, uint64_t, float)>(
69 RSParallelRenderExt::addRenderLoadFunc_);
70 parallelRenderExtAddRenderLoad(loadBalance_, renderTask->GetIdx(), 0.f);
71 }
72 renderTaskList_.push_back(std::move(renderTask));
73 }
74
PushCompositionTask(std::unique_ptr<RSCompositionTask> compositionTask)75 void RSParallelTaskManager::PushCompositionTask(std::unique_ptr<RSCompositionTask> compositionTask)
76 {
77 compositionTaskList_.push_back(std::move(compositionTask));
78 }
79
LBCalcAndSubmitSuperTask(std::shared_ptr<RSBaseRenderNode> displayNode)80 void RSParallelTaskManager::LBCalcAndSubmitSuperTask(std::shared_ptr<RSBaseRenderNode> displayNode)
81 {
82 if (renderTaskList_.size() == 0) {
83 taskNum_ = 0;
84 return;
85 }
86 std::vector<uint32_t> loadNumPerThread = LoadBalancing();
87 uint32_t index = 0;
88 uint32_t loadNumSum = 0;
89 taskNum_ = 0;
90 cachedSuperRenderTask_ = std::make_unique<RSSuperRenderTask>(displayNode);
91 for (uint32_t i = 0; i < loadNumPerThread.size(); i++) {
92 loadNumSum += loadNumPerThread[i];
93 while (index < loadNumSum) {
94 cachedSuperRenderTask_->AddTask(std::move(renderTaskList_[index]));
95 index++;
96 }
97 RSParallelRenderManager::Instance()->SubmitSuperTask(taskNum_, std::move(cachedSuperRenderTask_));
98 taskNum_++;
99 cachedSuperRenderTask_ = std::make_unique<RSSuperRenderTask>(displayNode);
100 }
101 }
102
LBCalcAndSubmitCompositionTask(std::shared_ptr<RSBaseRenderNode> baseNode)103 void RSParallelTaskManager::LBCalcAndSubmitCompositionTask(std::shared_ptr<RSBaseRenderNode> baseNode)
104 {
105 taskNum_ = 0;
106 for (decltype(compositionTaskList_.size()) i = 0; i < compositionTaskList_.size(); i++) {
107 RSParallelRenderManager::Instance()->SubmitCompositionTask(taskNum_, std::move(compositionTaskList_[i]));
108 taskNum_++;
109 }
110 }
111
LoadBalancing()112 std::vector<uint32_t> RSParallelTaskManager::LoadBalancing()
113 {
114 RS_TRACE_FUNC();
115 if (parallelPolicy_.size() > 0) {
116 return parallelPolicy_;
117 }
118
119 std::vector<uint32_t> loadNumPerThread{};
120 if (isParallelRenderExtEnabled_ && (RSParallelRenderExt::loadBalancingFunc_ != nullptr)) {
121 auto parallelRenderExtLB = reinterpret_cast<void(*)(int*, std::vector<uint32_t> &)>(
122 RSParallelRenderExt::loadBalancingFunc_);
123 parallelRenderExtLB(loadBalance_, loadNumPerThread);
124 } else {
125 if (threadNum_ == 0) {
126 RS_LOGE("RSParallelTaskManager::LoadBalancing threadNum_ == 0");
127 return loadNumPerThread;
128 }
129 uint32_t avgLoadNum = renderTaskList_.size() / threadNum_;
130 uint32_t loadMod = renderTaskList_.size() % threadNum_;
131 for (uint32_t i = threadNum_; i > 0; i--) {
132 if (i <= loadMod) {
133 loadNumPerThread.push_back(avgLoadNum + 1);
134 } else {
135 loadNumPerThread.push_back(avgLoadNum);
136 }
137 }
138 }
139 return loadNumPerThread;
140 }
141
GetTaskNum() const142 uint32_t RSParallelTaskManager::GetTaskNum() const
143 {
144 return taskNum_;
145 }
146
Reset()147 void RSParallelTaskManager::Reset()
148 {
149 taskNum_ = 0;
150 renderTaskList_.clear();
151 superRenderTaskList_.clear();
152 parallelPolicy_.clear();
153 compositionTaskList_.clear();
154 if (isParallelRenderExtEnabled_ && (RSParallelRenderExt::clearRenderLoadFunc_ != nullptr)) {
155 auto parallelRenderExtClearRenderLoad = reinterpret_cast<void(*)(int*)>(
156 RSParallelRenderExt::clearRenderLoadFunc_);
157 parallelRenderExtClearRenderLoad(loadBalance_);
158 }
159 }
160
SetSubThreadRenderTaskLoad(uint32_t threadIdx,uint64_t loadId,float cost)161 void RSParallelTaskManager::SetSubThreadRenderTaskLoad(uint32_t threadIdx, uint64_t loadId, float cost)
162 {
163 if (isParallelRenderExtEnabled_ && (RSParallelRenderExt::updateLoadCostFunc_ != nullptr)) {
164 auto parallelRenderExtUpdateLoadCost = reinterpret_cast<void(*)(int*, uint32_t, uint64_t, float)>(
165 RSParallelRenderExt::updateLoadCostFunc_);
166 parallelRenderExtUpdateLoadCost(loadBalance_, threadIdx, loadId, cost);
167 }
168 }
169
UpdateNodeCost(RSDisplayRenderNode & node,std::vector<uint32_t> & parallelPolicy) const170 void RSParallelTaskManager::UpdateNodeCost(RSDisplayRenderNode& node, std::vector<uint32_t>& parallelPolicy) const
171 {
172 if (!isParallelRenderExtEnabled_ || (RSParallelRenderExt::updateNodeCostFunc_ == nullptr)) {
173 return;
174 }
175 RS_TRACE_NAME("UpdateNodeCost");
176 auto surfaceNodes = node.GetSortedChildren();
177 std::map<uint64_t, int32_t> costs;
178 for (auto it = surfaceNodes.begin(); it != surfaceNodes.end(); ++it) {
179 auto surface = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
180 costs.insert(std::pair<uint64_t, int32_t>(surface->GetId(), surface->GetNodeCost()));
181 }
182 auto updateNodeCost = reinterpret_cast<void(*)(int*, std::map<uint64_t, int32_t> &, std::vector<uint32_t> &)>(
183 RSParallelRenderExt::updateNodeCostFunc_);
184 updateNodeCost(loadBalance_, costs, parallelPolicy);
185 }
186
GetCostFactor(std::map<std::string,int32_t> & costFactor,std::map<int64_t,int32_t> & imageFactor) const187 void RSParallelTaskManager::GetCostFactor(std::map<std::string, int32_t>& costFactor,
188 std::map<int64_t, int32_t>& imageFactor) const
189 {
190 if (!isParallelRenderExtEnabled_ || (RSParallelRenderExt::getCostFactorFunc_ == nullptr)) {
191 return;
192 }
193 auto getCostFactor = reinterpret_cast<void(*)(int*, std::map<std::string, int32_t> &,
194 std::map<int64_t, int32_t> &)>(RSParallelRenderExt::getCostFactorFunc_);
195 getCostFactor(loadBalance_, costFactor, imageFactor);
196 }
197
LoadParallelPolicy(std::vector<uint32_t> & parallelPolicy)198 void RSParallelTaskManager::LoadParallelPolicy(std::vector<uint32_t>& parallelPolicy)
199 {
200 parallelPolicy_.swap(parallelPolicy);
201 }
202 } // namespace Rosen
203 } // namespace OHOS