• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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