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
18 #include <iservice_registry.h>
19 #include <malloc.h>
20 #include <parameters.h>
21 #include <platform/common/rs_log.h>
22 #include "platform/common/rs_system_properties.h"
23 #include <string>
24 #include <system_ability_definition.h>
25 #include <unistd.h>
26
27 #include "hgm_core.h"
28 #include "parameter.h"
29 #include "rs_main_thread.h"
30 #include "rs_profiler.h"
31 #include "rs_render_service_connection.h"
32 #include "vsync_generator.h"
33
34 #include "common/rs_singleton.h"
35 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
36 #include "pipeline/round_corner_display/rs_message_bus.h"
37 #include "pipeline/round_corner_display/rs_round_corner_display.h"
38 #include "pipeline/rs_hardware_thread.h"
39 #include "pipeline/rs_surface_render_node.h"
40 #include "pipeline/rs_uni_render_judgement.h"
41 #include "system/rs_system_parameters.h"
42
43 #include "text/font_mgr.h"
44
45 #ifdef TP_FEATURE_ENABLE
46 #include "touch_screen/touch_screen.h"
47 #endif
48
49 namespace OHOS {
50 namespace Rosen {
51 namespace {
52 constexpr uint32_t UNI_RENDER_VSYNC_OFFSET = 5000000;
53 const std::string BOOTEVENT_RENDER_SERVICE_READY = "bootevent.renderservice.ready";
54 constexpr size_t CLIENT_DUMP_TREE_TIMEOUT = 2000; // 2000ms
55
GenerateTaskId()56 uint32_t GenerateTaskId()
57 {
58 static std::atomic<uint32_t> id;
59 return id.fetch_add(1, std::memory_order::memory_order_relaxed);
60 }
61 }
RSRenderService()62 RSRenderService::RSRenderService() {}
63
~RSRenderService()64 RSRenderService::~RSRenderService() noexcept {}
65
Init()66 bool RSRenderService::Init()
67 {
68 system::SetParameter(BOOTEVENT_RENDER_SERVICE_READY.c_str(), "false");
69 std::thread preLoadSysTTFThread([]() {
70 Drawing::FontMgr::CreateDefaultFontMgr();
71 });
72 preLoadSysTTFThread.detach();
73
74 if (RSSystemParameters::GetTcacheEnabled()) {
75 // enable cache
76 mallopt(M_OHOS_CONFIG, M_TCACHE_NORMAL_MODE);
77 mallopt(M_OHOS_CONFIG, M_ENABLE_OPT_TCACHE);
78 mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_ENABLE);
79 mallopt(M_DELAYED_FREE, M_DELAYED_FREE_ENABLE);
80 }
81
82 RSMainThread::Instance();
83 RSUniRenderJudgement::InitUniRenderConfig();
84 #ifdef TP_FEATURE_ENABLE
85 TOUCH_SCREEN->InitTouchScreen();
86 #endif
87 screenManager_ = CreateOrGetScreenManager();
88 if (RSUniRenderJudgement::GetUniRenderEnabledType() != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
89 // screenManager initializtion executes in RSHHardwareThread under UNI_RENDER mode
90 if (screenManager_ == nullptr || !screenManager_->Init()) {
91 RS_LOGE("RSRenderService CreateOrGetScreenManager fail.");
92 return false;
93 }
94 } else {
95 RSUniRenderThread::Instance().Start();
96 RSHardwareThread::Instance().Start();
97 RegisterRcdMsg();
98 }
99
100 auto generator = CreateVSyncGenerator();
101
102 // The offset needs to be set
103 int64_t offset = 0;
104 if (!HgmCore::Instance().GetLtpoEnabled()) {
105 if (RSUniRenderJudgement::GetUniRenderEnabledType() == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
106 offset = UNI_RENDER_VSYNC_OFFSET;
107 }
108 rsVSyncController_ = new VSyncController(generator, offset);
109 appVSyncController_ = new VSyncController(generator, offset);
110 } else {
111 rsVSyncController_ = new VSyncController(generator, 0);
112 appVSyncController_ = new VSyncController(generator, 0);
113 generator->SetVSyncMode(VSYNC_MODE_LTPO);
114 }
115 rsVSyncDistributor_ = new VSyncDistributor(rsVSyncController_, "rs");
116 appVSyncDistributor_ = new VSyncDistributor(appVSyncController_, "app");
117
118 generator->SetRSDistributor(rsVSyncDistributor_);
119 generator->SetAppDistributor(appVSyncDistributor_);
120
121 mainThread_ = RSMainThread::Instance();
122 if (mainThread_ == nullptr) {
123 return false;
124 }
125 mainThread_->rsVSyncDistributor_ = rsVSyncDistributor_;
126 mainThread_->rsVSyncController_ = rsVSyncController_;
127 mainThread_->appVSyncController_ = appVSyncController_;
128 mainThread_->vsyncGenerator_ = generator;
129 mainThread_->Init();
130 mainThread_->SetAppVSyncDistributor(appVSyncDistributor_);
131 mainThread_->PostTask([]() {
132 system::SetParameter(BOOTEVENT_RENDER_SERVICE_READY.c_str(), "true");
133 RS_LOGI("Set boot render service started true");
134 }, "BOOTEVENT_RENDER_SERVICE_READY", 0, AppExecFwk::EventQueue::Priority::VIP);
135
136 // Wait samgr ready for up to 5 second to ensure adding service to samgr.
137 int status = WaitParameter("bootevent.samgr.ready", "true", 5);
138 if (status != 0) {
139 RS_LOGE("RSRenderService wait SAMGR error, return value [%d].", status);
140 }
141
142 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
143 if (samgr == nullptr) {
144 RS_LOGE("RSRenderService GetSystemAbilityManager fail.");
145 return false;
146 }
147 samgr->AddSystemAbility(RENDER_SERVICE, this);
148
149 RS_PROFILER_INIT(this);
150
151 return true;
152 }
153
Run()154 void RSRenderService::Run()
155 {
156 if (!mainThread_) {
157 RS_LOGE("RSRenderService::Run failed, mainThread is nullptr");
158 return;
159 }
160 RS_LOGE("RSRenderService::Run");
161 mainThread_->Start();
162 }
163
RegisterRcdMsg()164 void RSRenderService::RegisterRcdMsg()
165 {
166 if (RSSingleton<RoundCornerDisplay>::GetInstance().GetRcdEnable()) {
167 RS_LOGD("RSSubThreadManager::RegisterRcdMsg");
168 if (!isRcdServiceRegister_) {
169 auto& rcdInstance = RSSingleton<RoundCornerDisplay>::GetInstance();
170 auto& msgBus = RSSingleton<RsMessageBus>::GetInstance();
171 msgBus.RegisterTopic<uint32_t, uint32_t>(
172 TOPIC_RCD_DISPLAY_SIZE, &rcdInstance,
173 &RoundCornerDisplay::UpdateDisplayParameter);
174 msgBus.RegisterTopic<ScreenRotation>(
175 TOPIC_RCD_DISPLAY_ROTATION, &rcdInstance,
176 &RoundCornerDisplay::UpdateOrientationStatus);
177 msgBus.RegisterTopic<int>(
178 TOPIC_RCD_DISPLAY_NOTCH, &rcdInstance,
179 &RoundCornerDisplay::UpdateNotchStatus);
180 msgBus.RegisterTopic<bool>(
181 TOPIC_RCD_DISPLAY_HWRESOURCE, &rcdInstance,
182 &RoundCornerDisplay::UpdateHardwareResourcePrepared);
183 isRcdServiceRegister_ = true;
184 RS_LOGD("RSSubThreadManager::RegisterRcdMsg Registed rcd renderservice end");
185 return;
186 }
187 RS_LOGD("RSSubThreadManager::RegisterRcdMsg Registed rcd renderservice already.");
188 }
189 }
190
CreateConnection(const sptr<RSIConnectionToken> & token)191 sptr<RSIRenderServiceConnection> RSRenderService::CreateConnection(const sptr<RSIConnectionToken>& token)
192 {
193 if (!mainThread_ || !token) {
194 RS_LOGE("RSRenderService::CreateConnection failed, mainThread or token is nullptr");
195 return nullptr;
196 }
197 pid_t remotePid = GetCallingPid();
198 RS_PROFILER_ON_CREATE_CONNECTION(remotePid);
199
200 auto tokenObj = token->AsObject();
201 sptr<RSIRenderServiceConnection> newConn(
202 new RSRenderServiceConnection(remotePid, this, mainThread_, screenManager_, tokenObj, appVSyncDistributor_));
203
204 sptr<RSIRenderServiceConnection> tmp;
205 std::unique_lock<std::mutex> lock(mutex_);
206 // if connections_ has the same token one, replace it.
207 auto it = connections_.find(tokenObj);
208 if (it != connections_.end()) {
209 tmp = it->second;
210 }
211 connections_[tokenObj] = newConn;
212 lock.unlock();
213 mainThread_->AddTransactionDataPidInfo(remotePid);
214 return newConn;
215 }
216
RemoveConnection(sptr<IRemoteObject> token)217 void RSRenderService::RemoveConnection(sptr<IRemoteObject> token)
218 {
219 std::unique_lock<std::mutex> lock(mutex_);
220 if (connections_.count(token) == 0) {
221 return;
222 }
223
224 auto tmp = connections_.at(token);
225 connections_.erase(token);
226 lock.unlock();
227 }
228
Dump(int fd,const std::vector<std::u16string> & args)229 int RSRenderService::Dump(int fd, const std::vector<std::u16string>& args)
230 {
231 std::unordered_set<std::u16string> argSets;
232 for (decltype(args.size()) index = 0; index < args.size(); ++index) {
233 argSets.insert(args[index]);
234 }
235 if (screenManager_ == nullptr) {
236 return OHOS::INVALID_OPERATION;
237 }
238 std::string dumpString;
239 DoDump(argSets, dumpString);
240 if (dumpString.size() == 0) {
241 return OHOS::INVALID_OPERATION;
242 }
243 if (write(fd, dumpString.c_str(), dumpString.size()) < 0) {
244 RS_LOGE("RSRenderService::DumpNodesNotOnTheTree write failed");
245 return UNKNOWN_ERROR;
246 }
247 return OHOS::NO_ERROR;
248 }
249
DumpNodesNotOnTheTree(std::string & dumpString) const250 void RSRenderService::DumpNodesNotOnTheTree(std::string& dumpString) const
251 {
252 dumpString.append("\n");
253 dumpString.append("-- Node Not On Tree\n");
254
255 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
256 nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
257 if (node == nullptr) {
258 return;
259 }
260
261 if (node->IsInstanceOf<RSSurfaceRenderNode>() && !node->IsOnTheTree()) {
262 const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
263 dumpString += "\n node Id[" + std::to_string(node->GetId()) + "]:\n";
264 const auto& surfaceConsumer = surfaceNode->GetRSSurfaceHandler()->GetConsumer();
265 if (surfaceConsumer == nullptr) {
266 return;
267 }
268 surfaceConsumer->Dump(dumpString);
269 }
270 });
271 }
272
DumpAllNodesMemSize(std::string & dumpString) const273 void RSRenderService::DumpAllNodesMemSize(std::string& dumpString) const
274 {
275 dumpString.append("\n");
276 dumpString.append("-- All Surfaces Memory Size\n");
277 dumpString.append("the memory size of all surfaces buffer is : dumpend");
278
279 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
280 nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
281 if (node == nullptr || !node->IsInstanceOf<RSSurfaceRenderNode>()) {
282 return;
283 }
284
285 const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
286 const auto& surfaceConsumer = surfaceNode->GetRSSurfaceHandler()->GetConsumer();
287 if (surfaceConsumer == nullptr) {
288 return;
289 }
290
291 surfaceConsumer->Dump(dumpString);
292 });
293 }
294
DumpHelpInfo(std::string & dumpString) const295 void RSRenderService::DumpHelpInfo(std::string& dumpString) const
296 {
297 dumpString.append("------Graphic2D--RenderSerice ------\n")
298 .append("Usage:\n")
299 .append(" h ")
300 .append("|help text for the tool\n")
301 .append("screen ")
302 .append("|dump all screen infomation in the system\n")
303 .append("surface ")
304 .append("|dump all surface information\n")
305 .append("composer fps ")
306 .append("|dump the fps info of composer\n")
307 .append("[surface name] fps ")
308 .append("|dump the fps info of surface\n")
309 .append("composer fpsClear ")
310 .append("|clear the fps info of composer\n")
311 .append("[windowname] fps ")
312 .append("|dump the fps info of window\n")
313 .append("[windowname] hitchs ")
314 .append("|dump the hitchs info of window\n")
315 .append("[surface name] fpsClear ")
316 .append("|clear the fps info of surface\n")
317 .append("nodeNotOnTree ")
318 .append("|dump nodeNotOnTree info\n")
319 .append("allSurfacesMem ")
320 .append("|dump surface mem info\n")
321 .append("RSTree ")
322 .append("|dump RSTree info\n")
323 .append("EventParamList ")
324 .append("|dump EventParamList info\n")
325 .append("allInfo ")
326 .append("|dump all info\n")
327 .append("client ")
328 .append("|dump client ui node trees\n")
329 .append("client-server ")
330 .append("|dump client and server info\n")
331 .append("dumpMem ")
332 .append("|dump Cache\n")
333 .append("trimMem cpu/gpu/shader ")
334 .append("|release Cache\n")
335 .append("surfacenode [id] ")
336 .append("|dump node info\n")
337 .append("fpsCount ")
338 .append("|dump the refresh rate counts info\n")
339 .append("clearFpsCount ")
340 .append("|clear the refresh rate counts info\n")
341 #ifdef RS_ENABLE_VK
342 .append("vktextureLimit ")
343 .append("|dump vk texture limit info\n")
344 #endif
345 .append("flushJankStatsRs")
346 .append("|flush rs jank stats hisysevent\n");
347 }
348
FPSDUMPProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const349 void RSRenderService::FPSDUMPProcess(std::unordered_set<std::u16string>& argSets,
350 std::string& dumpString, const std::u16string& arg) const
351 {
352 auto iter = argSets.find(arg);
353 if (iter != argSets.end()) {
354 std::string layerArg;
355 argSets.erase(iter);
356 if (!argSets.empty()) {
357 layerArg = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
358 }
359 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
360 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
361 RSHardwareThread::Instance().ScheduleTask(
362 [this, &dumpString, &layerArg]() { return screenManager_->FpsDump(dumpString, layerArg); }).wait();
363 } else {
364 mainThread_->ScheduleTask(
365 [this, &dumpString, &layerArg]() { return screenManager_->FpsDump(dumpString, layerArg); }).wait();
366 }
367 }
368 }
369
FPSDUMPClearProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const370 void RSRenderService::FPSDUMPClearProcess(std::unordered_set<std::u16string>& argSets,
371 std::string& dumpString, const std::u16string& arg) const
372 {
373 auto iter = argSets.find(arg);
374 if (iter != argSets.end()) {
375 std::string layerArg;
376 argSets.erase(iter);
377 if (!argSets.empty()) {
378 layerArg = std::wstring_convert<
379 std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
380 }
381 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
382 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
383 RSHardwareThread::Instance().ScheduleTask(
384 [this, &dumpString, &layerArg]() {
385 return screenManager_->ClearFpsDump(dumpString, layerArg);
386 }).wait();
387 } else {
388 mainThread_->ScheduleTask(
389 [this, &dumpString, &layerArg]() {
390 return screenManager_->ClearFpsDump(dumpString, layerArg);
391 }).wait();
392 }
393 }
394 }
395
DumpRSEvenParam(std::string & dumpString) const396 void RSRenderService::DumpRSEvenParam(std::string& dumpString) const
397 {
398 dumpString.append("\n");
399 dumpString.append("-- EventParamListDump: \n");
400 mainThread_->RsEventParamDump(dumpString);
401 }
402
DumpRenderServiceTree(std::string & dumpString,bool forceDumpSingleFrame) const403 void RSRenderService::DumpRenderServiceTree(std::string& dumpString, bool forceDumpSingleFrame) const
404 {
405 dumpString.append("\n");
406 dumpString.append("-- RenderServiceTreeDump: \n");
407 mainThread_->RenderServiceTreeDump(dumpString, forceDumpSingleFrame);
408 }
409
DumpRefreshRateCounts(std::string & dumpString) const410 void RSRenderService::DumpRefreshRateCounts(std::string& dumpString) const
411 {
412 dumpString.append("\n");
413 dumpString.append("-- RefreshRateCounts: \n");
414 RSHardwareThread::Instance().RefreshRateCounts(dumpString);
415 }
416
DumpClearRefreshRateCounts(std::string & dumpString) const417 void RSRenderService::DumpClearRefreshRateCounts(std::string& dumpString) const
418 {
419 dumpString.append("\n");
420 dumpString.append("-- ClearRefreshRateCounts: \n");
421 RSHardwareThread::Instance().ClearRefreshRateCounts(dumpString);
422 }
423
WindowHitchsDump(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const424 void RSRenderService::WindowHitchsDump(
425 std::unordered_set<std::u16string>& argSets, std::string& dumpString, const std::u16string& arg) const
426 {
427 auto iter = argSets.find(arg);
428 if (iter != argSets.end()) {
429 std::string layerArg;
430 argSets.erase(iter);
431 if (!argSets.empty()) {
432 layerArg = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
433 }
434 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
435 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
436 RSHardwareThread::Instance().ScheduleTask(
437 [this, &dumpString, &layerArg]() { return screenManager_->HitchsDump(dumpString, layerArg); }).wait();
438 } else {
439 mainThread_->ScheduleTask(
440 [this, &dumpString, &layerArg]() { return screenManager_->HitchsDump(dumpString, layerArg); }).wait();
441 }
442 }
443 }
444
DumpSurfaceNode(std::string & dumpString,NodeId id) const445 void RSRenderService::DumpSurfaceNode(std::string& dumpString, NodeId id) const
446 {
447 dumpString.append("\n");
448 dumpString.append("-- SurfaceNode\n");
449
450 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
451 auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
452 if (node == nullptr) {
453 dumpString += std::to_string(id) + " is invalid ID\n";
454 return;
455 }
456 dumpString += "ID: " + std::to_string(node->GetId()) + "\n";
457 dumpString += "Name: " + node->GetName() + "\n";
458 dumpString += "SrcRect: [" + std::to_string(node->GetSrcRect().left_) + "," +
459 std::to_string(node->GetSrcRect().top_) + "," +
460 std::to_string(node->GetSrcRect().width_) + "," +
461 std::to_string(node->GetSrcRect().height_) + "]\n";
462 dumpString += "DstRect: [" + std::to_string(node->GetDstRect().left_) + "," +
463 std::to_string(node->GetDstRect().top_) + "," +
464 std::to_string(node->GetDstRect().width_) + "," +
465 std::to_string(node->GetDstRect().height_) + "]\n";
466 dumpString += "CornerRadius: [" + std::to_string(node->GetRenderProperties().GetCornerRadius().x_) + "," +
467 std::to_string(node->GetRenderProperties().GetCornerRadius().y_) + "," +
468 std::to_string(node->GetRenderProperties().GetCornerRadius().z_) + "," +
469 std::to_string(node->GetRenderProperties().GetCornerRadius().w_) + "]\n";
470 dumpString += "Bounds: [" + std::to_string(node->GetRenderProperties().GetBoundsWidth()) + "," +
471 std::to_string(node->GetRenderProperties().GetBoundsHeight()) + "]\n";
472 if (auto& contextClipRegion = node->contextClipRect_) {
473 dumpString += "ContextClipRegion: [" + std::to_string(contextClipRegion->GetWidth()) + "," +
474 std::to_string(contextClipRegion->GetHeight()) + "]\n";
475 } else {
476 dumpString += "ContextClipRegion: [ empty ]\n";
477 }
478 dumpString += "Zorder: " + std::to_string(node->GetRenderProperties().GetPositionZ()) + "\n";
479 dumpString += "IsOnTheTree: " + std::to_string(node->IsOnTheTree()) + "\n";
480 dumpString += "Visible: " + std::to_string(node->GetRenderProperties().GetVisible()) + "\n";
481 dumpString += "OcclusionBg: " + std::to_string(node->GetAbilityBgAlpha())+ "\n";
482 dumpString += "Alpha: " + std::to_string(node->GetRenderProperties().GetAlpha()) +
483 "(include ContextAlpha: " + std::to_string(node->contextAlpha_) + ")\n";
484 dumpString += "GlobalAlpha: " + std::to_string(node->GetGlobalAlpha()) + "\n";
485 dumpString += node->GetVisibleRegion().GetRegionInfo() + "\n";
486 const auto consumer = node->GetRSSurfaceHandler()->GetConsumer();
487 if (consumer == nullptr) {
488 return;
489 }
490 dumpString += "Consumer Info: \n";
491 consumer->Dump(dumpString);
492 }
493
IsNumber(const std::string & type)494 static bool IsNumber(const std::string& type)
495 {
496 auto number = static_cast<uint32_t>(std::count_if(type.begin(), type.end(), [](unsigned char c) {
497 return std::isdigit(c);
498 }));
499 return number == type.length();
500 }
501
DumpMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const502 void RSRenderService::DumpMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
503 {
504 if (!RSUniRenderJudgement::IsUniRender()) {
505 dumpString.append("\n---------------\nNot in UniRender and no information");
506 } else {
507 std::string type;
508 if (argSets.size() > 1) {
509 argSets.erase(u"dumpMem");
510 if (!argSets.empty()) {
511 type = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
512 }
513 }
514 int pid = 0;
515 if (!type.empty() && IsNumber(type)) {
516 pid = std::stoi(type);
517 }
518 mainThread_->ScheduleTask(
519 [this, &argSets, &dumpString, &type, &pid]() {
520 return mainThread_->DumpMem(argSets, dumpString, type, pid);
521 }).wait();
522 return;
523 }
524 }
525
DumpJankStatsRs(std::string & dumpString) const526 void RSRenderService::DumpJankStatsRs(std::string& dumpString) const
527 {
528 dumpString.append("\n");
529 RSJankStats::GetInstance().ReportJankStats();
530 dumpString.append("flush done\n");
531 }
532
533 #ifdef RS_ENABLE_VK
DumpVkTextureLimit(std::string & dumpString) const534 void RSRenderService::DumpVkTextureLimit(std::string& dumpString) const
535 {
536 dumpString.append("\n");
537 dumpString.append("-- vktextureLimit:\n");
538 auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
539 VkPhysicalDevice physicalDevice = vkContext.GetPhysicalDevice();
540 VkPhysicalDeviceProperties deviceProperties;
541 vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
542
543 uint32_t maxTextureWidth = deviceProperties.limits.maxImageDimension2D;
544 uint32_t maxTextureHeight = deviceProperties.limits.maxImageDimension2D;
545 dumpString.append(
546 "width: " + std::to_string(maxTextureWidth) + " height: " + std::to_string(maxTextureHeight) + "\n");
547 }
548 #endif
549
DoDump(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const550 void RSRenderService::DoDump(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
551 {
552 if (!mainThread_ || !screenManager_) {
553 RS_LOGE("RSRenderService::DoDump failed, mainThread or screenManager is nullptr");
554 return;
555 }
556 std::u16string arg1(u"screen");
557 std::u16string arg2(u"surface");
558 std::u16string arg3(u"fps");
559 std::u16string arg4(u"nodeNotOnTree");
560 std::u16string arg5(u"allSurfacesMem");
561 std::u16string arg6(u"RSTree");
562 std::u16string arg6_1(u"MultiRSTrees");
563 std::u16string arg7(u"EventParamList");
564 std::u16string arg8(u"h");
565 std::u16string arg9(u"allInfo");
566 std::u16string arg10(u"trimMem");
567 std::u16string arg11(u"dumpMem");
568 std::u16string arg12(u"surfacenode");
569 std::u16string arg13(u"fpsClear");
570 std::u16string arg15(u"fpsCount");
571 std::u16string arg16(u"clearFpsCount");
572 std::u16string arg17(u"hitchs");
573 std::u16string arg18(u"rsLogFlag");
574 std::u16string arg19(u"flushJankStatsRs");
575 std::u16string arg20(u"client");
576 std::u16string arg21(u"client-server");
577 #ifdef RS_ENABLE_VK
578 std::u16string arg22(u"vktextureLimit");
579 #endif
580 if (argSets.count(arg21)) {
581 argSets.insert(arg9);
582 argSets.insert(arg20);
583 }
584 if (argSets.count(arg9) || argSets.count(arg1) != 0) {
585 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
586 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
587 RSHardwareThread::Instance().ScheduleTask(
588 [this, &dumpString]() { screenManager_->DisplayDump(dumpString); }).wait();
589 } else {
590 mainThread_->ScheduleTask(
591 [this, &dumpString]() { screenManager_->DisplayDump(dumpString); }).wait();
592 }
593 }
594 if (argSets.count(arg9) || argSets.count(arg2) != 0) {
595 mainThread_->ScheduleTask(
596 [this, &dumpString]() { return screenManager_->SurfaceDump(dumpString); }).wait();
597 }
598 if (argSets.count(arg9) || argSets.count(arg4) != 0) {
599 mainThread_->ScheduleTask(
600 [this, &dumpString]() { DumpNodesNotOnTheTree(dumpString); }).wait();
601 }
602 if (argSets.count(arg9) || argSets.count(arg5) != 0) {
603 mainThread_->ScheduleTask(
604 [this, &dumpString]() { DumpAllNodesMemSize(dumpString); }).wait();
605 }
606 if (argSets.count(arg9) || argSets.count(arg6) != 0) {
607 mainThread_->ScheduleTask(
608 [this, &dumpString]() { DumpRenderServiceTree(dumpString); }).wait();
609 }
610 if (argSets.count(arg9) || argSets.count(arg6_1) != 0) {
611 mainThread_->ScheduleTask(
612 [this, &dumpString]() {DumpRenderServiceTree(dumpString, false); }).wait();
613 }
614 if (argSets.count(arg9) ||argSets.count(arg7) != 0) {
615 mainThread_->ScheduleTask(
616 [this, &dumpString]() { DumpRSEvenParam(dumpString); }).wait();
617 }
618 if (argSets.count(arg10)) {
619 mainThread_->ScheduleTask(
620 [this, &argSets, &dumpString]() { return mainThread_->TrimMem(argSets, dumpString); }).wait();
621 }
622 if (argSets.count(arg11)) {
623 DumpMem(argSets, dumpString);
624 }
625 if (auto iter = argSets.find(arg12) != argSets.end()) {
626 argSets.erase(arg12);
627 if (!argSets.empty()) {
628 NodeId id = static_cast<NodeId>(std::atoll(std::wstring_convert<
629 std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(*argSets.begin()).c_str()));
630 mainThread_->ScheduleTask(
631 [this, &dumpString, &id]() { return DumpSurfaceNode(dumpString, id); }).wait();
632 }
633 }
634 FPSDUMPProcess(argSets, dumpString, arg3);
635 FPSDUMPClearProcess(argSets, dumpString, arg13);
636 WindowHitchsDump(argSets, dumpString, arg17);
637 if (auto iter = argSets.find(arg18) != argSets.end()) {
638 argSets.erase(arg18);
639 if (!argSets.empty()) {
640 std::string logFlag = std::wstring_convert<
641 std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(*argSets.begin());
642 if (RSLogManager::GetInstance().SetRSLogFlag(logFlag)) {
643 dumpString.append("Successed to set flag: " + logFlag + "\n");
644 } else {
645 dumpString.append("Failed to set flag: " + logFlag + "\n");
646 }
647 }
648 }
649 if (argSets.size() == 0 || argSets.count(arg8) != 0 || dumpString.empty()) {
650 mainThread_->ScheduleTask(
651 [this, &dumpString]() { DumpHelpInfo(dumpString); }).wait();
652 }
653 if (argSets.count(arg9) || argSets.count(arg15) != 0) {
654 mainThread_->ScheduleTask(
655 [this, &dumpString]() { DumpRefreshRateCounts(dumpString); }).wait();
656 }
657 if (argSets.count(arg16) != 0) {
658 mainThread_->ScheduleTask(
659 [this, &dumpString]() { DumpClearRefreshRateCounts(dumpString); }).wait();
660 }
661 if (argSets.count(arg19) != 0) {
662 mainThread_->ScheduleTask(
663 [this, &dumpString]() { DumpJankStatsRs(dumpString); }).wait();
664 }
665 if (argSets.count(arg20)) {
666 auto taskId = GenerateTaskId();
667 mainThread_->ScheduleTask(
668 [this, taskId]() {
669 mainThread_->SendClientDumpNodeTreeCommands(taskId);
670 }).wait();
671 mainThread_->CollectClientNodeTreeResult(taskId, dumpString, CLIENT_DUMP_TREE_TIMEOUT);
672 }
673 #ifdef RS_ENABLE_VK
674 if (argSets.count(arg22) != 0) {
675 mainThread_->ScheduleTask(
676 [this, &dumpString]() { DumpVkTextureLimit(dumpString); }).wait();
677 }
678 #endif
679 }
680 } // namespace Rosen
681 } // namespace OHOS
682