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