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