• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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