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 22namespace OHOS { 23BufferManager* BufferManager::GetInstance() 24{ 25 static BufferManager instance; 26 return &instance; 27} 28 29bool 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 41bool 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 61bool 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 98BufferHandle* 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 122SurfaceBufferImpl* 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 152SurfaceBufferImpl* 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 172SurfaceBufferImpl* 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 195void 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 217bool 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 251void 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 264int32_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