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 HWCBufferAllocator::HWCBufferAllocator() { 45 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module_); 46 if (err != 0) { 47 DLOGE("FATAL: can not open GRALLOC module"); 48 } else { 49 gralloc1_open(module_, &gralloc_device_); 50 } 51 if (gralloc_device_ != nullptr) { 52 ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>( 53 gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE)); 54 Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>( 55 gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM)); 56 Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>( 57 gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK)); 58 } 59 } 60 61 HWCBufferAllocator::~HWCBufferAllocator() { 62 if (gralloc_device_ != nullptr) { 63 gralloc1_close(gralloc_device_); 64 } 65 } 66 67 DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) { 68 const BufferConfig &buffer_config = buffer_info->buffer_config; 69 AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info; 70 uint32_t width = buffer_config.width; 71 uint32_t height = buffer_config.height; 72 int format; 73 uint64_t alloc_flags = 0; 74 int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags); 75 if (error != 0) { 76 return kErrorParameters; 77 } 78 79 if (buffer_config.secure) { 80 alloc_flags |= GRALLOC1_PRODUCER_USAGE_PROTECTED; 81 } 82 83 if (!buffer_config.cache) { 84 // Allocate uncached buffers 85 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED; 86 } 87 88 if (buffer_config.gfx_client) { 89 alloc_flags |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE; 90 } 91 92 uint64_t producer_usage = alloc_flags; 93 uint64_t consumer_usage = alloc_flags; 94 // CreateBuffer 95 private_handle_t *hnd = nullptr; 96 Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format, 97 producer_usage, consumer_usage, &hnd); 98 99 if (hnd) { 100 alloc_buffer_info->fd = hnd->fd; 101 alloc_buffer_info->stride = UINT32(hnd->width); 102 alloc_buffer_info->size = hnd->size; 103 } else { 104 DLOGE("Failed to allocate memory"); 105 return kErrorMemory; 106 } 107 108 buffer_info->private_data = reinterpret_cast<void *>(hnd); 109 return kErrorNone; 110 } 111 112 DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) { 113 DisplayError err = kErrorNone; 114 buffer_handle_t hnd = static_cast<private_handle_t *>(buffer_info->private_data); 115 ReleaseBuffer_(gralloc_device_, hnd); 116 AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info; 117 118 alloc_buffer_info->fd = -1; 119 alloc_buffer_info->stride = 0; 120 alloc_buffer_info->size = 0; 121 buffer_info->private_data = NULL; 122 return err; 123 } 124 125 void HWCBufferAllocator::GetCustomWidthAndHeight(const private_handle_t *handle, int *width, 126 int *height) { 127 Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE, handle, 128 width, height); 129 } 130 131 void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int format, 132 uint32_t alloc_type, int *aligned_width, 133 int *aligned_height) { 134 int tile_enabled; 135 gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE; 136 gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE; 137 if (alloc_type & GRALLOC_USAGE_HW_FB) { 138 consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET; 139 } 140 if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) { 141 producer_usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 142 } 143 144 Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format, 145 producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled); 146 } 147 148 uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) { 149 const BufferConfig &buffer_config = buffer_info->buffer_config; 150 uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP; 151 152 int width = INT(buffer_config.width); 153 int height = INT(buffer_config.height); 154 int format; 155 156 if (buffer_config.secure) { 157 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED); 158 } 159 160 if (!buffer_config.cache) { 161 // Allocate uncached buffers 162 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED; 163 } 164 165 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) { 166 return 0; 167 } 168 169 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0; 170 gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE; 171 gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE; 172 // TODO(user): Currently both flags are treated similarly in gralloc 173 producer_usage = gralloc1_producer_usage_t(alloc_flags); 174 consumer_usage = gralloc1_consumer_usage_t(alloc_flags); 175 gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage); 176 GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height); 177 return buffer_size; 178 } 179 180 int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags) { 181 switch (format) { 182 case kFormatRGBA8888: 183 *target = HAL_PIXEL_FORMAT_RGBA_8888; 184 break; 185 case kFormatRGBX8888: 186 *target = HAL_PIXEL_FORMAT_RGBX_8888; 187 break; 188 case kFormatRGB888: 189 *target = HAL_PIXEL_FORMAT_RGB_888; 190 break; 191 case kFormatRGB565: 192 *target = HAL_PIXEL_FORMAT_RGB_565; 193 break; 194 case kFormatBGR565: 195 *target = HAL_PIXEL_FORMAT_BGR_565; 196 break; 197 case kFormatBGR888: 198 *target = HAL_PIXEL_FORMAT_BGR_888; 199 break; 200 case kFormatBGRA8888: 201 *target = HAL_PIXEL_FORMAT_BGRA_8888; 202 break; 203 case kFormatYCrCb420PlanarStride16: 204 *target = HAL_PIXEL_FORMAT_YV12; 205 break; 206 case kFormatYCrCb420SemiPlanar: 207 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP; 208 break; 209 case kFormatYCbCr420SemiPlanar: 210 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP; 211 break; 212 case kFormatYCbCr422H2V1Packed: 213 *target = HAL_PIXEL_FORMAT_YCbCr_422_I; 214 break; 215 case kFormatCbYCrY422H2V1Packed: 216 *target = HAL_PIXEL_FORMAT_CbYCrY_422_I; 217 break; 218 case kFormatYCbCr422H2V1SemiPlanar: 219 *target = HAL_PIXEL_FORMAT_YCbCr_422_SP; 220 break; 221 case kFormatYCbCr420SemiPlanarVenus: 222 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; 223 break; 224 case kFormatYCrCb420SemiPlanarVenus: 225 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS; 226 break; 227 case kFormatYCbCr420SPVenusUbwc: 228 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC; 229 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 230 break; 231 case kFormatRGBA5551: 232 *target = HAL_PIXEL_FORMAT_RGBA_5551; 233 break; 234 case kFormatRGBA4444: 235 *target = HAL_PIXEL_FORMAT_RGBA_4444; 236 break; 237 case kFormatRGBA1010102: 238 *target = HAL_PIXEL_FORMAT_RGBA_1010102; 239 break; 240 case kFormatARGB2101010: 241 *target = HAL_PIXEL_FORMAT_ARGB_2101010; 242 break; 243 case kFormatRGBX1010102: 244 *target = HAL_PIXEL_FORMAT_RGBX_1010102; 245 break; 246 case kFormatXRGB2101010: 247 *target = HAL_PIXEL_FORMAT_XRGB_2101010; 248 break; 249 case kFormatBGRA1010102: 250 *target = HAL_PIXEL_FORMAT_BGRA_1010102; 251 break; 252 case kFormatABGR2101010: 253 *target = HAL_PIXEL_FORMAT_ABGR_2101010; 254 break; 255 case kFormatBGRX1010102: 256 *target = HAL_PIXEL_FORMAT_BGRX_1010102; 257 break; 258 case kFormatXBGR2101010: 259 *target = HAL_PIXEL_FORMAT_XBGR_2101010; 260 break; 261 case kFormatYCbCr420P010: 262 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010; 263 break; 264 case kFormatYCbCr420TP10Ubwc: 265 *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC; 266 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 267 break; 268 case kFormatYCbCr420P010Ubwc: 269 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC; 270 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 271 break; 272 case kFormatRGBA8888Ubwc: 273 *target = HAL_PIXEL_FORMAT_RGBA_8888; 274 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 275 break; 276 case kFormatRGBX8888Ubwc: 277 *target = HAL_PIXEL_FORMAT_RGBX_8888; 278 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 279 break; 280 case kFormatBGR565Ubwc: 281 *target = HAL_PIXEL_FORMAT_BGR_565; 282 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 283 break; 284 case kFormatRGBA1010102Ubwc: 285 *target = HAL_PIXEL_FORMAT_RGBA_1010102; 286 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 287 break; 288 case kFormatRGBX1010102Ubwc: 289 *target = HAL_PIXEL_FORMAT_RGBX_1010102; 290 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 291 break; 292 default: 293 DLOGE("Unsupported format = 0x%x", format); 294 return -EINVAL; 295 } 296 return 0; 297 } 298 299 DisplayError HWCBufferAllocator::GetAllocatedBufferInfo( 300 const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) { 301 // TODO(user): This API should pass the buffer_info of the already allocated buffer 302 // The private_data can then be typecast to the private_handle and used directly. 303 uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP; 304 305 int width = INT(buffer_config.width); 306 int height = INT(buffer_config.height); 307 int format; 308 309 if (buffer_config.secure) { 310 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED); 311 } 312 313 if (!buffer_config.cache) { 314 // Allocate uncached buffers 315 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED; 316 } 317 318 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) { 319 return kErrorParameters; 320 } 321 322 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0; 323 gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE; 324 gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE; 325 // TODO(user): Currently both flags are treated similarly in gralloc 326 producer_usage = gralloc1_producer_usage_t(alloc_flags); 327 consumer_usage = gralloc1_consumer_usage_t(alloc_flags); 328 gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage); 329 GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height); 330 allocated_buffer_info->stride = UINT32(aligned_width); 331 allocated_buffer_info->aligned_width = UINT32(aligned_width); 332 allocated_buffer_info->aligned_height = UINT32(aligned_height); 333 allocated_buffer_info->size = UINT32(buffer_size); 334 335 return kErrorNone; 336 } 337 338 DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info, 339 uint32_t stride[4], uint32_t offset[4], 340 uint32_t *num_planes) { 341 // TODO(user): Transition APIs to not need a private handle 342 private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0); 343 int format = HAL_PIXEL_FORMAT_RGBA_8888; 344 uint64_t flags = 0; 345 346 SetBufferInfo(buf_info.format, &format, &flags); 347 // Setup only the required stuff, skip rest 348 hnd.format = format; 349 hnd.width = INT32(buf_info.aligned_width); 350 hnd.height = INT32(buf_info.aligned_height); 351 if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) { 352 hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 353 } 354 355 int ret = gralloc1::GetBufferLayout(&hnd, stride, offset, num_planes); 356 if (ret < 0) { 357 DLOGE("GetBufferLayout failed"); 358 return kErrorParameters; 359 } 360 361 return kErrorNone; 362 } 363 364 DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) { 365 void* buffer_ptr = NULL; 366 const gralloc1_rect_t accessRegion = { 367 .left = 0, 368 .top = 0, 369 .width = 0, 370 .height = 0 371 }; 372 Lock_(gralloc_device_, handle, GRALLOC1_PRODUCER_USAGE_CPU_READ, GRALLOC1_CONSUMER_USAGE_NONE, 373 &accessRegion, &buffer_ptr, acquire_fence); 374 if (!buffer_ptr) { 375 return kErrorUndefined; 376 } 377 378 return kErrorNone; 379 } 380 381 } // namespace sdm 382