1 /*
2 * Copyright (c) 2020-2021 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 "buffer_manager.h"
17
18 #include "buffer_common.h"
19 #include "securec.h"
20 #include "surface_buffer.h"
21
22 namespace OHOS {
GetInstance()23 BufferManager* BufferManager::GetInstance()
24 {
25 static BufferManager instance;
26 return &instance;
27 }
28
Init()29 bool BufferManager::Init()
30 {
31 if (grallocFucs_ != nullptr) {
32 GRAPHIC_LOGI("BufferManager has init succeed.");
33 return true;
34 }
35 if (GrallocInitialize(&grallocFucs_) != DISPLAY_SUCCESS) {
36 return false;
37 }
38 return true;
39 }
40
ConvertUsage(uint64_t & destUsage,uint32_t srcUsage) const41 bool BufferManager::ConvertUsage(uint64_t& destUsage, uint32_t srcUsage) const
42 {
43 switch (srcUsage) {
44 case BUFFER_CONSUMER_USAGE_SORTWARE:
45 destUsage = HBM_USE_MEM_SHARE;
46 break;
47 case BUFFER_CONSUMER_USAGE_HARDWARE:
48 case BUFFER_CONSUMER_USAGE_HARDWARE_PRODUCER_CACHE:
49 destUsage = HBM_USE_MEM_MMZ;
50 break;
51 case BUFFER_CONSUMER_USAGE_HARDWARE_CONSUMER_CACHE:
52 destUsage = HBM_USE_MEM_MMZ_CACHE;
53 break;
54 default:
55 GRAPHIC_LOGW("Conversion usage failed.");
56 return false;
57 }
58 return true;
59 }
60
ConvertFormat(PixelFormat & destFormat,uint32_t srcFormat) const61 bool BufferManager::ConvertFormat(PixelFormat& destFormat, uint32_t srcFormat) const
62 {
63 switch (srcFormat) {
64 case IMAGE_PIXEL_FORMAT_NONE:
65 destFormat = PIXEL_FMT_BUTT;
66 break;
67 case IMAGE_PIXEL_FORMAT_RGB565:
68 destFormat = PIXEL_FMT_RGB_565;
69 break;
70 case IMAGE_PIXEL_FORMAT_ARGB1555:
71 destFormat = PIXEL_FMT_RGBA_5551;
72 break;
73 case IMAGE_PIXEL_FORMAT_RGB888:
74 destFormat = PIXEL_FMT_RGB_888;
75 break;
76 case IMAGE_PIXEL_FORMAT_ARGB8888:
77 destFormat = PIXEL_FMT_RGBA_8888;
78 break;
79 case IMAGE_PIXEL_FORMAT_NV12:
80 destFormat = PIXEL_FMT_YCBCR_420_SP;
81 break;
82 case IMAGE_PIXEL_FORMAT_NV21:
83 destFormat = PIXEL_FMT_YCRCB_420_SP;
84 break;
85 case IMAGE_PIXEL_FORMAT_YUV420:
86 destFormat = PIXEL_FMT_YCBCR_420_P;
87 break;
88 case IMAGE_PIXEL_FORMAT_YVU420:
89 destFormat = PIXEL_FMT_YCRCB_420_P;
90 break;
91 default:
92 GRAPHIC_LOGW("Conversion format failed.");
93 return false;
94 }
95 return true;
96 }
97
AllocateBufferHandle(SurfaceBufferImpl & buffer) const98 BufferHandle* BufferManager::AllocateBufferHandle(SurfaceBufferImpl& buffer) const
99 {
100 uint32_t total = buffer.GetReserveFds() + buffer.GetReserveInts() + sizeof(BufferHandle);
101 BufferHandle* bufferHandle = static_cast<BufferHandle *>(malloc(total));
102 if (bufferHandle != nullptr) {
103 bufferHandle->fd = buffer.GetKey();
104 bufferHandle->phyAddr = buffer.GetPhyAddr();
105 bufferHandle->size = buffer.GetSize();
106 if (!ConvertUsage(bufferHandle->usage, buffer.GetUsage())) {
107 GRAPHIC_LOGW("Conversion usage failed.");
108 free(bufferHandle);
109 return nullptr;
110 }
111 bufferHandle->virAddr = buffer.GetVirAddr();
112 bufferHandle->reserveFds = buffer.GetReserveFds();
113 bufferHandle->reserveInts = buffer.GetReserveInts();
114 for (uint32_t i = 0; i < (buffer.GetReserveFds() + buffer.GetReserveInts()); i++) {
115 buffer.GetInt32(i, bufferHandle->reserve[i]);
116 }
117 return bufferHandle;
118 }
119 return nullptr;
120 }
121
AllocBuffer(AllocInfo info)122 SurfaceBufferImpl* BufferManager::AllocBuffer(AllocInfo info)
123 {
124 RETURN_VAL_IF_FAIL((grallocFucs_ != nullptr), nullptr);
125 BufferHandle* bufferHandle = nullptr;
126 if ((grallocFucs_->AllocMem == nullptr) || (grallocFucs_->AllocMem(&info, &bufferHandle) != DISPLAY_SUCCESS)) {
127 GRAPHIC_LOGE("Alloc graphic buffer failed");
128 return nullptr;
129 }
130 SurfaceBufferImpl* buffer = new SurfaceBufferImpl();
131 if (buffer != nullptr) {
132 buffer->SetMaxSize(bufferHandle->size);
133 buffer->SetVirAddr(bufferHandle->virAddr);
134 buffer->SetKey(bufferHandle->fd);
135 buffer->SetPhyAddr(bufferHandle->phyAddr);
136 buffer->SetStride(bufferHandle->stride);
137 buffer->SetReserveFds(bufferHandle->reserveFds);
138 buffer->SetReserveInts(bufferHandle->reserveInts);
139 for (uint32_t i = 0; i < (bufferHandle->reserveFds + bufferHandle->reserveInts); i++) {
140 buffer->SetInt32(i, bufferHandle->reserve[i]);
141 }
142 BufferKey key = {bufferHandle->fd, bufferHandle->phyAddr};
143 bufferHandleMap_.insert(std::make_pair(key, bufferHandle));
144 GRAPHIC_LOGD("Alloc buffer succeed to shared memory segment.");
145 } else {
146 grallocFucs_->FreeMem(bufferHandle);
147 GRAPHIC_LOGW("Alloc buffer failed to shared memory segment.");
148 }
149 return buffer;
150 }
151
AllocBuffer(uint32_t size,uint32_t usage)152 SurfaceBufferImpl* BufferManager::AllocBuffer(uint32_t size, uint32_t usage)
153 {
154 RETURN_VAL_IF_FAIL((grallocFucs_ != nullptr), nullptr);
155 AllocInfo info = {0};
156 info.expectedSize = size;
157 info.format = PIXEL_FMT_RGB_565;
158 if (!ConvertUsage(info.usage, usage)) {
159 GRAPHIC_LOGW("Alloc graphic buffer failed --- conversion usage.");
160 return nullptr;
161 }
162 info.usage |= HBM_USE_ASSIGN_SIZE;
163 SurfaceBufferImpl* buffer = AllocBuffer(info);
164 if (buffer == nullptr) {
165 GRAPHIC_LOGE("Alloc graphic buffer failed");
166 return nullptr;
167 }
168 buffer->SetUsage(usage);
169 return buffer;
170 }
171
AllocBuffer(uint32_t width,uint32_t height,uint32_t format,uint32_t usage)172 SurfaceBufferImpl* BufferManager::AllocBuffer(uint32_t width, uint32_t height, uint32_t format, uint32_t usage)
173 {
174 RETURN_VAL_IF_FAIL((grallocFucs_ != nullptr), nullptr);
175 AllocInfo info = {0};
176 info.width = width;
177 info.height = height;
178 if (!ConvertUsage(info.usage, usage)) {
179 GRAPHIC_LOGW("Alloc graphic buffer failed --- conversion usage.");
180 return nullptr;
181 }
182 if (!ConvertFormat(info.format, format)) {
183 GRAPHIC_LOGW("Alloc graphic buffer failed --- conversion format.");
184 return nullptr;
185 }
186 SurfaceBufferImpl* buffer = AllocBuffer(info);
187 if (buffer == nullptr) {
188 GRAPHIC_LOGE("Alloc graphic buffer failed");
189 return nullptr;
190 }
191 buffer->SetUsage(usage);
192 return buffer;
193 }
194
FreeBuffer(SurfaceBufferImpl ** buffer)195 void BufferManager::FreeBuffer(SurfaceBufferImpl** buffer)
196 {
197 RETURN_IF_FAIL((grallocFucs_ != nullptr));
198 if ((*buffer) == nullptr) {
199 GRAPHIC_LOGW("Input param buffer is null.");
200 return;
201 }
202 BufferKey key = {(*buffer)->GetKey(), (*buffer)->GetPhyAddr()};
203 auto iter = bufferHandleMap_.find(key);
204 if (iter == bufferHandleMap_.end()) {
205 return;
206 }
207 BufferHandle* bufferHandle = iter->second;
208 if (grallocFucs_->FreeMem != nullptr) {
209 grallocFucs_->FreeMem(bufferHandle);
210 bufferHandleMap_.erase(key);
211 delete *buffer;
212 *buffer = nullptr;
213 GRAPHIC_LOGD("Free buffer succeed.");
214 }
215 }
216
MapBuffer(SurfaceBufferImpl & buffer) const217 bool BufferManager::MapBuffer(SurfaceBufferImpl& buffer) const
218 {
219 RETURN_VAL_IF_FAIL((grallocFucs_ != nullptr), false);
220 void* virAddr = nullptr;
221 BufferHandle* bufferHandle = AllocateBufferHandle(buffer);
222 if (bufferHandle == nullptr) {
223 return false;
224 }
225 if (buffer.GetUsage() == BUFFER_CONSUMER_USAGE_HARDWARE ||
226 buffer.GetUsage() == BUFFER_CONSUMER_USAGE_HARDWARE_CONSUMER_CACHE ||
227 buffer.GetUsage() == BUFFER_CONSUMER_USAGE_SORTWARE) {
228 if (grallocFucs_->Mmap != nullptr) {
229 virAddr = grallocFucs_->Mmap(bufferHandle);
230 }
231 } else if (buffer.GetUsage() == BUFFER_CONSUMER_USAGE_HARDWARE_PRODUCER_CACHE) {
232 if (grallocFucs_->MmapCache != nullptr) {
233 virAddr = grallocFucs_->MmapCache(bufferHandle);
234 }
235 } else {
236 GRAPHIC_LOGE("No support usage.");
237 free(bufferHandle);
238 return false;
239 }
240 if (virAddr == nullptr) {
241 GRAPHIC_LOGE("Map Buffer error.");
242 free(bufferHandle);
243 return false;
244 }
245 buffer.SetVirAddr(virAddr);
246 GRAPHIC_LOGD("Map Buffer succeed.");
247 free(bufferHandle);
248 return true;
249 }
250
UnmapBuffer(SurfaceBufferImpl & buffer) const251 void BufferManager::UnmapBuffer(SurfaceBufferImpl& buffer) const
252 {
253 RETURN_IF_FAIL((grallocFucs_ != nullptr));
254 BufferHandle* bufferHandle = AllocateBufferHandle(buffer);
255 if (bufferHandle == nullptr) {
256 return;
257 }
258 if ((grallocFucs_->Unmap == nullptr) || (grallocFucs_->Unmap(bufferHandle) != DISPLAY_SUCCESS)) {
259 GRAPHIC_LOGE("Umap buffer failed.");
260 }
261 free(bufferHandle);
262 }
263
FlushCache(SurfaceBufferImpl & buffer) const264 int32_t BufferManager::FlushCache(SurfaceBufferImpl& buffer) const
265 {
266 RETURN_VAL_IF_FAIL((grallocFucs_ != nullptr), SURFACE_ERROR_NOT_READY);
267 BufferHandle* bufferHandle = AllocateBufferHandle(buffer);
268 if (bufferHandle == nullptr) {
269 return -1;
270 }
271 if (buffer.GetUsage() == BUFFER_CONSUMER_USAGE_HARDWARE_CONSUMER_CACHE) {
272 if ((grallocFucs_->FlushCache == nullptr) || (grallocFucs_->FlushCache(bufferHandle) != DISPLAY_SUCCESS)) {
273 GRAPHIC_LOGE("Flush cache buffer failed.");
274 }
275 } else if (buffer.GetUsage() == BUFFER_CONSUMER_USAGE_HARDWARE_PRODUCER_CACHE) {
276 if ((grallocFucs_->FlushMCache == nullptr) || (grallocFucs_->FlushMCache(bufferHandle) != DISPLAY_SUCCESS)) {
277 GRAPHIC_LOGE("Flush M cache buffer failed.");
278 }
279 }
280 free(bufferHandle);
281 return SURFACE_ERROR_OK;
282 }
283 } // namespace OHOS
284