• 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 #include "driver_loader.h"
16 #include <dlfcn.h>
17 #include <iostream>
18 #include <mutex>
19 #include "wrapper_log.h"
20 #include "directory_ex.h"
21 
22 namespace vulkan {
23 namespace driver {
24 #ifdef __aarch64__
25 constexpr const char *VENDOR_LIB_PATH = "/vendor/lib64/chipsetsdk/";
26 constexpr const char *SYSTEM_LIB_PATH = "/system/lib64/";
27 #else
28 constexpr const char *VENDOR_LIB_PATH = "/vendor/lib/chipsetsdk/";
29 constexpr const char *SYSTEM_LIB_PATH = "/system/lib/";
30 #endif
31 constexpr const char *LIB_NAME = "libEGL_impl.so";
32 constexpr const char *HDI_VULKAN_MODULE_INIT = "VulkanInitialize";
33 constexpr const char *HDI_VULKAN_MODULE_UNINIT = "VulkanUnInitialize";
34 
Load()35 bool DriverLoader::Load()
36 {
37     static std::mutex loadLock;
38     std::lock_guard<std::mutex> lock(loadLock);
39 
40     if (loader_.vulkanFuncs_ != nullptr) {
41         return true;
42     }
43     loader_.supported_ = false;
44 
45     if (!LoadDriver()) {
46         WLOGE("LoadDriver failed");
47         return false;
48     }
49 
50     PFN_VulkanInitialize VulkanInitializeFunc
51         = reinterpret_cast<PFN_VulkanInitialize>(dlsym(loader_.handle_, HDI_VULKAN_MODULE_INIT));
52     if (VulkanInitializeFunc == nullptr) {
53         WLOGE("DriverLoader:: couldn't find symbol(VulkanInitializeFunc) in library : %{public}s.", dlerror());
54         UnloadDriver();
55         return false;
56     }
57 
58     if (VulkanInitializeFunc(&loader_.vulkanFuncs_) != 0) {
59         WLOGE("DriverLoader:: Initialize Vulkan Func fail");
60         UnloadDriver();
61         return false;
62     }
63 
64     loader_.vulkanUnInitializeFunc_ = reinterpret_cast<PFN_VulkanUnInitialize>(
65         dlsym(loader_.handle_, HDI_VULKAN_MODULE_UNINIT));
66 
67     if (loader_.vulkanUnInitializeFunc_ == nullptr) {
68         WLOGE("DriverLoader:: couldn't find symbol(VulkanUnInitialize) in library : %{public}s.", dlerror());
69         UnloadDriver();
70         return false;
71     }
72     loader_.supported_ = true;
73     WLOGI("DriverLoader:: Found Vulkan Func success");
74     return true;
75 }
76 
Unload()77 bool DriverLoader::Unload()
78 {
79     if (loader_.vulkanUnInitializeFunc_ == nullptr) {
80         WLOGE("DriverLoader::Unload can not find vulkan UnInitialize Func.");
81         return false;
82     }
83     if (loader_.vulkanUnInitializeFunc_(loader_.vulkanFuncs_) != 0) {
84         WLOGE("DriverLoader::Unload vulkan UnInitialize Func failed.");
85         return false;
86     }
87     loader_.vulkanFuncs_ = nullptr;
88     loader_.vulkanUnInitializeFunc_ = nullptr;
89     WLOGD("DriverLoader::Unload vulkan UnInitialize Func successfully.");
90     return UnloadDriver();
91 }
92 
LoadDriver()93 bool DriverLoader::LoadDriver()
94 {
95     if (loader_.handle_ != nullptr) {
96         WLOGD("handle is not null, no need to dlopen.");
97         return true;
98     }
99     std::string venderPath = std::string(VENDOR_LIB_PATH) + std::string(LIB_NAME);
100     std::string systemPath = std::string(SYSTEM_LIB_PATH) + std::string(LIB_NAME);
101     if (!LoadDriverFromFile(venderPath)) {
102         if (!LoadDriverFromFile(systemPath)) {
103             return false;
104         }
105     }
106     WLOGD("DriverLoader::LoadDriver successfully.");
107     return true;
108 }
109 
UnloadDriver()110 bool DriverLoader::UnloadDriver()
111 {
112     if (loader_.handle_ == nullptr) {
113         WLOGD("DriverLoader::UnloadDriver handle is null already.");
114         return true;
115     }
116     if (dlclose(loader_.handle_) != 0) {
117         WLOGE("DriverLoader::UnloadDriver dlclose failed.");
118         return false;
119     }
120     loader_.handle_ = nullptr;
121     WLOGD("DriverLoader::UnloadDriver dlclose success.");
122     return true;
123 }
124 
LoadDriverFromFile(std::string path)125 bool DriverLoader::LoadDriverFromFile(std::string path)
126 {
127     std::string realPath;
128     if (!OHOS::PathToRealPath(path, realPath)) {
129         WLOGE("file is not in path: %{private}s", path.c_str());
130         return false;
131     }
132     loader_.handle_ = dlopen(realPath.c_str(), RTLD_LOCAL | RTLD_NOW);
133     if (loader_.handle_ == nullptr) {
134         WLOGE("dlopen failed. error: %{public}s.", dlerror());
135         return false;
136     }
137     return true;
138 }
139 }  // namespace driver
140 }  // namespace vulkan
141