1/* 2 * Copyright (C) 2010 ARM Limited. All rights reserved. 3 * 4 * Copyright (C) 2008 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * You may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19#include <errno.h> 20#include <pthread.h> 21#include <string.h> 22 23#include <cutils/log.h> 24#include <cutils/atomic.h> 25#include <hardware/hardware.h> 26#include <hardware/gralloc.h> 27 28#include "gralloc_priv.h" 29#include "alloc_device.h" 30#include "framebuffer_device.h" 31 32#if GRALLOC_ARM_UMP_MODULE 33#include <ump/ump_ref_drv.h> 34static int s_ump_is_open = 0; 35#endif 36 37#if GRALLOC_ARM_DMA_BUF_MODULE 38#include <linux/ion.h> 39#include <ion/ion.h> 40#include <sys/mman.h> 41#endif 42 43static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER; 44 45static int gralloc_device_open(const hw_module_t *module, const char *name, hw_device_t **device) 46{ 47 int status = -EINVAL; 48 49 if (!strncmp(name, GRALLOC_HARDWARE_GPU0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN)) 50 { 51 status = alloc_device_open(module, name, device); 52 } 53 else if (!strncmp(name, GRALLOC_HARDWARE_FB0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN)) 54 { 55 status = framebuffer_device_open(module, name, device); 56 } 57 58 return status; 59} 60 61static int gralloc_register_buffer(gralloc_module_t const *module, buffer_handle_t handle) 62{ 63 MALI_IGNORE(module); 64 65 if (private_handle_t::validate(handle) < 0) 66 { 67 AERR("Registering invalid buffer 0x%p, returning error", handle); 68 return -EINVAL; 69 } 70 71 // if this handle was created in this process, then we keep it as is. 72 private_handle_t *hnd = (private_handle_t *)handle; 73 74 int retval = -EINVAL; 75 76 pthread_mutex_lock(&s_map_lock); 77 78#if GRALLOC_ARM_UMP_MODULE 79 80 if (!s_ump_is_open) 81 { 82 ump_result res = ump_open(); // MJOLL-4012: UMP implementation needs a ump_close() for each ump_open 83 84 if (res != UMP_OK) 85 { 86 pthread_mutex_unlock(&s_map_lock); 87 AERR("Failed to open UMP library with res=%d", res); 88 return retval; 89 } 90 91 s_ump_is_open = 1; 92 } 93 94#endif 95 96 hnd->pid = getpid(); 97 98 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) 99 { 100 AINF("Register framebuffer 0x%p is no-op", handle); 101 retval = 0; 102 103 } 104 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) 105 { 106#if GRALLOC_ARM_UMP_MODULE 107 hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id); 108 109 if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle) 110 { 111 hnd->base = ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle); 112 113 if (0 != hnd->base) 114 { 115 hnd->writeOwner = 0; 116 hnd->lockState &= ~(private_handle_t::LOCK_STATE_UNREGISTERED); 117 pthread_mutex_unlock(&s_map_lock); 118 return 0; 119 } 120 else 121 { 122 AERR("Failed to map UMP handle 0x%x", hnd->ump_mem_handle); 123 } 124 125 ump_reference_release((ump_handle)hnd->ump_mem_handle); 126 } 127 else 128 { 129 AERR("Failed to create UMP handle 0x%x", hnd->ump_mem_handle); 130 } 131 132#else 133 AERR("Gralloc does not support UMP. Unable to register UMP memory for handle 0x%p", hnd); 134#endif 135 } 136 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 137 { 138#if GRALLOC_ARM_DMA_BUF_MODULE 139 unsigned char *mappedAddress; 140 size_t size = hnd->size; 141 hw_module_t *pmodule = NULL; 142 private_module_t *m = NULL; 143 144 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0) 145 { 146 m = reinterpret_cast<private_module_t *>(pmodule); 147 } 148 else 149 { 150 AERR("Could not get gralloc module for handle: 0x%p", hnd); 151 retval = -errno; 152 goto cleanup; 153 } 154 155 /* the test condition is set to m->ion_client <= 0 here, because: 156 * 1) module structure are initialized to 0 if no initial value is applied 157 * 2) a second user process should get a ion fd greater than 0. 158 */ 159 if (m->ion_client <= 0) 160 { 161 /* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/ 162 m->ion_client = ion_open(); 163 164 if (m->ion_client < 0) 165 { 166 AERR("Could not open ion device for handle: 0x%p", hnd); 167 retval = -errno; 168 goto cleanup; 169 } 170 } 171 172 mappedAddress = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0); 173 174 if (MAP_FAILED == mappedAddress) 175 { 176 AERR("mmap( share_fd:%d ) failed with %s", hnd->share_fd, strerror(errno)); 177 retval = -errno; 178 goto cleanup; 179 } 180 181 hnd->base = mappedAddress + hnd->offset; 182 hnd->lockState &= ~(private_handle_t::LOCK_STATE_UNREGISTERED); 183 pthread_mutex_unlock(&s_map_lock); 184 return 0; 185#endif 186 } 187 else 188 { 189 AERR("registering non-UMP buffer not supported. flags = %d", hnd->flags); 190 } 191 192cleanup: 193 pthread_mutex_unlock(&s_map_lock); 194 return retval; 195} 196 197static void unmap_buffer(private_handle_t *hnd) 198{ 199 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) 200 { 201#if GRALLOC_ARM_UMP_MODULE 202 ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle); 203 ump_reference_release((ump_handle)hnd->ump_mem_handle); 204 hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE; 205#else 206 AERR("Can't unregister UMP buffer for handle 0x%p. Not supported", hnd); 207#endif 208 } 209 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 210 { 211#if GRALLOC_ARM_DMA_BUF_MODULE 212 void *base = (void *)hnd->base; 213 size_t size = hnd->size; 214 215 if (munmap(base, size) < 0) 216 { 217 AERR("Could not munmap base:0x%p size:%lu '%s'", base, (unsigned long)size, strerror(errno)); 218 } 219 220#else 221 AERR("Can't unregister DMA_BUF buffer for hnd %p. Not supported", hnd); 222#endif 223 224 } 225 else 226 { 227 AERR("Unregistering unknown buffer is not supported. Flags = %d", hnd->flags); 228 } 229 230 hnd->base = 0; 231 hnd->lockState = 0; 232 hnd->writeOwner = 0; 233} 234 235static int gralloc_unregister_buffer(gralloc_module_t const *module, buffer_handle_t handle) 236{ 237 MALI_IGNORE(module); 238 239 if (private_handle_t::validate(handle) < 0) 240 { 241 AERR("unregistering invalid buffer 0x%p, returning error", handle); 242 return -EINVAL; 243 } 244 245 private_handle_t *hnd = (private_handle_t *)handle; 246 247 AERR_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState); 248 249 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) 250 { 251 AERR("Can't unregister buffer 0x%p as it is a framebuffer", handle); 252 } 253 else if (hnd->pid == getpid()) // never unmap buffers that were not registered in this process 254 { 255 pthread_mutex_lock(&s_map_lock); 256 257 hnd->lockState &= ~(private_handle_t::LOCK_STATE_MAPPED); 258 259 /* if handle is still locked, the unmapping would not happen until unlocked*/ 260 if (!(hnd->lockState & private_handle_t::LOCK_STATE_WRITE)) 261 { 262 unmap_buffer(hnd); 263 } 264 265 hnd->lockState |= private_handle_t::LOCK_STATE_UNREGISTERED; 266 267 pthread_mutex_unlock(&s_map_lock); 268 } 269 else 270 { 271 AERR("Trying to unregister buffer 0x%p from process %d that was not created in current process: %d", hnd, hnd->pid, getpid()); 272 } 273 274 return 0; 275} 276 277static int gralloc_lock(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, void **vaddr) 278{ 279 if (private_handle_t::validate(handle) < 0) 280 { 281 AERR("Locking invalid buffer 0x%p, returning error", handle); 282 return -EINVAL; 283 } 284 285 private_handle_t *hnd = (private_handle_t *)handle; 286 287 pthread_mutex_lock(&s_map_lock); 288 289 if (hnd->lockState & private_handle_t::LOCK_STATE_UNREGISTERED) 290 { 291 AERR("Locking on an unregistered buffer 0x%p, returning error", hnd); 292 pthread_mutex_unlock(&s_map_lock); 293 return -EINVAL; 294 } 295 296 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP || hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 297 { 298 hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK; 299 } 300 301 hnd->lockState |= private_handle_t::LOCK_STATE_WRITE; 302 303 pthread_mutex_unlock(&s_map_lock); 304 305 if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) 306 { 307 *vaddr = (void *)hnd->base; 308 } 309 310 MALI_IGNORE(module); 311 MALI_IGNORE(l); 312 MALI_IGNORE(t); 313 MALI_IGNORE(w); 314 MALI_IGNORE(h); 315 return 0; 316} 317 318static int gralloc_unlock(gralloc_module_t const *module, buffer_handle_t handle) 319{ 320 MALI_IGNORE(module); 321 322 if (private_handle_t::validate(handle) < 0) 323 { 324 AERR("Unlocking invalid buffer 0x%p, returning error", handle); 325 return -EINVAL; 326 } 327 328 private_handle_t *hnd = (private_handle_t *)handle; 329 330 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP && hnd->writeOwner) 331 { 332#if GRALLOC_ARM_UMP_MODULE 333 ump_cpu_msync_now((ump_handle)hnd->ump_mem_handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, (void *)hnd->base, hnd->size); 334#else 335 AERR("Buffer 0x%p is UMP type but it is not supported", hnd); 336#endif 337 } 338 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && hnd->writeOwner) 339 { 340#if GRALLOC_ARM_DMA_BUF_MODULE 341 hw_module_t *pmodule = NULL; 342 343 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) != 0) 344 { 345 AERR("Couldnot get gralloc module for handle 0x%p\n", handle); 346 } 347#endif 348 } 349 350 pthread_mutex_lock(&s_map_lock); 351 352 hnd->lockState &= ~(private_handle_t::LOCK_STATE_WRITE); 353 354 /* if the handle has already been unregistered, unmap it here*/ 355 if (hnd->lockState & private_handle_t::LOCK_STATE_UNREGISTERED) 356 { 357 unmap_buffer(hnd); 358 } 359 360 pthread_mutex_unlock(&s_map_lock); 361 362 return 0; 363} 364 365// There is one global instance of the module 366 367static struct hw_module_methods_t gralloc_module_methods = 368{ 369 .open = gralloc_device_open, 370}; 371 372private_module_t::private_module_t() 373{ 374#define INIT_ZERO(obj) (memset(&(obj),0,sizeof((obj)))) 375 376 base.common.tag = HARDWARE_MODULE_TAG; 377 base.common.version_major = 1; 378 base.common.version_minor = 0; 379 base.common.id = GRALLOC_HARDWARE_MODULE_ID; 380 base.common.name = "Graphics Memory Allocator Module"; 381 base.common.author = "ARM Ltd."; 382 base.common.methods = &gralloc_module_methods; 383 base.common.dso = NULL; 384 INIT_ZERO(base.common.reserved); 385 386 base.registerBuffer = gralloc_register_buffer; 387 base.unregisterBuffer = gralloc_unregister_buffer; 388 base.lock = gralloc_lock; 389 base.unlock = gralloc_unlock; 390 base.perform = NULL; 391 INIT_ZERO(base.reserved_proc); 392 393 framebuffer = NULL; 394 flags = 0; 395 numBuffers = 0; 396 bufferMask = 0; 397 pthread_mutex_init(&(lock), NULL); 398 currentBuffer = NULL; 399 INIT_ZERO(info); 400 INIT_ZERO(finfo); 401 xdpi = 0.0f; 402 ydpi = 0.0f; 403 fps = 0.0f; 404 405#undef INIT_ZERO 406}; 407 408/* 409 * HAL_MODULE_INFO_SYM will be initialized using the default constructor 410 * implemented above 411 */ 412struct private_module_t HAL_MODULE_INFO_SYM; 413 414