Home | History | Annotate | Download | only in gralloc
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <hardware/gralloc.h>
     18 #include <hardware/hardware.h>
     19 #include <log/log.h>
     20 #include <stdlib.h>
     21 
     22 #include "guest/libs/platform_support/api_level_fixes.h"
     23 
     24 #include "guest/hals/gralloc/gralloc_vsoc_priv.h"
     25 #include "guest/vsoc/lib/gralloc_region_view.h"
     26 
     27 using vsoc::gralloc::GrallocRegionView;
     28 
     29 namespace {
     30 
     31 static const int kSwiftShaderPadding = 4;
     32 
     33 inline void formatToYcbcr(
     34     int format, int width, int height, void* base_v, android_ycbcr* ycbcr) {
     35   uintptr_t it = reinterpret_cast<uintptr_t>(base_v);
     36   // Clear reserved fields;
     37   memset(ycbcr, 0, sizeof(*ycbcr));
     38   switch (format) {
     39     case HAL_PIXEL_FORMAT_YV12:
     40     case HAL_PIXEL_FORMAT_YCbCr_420_888:
     41       ycbcr->ystride = align(width, 16);
     42       ycbcr->cstride = align(ycbcr->ystride / 2, 16);
     43       ycbcr->chroma_step = 1;
     44       ycbcr->y = reinterpret_cast<void*>(it);
     45       it += ycbcr->ystride * height;
     46       ycbcr->cr = reinterpret_cast<void*>(it);
     47       it += ycbcr->cstride * height / 2;
     48       ycbcr->cb = reinterpret_cast<void*>(it);
     49       break;
     50     default:
     51       ALOGE("%s: can't deal with format=0x%x", __FUNCTION__, format);
     52   }
     53 }
     54 
     55 inline int formatToBytesPerPixel(int format) {
     56   switch (format) {
     57 #if VSOC_PLATFORM_SDK_AFTER(N_MR1)
     58     case HAL_PIXEL_FORMAT_RGBA_FP16:
     59       return 8;
     60 #endif
     61     case HAL_PIXEL_FORMAT_RGBA_8888:
     62     case HAL_PIXEL_FORMAT_RGBX_8888:
     63     case HAL_PIXEL_FORMAT_BGRA_8888:
     64     // The camera 3.0 implementation assumes that IMPLEMENTATION_DEFINED
     65     // means HAL_PIXEL_FORMAT_RGBA_8888
     66     case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
     67       return 4;
     68     case HAL_PIXEL_FORMAT_RGB_888:
     69       return 3;
     70     case HAL_PIXEL_FORMAT_RGB_565:
     71     case HAL_PIXEL_FORMAT_YV12:
     72     case HAL_PIXEL_FORMAT_YCbCr_420_888:
     73       return 2;
     74     case HAL_PIXEL_FORMAT_BLOB:
     75       return 1;
     76     default:
     77       ALOGE("%s: unknown format=%d", __FUNCTION__, format);
     78       return 8;
     79   }
     80 }
     81 
     82 inline int formatToBytesPerFrame(int format, int w, int h) {
     83   int bytes_per_pixel = formatToBytesPerPixel(format);
     84   int w16, h16;
     85   int y_size, c_size;
     86 
     87   switch (format) {
     88     // BLOB is used to allocate buffers for JPEG formatted data. Bytes per pixel
     89     // is 1, the desired buffer size is in w, and h should be 1. We refrain from
     90     // adding additional padding, although the caller is likely to round
     91     // up to a page size.
     92     case HAL_PIXEL_FORMAT_BLOB:
     93       return bytes_per_pixel * w * h;
     94     case HAL_PIXEL_FORMAT_YV12:
     95     case HAL_PIXEL_FORMAT_YCbCr_420_888:
     96       android_ycbcr strides;
     97       formatToYcbcr(format, w, h, NULL, &strides);
     98       y_size = strides.ystride * h;
     99       c_size = strides.cstride * h / 2;
    100       return (y_size + 2 * c_size + kSwiftShaderPadding);
    101     /*case HAL_PIXEL_FORMAT_RGBA_8888:
    102     case HAL_PIXEL_FORMAT_RGBX_8888:
    103     case HAL_PIXEL_FORMAT_BGRA_8888:
    104     case HAL_PIXEL_FORMAT_RGB_888:
    105     case HAL_PIXEL_FORMAT_RGB_565:*/
    106     default:
    107       w16 = align(w, 16);
    108       h16 = align(h, 16);
    109       return bytes_per_pixel * w16 * h16 + kSwiftShaderPadding;
    110   }
    111 }
    112 
    113 }
    114 
    115 /******************************************************************************/
    116 
    117 void dump(struct alloc_device_t */*dev*/, char */*buff*/, int /*buff_len*/) {}
    118 
    119 /******************************************************************************/
    120 
    121 int lock(struct gralloc_module_t const* /*module*/,
    122          buffer_handle_t handle,
    123          int /*usage*/,
    124          int /*l*/,
    125          int /*t*/,
    126          int /*w*/,
    127          int /*h*/,
    128          void** vaddr) {
    129   if (!vaddr || vsoc_buffer_handle_t::validate(handle)) {
    130     return -EINVAL;
    131   }
    132   // TODO(jemoreira): Check allocation usage flags against requested usage.
    133   const vsoc_buffer_handle_t* hnd =
    134       reinterpret_cast<const vsoc_buffer_handle_t*>(handle);
    135   void* mapped = reference_buffer(hnd);
    136   if (mapped == NULL) {
    137     ALOGE("Unable to reference buffer, %s", __FUNCTION__);
    138     return -1;
    139   }
    140   *vaddr = mapped;
    141   return 0;
    142 }
    143 
    144 int unlock(struct gralloc_module_t const* /*module*/, buffer_handle_t handle) {
    145   if (vsoc_buffer_handle_t::validate(handle)) {
    146     return -EINVAL;
    147   }
    148   return unreference_buffer(
    149       reinterpret_cast<const vsoc_buffer_handle_t*>(handle));
    150 }
    151 
    152 int lock_ycbcr(struct gralloc_module_t const* module,
    153                buffer_handle_t handle,
    154                int usage,
    155                int l,
    156                int t,
    157                int w,
    158                int h,
    159                struct android_ycbcr* ycbcr) {
    160   void* mapped;
    161   int retval = lock(module, handle, usage, l, t, w, h, &mapped);
    162   if (retval) {
    163     return retval;
    164   }
    165   const vsoc_buffer_handle_t* hnd =
    166       reinterpret_cast<const vsoc_buffer_handle_t*>(handle);
    167   formatToYcbcr(hnd->format, w, h, mapped, ycbcr);
    168   return 0;
    169 }
    170 
    171 /******************************************************************************/
    172 
    173 static int gralloc_alloc(alloc_device_t* /*dev*/,
    174                          int w,
    175                          int h,
    176                          int format,
    177                          int /*usage*/,
    178                          buffer_handle_t* pHandle,
    179                          int* pStrideInPixels) {
    180   int fd = -1;
    181 
    182   int bytes_per_pixel = formatToBytesPerPixel(format);
    183   int bytes_per_line;
    184   int stride_in_pixels;
    185   int size = 0;
    186   uint32_t offset = 0;
    187   // SwiftShader can't handle RGB_888, so fail fast and hard if we try to create
    188   // a gralloc buffer in this format.
    189   ALOG_ASSERT(format != HAL_PIXEL_FORMAT_RGB_888);
    190   if (format == HAL_PIXEL_FORMAT_YV12) {
    191     bytes_per_line = align(bytes_per_pixel * w, 16);
    192   } else {
    193     bytes_per_line = align(bytes_per_pixel * w, 8);
    194   }
    195   size = align(size + formatToBytesPerFrame(format, w, h), PAGE_SIZE);
    196   size += PAGE_SIZE;
    197   fd = GrallocRegionView::GetInstance()->AllocateBuffer(size, &offset);
    198   if (fd < 0) {
    199     ALOGE("Unable to allocate buffer (%s)", strerror(-fd));
    200     return fd;
    201   }
    202 
    203   stride_in_pixels = bytes_per_line / bytes_per_pixel;
    204   vsoc_buffer_handle_t* hnd = new vsoc_buffer_handle_t(fd,
    205                                                        offset,
    206                                                        size,
    207                                                        format,
    208                                                        w, h,
    209                                                        stride_in_pixels);
    210   void* addr =
    211       reference_buffer(reinterpret_cast<const vsoc_buffer_handle_t*>(hnd));
    212   if (!addr) {
    213     ALOGE("Unable to reference buffer, %s", __FUNCTION__);
    214     return -EIO;
    215   }
    216 
    217   *pHandle = hnd;
    218   *pStrideInPixels = stride_in_pixels;
    219 
    220   return 0;
    221 }
    222 
    223 static int gralloc_free(alloc_device_t* /*dev*/, buffer_handle_t handle) {
    224   // No need to do anything else, the buffer will be atomatically deallocated
    225   // when the handle is closed.
    226   return unreference_buffer(
    227       reinterpret_cast<const vsoc_buffer_handle_t*>(handle));
    228 }
    229 
    230 static int register_buffer(struct gralloc_module_t const* /*module*/,
    231                           buffer_handle_t handle) {
    232   if (vsoc_buffer_handle_t::validate(handle)) {
    233     return -EINVAL;
    234   }
    235   void* addr =
    236       reference_buffer(reinterpret_cast<const vsoc_buffer_handle_t*>(handle));
    237   if (!addr) {
    238     ALOGE("Unable to reference buffer, %s", __FUNCTION__);
    239     return -EIO;
    240   }
    241   return 0;
    242 }
    243 
    244 int unregister_buffer(struct gralloc_module_t const* /*module*/,
    245                      buffer_handle_t handle) {
    246   if (vsoc_buffer_handle_t::validate(handle)) {
    247     return -EINVAL;
    248   }
    249   return unreference_buffer(
    250       reinterpret_cast<const vsoc_buffer_handle_t*>(handle));
    251 }
    252 
    253 /******************************************************************************/
    254 
    255 static int gralloc_device_close(struct hw_device_t *dev) {
    256   vsoc_alloc_device_t* pdev = reinterpret_cast<vsoc_alloc_device_t*>(dev);
    257   if (pdev) {
    258     free(pdev);
    259   }
    260   return 0;
    261 }
    262 
    263 static int gralloc_device_open(
    264     const hw_module_t* module, const char* name, hw_device_t** device) {
    265     int status = -EINVAL;
    266   if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
    267     vsoc_alloc_device_t *dev;
    268     dev = (vsoc_alloc_device_t*) malloc(sizeof(*dev));
    269     LOG_FATAL_IF(!dev, "%s: malloc returned NULL.", __FUNCTION__);
    270 
    271     /* initialize our state here */
    272     memset(dev, 0, sizeof(*dev));
    273 
    274     /* initialize the procs */
    275     dev->device.common.tag = HARDWARE_DEVICE_TAG;
    276     dev->device.common.version = 0; // TODO(jemoreira): Bump to 0_2 when stable
    277     dev->device.common.module = const_cast<hw_module_t*>(module);
    278     dev->device.common.close = gralloc_device_close;
    279 
    280     dev->device.alloc   = gralloc_alloc;
    281     dev->device.free    = gralloc_free;
    282 
    283     if (!GrallocRegionView::GetInstance()) {
    284       LOG_FATAL("Unable to instantiate the gralloc region");
    285       free(dev);
    286       return -EIO;
    287     }
    288 
    289     *device = &dev->device.common;
    290     status = 0;
    291   }
    292   // TODO(jemoreira): Consider opening other type of devices (framebuffer)
    293   return status;
    294 }
    295 
    296 /******************************************************************************/
    297 
    298 static struct hw_module_methods_t gralloc_module_methods = {
    299   .open = gralloc_device_open
    300 };
    301 
    302 struct vsoc_gralloc_module_t HAL_MODULE_INFO_SYM = {
    303   .base = {
    304     .common = {
    305       .tag = HARDWARE_MODULE_TAG,
    306       .version_major = GRALLOC_MODULE_API_VERSION_0_2,
    307       .version_minor = 0,
    308       .id = GRALLOC_HARDWARE_MODULE_ID,
    309       .name = "VSoC X86 Graphics Memory Allocator Module",
    310       .author = "The Android Open Source Project",
    311       .methods = &gralloc_module_methods,
    312       .dso = NULL,
    313       .reserved = {0},
    314     },
    315     .registerBuffer = register_buffer,
    316     .unregisterBuffer = unregister_buffer,
    317     .lock = lock,
    318     .unlock = unlock,
    319     .lock_ycbcr = lock_ycbcr,
    320     .perform = NULL,
    321     .validateBufferSize = NULL,
    322     .getTransportSize = NULL,
    323   },
    324 };
    325