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