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 #include "pipeline/rs_hardware_thread.h"
24
25 #include <string>
26 #include <unistd.h>
27
28 #include <iservice_registry.h>
29 #include <platform/common/rs_log.h>
30 #include <system_ability_definition.h>
31 #include "parameter.h"
32
33 namespace OHOS {
34 namespace Rosen {
35 namespace {
36 constexpr uint32_t UNI_RENDER_VSYNC_OFFSET = 5000000;
37 }
RSRenderService()38 RSRenderService::RSRenderService() {}
39
~RSRenderService()40 RSRenderService::~RSRenderService() noexcept {}
41
Init()42 bool RSRenderService::Init()
43 {
44 RSMainThread::Instance();
45 RSUniRenderJudgement::InitUniRenderConfig();
46 screenManager_ = CreateOrGetScreenManager();
47 if (RSUniRenderJudgement::GetUniRenderEnabledType() != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
48 // screenManager initializtion executes in RSHHardwareThread under UNI_RENDER mode
49 if (screenManager_ == nullptr || !screenManager_->Init()) {
50 RS_LOGE("RSRenderService CreateOrGetScreenManager fail.");
51 return false;
52 }
53 } else {
54 RSHardwareThread::Instance().Start();
55 }
56
57 auto generator = CreateVSyncGenerator();
58
59 // The offset needs to be set
60 int64_t offset = 0;
61 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
62 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
63 offset = UNI_RENDER_VSYNC_OFFSET;
64 }
65 rsVSyncController_ = new VSyncController(generator, offset);
66 appVSyncController_ = new VSyncController(generator, offset);
67 rsVSyncDistributor_ = new VSyncDistributor(rsVSyncController_, "rs");
68 appVSyncDistributor_ = new VSyncDistributor(appVSyncController_, "app");
69
70 mainThread_ = RSMainThread::Instance();
71 if (mainThread_ == nullptr) {
72 return false;
73 }
74 mainThread_->rsVSyncDistributor_ = rsVSyncDistributor_;
75 mainThread_->Init();
76
77 RSQosThread::GetInstance()->appVSyncDistributor_ = appVSyncDistributor_;
78 RSQosThread::ThreadStart();
79
80 // Wait samgr ready for up to 5 second to ensure adding service to samgr.
81 int status = WaitParameter("bootevent.samgr.ready", "true", 5);
82 if (status != 0) {
83 RS_LOGE("RSRenderService wait SAMGR error, return value [%d].", status);
84 }
85
86 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
87 if (samgr == nullptr) {
88 RS_LOGE("RSRenderService GetSystemAbilityManager fail.");
89 return false;
90 }
91 samgr->AddSystemAbility(RENDER_SERVICE, this);
92
93 return true;
94 }
95
Run()96 void RSRenderService::Run()
97 {
98 RS_LOGE("RSRenderService::Run");
99 mainThread_->Start();
100 }
101
CreateConnection(const sptr<RSIConnectionToken> & token)102 sptr<RSIRenderServiceConnection> RSRenderService::CreateConnection(const sptr<RSIConnectionToken>& token)
103 {
104 pid_t remotePid = GetCallingPid();
105
106 auto tokenObj = token->AsObject();
107 sptr<RSIRenderServiceConnection> newConn(
108 new RSRenderServiceConnection(remotePid, this, mainThread_, screenManager_, tokenObj, appVSyncDistributor_));
109
110 sptr<RSIRenderServiceConnection> tmp;
111 std::unique_lock<std::mutex> lock(mutex_);
112 // if connections_ has the same token one, replace it.
113 if (connections_.count(tokenObj) > 0) {
114 tmp = connections_.at(tokenObj);
115 }
116 connections_[tokenObj] = newConn;
117 lock.unlock();
118 mainThread_->AddTransactionDataPidInfo(remotePid);
119 return newConn;
120 }
121
RemoveConnection(sptr<IRemoteObject> token)122 void RSRenderService::RemoveConnection(sptr<IRemoteObject> token)
123 {
124 std::unique_lock<std::mutex> lock(mutex_);
125 if (connections_.count(token) == 0) {
126 return;
127 }
128
129 auto tmp = connections_.at(token);
130 connections_.erase(token);
131 lock.unlock();
132 }
133
Dump(int fd,const std::vector<std::u16string> & args)134 int RSRenderService::Dump(int fd, const std::vector<std::u16string>& args)
135 {
136 std::unordered_set<std::u16string> argSets;
137 for (decltype(args.size()) index = 0; index < args.size(); ++index) {
138 argSets.insert(args[index]);
139 }
140 if (screenManager_ == nullptr) {
141 return OHOS::INVALID_OPERATION;
142 }
143 std::string dumpString;
144 DoDump(argSets, dumpString);
145 if (dumpString.size() == 0) {
146 return OHOS::INVALID_OPERATION;
147 }
148 write(fd, dumpString.c_str(), dumpString.size());
149 return OHOS::NO_ERROR;
150 }
151
DumpNodesNotOnTheTree(std::string & dumpString) const152 void RSRenderService::DumpNodesNotOnTheTree(std::string& dumpString) const
153 {
154 dumpString.append("\n");
155 dumpString.append("-- Node Not On Tree\n");
156
157 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
158 nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
159 if (node == nullptr) {
160 return;
161 }
162
163 if (node->IsInstanceOf<RSSurfaceRenderNode>() && !node->IsOnTheTree()) {
164 const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
165 dumpString += "\n node Id[" + std::to_string(node->GetId()) + "]:\n";
166 const auto& surfaceConsumer = surfaceNode->GetConsumer();
167 if (surfaceConsumer == nullptr) {
168 return;
169 }
170 surfaceConsumer->Dump(dumpString);
171 }
172 });
173 }
174
DumpAllNodesMemSize(std::string & dumpString) const175 void RSRenderService::DumpAllNodesMemSize(std::string& dumpString) const
176 {
177 dumpString.append("\n");
178 dumpString.append("-- All Surfaces Memory Size\n");
179 dumpString.append("the memory size of all surfaces buffer is : dumpend");
180
181 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
182 nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
183 if (node == nullptr || !node->IsInstanceOf<RSSurfaceRenderNode>()) {
184 return;
185 }
186
187 const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
188 const auto& surfaceConsumer = surfaceNode->GetConsumer();
189 if (surfaceConsumer == nullptr) {
190 return;
191 }
192
193 surfaceConsumer->Dump(dumpString);
194 });
195 }
196
DumpHelpInfo(std::string & dumpString) const197 void RSRenderService::DumpHelpInfo(std::string& dumpString) const
198 {
199 dumpString.append("------Graphic2D--RenderSerice ------\n")
200 .append("Usage:\n")
201 .append(" h ")
202 .append("|help text for the tool\n")
203 .append("screen ")
204 .append("|dump all screen infomation in the system\n")
205 .append("surface ")
206 .append("|dump all surface information\n")
207 .append("composer fps ")
208 .append("|dump the fps info of composer\n")
209 .append("[surface name] fps ")
210 .append("|dump the fps info of surface\n")
211 .append("composer fpsClear ")
212 .append("|clear the fps info of composer\n")
213 .append("[surface name] fpsClear ")
214 .append("|clear the fps info of surface\n")
215 .append("nodeNotOnTree ")
216 .append("|dump nodeNotOnTree info\n")
217 .append("allSurfacesMem ")
218 .append("|dump surface mem info\n")
219 .append("RSTree ")
220 .append("|dump RSTree info\n")
221 .append("EventParamList ")
222 .append("|dump EventParamList info\n")
223 .append("allInfo ")
224 .append("|dump all info\n")
225 .append("dumpMem ")
226 .append("|dump Cache\n")
227 .append("trimMem cpu/gpu/shader ")
228 .append("|release Cache\n")
229 .append("surfacenode [id] ")
230 .append("|dump node info\n");
231 }
232
FPSDUMPProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const233 void RSRenderService::FPSDUMPProcess(std::unordered_set<std::u16string>& argSets,
234 std::string& dumpString, const std::u16string& arg) const
235 {
236 auto iter = argSets.find(arg);
237 if (iter != argSets.end()) {
238 std::string layerArg;
239 argSets.erase(iter);
240 if (!argSets.empty()) {
241 layerArg = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
242 }
243 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
244 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
245 RSHardwareThread::Instance().ScheduleTask(
246 [this, &dumpString, &layerArg]() { return screenManager_->FpsDump(dumpString, layerArg); }).wait();
247 } else {
248 mainThread_->ScheduleTask(
249 [this, &dumpString, &layerArg]() { return screenManager_->FpsDump(dumpString, layerArg); }).wait();
250 }
251 }
252 }
253
FPSDUMPClearProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const254 void RSRenderService::FPSDUMPClearProcess(std::unordered_set<std::u16string>& argSets,
255 std::string& dumpString, const std::u16string& arg) const
256 {
257 auto iter = argSets.find(arg);
258 if (iter != argSets.end()) {
259 std::string layerArg;
260 argSets.erase(iter);
261 if (!argSets.empty()) {
262 layerArg = std::wstring_convert<
263 std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
264 }
265 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
266 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
267 RSHardwareThread::Instance().ScheduleTask(
268 [this, &dumpString, &layerArg]() {
269 return screenManager_->ClearFpsDump(dumpString, layerArg);
270 }).wait();
271 } else {
272 mainThread_->ScheduleTask(
273 [this, &dumpString, &layerArg]() {
274 return screenManager_->ClearFpsDump(dumpString, layerArg);
275 }).wait();
276 }
277 }
278 }
279
DumpRSEvenParam(std::string & dumpString) const280 void RSRenderService::DumpRSEvenParam(std::string& dumpString) const
281 {
282 dumpString.append("\n");
283 dumpString.append("-- EventParamListDump: \n");
284 mainThread_->RsEventParamDump(dumpString);
285 dumpString.append("-- QosDump: \n");
286 mainThread_->QosStateDump(dumpString);
287 }
288
DumpRenderServiceTree(std::string & dumpString) const289 void RSRenderService::DumpRenderServiceTree(std::string& dumpString) const
290 {
291 dumpString.append("\n");
292 dumpString.append("-- RenderServiceTreeDump: \n");
293 mainThread_->RenderServiceTreeDump(dumpString);
294 }
295
DumpSurfaceNode(std::string & dumpString,NodeId id) const296 void RSRenderService::DumpSurfaceNode(std::string& dumpString, NodeId id) const
297 {
298 dumpString.append("\n");
299 dumpString.append("-- SurfaceNode\n");
300
301 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
302 auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
303 if (node == nullptr) {
304 dumpString += std::to_string(id) + " is invalid ID\n";
305 return;
306 }
307 dumpString += "ID: " + std::to_string(node->GetId()) + "\n";
308 dumpString += "Name: " + node->GetName() + "\n";
309 dumpString += "SrcRect: [" + std::to_string(node->GetSrcRect().left_) + "," +
310 std::to_string(node->GetSrcRect().top_) + "," +
311 std::to_string(node->GetSrcRect().width_) + "," +
312 std::to_string(node->GetSrcRect().height_) + "]\n";
313 dumpString += "DstRect: [" + std::to_string(node->GetDstRect().left_) + "," +
314 std::to_string(node->GetDstRect().top_) + "," +
315 std::to_string(node->GetDstRect().width_) + "," +
316 std::to_string(node->GetDstRect().height_) + "]\n";
317 dumpString += "CornerRadius: [" + std::to_string(node->GetRenderProperties().GetCornerRadius().x_) + "," +
318 std::to_string(node->GetRenderProperties().GetCornerRadius().y_) + "," +
319 std::to_string(node->GetRenderProperties().GetCornerRadius().z_) + "," +
320 std::to_string(node->GetRenderProperties().GetCornerRadius().w_) + "]\n";
321 dumpString += "Bounds: [" + std::to_string(node->GetRenderProperties().GetBoundsWidth()) + "," +
322 std::to_string(node->GetRenderProperties().GetBoundsHeight()) + "]\n";
323 if (auto& contextClipRegion = node->contextClipRect_) {
324 #ifndef USE_ROSEN_DRAWING
325 dumpString += "ContextClipRegion: [" + std::to_string(contextClipRegion->width()) + "," +
326 std::to_string(contextClipRegion->height()) + "]\n";
327 #else
328 dumpString += "ContextClipRegion: [" + std::to_string(contextClipRegion->GetWidth()) + "," +
329 std::to_string(contextClipRegion->GetHeight()) + "]\n";
330 #endif
331 } else {
332 dumpString += "ContextClipRegion: [ empty ]\n";
333 }
334 dumpString += "Zorder: " + std::to_string(node->GetRenderProperties().GetPositionZ()) + "\n";
335 dumpString += "IsOnTheTree: " + std::to_string(node->IsOnTheTree()) + "\n";
336 dumpString += "Visible: " + std::to_string(node->GetRenderProperties().GetVisible()) + "\n";
337 dumpString += "OcclusionBg: " + std::to_string(node->GetAbilityBgAlpha())+ "\n";
338 dumpString += "Alpha: " + std::to_string(node->GetRenderProperties().GetAlpha()) +
339 "(include ContextAlpha: " + std::to_string(node->contextAlpha_) + ")\n";
340 dumpString += "GlobalAlpha: " + std::to_string(node->GetGlobalAlpha()) + "\n";
341 dumpString += node->GetVisibleRegion().GetRegionInfo() + "\n";
342 const auto& consumer = node->GetConsumer();
343 if (consumer == nullptr) {
344 return;
345 }
346 dumpString += "Consumer Info: \n";
347 consumer->Dump(dumpString);
348 }
349
IsNumber(const std::string & type)350 static bool IsNumber(const std::string& type)
351 {
352 auto number = static_cast<uint32_t>(std::count_if(type.begin(), type.end(), [](unsigned char c) {
353 return std::isdigit(c);
354 }));
355 return number == type.length();
356 }
357
DumpMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const358 void RSRenderService::DumpMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
359 {
360 if (!RSUniRenderJudgement::IsUniRender()) {
361 dumpString.append("\n---------------\nNot in UniRender and no information");
362 } else {
363 std::string type;
364 if (argSets.size() > 1) {
365 argSets.erase(u"dumpMem");
366 if (!argSets.empty()) {
367 type = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
368 }
369 }
370 int pid = 0;
371 if (!type.empty() && IsNumber(type)) {
372 pid = std::stoi(type);
373 }
374 mainThread_->ScheduleTask(
375 [this, &argSets, &dumpString, &type, &pid]() {
376 return mainThread_->DumpMem(argSets, dumpString, type, pid);
377 }).wait();
378 return;
379 }
380 }
381
DoDump(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const382 void RSRenderService::DoDump(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
383 {
384 std::u16string arg1(u"screen");
385 std::u16string arg2(u"surface");
386 std::u16string arg3(u"fps");
387 std::u16string arg4(u"nodeNotOnTree");
388 std::u16string arg5(u"allSurfacesMem");
389 std::u16string arg6(u"RSTree");
390 std::u16string arg7(u"EventParamList");
391 std::u16string arg8(u"h");
392 std::u16string arg9(u"allInfo");
393 std::u16string arg10(u"trimMem");
394 std::u16string arg11(u"dumpMem");
395 std::u16string arg12(u"surfacenode");
396 std::u16string arg13(u"fpsClear");
397 if (argSets.count(arg9) || argSets.count(arg1) != 0) {
398 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
399 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
400 RSHardwareThread::Instance().ScheduleTask(
401 [this, &dumpString]() { screenManager_->DisplayDump(dumpString); }).wait();
402 } else {
403 mainThread_->ScheduleTask(
404 [this, &dumpString]() { screenManager_->DisplayDump(dumpString); }).wait();
405 }
406 }
407 if (argSets.count(arg9) || argSets.count(arg2) != 0) {
408 mainThread_->ScheduleTask(
409 [this, &dumpString]() { return screenManager_->SurfaceDump(dumpString); }).wait();
410 }
411 if (argSets.count(arg9) || argSets.count(arg4) != 0) {
412 mainThread_->ScheduleTask(
413 [this, &dumpString]() { DumpNodesNotOnTheTree(dumpString); }).wait();
414 }
415 if (argSets.count(arg9) || argSets.count(arg5) != 0) {
416 mainThread_->ScheduleTask(
417 [this, &dumpString]() { DumpAllNodesMemSize(dumpString); }).wait();
418 }
419 if (argSets.count(arg9) || argSets.count(arg6) != 0) {
420 mainThread_->ScheduleTask(
421 [this, &dumpString]() { DumpRenderServiceTree(dumpString); }).wait();
422 }
423 if (argSets.count(arg9) ||argSets.count(arg7) != 0) {
424 mainThread_->ScheduleTask(
425 [this, &dumpString]() { DumpRSEvenParam(dumpString); }).wait();
426 }
427 if (argSets.count(arg10)) {
428 mainThread_->ScheduleTask(
429 [this, &argSets, &dumpString]() { return mainThread_->TrimMem(argSets, dumpString); }).wait();
430 }
431 if (argSets.count(arg11)) {
432 DumpMem(argSets, dumpString);
433 }
434 if (auto iter = argSets.find(arg12) != argSets.end()) {
435 argSets.erase(arg12);
436 if (!argSets.empty()) {
437 NodeId id = static_cast<NodeId>(std::atoll(std::wstring_convert<
438 std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(*argSets.begin()).c_str()));
439 mainThread_->ScheduleTask(
440 [this, &dumpString, &id]() { return DumpSurfaceNode(dumpString, id); }).wait();
441 }
442 }
443 FPSDUMPProcess(argSets, dumpString, arg3);
444 FPSDUMPClearProcess(argSets, dumpString, arg13);
445 if (argSets.size() == 0 || argSets.count(arg8) != 0 || dumpString.empty()) {
446 mainThread_->ScheduleTask(
447 [this, &dumpString]() { DumpHelpInfo(dumpString); }).wait();
448 }
449 }
450 } // namespace Rosen
451 } // namespace OHOS
452