• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "hpae_base/rs_hpae_ffrt_pattern_manager.h"
17 
18 #if defined(ROSEN_OHOS)
19 #include <dlfcn.h>
20 #include <unistd.h>
21 #endif
22 
23 #include "hpae_base/rs_hpae_log.h"
24 
25 #include "platform/common/rs_log.h"
26 
27 namespace OHOS {
28 namespace Rosen {
29 
30 namespace {
31 using GPInstanceGetFunc = void*(*)(PatternType_C, const char*);
32 using GPInstanceInitFunc = bool(*)(void*, size_t);
33 using GPInstanceDestroyFunc = void(*)(void*);
34 using GPRequestEGraphFunc = bool(*)(void*, uint64_t);
35 using GPReleaseEGraphFunc = bool(*)(void*, uint64_t);
36 using GPReleaseAllEGraphFunc = bool(*)(void*);
37 using GPWaitFunc = void*(*)(void*, uint64_t, MHC_PatternTaskName);
38 using GPGetGPUWaitEventFunc = uint16_t(*)(void*, uint64_t, MHC_PatternTaskName);
39 using GPGetGPUNotifyEventFunc = uint16_t(*)(void*, uint64_t, MHC_PatternTaskName);
40 using GPGPTaskSubmitFunc = void(*)(void*, uint64_t, MHC_TaskInfo*);
41 
42 static GPInstanceGetFunc g_getGPInstance = nullptr;
43 static GPInstanceInitFunc g_GPInit = nullptr;
44 static GPInstanceDestroyFunc g_GPDestroy = nullptr;
45 static GPRequestEGraphFunc g_GPRequestEGraph = nullptr;
46 static GPReleaseEGraphFunc g_GPReleaseEGraph = nullptr;
47 static GPReleaseAllEGraphFunc g_GPReleaseAll = nullptr;
48 static GPWaitFunc g_GPWait = nullptr;
49 static GPGetGPUWaitEventFunc g_GPGetVulkanWaitEvent = nullptr;
50 static GPGetGPUNotifyEventFunc g_GPGetVulkanNotifyEvent = nullptr;
51 static GPGPTaskSubmitFunc g_GPTaskSubmit = nullptr;
52 static void* g_mhcHandle = nullptr;
53 }
54 
Instance()55 RSHpaeFfrtPatternManager& RSHpaeFfrtPatternManager::Instance()
56 {
57     static RSHpaeFfrtPatternManager instance;
58     return instance;
59 }
60 
RSHpaeFfrtPatternManager()61 RSHpaeFfrtPatternManager::RSHpaeFfrtPatternManager()
62 {
63     if (!MHCDlOpen()) {
64         HPAE_LOGE("MHCDlOpen() failed!");
65     }
66     if (!MHCGraphPatternInit(GRAPH_NUM)) {
67         HPAE_LOGE("MHCGraphPatternInit() failed!");
68     }
69     HPAE_LOGW("mhc_so MHCGraphPatternInit success!");
70 }
71 
~RSHpaeFfrtPatternManager()72 RSHpaeFfrtPatternManager::~RSHpaeFfrtPatternManager()
73 {
74     if (g_instance) {
75         g_GPDestroy(g_instance);
76         g_instance = nullptr;
77     }
78 
79     if (g_mhcHandle) {
80 #if defined(ROSEN_OHOS)
81         dlclose(g_mhcHandle);
82 #endif
83         g_getGPInstance = nullptr;
84         g_GPInit = nullptr;
85         g_GPDestroy = nullptr;
86         g_GPRequestEGraph = nullptr;
87         g_GPReleaseEGraph = nullptr;
88         g_GPReleaseAll = nullptr;
89         g_GPWait = nullptr;
90         g_GPGetVulkanWaitEvent = nullptr;
91         g_GPGetVulkanNotifyEvent = nullptr;
92         g_GPTaskSubmit = nullptr;
93         g_mhcHandle = nullptr;
94     }
95 }
96 
MHCDlOpen()97 bool RSHpaeFfrtPatternManager::MHCDlOpen()
98 {
99 #if defined(ROSEN_OHOS)
100     HPAE_LOGW("mhc_so MHCDlOpen start\n");
101     if (g_mhcHandle == nullptr) {
102         g_mhcHandle = dlopen("/vendor/lib64/libmhc_framework.so", RTLD_LAZY | RTLD_NODELETE);
103         if (!g_mhcHandle) {
104             HPAE_LOGW("mhc_so dlopen libmhc_framework.so error\n");
105             return false;
106         }
107     }
108 
109     g_getGPInstance = reinterpret_cast<GPInstanceGetFunc>(dlsym(g_mhcHandle, "mhc_graph_pattern_get"));
110     g_GPInit = reinterpret_cast<GPInstanceInitFunc>(dlsym(g_mhcHandle, "mhc_graph_pattern_init"));
111     g_GPDestroy = reinterpret_cast<GPInstanceDestroyFunc>(dlsym(g_mhcHandle, "mhc_graph_pattern_destroy"));
112     g_GPRequestEGraph = reinterpret_cast<GPRequestEGraphFunc>(dlsym(g_mhcHandle, "mhc_graph_pattern_request_eg"));
113     g_GPReleaseEGraph = reinterpret_cast<GPReleaseEGraphFunc>(dlsym(g_mhcHandle, "mhc_graph_pattern_release_eg"));
114     g_GPReleaseAll = reinterpret_cast<GPReleaseAllEGraphFunc>(dlsym(g_mhcHandle, "mhc_graph_pattern_relsease_all"));
115     g_GPWait = reinterpret_cast<GPWaitFunc>(dlsym(g_mhcHandle, "mhc_gp_task_wait"));
116     g_GPGetVulkanWaitEvent = reinterpret_cast<GPGetGPUWaitEventFunc>(
117         dlsym(g_mhcHandle, "mhc_gp_vulkan_task_get_wait_event"));
118     g_GPGetVulkanNotifyEvent = reinterpret_cast<GPGetGPUNotifyEventFunc>(
119         dlsym(g_mhcHandle, "mhc_gp_vulkan_task_get_notify_event"));
120     g_GPTaskSubmit = reinterpret_cast<GPGPTaskSubmitFunc>(dlsym(g_mhcHandle, "mhc_gp_task_submit"));
121     if (!g_getGPInstance || !g_GPInit || !g_GPDestroy || !g_GPRequestEGraph || !g_GPReleaseEGraph || !g_GPWait\
122         || !g_GPGetVulkanWaitEvent || !g_GPGetVulkanNotifyEvent || !g_GPTaskSubmit || !g_GPReleaseAll) {
123         HPAE_LOGE("mhc_so dlsym error\n");
124         dlclose(g_mhcHandle);
125         g_mhcHandle = nullptr;
126         return false;
127     }
128 
129     HPAE_LOGW("mhc_so LoadLibMHC success\n");
130     return true;
131 #else
132     return false;
133 #endif
134 }
135 
MHCCheck(const std::string logTag,uint64_t frameId)136 bool RSHpaeFfrtPatternManager::MHCCheck(const std::string logTag, uint64_t frameId)
137 {
138     if (!g_instance) {
139         HPAE_LOGE("mhc_so MHCCheck %{public}s g_instance == nullptr", logTag.c_str());
140         return false;
141     }
142     HPAE_LOGW("mhc_so %{public}s MHCCheck frameId:%{public}" PRIu64 " ", logTag.c_str(), frameId);
143     return true;
144 }
145 
MHCGraphPatternInit(size_t size)146 bool RSHpaeFfrtPatternManager::MHCGraphPatternInit(size_t size)
147 {
148     HPAE_LOGW("mhc_so MHCGraphPatternInit");
149     if (g_instance) {
150         return true;
151     }
152     if (g_getGPInstance == nullptr) {
153         HPAE_LOGW("mhc_so g_getGPInstance nullptr");
154         return false;
155     }
156     g_instance =  g_getGPInstance(PatternType_C::BLUR, "blur_graph");
157     return g_GPInit(g_instance, size);
158 }
159 
MHCRequestEGraph(uint64_t frameId)160 bool RSHpaeFfrtPatternManager::MHCRequestEGraph(uint64_t frameId)
161 {
162     if (!g_instance) {
163         HPAE_LOGW("mhc_so MHCRequestEGraph g_instance nullptr");
164         return false;
165     }
166     if (g_GPRequestEGraph == nullptr) {
167         HPAE_LOGW("mhc_so g_GPRequestEGraph nullptr");
168         return false;
169     }
170     return g_GPRequestEGraph(g_instance, frameId);
171 }
172 
MHCWait(uint64_t frameId,MHC_PatternTaskName taskName)173 bool RSHpaeFfrtPatternManager::MHCWait(uint64_t frameId, MHC_PatternTaskName taskName)
174 {
175     if (!MHCCheck("MHCWait", frameId)) {
176         return false;
177     }
178 
179     if (g_GPWait == nullptr) {
180         HPAE_LOGW("mhc_so g_GPWait nullptr");
181         return false;
182     }
183 
184     g_GPWait(g_instance, frameId, taskName);
185     return true;
186 }
187 
MHCGetVulkanTaskWaitEvent(uint64_t frameId,MHC_PatternTaskName taskName)188 uint16_t RSHpaeFfrtPatternManager::MHCGetVulkanTaskWaitEvent(uint64_t frameId, MHC_PatternTaskName taskName)
189 {
190     if (!MHCCheck("MHCGetVulkanTaskWaitEvent", frameId)) {
191         return false;
192     }
193 
194     if (g_GPGetVulkanWaitEvent == nullptr) {
195         HPAE_LOGW("mhc_so g_GPGetVulkanWaitEvent nullptr");
196         return false;
197     }
198 
199     auto eventId = g_GPGetVulkanWaitEvent(g_instance, frameId, taskName);
200     HPAE_LOGW("mhc_so MHCGetVulkanTaskWaitEvent event = %{public}d, taskName=%{public}d\n", eventId, taskName);
201     return eventId;
202 }
203 
MHCGetVulkanTaskNotifyEvent(uint64_t frameId,MHC_PatternTaskName taskName)204 uint16_t RSHpaeFfrtPatternManager::MHCGetVulkanTaskNotifyEvent(uint64_t frameId, MHC_PatternTaskName taskName)
205 {
206     if (!MHCCheck("MHCGetVulkanTaskNotifyEvent", frameId)) {
207         return false;
208     }
209 
210     if (g_GPGetVulkanNotifyEvent == nullptr) {
211         HPAE_LOGW("mhc_so g_GPGetVulkanNotifyEvent nullptr");
212         return false;
213     }
214 
215     auto eventId = g_GPGetVulkanNotifyEvent(g_instance, frameId, taskName);
216     HPAE_LOGW("mhc_so MHCGetVulkanTaskNotifyEvent event = %{public}d, taskName=%{public}d\n", eventId, taskName);
217     return eventId;
218 }
219 
MHCReleaseEGraph(uint64_t frameId)220 bool RSHpaeFfrtPatternManager::MHCReleaseEGraph(uint64_t frameId)
221 {
222     if (!MHCCheck("MHCReleaseEGraph", frameId)) {
223         return false;
224     }
225 
226     if (g_GPReleaseEGraph == nullptr) {
227         HPAE_LOGW("mhc_so g_GPReleaseEGraph nullptr");
228         return false;
229     }
230 
231     return g_GPReleaseEGraph(g_instance, frameId);
232 }
233 
MHCReleaseAll()234 void RSHpaeFfrtPatternManager::MHCReleaseAll()
235 {
236     HPAE_LOGW("mhc_so MHCReleaseAll");
237     if (g_instance == nullptr) {
238         HPAE_LOGE("mhc_so MHCReleaseAll g_instance == nullptr");
239         return;
240     }
241 
242     if (g_GPReleaseAll == nullptr) {
243         HPAE_LOGW("mhc_so g_GPReleaseAll nullptr");
244         return;
245     }
246     // return 1 is succ
247     int ret = g_GPReleaseAll(g_instance);
248     ROSEN_LOGI("mhc_so MHCReleaseAll, ret=%{public}d", ret);
249 }
250 
MHCSubmitTask(uint64_t frameId,MHC_PatternTaskName taskName,std::function<void ()> && preFunc,void *** taskHandleVec,size_t numTask,std::function<void ()> && afterFunc)251 bool RSHpaeFfrtPatternManager::MHCSubmitTask(uint64_t frameId, MHC_PatternTaskName taskName, \
252     std::function<void()>&& preFunc, void*** taskHandleVec, size_t numTask, std::function<void()>&&afterFunc)
253 {
254     if (!MHCCheck("MHCSubmitTask", frameId)) {
255         return false;
256     }
257 
258     if (g_GPTaskSubmit == nullptr) {
259         HPAE_LOGW("mhc_so g_GPTaskSubmit nullptr");
260         return false;
261     }
262 
263     FunctionHeader* preFuncHeader = create_function_wrapper(std::move(preFunc));
264     void* c_preFunc = static_cast<void*>(preFuncHeader);
265     FunctionHeader* afterFuncHeader = create_function_wrapper(std::move(afterFunc));
266     void* c_afterFunc = static_cast<void*>(afterFuncHeader);
267 
268     MHC_TaskInfo mhcTaskInfo = {
269         .taskName = taskName,
270         .c_prefunc = c_preFunc,
271         .c_taskHandles = taskHandleVec,
272         .numTasks = numTask,
273         .c_afterFunc = c_afterFunc
274     };
275     g_GPTaskSubmit(g_instance, frameId, &mhcTaskInfo);
276     return true;
277 }
278 
IsThreadIdMatch()279 bool RSHpaeFfrtPatternManager::IsThreadIdMatch()
280 {
281 #if defined(ROSEN_OHOS)
282     return tid_ == gettid();
283 #else
284     return false;
285 #endif
286 }
SetThreadId()287 void RSHpaeFfrtPatternManager::SetThreadId()
288 {
289 #if defined(ROSEN_OHOS)
290     tid_ = gettid();
291 #endif
292 }
IsUpdated()293 bool RSHpaeFfrtPatternManager::IsUpdated()
294 {
295     return updated_ && IsThreadIdMatch();
296 }
297 
298 } // namespace Rosen
299 } // namespace OHOS