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