• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "rs_render_service.h"
17 
18 #include <iservice_registry.h>
19 #include <malloc.h>
20 #include <parameters.h>
21 #include <platform/common/rs_log.h>
22 #include "platform/common/rs_system_properties.h"
23 #include <string>
24 #include <system_ability_definition.h>
25 #include <unistd.h>
26 
27 #include "hgm_core.h"
28 #include "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