• 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 #include "rs_main_thread.h"
18 #include "rs_qos_thread.h"
19 #include "rs_render_service_connection.h"
20 #include "vsync_generator.h"
21 #include "pipeline/rs_surface_render_node.h"
22 #include "pipeline/rs_uni_render_judgement.h"
23 #include "pipeline/rs_hardware_thread.h"
24 
25 #include <string>
26 #include <unistd.h>
27 
28 #include <iservice_registry.h>
29 #include <platform/common/rs_log.h>
30 #include <system_ability_definition.h>
31 #include "parameter.h"
32 
33 namespace OHOS {
34 namespace Rosen {
35 namespace {
36     constexpr uint32_t UNI_RENDER_VSYNC_OFFSET = 5000000;
37 }
RSRenderService()38 RSRenderService::RSRenderService() {}
39 
~RSRenderService()40 RSRenderService::~RSRenderService() noexcept {}
41 
Init()42 bool RSRenderService::Init()
43 {
44     RSMainThread::Instance();
45     RSUniRenderJudgement::InitUniRenderConfig();
46     screenManager_ = CreateOrGetScreenManager();
47     if (RSUniRenderJudgement::GetUniRenderEnabledType() != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
48         // screenManager initializtion executes in RSHHardwareThread under UNI_RENDER mode
49         if (screenManager_ == nullptr || !screenManager_->Init()) {
50             RS_LOGE("RSRenderService CreateOrGetScreenManager fail.");
51             return false;
52         }
53     } else {
54         RSHardwareThread::Instance().Start();
55     }
56 
57     auto generator = CreateVSyncGenerator();
58 
59     // The offset needs to be set
60     int64_t offset = 0;
61     auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
62     if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
63         offset = UNI_RENDER_VSYNC_OFFSET;
64     }
65     rsVSyncController_ = new VSyncController(generator, offset);
66     appVSyncController_ = new VSyncController(generator, offset);
67     rsVSyncDistributor_ = new VSyncDistributor(rsVSyncController_, "rs");
68     appVSyncDistributor_ = new VSyncDistributor(appVSyncController_, "app");
69 
70     mainThread_ = RSMainThread::Instance();
71     if (mainThread_ == nullptr) {
72         return false;
73     }
74     mainThread_->rsVSyncDistributor_ = rsVSyncDistributor_;
75     mainThread_->Init();
76 
77     RSQosThread::GetInstance()->appVSyncDistributor_ = appVSyncDistributor_;
78     RSQosThread::ThreadStart();
79 
80     // Wait samgr ready for up to 5 second to ensure adding service to samgr.
81     int status = WaitParameter("bootevent.samgr.ready", "true", 5);
82     if (status != 0) {
83         RS_LOGE("RSRenderService wait SAMGR error, return value [%d].", status);
84     }
85 
86     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
87     if (samgr == nullptr) {
88         RS_LOGE("RSRenderService GetSystemAbilityManager fail.");
89         return false;
90     }
91     samgr->AddSystemAbility(RENDER_SERVICE, this);
92 
93     return true;
94 }
95 
Run()96 void RSRenderService::Run()
97 {
98     RS_LOGE("RSRenderService::Run");
99     mainThread_->Start();
100 }
101 
CreateConnection(const sptr<RSIConnectionToken> & token)102 sptr<RSIRenderServiceConnection> RSRenderService::CreateConnection(const sptr<RSIConnectionToken>& token)
103 {
104     pid_t remotePid = GetCallingPid();
105 
106     auto tokenObj = token->AsObject();
107     sptr<RSIRenderServiceConnection> newConn(
108         new RSRenderServiceConnection(remotePid, this, mainThread_, screenManager_, tokenObj, appVSyncDistributor_));
109 
110     sptr<RSIRenderServiceConnection> tmp;
111     std::unique_lock<std::mutex> lock(mutex_);
112     // if connections_ has the same token one, replace it.
113     if (connections_.count(tokenObj) > 0) {
114         tmp = connections_.at(tokenObj);
115     }
116     connections_[tokenObj] = newConn;
117     lock.unlock();
118     mainThread_->AddTransactionDataPidInfo(remotePid);
119     return newConn;
120 }
121 
RemoveConnection(sptr<IRemoteObject> token)122 void RSRenderService::RemoveConnection(sptr<IRemoteObject> token)
123 {
124     std::unique_lock<std::mutex> lock(mutex_);
125     if (connections_.count(token) == 0) {
126         return;
127     }
128 
129     auto tmp = connections_.at(token);
130     connections_.erase(token);
131     lock.unlock();
132 }
133 
Dump(int fd,const std::vector<std::u16string> & args)134 int RSRenderService::Dump(int fd, const std::vector<std::u16string>& args)
135 {
136     std::unordered_set<std::u16string> argSets;
137     for (decltype(args.size()) index = 0; index < args.size(); ++index) {
138         argSets.insert(args[index]);
139     }
140     if (screenManager_ == nullptr) {
141         return OHOS::INVALID_OPERATION;
142     }
143     std::string dumpString;
144     DoDump(argSets, dumpString);
145     if (dumpString.size() == 0) {
146         return OHOS::INVALID_OPERATION;
147     }
148     write(fd, dumpString.c_str(), dumpString.size());
149     return OHOS::NO_ERROR;
150 }
151 
DumpNodesNotOnTheTree(std::string & dumpString) const152 void RSRenderService::DumpNodesNotOnTheTree(std::string& dumpString) const
153 {
154     dumpString.append("\n");
155     dumpString.append("-- Node Not On Tree\n");
156 
157     const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
158     nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
159         if (node == nullptr) {
160             return;
161         }
162 
163         if (node->IsInstanceOf<RSSurfaceRenderNode>() && !node->IsOnTheTree()) {
164             const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
165             dumpString += "\n node Id[" + std::to_string(node->GetId()) + "]:\n";
166             const auto& surfaceConsumer = surfaceNode->GetConsumer();
167             if (surfaceConsumer == nullptr) {
168                 return;
169             }
170             surfaceConsumer->Dump(dumpString);
171         }
172     });
173 }
174 
DumpAllNodesMemSize(std::string & dumpString) const175 void RSRenderService::DumpAllNodesMemSize(std::string& dumpString) const
176 {
177     dumpString.append("\n");
178     dumpString.append("-- All Surfaces Memory Size\n");
179     dumpString.append("the memory size of all surfaces buffer is : dumpend");
180 
181     const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
182     nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
183         if (node == nullptr || !node->IsInstanceOf<RSSurfaceRenderNode>()) {
184             return;
185         }
186 
187         const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
188         const auto& surfaceConsumer = surfaceNode->GetConsumer();
189         if (surfaceConsumer == nullptr) {
190             return;
191         }
192 
193         surfaceConsumer->Dump(dumpString);
194     });
195 }
196 
DumpHelpInfo(std::string & dumpString) const197 void RSRenderService::DumpHelpInfo(std::string& dumpString) const
198 {
199     dumpString.append("------Graphic2D--RenderSerice ------\n")
200         .append("Usage:\n")
201         .append(" h                             ")
202         .append("|help text for the tool\n")
203         .append("screen                         ")
204         .append("|dump all screen infomation in the system\n")
205         .append("surface                        ")
206         .append("|dump all surface information\n")
207         .append("composer fps                   ")
208         .append("|dump the fps info of composer\n")
209         .append("[surface name] fps             ")
210         .append("|dump the fps info of surface\n")
211         .append("composer fpsClear                   ")
212         .append("|clear the fps info of composer\n")
213         .append("[surface name] fpsClear             ")
214         .append("|clear the fps info of surface\n")
215         .append("nodeNotOnTree                  ")
216         .append("|dump nodeNotOnTree info\n")
217         .append("allSurfacesMem                 ")
218         .append("|dump surface mem info\n")
219         .append("RSTree                         ")
220         .append("|dump RSTree info\n")
221         .append("EventParamList                 ")
222         .append("|dump EventParamList info\n")
223         .append("allInfo                        ")
224         .append("|dump all info\n")
225         .append("dumpMem                        ")
226         .append("|dump Cache\n")
227         .append("trimMem cpu/gpu/shader         ")
228         .append("|release Cache\n")
229         .append("surfacenode [id]               ")
230         .append("|dump node info\n");
231 }
232 
FPSDUMPProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const233 void RSRenderService::FPSDUMPProcess(std::unordered_set<std::u16string>& argSets,
234     std::string& dumpString, const std::u16string& arg) const
235 {
236     auto iter = argSets.find(arg);
237     if (iter != argSets.end()) {
238         std::string layerArg;
239         argSets.erase(iter);
240         if (!argSets.empty()) {
241             layerArg = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
242         }
243         auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
244         if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
245             RSHardwareThread::Instance().ScheduleTask(
246                 [this, &dumpString, &layerArg]() { return screenManager_->FpsDump(dumpString, layerArg); }).wait();
247         } else {
248             mainThread_->ScheduleTask(
249                 [this, &dumpString, &layerArg]() { return screenManager_->FpsDump(dumpString, layerArg); }).wait();
250         }
251     }
252 }
253 
FPSDUMPClearProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const254 void RSRenderService::FPSDUMPClearProcess(std::unordered_set<std::u16string>& argSets,
255     std::string& dumpString, const std::u16string& arg) const
256 {
257     auto iter = argSets.find(arg);
258     if (iter != argSets.end()) {
259         std::string layerArg;
260         argSets.erase(iter);
261         if (!argSets.empty()) {
262             layerArg = std::wstring_convert<
263             std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
264         }
265         auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
266         if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
267             RSHardwareThread::Instance().ScheduleTask(
268                 [this, &dumpString, &layerArg]() {
269                     return screenManager_->ClearFpsDump(dumpString, layerArg);
270                 }).wait();
271         } else {
272             mainThread_->ScheduleTask(
273                 [this, &dumpString, &layerArg]() {
274                     return screenManager_->ClearFpsDump(dumpString, layerArg);
275                 }).wait();
276         }
277     }
278 }
279 
DumpRSEvenParam(std::string & dumpString) const280 void RSRenderService::DumpRSEvenParam(std::string& dumpString) const
281 {
282     dumpString.append("\n");
283     dumpString.append("-- EventParamListDump: \n");
284     mainThread_->RsEventParamDump(dumpString);
285     dumpString.append("-- QosDump: \n");
286     mainThread_->QosStateDump(dumpString);
287 }
288 
DumpRenderServiceTree(std::string & dumpString) const289 void RSRenderService::DumpRenderServiceTree(std::string& dumpString) const
290 {
291     dumpString.append("\n");
292     dumpString.append("-- RenderServiceTreeDump: \n");
293     mainThread_->RenderServiceTreeDump(dumpString);
294 }
295 
DumpSurfaceNode(std::string & dumpString,NodeId id) const296 void RSRenderService::DumpSurfaceNode(std::string& dumpString, NodeId id) const
297 {
298     dumpString.append("\n");
299     dumpString.append("-- SurfaceNode\n");
300 
301     const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
302     auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
303     if (node == nullptr) {
304         dumpString +=  std::to_string(id) + " is invalid ID\n";
305         return;
306     }
307     dumpString += "ID: " + std::to_string(node->GetId()) + "\n";
308     dumpString += "Name: " + node->GetName() + "\n";
309     dumpString += "SrcRect: [" + std::to_string(node->GetSrcRect().left_) + "," +
310         std::to_string(node->GetSrcRect().top_) + "," +
311         std::to_string(node->GetSrcRect().width_) + "," +
312         std::to_string(node->GetSrcRect().height_) + "]\n";
313     dumpString += "DstRect: [" + std::to_string(node->GetDstRect().left_) + "," +
314         std::to_string(node->GetDstRect().top_) + "," +
315         std::to_string(node->GetDstRect().width_) + "," +
316         std::to_string(node->GetDstRect().height_) + "]\n";
317     dumpString += "CornerRadius: [" + std::to_string(node->GetRenderProperties().GetCornerRadius().x_) + "," +
318         std::to_string(node->GetRenderProperties().GetCornerRadius().y_) + "," +
319         std::to_string(node->GetRenderProperties().GetCornerRadius().z_) + "," +
320         std::to_string(node->GetRenderProperties().GetCornerRadius().w_) + "]\n";
321     dumpString += "Bounds: [" + std::to_string(node->GetRenderProperties().GetBoundsWidth()) + "," +
322         std::to_string(node->GetRenderProperties().GetBoundsHeight()) + "]\n";
323     if (auto& contextClipRegion = node->contextClipRect_) {
324 #ifndef USE_ROSEN_DRAWING
325         dumpString += "ContextClipRegion: [" + std::to_string(contextClipRegion->width()) + "," +
326                       std::to_string(contextClipRegion->height()) + "]\n";
327 #else
328         dumpString += "ContextClipRegion: [" + std::to_string(contextClipRegion->GetWidth()) + "," +
329                       std::to_string(contextClipRegion->GetHeight()) + "]\n";
330 #endif
331     } else {
332         dumpString += "ContextClipRegion: [ empty ]\n";
333     }
334     dumpString += "Zorder: " + std::to_string(node->GetRenderProperties().GetPositionZ()) + "\n";
335     dumpString += "IsOnTheTree: " + std::to_string(node->IsOnTheTree()) + "\n";
336     dumpString += "Visible: " + std::to_string(node->GetRenderProperties().GetVisible()) + "\n";
337     dumpString += "OcclusionBg: " + std::to_string(node->GetAbilityBgAlpha())+ "\n";
338     dumpString += "Alpha: " + std::to_string(node->GetRenderProperties().GetAlpha()) +
339                   "(include ContextAlpha: " + std::to_string(node->contextAlpha_) + ")\n";
340     dumpString += "GlobalAlpha: " + std::to_string(node->GetGlobalAlpha()) + "\n";
341     dumpString += node->GetVisibleRegion().GetRegionInfo() + "\n";
342     const auto& consumer = node->GetConsumer();
343     if (consumer == nullptr) {
344         return;
345     }
346     dumpString += "Consumer Info: \n";
347     consumer->Dump(dumpString);
348 }
349 
IsNumber(const std::string & type)350 static bool IsNumber(const std::string& type)
351 {
352     auto number = static_cast<uint32_t>(std::count_if(type.begin(), type.end(), [](unsigned char c) {
353         return std::isdigit(c);
354     }));
355     return number == type.length();
356 }
357 
DumpMem(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const358 void RSRenderService::DumpMem(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
359 {
360     if (!RSUniRenderJudgement::IsUniRender()) {
361         dumpString.append("\n---------------\nNot in UniRender and no information");
362     } else {
363         std::string type;
364         if (argSets.size() > 1) {
365             argSets.erase(u"dumpMem");
366             if (!argSets.empty()) {
367                 type = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
368             }
369         }
370         int pid = 0;
371         if (!type.empty() && IsNumber(type)) {
372             pid = std::stoi(type);
373         }
374         mainThread_->ScheduleTask(
375             [this, &argSets, &dumpString, &type, &pid]() {
376                 return mainThread_->DumpMem(argSets, dumpString, type, pid);
377             }).wait();
378         return;
379     }
380 }
381 
DoDump(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const382 void RSRenderService::DoDump(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
383 {
384     std::u16string arg1(u"screen");
385     std::u16string arg2(u"surface");
386     std::u16string arg3(u"fps");
387     std::u16string arg4(u"nodeNotOnTree");
388     std::u16string arg5(u"allSurfacesMem");
389     std::u16string arg6(u"RSTree");
390     std::u16string arg7(u"EventParamList");
391     std::u16string arg8(u"h");
392     std::u16string arg9(u"allInfo");
393     std::u16string arg10(u"trimMem");
394     std::u16string arg11(u"dumpMem");
395     std::u16string arg12(u"surfacenode");
396     std::u16string arg13(u"fpsClear");
397     if (argSets.count(arg9) || argSets.count(arg1) != 0) {
398         auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
399         if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
400             RSHardwareThread::Instance().ScheduleTask(
401                 [this, &dumpString]() { screenManager_->DisplayDump(dumpString); }).wait();
402         } else {
403             mainThread_->ScheduleTask(
404                 [this, &dumpString]() { screenManager_->DisplayDump(dumpString); }).wait();
405         }
406     }
407     if (argSets.count(arg9) || argSets.count(arg2) != 0) {
408         mainThread_->ScheduleTask(
409             [this, &dumpString]() { return screenManager_->SurfaceDump(dumpString); }).wait();
410     }
411     if (argSets.count(arg9) || argSets.count(arg4) != 0) {
412         mainThread_->ScheduleTask(
413             [this, &dumpString]() { DumpNodesNotOnTheTree(dumpString); }).wait();
414     }
415     if (argSets.count(arg9) || argSets.count(arg5) != 0) {
416         mainThread_->ScheduleTask(
417             [this, &dumpString]() { DumpAllNodesMemSize(dumpString); }).wait();
418     }
419     if (argSets.count(arg9) || argSets.count(arg6) != 0) {
420         mainThread_->ScheduleTask(
421             [this, &dumpString]() { DumpRenderServiceTree(dumpString); }).wait();
422     }
423     if (argSets.count(arg9) ||argSets.count(arg7) != 0) {
424         mainThread_->ScheduleTask(
425             [this, &dumpString]() { DumpRSEvenParam(dumpString); }).wait();
426     }
427     if (argSets.count(arg10)) {
428         mainThread_->ScheduleTask(
429             [this, &argSets, &dumpString]() { return mainThread_->TrimMem(argSets, dumpString); }).wait();
430     }
431     if (argSets.count(arg11)) {
432         DumpMem(argSets, dumpString);
433     }
434     if (auto iter = argSets.find(arg12) != argSets.end()) {
435         argSets.erase(arg12);
436         if (!argSets.empty()) {
437             NodeId id = static_cast<NodeId>(std::atoll(std::wstring_convert<
438                 std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(*argSets.begin()).c_str()));
439             mainThread_->ScheduleTask(
440                 [this, &dumpString, &id]() { return DumpSurfaceNode(dumpString, id); }).wait();
441         }
442     }
443     FPSDUMPProcess(argSets, dumpString, arg3);
444     FPSDUMPClearProcess(argSets, dumpString, arg13);
445     if (argSets.size() == 0 || argSets.count(arg8) != 0 || dumpString.empty()) {
446         mainThread_->ScheduleTask(
447             [this, &dumpString]() { DumpHelpInfo(dumpString); }).wait();
448     }
449 }
450 } // namespace Rosen
451 } // namespace OHOS
452