• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
gralloc_device_open(const hw_module_t * module,const char * name,hw_device_t ** device)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 
gralloc_register_buffer(gralloc_module_t const * module,buffer_handle_t handle)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 
unmap_buffer(private_handle_t * hnd)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 
gralloc_unregister_buffer(gralloc_module_t const * module,buffer_handle_t handle)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 
gralloc_lock(gralloc_module_t const * module,buffer_handle_t handle,int usage,int l,int t,int w,int h,void ** vaddr)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 
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)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 
gralloc_unlock(gralloc_module_t const * module,buffer_handle_t handle)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)
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)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 
gralloc_unlock_async(gralloc_module_t const * module,buffer_handle_t handle,int * fenceFD)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 
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)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 
private_module_t()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