1 /* 2 * Copyright (C) 2010 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 <unistd.h> 20 #include <fcntl.h> 21 #include <cutils/properties.h> 22 #include <sys/mman.h> 23 24 #include "gr.h" 25 #include "gpu.h" 26 #include "memalloc.h" 27 #include "alloc_controller.h" 28 #include <qdMetaData.h> 29 30 using namespace gralloc; 31 32 #define SZ_1M 0x100000 33 34 gpu_context_t::gpu_context_t(const private_module_t* module, 35 IAllocController* alloc_ctrl ) : 36 mAllocCtrl(alloc_ctrl) 37 { 38 // Zero out the alloc_device_t 39 memset(static_cast<alloc_device_t*>(this), 0, sizeof(alloc_device_t)); 40 41 // Initialize the procs 42 common.tag = HARDWARE_DEVICE_TAG; 43 common.version = 0; 44 common.module = const_cast<hw_module_t*>(&module->base.common); 45 common.close = gralloc_close; 46 alloc = gralloc_alloc; 47 #ifdef QCOM_BSP 48 allocSize = gralloc_alloc_size; 49 #endif 50 free = gralloc_free; 51 52 } 53 54 int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, 55 buffer_handle_t* pHandle, int bufferType, 56 int format, int width, int height) 57 { 58 int err = 0; 59 int flags = 0; 60 size = roundUpToPageSize(size); 61 alloc_data data; 62 data.offset = 0; 63 data.fd = -1; 64 data.base = 0; 65 if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) 66 data.align = 8192; 67 else 68 data.align = getpagesize(); 69 70 /* force 1MB alignment selectively for secure buffers, MDP5 onwards */ 71 #ifdef MDSS_TARGET 72 if (usage & GRALLOC_USAGE_PROTECTED) { 73 data.align = ALIGN(data.align, SZ_1M); 74 size = ALIGN(size, data.align); 75 } 76 #endif 77 78 data.size = size; 79 data.pHandle = (unsigned int) pHandle; 80 err = mAllocCtrl->allocate(data, usage); 81 82 if (!err) { 83 /* allocate memory for enhancement data */ 84 alloc_data eData; 85 eData.fd = -1; 86 eData.base = 0; 87 eData.offset = 0; 88 eData.size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 89 eData.pHandle = data.pHandle; 90 eData.align = getpagesize(); 91 int eDataUsage = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP; 92 int eDataErr = mAllocCtrl->allocate(eData, eDataUsage); 93 ALOGE_IF(eDataErr, "gralloc failed for eDataErr=%s", 94 strerror(-eDataErr)); 95 96 if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) { 97 flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY; 98 } 99 100 if (bufferType == BUFFER_TYPE_VIDEO) { 101 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) { 102 #ifndef MDSS_TARGET 103 flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR; 104 #else 105 // Per the camera spec ITU 709 format should be set only for 106 // video encoding. 107 // It should be set to ITU 601 full range format for any other 108 // camera buffer 109 // 110 if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) { 111 if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) 112 flags |= private_handle_t::PRIV_FLAGS_ITU_R_709; 113 else 114 flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR; 115 } 116 #endif 117 } else { 118 flags |= private_handle_t::PRIV_FLAGS_ITU_R_601; 119 } 120 } 121 122 if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) { 123 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER; 124 } 125 126 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) { 127 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE; 128 } 129 130 if (usage & GRALLOC_USAGE_HW_CAMERA_READ) { 131 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ; 132 } 133 134 if (usage & GRALLOC_USAGE_HW_COMPOSER) { 135 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER; 136 } 137 138 if (usage & GRALLOC_USAGE_HW_TEXTURE) { 139 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE; 140 } 141 142 if(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) { 143 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY; 144 } 145 146 if(isMacroTileEnabled(format, usage)) { 147 flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED; 148 } 149 150 flags |= data.allocType; 151 int eBaseAddr = int(eData.base) + eData.offset; 152 private_handle_t *hnd = new private_handle_t(data.fd, size, flags, 153 bufferType, format, width, height, eData.fd, eData.offset, 154 eBaseAddr); 155 156 hnd->offset = data.offset; 157 hnd->base = int(data.base) + data.offset; 158 hnd->gpuaddr = 0; 159 160 *pHandle = hnd; 161 } 162 163 ALOGE_IF(err, "gralloc failed err=%s", strerror(-err)); 164 165 return err; 166 } 167 168 void gpu_context_t::getGrallocInformationFromFormat(int inputFormat, 169 int *bufferType) 170 { 171 *bufferType = BUFFER_TYPE_VIDEO; 172 173 if (inputFormat == HAL_PIXEL_FORMAT_RGB_888) 174 return; 175 176 if (inputFormat <= HAL_PIXEL_FORMAT_sRGB_X_8888) { 177 // RGB formats 178 *bufferType = BUFFER_TYPE_UI; 179 } else if ((inputFormat == HAL_PIXEL_FORMAT_R_8) || 180 (inputFormat == HAL_PIXEL_FORMAT_RG_88)) { 181 *bufferType = BUFFER_TYPE_UI; 182 } 183 } 184 185 int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage, 186 buffer_handle_t* pHandle) 187 { 188 private_module_t* m = reinterpret_cast<private_module_t*>(common.module); 189 190 // we don't support framebuffer allocations with graphics heap flags 191 if (usage & GRALLOC_HEAP_MASK) { 192 return -EINVAL; 193 } 194 195 if (m->framebuffer == NULL) { 196 ALOGE("%s: Invalid framebuffer", __FUNCTION__); 197 return -EINVAL; 198 } 199 200 const uint32_t bufferMask = m->bufferMask; 201 const uint32_t numBuffers = m->numBuffers; 202 size_t bufferSize = m->finfo.line_length * m->info.yres; 203 204 //adreno needs FB size to be page aligned 205 bufferSize = roundUpToPageSize(bufferSize); 206 207 if (numBuffers == 1) { 208 // If we have only one buffer, we never use page-flipping. Instead, 209 // we return a regular buffer which will be memcpy'ed to the main 210 // screen when post is called. 211 int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; 212 return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI, 213 m->fbFormat, m->info.xres, m->info.yres); 214 } 215 216 if (bufferMask >= ((1LU<<numBuffers)-1)) { 217 // We ran out of buffers. 218 return -ENOMEM; 219 } 220 221 // create a "fake" handle for it 222 intptr_t vaddr = intptr_t(m->framebuffer->base); 223 private_handle_t* hnd = new private_handle_t( 224 dup(m->framebuffer->fd), bufferSize, 225 private_handle_t::PRIV_FLAGS_USES_PMEM | 226 private_handle_t::PRIV_FLAGS_FRAMEBUFFER, 227 BUFFER_TYPE_UI, m->fbFormat, m->info.xres, 228 m->info.yres); 229 230 // find a free slot 231 for (uint32_t i=0 ; i<numBuffers ; i++) { 232 if ((bufferMask & (1LU<<i)) == 0) { 233 m->bufferMask |= (1LU<<i); 234 break; 235 } 236 vaddr += bufferSize; 237 } 238 hnd->base = vaddr; 239 hnd->offset = vaddr - intptr_t(m->framebuffer->base); 240 *pHandle = hnd; 241 return 0; 242 } 243 244 245 int gpu_context_t::gralloc_alloc_framebuffer(size_t size, int usage, 246 buffer_handle_t* pHandle) 247 { 248 private_module_t* m = reinterpret_cast<private_module_t*>(common.module); 249 pthread_mutex_lock(&m->lock); 250 int err = gralloc_alloc_framebuffer_locked(size, usage, pHandle); 251 pthread_mutex_unlock(&m->lock); 252 return err; 253 } 254 255 int gpu_context_t::alloc_impl(int w, int h, int format, int usage, 256 buffer_handle_t* pHandle, int* pStride, 257 size_t bufferSize) { 258 if (!pHandle || !pStride) 259 return -EINVAL; 260 261 size_t size; 262 int alignedw, alignedh; 263 int grallocFormat = format; 264 int bufferType; 265 266 //If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on 267 //the usage bits, gralloc assigns a format. 268 if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 269 if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) 270 grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12 271 else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK) 272 == GRALLOC_USAGE_HW_CAMERA_ZSL) 273 grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21 ZSL 274 else if(usage & GRALLOC_USAGE_HW_CAMERA_READ) 275 grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21 276 else if(usage & GRALLOC_USAGE_HW_CAMERA_WRITE) 277 grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21 278 else if(usage & GRALLOC_USAGE_HW_COMPOSER) 279 //XXX: If we still haven't set a format, default to RGBA8888 280 grallocFormat = HAL_PIXEL_FORMAT_RGBA_8888; 281 } 282 283 getGrallocInformationFromFormat(grallocFormat, &bufferType); 284 size = getBufferSizeAndDimensions(w, h, grallocFormat, usage, alignedw, 285 alignedh); 286 287 if ((ssize_t)size <= 0) 288 return -EINVAL; 289 size = (bufferSize >= size)? bufferSize : size; 290 291 bool useFbMem = false; 292 char property[PROPERTY_VALUE_MAX]; 293 if((usage & GRALLOC_USAGE_HW_FB) && 294 (property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) && 295 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || 296 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { 297 useFbMem = true; 298 } 299 300 int err = 0; 301 if(useFbMem) { 302 err = gralloc_alloc_framebuffer(size, usage, pHandle); 303 } else { 304 err = gralloc_alloc_buffer(size, usage, pHandle, bufferType, 305 grallocFormat, alignedw, alignedh); 306 } 307 308 if (err < 0) { 309 return err; 310 } 311 312 *pStride = alignedw; 313 return 0; 314 } 315 316 int gpu_context_t::free_impl(private_handle_t const* hnd) { 317 private_module_t* m = reinterpret_cast<private_module_t*>(common.module); 318 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { 319 const size_t bufferSize = m->finfo.line_length * m->info.yres; 320 int index = (hnd->base - m->framebuffer->base) / bufferSize; 321 m->bufferMask &= ~(1<<index); 322 } else { 323 324 terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd)); 325 IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags); 326 int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size, 327 hnd->offset, hnd->fd); 328 if(err) 329 return err; 330 // free the metadata space 331 unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 332 err = memalloc->free_buffer((void*)hnd->base_metadata, 333 (size_t) size, hnd->offset_metadata, 334 hnd->fd_metadata); 335 if (err) 336 return err; 337 } 338 delete hnd; 339 return 0; 340 } 341 342 int gpu_context_t::gralloc_alloc(alloc_device_t* dev, int w, int h, int format, 343 int usage, buffer_handle_t* pHandle, 344 int* pStride) 345 { 346 if (!dev) { 347 return -EINVAL; 348 } 349 gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev); 350 return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, 0); 351 } 352 int gpu_context_t::gralloc_alloc_size(alloc_device_t* dev, int w, int h, 353 int format, int usage, 354 buffer_handle_t* pHandle, int* pStride, 355 int bufferSize) 356 { 357 if (!dev) { 358 return -EINVAL; 359 } 360 gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev); 361 return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, bufferSize); 362 } 363 364 365 int gpu_context_t::gralloc_free(alloc_device_t* dev, 366 buffer_handle_t handle) 367 { 368 if (private_handle_t::validate(handle) < 0) 369 return -EINVAL; 370 371 private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle); 372 gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev); 373 return gpu->free_impl(hnd); 374 } 375 376 /*****************************************************************************/ 377 378 int gpu_context_t::gralloc_close(struct hw_device_t *dev) 379 { 380 gpu_context_t* ctx = reinterpret_cast<gpu_context_t*>(dev); 381 if (ctx) { 382 /* TODO: keep a list of all buffer_handle_t created, and free them 383 * all here. 384 */ 385 delete ctx; 386 } 387 return 0; 388 } 389 390