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 }, 322 }; 323