1 /* 2 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 13 * * Neither the name of The Linux Foundation nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <gralloc_priv.h> 31 32 #include <core/buffer_allocator.h> 33 #include <utils/constants.h> 34 #include <utils/debug.h> 35 36 #include "hwc_buffer_allocator.h" 37 #include "hwc_debugger.h" 38 #include "gr_utils.h" 39 40 #define __CLASS__ "HWCBufferAllocator" 41 42 namespace sdm { 43 44 DisplayError HWCBufferAllocator::Init() { 45 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module_); 46 if (err != 0) { 47 DLOGE("FATAL: can not get GRALLOC module"); 48 return kErrorResources; 49 } 50 51 err = gralloc1_open(module_, &gralloc_device_); 52 if (err != 0) { 53 DLOGE("FATAL: can not open GRALLOC device"); 54 return kErrorResources; 55 } 56 57 if (gralloc_device_ == nullptr) { 58 DLOGE("FATAL: gralloc device is null"); 59 return kErrorResources; 60 } 61 62 ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>( 63 gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE)); 64 Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>( 65 gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM)); 66 Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>( 67 gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK)); 68 Unlock_ = reinterpret_cast<GRALLOC1_PFN_UNLOCK>( 69 gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_UNLOCK)); 70 71 return kErrorNone; 72 } 73 74 DisplayError HWCBufferAllocator::Deinit() { 75 if (gralloc_device_ != nullptr) { 76 int err = gralloc1_close(gralloc_device_); 77 if (err != 0) { 78 DLOGE("FATAL: can not close GRALLOC device"); 79 return kErrorResources; 80 } 81 } 82 return kErrorNone; 83 } 84 85 DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) { 86 const BufferConfig &buffer_config = buffer_info->buffer_config; 87 AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info; 88 uint32_t width = buffer_config.width; 89 uint32_t height = buffer_config.height; 90 int format; 91 uint64_t alloc_flags = 0; 92 int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags); 93 if (error != 0) { 94 return kErrorParameters; 95 } 96 97 if (buffer_config.secure) { 98 alloc_flags |= GRALLOC1_PRODUCER_USAGE_PROTECTED; 99 } 100 101 if (buffer_config.secure_camera) { 102 alloc_flags |= GRALLOC1_PRODUCER_USAGE_CAMERA; 103 } 104 105 if (!buffer_config.cache) { 106 // Allocate uncached buffers 107 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED; 108 } 109 110 if (buffer_config.gfx_client) { 111 alloc_flags |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE; 112 } 113 114 uint64_t producer_usage = alloc_flags; 115 uint64_t consumer_usage = (alloc_flags | GRALLOC1_CONSUMER_USAGE_HWCOMPOSER); 116 // CreateBuffer 117 private_handle_t *hnd = nullptr; 118 Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format, 119 producer_usage, consumer_usage, &hnd); 120 121 if (hnd) { 122 alloc_buffer_info->fd = hnd->fd; 123 alloc_buffer_info->stride = UINT32(hnd->width); 124 alloc_buffer_info->aligned_width = UINT32(hnd->width); 125 alloc_buffer_info->aligned_height = UINT32(hnd->height); 126 alloc_buffer_info->size = hnd->size; 127 } else { 128 DLOGE("Failed to allocate memory"); 129 return kErrorMemory; 130 } 131 132 buffer_info->private_data = reinterpret_cast<void *>(hnd); 133 return kErrorNone; 134 } 135 136 DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) { 137 DisplayError err = kErrorNone; 138 buffer_handle_t hnd = static_cast<private_handle_t *>(buffer_info->private_data); 139 ReleaseBuffer_(gralloc_device_, hnd); 140 AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info; 141 142 alloc_buffer_info->fd = -1; 143 alloc_buffer_info->stride = 0; 144 alloc_buffer_info->size = 0; 145 buffer_info->private_data = NULL; 146 return err; 147 } 148 149 void HWCBufferAllocator::GetCustomWidthAndHeight(const private_handle_t *handle, int *width, 150 int *height) { 151 Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE, handle, 152 width, height); 153 } 154 155 void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int format, 156 uint32_t alloc_type, int *aligned_width, 157 int *aligned_height) { 158 int tile_enabled; 159 gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE; 160 gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE; 161 if (alloc_type & GRALLOC_USAGE_HW_FB) { 162 consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET; 163 } 164 if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) { 165 producer_usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 166 } 167 168 Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format, 169 producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled); 170 } 171 172 uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) { 173 const BufferConfig &buffer_config = buffer_info->buffer_config; 174 uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP; 175 176 int width = INT(buffer_config.width); 177 int height = INT(buffer_config.height); 178 int format; 179 180 if (buffer_config.secure) { 181 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED); 182 } 183 184 if (!buffer_config.cache) { 185 // Allocate uncached buffers 186 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED; 187 } 188 189 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) { 190 return 0; 191 } 192 193 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0; 194 gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE; 195 gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE; 196 // TODO(user): Currently both flags are treated similarly in gralloc 197 producer_usage = gralloc1_producer_usage_t(alloc_flags); 198 consumer_usage = gralloc1_consumer_usage_t(alloc_flags); 199 gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage); 200 GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height); 201 return buffer_size; 202 } 203 204 int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags) { 205 switch (format) { 206 case kFormatRGBA8888: 207 *target = HAL_PIXEL_FORMAT_RGBA_8888; 208 break; 209 case kFormatRGBX8888: 210 *target = HAL_PIXEL_FORMAT_RGBX_8888; 211 break; 212 case kFormatRGB888: 213 *target = HAL_PIXEL_FORMAT_RGB_888; 214 break; 215 case kFormatRGB565: 216 *target = HAL_PIXEL_FORMAT_RGB_565; 217 break; 218 case kFormatBGR565: 219 *target = HAL_PIXEL_FORMAT_BGR_565; 220 break; 221 case kFormatBGR888: 222 *target = HAL_PIXEL_FORMAT_BGR_888; 223 break; 224 case kFormatBGRA8888: 225 *target = HAL_PIXEL_FORMAT_BGRA_8888; 226 break; 227 case kFormatYCrCb420PlanarStride16: 228 *target = HAL_PIXEL_FORMAT_YV12; 229 break; 230 case kFormatYCrCb420SemiPlanar: 231 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP; 232 break; 233 case kFormatYCbCr420SemiPlanar: 234 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP; 235 break; 236 case kFormatYCbCr422H2V1Packed: 237 *target = HAL_PIXEL_FORMAT_YCbCr_422_I; 238 break; 239 case kFormatCbYCrY422H2V1Packed: 240 *target = HAL_PIXEL_FORMAT_CbYCrY_422_I; 241 break; 242 case kFormatYCbCr422H2V1SemiPlanar: 243 *target = HAL_PIXEL_FORMAT_YCbCr_422_SP; 244 break; 245 case kFormatYCbCr420SemiPlanarVenus: 246 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; 247 break; 248 case kFormatYCrCb420SemiPlanarVenus: 249 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS; 250 break; 251 case kFormatYCbCr420SPVenusUbwc: 252 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC; 253 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 254 break; 255 case kFormatRGBA5551: 256 *target = HAL_PIXEL_FORMAT_RGBA_5551; 257 break; 258 case kFormatRGBA4444: 259 *target = HAL_PIXEL_FORMAT_RGBA_4444; 260 break; 261 case kFormatRGBA1010102: 262 *target = HAL_PIXEL_FORMAT_RGBA_1010102; 263 break; 264 case kFormatARGB2101010: 265 *target = HAL_PIXEL_FORMAT_ARGB_2101010; 266 break; 267 case kFormatRGBX1010102: 268 *target = HAL_PIXEL_FORMAT_RGBX_1010102; 269 break; 270 case kFormatXRGB2101010: 271 *target = HAL_PIXEL_FORMAT_XRGB_2101010; 272 break; 273 case kFormatBGRA1010102: 274 *target = HAL_PIXEL_FORMAT_BGRA_1010102; 275 break; 276 case kFormatABGR2101010: 277 *target = HAL_PIXEL_FORMAT_ABGR_2101010; 278 break; 279 case kFormatBGRX1010102: 280 *target = HAL_PIXEL_FORMAT_BGRX_1010102; 281 break; 282 case kFormatXBGR2101010: 283 *target = HAL_PIXEL_FORMAT_XBGR_2101010; 284 break; 285 case kFormatYCbCr420P010: 286 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010; 287 break; 288 case kFormatYCbCr420TP10Ubwc: 289 *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC; 290 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 291 break; 292 case kFormatYCbCr420P010Ubwc: 293 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC; 294 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 295 break; 296 case kFormatRGBA8888Ubwc: 297 *target = HAL_PIXEL_FORMAT_RGBA_8888; 298 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 299 break; 300 case kFormatRGBX8888Ubwc: 301 *target = HAL_PIXEL_FORMAT_RGBX_8888; 302 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 303 break; 304 case kFormatBGR565Ubwc: 305 *target = HAL_PIXEL_FORMAT_BGR_565; 306 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 307 break; 308 case kFormatRGBA1010102Ubwc: 309 *target = HAL_PIXEL_FORMAT_RGBA_1010102; 310 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 311 break; 312 case kFormatRGBX1010102Ubwc: 313 *target = HAL_PIXEL_FORMAT_RGBX_1010102; 314 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 315 break; 316 default: 317 DLOGE("Unsupported format = 0x%x", format); 318 return -EINVAL; 319 } 320 return 0; 321 } 322 323 DisplayError HWCBufferAllocator::GetAllocatedBufferInfo( 324 const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) { 325 // TODO(user): This API should pass the buffer_info of the already allocated buffer 326 // The private_data can then be typecast to the private_handle and used directly. 327 uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP; 328 329 int width = INT(buffer_config.width); 330 int height = INT(buffer_config.height); 331 int format; 332 333 if (buffer_config.secure) { 334 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED); 335 } 336 337 if (!buffer_config.cache) { 338 // Allocate uncached buffers 339 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED; 340 } 341 342 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) { 343 return kErrorParameters; 344 } 345 346 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0; 347 gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE; 348 gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE; 349 // TODO(user): Currently both flags are treated similarly in gralloc 350 producer_usage = gralloc1_producer_usage_t(alloc_flags); 351 consumer_usage = gralloc1_consumer_usage_t(alloc_flags); 352 gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage); 353 GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height); 354 allocated_buffer_info->stride = UINT32(aligned_width); 355 allocated_buffer_info->aligned_width = UINT32(aligned_width); 356 allocated_buffer_info->aligned_height = UINT32(aligned_height); 357 allocated_buffer_info->size = UINT32(buffer_size); 358 359 return kErrorNone; 360 } 361 362 DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info, 363 uint32_t stride[4], uint32_t offset[4], 364 uint32_t *num_planes) { 365 // TODO(user): Transition APIs to not need a private handle 366 private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0); 367 int format = HAL_PIXEL_FORMAT_RGBA_8888; 368 uint64_t flags = 0; 369 370 SetBufferInfo(buf_info.format, &format, &flags); 371 // Setup only the required stuff, skip rest 372 hnd.format = format; 373 hnd.width = INT32(buf_info.aligned_width); 374 hnd.height = INT32(buf_info.aligned_height); 375 if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) { 376 hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 377 } 378 379 int ret = gralloc1::GetBufferLayout(&hnd, stride, offset, num_planes); 380 if (ret < 0) { 381 DLOGE("GetBufferLayout failed"); 382 return kErrorParameters; 383 } 384 385 return kErrorNone; 386 } 387 388 DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) { 389 void* buffer_ptr = NULL; 390 const gralloc1_rect_t accessRegion = { 391 .left = 0, 392 .top = 0, 393 .width = 0, 394 .height = 0 395 }; 396 Lock_(gralloc_device_, handle, GRALLOC1_PRODUCER_USAGE_CPU_READ, GRALLOC1_CONSUMER_USAGE_NONE, 397 &accessRegion, &buffer_ptr, acquire_fence); 398 if (!buffer_ptr) { 399 return kErrorUndefined; 400 } 401 402 return kErrorNone; 403 } 404 405 DisplayError HWCBufferAllocator::UnmapBuffer(const private_handle_t *handle, int* release_fence) { 406 return (DisplayError)(Unlock_(gralloc_device_, handle, release_fence)); 407 } 408 409 } // namespace sdm 410