• 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 
24 #include <string>
25 #include <unistd.h>
26 
27 #include <iservice_registry.h>
28 #include <platform/common/rs_log.h>
29 #include <system_ability_definition.h>
30 #include "parameter.h"
31 
32 namespace OHOS {
33 namespace Rosen {
34 namespace {
35     constexpr uint32_t UNI_RENDER_VSYNC_OFFSET = 10000000;
36 }
RSRenderService()37 RSRenderService::RSRenderService() {}
38 
~RSRenderService()39 RSRenderService::~RSRenderService() noexcept {}
40 
Init()41 bool RSRenderService::Init()
42 {
43     RSUniRenderJudgement::InitUniRenderConfig();
44     screenManager_ = CreateOrGetScreenManager();
45     if (screenManager_ == nullptr || !screenManager_->Init()) {
46         RS_LOGE("RSRenderService CreateOrGetScreenManager fail.");
47         return false;
48     }
49 
50     auto generator = CreateVSyncGenerator();
51 
52     // The offset needs to be set
53     int64_t offset = 0;
54     auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
55     if (renderType == UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL ||
56         renderType == UniRenderEnabledType::UNI_RENDER_DYNAMIC_SWITCH) {
57         offset = UNI_RENDER_VSYNC_OFFSET;
58     }
59     rsVSyncController_ = new VSyncController(generator, offset);
60     appVSyncController_ = new VSyncController(generator, offset);
61     rsVSyncDistributor_ = new VSyncDistributor(rsVSyncController_, "rs");
62     appVSyncDistributor_ = new VSyncDistributor(appVSyncController_, "app");
63 
64     mainThread_ = RSMainThread::Instance();
65     if (mainThread_ == nullptr) {
66         return false;
67     }
68     mainThread_->rsVSyncDistributor_ = rsVSyncDistributor_;
69     mainThread_->Init();
70 
71     RSQosThread::GetInstance()->appVSyncDistributor_ = appVSyncDistributor_;
72     RSQosThread::ThreadStart();
73 
74     // Wait samgr ready for up to 5 second to ensure adding service to samgr.
75     int status = WaitParameter("bootevent.samgr.ready", "true", 5);
76     if (status != 0) {
77         RS_LOGE("RSRenderService wait SAMGR error, return value [%d].", status);
78     }
79 
80     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
81     if (samgr == nullptr) {
82         RS_LOGE("RSRenderService GetSystemAbilityManager fail.");
83         return false;
84     }
85     samgr->AddSystemAbility(RENDER_SERVICE, this);
86 
87     return true;
88 }
89 
Run()90 void RSRenderService::Run()
91 {
92     RS_LOGE("RSRenderService::Run");
93     mainThread_->Start();
94 }
95 
CreateConnection(const sptr<RSIConnectionToken> & token)96 sptr<RSIRenderServiceConnection> RSRenderService::CreateConnection(const sptr<RSIConnectionToken>& token)
97 {
98     pid_t remotePid = GetCallingPid();
99 
100     auto tokenObj = token->AsObject();
101     sptr<RSIRenderServiceConnection> newConn(
102         new RSRenderServiceConnection(remotePid, this, mainThread_, screenManager_, tokenObj, appVSyncDistributor_));
103 
104     sptr<RSIRenderServiceConnection> tmp;
105     std::unique_lock<std::mutex> lock(mutex_);
106     // if connections_ has the same token one, replace it.
107     if (connections_.count(tokenObj) > 0) {
108         tmp = connections_.at(tokenObj);
109     }
110     connections_[tokenObj] = newConn;
111     lock.unlock();
112     mainThread_->AddTransactionDataPidInfo(remotePid);
113     return newConn;
114 }
115 
RemoveConnection(sptr<IRemoteObject> token)116 void RSRenderService::RemoveConnection(sptr<IRemoteObject> token)
117 {
118     std::unique_lock<std::mutex> lock(mutex_);
119     if (connections_.count(token) == 0) {
120         return;
121     }
122 
123     auto tmp = connections_.at(token);
124     connections_.erase(token);
125     lock.unlock();
126 }
127 
Dump(int fd,const std::vector<std::u16string> & args)128 int RSRenderService::Dump(int fd, const std::vector<std::u16string>& args)
129 {
130     std::unordered_set<std::u16string> argSets;
131     for (decltype(args.size()) index = 0; index < args.size(); ++index) {
132         argSets.insert(args[index]);
133     }
134     if (screenManager_ == nullptr) {
135         return OHOS::INVALID_OPERATION;
136     }
137     std::string dumpString;
138     DoDump(argSets, dumpString);
139     if (dumpString.size() == 0) {
140         return OHOS::INVALID_OPERATION;
141     }
142     write(fd, dumpString.c_str(), dumpString.size());
143     return OHOS::NO_ERROR;
144 }
145 
DumpNodesNotOnTheTree(std::string & dumpString) const146 void RSRenderService::DumpNodesNotOnTheTree(std::string& dumpString) const
147 {
148     dumpString.append("\n");
149     dumpString.append("-- Node Not On Tree\n");
150 
151     const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
152     nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
153         if (node == nullptr) {
154             return;
155         }
156 
157         if (node->IsInstanceOf<RSSurfaceRenderNode>() && !node->IsOnTheTree()) {
158             const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
159             dumpString += "\n node Id[" + std::to_string(node->GetId()) + "]:\n";
160             const auto& surfaceConsumer = surfaceNode->GetConsumer();
161             if (surfaceConsumer == nullptr) {
162                 return;
163             }
164             surfaceConsumer->Dump(dumpString);
165         }
166     });
167 }
168 
DumpAllNodesMemSize(std::string & dumpString) const169 void RSRenderService::DumpAllNodesMemSize(std::string& dumpString) const
170 {
171     dumpString.append("\n");
172     dumpString.append("-- All Surfaces Memory Size\n");
173     dumpString.append("the memory size of all surfaces buffer is : dumpend");
174 
175     const auto& nodeMap = mainThread_->GetContext().GetNodeMap();
176     nodeMap.TraversalNodes([&dumpString](const std::shared_ptr<RSBaseRenderNode>& node) {
177         if (node == nullptr || !node->IsInstanceOf<RSSurfaceRenderNode>()) {
178             return;
179         }
180 
181         const auto& surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(node);
182         const auto& surfaceConsumer = surfaceNode->GetConsumer();
183         if (surfaceConsumer == nullptr) {
184             return;
185         }
186 
187         surfaceConsumer->Dump(dumpString);
188     });
189 }
190 
DumpHelpInfo(std::string & dumpString) const191 void RSRenderService::DumpHelpInfo(std::string& dumpString) const
192 {
193     dumpString.append("------Graphic2D--RenderSerice ------\n")
194         .append("Usage:\n")
195         .append(" h                             ")
196         .append("|help text for the tool\n")
197         .append("screen                         ")
198         .append("|dump all screen infomation in the system\n")
199         .append("surface                        ")
200         .append("|dump all surface information\n")
201         .append("composer fps                   ")
202         .append("|dump the fps info of composer\n")
203         .append("[surface name] fps             ")
204         .append("|dump the fps info of surface\n")
205         .append("composer fpsClear                   ")
206         .append("|clear the fps info of composer\n")
207         .append("[surface name] fpsClear             ")
208         .append("|clear the fps info of surface\n")
209         .append("nodeNotOnTree                  ")
210         .append("|dump nodeNotOnTree info\n")
211         .append("allSurfacesMem                 ")
212         .append("|dump surface mem info\n")
213         .append("RSTree                         ")
214         .append("|dump RSTree info\n")
215         .append("EventParamList                 ")
216         .append("|dump EventParamList info\n")
217         .append("allInfo                        ")
218         .append("|dump all info\n");
219 }
220 
FPSDUMPProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const221 void RSRenderService::FPSDUMPProcess(std::unordered_set<std::u16string>& argSets,
222     std::string& dumpString, const std::u16string& arg) const
223 {
224     auto iter = argSets.find(arg);
225     if (iter != argSets.end()) {
226         std::string layerArg;
227         argSets.erase(iter);
228         if (!argSets.empty()) {
229             layerArg = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
230         }
231         mainThread_->ScheduleTask([this, &dumpString, &layerArg]() {
232             return screenManager_->FpsDump(dumpString, layerArg);
233         }).wait();
234     }
235 }
236 
FPSDUMPClearProcess(std::unordered_set<std::u16string> & argSets,std::string & dumpString,const std::u16string & arg) const237 void RSRenderService::FPSDUMPClearProcess(std::unordered_set<std::u16string>& argSets,
238     std::string& dumpString, const std::u16string& arg) const
239 {
240     auto iter = argSets.find(arg);
241     if (iter != argSets.end()) {
242         std::string layerArg;
243         argSets.erase(iter);
244         if (!argSets.empty()) {
245             layerArg = std::wstring_convert<
246             std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(*argSets.begin());
247         }
248         mainThread_->ScheduleTask([this, &dumpString, &layerArg]() {
249             return screenManager_->ClearFpsDump(dumpString, layerArg);
250         }).wait();
251     }
252 }
253 
DumpRSEvenParam(std::string & dumpString) const254 void RSRenderService::DumpRSEvenParam(std::string& dumpString) const
255 {
256     dumpString.append("\n");
257     dumpString.append("-- EventParamListDump: \n");
258     mainThread_->RsEventParamDump(dumpString);
259     dumpString.append("-- QosDump: \n");
260     mainThread_->QosStateDump(dumpString);
261 }
262 
DumpRenderServiceTree(std::string & dumpString) const263 void RSRenderService::DumpRenderServiceTree(std::string& dumpString) const
264 {
265     dumpString.append("\n");
266     dumpString.append("-- RenderServiceTreeDump: \n");
267     mainThread_->RenderServiceTreeDump(dumpString);
268 }
269 
DoDump(std::unordered_set<std::u16string> & argSets,std::string & dumpString) const270 void RSRenderService::DoDump(std::unordered_set<std::u16string>& argSets, std::string& dumpString) const
271 {
272     std::u16string arg1(u"screen");
273     std::u16string arg2(u"surface");
274     std::u16string arg3(u"fps");
275     std::u16string arg4(u"nodeNotOnTree");
276     std::u16string arg5(u"allSurfacesMem");
277     std::u16string arg6(u"RSTree");
278     std::u16string arg7(u"EventParamList");
279     std::u16string arg8(u"h");
280     std::u16string arg9(u"allInfo");
281     std::u16string arg13(u"fpsClear");
282     if (argSets.count(arg9) || argSets.count(arg1) != 0) {
283         mainThread_->ScheduleTask([this, &dumpString]() {
284             screenManager_->DisplayDump(dumpString);
285         }).wait();
286     }
287     if (argSets.count(arg9) || argSets.count(arg2) != 0) {
288         mainThread_->ScheduleTask([this, &dumpString]() {
289             return screenManager_->SurfaceDump(dumpString);
290         }).wait();
291     }
292     if (argSets.count(arg9) || argSets.count(arg4) != 0) {
293         mainThread_->ScheduleTask([this, &dumpString]() {
294             DumpNodesNotOnTheTree(dumpString);
295         }).wait();
296     }
297     if (argSets.count(arg9) || argSets.count(arg5) != 0) {
298         mainThread_->ScheduleTask([this, &dumpString]() {
299             DumpAllNodesMemSize(dumpString);
300         }).wait();
301     }
302     if (argSets.count(arg9) || argSets.count(arg6) != 0) {
303         mainThread_->ScheduleTask([this, &dumpString]() {
304             DumpRenderServiceTree(dumpString);
305         }).wait();
306     }
307     if (argSets.count(arg9) ||argSets.count(arg7) != 0) {
308         mainThread_->ScheduleTask([this, &dumpString]() {
309             DumpRSEvenParam(dumpString);
310         }).wait();
311     }
312     FPSDUMPProcess(argSets, dumpString, arg3);
313     FPSDUMPClearProcess(argSets, dumpString, arg13);
314     if (argSets.size() == 0 || argSets.count(arg8) != 0 || dumpString.empty()) {
315         mainThread_->ScheduleTask([this, &dumpString]() {
316             DumpHelpInfo(dumpString);
317         }).wait();
318     }
319 }
320 } // namespace Rosen
321 } // namespace OHOS
322