Home | History | Annotate | Download | only in gralloc
      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 //#include <sync/sync.h>
     23 #include <android/sync.h>
     24 
     25 #include <cutils/log.h>
     26 #include <cutils/atomic.h>
     27 #include <hardware/hardware.h>
     28 #include <hardware/gralloc.h>
     29 
     30 #include "gralloc_priv.h"
     31 #include "alloc_device.h"
     32 #include "framebuffer_device.h"
     33 
     34 #if GRALLOC_ARM_UMP_MODULE
     35 #include <ump/ump_ref_drv.h>
     36 static int s_ump_is_open = 0;
     37 #endif
     38 
     39 #if GRALLOC_ARM_DMA_BUF_MODULE
     40 #include <ion/ion.h>
     41 #include <sys/mman.h>
     42 #endif
     43 
     44 static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER;
     45 
     46 static int gralloc_device_open(const hw_module_t *module, const char *name, hw_device_t **device)
     47 {
     48 	int status = -EINVAL;
     49 
     50 	if (!strncmp(name, GRALLOC_HARDWARE_GPU0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN))
     51 	{
     52 		status = alloc_device_open(module, name, device);
     53 	}
     54 	else if (!strncmp(name, GRALLOC_HARDWARE_FB0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN))
     55 	{
     56 		status = framebuffer_device_open(module, name, device);
     57 	}
     58 
     59 	return status;
     60 }
     61 
     62 static int gralloc_register_buffer(gralloc_module_t const *module, buffer_handle_t handle)
     63 {
     64 	MALI_IGNORE(module);
     65 
     66 	if (private_handle_t::validate(handle) < 0)
     67 	{
     68 		AERR("Registering invalid buffer %p, returning error", handle);
     69 		return -EINVAL;
     70 	}
     71 
     72 	// if this handle was created in this process, then we keep it as is.
     73 	private_handle_t *hnd = (private_handle_t *)handle;
     74 
     75 	int retval = -EINVAL;
     76 
     77 	pthread_mutex_lock(&s_map_lock);
     78 
     79 #if GRALLOC_ARM_UMP_MODULE
     80 
     81 	if (!s_ump_is_open)
     82 	{
     83 		ump_result res = ump_open(); // MJOLL-4012: UMP implementation needs a ump_close() for each ump_open
     84 
     85 		if (res != UMP_OK)
     86 		{
     87 			pthread_mutex_unlock(&s_map_lock);
     88 			AERR("Failed to open UMP library with res=%d", res);
     89 			return retval;
     90 		}
     91 
     92 		s_ump_is_open = 1;
     93 	}
     94 
     95 #endif
     96 
     97 	hnd->pid = getpid();
     98 
     99 	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
    100 	{
    101 		AINF("Register buffer %p although it will be treated as a nop", handle);
    102 		retval = 0;
    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 
    118 				pthread_mutex_unlock(&s_map_lock);
    119 				return 0;
    120 			}
    121 			else
    122 			{
    123 				AERR("Failed to map UMP handle 0x%x", hnd->ump_mem_handle);
    124 			}
    125 
    126 			ump_reference_release((ump_handle)hnd->ump_mem_handle);
    127 		}
    128 		else
    129 		{
    130 			AERR("Failed to create UMP handle 0x%x", hnd->ump_mem_handle);
    131 		}
    132 
    133 #else
    134 		AERR("Gralloc does not support UMP. Unable to register UMP memory for handle %p", hnd);
    135 #endif
    136 	}
    137 	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
    138 	{
    139 #if GRALLOC_ARM_DMA_BUF_MODULE
    140 		unsigned char *mappedAddress;
    141 		size_t size = hnd->size;
    142 		hw_module_t *pmodule = NULL;
    143 		private_module_t *m = NULL;
    144 
    145 		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
    146 		{
    147 			m = reinterpret_cast<private_module_t *>(pmodule);
    148 		}
    149 		else
    150 		{
    151 			AERR("Could not get gralloc module for handle: %p", hnd);
    152 			retval = -errno;
    153 			goto cleanup;
    154 		}
    155 
    156 		/* the test condition is set to m->ion_client <= 0 here, because:
    157 		 * 1) module structure are initialized to 0 if no initial value is applied
    158 		 * 2) a second user process should get a ion fd greater than 0.
    159 		 */
    160 		if (m->ion_client <= 0)
    161 		{
    162 			/* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/
    163 			m->ion_client = ion_open();
    164 
    165 			if (m->ion_client < 0)
    166 			{
    167 				AERR("Could not open ion device for handle: %p", hnd);
    168 				retval = -errno;
    169 				goto cleanup;
    170 			}
    171 		}
    172 
    173 		mappedAddress = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0);
    174 
    175 		if (MAP_FAILED == mappedAddress)
    176 		{
    177 			AERR("mmap( share_fd:%d ) failed with %s",  hnd->share_fd, strerror(errno));
    178 			retval = -errno;
    179 			goto cleanup;
    180 		}
    181 
    182 		hnd->base = mappedAddress + hnd->offset;
    183 		hnd->lockState &= ~(private_handle_t::LOCK_STATE_UNREGISTERED);
    184 
    185 		pthread_mutex_unlock(&s_map_lock);
    186 		return 0;
    187 #endif
    188 	}
    189 	else
    190 	{
    191 		AERR("registering non-UMP buffer not supported. flags = %d", hnd->flags);
    192 	}
    193 
    194 #if GRALLOC_ARM_DMA_BUF_MODULE
    195 cleanup:
    196 #endif
    197 	pthread_mutex_unlock(&s_map_lock);
    198 	return retval;
    199 }
    200 
    201 static void unmap_buffer(private_handle_t *hnd)
    202 {
    203 	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
    204 	{
    205 #if GRALLOC_ARM_UMP_MODULE
    206 		ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
    207 		ump_reference_release((ump_handle)hnd->ump_mem_handle);
    208 		hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE;
    209 #else
    210 		AERR("Can't unregister UMP buffer for handle %p. Not supported", hnd);
    211 #endif
    212 	}
    213 	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
    214 	{
    215 #if GRALLOC_ARM_DMA_BUF_MODULE
    216 		void *base = (void *)hnd->base;
    217 		size_t size = hnd->size;
    218 
    219 		if (munmap(base, size) < 0)
    220 		{
    221 			AERR("Could not munmap base:%p size:%lu '%s'", base, (unsigned long)size, strerror(errno));
    222 		}
    223 
    224 #else
    225 		AERR("Can't unregister DMA_BUF buffer for hnd %p. Not supported", hnd);
    226 #endif
    227 
    228 	}
    229 	else
    230 	{
    231 		AERR("Unregistering unknown buffer is not supported. Flags = %d", hnd->flags);
    232 	}
    233 
    234 	hnd->base = 0;
    235 	hnd->lockState = 0;
    236 	hnd->writeOwner = 0;
    237 }
    238 
    239 static int gralloc_unregister_buffer(gralloc_module_t const *module, buffer_handle_t handle)
    240 {
    241 	MALI_IGNORE(module);
    242 
    243 	if (private_handle_t::validate(handle) < 0)
    244 	{
    245 		AERR("unregistering invalid buffer %p, returning error", handle);
    246 		return -EINVAL;
    247 	}
    248 
    249 	private_handle_t *hnd = (private_handle_t *)handle;
    250 
    251 	AERR_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState);
    252 
    253 	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
    254 	{
    255 		AERR("Can't unregister buffer %p as it is a framebuffer", handle);
    256 	}
    257 	else if (hnd->pid == getpid()) // never unmap buffers that were not registered in this process
    258 	{
    259 		pthread_mutex_lock(&s_map_lock);
    260 
    261 		hnd->lockState &= ~(private_handle_t::LOCK_STATE_MAPPED);
    262 
    263 		/* if handle is still locked, the unmapping would not happen until unlocked*/
    264 		if (!(hnd->lockState & private_handle_t::LOCK_STATE_WRITE))
    265 		{
    266 			unmap_buffer(hnd);
    267 		}
    268 
    269 		hnd->lockState |= private_handle_t::LOCK_STATE_UNREGISTERED;
    270 
    271 		pthread_mutex_unlock(&s_map_lock);
    272 	}
    273 	else
    274 	{
    275 		AERR("Trying to unregister buffer %p from process %d that was not created in current process: %d", hnd, hnd->pid, getpid());
    276 	}
    277 
    278 	return 0;
    279 }
    280 
    281 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)
    282 {
    283 
    284 
    285 	if (private_handle_t::validate(handle) < 0)
    286 	{
    287 		AERR("Locking invalid buffer %p, returning error", handle);
    288 		return -EINVAL;
    289 	}
    290 
    291 	private_handle_t *hnd = (private_handle_t *)handle;
    292 
    293 	if (hnd->format == HAL_PIXEL_FORMAT_YCbCr_420_888)
    294 	{
    295 		AERR("Buffer with format HAL_PIXEL_FORMAT_YCbCr_*_888 must be locked by lock_ycbcr()");
    296 		return -EINVAL;
    297 	}
    298 
    299 	pthread_mutex_lock(&s_map_lock);
    300 
    301 	if (hnd->lockState & private_handle_t::LOCK_STATE_UNREGISTERED)
    302 	{
    303 		AERR("Locking on an unregistered buffer %p, returning error", hnd);
    304 		pthread_mutex_unlock(&s_map_lock);
    305 		return -EINVAL;
    306 	}
    307 
    308 	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP || hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
    309 	{
    310 		hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
    311 	}
    312 
    313 	hnd->lockState |= private_handle_t::LOCK_STATE_WRITE;
    314 
    315 	pthread_mutex_unlock(&s_map_lock);
    316 
    317 	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
    318 	{
    319 		*vaddr = (void *)hnd->base;
    320 	}
    321 
    322 	MALI_IGNORE(module);
    323 	MALI_IGNORE(l);
    324 	MALI_IGNORE(t);
    325 	MALI_IGNORE(w);
    326 	MALI_IGNORE(h);
    327 	return 0;
    328 }
    329 
    330 static int gralloc_lock_ycbcr(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr)
    331 {
    332 	int retval = 0;
    333 	int ystride, cstride;
    334 
    335 	if (private_handle_t::validate(handle) < 0)
    336 	{
    337 		AERR("Locking invalid buffer %p, returning error", handle);
    338 		return -EINVAL;
    339 	}
    340 
    341 	private_handle_t *hnd = (private_handle_t *)handle;
    342 
    343 	pthread_mutex_lock(&s_map_lock);
    344 
    345 	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP || hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
    346 	{
    347 		hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
    348 	}
    349 
    350 	hnd->lockState |= private_handle_t::LOCK_STATE_WRITE;
    351 
    352 	pthread_mutex_unlock(&s_map_lock);
    353 
    354 
    355 	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
    356 	{
    357 		switch (hnd->format)
    358 		{
    359 			case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    360 				ystride = cstride = GRALLOC_ALIGN(hnd->width, 16);
    361 				ycbcr->y  = (void *)hnd->base;
    362 				ycbcr->cr = (void *)((unsigned char *)hnd->base + ystride * hnd->height);
    363 				ycbcr->cb = (void *)((unsigned char *)hnd->base + ystride * hnd->height + 1);
    364 				ycbcr->ystride = ystride;
    365 				ycbcr->cstride = cstride;
    366 				ycbcr->chroma_step = 2;
    367 				break;
    368 
    369 			case HAL_PIXEL_FORMAT_YV12:
    370 				/* Here to keep consistency with YV12 alignment, define the ystride according to image height. */
    371 				ystride = GRALLOC_ALIGN(hnd->width, (hnd->height % 8 == 0) ? GRALLOC_ALIGN_BASE_16 :
    372 										  		   ((hnd->height % 4 == 0) ? GRALLOC_ALIGN_BASE_64 : GRALLOC_ALIGN_BASE_128));
    373 				cstride = GRALLOC_ALIGN(ystride / 2, 16);
    374 				ycbcr->y  = (void *)hnd->base;
    375 				/* the ystride calc is assuming the height can at least be divided by 2 */
    376 				ycbcr->cr = (void *)((unsigned char *)hnd->base + ystride * GRALLOC_ALIGN(hnd->height, 2));
    377 				ycbcr->cb = (void *)((unsigned char *)hnd->base + ystride * GRALLOC_ALIGN(hnd->height, 2) + cstride * hnd->height / 2);
    378 				ycbcr->ystride = ystride;
    379 				ycbcr->cstride = cstride;
    380 				ycbcr->chroma_step = 1;
    381 				break;
    382 
    383 #ifdef SUPPORT_LEGACY_FORMAT
    384 
    385 			case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    386 				ystride = cstride = GRALLOC_ALIGN(hnd->width, 16);
    387 				ycbcr->y  = (void *)hnd->base;
    388 				ycbcr->cb = (void *)((unsigned char *)hnd->base + ystride * hnd->height);
    389 				ycbcr->cr = (void *)((unsigned char *)hnd->base + ystride * hnd->height + 1);
    390 				ycbcr->ystride = ystride;
    391 				ycbcr->cstride = cstride;
    392 				ycbcr->chroma_step = 2;
    393 				break;
    394 #endif
    395 
    396 			default:
    397 				AERR("Can not lock buffer, invalid format: 0x%x", hnd->format);
    398 				retval = -EINVAL;
    399 		}
    400 	}
    401 
    402 	MALI_IGNORE(module);
    403 	MALI_IGNORE(l);
    404 	MALI_IGNORE(t);
    405 	MALI_IGNORE(w);
    406 	MALI_IGNORE(h);
    407 	return retval;
    408 }
    409 
    410 static int gralloc_unlock(gralloc_module_t const *module, buffer_handle_t handle)
    411 {
    412 	MALI_IGNORE(module);
    413 
    414 	if (private_handle_t::validate(handle) < 0)
    415 	{
    416 		AERR("Unlocking invalid buffer %p, returning error", handle);
    417 		return -EINVAL;
    418 	}
    419 
    420 	private_handle_t *hnd = (private_handle_t *)handle;
    421 
    422 	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP && hnd->writeOwner)
    423 	{
    424 #if GRALLOC_ARM_UMP_MODULE
    425 		ump_cpu_msync_now((ump_handle)hnd->ump_mem_handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, (void *)hnd->base, hnd->size);
    426 #else
    427 		AERR("Buffer %p is UMP type but it is not supported", hnd);
    428 #endif
    429 	}
    430 	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && hnd->writeOwner)
    431 	{
    432 #if GRALLOC_ARM_DMA_BUF_MODULE
    433 		hw_module_t *pmodule = NULL;
    434 		private_module_t *m = NULL;
    435 
    436 		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
    437 		{
    438 			m = reinterpret_cast<private_module_t *>(pmodule);
    439 			//ion_sync_fd(m->ion_client, hnd->share_fd);
    440 		}
    441 		else
    442 		{
    443 			AERR("Couldnot get gralloc module for handle %p\n", handle);
    444 		}
    445 
    446 #endif
    447 	}
    448 
    449 	pthread_mutex_lock(&s_map_lock);
    450 
    451 	hnd->lockState &= ~(private_handle_t::LOCK_STATE_WRITE);
    452 
    453 	/* if the handle has already been unregistered, unmap it here*/
    454 	if (hnd->lockState & private_handle_t::LOCK_STATE_UNREGISTERED)
    455 	{
    456 		unmap_buffer(hnd);
    457 	}
    458 
    459 	pthread_mutex_unlock(&s_map_lock);
    460 
    461 	return 0;
    462 }
    463 
    464 #if defined(GRALLOC_MODULE_API_VERSION_0_3)
    465 static int gralloc_lock_async (gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, void **vaddr, int fenceFD)
    466 {
    467 	if (fenceFD >= 0)
    468 	{
    469 		sync_wait(fenceFD, -1);
    470 		close(fenceFD);
    471 	}
    472 
    473 	return gralloc_lock(module, handle, usage, l, t, w, h, vaddr);
    474 }
    475 
    476 static int gralloc_unlock_async(gralloc_module_t const *module, buffer_handle_t handle, int *fenceFD)
    477 {
    478 	*fenceFD = -1;
    479 
    480 	if (gralloc_unlock(module, handle) < 0)
    481 	{
    482 		return -EINVAL;
    483 	}
    484 
    485 	return 0;
    486 
    487 }
    488 
    489 static int gralloc_lock_async_ycbcr(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr, int fenceFD)
    490 {
    491 	if (fenceFD >= 0)
    492 	{
    493 		sync_wait(fenceFD, -1);
    494 		close(fenceFD);
    495 	}
    496 
    497 	return gralloc_lock_ycbcr(module, handle, usage, l, t, w, h, ycbcr);
    498 }
    499 #endif
    500 
    501 // There is one global instance of the module
    502 
    503 static struct hw_module_methods_t gralloc_module_methods =
    504 {
    505 	.open = gralloc_device_open
    506 };
    507 
    508 private_module_t::private_module_t()
    509 {
    510 #define INIT_ZERO(obj) (memset(&(obj),0,sizeof((obj))))
    511 
    512 	base.common.tag = HARDWARE_MODULE_TAG;
    513 #if defined(GRALLOC_MODULE_API_VERSION_0_3)
    514 	base.common.version_major = GRALLOC_MODULE_API_VERSION_0_3;
    515 #else
    516 	base.common.version_major = GRALLOC_MODULE_API_VERSION_0_2;
    517 #endif
    518 	base.common.version_minor = 0;
    519 	base.common.id = GRALLOC_HARDWARE_MODULE_ID;
    520 	base.common.name = "Graphics Memory Allocator Module";
    521 	base.common.author = "ARM Ltd.";
    522 	base.common.methods = &gralloc_module_methods;
    523 	base.common.dso = NULL;
    524 	INIT_ZERO(base.common.reserved);
    525 
    526 	base.registerBuffer = gralloc_register_buffer;
    527 	base.unregisterBuffer = gralloc_unregister_buffer;
    528 	base.lock = gralloc_lock;
    529 	base.unlock = gralloc_unlock;
    530 	base.perform = NULL;
    531 	base.lock_ycbcr = gralloc_lock_ycbcr;
    532         base.getTransportSize = NULL;
    533         base.validateBufferSize = NULL;
    534 #if defined(GRALLOC_MODULE_API_VERSION_0_3)
    535 	base.lockAsync = gralloc_lock_async;
    536 	base.unlockAsync = gralloc_unlock_async;
    537 	base.lockAsync_ycbcr = gralloc_lock_async_ycbcr;
    538 #endif
    539 	INIT_ZERO(base.reserved_proc);
    540 
    541 	framebuffer = NULL;
    542 	flags = 0;
    543 	numBuffers = 0;
    544 	bufferMask = 0;
    545 	pthread_mutex_init(&(lock), NULL);
    546 	currentBuffer = NULL;
    547 	INIT_ZERO(info);
    548 	INIT_ZERO(finfo);
    549 	xdpi = 0.0f;
    550 	ydpi = 0.0f;
    551 	fps = 0.0f;
    552 
    553 #undef INIT_ZERO
    554 };
    555 
    556 /*
    557  * HAL_MODULE_INFO_SYM will be initialized using the default constructor
    558  * implemented above
    559  */
    560 struct private_module_t HAL_MODULE_INFO_SYM;
    561 
    562