• 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 "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