• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "egl_wrapper_loader.h"
17 
18 #include <dlfcn.h>
19 #include <string>
20 
21 #include "directory_ex.h"
22 
23 #include "egl_defs.h"
24 #include "../wrapper_log.h"
25 
26 using namespace OHOS;
27 namespace OHOS {
28 namespace {
29 #ifdef __aarch64__
30     constexpr const char *VENDOR_LIB_PATH = "/vendor/lib64/chipsetsdk/";
31     constexpr const char *SYSTEM_LIB_PATH = "/system/lib64/";
32 #else
33     constexpr const char *VENDOR_LIB_PATH = "/vendor/lib/chipsetsdk/";
34     constexpr const char *SYSTEM_LIB_PATH = "/system/lib/";
35 #endif
36 constexpr const char *LIB_EGL_NAME = "libEGL_impl.so";
37 constexpr const char *LIB_GLESV1_NAME = "libGLESv1_impl.so";
38 constexpr const char *LIB_GLESV2_NAME = "libGLESv2_impl.so";
39 constexpr const char *LIB_GLESV3_NAME = "libGLESv3_impl.so";
40 }
41 
GetInstance()42 EglWrapperLoader& EglWrapperLoader::GetInstance()
43 {
44     static EglWrapperLoader loader;
45     return loader;
46 }
47 
~EglWrapperLoader()48 EglWrapperLoader::~EglWrapperLoader()
49 {
50     WLOGD("");
51 }
52 
53 using GetProcAddressType = FunctionPointerType (*)(const char *);
LoadEgl(const char * libName,EglHookTable * table)54 bool EglWrapperLoader::LoadEgl(const char *libName, EglHookTable *table)
55 {
56     WLOGD("");
57     std::string path = std::string(VENDOR_LIB_PATH) + std::string(libName);
58     dlEglHandle_ = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
59     if (dlEglHandle_ == nullptr) {
60         path = std::string(SYSTEM_LIB_PATH) + std::string(libName);
61         std::string realPath;
62         if (!PathToRealPath(path, realPath)) {
63             WLOGE("file is not real path, file path: %{private}s", path.c_str());
64             return false;
65         }
66         dlEglHandle_ = dlopen(realPath.c_str(), RTLD_NOW | RTLD_LOCAL);
67         if (dlEglHandle_ == nullptr) {
68             WLOGE("dlopen failed. error: %{public}s.", dlerror());
69             return false;
70         }
71     }
72 
73     GetProcAddressType getProcAddr =
74         (GetProcAddressType)dlsym(dlEglHandle_, "eglGetProcAddress");
75     if (getProcAddr == nullptr) {
76         WLOGE("can't find eglGetProcAddress() in EGL driver library.");
77         return false;
78     }
79 
80     FunctionPointerType *current = (FunctionPointerType *)table;
81     char const * const *api = gEglApiNames;
82     while (*api) {
83         char const *name = *api;
84         FunctionPointerType func = (FunctionPointerType)dlsym(dlEglHandle_, name);
85         if (func == nullptr) {
86             WLOGD("try to getProcAddr %{public}s.", name);
87             func = getProcAddr(name);
88             if (func == nullptr) {
89                 WLOGD("couldn't find the entry-point: %{public}s.", name);
90             }
91         }
92 
93         *current++ = func;
94         api++;
95     }
96 
97     return true;
98 }
99 
LoadGl(const char * libName,char const * const * glName,FunctionPointerType * entry)100 void *EglWrapperLoader::LoadGl(const char *libName, char const * const *glName, FunctionPointerType *entry)
101 {
102     WLOGD("");
103     std::string path = std::string(VENDOR_LIB_PATH) + std::string(libName);
104     void *dlHandle = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
105     if (dlHandle == nullptr) {
106         path = std::string(SYSTEM_LIB_PATH) + std::string(libName);
107         std::string realPath;
108         if (!PathToRealPath(path, realPath)) {
109             WLOGE("file is not real path, file path: %{private}s", path.c_str());
110             return nullptr;
111         }
112         dlHandle = dlopen(realPath.c_str(), RTLD_NOW | RTLD_LOCAL);
113         if (dlHandle == nullptr) {
114             WLOGE("dlopen failed. error: %{public}s.", dlerror());
115             return nullptr;
116         }
117     }
118 
119     GetProcAddressType getProcAddr =
120         (GetProcAddressType)dlsym(dlEglHandle_, "eglGetProcAddress");
121     if (getProcAddr == nullptr) {
122         WLOGE("can't find eglGetProcAddress() in EGL driver library.");
123         return nullptr;
124     }
125 
126     FunctionPointerType *current = entry;
127     char const * const *api = glName;
128     while (*api) {
129         char const *name = *api;
130         FunctionPointerType func = (FunctionPointerType)dlsym(dlHandle, name);
131         if (func == nullptr) {
132             WLOGD("try to getProcAddr %{public}s.", name);
133             func = getProcAddr(name);
134             if (func == nullptr) {
135                 WLOGD("couldn't find the entry-point: %{public}s.", name);
136             }
137         }
138         *current++ = func;
139         api++;
140     }
141 
142     return dlHandle;
143 }
144 
LoadVendorDriver(EglWrapperDispatchTable * table)145 bool EglWrapperLoader::LoadVendorDriver(EglWrapperDispatchTable *table)
146 {
147     WLOGD("EGL");
148     if (!LoadEgl(LIB_EGL_NAME, &table->egl)) {
149         WLOGE("LoadEgl Failed.");
150         return false;
151     }
152 
153     WLOGD("GLESV1");
154     dlGlHandle1_ = LoadGl(LIB_GLESV1_NAME, gGlApiNames1, (FunctionPointerType *)&table->gl.table1);
155     if (!dlEglHandle_) {
156         WLOGE("LoadGl GLESV1 Failed.");
157         return false;
158     }
159 
160     WLOGD("GLESV2");
161     dlGlHandle2_ = LoadGl(LIB_GLESV2_NAME, gGlApiNames2, (FunctionPointerType *)&table->gl.table2);
162     if (!dlGlHandle2_) {
163         WLOGE("LoadGl GLESV2 Failed.");
164         return false;
165     }
166 
167     WLOGD("GLESV3");
168     dlGlHandle3_ = LoadGl(LIB_GLESV3_NAME, gGlApiNames3, (FunctionPointerType *)&table->gl.table3);
169     if (!dlGlHandle3_) {
170         WLOGE("LoadGl GLESV3 Failed.");
171         return false;
172     }
173 
174     return true;
175 }
176 
Load(EglWrapperDispatchTable * table)177 bool EglWrapperLoader::Load(EglWrapperDispatchTable *table)
178 {
179     WLOGD("");
180     if (table == nullptr) {
181         WLOGE("table is nullptr.");
182         return false;
183     }
184 
185     if (table->isLoad) {
186         WLOGI("EglWrapperLoader has been already loaded.");
187         return true;
188     }
189 
190     if (!LoadVendorDriver(table)) {
191         WLOGE("LoadVendorDriver Failed.");
192         return false;
193     }
194 
195     table->isLoad = true;
196     return true;
197 }
198 
Unload(EglWrapperDispatchTable * table)199 bool EglWrapperLoader::Unload(EglWrapperDispatchTable *table)
200 {
201     WLOGD("");
202     if (table == nullptr) {
203         WLOGE("table is nullptr.");
204         return false;
205     }
206     if (!table->isLoad) {
207         WLOGE("EglWrapperLoader is not loaded.");
208         return false;
209     }
210 
211     table->isLoad = false;
212 
213     if (dlEglHandle_) {
214         dlclose(dlEglHandle_);
215         dlEglHandle_ = nullptr;
216     }
217     if (dlGlHandle1_) {
218         dlclose(dlGlHandle1_);
219         dlGlHandle1_ = nullptr;
220     }
221     if (dlGlHandle2_) {
222         dlclose(dlGlHandle2_);
223         dlGlHandle2_ = nullptr;
224     }
225     if (dlGlHandle3_) {
226         dlclose(dlGlHandle3_);
227         dlGlHandle3_ = nullptr;
228     }
229 
230     return true;
231 }
232 
GetProcAddrFromDriver(const char * name)233 void *EglWrapperLoader::GetProcAddrFromDriver(const char *name)
234 {
235     void *func = nullptr;
236 
237     if (dlEglHandle_) {
238         func = dlsym(dlEglHandle_, name);
239     }
240 
241     if (!func && dlGlHandle3_) {
242         func = dlsym(dlGlHandle3_, name);
243     }
244 
245     if (!func && dlGlHandle2_) {
246         func = dlsym(dlGlHandle2_, name);
247     }
248 
249     if (!func && dlGlHandle1_) {
250         func = dlsym(dlGlHandle1_, name);
251     }
252 
253     return func;
254 }
255 } // namespace OHOS
256