1 /* 2 * Copyright (C) 2016 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 #include <limits.h> 17 #include <unistd.h> 18 #include <fcntl.h> 19 #include <errno.h> 20 #include <pthread.h> 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include <sys/mman.h> 25 #include <sys/stat.h> 26 #include <sys/types.h> 27 #include <sys/ioctl.h> 28 29 #include <cutils/ashmem.h> 30 #include <log/log.h> 31 #include <cutils/atomic.h> 32 #include <utils/String8.h> 33 34 #include <hardware/hardware.h> 35 #include <hardware/gralloc.h> 36 37 #include <guest/libs/platform_support/api_level_fixes.h> 38 39 #include "common/libs/auto_resources/auto_resources.h" 40 #include "common/vsoc/lib/screen_region_view.h" 41 #include "gralloc_vsoc_priv.h" 42 #include "region_registry.h" 43 44 using vsoc::screen::ScreenRegionView; 45 46 /*****************************************************************************/ 47 48 static inline size_t roundUpToPageSize(size_t x) { 49 return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); 50 } 51 52 static int gralloc_alloc_buffer( 53 alloc_device_t* /*dev*/, int format, int w, int h, 54 buffer_handle_t* pHandle, int* pStrideInPixels) { 55 int err = 0; 56 int fd = -1; 57 static int sequence = 0; 58 59 int bytes_per_pixel = formatToBytesPerPixel(format); 60 int bytes_per_line; 61 int stride_in_pixels; 62 int size = 0; 63 // SwiftShader can't handle RGB_888, so fail fast and hard if we try to create 64 // a gralloc buffer in this format. 65 ALOG_ASSERT(format != HAL_PIXEL_FORMAT_RGB_888); 66 if (format == HAL_PIXEL_FORMAT_YV12) { 67 bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w, 16); 68 } else { 69 bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w); 70 } 71 size = roundUpToPageSize(size + formatToBytesPerFrame(format, w, h)); 72 size += PAGE_SIZE; 73 fd = ashmem_create_region( 74 android::String8::format( 75 "gralloc-%d.%d", getpid(), sequence++).string(), 76 size); 77 if (fd < 0) { 78 ALOGE("couldn't create ashmem (%s)", strerror(-errno)); 79 err = -errno; 80 } 81 82 if (err == 0) { 83 stride_in_pixels = bytes_per_line / bytes_per_pixel; 84 private_handle_t* hnd = 85 new private_handle_t(fd, size, format, w, h, stride_in_pixels, 0); 86 void* base = reference_region(__FUNCTION__, hnd); 87 if (base) { 88 *pHandle = hnd; 89 *pStrideInPixels = stride_in_pixels; 90 } else { 91 err = -EIO; 92 } 93 } 94 95 ALOGE_IF(err, "gralloc failed err=%s", strerror(-err)); 96 97 return err; 98 } 99 100 /*****************************************************************************/ 101 102 static int gralloc_alloc(alloc_device_t* dev, int w, int h, int format, 103 int /*usage*/, buffer_handle_t* pHandle, 104 int* pStrideInPixels) { 105 if (!pHandle || !pStrideInPixels) 106 return -EINVAL; 107 108 int err = gralloc_alloc_buffer(dev, format, w, h, pHandle, pStrideInPixels); 109 110 if (err < 0) { 111 return err; 112 } 113 return 0; 114 } 115 116 static int gralloc_free(alloc_device_t* /*dev*/, buffer_handle_t handle) { 117 if (private_handle_t::validate(handle) < 0) { 118 return -EINVAL; 119 } 120 121 private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>( 122 handle); 123 int retval = unreference_region(__FUNCTION__, hnd); 124 125 close(hnd->fd); 126 delete hnd; 127 return retval; 128 } 129 130 /*****************************************************************************/ 131 132 static int gralloc_close(struct hw_device_t *dev) { 133 priv_alloc_device_t* ctx = reinterpret_cast<priv_alloc_device_t*>(dev); 134 if (ctx) { 135 /* TODO: keep a list of all buffer_handle_t created, and free them 136 * all here. 137 */ 138 free(ctx); 139 } 140 return 0; 141 } 142 143 static int gralloc_device_open( 144 const hw_module_t* module, const char* name, hw_device_t** device) { 145 int status = -EINVAL; 146 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) { 147 priv_alloc_device_t *dev; 148 dev = (priv_alloc_device_t*) malloc(sizeof(*dev)); 149 LOG_FATAL_IF(!dev, "%s: malloc returned NULL.", __FUNCTION__); 150 151 /* initialize our state here */ 152 memset(dev, 0, sizeof(*dev)); 153 154 /* initialize the procs */ 155 dev->device.common.tag = HARDWARE_DEVICE_TAG; 156 dev->device.common.version = 0; 157 dev->device.common.module = const_cast<hw_module_t*>(module); 158 dev->device.common.close = gralloc_close; 159 160 dev->device.alloc = gralloc_alloc; 161 dev->device.free = gralloc_free; 162 163 *device = &dev->device.common; 164 status = 0; 165 } else { 166 status = fb_device_open(module, name, device); 167 } 168 return status; 169 } 170 171 /*****************************************************************************/ 172 173 static struct hw_module_methods_t gralloc_module_methods = { 174 VSOC_STATIC_INITIALIZER(open) gralloc_device_open 175 }; 176 177 struct private_module_t HAL_MODULE_INFO_SYM = { 178 VSOC_STATIC_INITIALIZER(base) { 179 VSOC_STATIC_INITIALIZER(common) { 180 VSOC_STATIC_INITIALIZER(tag) HARDWARE_MODULE_TAG, 181 #ifdef GRALLOC_MODULE_API_VERSION_0_2 182 VSOC_STATIC_INITIALIZER(version_major) GRALLOC_MODULE_API_VERSION_0_2, 183 #else 184 VSOC_STATIC_INITIALIZER(version_major) 1, 185 #endif 186 VSOC_STATIC_INITIALIZER(version_minor) 0, 187 VSOC_STATIC_INITIALIZER(id) GRALLOC_HARDWARE_MODULE_ID, 188 VSOC_STATIC_INITIALIZER(name) "VSOC X86 Graphics Memory Allocator Module", 189 VSOC_STATIC_INITIALIZER(author) "The Android Open Source Project", 190 VSOC_STATIC_INITIALIZER(methods) &gralloc_module_methods, 191 VSOC_STATIC_INITIALIZER(dso) NULL, 192 VSOC_STATIC_INITIALIZER(reserved) {0}, 193 }, 194 VSOC_STATIC_INITIALIZER(registerBuffer) gralloc_register_buffer, 195 VSOC_STATIC_INITIALIZER(unregisterBuffer) gralloc_unregister_buffer, 196 VSOC_STATIC_INITIALIZER(lock) gralloc_lock, 197 VSOC_STATIC_INITIALIZER(unlock) gralloc_unlock, 198 VSOC_STATIC_INITIALIZER(validateBufferSize) NULL, 199 VSOC_STATIC_INITIALIZER(getTransportSize) NULL, 200 #ifdef GRALLOC_MODULE_API_VERSION_0_2 201 VSOC_STATIC_INITIALIZER(perform) NULL, 202 VSOC_STATIC_INITIALIZER(lock_ycbcr) gralloc_lock_ycbcr, 203 #endif 204 }, 205 }; 206