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