mapper.cpp revision 6341a157555917b7dadd894c90ddd5093c9e1e47
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 45using namespace gralloc; 46/*****************************************************************************/ 47 48// Return the type of allocator - 49// these are used for mapping/unmapping 50static 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 58static 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 92static 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 123static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER; 124 125/*****************************************************************************/ 126 127int 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 154int 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 176int 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 201static 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 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { 219 //Invalidate if reading in software. No need to do this for the 220 //metadata buffer as it is only read/written in software. 221 IMemAlloc* memalloc = getAllocator(hnd->flags) ; 222 err = memalloc->clean_buffer((void*)hnd->base, 223 hnd->size, hnd->offset, hnd->fd, 224 CACHE_INVALIDATE); 225 if (usage & GRALLOC_USAGE_SW_WRITE_MASK) { 226 // Mark the buffer to be flushed after cpu read/write 227 hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 228 } 229 } 230 } else { 231 hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; 232 } 233 return err; 234} 235 236int gralloc_lock(gralloc_module_t const* module, 237 buffer_handle_t handle, int usage, 238 int l, int t, int w, int h, 239 void** vaddr) 240{ 241 private_handle_t* hnd = (private_handle_t*)handle; 242 int err = gralloc_map_and_invalidate(module, handle, usage, l, t, w, h); 243 if(!err) 244 *vaddr = (void*)hnd->base; 245 return err; 246} 247 248int gralloc_lock_ycbcr(gralloc_module_t const* module, 249 buffer_handle_t handle, int usage, 250 int l, int t, int w, int h, 251 struct android_ycbcr *ycbcr) 252{ 253 private_handle_t* hnd = (private_handle_t*)handle; 254 int err = gralloc_map_and_invalidate(module, handle, usage, l, t, w, h); 255 int ystride; 256 if(!err) { 257 //hnd->format holds our implementation defined format 258 //HAL_PIXEL_FORMAT_YCrCb_420_SP is the only one set right now. 259 switch (hnd->format) { 260 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 261 ystride = ALIGN(hnd->width, 16); 262 ycbcr->y = (void*)hnd->base; 263 ycbcr->cr = (void*)(hnd->base + ystride * hnd->height); 264 ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1); 265 ycbcr->ystride = ystride; 266 ycbcr->cstride = ystride; 267 ycbcr->chroma_step = 2; 268 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); 269 break; 270 default: 271 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, 272 hnd->format); 273 err = -EINVAL; 274 } 275 } 276 return err; 277} 278 279int gralloc_unlock(gralloc_module_t const* module, 280 buffer_handle_t handle) 281{ 282 if (private_handle_t::validate(handle) < 0) 283 return -EINVAL; 284 int err = 0; 285 private_handle_t* hnd = (private_handle_t*)handle; 286 287 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { 288 IMemAlloc* memalloc = getAllocator(hnd->flags); 289 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { 290 err = memalloc->clean_buffer((void*)hnd->base, 291 hnd->size, hnd->offset, hnd->fd, 292 CACHE_CLEAN_AND_INVALIDATE); 293 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 294 } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) { 295 hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; 296 } else { 297 //Probably a round about way to do this, but this avoids adding new 298 //flags 299 err = memalloc->clean_buffer((void*)hnd->base, 300 hnd->size, hnd->offset, hnd->fd, 301 CACHE_INVALIDATE); 302 } 303 } 304 305 return err; 306} 307 308/*****************************************************************************/ 309 310int gralloc_perform(struct gralloc_module_t const* module, 311 int operation, ... ) 312{ 313 int res = -EINVAL; 314 va_list args; 315 va_start(args, operation); 316 switch (operation) { 317 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: 318 { 319 int fd = va_arg(args, int); 320 size_t size = va_arg(args, size_t); 321 size_t offset = va_arg(args, size_t); 322 void* base = va_arg(args, void*); 323 int width = va_arg(args, int); 324 int height = va_arg(args, int); 325 int format = va_arg(args, int); 326 327 native_handle_t** handle = va_arg(args, native_handle_t**); 328 int memoryFlags = va_arg(args, int); 329 private_handle_t* hnd = (private_handle_t*)native_handle_create( 330 private_handle_t::sNumFds, private_handle_t::sNumInts); 331 hnd->magic = private_handle_t::sMagic; 332 hnd->fd = fd; 333 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION; 334 hnd->size = size; 335 hnd->offset = offset; 336 hnd->base = intptr_t(base) + offset; 337 hnd->gpuaddr = 0; 338 hnd->width = width; 339 hnd->height = height; 340 hnd->format = format; 341 *handle = (native_handle_t *)hnd; 342 res = 0; 343 break; 344 345 } 346#ifdef QCOM_BSP 347 case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY: 348 { 349 int width = va_arg(args, int); 350 int height = va_arg(args, int); 351 int format = va_arg(args, int); 352 private_handle_t* hnd = va_arg(args, private_handle_t*); 353 if (private_handle_t::validate(hnd)) { 354 return res; 355 } 356 hnd->width = width; 357 hnd->height = height; 358 hnd->format = format; 359 res = 0; 360 } 361 break; 362#endif 363 case GRALLOC_MODULE_PERFORM_GET_STRIDE: 364 { 365 int width = va_arg(args, int); 366 int format = va_arg(args, int); 367 int *stride = va_arg(args, int *); 368 *stride = AdrenoMemInfo::getInstance().getStride(width, format); 369 res = 0; 370 } break; 371 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: 372 { 373 private_handle_t* hnd = va_arg(args, private_handle_t*); 374 int *stride = va_arg(args, int *); 375 if (private_handle_t::validate(hnd)) { 376 return res; 377 } 378 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 379 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { 380 *stride = metadata->bufferDim.sliceWidth; 381 } else { 382 *stride = hnd->width; 383 } 384 res = 0; 385 } break; 386 default: 387 break; 388 } 389 va_end(args); 390 return res; 391} 392