1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include <limits.h> 19 #include <errno.h> 20 #include <pthread.h> 21 #include <unistd.h> 22 #include <string.h> 23 #include <stdarg.h> 24 25 #include <sys/mman.h> 26 #include <sys/stat.h> 27 #include <sys/types.h> 28 #include <sys/ioctl.h> 29 #include <linux/ashmem.h> 30 31 #include <cutils/log.h> 32 #include <cutils/atomic.h> 33 #include <cutils/ashmem.h> 34 35 #include <hardware/hardware.h> 36 #include <hardware/gralloc.h> 37 #include <linux/android_pmem.h> 38 39 #include "gralloc_priv.h" 40 #include "gr.h" 41 #include "alloc_controller.h" 42 #include "memalloc.h" 43 #include <qdMetaData.h> 44 45 using namespace gralloc; 46 /*****************************************************************************/ 47 48 // Return the type of allocator - 49 // these are used for mapping/unmapping 50 static IMemAlloc* getAllocator(int flags) 51 { 52 IMemAlloc* memalloc; 53 IAllocController* alloc_ctrl = IAllocController::getInstance(); 54 memalloc = alloc_ctrl->getAllocator(flags); 55 return memalloc; 56 } 57 58 static int gralloc_map(gralloc_module_t const* module, 59 buffer_handle_t handle) 60 { 61 private_handle_t* hnd = (private_handle_t*)handle; 62 void *mappedAddress; 63 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) && 64 !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) { 65 size_t size = hnd->size; 66 IMemAlloc* memalloc = getAllocator(hnd->flags) ; 67 int err = memalloc->map_buffer(&mappedAddress, size, 68 hnd->offset, hnd->fd); 69 if(err || mappedAddress == MAP_FAILED) { 70 ALOGE("Could not mmap handle %p, fd=%d (%s)", 71 handle, hnd->fd, strerror(errno)); 72 hnd->base = 0; 73 return -errno; 74 } 75 76 hnd->base = intptr_t(mappedAddress) + hnd->offset; 77 mappedAddress = MAP_FAILED; 78 size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 79 err = memalloc->map_buffer(&mappedAddress, size, 80 hnd->offset_metadata, hnd->fd_metadata); 81 if(err || mappedAddress == MAP_FAILED) { 82 ALOGE("Could not mmap handle %p, fd=%d (%s)", 83 handle, hnd->fd_metadata, strerror(errno)); 84 hnd->base_metadata = 0; 85 return -errno; 86 } 87 hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata; 88 } 89 return 0; 90 } 91 92 static int gralloc_unmap(gralloc_module_t const* module, 93 buffer_handle_t handle) 94 { 95 private_handle_t* hnd = (private_handle_t*)handle; 96 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { 97 int err = -EINVAL; 98 void* base = (void*)hnd->base; 99 size_t size = hnd->size; 100 IMemAlloc* memalloc = getAllocator(hnd->flags) ; 101 if(memalloc != NULL) { 102 err = memalloc->unmap_buffer(base, size, hnd->offset); 103 if (err) { 104 ALOGE("Could not unmap memory at address %p", base); 105 } 106 base = (void*)hnd->base_metadata; 107 size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 108 err = memalloc->unmap_buffer(base, size, hnd->offset_metadata); 109 if (err) { 110 ALOGE("Could not unmap memory at address %p", base); 111 } 112 } 113 } 114 /* need to initialize the pointer to NULL otherwise unmapping for that 115 * buffer happens twice which leads to crash */ 116 hnd->base = 0; 117 hnd->base_metadata = 0; 118 return 0; 119 } 120 121 /*****************************************************************************/ 122 123 static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER; 124 125 /*****************************************************************************/ 126 127 int gralloc_register_buffer(gralloc_module_t const* module, 128 buffer_handle_t handle) 129 { 130 if (private_handle_t::validate(handle) < 0) 131 return -EINVAL; 132 133 // In this implementation, we don't need to do anything here 134 135 /* NOTE: we need to initialize the buffer as not mapped/not locked 136 * because it shouldn't when this function is called the first time 137 * in a new process. Ideally these flags shouldn't be part of the 138 * handle, but instead maintained in the kernel or at least 139 * out-of-line 140 */ 141 142 private_handle_t* hnd = (private_handle_t*)handle; 143 hnd->base = 0; 144 hnd->base_metadata = 0; 145 int err = gralloc_map(module, handle); 146 if (err) { 147 ALOGE("%s: gralloc_map failed", __FUNCTION__); 148 return err; 149 } 150 151 return 0; 152 } 153 154 int gralloc_unregister_buffer(gralloc_module_t const* module, 155 buffer_handle_t handle) 156 { 157 if (private_handle_t::validate(handle) < 0) 158 return -EINVAL; 159 160 /* 161 * If the buffer has been mapped during a lock operation, it's time 162 * to un-map it. It's an error to be here with a locked buffer. 163 * NOTE: the framebuffer is handled differently and is never unmapped. 164 */ 165 166 private_handle_t* hnd = (private_handle_t*)handle; 167 168 if (hnd->base != 0) { 169 gralloc_unmap(module, handle); 170 } 171 hnd->base = 0; 172 hnd->base_metadata = 0; 173 return 0; 174 } 175 176 int terminateBuffer(gralloc_module_t const* module, 177 private_handle_t* hnd) 178 { 179 /* 180 * If the buffer has been mapped during a lock operation, it's time 181 * to un-map it. It's an error to be here with a locked buffer. 182 */ 183 184 if (hnd->base != 0) { 185 // this buffer was mapped, unmap it now 186 if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM | 187 private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP | 188 private_handle_t::PRIV_FLAGS_USES_ASHMEM | 189 private_handle_t::PRIV_FLAGS_USES_ION)) { 190 gralloc_unmap(module, hnd); 191 } else { 192 ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x", 193 hnd->flags); 194 gralloc_unmap(module, hnd); 195 } 196 } 197 198 return 0; 199 } 200 201 static int gralloc_map_and_invalidate (gralloc_module_t const* module, 202 buffer_handle_t handle, int usage, 203 int l, int t, int w, int h) 204 { 205 if (private_handle_t::validate(handle) < 0) 206 return -EINVAL; 207 208 int err = 0; 209 private_handle_t* hnd = (private_handle_t*)handle; 210 if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { 211 if (hnd->base == 0) { 212 // we need to map for real 213 pthread_mutex_t* const lock = &sMapLock; 214 pthread_mutex_lock(lock); 215 err = gralloc_map(module, handle); 216 pthread_mutex_unlock(lock); 217 } 218 //Invalidate if reading in software. No need to do this for the metadata 219 //buffer as it is only read/written in software. 220 IMemAlloc* memalloc = getAllocator(hnd->flags) ; 221 err = memalloc->clean_buffer((void*)hnd->base, 222 hnd->size, hnd->offset, hnd->fd, 223 CACHE_INVALIDATE); 224 if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) && 225 !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { 226 // Mark the buffer to be flushed after cpu read/write 227 hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 228 } 229 } else { 230 hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; 231 } 232 return err; 233 } 234 235 int gralloc_lock(gralloc_module_t const* module, 236 buffer_handle_t handle, int usage, 237 int l, int t, int w, int h, 238 void** vaddr) 239 { 240 private_handle_t* hnd = (private_handle_t*)handle; 241 int err = gralloc_map_and_invalidate(module, handle, usage, l, t, w, h); 242 if(!err) 243 *vaddr = (void*)hnd->base; 244 return err; 245 } 246 247 int gralloc_lock_ycbcr(gralloc_module_t const* module, 248 buffer_handle_t handle, int usage, 249 int l, int t, int w, int h, 250 struct android_ycbcr *ycbcr) 251 { 252 private_handle_t* hnd = (private_handle_t*)handle; 253 int err = gralloc_map_and_invalidate(module, handle, usage, l, t, w, h); 254 int ystride; 255 if(!err) { 256 //hnd->format holds our implementation defined format 257 //HAL_PIXEL_FORMAT_YCrCb_420_SP is the only one set right now. 258 switch (hnd->format) { 259 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 260 ystride = ALIGN(hnd->width, 16); 261 ycbcr->y = (void*)hnd->base; 262 ycbcr->cr = (void*)(hnd->base + ystride * hnd->height); 263 ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1); 264 ycbcr->ystride = ystride; 265 ycbcr->cstride = ystride; 266 ycbcr->chroma_step = 2; 267 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); 268 break; 269 default: 270 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, 271 hnd->format); 272 err = -EINVAL; 273 } 274 } 275 return err; 276 } 277 278 int gralloc_unlock(gralloc_module_t const* module, 279 buffer_handle_t handle) 280 { 281 if (private_handle_t::validate(handle) < 0) 282 return -EINVAL; 283 int err = 0; 284 private_handle_t* hnd = (private_handle_t*)handle; 285 IMemAlloc* memalloc = getAllocator(hnd->flags); 286 287 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { 288 err = memalloc->clean_buffer((void*)hnd->base, 289 hnd->size, hnd->offset, hnd->fd, 290 CACHE_CLEAN_AND_INVALIDATE); 291 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 292 } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) { 293 hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; 294 } else { 295 //Probably a round about way to do this, but this avoids adding new 296 //flags 297 err = memalloc->clean_buffer((void*)hnd->base, 298 hnd->size, hnd->offset, hnd->fd, 299 CACHE_INVALIDATE); 300 } 301 302 return err; 303 } 304 305 /*****************************************************************************/ 306 307 int gralloc_perform(struct gralloc_module_t const* module, 308 int operation, ... ) 309 { 310 int res = -EINVAL; 311 va_list args; 312 va_start(args, operation); 313 switch (operation) { 314 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: 315 { 316 int fd = va_arg(args, int); 317 size_t size = va_arg(args, size_t); 318 size_t offset = va_arg(args, size_t); 319 void* base = va_arg(args, void*); 320 int width = va_arg(args, int); 321 int height = va_arg(args, int); 322 int format = va_arg(args, int); 323 324 native_handle_t** handle = va_arg(args, native_handle_t**); 325 int memoryFlags = va_arg(args, int); 326 private_handle_t* hnd = (private_handle_t*)native_handle_create( 327 private_handle_t::sNumFds, private_handle_t::sNumInts); 328 hnd->magic = private_handle_t::sMagic; 329 hnd->fd = fd; 330 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION; 331 hnd->size = size; 332 hnd->offset = offset; 333 hnd->base = intptr_t(base) + offset; 334 hnd->gpuaddr = 0; 335 hnd->width = width; 336 hnd->height = height; 337 hnd->format = format; 338 *handle = (native_handle_t *)hnd; 339 res = 0; 340 break; 341 342 } 343 #ifdef QCOM_BSP 344 case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY: 345 { 346 int width = va_arg(args, int); 347 int height = va_arg(args, int); 348 int format = va_arg(args, int); 349 private_handle_t* hnd = va_arg(args, private_handle_t*); 350 if (private_handle_t::validate(hnd)) { 351 return res; 352 } 353 hnd->width = width; 354 hnd->height = height; 355 hnd->format = format; 356 res = 0; 357 } 358 break; 359 #endif 360 case GRALLOC_MODULE_PERFORM_GET_STRIDE: 361 { 362 int width = va_arg(args, int); 363 int format = va_arg(args, int); 364 int *stride = va_arg(args, int *); 365 *stride = AdrenoMemInfo::getInstance().getStride(width, format); 366 res = 0; 367 } break; 368 default: 369 break; 370 } 371 va_end(args); 372 return res; 373 } 374