1 /*
2 * Copyright (c) 2022-2024 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_frame_report.h"
17
18 #include <dlfcn.h>
19 #include <cstdio>
20 #include <unistd.h>
21
22 #include "hilog/log.h"
23
24 namespace OHOS {
25 namespace Rosen {
26 #undef LOG_DOMAIN
27 #define LOG_DOMAIN 0xD001400
28
29 #undef LOG_TAG
30 #define LOG_TAG "OHOS::RS"
31 #define LOGI(fmt, ...) HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__)
32 #define LOGE(fmt, ...) HILOG_ERROR(LOG_CORE, fmt, ##__VA_ARGS__)
33 namespace {
34 const std::string FRAME_AWARE_SO_PATH = "libframe_ui_intf.z.so";
35 }
GetInstance()36 RsFrameReport& RsFrameReport::GetInstance()
37 {
38 static RsFrameReport instance;
39 return instance;
40 }
41
RsFrameReport()42 RsFrameReport::RsFrameReport()
43 {
44 LOGI("RsFrameReport:[Init] LoadLibrary");
45 int ret = LoadLibrary();
46 if (!ret) {
47 LOGE("RsFrameReport:[Init] dlopen libframe_ui_intf.so failed!");
48 return;
49 }
50 LOGI("RsFrameReport:[Init] dlopen libframe_ui_intf.so success!");
51 initFunc_ = (InitFunc)LoadSymbol("Init");
52 if (initFunc_ != nullptr) {
53 initFunc_();
54 LOGI("RsFrameReport:[Init] Init success");
55 }
56 }
57
~RsFrameReport()58 RsFrameReport::~RsFrameReport() {}
59
Init()60 void RsFrameReport::Init()
61 {
62 LOGI("RsFrameReport init");
63 ReportSchedEvent(FrameSchedEvent::INIT, {});
64 }
65
LoadLibrary()66 bool RsFrameReport::LoadLibrary()
67 {
68 if (!frameSchedSoLoaded_) {
69 frameSchedHandle_ = dlopen(FRAME_AWARE_SO_PATH.c_str(), RTLD_LAZY);
70 if (frameSchedHandle_ == nullptr) {
71 LOGE("RsFrameReport:[LoadLibrary]dlopen libframe_ui_intf.so failed!"
72 " error = %{public}s\n", dlerror());
73 return false;
74 }
75 frameSchedSoLoaded_ = true;
76 }
77 LOGI("RsFrameReport:[LoadLibrary] load library success!");
78 return true;
79 }
80
CloseLibrary()81 void RsFrameReport::CloseLibrary()
82 {
83 if (dlclose(frameSchedHandle_) != 0) {
84 LOGE("RsFrameReport:[CloseLibrary]libframe_ui_intf.so failed!\n");
85 return;
86 }
87 frameSchedHandle_ = nullptr;
88 frameSchedSoLoaded_ = false;
89 LOGI("RsFrameReport:[CloseLibrary]libframe_ui_intf.so close success!\n");
90 }
91
LoadSymbol(const char * symName)92 void *RsFrameReport::LoadSymbol(const char *symName)
93 {
94 if (!frameSchedSoLoaded_) {
95 LOGE("RsFrameReport:[loadSymbol]libframe_ui_intf.so not loaded.\n");
96 return nullptr;
97 }
98 void *funcSym = dlsym(frameSchedHandle_, symName);
99 if (funcSym == nullptr) {
100 LOGE("RsFrameReport:[loadSymbol]Get %{public}s symbol failed: %{public}s\n", symName, dlerror());
101 return nullptr;
102 }
103 return funcSym;
104 }
105
GetEnable()106 int RsFrameReport::GetEnable()
107 {
108 if (!frameSchedSoLoaded_) {
109 return 0;
110 }
111 if (frameGetEnableFunc_ == nullptr) {
112 frameGetEnableFunc_ = (FrameGetEnableFunc)LoadSymbol("GetSenseSchedEnable");
113 }
114 if (frameGetEnableFunc_ != nullptr) {
115 return frameGetEnableFunc_();
116 } else {
117 LOGE("RsFrameReport:[GetEnable]load GetSenseSchedEnable function failed!");
118 return 0;
119 }
120 }
121
ReportSchedEvent(FrameSchedEvent event,const std::unordered_map<std::string,std::string> & payload)122 void RsFrameReport::ReportSchedEvent(FrameSchedEvent event, const std::unordered_map<std::string, std::string> &payload)
123 {
124 std::lock_guard<std::mutex> lock(reportSchedEventFuncLock_);
125 if (reportSchedEventFunc_ == nullptr) {
126 reportSchedEventFunc_ = (ReportSchedEventFunc)LoadSymbol("ReportSchedEvent");
127 }
128 if (reportSchedEventFunc_ != nullptr) {
129 reportSchedEventFunc_(event, payload);
130 } else {
131 LOGE("RsFrameReport load ReportSchedEvent function failed!");
132 }
133 }
134
SetFrameParam(int requestId,int load,int schedFrameNum,int value)135 void RsFrameReport::SetFrameParam(int requestId, int load, int schedFrameNum, int value)
136 {
137 if (setFrameParamFunc_ == nullptr) {
138 setFrameParamFunc_ = (SetFrameParamFunc)LoadSymbol("SetFrameParam");
139 }
140
141 if (setFrameParamFunc_ != nullptr) {
142 setFrameParamFunc_(requestId, load, schedFrameNum, value);
143 } else {
144 LOGE("RsFrameReport:[SetFrameParam]load SetFrameParam function failed");
145 }
146 }
147
SendCommandsStart()148 void RsFrameReport::SendCommandsStart()
149 {
150 if (sendCommandsStartFunc_ == nullptr) {
151 sendCommandsStartFunc_ = (SendCommandsStartFunc)LoadSymbol("SendCommandsStart");
152 }
153 if (sendCommandsStartFunc_ != nullptr) {
154 sendCommandsStartFunc_();
155 } else {
156 LOGE("RsFrameReport:[SendCommandsStart]load SendCommandsStart function failed!");
157 }
158 }
159
RenderStart(uint64_t timestamp,int skipFirstFrame)160 void RsFrameReport::RenderStart(uint64_t timestamp, int skipFirstFrame)
161 {
162 std::unordered_map<std::string, std::string> payload = {};
163 payload["vsyncTime"] = std::to_string(timestamp);
164 payload["skipFirstFrame"] = std::to_string(skipFirstFrame);
165 ReportSchedEvent(FrameSchedEvent::RS_RENDER_START, payload);
166 }
167
RenderEnd()168 void RsFrameReport::RenderEnd()
169 {
170 ReportSchedEvent(FrameSchedEvent::RS_RENDER_END, {});
171 }
172
DirectRenderEnd()173 void RsFrameReport::DirectRenderEnd()
174 {
175 ReportSchedEvent(FrameSchedEvent::RS_UNI_RENDER_END, {});
176 }
177
UniRenderStart()178 void RsFrameReport::UniRenderStart()
179 {
180 ReportSchedEvent(FrameSchedEvent::RS_UNI_RENDER_START, {});
181 }
182
UniRenderEnd()183 void RsFrameReport::UniRenderEnd()
184 {
185 ReportSchedEvent(FrameSchedEvent::RS_UNI_RENDER_END, {});
186 }
187
CheckUnblockMainThreadPoint()188 void RsFrameReport::CheckUnblockMainThreadPoint()
189 {
190 ReportSchedEvent(FrameSchedEvent::RS_UNBLOCK_MAINTHREAD, {});
191 }
192
CheckPostAndWaitPoint()193 void RsFrameReport::CheckPostAndWaitPoint()
194 {
195 ReportSchedEvent(FrameSchedEvent::RS_POST_AND_WAIT, {});
196 }
197
CheckBeginFlushPoint()198 void RsFrameReport::CheckBeginFlushPoint()
199 {
200 ReportSchedEvent(FrameSchedEvent::RS_BEGIN_FLUSH, {});
201 }
202
ReportBufferCount(int count)203 void RsFrameReport::ReportBufferCount(int count)
204 {
205 if (bufferCount_ == count) {
206 return;
207 }
208 bufferCount_ = count;
209 std::unordered_map<std::string, std::string> payload = {};
210 payload["bufferCount"] = std::to_string(count);
211 ReportSchedEvent(FrameSchedEvent::RS_BUFFER_COUNT, payload);
212 }
213
ReportHardwareInfo(int tid)214 void RsFrameReport::ReportHardwareInfo(int tid)
215 {
216 if (hardwareTid_ == tid) {
217 return;
218 }
219 hardwareTid_ = tid;
220 std::unordered_map<std::string, std::string> payload = {};
221 payload["hardwareTid"] = std::to_string(tid);
222 ReportSchedEvent(FrameSchedEvent::RS_HARDWARE_INFO, payload);
223 }
224
ReportFrameDeadline(int deadline,uint32_t currentRate)225 void RsFrameReport::ReportFrameDeadline(int deadline, uint32_t currentRate)
226 {
227 std::unordered_map<std::string, std::string> payload = {};
228 payload["rsFrameDeadline"] = std::to_string(deadline);
229 payload["currentRate"] = std::to_string(currentRate);
230 ReportSchedEvent(FrameSchedEvent::RS_FRAME_DEADLINE, payload);
231 }
232
ReportUnmarshalData(int unmarshalTid,size_t dataSize)233 void RsFrameReport::ReportUnmarshalData(int unmarshalTid, size_t dataSize)
234 {
235 if (unmarshalTid <= 0) {
236 return;
237 }
238 std::unordered_map<std::string, std::string> payload = {};
239 payload["unmarshalTid"] = std::to_string(unmarshalTid);
240 payload["dataSize"] = std::to_string(dataSize);
241 ReportSchedEvent(FrameSchedEvent::RS_UNMARSHAL_DATA, payload);
242 }
243
ReportDDGRTaskInfo()244 void RsFrameReport::ReportDDGRTaskInfo()
245 {
246 ReportSchedEvent(FrameSchedEvent::RS_DDGR_TASK, {});
247 }
248
ReportScbSceneInfo(const std::string & description,bool eventStatus)249 void RsFrameReport::ReportScbSceneInfo(const std::string& description, bool eventStatus)
250 {
251 std::unordered_map<std::string, std::string> payload = {};
252 payload["description"] = description;
253 payload["eventStatus"] = eventStatus ? "1" : "0"; // true:enter false:exit
254 ReportSchedEvent(FrameSchedEvent::GPU_SCB_SCENE_INFO, payload);
255 }
256 } // namespace Rosen
257 } // namespace OHOS
258