mapper.cpp revision 85b1615c5a11a14fe9fcb0e74e7c8843af2b0733
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * Copyright (c) 2011-2014, 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 void** vaddr) 61{ 62 private_handle_t* hnd = (private_handle_t*)handle; 63 void *mappedAddress; 64 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) && 65 !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) { 66 size_t size = hnd->size; 67 IMemAlloc* memalloc = getAllocator(hnd->flags) ; 68 int err = memalloc->map_buffer(&mappedAddress, size, 69 hnd->offset, hnd->fd); 70 if(err || mappedAddress == MAP_FAILED) { 71 ALOGE("Could not mmap handle %p, fd=%d (%s)", 72 handle, hnd->fd, strerror(errno)); 73 hnd->base = 0; 74 return -errno; 75 } 76 77 hnd->base = intptr_t(mappedAddress) + hnd->offset; 78 //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p", 79 // hnd->fd, hnd->offset, hnd->size, mappedAddress); 80 mappedAddress = MAP_FAILED; 81 size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 82 err = memalloc->map_buffer(&mappedAddress, size, 83 hnd->offset_metadata, hnd->fd_metadata); 84 if(err || mappedAddress == MAP_FAILED) { 85 ALOGE("Could not mmap handle %p, fd=%d (%s)", 86 handle, hnd->fd_metadata, strerror(errno)); 87 hnd->base_metadata = 0; 88 return -errno; 89 } 90 hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata; 91 } 92 *vaddr = (void*)hnd->base; 93 return 0; 94} 95 96static int gralloc_unmap(gralloc_module_t const* module, 97 buffer_handle_t handle) 98{ 99 private_handle_t* hnd = (private_handle_t*)handle; 100 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { 101 int err = -EINVAL; 102 void* base = (void*)hnd->base; 103 size_t size = hnd->size; 104 IMemAlloc* memalloc = getAllocator(hnd->flags) ; 105 if(memalloc != NULL) { 106 err = memalloc->unmap_buffer(base, size, hnd->offset); 107 if (err) { 108 ALOGE("Could not unmap memory at address %p", base); 109 } 110 base = (void*)hnd->base_metadata; 111 size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 112 err = memalloc->unmap_buffer(base, size, hnd->offset_metadata); 113 if (err) { 114 ALOGE("Could not unmap memory at address %p", base); 115 } 116 } 117 } 118 /* need to initialize the pointer to NULL otherwise unmapping for that 119 * buffer happens twice which leads to crash */ 120 hnd->base = 0; 121 hnd->base_metadata = 0; 122 return 0; 123} 124 125/*****************************************************************************/ 126 127static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER; 128 129/*****************************************************************************/ 130 131int gralloc_register_buffer(gralloc_module_t const* module, 132 buffer_handle_t handle) 133{ 134 if (private_handle_t::validate(handle) < 0) 135 return -EINVAL; 136 137 // In this implementation, we don't need to do anything here 138 139 /* NOTE: we need to initialize the buffer as not mapped/not locked 140 * because it shouldn't when this function is called the first time 141 * in a new process. Ideally these flags shouldn't be part of the 142 * handle, but instead maintained in the kernel or at least 143 * out-of-line 144 */ 145 146 private_handle_t* hnd = (private_handle_t*)handle; 147 hnd->base = 0; 148 hnd->base_metadata = 0; 149 void *vaddr; 150 int err = gralloc_map(module, handle, &vaddr); 151 if (err) { 152 ALOGE("%s: gralloc_map failed", __FUNCTION__); 153 return err; 154 } 155 156 return 0; 157} 158 159int gralloc_unregister_buffer(gralloc_module_t const* module, 160 buffer_handle_t handle) 161{ 162 if (private_handle_t::validate(handle) < 0) 163 return -EINVAL; 164 165 /* 166 * If the buffer has been mapped during a lock operation, it's time 167 * to un-map it. It's an error to be here with a locked buffer. 168 * NOTE: the framebuffer is handled differently and is never unmapped. 169 */ 170 171 private_handle_t* hnd = (private_handle_t*)handle; 172 173 if (hnd->base != 0) { 174 gralloc_unmap(module, handle); 175 } 176 hnd->base = 0; 177 hnd->base_metadata = 0; 178 return 0; 179} 180 181int terminateBuffer(gralloc_module_t const* module, 182 private_handle_t* hnd) 183{ 184 /* 185 * If the buffer has been mapped during a lock operation, it's time 186 * to un-map it. It's an error to be here with a locked buffer. 187 */ 188 189 if (hnd->base != 0) { 190 // this buffer was mapped, unmap it now 191 if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM | 192 private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP | 193 private_handle_t::PRIV_FLAGS_USES_ASHMEM | 194 private_handle_t::PRIV_FLAGS_USES_ION)) { 195 gralloc_unmap(module, hnd); 196 } else { 197 ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x", 198 hnd->flags); 199 gralloc_unmap(module, hnd); 200 } 201 } 202 203 return 0; 204} 205 206int gralloc_lock(gralloc_module_t const* module, 207 buffer_handle_t handle, int usage, 208 int l, int t, int w, int h, 209 void** vaddr) 210{ 211 if (private_handle_t::validate(handle) < 0) 212 return -EINVAL; 213 214 int err = 0; 215 private_handle_t* hnd = (private_handle_t*)handle; 216 if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { 217 if (hnd->base == 0) { 218 // we need to map for real 219 pthread_mutex_t* const lock = &sMapLock; 220 pthread_mutex_lock(lock); 221 err = gralloc_map(module, handle, vaddr); 222 pthread_mutex_unlock(lock); 223 } 224 *vaddr = (void*)hnd->base; 225 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { 226 //Invalidate if reading in software. No need to do this for the 227 //metadata buffer as it is only read/written in software. 228 IMemAlloc* memalloc = getAllocator(hnd->flags) ; 229 err = memalloc->clean_buffer((void*)hnd->base, 230 hnd->size, hnd->offset, hnd->fd, 231 CACHE_INVALIDATE); 232 if (usage & GRALLOC_USAGE_SW_WRITE_MASK) { 233 // Mark the buffer to be flushed after cpu read/write 234 hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 235 } 236 } 237 } else { 238 hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; 239 } 240 return err; 241} 242 243int gralloc_unlock(gralloc_module_t const* module, 244 buffer_handle_t handle) 245{ 246 if (private_handle_t::validate(handle) < 0) 247 return -EINVAL; 248 int err = 0; 249 private_handle_t* hnd = (private_handle_t*)handle; 250 251 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) { 252 IMemAlloc* memalloc = getAllocator(hnd->flags); 253 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { 254 err = memalloc->clean_buffer((void*)hnd->base, 255 hnd->size, hnd->offset, hnd->fd, 256 CACHE_CLEAN_AND_INVALIDATE); 257 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 258 } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) { 259 hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH; 260 } else { 261 //Probably a round about way to do this, but this avoids adding new 262 //flags 263 err = memalloc->clean_buffer((void*)hnd->base, 264 hnd->size, hnd->offset, hnd->fd, 265 CACHE_INVALIDATE); 266 } 267 } 268 269 return err; 270} 271 272/*****************************************************************************/ 273 274int gralloc_perform(struct gralloc_module_t const* module, 275 int operation, ... ) 276{ 277 int res = -EINVAL; 278 va_list args; 279 va_start(args, operation); 280 switch (operation) { 281 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: 282 { 283 int fd = va_arg(args, int); 284 size_t size = va_arg(args, size_t); 285 size_t offset = va_arg(args, size_t); 286 void* base = va_arg(args, void*); 287 int width = va_arg(args, int); 288 int height = va_arg(args, int); 289 int format = va_arg(args, int); 290 291 native_handle_t** handle = va_arg(args, native_handle_t**); 292 int memoryFlags = va_arg(args, int); 293 private_handle_t* hnd = (private_handle_t*)native_handle_create( 294 private_handle_t::sNumFds, private_handle_t::sNumInts); 295 hnd->magic = private_handle_t::sMagic; 296 hnd->fd = fd; 297 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION; 298 hnd->size = size; 299 hnd->offset = offset; 300 hnd->base = intptr_t(base) + offset; 301 hnd->gpuaddr = 0; 302 hnd->width = width; 303 hnd->height = height; 304 hnd->format = format; 305 *handle = (native_handle_t *)hnd; 306 res = 0; 307 break; 308 309 } 310#ifdef QCOM_BSP 311 case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY: 312 { 313 int width = va_arg(args, int); 314 int height = va_arg(args, int); 315 int format = va_arg(args, int); 316 private_handle_t* hnd = va_arg(args, private_handle_t*); 317 if (private_handle_t::validate(hnd)) { 318 return res; 319 } 320 hnd->width = width; 321 hnd->height = height; 322 hnd->format = format; 323 res = 0; 324 } 325 break; 326#endif 327 case GRALLOC_MODULE_PERFORM_GET_STRIDE: 328 { 329 int width = va_arg(args, int); 330 int format = va_arg(args, int); 331 int *stride = va_arg(args, int *); 332 int alignedw = 0, alignedh = 0; 333 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, 334 0, format, false, alignedw, alignedh); 335 *stride = alignedw; 336 res = 0; 337 } break; 338 339 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: 340 { 341 private_handle_t* hnd = va_arg(args, private_handle_t*); 342 int *stride = va_arg(args, int *); 343 if (private_handle_t::validate(hnd)) { 344 return res; 345 } 346 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 347 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { 348 *stride = metadata->bufferDim.sliceWidth; 349 } else { 350 *stride = hnd->width; 351 } 352 res = 0; 353 } break; 354 355 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: 356 { 357 int width = va_arg(args, int); 358 int height = va_arg(args, int); 359 int format = va_arg(args, int); 360 int usage = va_arg(args, int); 361 int *alignedWidth = va_arg(args, int *); 362 int *alignedHeight = va_arg(args, int *); 363 int *tileEnabled = va_arg(args,int *); 364 *tileEnabled = isMacroTileEnabled(format, usage); 365 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, 366 height, format, *tileEnabled, *alignedWidth, 367 *alignedHeight); 368 res = 0; 369 } break; 370 371 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: 372 { 373 private_handle_t* hnd = va_arg(args, private_handle_t*); 374 int *color_space = 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_COLOR_SPACE) { 380 *color_space = metadata->colorSpace; 381 res = 0; 382 } 383 } break; 384 default: 385 break; 386 } 387 va_end(args); 388 return res; 389} 390