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