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 "memory/rs_memory_manager.h"
29 #include "parameter.h"
30 #include "rs_main_thread.h"
31 #include "rs_profiler.h"
32 #include "rs_render_service_connection.h"
33 #include "vsync_generator.h"
34 #include "rs_trace.h"
35
36 #include "common/rs_singleton.h"
37 #ifdef RS_ENABLE_GPU
38 #include "feature/round_corner_display/rs_round_corner_display_manager.h"
39 #endif
40 #include "pipeline/hardware_thread/rs_hardware_thread.h"
41 #include "pipeline/rs_surface_render_node.h"
42 #include "pipeline/rs_uni_render_judgement.h"
43 #include "system/rs_system_parameters.h"
44 #include "gfx/fps_info/rs_surface_fps_manager.h"
45 #include "gfx/dump/rs_dump_manager.h"
46 #include "graphic_feature_param_manager.h"
47
48 #include "text/font_mgr.h"
49
50 #ifdef TP_FEATURE_ENABLE
51 #include "screen_manager/touch_screen.h"
52 #endif
53
54 namespace OHOS {
55 namespace Rosen {
56 namespace {
57 constexpr int64_t UNI_RENDER_VSYNC_OFFSET = 5000000; // ns
58 constexpr int64_t UNI_RENDER_VSYNC_OFFSET_DELAY_MODE = -3300000; // ns
59 const std::string BOOTEVENT_RENDER_SERVICE_READY = "bootevent.renderservice.ready";
60 constexpr size_t CLIENT_DUMP_TREE_TIMEOUT = 2000; // 2000ms
61 #ifdef RS_ENABLE_GPU
62 static const int INT_INIT_VAL = 0;
63 static const int CREAT_NUM_ONE = 1;
64 static const int INIT_EGL_VERSION = 3;
65 static EGLDisplay g_tmpDisplay = EGL_NO_DISPLAY;
66 static EGLContext g_tmpContext = EGL_NO_CONTEXT;
67 #endif
68
GenerateTaskId()69 uint32_t GenerateTaskId()
70 {
71 static std::atomic<uint32_t> id;
72 return id.fetch_add(1, std::memory_order::memory_order_relaxed);
73 }
74 }
RSRenderService()75 RSRenderService::RSRenderService() {}
76
~RSRenderService()77 RSRenderService::~RSRenderService() noexcept {}
78
Init()79 bool RSRenderService::Init()
80 {
81 system::SetParameter(BOOTEVENT_RENDER_SERVICE_READY.c_str(), "false");
82 std::thread preLoadSysTTFThread([]() {
83 Drawing::FontMgr::CreateDefaultFontMgr();
84 });
85 preLoadSysTTFThread.detach();
86
87 if (RSSystemParameters::GetTcacheEnabled()) {
88 // enable cache
89 mallopt(M_OHOS_CONFIG, M_TCACHE_NORMAL_MODE);
90 mallopt(M_OHOS_CONFIG, M_ENABLE_OPT_TCACHE);
91 mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_ENABLE);
92 mallopt(M_DELAYED_FREE, M_DELAYED_FREE_ENABLE);
93 }
94
95 RSMainThread::Instance();
96 RSUniRenderJudgement::InitUniRenderConfig();
97
98 // feature param parse
99 GraphicFeatureParamManager::GetInstance().Init();
100
101 // need called after GraphicFeatureParamManager::GetInstance().Init();
102 FilterCCMInit();
103
104 #ifdef TP_FEATURE_ENABLE
105 TOUCH_SCREEN->InitTouchScreen();
106 #endif
107 screenManager_ = CreateOrGetScreenManager();
108 if (RSUniRenderJudgement::GetUniRenderEnabledType() != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
109 // screenManager initializtion executes in RSHHardwareThread under UNI_RENDER mode
110 if (screenManager_ == nullptr || !screenManager_->Init()) {
111 RS_LOGE("RSRenderService CreateOrGetScreenManager fail.");
112 return false;
113 }
114 } else {
115 #ifdef RS_ENABLE_GPU
116 RSUniRenderThread::Instance().Start();
117 RSHardwareThread::Instance().Start();
118 RSSingleton<RoundCornerDisplayManager>::GetInstance().RegisterRcdMsg();
119 #endif
120 }
121
122 auto generator = CreateVSyncGenerator();
123
124 // The offset needs to be set
125 int64_t offset = 0;
126 if (!HgmCore::Instance().GetLtpoEnabled()) {
127 if (RSUniRenderJudgement::GetUniRenderEnabledType() == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
128 offset = HgmCore::Instance().IsDelayMode() ? UNI_RENDER_VSYNC_OFFSET_DELAY_MODE : UNI_RENDER_VSYNC_OFFSET;
129 }
130 rsVSyncController_ = new VSyncController(generator, offset);
131 appVSyncController_ = new VSyncController(generator, offset);
132 } else {
133 rsVSyncController_ = new VSyncController(generator, 0);
134 appVSyncController_ = new VSyncController(generator, 0);
135 generator->SetVSyncMode(VSYNC_MODE_LTPO);
136 }
137 DVSyncFeatureParam dvsyncParam;
138 InitDVSyncParams(dvsyncParam);
139 rsVSyncDistributor_ = new VSyncDistributor(rsVSyncController_, "rs", dvsyncParam);
140 appVSyncDistributor_ = new VSyncDistributor(appVSyncController_, "app", dvsyncParam);
141
142 generator->SetRSDistributor(rsVSyncDistributor_);
143 generator->SetAppDistributor(appVSyncDistributor_);
144
145 mainThread_ = RSMainThread::Instance();
146 if (mainThread_ == nullptr) {
147 return false;
148 }
149 mainThread_->rsVSyncDistributor_ = rsVSyncDistributor_;
150 mainThread_->rsVSyncController_ = rsVSyncController_;
151 mainThread_->appVSyncController_ = appVSyncController_;
152 mainThread_->vsyncGenerator_ = generator;
153 mainThread_->SetAppVSyncDistributor(appVSyncDistributor_);
154 mainThread_->Init();
155 mainThread_->PostTask([]() {
156 system::SetParameter(BOOTEVENT_RENDER_SERVICE_READY.c_str(), "true");
157 RS_LOGI("Set boot render service started true");
158 }, "BOOTEVENT_RENDER_SERVICE_READY", 0, AppExecFwk::EventQueue::Priority::VIP);
159
160 // Wait samgr ready for up to 5 second to ensure adding service to samgr.
161 int status = WaitParameter("bootevent.samgr.ready", "true", 5);
162 if (status != 0) {
163 RS_LOGE("RSRenderService wait SAMGR error, return value [%d].", status);
164 }
165
166 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
167 if (samgr == nullptr) {
168 RS_LOGE("RSRenderService GetSystemAbilityManager fail.");
169 return false;
170 }
171 samgr->AddSystemAbility(RENDER_SERVICE, this);
172
173 RSGfxDumpInit(); // Gfx Init
174
175 RS_PROFILER_INIT(this);
176
177 return true;
178 }
179
InitDVSyncParams(DVSyncFeatureParam & dvsyncParam)180 void RSRenderService::InitDVSyncParams(DVSyncFeatureParam &dvsyncParam)
181 {
182 std::shared_ptr<FeatureParam> featureParam =
183 GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[DVSYNC]);
184 std::vector<bool> switchParams = {};
185 std::vector<uint32_t> bufferCountParams = {};
186 std::unordered_map<std::string, std::string> adaptiveConfigs;
187 if (featureParam != nullptr) {
188 std::shared_ptr<DVSyncParam> dvsyncFeatureParam = std::static_pointer_cast<DVSyncParam>(featureParam);
189 switchParams = {
190 dvsyncFeatureParam->IsDVSyncEnable(),
191 dvsyncFeatureParam->IsUiDVSyncEnable(),
192 dvsyncFeatureParam->IsNativeDVSyncEnable(),
193 dvsyncFeatureParam->IsAdaptiveDVSyncEnable(),
194 };
195 bufferCountParams = {
196 dvsyncFeatureParam->GetUiBufferCount(),
197 dvsyncFeatureParam->GetRsBufferCount(),
198 dvsyncFeatureParam->GetNativeBufferCount(),
199 dvsyncFeatureParam->GetWebBufferCount(),
200 };
201 adaptiveConfigs = dvsyncFeatureParam->GetAdaptiveConfig();
202 }
203 dvsyncParam = { switchParams, bufferCountParams, adaptiveConfigs };
204 }
205
Run()206 void RSRenderService::Run()
207 {
208 if (!mainThread_) {
209 RS_LOGE("RSRenderService::Run failed, mainThread is nullptr");
210 return;
211 }
212 RS_LOGE("RSRenderService::Run");
213 mainThread_->Start();
214 }
215
CreateConnection(const sptr<RSIConnectionToken> & token)216 sptr<RSIRenderServiceConnection> RSRenderService::CreateConnection(const sptr<RSIConnectionToken>& token)
217 {
218 if (!mainThread_ || !token) {
219 RS_LOGE("RSRenderService::CreateConnection failed, mainThread or token is nullptr");
220 return nullptr;
221 }
222 pid_t remotePid = GetCallingPid();
223 RS_PROFILER_ON_CREATE_CONNECTION(remotePid);
224
225 auto tokenObj = token->AsObject();
226 sptr<RSIRenderServiceConnection> newConn(
227 new RSRenderServiceConnection(remotePid, this, mainThread_, screenManager_, tokenObj, appVSyncDistributor_));
228
229 sptr<RSIRenderServiceConnection> tmp;
230 std::unique_lock<std::mutex> lock(mutex_);
231 // if connections_ has the same token one, replace it.
232 auto it = connections_.find(tokenObj);
233 if (it != connections_.end()) {
234 tmp = it->second;
235 }
236 connections_[tokenObj] = newConn;
237 lock.unlock();
238 mainThread_->AddTransactionDataPidInfo(remotePid);
239 return newConn;
240 }
241
RemoveConnection(sptr<IRemoteObject> token)242 void RSRenderService::RemoveConnection(sptr<IRemoteObject> token)
243 {
244 // temporarily extending the life cycle
245 std::unique_lock<std::mutex> lock(mutex_);
246 auto iter = connections_.find(token);
247 if (iter == connections_.end()) {
248 RS_LOGE("RSRenderService::RemoveConnection: connections_ cannot find token");
249 return;
250 }
251 auto tmp = iter->second;
252 connections_.erase(token);
253 lock.unlock();
254 }
255
Dump(int fd,const std::vector<std::u16string> & args)256 int RSRenderService::Dump(int fd, const std::vector<std::u16string>& args)
257 {
258 std::unordered_set<std::u16string> argSets;
259 for (decltype(args.size()) index = 0; index < args.size(); ++index) {
260 argSets.insert(args[index]);
261 }
262 if (screenManager_ == nullptr) {
263 return OHOS::INVALID_OPERATION;
264 }
265 std::string dumpString;
266 DoDump(argSets, dumpString);
267 if (dumpString.size() == 0) {
268 return OHOS::INVALID_OPERATION;
269 }
270 if (write(fd, dumpString.c_str(), dumpString.size()) < 0) {
271 RS_LOGE("RSRenderService::DumpNodesNotOnTheTree write failed, string size: %{public}zu", dumpString.size());
272 return UNKNOWN_ERROR;
273 }
274 return OHOS::NO_ERROR;
275 }
276
DumpNodesNotOnTheTree(std::string & dumpString) const277 void RSRenderService::DumpNodesNotOnTheTree(std::string& dumpString) const
278 {
279 dumpString.append("\n");
280 dumpString.append("-- Node Not On Tree\n");
281
282 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
283 nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
284 if (node == nullptr) {
285 return;
286 }
287
288 if (node->IsInstanceOf<RSSurfaceRenderNode>() && !node->IsOnTheTree()) {
289 const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
290 dumpString += "\n node Id[" + std::to_string(node->GetId()) + "]:\n";
291 const auto& surfaceConsumer = surfaceNode->GetRSSurfaceHandler()->GetConsumer();
292 if (surfaceConsumer == nullptr) {
293 return;
294 }
295 surfaceConsumer->Dump(dumpString);
296 }
297 });
298 }
299
DumpAllNodesMemSize(std::string & dumpString) const300 void RSRenderService::DumpAllNodesMemSize(std::string& dumpString) const
301 {
302 dumpString.append("\n");
303 dumpString.append("-- All Surfaces Memory Size\n");
304 dumpString.append("the memory size of all surfaces buffer is : dumpend");
305
306 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
307 nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
308 if (node == nullptr || !node->IsInstanceOf<RSSurfaceRenderNode>()) {
309 return;
310 }
311
312 const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
313 const auto& surfaceConsumer = surfaceNode->GetRSSurfaceHandler()->GetConsumer();
314 if (surfaceConsumer == nullptr) {
315 return;
316 }
317
318 surfaceConsumer->Dump(dumpString);
319 });
320 }
321
FPSDUMPProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const322 void RSRenderService::FPSDUMPProcess(std::unordered_set<std::u16string>& argSets,
323 std::string& dumpString, const std::u16string& arg) const
324 {
325 auto iter = argSets.find(arg);
326 if (iter == argSets.end()) {
327 return ;
328 }
329 argSets.erase(iter);
330 if (argSets.empty()) {
331 RS_LOGE("RSRenderService::FPSDUMPProcess layer name is not specified");
332 return ;
333 }
334 RS_TRACE_NAME("RSRenderService::FPSDUMPProcess");
335 std::string fpsArg = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}
336 .to_bytes(*argSets.begin());
337 std::unordered_set<std::string> args{"DisplayNode", "composer", "UniRender"};
338 if (args.find(fpsArg) != args.end()) {
339 DumpFps(dumpString, fpsArg);
340 } else {
341 DumpSurfaceNodeFps(dumpString, fpsArg);
342 }
343 }
344
DumpFps(std::string & dumpString,std::string & fpsArg) const345 void RSRenderService::DumpFps(std::string& dumpString, std::string& fpsArg) const
346 {
347 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
348 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
349 #ifdef RS_ENABLE_GPU
350 RSHardwareThread::Instance().ScheduleTask(
351 [this, &dumpString, &fpsArg]() { return screenManager_->FpsDump(dumpString, fpsArg); }).wait();
352 #endif
353 } else {
354 mainThread_->ScheduleTask(
355 [this, &dumpString, &fpsArg]() { return screenManager_->FpsDump(dumpString, fpsArg); }).wait();
356 }
357 }
358
DumpSurfaceNodeFps(std::string & dumpString,std::string & fpsArg) const359 void RSRenderService::DumpSurfaceNodeFps(std::string& dumpString, std::string& fpsArg) const
360 {
361 dumpString += "\n-- The recently fps records info of screens:\n";
362 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
363 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
364 NodeId nodeId = 0;
365 nodeMap.TraverseSurfaceNodesBreakOnCondition(
366 [&nodeId, &fpsArg](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) {
367 if (surfaceNode->GetName() == fpsArg && surfaceNode->IsOnTheTree() == true) {
368 nodeId = surfaceNode->GetId();
369 return true;
370 }
371 return false;
372 });
373 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
374 #ifdef RS_ENABLE_GPU
375 RSHardwareThread::Instance().ScheduleTask(
376 [this, &dumpString, &nodeId]() {
377 return RSSurfaceFpsManager::GetInstance().Dump(dumpString, nodeId);
378 }).wait();
379 #endif
380 } else {
381 mainThread_->ScheduleTask(
382 [this, &dumpString, &nodeId]() {
383 return RSSurfaceFpsManager::GetInstance().Dump(dumpString, nodeId);
384 }).wait();
385 }
386 }
387
FPSDUMPClearProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const388 void RSRenderService::FPSDUMPClearProcess(std::unordered_set<std::u16string>& argSets,
389 std::string& dumpString, const std::u16string& arg) const
390 {
391 auto iter = argSets.find(arg);
392 if (iter == argSets.end()) {
393 return ;
394 }
395 argSets.erase(iter);
396 if (argSets.empty()) {
397 RS_LOGE("RSRenderService::FPSDUMPClearProcess layer name is not specified");
398 return ;
399 }
400 RS_TRACE_NAME("RSRenderService::FPSDUMPClearProcess");
401 std::string fpsArg = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}
402 .to_bytes(*argSets.begin());
403 std::unordered_set<std::string> args{"DisplayNode", "composer"};
404 if (args.find(fpsArg) != args.end()) {
405 ClearFps(dumpString, fpsArg);
406 } else {
407 ClearSurfaceNodeFps(dumpString, fpsArg);
408 }
409 }
410
ClearFps(std::string & dumpString,std::string & fpsArg) const411 void RSRenderService::ClearFps(std::string& dumpString, std::string& fpsArg) const
412 {
413 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
414 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
415 #ifdef RS_ENABLE_GPU
416 RSHardwareThread::Instance().ScheduleTask(
417 [this, &dumpString, &fpsArg]() {
418 return screenManager_->ClearFpsDump(dumpString, fpsArg);
419 }).wait();
420 #endif
421 } else {
422 mainThread_->ScheduleTask(
423 [this, &dumpString, &fpsArg]() {
424 return screenManager_->ClearFpsDump(dumpString, fpsArg);
425 }).wait();
426 }
427 }
428
ClearSurfaceNodeFps(std::string & dumpString,std::string & fpsArg) const429 void RSRenderService::ClearSurfaceNodeFps(std::string& dumpString, std::string& fpsArg) const
430 {
431 dumpString += "\n-- Clear fps records info of screens:\n";
432 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
433 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
434 NodeId nodeId = 0;
435 nodeMap.TraverseSurfaceNodesBreakOnCondition(
436 [&nodeId, &fpsArg](const std::shared_ptr<RSSurfaceRenderNode>& surfaceNode) {
437 if (surfaceNode->GetName() == fpsArg && surfaceNode->IsOnTheTree() == true) {
438 nodeId = surfaceNode->GetId();
439 return true;
440 }
441 return false;
442 });
443 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
444 #ifdef RS_ENABLE_GPU
445 RSHardwareThread::Instance().ScheduleTask(
446 [this, &dumpString, &nodeId]() {
447 return RSSurfaceFpsManager::GetInstance().ClearDump(dumpString, nodeId);
448 }).wait();
449 #endif
450 } else {
451 mainThread_->ScheduleTask(
452 [this, &dumpString, &nodeId]() {
453 return RSSurfaceFpsManager::GetInstance().ClearDump(dumpString, nodeId);
454 }).wait();
455 }
456 }
457
DumpRSEvenParam(std::string & dumpString) const458 void RSRenderService::DumpRSEvenParam(std::string& dumpString) const
459 {
460 dumpString.append("\n");
461 dumpString.append("-- EventParamListDump: \n");
462 mainThread_->RsEventParamDump(dumpString);
463 }
464
DumpRenderServiceTree(std::string & dumpString,bool forceDumpSingleFrame) const465 void RSRenderService::DumpRenderServiceTree(std::string& dumpString, bool forceDumpSingleFrame) const
466 {
467 dumpString.append("\n");
468 dumpString.append("-- RenderServiceTreeDump: \n");
469 #ifdef RS_ENABLE_GPU
470 mainThread_->RenderServiceTreeDump(dumpString, forceDumpSingleFrame, true);
471 #endif
472 }
473
DumpRefreshRateCounts(std::string & dumpString) const474 void RSRenderService::DumpRefreshRateCounts(std::string& dumpString) const
475 {
476 dumpString.append("\n");
477 dumpString.append("-- RefreshRateCounts: \n");
478 #ifdef RS_ENABLE_GPU
479 RSHardwareThread::Instance().RefreshRateCounts(dumpString);
480 #endif
481 }
482
DumpClearRefreshRateCounts(std::string & dumpString) const483 void RSRenderService::DumpClearRefreshRateCounts(std::string& dumpString) const
484 {
485 dumpString.append("\n");
486 dumpString.append("-- ClearRefreshRateCounts: \n");
487 #ifdef RS_ENABLE_GPU
488 RSHardwareThread::Instance().ClearRefreshRateCounts(dumpString);
489 #endif
490 }
491
WindowHitchsDump(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const492 void RSRenderService::WindowHitchsDump(
493 std::unordered_set<std::u16string>& argSets, std::string& dumpString, const std::u16string& arg) const
494 {
495 auto iter = argSets.find(arg);
496 if (iter != argSets.end()) {
497 std::string layerArg;
498 argSets.erase(iter);
499 if (!argSets.empty()) {
500 layerArg = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
501 }
502 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
503 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
504 #ifdef RS_ENABLE_GPU
505 RSHardwareThread::Instance().ScheduleTask(
506 [this, &dumpString, &layerArg]() { return screenManager_->HitchsDump(dumpString, layerArg); }).wait();
507 #endif
508 } else {
509 mainThread_->ScheduleTask(
510 [this, &dumpString, &layerArg]() { return screenManager_->HitchsDump(dumpString, layerArg); }).wait();
511 }
512 }
513 }
514
DumpSurfaceNode(std::string & dumpString,NodeId id) const515 void RSRenderService::DumpSurfaceNode(std::string& dumpString, NodeId id) const
516 {
517 dumpString.append("\n");
518 dumpString.append("-- SurfaceNode\n");
519
520 const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
521 auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
522 if (node == nullptr) {
523 dumpString += std::to_string(id) + " is invalid ID\n";
524 return;
525 }
526 dumpString += "ID: " + std::to_string(node->GetId()) + "\n";
527 dumpString += "Name: " + node->GetName() + "\n";
528 dumpString += "SrcRect: [" + std::to_string(node->GetSrcRect().left_) + "," +
529 std::to_string(node->GetSrcRect().top_) + "," +
530 std::to_string(node->GetSrcRect().width_) + "," +
531 std::to_string(node->GetSrcRect().height_) + "]\n";
532 dumpString += "DstRect: [" + std::to_string(node->GetDstRect().left_) + "," +
533 std::to_string(node->GetDstRect().top_) + "," +
534 std::to_string(node->GetDstRect().width_) + "," +
535 std::to_string(node->GetDstRect().height_) + "]\n";
536 dumpString += "CornerRadius: [" + std::to_string(node->GetRenderProperties().GetCornerRadius().x_) + "," +
537 std::to_string(node->GetRenderProperties().GetCornerRadius().y_) + "," +
538 std::to_string(node->GetRenderProperties().GetCornerRadius().z_) + "," +
539 std::to_string(node->GetRenderProperties().GetCornerRadius().w_) + "]\n";
540 dumpString += "Bounds: [" + std::to_string(node->GetRenderProperties().GetBoundsWidth()) + "," +
541 std::to_string(node->GetRenderProperties().GetBoundsHeight()) + "]\n";
542 if (auto& contextClipRegion = node->contextClipRect_) {
543 dumpString += "ContextClipRegion: [" + std::to_string(contextClipRegion->GetWidth()) + "," +
544 std::to_string(contextClipRegion->GetHeight()) + "]\n";
545 } else {
546 dumpString += "ContextClipRegion: [ empty ]\n";
547 }
548 dumpString += "Zorder: " + std::to_string(node->GetRenderProperties().GetPositionZ()) + "\n";
549 dumpString += "IsOnTheTree: " + std::to_string(node->IsOnTheTree()) + "\n";
550 dumpString += "Visible: " + std::to_string(node->GetRenderProperties().GetVisible()) + "\n";
551 dumpString += "OcclusionBg: " + std::to_string(node->GetAbilityBgAlpha())+ "\n";
552 dumpString += "Alpha: " + std::to_string(node->GetRenderProperties().GetAlpha()) +
553 "(include ContextAlpha: " + std::to_string(node->contextAlpha_) + ")\n";
554 dumpString += "GlobalAlpha: " + std::to_string(node->GetGlobalAlpha()) + "\n";
555 dumpString += node->GetVisibleRegion().GetRegionInfo() + "\n";
556 const auto consumer = node->GetRSSurfaceHandler()->GetConsumer();
557 if (consumer == nullptr) {
558 return;
559 }
560 dumpString += "Consumer Info: \n";
561 consumer->Dump(dumpString);
562 }
563
IsNumber(const std::string & type)564 static bool IsNumber(const std::string& type)
565 {
566 auto number = static_cast<uint32_t>(std::count_if(type.begin(), type.end(), [](unsigned char c) {
567 return std::isdigit(c);
568 }));
569 return number == type.length();
570 }
571
ExtractDumpInfo(std::unordered_set<std::u16string> & argSets,std::string & dumpInfo,std::u16string title)572 static bool ExtractDumpInfo(std::unordered_set<std::u16string>& argSets, std::string& dumpInfo, std::u16string title)
573 {
574 if (!RSUniRenderJudgement::IsUniRender()) {
575 dumpInfo.append("\n---------------\n Not in UniRender and no information");
576 return false;
577 }
578 if (argSets.size() < 2) {
579 dumpInfo.append("\n---------------\n no need extract info");
580 return false;
581 }
582 argSets.erase(title);
583 if (!argSets.empty()) {
584 dumpInfo = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
585 }
586 return true;
587 }
588
DumpMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const589 void RSRenderService::DumpMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
590 {
591 std::string type;
592 bool isSuccess = ExtractDumpInfo(argSets, type, u"dumpMem");
593 if (!isSuccess) {
594 return;
595 }
596 int pid = 0;
597 if (!type.empty() && IsNumber(type) && type.length() < 10) {
598 pid = std::atoi(type.c_str());
599 }
600 mainThread_->ScheduleTask(
601 [this, &argSets, &dumpString, &type, &pid]() {
602 return mainThread_->DumpMem(argSets, dumpString, type, pid);
603 }).wait();
604 }
605
DumpNode(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const606 void RSRenderService::DumpNode(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
607 {
608 std::string type;
609 bool isSuccess = ExtractDumpInfo(argSets, type, u"dumpNode");
610 if (!isSuccess) {
611 return;
612 }
613 uint64_t nodeId = 0;
614 if (!type.empty() && IsNumber(type) && type.length() < 20) {
615 nodeId = std::stoull(type);
616 }
617 mainThread_->ScheduleTask(
618 [this, &dumpString, &nodeId]() {
619 return mainThread_->DumpNode(dumpString, nodeId);
620 }).wait();
621
622 }
623
DumpJankStatsRs(std::string & dumpString) const624 void RSRenderService::DumpJankStatsRs(std::string& dumpString) const
625 {
626 dumpString.append("\n");
627 RSJankStats::GetInstance().ReportJankStats();
628 dumpString.append("flush done\n");
629 }
630
631 #ifdef RS_ENABLE_GPU
InitGLES()632 static void InitGLES()
633 {
634 g_tmpDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
635 if (g_tmpDisplay == EGL_NO_DISPLAY) {
636 RS_LOGE("Failed to get default display.");
637 return;
638 }
639 EGLint major, minor;
640 if (eglInitialize(g_tmpDisplay, &major, &minor) == EGL_FALSE) {
641 RS_LOGE("Failed to initialize EGL.");
642 return;
643 }
644
645 EGLint numConfigs = INT_INIT_VAL;
646 EGLConfig config;
647 if (eglChooseConfig(g_tmpDisplay, nullptr, &config, CREAT_NUM_ONE, &numConfigs) == EGL_FALSE || numConfigs < 1) {
648 RS_LOGE("Failed to choose EGL config.");
649 eglTerminate(g_tmpDisplay);
650 return;
651 }
652 const EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, INIT_EGL_VERSION, EGL_NONE };
653 g_tmpContext = eglCreateContext(g_tmpDisplay, config, EGL_NO_CONTEXT, contextAttribs);
654 if (g_tmpContext == EGL_NO_CONTEXT) {
655 RS_LOGE("Failed to create EGL context.");
656 eglTerminate(g_tmpDisplay);
657 return;
658 }
659 if (eglMakeCurrent(g_tmpDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, g_tmpContext) == EGL_FALSE) {
660 RS_LOGE("Failed to make EGL context current.");
661 eglDestroyContext(g_tmpDisplay, g_tmpContext);
662 eglTerminate(g_tmpDisplay);
663 return;
664 }
665 }
666
DestroyGLES()667 static void DestroyGLES()
668 {
669 eglDestroyContext(g_tmpDisplay, g_tmpContext);
670 g_tmpContext = EGL_NO_CONTEXT;
671 eglTerminate(g_tmpDisplay);
672 g_tmpDisplay = EGL_NO_DISPLAY;
673 }
674
DumpGpuInfo(std::string & dumpString) const675 void RSRenderService::DumpGpuInfo(std::string& dumpString) const
676 {
677 InitGLES(); // This is necessary because you cannot query GPU information without initialization.
678 dumpString.append("\n");
679 dumpString.append("-- DumpGpuInfo: \n");
680 auto glVendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
681 auto glRenderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
682 auto glesVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
683 auto glShadingLanguageVersion = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
684 dumpString.append("GL_VENDOR: ");
685 dumpString.append(glVendor ? glVendor : "Unknown");
686 dumpString.append("\n");
687 dumpString.append("GL_RENDERER: ");
688 dumpString.append(glRenderer ? glRenderer : "Unknown");
689 dumpString.append("\n");
690 dumpString.append("GL_VERSION: ");
691 dumpString.append(glesVersion ? glesVersion : "Unknown");
692 dumpString.append("\n");
693 dumpString.append("GL_SHADING_LANGUAGE_VERSION: ");
694 dumpString.append(glShadingLanguageVersion ? glShadingLanguageVersion : "Unknown");
695 dumpString.append("\n");
696 DestroyGLES();
697 }
698 #endif
699
700 #ifdef RS_ENABLE_VK
DumpVkTextureLimit(std::string & dumpString) const701 void RSRenderService::DumpVkTextureLimit(std::string& dumpString) const
702 {
703 dumpString.append("\n");
704 dumpString.append("-- vktextureLimit:\n");
705 auto& vkContext = OHOS::Rosen::RsVulkanContext::GetSingleton().GetRsVulkanInterface();
706 VkPhysicalDevice physicalDevice = vkContext.GetPhysicalDevice();
707 VkPhysicalDeviceProperties deviceProperties;
708 vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
709
710 uint32_t maxTextureWidth = deviceProperties.limits.maxImageDimension2D;
711 uint32_t maxTextureHeight = deviceProperties.limits.maxImageDimension2D;
712 dumpString.append(
713 "width: " + std::to_string(maxTextureWidth) + " height: " + std::to_string(maxTextureHeight) + "\n");
714 }
715 #endif
716
DumpExistPidMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const717 void RSRenderService::DumpExistPidMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
718 {
719 if (!RSUniRenderJudgement::IsUniRender()) {
720 dumpString.append("\n---------------\n Not in UniRender and no information");
721 return;
722 }
723
724 std::string type;
725 if (!argSets.empty()) {
726 type = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
727 }
728 int pid = 0;
729 if (!type.empty() && IsNumber(type)) {
730 pid = std::atoi(type.c_str());
731 MemoryManager::DumpExitPidMem(dumpString, pid);
732 } else {
733 dumpString.append("\n---------------\n Pid is error \n" + type);
734 }
735 }
736
DoDump(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const737 void RSRenderService::DoDump(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
738 {
739 if (!mainThread_ || !screenManager_) {
740 RS_LOGE("RSRenderService::DoDump failed, mainThread, screenManager is nullptr");
741 return;
742 }
743
744 std::string cmdStr;
745 for (const std::u16string &cmd : argSets) {
746 cmdStr += std::string(cmd.begin(), cmd.end()) + " ";
747 }
748 RS_TRACE_NAME("RSRenderService::DoDump args is [ " + cmdStr + " ]");
749
750 RSDumpManager::GetInstance().CmdExec(argSets, dumpString);
751 }
752
RSGfxDumpInit()753 void RSRenderService::RSGfxDumpInit()
754 {
755 RegisterRSGfxFuncs();
756 RegisterRSTreeFuncs();
757 RegisterMemFuncs();
758 RegisterFpsFuncs();
759 RegisterGpuFuncs();
760 }
761
RegisterRSGfxFuncs()762 void RSRenderService::RegisterRSGfxFuncs()
763 {
764 // screen info
765 RSDumpFunc screenInfoFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
766 std::string &dumpString) -> void {
767 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
768 if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
769 #ifdef RS_ENABLE_GPU
770 RSHardwareThread::Instance()
771 .ScheduleTask([this, &dumpString]() { screenManager_->DisplayDump(dumpString); })
772 .wait();
773 #endif
774 } else {
775 mainThread_->ScheduleTask([this, &dumpString]() { screenManager_->DisplayDump(dumpString); }).wait();
776 }
777 };
778
779 // Event Param List
780 RSDumpFunc rsEventParamFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
781 std::string &dumpString) -> void {
782 mainThread_->ScheduleTask([this, &dumpString]() { DumpRSEvenParam(dumpString); }).wait();
783 };
784
785 // rs log flag
786 RSDumpFunc rsLogFlagFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
787 std::string &dumpString) -> void {
788 argSets.erase(cmd);
789 if (!argSets.empty()) {
790 std::string logFlag =
791 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(*argSets.begin());
792 if (RSLogManager::GetInstance().SetRSLogFlag(logFlag)) {
793 dumpString.append("Successed to set flag: " + logFlag + "\n");
794 } else {
795 dumpString.append("Failed to set flag: " + logFlag + "\n");
796 }
797 }
798 };
799
800 // flush Jank Stats
801 RSDumpFunc flushJankStatsRsFunc = [this](const std::u16string &cmd,
802 std::unordered_set<std::u16string> &argSets,
803 std::string &dumpString) -> void {
804 mainThread_->ScheduleTask([this, &dumpString]() { DumpJankStatsRs(dumpString); }).wait();
805 };
806
807 std::vector<RSDumpHander> handers = {
808 { RSDumpID::SCREEN_INFO, screenInfoFunc },
809 { RSDumpID::EVENT_PARAM_LIST, rsEventParamFunc },
810 { RSDumpID::RS_LOG_FLAG, rsLogFlagFunc },
811 { RSDumpID::RS_FLUSH_JANK_STATS, flushJankStatsRsFunc },
812 };
813 RSDumpManager::GetInstance().Register(handers);
814 }
815
RegisterRSTreeFuncs()816 void RSRenderService::RegisterRSTreeFuncs()
817 {
818 // RS not on Tree
819 RSDumpFunc rsNotOnTreeFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
820 std::string &dumpString) -> void {
821 mainThread_->ScheduleTask([this, &dumpString]() { DumpNodesNotOnTheTree(dumpString); }).wait();
822 };
823
824 // RS Tree
825 RSDumpFunc rsTreeFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
826 std::string &dumpString) -> void {
827 mainThread_->ScheduleTask([this, &dumpString]() { DumpRenderServiceTree(dumpString); }).wait();
828 };
829
830 // RS SurfaceNode
831 RSDumpFunc surfaceNodeFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
832 std::string &dumpString) -> void {
833 argSets.erase(cmd);
834 if (!argSets.empty()) {
835 NodeId id =
836 static_cast<NodeId>(std::atoll(std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}
837 .to_bytes(*argSets.begin())
838 .c_str()));
839 mainThread_->ScheduleTask([this, &dumpString, &id]() { return DumpSurfaceNode(dumpString, id); }).wait();
840 }
841 };
842
843 // Multi RS Trees
844 RSDumpFunc multiRSTreesFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
845 std::string &dumpString) -> void {
846 mainThread_->ScheduleTask([this, &dumpString]() { DumpRenderServiceTree(dumpString, false); }).wait();
847 };
848
849 // client tree
850 RSDumpFunc rsClientFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
851 std::string &dumpString) -> void {
852 auto taskId = GenerateTaskId();
853 mainThread_->ScheduleTask([this, taskId]() { mainThread_->SendClientDumpNodeTreeCommands(taskId); }).wait();
854 mainThread_->CollectClientNodeTreeResult(taskId, dumpString, CLIENT_DUMP_TREE_TIMEOUT);
855 };
856
857 // Dump Node
858 RSDumpFunc dumpNodeFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
859 std::string &dumpString) -> void {
860 DumpNode(argSets, dumpString);
861 };
862
863 std::vector<RSDumpHander> handers = {
864 { RSDumpID::RS_NOT_ON_TREE_INFO, rsNotOnTreeFunc },
865 { RSDumpID::RENDER_NODE_INFO, rsTreeFunc, RS_MAIN_THREAD_TAG },
866 { RSDumpID::SURFACENODE_INFO, surfaceNodeFunc },
867 { RSDumpID::MULTI_RSTREES_INFO, multiRSTreesFunc },
868 { RSDumpID::CLIENT_INFO, rsClientFunc, RS_CLIENT_TAG },
869 { RSDumpID::RS_RENDER_NODE_INFO, dumpNodeFunc },
870 };
871
872 RSDumpManager::GetInstance().Register(handers);
873 }
874
RegisterMemFuncs()875 void RSRenderService::RegisterMemFuncs()
876 {
877 // surface info
878 RSDumpFunc surfaceInfoFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
879 std::string &dumpString) -> void {
880 mainThread_->ScheduleTask([this, &dumpString]() { return screenManager_->SurfaceDump(dumpString); }).wait();
881 };
882
883 // surface mem
884 RSDumpFunc surfaceMemFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
885 std::string &dumpString) -> void {
886 mainThread_->ScheduleTask([this, &dumpString]() { DumpAllNodesMemSize(dumpString); }).wait();
887 };
888
889 // trim mem
890 RSDumpFunc trimMemFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
891 std::string &dumpString) -> void {
892 mainThread_->ScheduleTask([this, &argSets, &dumpString]() { return mainThread_->TrimMem(argSets, dumpString); })
893 .wait();
894 };
895
896 // Mem
897 RSDumpFunc memDumpFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
898 std::string &dumpString) -> void {
899 DumpMem(argSets, dumpString);
900 };
901
902 // pid mem
903 RSDumpFunc existPidMemFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
904 std::string &dumpString) -> void {
905 argSets.erase(cmd);
906 DumpExistPidMem(argSets, dumpString);
907 };
908
909 std::vector<RSDumpHander> handers = {
910 { RSDumpID::SURFACE_INFO, surfaceInfoFunc, RS_HW_THREAD_TAG },
911 { RSDumpID::SURFACE_MEM_INFO, surfaceMemFunc },
912 { RSDumpID::TRIM_MEM_INFO, trimMemFunc },
913 { RSDumpID::MEM_INFO, memDumpFunc },
914 { RSDumpID::EXIST_PID_MEM_INFO, existPidMemFunc },
915 };
916
917 RSDumpManager::GetInstance().Register(handers);
918 }
919
RegisterFpsFuncs()920 void RSRenderService::RegisterFpsFuncs()
921 {
922 // fps info cmd, [windowname]/composer fps
923 RSDumpFunc fpsInfoFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
924 std::string &dumpString) -> void {
925 FPSDUMPProcess(argSets, dumpString, cmd);
926 };
927
928 // fps clear cmd : [surface name]/composer fpsClear
929 RSDumpFunc fpsClearFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
930 std::string &dumpString) -> void {
931 FPSDUMPClearProcess(argSets, dumpString, cmd);
932 };
933
934 // fps count
935 RSDumpFunc fpsCountFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
936 std::string &dumpString) -> void {
937 mainThread_->ScheduleTask([this, &dumpString]() { DumpRefreshRateCounts(dumpString); }).wait();
938 };
939
940 // clear fps Count
941 RSDumpFunc clearFpsCountFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
942 std::string &dumpString) -> void {
943 mainThread_->ScheduleTask([this, &dumpString]() { DumpClearRefreshRateCounts(dumpString); }).wait();
944 };
945
946 // [windowname] hitchs
947 RSDumpFunc hitchsFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
948 std::string &dumpString) -> void {
949 WindowHitchsDump(argSets, dumpString, cmd);
950 };
951
952 std::vector<RSDumpHander> handers = {
953 { RSDumpID::FPS_INFO, fpsInfoFunc }, { RSDumpID::FPS_CLEAR, fpsClearFunc },
954 { RSDumpID::FPS_COUNT, fpsCountFunc }, { RSDumpID::CLEAR_FPS_COUNT, clearFpsCountFunc },
955 { RSDumpID::HITCHS, hitchsFunc },
956 };
957
958 RSDumpManager::GetInstance().Register(handers);
959 }
960
RegisterGpuFuncs()961 void RSRenderService::RegisterGpuFuncs()
962 {
963 // gpu info
964 RSDumpFunc gpuInfoFunc = [this](const std::u16string &cmd, std::unordered_set<std::u16string> &argSets,
965 std::string &dumpString) -> void {
966 mainThread_->ScheduleTask([this, &dumpString]() { DumpGpuInfo(dumpString); }).wait();
967 };
968
969 #ifdef RS_ENABLE_VK
970 // vk texture Limit
971 RSDumpFunc vktextureLimitFunc = [this](const std::u16string &cmd,
972 std::unordered_set<std::u16string> &argSets,
973 std::string &dumpString) -> void {
974 mainThread_->ScheduleTask([this, &dumpString]() { DumpVkTextureLimit(dumpString); }).wait();
975 };
976 #endif
977
978 std::vector<RSDumpHander> handers = {
979 { RSDumpID::GPU_INFO, gpuInfoFunc },
980 #ifdef RS_ENABLE_VK
981 { RSDumpID::VK_TEXTURE_LIMIT, vktextureLimitFunc },
982 #endif
983 };
984
985 RSDumpManager::GetInstance().Register(handers);
986 }
987
988 // need called after GraphicFeatureParamManager::GetInstance().Init();
FilterCCMInit()989 void RSRenderService::FilterCCMInit()
990 {
991 auto filterParam = GraphicFeatureParamManager::GetInstance().featureParamMap_[FEATURE_CONFIGS[FILTER]];
992 if (filterParam == nullptr) {
993 return;
994 }
995 RSFilterCacheManager::isCCMFilterCacheEnable_ =
996 std::static_pointer_cast<FilterParam>(filterParam)->IsFilterCacheEnable();
997 RSFilterCacheManager::isCCMEffectMergeEnable_ =
998 std::static_pointer_cast<FilterParam>(filterParam)->IsEffectMergeEnable();
999 RSProperties::SetFilterCacheEnabledByCCM(RSFilterCacheManager::isCCMFilterCacheEnable_);
1000 }
1001 } // namespace Rosen
1002 } // namespace OHOS
1003