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