Home | History | Annotate | Download | only in hwc2
      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