1 /*
2 * Copyright (c) 2023 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 "mapper_service.h"
17
18 #include <dlfcn.h>
19 #include <hdf_base.h>
20 #include <hdf_log.h>
21 #include "display_log.h"
22 #include "hdf_trace.h"
23
24 #undef LOG_TAG
25 #define LOG_TAG "MAPPER_SRV"
26 #undef LOG_DOMAIN
27 #define LOG_DOMAIN 0xD002515
28 #undef DISPLAY_TRACE
29 #define DISPLAY_TRACE HdfTrace trace(__func__, "HDI:DISP:")
30
31 namespace OHOS {
32 namespace HDI {
33 namespace Display {
34 namespace Buffer {
35 namespace V1_0 {
MapperImplGetInstance(void)36 extern "C" Buffer::V1_2::IMapper* MapperImplGetInstance(void)
37 {
38 return new (std::nothrow) MapperService();
39 }
40
MapperService()41 MapperService::MapperService()
42 : libHandle_(nullptr),
43 vdiImpl_(nullptr),
44 createVdi_(nullptr),
45 destroyVdi_(nullptr)
46 {
47 int32_t ret = LoadVdi();
48 if (ret == HDF_SUCCESS) {
49 vdiImpl_ = createVdi_();
50 CHECK_NULLPOINTER_RETURN(vdiImpl_);
51 } else {
52 HDF_LOGE("%{public}s: Load buffer VDI failed", __func__);
53 }
54 }
55
~MapperService()56 MapperService::~MapperService()
57 {
58 std::lock_guard<std::mutex> lck(mutex_);
59 if (destroyVdi_ != nullptr && vdiImpl_ != nullptr) {
60 destroyVdi_(vdiImpl_);
61 vdiImpl_ = nullptr;
62 destroyVdi_ = nullptr;
63 }
64 if (libHandle_ != nullptr) {
65 dlclose(libHandle_);
66 libHandle_ = nullptr;
67 }
68 }
69
LoadVdi()70 int32_t MapperService::LoadVdi()
71 {
72 const char* errStr = dlerror();
73 if (errStr != nullptr) {
74 HDF_LOGD("%{public}s: mapper load vdi, clear earlier dlerror: %{public}s", __func__, errStr);
75 }
76 #ifdef BUFFER_VDI_DEFAULT_LIBRARY_ENABLE
77 libHandle_ = dlopen(DISPLAY_BUFFER_VDI_DEFAULT_LIBRARY, RTLD_LAZY);
78 if (libHandle_ == nullptr) {
79 DISPLAY_LOGE("display buffer load vendor vdi default library failed: %{public}s", DISPLAY_BUFFER_VDI_LIBRARY);
80 #endif // BUFFER_VDI_DEFAULT_LIBRARY_ENABLE
81 libHandle_ = dlopen(DISPLAY_BUFFER_VDI_LIBRARY, RTLD_LAZY);
82 DISPLAY_LOGD("display buffer load vendor vdi library: %{public}s", DISPLAY_BUFFER_VDI_LIBRARY);
83 #ifdef BUFFER_VDI_DEFAULT_LIBRARY_ENABLE
84 } else {
85 DISPLAY_LOGD("display buffer load vendor vdi default library: %{public}s", DISPLAY_BUFFER_VDI_LIBRARY);
86 }
87 #endif // BUFFER_VDI_DEFAULT_LIBRARY_ENABLE
88 CHECK_NULLPOINTER_RETURN_VALUE(libHandle_, HDF_FAILURE);
89
90 createVdi_ = reinterpret_cast<CreateDisplayBufferVdiFunc>(dlsym(libHandle_, "CreateDisplayBufferVdi"));
91 if (createVdi_ == nullptr) {
92 errStr = dlerror();
93 if (errStr != nullptr) {
94 HDF_LOGE("%{public}s: mapper CreateDisplayBufferVdi dlsym error: %{public}s", __func__, errStr);
95 }
96 dlclose(libHandle_);
97 return HDF_FAILURE;
98 }
99
100 destroyVdi_ = reinterpret_cast<DestroyDisplayBufferVdiFunc>(dlsym(libHandle_, "DestroyDisplayBufferVdi"));
101 if (destroyVdi_ == nullptr) {
102 errStr = dlerror();
103 if (errStr != nullptr) {
104 HDF_LOGE("%{public}s: mapper DestroyDisplayBufferVdi dlsym error: %{public}s", __func__, errStr);
105 }
106 dlclose(libHandle_);
107 return HDF_FAILURE;
108 }
109
110 return HDF_SUCCESS;
111 }
112
FreeMem(const sptr<NativeBuffer> & handle)113 int32_t MapperService::FreeMem(const sptr<NativeBuffer>& handle)
114 {
115 DISPLAY_TRACE;
116 CHECK_NULLPOINTER_RETURN_VALUE(handle, HDF_FAILURE);
117 CHECK_NULLPOINTER_RETURN_VALUE(vdiImpl_, HDF_FAILURE);
118
119 BufferHandle* buffer = handle->Move();
120 CHECK_NULLPOINTER_RETURN_VALUE(buffer, HDF_FAILURE);
121 vdiImpl_->FreeMem(*buffer);
122 return HDF_SUCCESS;
123 }
124
Mmap(const sptr<NativeBuffer> & handle)125 int32_t MapperService::Mmap(const sptr<NativeBuffer>& handle)
126 {
127 DISPLAY_TRACE;
128 CHECK_NULLPOINTER_RETURN_VALUE(handle, HDF_FAILURE);
129 CHECK_NULLPOINTER_RETURN_VALUE(vdiImpl_, HDF_FAILURE);
130
131 BufferHandle* buffer = handle->GetBufferHandle();
132 CHECK_NULLPOINTER_RETURN_VALUE(buffer, HDF_FAILURE);
133 void* retPtr = vdiImpl_->Mmap(*buffer);
134 CHECK_NULLPOINTER_RETURN_VALUE(retPtr, HDF_FAILURE);
135 return HDF_SUCCESS;
136 }
137
Unmap(const sptr<NativeBuffer> & handle)138 int32_t MapperService::Unmap(const sptr<NativeBuffer>& handle)
139 {
140 DISPLAY_TRACE;
141 CHECK_NULLPOINTER_RETURN_VALUE(handle, HDF_FAILURE);
142 CHECK_NULLPOINTER_RETURN_VALUE(vdiImpl_, HDF_FAILURE);
143
144 BufferHandle* buffer = handle->GetBufferHandle();
145 CHECK_NULLPOINTER_RETURN_VALUE(buffer, HDF_FAILURE);
146 int32_t ret = vdiImpl_->Unmap(*buffer);
147 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, HDF_FAILURE, DISPLAY_LOGE(" fail"));
148 return ret;
149 }
150
FlushCache(const sptr<NativeBuffer> & handle)151 int32_t MapperService::FlushCache(const sptr<NativeBuffer>& handle)
152 {
153 DISPLAY_TRACE;
154 CHECK_NULLPOINTER_RETURN_VALUE(handle, HDF_FAILURE);
155 CHECK_NULLPOINTER_RETURN_VALUE(vdiImpl_, HDF_FAILURE);
156
157 BufferHandle* buffer = handle->GetBufferHandle();
158 CHECK_NULLPOINTER_RETURN_VALUE(buffer, HDF_FAILURE);
159 int32_t ret = vdiImpl_->FlushCache(*buffer);
160 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, HDF_FAILURE, DISPLAY_LOGE(" fail"));
161 return ret;
162 }
163
InvalidateCache(const sptr<NativeBuffer> & handle)164 int32_t MapperService::InvalidateCache(const sptr<NativeBuffer>& handle)
165 {
166 DISPLAY_TRACE;
167 CHECK_NULLPOINTER_RETURN_VALUE(handle, HDF_FAILURE);
168 CHECK_NULLPOINTER_RETURN_VALUE(vdiImpl_, HDF_FAILURE);
169
170 BufferHandle* buffer = handle->GetBufferHandle();
171 CHECK_NULLPOINTER_RETURN_VALUE(buffer, HDF_FAILURE);
172 int32_t ret = vdiImpl_->InvalidateCache(*buffer);
173 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, HDF_FAILURE, DISPLAY_LOGE(" fail"));
174 return ret;
175 }
176
GetImageLayout(const sptr<NativeBuffer> & handle,V1_2::ImageLayout & layout)177 int32_t MapperService::GetImageLayout(const sptr<NativeBuffer>& handle, V1_2::ImageLayout& layout)
178 {
179 CHECK_NULLPOINTER_RETURN_VALUE(handle, HDF_FAILURE);
180 CHECK_NULLPOINTER_RETURN_VALUE(vdiImpl_, HDF_FAILURE);
181
182 BufferHandle* buffer = handle->GetBufferHandle();
183 CHECK_NULLPOINTER_RETURN_VALUE(buffer, HDF_FAILURE);
184 int32_t ret = vdiImpl_->GetImageLayout(*buffer, layout);
185 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, HDF_FAILURE, DISPLAY_LOGE(" fail"));
186 return ret;
187 }
188
FreeMemVdi(BufferHandle * handle)189 void MapperService::FreeMemVdi(BufferHandle* handle)
190 {
191 HdfTrace traceTwo("FreeMem", "HDI:VDI:");
192 vdiImpl_->FreeMem(*handle);
193 }
194
AllocMem(const AllocInfo & info,sptr<NativeBuffer> & handle)195 int32_t MapperService::AllocMem(const AllocInfo& info, sptr<NativeBuffer>& handle)
196 {
197 BufferHandle* buffer = nullptr;
198 CHECK_NULLPOINTER_RETURN_VALUE(vdiImpl_, HDF_FAILURE);
199 HdfTrace traceOne("AllocMem-VDI", "HDI:VDI:");
200 int32_t ec = vdiImpl_->AllocMem(info, buffer);
201 if (ec != HDF_SUCCESS) {
202 HDF_LOGE("%{public}s: AllocMem failed, ec = %{public}d", __func__, ec);
203 return ec;
204 }
205
206 CHECK_NULLPOINTER_RETURN_VALUE(buffer, HDF_DEV_ERR_NO_MEMORY);
207
208 handle = new NativeBuffer();
209 if (handle == nullptr) {
210 HDF_LOGE("%{public}s: new NativeBuffer failed", __func__);
211 FreeMemVdi(buffer);
212 return HDF_FAILURE;
213 }
214
215 handle->SetBufferHandle(buffer, true, [this](BufferHandle* freeBuffer) {
216 FreeMemVdi(freeBuffer);
217 });
218 return HDF_SUCCESS;
219 }
220
IsSupportAllocPassthrough(const AllocInfo & info)221 int32_t MapperService::IsSupportAllocPassthrough(const AllocInfo& info)
222 {
223 CHECK_NULLPOINTER_RETURN_VALUE(vdiImpl_, HDF_FAILURE);
224 HdfTrace traceOne("IsSupportAllocPassthrough-VDI", "HDI:VDI:");
225 return vdiImpl_->IsSupportAllocPassthrough(info);
226 }
227
ReAllocMem(const AllocInfo & info,const sptr<NativeBuffer> & inBuffer,sptr<NativeBuffer> & outBuffer)228 int32_t MapperService::ReAllocMem(const AllocInfo& info,
229 const sptr<NativeBuffer>& inBuffer, sptr<NativeBuffer>& outBuffer)
230 {
231 CHECK_NULLPOINTER_RETURN_VALUE(vdiImpl_, HDF_FAILURE);
232 CHECK_NULLPOINTER_RETURN_VALUE(inBuffer, HDF_FAILURE);
233 BufferHandle* inHandle = inBuffer->GetBufferHandle();
234 BufferHandle* outHandle = nullptr;
235 HdfTrace traceOne("AllocMem-VDI", "HDI:VDI:");
236
237 int32_t ec = vdiImpl_->ReAllocMem(info, *inHandle, outHandle);
238 if (ec != HDF_SUCCESS) {
239 HDF_LOGE("%{public}s: ReAllocMem failed, ec = %{public}d", __func__, ec);
240 return ec;
241 }
242
243 CHECK_NULLPOINTER_RETURN_VALUE(outHandle, HDF_FAILURE);
244
245 outBuffer = new NativeBuffer();
246 if (outBuffer == nullptr) {
247 HDF_LOGE("%{public}s: new NativeBuffer failed", __func__);
248 FreeMemVdi(outHandle);
249 return HDF_FAILURE;
250 }
251
252 outBuffer->SetBufferHandle(outHandle, true, [this](BufferHandle* freeBuffer) {
253 FreeMemVdi(freeBuffer);
254 });
255 return HDF_SUCCESS;
256 }
257 } // namespace V1_2
258 } // namespace Buffer
259 } // namespace Display
260 } // namespace HDI
261 } // namespace OHOS
262