1 /*
2 * Copyright (c) 2021-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_render_service.h"
17 #include "rs_main_thread.h"
18 #include "rs_qos_thread.h"
19 #include "rs_render_service_connection.h"
20 #include "vsync_generator.h"
21 #include "pipeline/rs_surface_render_node.h"
22 #include "pipeline/rs_uni_render_judgement.h"
23
24 #include <string>
25 #include <unistd.h>
26
27 #include <iservice_registry.h>
28 #include <platform/common/rs_log.h>
29 #include <system_ability_definition.h>
30 #include "parameter.h"
31
32 namespace OHOS {
33 namespace Rosen {
34 namespace {
35 constexpr uint32_t UNI_RENDER_VSYNC_OFFSET = 10000000;
36 }
RSRenderService()37 RSRenderService::RSRenderService() {}
38
~RSRenderService()39 RSRenderService::~RSRenderService() noexcept {}
40
Init()41 bool RSRenderService::Init()
42 {
43 RSUniRenderJudgement::InitUniRenderConfig();
44 screenManager_ = CreateOrGetScreenManager();
45 if (screenManager_ == nullptr || !screenManager_->Init()) {
46 RS_LOGE("RSRenderService CreateOrGetScreenManager fail.");
47 return false;
48 }
49
50 auto generator = CreateVSyncGenerator();
51
52 // The offset needs to be set
53 int64_t offset = 0;
54 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
55 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL ||
56 renderType == UniRenderEnabledType::UNI_RENDER_DYNAMIC_SWITCH) {
57 offset = UNI_RENDER_VSYNC_OFFSET;
58 }
59 rsVSyncController_ = new VSyncController(generator, offset);
60 appVSyncController_ = new VSyncController(generator, offset);
61 rsVSyncDistributor_ = new VSyncDistributor(rsVSyncController_, "rs");
62 appVSyncDistributor_ = new VSyncDistributor(appVSyncController_, "app");
63
64 mainThread_ = RSMainThread::Instance();
65 if (mainThread_ == nullptr) {
66 return false;
67 }
68 mainThread_->rsVSyncDistributor_ = rsVSyncDistributor_;
69 mainThread_->Init();
70
71 RSQosThread::GetInstance()->appVSyncDistributor_ = appVSyncDistributor_;
72 RSQosThread::ThreadStart();
73
74 // Wait samgr ready for up to 5 second to ensure adding service to samgr.
75 int status = WaitParameter("bootevent.samgr.ready", "true", 5);
76 if (status != 0) {
77 RS_LOGE("RSRenderService wait SAMGR error, return value [%d].", status);
78 }
79
80 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
81 if (samgr == nullptr) {
82 RS_LOGE("RSRenderService GetSystemAbilityManager fail.");
83 return false;
84 }
85 samgr->AddSystemAbility(RENDER_SERVICE, this);
86
87 return true;
88 }
89
Run()90 void RSRenderService::Run()
91 {
92 RS_LOGE("RSRenderService::Run");
93 mainThread_->Start();
94 }
95
CreateConnection(const sptr<RSIConnectionToken> & token)96 sptr<RSIRenderServiceConnection> RSRenderService::CreateConnection(const sptr<RSIConnectionToken>& token)
97 {
98 pid_t remotePid = GetCallingPid();
99
100 auto tokenObj = token->AsObject();
101 sptr<RSIRenderServiceConnection> newConn(
102 new RSRenderServiceConnection(remotePid, this, mainThread_, screenManager_, tokenObj, appVSyncDistributor_));
103
104 sptr<RSIRenderServiceConnection> tmp;
105 std::unique_lock<std::mutex> lock(mutex_);
106 // if connections_ has the same token one, replace it.
107 if (connections_.count(tokenObj) > 0) {
108 tmp = connections_.at(tokenObj);
109 }
110 connections_[tokenObj] = newConn;
111 lock.unlock();
112 mainThread_->AddTransactionDataPidInfo(remotePid);
113 return newConn;
114 }
115
RemoveConnection(sptr<IRemoteObject> token)116 void RSRenderService::RemoveConnection(sptr<IRemoteObject> token)
117 {
118 std::unique_lock<std::mutex> lock(mutex_);
119 if (connections_.count(token) == 0) {
120 return;
121 }
122
123 auto tmp = connections_.at(token);
124 connections_.erase(token);
125 lock.unlock();
126 }
127
Dump(int fd,const std::vector<std::u16string> & args)128 int RSRenderService::Dump(int fd, const std::vector<std::u16string>& args)
129 {
130 std::unordered_set<std::u16string> argSets;
131 for (decltype(args.size()) index = 0; index < args.size(); ++index) {
132 argSets.insert(args[index]);
133 }
134 if (screenManager_ == nullptr) {
135 return OHOS::INVALID_OPERATION;
136 }
137 std::string dumpString;
138 DoDump(argSets, dumpString);
139 if (dumpString.size() == 0) {
140 return OHOS::INVALID_OPERATION;
141 }
142 write(fd, dumpString.c_str(), dumpString.size());
143 return OHOS::NO_ERROR;
144 }
145
DumpNodesNotOnTheTree(std::string & dumpString) const146 void RSRenderService::DumpNodesNotOnTheTree(std::string& dumpString) const
147 {
148 dumpString.append("\n");
149 dumpString.append("-- Node Not On Tree\n");
150
151 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
152 nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
153 if (node == nullptr) {
154 return;
155 }
156
157 if (node->IsInstanceOf<RSSurfaceRenderNode>() && !node->IsOnTheTree()) {
158 const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
159 dumpString += "\n node Id[" + std::to_string(node->GetId()) + "]:\n";
160 const auto& surfaceConsumer = surfaceNode->GetConsumer();
161 if (surfaceConsumer == nullptr) {
162 return;
163 }
164 surfaceConsumer->Dump(dumpString);
165 }
166 });
167 }
168
DumpAllNodesMemSize(std::string & dumpString) const169 void RSRenderService::DumpAllNodesMemSize(std::string& dumpString) const
170 {
171 dumpString.append("\n");
172 dumpString.append("-- All Surfaces Memory Size\n");
173 dumpString.append("the memory size of all surfaces buffer is : dumpend");
174
175 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
176 nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
177 if (node == nullptr || !node->IsInstanceOf<RSSurfaceRenderNode>()) {
178 return;
179 }
180
181 const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
182 const auto& surfaceConsumer = surfaceNode->GetConsumer();
183 if (surfaceConsumer == nullptr) {
184 return;
185 }
186
187 surfaceConsumer->Dump(dumpString);
188 });
189 }
190
DumpHelpInfo(std::string & dumpString) const191 void RSRenderService::DumpHelpInfo(std::string& dumpString) const
192 {
193 dumpString.append("------Graphic2D--RenderSerice ------\n")
194 .append("Usage:\n")
195 .append(" h ")
196 .append("|help text for the tool\n")
197 .append("screen ")
198 .append("|dump all screen infomation in the system\n")
199 .append("surface ")
200 .append("|dump all surface information\n")
201 .append("composer fps ")
202 .append("|dump the fps info of composer\n")
203 .append("[surface name] fps ")
204 .append("|dump the fps info of surface\n")
205 .append("composer fpsClear ")
206 .append("|clear the fps info of composer\n")
207 .append("[surface name] fpsClear ")
208 .append("|clear the fps info of surface\n")
209 .append("nodeNotOnTree ")
210 .append("|dump nodeNotOnTree info\n")
211 .append("allSurfacesMem ")
212 .append("|dump surface mem info\n")
213 .append("RSTree ")
214 .append("|dump RSTree info\n")
215 .append("EventParamList ")
216 .append("|dump EventParamList info\n")
217 .append("allInfo ")
218 .append("|dump all info\n");
219 }
220
FPSDUMPProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const221 void RSRenderService::FPSDUMPProcess(std::unordered_set<std::u16string>& argSets,
222 std::string& dumpString, const std::u16string& arg) const
223 {
224 auto iter = argSets.find(arg);
225 if (iter != argSets.end()) {
226 std::string layerArg;
227 argSets.erase(iter);
228 if (!argSets.empty()) {
229 layerArg = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
230 }
231 mainThread_->ScheduleTask([this, &dumpString, &layerArg]() {
232 return screenManager_->FpsDump(dumpString, layerArg);
233 }).wait();
234 }
235 }
236
FPSDUMPClearProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const237 void RSRenderService::FPSDUMPClearProcess(std::unordered_set<std::u16string>& argSets,
238 std::string& dumpString, const std::u16string& arg) const
239 {
240 auto iter = argSets.find(arg);
241 if (iter != argSets.end()) {
242 std::string layerArg;
243 argSets.erase(iter);
244 if (!argSets.empty()) {
245 layerArg = std::wstring_convert<
246 std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
247 }
248 mainThread_->ScheduleTask([this, &dumpString, &layerArg]() {
249 return screenManager_->ClearFpsDump(dumpString, layerArg);
250 }).wait();
251 }
252 }
253
DumpRSEvenParam(std::string & dumpString) const254 void RSRenderService::DumpRSEvenParam(std::string& dumpString) const
255 {
256 dumpString.append("\n");
257 dumpString.append("-- EventParamListDump: \n");
258 mainThread_->RsEventParamDump(dumpString);
259 dumpString.append("-- QosDump: \n");
260 mainThread_->QosStateDump(dumpString);
261 }
262
DumpRenderServiceTree(std::string & dumpString) const263 void RSRenderService::DumpRenderServiceTree(std::string& dumpString) const
264 {
265 dumpString.append("\n");
266 dumpString.append("-- RenderServiceTreeDump: \n");
267 mainThread_->RenderServiceTreeDump(dumpString);
268 }
269
DoDump(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const270 void RSRenderService::DoDump(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
271 {
272 std::u16string arg1(u"screen");
273 std::u16string arg2(u"surface");
274 std::u16string arg3(u"fps");
275 std::u16string arg4(u"nodeNotOnTree");
276 std::u16string arg5(u"allSurfacesMem");
277 std::u16string arg6(u"RSTree");
278 std::u16string arg7(u"EventParamList");
279 std::u16string arg8(u"h");
280 std::u16string arg9(u"allInfo");
281 std::u16string arg13(u"fpsClear");
282 if (argSets.count(arg9) || argSets.count(arg1) != 0) {
283 mainThread_->ScheduleTask([this, &dumpString]() {
284 screenManager_->DisplayDump(dumpString);
285 }).wait();
286 }
287 if (argSets.count(arg9) || argSets.count(arg2) != 0) {
288 mainThread_->ScheduleTask([this, &dumpString]() {
289 return screenManager_->SurfaceDump(dumpString);
290 }).wait();
291 }
292 if (argSets.count(arg9) || argSets.count(arg4) != 0) {
293 mainThread_->ScheduleTask([this, &dumpString]() {
294 DumpNodesNotOnTheTree(dumpString);
295 }).wait();
296 }
297 if (argSets.count(arg9) || argSets.count(arg5) != 0) {
298 mainThread_->ScheduleTask([this, &dumpString]() {
299 DumpAllNodesMemSize(dumpString);
300 }).wait();
301 }
302 if (argSets.count(arg9) || argSets.count(arg6) != 0) {
303 mainThread_->ScheduleTask([this, &dumpString]() {
304 DumpRenderServiceTree(dumpString);
305 }).wait();
306 }
307 if (argSets.count(arg9) ||argSets.count(arg7) != 0) {
308 mainThread_->ScheduleTask([this, &dumpString]() {
309 DumpRSEvenParam(dumpString);
310 }).wait();
311 }
312 FPSDUMPProcess(argSets, dumpString, arg3);
313 FPSDUMPClearProcess(argSets, dumpString, arg13);
314 if (argSets.size() == 0 || argSets.count(arg8) != 0 || dumpString.empty()) {
315 mainThread_->ScheduleTask([this, &dumpString]() {
316 DumpHelpInfo(dumpString);
317 }).wait();
318 }
319 }
320 } // namespace Rosen
321 } // namespace OHOS
322