• 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 
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