1 /**************************************************************************
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
39 #include <sys/ioctl.h>
40 #include <sys/types.h>
47 #include <tbm_bufmgr.h>
48 #include <tbm_bufmgr_backend.h>
49 #include <exynos_drm.h>
51 #include <tbm_surface.h>
52 #include <tbm_surface_internal.h>
56 #define TBM_COLOR_FORMAT_COUNT 8
59 #define LOG_TAG "TBM_BACKEND"
67 static int initialized = 0;
68 static char app_name[128];
73 /* get the application name */
74 f = fopen("/proc/self/cmdline", "r");
81 memset(app_name, 0x00, sizeof(app_name));
83 if ( fgets(app_name, 100, f) == NULL )
91 if ( (slash=strrchr(app_name, '/')) != NULL )
93 memmove(app_name, slash+1, strlen(slash));
100 #define TBM_EXYNOS4412_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args)
101 #define DBG(fmt, args...) if(bDebug&01) LOGE("[%s]" fmt, target_name(), ##args)
103 #define TBM_EXYNOS4412_LOG(...)
107 #define SIZE_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
109 #define TBM_SURFACE_ALIGNMENT_PLANE (64)
110 #define TBM_SURFACE_ALIGNMENT_PITCH_RGB (64)
111 #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16)
114 /* check condition */
115 #define EXYNOS4412_RETURN_IF_FAIL(cond) {\
117 TBM_EXYNOS4412_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
121 #define EXYNOS4412_RETURN_VAL_IF_FAIL(cond, val) {\
123 TBM_EXYNOS4412_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
128 struct dma_buf_info {
130 unsigned int fence_supported;
131 unsigned int padding;
134 #define DMA_BUF_ACCESS_READ 0x1
135 #define DMA_BUF_ACCESS_WRITE 0x2
136 #define DMA_BUF_ACCESS_DMA 0x4
137 #define DMA_BUF_ACCESS_MAX 0x8
139 #define DMA_FENCE_LIST_MAX 5
141 struct dma_buf_fence {
146 #define DMABUF_IOCTL_BASE 'F'
147 #define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type)
149 #define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info)
150 #define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence)
151 #define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence)
153 typedef struct _tbm_bufmgr_exynos4412 *tbm_bufmgr_exynos4412;
154 typedef struct _tbm_bo_exynos4412 *tbm_bo_exynos4412;
156 typedef struct _exynos4412_private
161 /* tbm buffor object for exynos4412 */
162 struct _tbm_bo_exynos4412
166 unsigned int name; /* FLINK ID */
168 unsigned int gem; /* GEM Handle */
170 unsigned int dmabuf; /* fd for dmabuf */
172 void *pBase; /* virtual address */
176 unsigned int flags_exynos;
177 unsigned int flags_tbm;
181 pthread_mutex_t mutex;
182 struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
187 /* tbm bufmgr private for exynos4412 */
188 struct _tbm_bufmgr_exynos4412
215 uint32_t tbm_exynos4412_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888,
226 _get_exynos_flag_from_tbm (unsigned int ftbm)
228 unsigned int flags = 0;
230 if (ftbm & TBM_BO_SCANOUT)
231 flags |= EXYNOS_BO_CONTIG;
233 flags |= EXYNOS_BO_NONCONTIG;
235 if (ftbm & TBM_BO_WC)
236 flags |= EXYNOS_BO_WC;
237 else if (ftbm & TBM_BO_NONCACHABLE)
238 flags |= EXYNOS_BO_NONCACHABLE;
240 flags |= EXYNOS_BO_CACHABLE;
246 _get_tbm_flag_from_exynos (unsigned int fexynos)
248 unsigned int flags = 0;
250 if (fexynos & EXYNOS_BO_NONCONTIG)
251 flags |= TBM_BO_DEFAULT;
253 flags |= TBM_BO_SCANOUT;
255 if (fexynos & EXYNOS_BO_WC)
257 else if (fexynos & EXYNOS_BO_CACHABLE)
258 flags |= TBM_BO_DEFAULT;
260 flags |= TBM_BO_NONCACHABLE;
266 _get_name (int fd, unsigned int gem)
268 struct drm_gem_flink arg = {0,};
271 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg))
273 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
274 "error %s:%d fail to get flink gem=%d\n",
275 getpid(), __FUNCTION__, __LINE__, gem);
279 return (unsigned int)arg.name;
283 _exynos4412_bo_handle (tbm_bo_exynos4412 bo_exynos4412, int device)
285 tbm_bo_handle bo_handle;
286 memset (&bo_handle, 0x0, sizeof (uint64_t));
290 case TBM_DEVICE_DEFAULT:
292 bo_handle.u32 = (uint32_t)bo_exynos4412->gem;
295 if (!bo_exynos4412->pBase)
297 struct drm_exynos_gem_mmap arg = {0,};
299 arg.handle = bo_exynos4412->gem;
300 arg.size = bo_exynos4412->size;
301 if (drmCommandWriteRead (bo_exynos4412->fd, DRM_EXYNOS_GEM_MMAP, &arg, sizeof(arg)))
303 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
304 "error %s:%d Cannot usrptr gem=%d\n",
305 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
306 return (tbm_bo_handle) NULL;
308 bo_exynos4412->pBase = (void*)((uint64_t)arg.mapped);
311 bo_handle.ptr = (void *)bo_exynos4412->pBase;
315 if (bo_exynos4412->dmabuf)
317 bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
321 if (!bo_exynos4412->dmabuf)
323 struct drm_prime_handle arg = {0, };
325 arg.handle = bo_exynos4412->gem;
326 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
328 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
329 "error %s:%d Cannot dmabuf=%d\n",
330 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
331 return (tbm_bo_handle) NULL;
333 bo_exynos4412->dmabuf = arg.fd;
336 bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
340 if (!bo_exynos4412->dmabuf)
342 struct drm_prime_handle arg = {0, };
344 arg.handle = bo_exynos4412->gem;
345 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
347 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
348 "error %s:%d Cannot dmabuf=%d\n",
349 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
350 return (tbm_bo_handle) NULL;
352 bo_exynos4412->dmabuf = arg.fd;
355 bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
358 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
359 "error %s:%d Not supported device:%d\n",
360 getpid(), __FUNCTION__, __LINE__, device);
361 bo_handle.ptr = (void *) NULL;
369 _exynos4412_cache_flush (int fd, tbm_bo_exynos4412 bo_exynos4412, int flags)
371 #ifdef ENABLE_CACHECRTL
372 struct drm_exynos_gem_cache_op cache_op = {0, };
375 /* if bo_exynos4412 is null, do cache_flush_all */
379 cache_op.usr_addr = (uint64_t)((uint32_t)bo_exynos4412->pBase);
380 cache_op.size = bo_exynos4412->size;
384 flags = TBM_CACHE_FLUSH_ALL;
386 cache_op.usr_addr = 0;
390 if (flags & TBM_CACHE_INV)
392 if(flags & TBM_CACHE_ALL)
393 cache_op.flags |= EXYNOS_DRM_CACHE_INV_ALL;
395 cache_op.flags |= EXYNOS_DRM_CACHE_INV_RANGE;
398 if (flags & TBM_CACHE_CLN)
400 if(flags & TBM_CACHE_ALL)
401 cache_op.flags |= EXYNOS_DRM_CACHE_CLN_ALL;
403 cache_op.flags |= EXYNOS_DRM_CACHE_CLN_RANGE;
406 if(flags & TBM_CACHE_ALL)
407 cache_op.flags |= EXYNOS_DRM_ALL_CACHES_CORES;
409 ret = drmCommandWriteRead (fd, DRM_EXYNOS_GEM_CACHE_OP, &cache_op, sizeof(cache_op));
412 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
413 "error %s:%d fail to flush the cache.\n",
414 getpid(), __FUNCTION__, __LINE__);
418 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
419 "warning %s:%d fail to enable the cache flush.\n",
420 getpid(), __FUNCTION__, __LINE__);
426 tbm_exynos4412_bo_size (tbm_bo bo)
428 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
430 tbm_bo_exynos4412 bo_exynos4412;
432 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
434 return bo_exynos4412->size;
438 tbm_exynos4412_bo_alloc (tbm_bo bo, int size, int flags)
440 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
442 tbm_bo_exynos4412 bo_exynos4412;
443 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
444 unsigned int exynos_flags;
446 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
447 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
449 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
452 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
453 "error %s:%d fail to allocate the bo private\n",
454 getpid(), __FUNCTION__, __LINE__);
458 exynos_flags = _get_exynos_flag_from_tbm (flags);
459 if((flags & TBM_BO_SCANOUT) &&
462 exynos_flags |= EXYNOS_BO_NONCONTIG;
465 struct drm_exynos_gem_create arg = {0, };
467 arg.flags = exynos_flags;
468 if (drmCommandWriteRead(bufmgr_exynos4412->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg)))
470 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
471 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
472 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
473 free (bo_exynos4412);
477 bo_exynos4412->fd = bufmgr_exynos4412->fd;
478 bo_exynos4412->gem = arg.handle;
479 bo_exynos4412->size = size;
480 bo_exynos4412->flags_tbm = flags;
481 bo_exynos4412->flags_exynos = exynos_flags;
482 bo_exynos4412->name = _get_name (bo_exynos4412->fd, bo_exynos4412->gem);
484 pthread_mutex_init(&bo_exynos4412->mutex, NULL);
486 if (bufmgr_exynos4412->use_dma_fence
487 && !bo_exynos4412->dmabuf)
489 struct drm_prime_handle arg = {0, };
491 arg.handle = bo_exynos4412->gem;
492 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
494 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
495 "error %s:%d Cannot dmabuf=%d\n",
496 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
497 free (bo_exynos4412);
500 bo_exynos4412->dmabuf = arg.fd;
504 PrivGem* privGem = calloc (1, sizeof(PrivGem));
505 privGem->ref_count = 1;
506 if (drmHashInsert(bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
508 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
509 "error %s:%d Cannot insert bo to Hash(%d)\n",
510 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
513 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
514 __FUNCTION__, bo_exynos4412->size,
515 bo_exynos4412->gem, bo_exynos4412->name,
516 flags, exynos_flags);
518 return (void *)bo_exynos4412;
522 tbm_exynos4412_bo_free(tbm_bo bo)
524 tbm_bo_exynos4412 bo_exynos4412;
525 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
530 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
531 EXYNOS4412_RETURN_IF_FAIL (bufmgr_exynos4412!=NULL);
533 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
534 EXYNOS4412_RETURN_IF_FAIL (bo_exynos4412!=NULL);
536 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d)\n",
537 getpid(), __FUNCTION__, bo_exynos4412->size, bo_exynos4412->gem, bo_exynos4412->name);
539 if (bo_exynos4412->pBase)
541 if (munmap(bo_exynos4412->pBase, bo_exynos4412->size) == -1)
543 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
545 getpid(), __FUNCTION__, __LINE__);
550 if (bo_exynos4412->dmabuf)
552 close (bo_exynos4412->dmabuf);
553 bo_exynos4412->dmabuf = 0;
556 /* delete bo from hash */
557 PrivGem *privGem = NULL;
560 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
563 privGem->ref_count--;
564 if (privGem->ref_count == 0)
566 drmHashDelete (bufmgr_exynos4412->hashBos, bo_exynos4412->name);
573 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
574 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
575 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name, ret);
578 /* Free gem handle */
579 struct drm_gem_close arg = {0, };
580 memset (&arg, 0, sizeof(arg));
581 arg.handle = bo_exynos4412->gem;
582 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_GEM_CLOSE, &arg))
584 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
586 getpid(), __FUNCTION__, __LINE__);
589 free (bo_exynos4412);
594 tbm_exynos4412_bo_import (tbm_bo bo, unsigned int key)
596 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
598 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
599 tbm_bo_exynos4412 bo_exynos4412;
601 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
602 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
604 struct drm_gem_open arg = {0, };
605 struct drm_exynos_gem_info info = {0, };
608 if (drmIoctl(bufmgr_exynos4412->fd, DRM_IOCTL_GEM_OPEN, &arg))
610 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
611 "error %s:%d Cannot open gem name=%d\n",
612 getpid(), __FUNCTION__, __LINE__, key);
616 info.handle = arg.handle;
617 if (drmCommandWriteRead(bufmgr_exynos4412->fd,
620 sizeof(struct drm_exynos_gem_info)))
622 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
623 "error %s:%d Cannot get gem info=%d\n",
624 getpid(), __FUNCTION__, __LINE__, key);
628 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
631 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
632 "error %s:%d fail to allocate the bo private\n",
633 getpid(), __FUNCTION__, __LINE__);
637 bo_exynos4412->fd = bufmgr_exynos4412->fd;
638 bo_exynos4412->gem = arg.handle;
639 bo_exynos4412->size = arg.size;
640 bo_exynos4412->flags_exynos = info.flags;
641 bo_exynos4412->name = key;
642 bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
644 if (!bo_exynos4412->dmabuf)
646 struct drm_prime_handle arg = {0, };
648 arg.handle = bo_exynos4412->gem;
649 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
651 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
652 "error %s:%d Cannot dmabuf=%d\n",
653 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
654 free (bo_exynos4412);
657 bo_exynos4412->dmabuf = arg.fd;
661 PrivGem *privGem = NULL;
664 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
667 privGem->ref_count++;
671 privGem = calloc (1, sizeof(PrivGem));
672 privGem->ref_count = 1;
673 if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
675 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
676 "error %s:%d Cannot insert bo to Hash(%d)\n",
677 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
682 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
683 "error %s:%d Cannot insert bo to Hash(%d)\n",
684 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
687 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d, %d), flags:%d(%d)\n", getpid(),
688 __FUNCTION__, bo_exynos4412->size,
689 bo_exynos4412->gem, bo_exynos4412->name, bo_exynos4412->dmabuf,
690 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
692 return (void *)bo_exynos4412;
696 tbm_exynos4412_bo_import_fd (tbm_bo bo, tbm_fd key)
698 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
700 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
701 tbm_bo_exynos4412 bo_exynos4412;
703 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
704 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
706 unsigned int gem = 0;
707 unsigned int real_size = -1;
708 struct drm_exynos_gem_info info = {0, };
710 //getting handle from fd
711 struct drm_prime_handle arg = {0, };
715 if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
717 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
718 "error %s:%d Cannot getting gem from prime fd=%d\n",
719 getpid(), __FUNCTION__, __LINE__, arg.fd);
724 /* Determine size of bo. The fd-to-handle ioctl really should
725 * return the size, but it doesn't. If we have kernel 3.12 or
726 * later, we can lseek on the prime fd to get the size. Older
727 * kernels will just fail, in which case we fall back to the
728 * provided (estimated or guess size). */
729 real_size = lseek(key, 0, SEEK_END);
732 if (drmCommandWriteRead(bufmgr_exynos4412->fd,
735 sizeof(struct drm_exynos_gem_info)))
737 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
738 "error %s:%d Cannot get gem info=%d\n",
739 getpid(), __FUNCTION__, __LINE__, key);
744 real_size = info.size;
746 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
749 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
750 "error %s:%d fail to allocate the bo private\n",
751 getpid(), __FUNCTION__, __LINE__);
755 bo_exynos4412->fd = bufmgr_exynos4412->fd;
756 bo_exynos4412->gem = gem;
757 bo_exynos4412->size = real_size;
758 bo_exynos4412->flags_exynos = info.flags;
759 bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
761 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
762 if (!bo_exynos4412->name)
764 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
765 "error %s:%d Cannot get name\n",
766 getpid(), __FUNCTION__, __LINE__);
770 bo_exynos4412->dmabuf = (unsigned int)key;
773 PrivGem *privGem = NULL;
776 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
779 privGem->ref_count++;
783 privGem = calloc (1, sizeof(PrivGem));
784 privGem->ref_count = 1;
785 if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
787 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
788 "error %s:%d Cannot insert bo to Hash(%d)\n",
789 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
794 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
795 "error %s:%d Cannot insert bo to Hash(%d)\n",
796 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
799 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d,%d), flags:%d(%d)\n", getpid(),
800 __FUNCTION__, bo_exynos4412->size,
801 bo_exynos4412->gem, bo_exynos4412->name, bo_exynos4412->dmabuf,
802 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
804 return (void *)bo_exynos4412;
808 tbm_exynos4412_bo_export (tbm_bo bo)
810 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
812 tbm_bo_exynos4412 bo_exynos4412;
814 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
815 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
817 if (!bo_exynos4412->name)
819 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
820 if (!bo_exynos4412->name)
822 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
823 "error %s:%d Cannot get name\n",
824 getpid(), __FUNCTION__, __LINE__);
829 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
830 __FUNCTION__, bo_exynos4412->size,
831 bo_exynos4412->gem, bo_exynos4412->name,
832 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
834 return (unsigned int)bo_exynos4412->name;
838 tbm_exynos4412_bo_export_fd (tbm_bo bo)
840 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
842 tbm_bo_exynos4412 bo_exynos4412;
844 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
845 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
847 if (!bo_exynos4412->dmabuf)
849 struct drm_prime_handle arg = {0, };
851 arg.handle = bo_exynos4412->gem;
852 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
854 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
855 "error %s:%d Cannot dmabuf=%d\n",
856 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
859 bo_exynos4412->dmabuf = arg.fd;
862 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d, %d), flags:%d(%d)\n", getpid(),
863 __FUNCTION__, bo_exynos4412->size,
864 bo_exynos4412->gem, bo_exynos4412->name, bo_exynos4412->dmabuf,
865 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
867 return (tbm_fd)bo_exynos4412->dmabuf;
871 tbm_exynos4412_bo_get_handle (tbm_bo bo, int device)
873 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
875 tbm_bo_handle bo_handle;
876 tbm_bo_exynos4412 bo_exynos4412;
878 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
879 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
881 if (!bo_exynos4412->gem)
883 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
884 "error %s:%d Cannot map gem=%d\n",
885 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
886 return (tbm_bo_handle) NULL;
889 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s\n", getpid(),
890 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device]);
892 /*Get mapped bo_handle*/
893 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
894 if (bo_handle.ptr == NULL)
896 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
897 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
898 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device);
899 return (tbm_bo_handle) NULL;
906 tbm_exynos4412_bo_map (tbm_bo bo, int device, int opt)
908 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
910 tbm_bo_handle bo_handle;
911 tbm_bo_exynos4412 bo_exynos4412;
913 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
914 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
916 if (!bo_exynos4412->gem)
918 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
919 "error %s:%d Cannot map gem=%d\n",
920 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
921 return (tbm_bo_handle) NULL;
924 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s, %s\n", getpid(),
925 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device], STR_OPT[opt]);
927 /*Get mapped bo_handle*/
928 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
929 if (bo_handle.ptr == NULL)
931 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
932 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
933 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device, opt);
934 return (tbm_bo_handle) NULL;
941 tbm_exynos4412_bo_unmap (tbm_bo bo)
943 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
945 tbm_bo_exynos4412 bo_exynos4412;
947 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
948 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
950 if (!bo_exynos4412->gem)
953 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d) \n", getpid(),
954 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name);
960 tbm_exynos4412_bo_cache_flush (tbm_bo bo, int flags)
962 tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
963 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
965 /* cache flush is managed by kernel side when using dma-fence. */
966 if (bufmgr_exynos4412->use_dma_fence)
969 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
971 tbm_bo_exynos4412 bo_exynos4412;
973 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
974 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
976 if (!_exynos4412_cache_flush(bo_exynos4412->fd, bo_exynos4412, flags))
983 tbm_exynos4412_bo_get_global_key (tbm_bo bo)
985 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
987 tbm_bo_exynos4412 bo_exynos4412;
989 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
990 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
992 if (!bo_exynos4412->name)
994 if (!bo_exynos4412->gem)
997 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
1000 return bo_exynos4412->name;
1004 tbm_exynos4412_bo_lock(tbm_bo bo, int device, int opt)
1006 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1008 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1009 tbm_bo_exynos4412 bo_exynos4412;
1010 struct dma_buf_fence fence;
1011 struct flock filelock;
1014 if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU)
1016 DBG ("[libtbm-exynos4412:%d] %s not support device type,\n", getpid(), __FUNCTION__);
1020 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1021 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1023 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
1024 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
1026 memset(&fence, 0, sizeof(struct dma_buf_fence));
1028 /* Check if the given type is valid or not. */
1029 if (opt & TBM_OPTION_WRITE)
1031 if (device == TBM_DEVICE_3D)
1032 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1034 else if (opt & TBM_OPTION_READ)
1036 if (device == TBM_DEVICE_3D)
1037 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1041 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__);
1045 /* Check if the tbm manager supports dma fence or not. */
1046 if (!bufmgr_exynos4412->use_dma_fence)
1048 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1049 "error %s:%d Not support DMA FENCE(%s)\n",
1050 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1055 if (device == TBM_DEVICE_3D)
1057 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1060 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1061 "error %s:%d Can not set GET FENCE(%s)\n",
1062 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1067 if (opt & TBM_OPTION_WRITE)
1068 filelock.l_type = F_WRLCK;
1070 filelock.l_type = F_RDLCK;
1072 filelock.l_whence = SEEK_CUR;
1073 filelock.l_start = 0;
1076 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1082 pthread_mutex_lock(&bo_exynos4412->mutex);
1084 if (device == TBM_DEVICE_3D)
1087 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1089 if (bo_exynos4412->dma_fence[i].ctx == 0)
1091 bo_exynos4412->dma_fence[i].type = fence.type;
1092 bo_exynos4412->dma_fence[i].ctx = fence.ctx;
1097 if (i == DMA_FENCE_LIST_MAX)
1099 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1100 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1101 "error %s:%d fence list is full\n",
1102 getpid(), __FUNCTION__, __LINE__);
1106 pthread_mutex_unlock(&bo_exynos4412->mutex);
1108 DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1109 __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
1115 tbm_exynos4412_bo_unlock(tbm_bo bo)
1117 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1119 tbm_bo_exynos4412 bo_exynos4412;
1120 struct dma_buf_fence fence;
1121 struct flock filelock;
1122 unsigned int dma_type = 0;
1125 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1126 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1128 if (bo_exynos4412->dma_fence[0].type & DMA_BUF_ACCESS_DMA)
1131 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1133 DBG ("[libtbm-exynos4412:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1137 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1139 DBG ("[libtbm-exynos4412:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1143 pthread_mutex_lock(&bo_exynos4412->mutex);
1147 fence.type = bo_exynos4412->dma_fence[0].type;
1148 fence.ctx = bo_exynos4412->dma_fence[0].ctx;
1150 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1152 bo_exynos4412->dma_fence[i-1].type = bo_exynos4412->dma_fence[i].type;
1153 bo_exynos4412->dma_fence[i-1].ctx = bo_exynos4412->dma_fence[i].ctx;
1155 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1156 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1158 pthread_mutex_unlock(&bo_exynos4412->mutex);
1162 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1165 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1166 "error %s:%d Can not set PUT FENCE(%s)\n",
1167 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1172 filelock.l_type = F_UNLCK;
1173 filelock.l_whence = SEEK_CUR;
1174 filelock.l_start = 0;
1177 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1183 DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1184 __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
1190 tbm_exynos4412_bufmgr_deinit (void *priv)
1192 EXYNOS4412_RETURN_IF_FAIL (priv!=NULL);
1194 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1196 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)priv;
1198 if (bufmgr_exynos4412->hashBos)
1203 while (drmHashFirst(bufmgr_exynos4412->hashBos, &key, &value) > 0)
1206 drmHashDelete (bufmgr_exynos4412->hashBos, key);
1209 drmHashDestroy (bufmgr_exynos4412->hashBos);
1210 bufmgr_exynos4412->hashBos = NULL;
1213 free (bufmgr_exynos4412);
1217 tbm_exynos4412_surface_supported_format(uint32_t **formats, uint32_t *num)
1219 uint32_t* color_formats=NULL;
1221 color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1223 if( color_formats == NULL )
1227 memcpy( color_formats, tbm_exynos4412_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1230 *formats = color_formats;
1231 *num = TBM_COLOR_FORMAT_COUNT;
1233 fprintf (stderr, "tbm_exynos4412_surface_supported_format count = %d \n",*num);
1240 * @brief get the plane data of the surface.
1241 * @param[in] surface : the surface
1242 * @param[in] width : the width of the surface
1243 * @param[in] height : the height of the surface
1244 * @param[in] format : the format of the surface
1245 * @param[in] plane_idx : the format of the surface
1246 * @param[out] size : the size of the plane
1247 * @param[out] offset : the offset of the plane
1248 * @param[out] pitch : the pitch of the plane
1249 * @param[out] padding : the padding of the plane
1250 * @return 1 if this function succeeds, otherwise 0.
1253 tbm_exynos4412_surface_get_plane_data(tbm_surface_h surface, int width, int height, tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
1265 case TBM_FORMAT_XRGB4444:
1266 case TBM_FORMAT_XBGR4444:
1267 case TBM_FORMAT_RGBX4444:
1268 case TBM_FORMAT_BGRX4444:
1269 case TBM_FORMAT_ARGB4444:
1270 case TBM_FORMAT_ABGR4444:
1271 case TBM_FORMAT_RGBA4444:
1272 case TBM_FORMAT_BGRA4444:
1273 case TBM_FORMAT_XRGB1555:
1274 case TBM_FORMAT_XBGR1555:
1275 case TBM_FORMAT_RGBX5551:
1276 case TBM_FORMAT_BGRX5551:
1277 case TBM_FORMAT_ARGB1555:
1278 case TBM_FORMAT_ABGR1555:
1279 case TBM_FORMAT_RGBA5551:
1280 case TBM_FORMAT_BGRA5551:
1281 case TBM_FORMAT_RGB565:
1284 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1285 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1288 case TBM_FORMAT_RGB888:
1289 case TBM_FORMAT_BGR888:
1292 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1293 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1296 case TBM_FORMAT_XRGB8888:
1297 case TBM_FORMAT_XBGR8888:
1298 case TBM_FORMAT_RGBX8888:
1299 case TBM_FORMAT_BGRX8888:
1300 case TBM_FORMAT_ARGB8888:
1301 case TBM_FORMAT_ABGR8888:
1302 case TBM_FORMAT_RGBA8888:
1303 case TBM_FORMAT_BGRA8888:
1306 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1307 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1311 case TBM_FORMAT_YUYV:
1312 case TBM_FORMAT_YVYU:
1313 case TBM_FORMAT_UYVY:
1314 case TBM_FORMAT_VYUY:
1315 case TBM_FORMAT_AYUV:
1318 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1319 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1324 * index 0 = Y plane, [7:0] Y
1325 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1327 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1329 case TBM_FORMAT_NV12:
1330 case TBM_FORMAT_NV21:
1335 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1336 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1338 else if( plane_idx ==1 )
1340 _offset = width*height;
1341 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1342 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1346 case TBM_FORMAT_NV16:
1347 case TBM_FORMAT_NV61:
1349 //if(plane_idx == 0)
1352 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1353 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1357 //else if( plane_idx ==1 )
1360 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1361 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1367 * index 0: Y plane, [7:0] Y
1368 * index 1: Cb plane, [7:0] Cb
1369 * index 2: Cr plane, [7:0] Cr
1371 * index 1: Cr plane, [7:0] Cr
1372 * index 2: Cb plane, [7:0] Cb
1375 NATIVE_BUFFER_FORMAT_YV12
1376 NATIVE_BUFFER_FORMAT_I420
1378 case TBM_FORMAT_YUV410:
1379 case TBM_FORMAT_YVU410:
1382 case TBM_FORMAT_YUV411:
1383 case TBM_FORMAT_YVU411:
1384 case TBM_FORMAT_YUV420:
1385 case TBM_FORMAT_YVU420:
1387 //if(plane_idx == 0)
1390 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1391 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1395 //else if( plane_idx == 1 )
1398 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1399 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1403 //else if (plane_idx == 2 )
1406 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1407 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1410 case TBM_FORMAT_YUV422:
1411 case TBM_FORMAT_YVU422:
1413 //if(plane_idx == 0)
1416 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1417 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1421 //else if( plane_idx == 1 )
1424 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1425 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1429 //else if (plane_idx == 2 )
1432 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1433 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1436 case TBM_FORMAT_YUV444:
1437 case TBM_FORMAT_YVU444:
1439 //if(plane_idx == 0)
1442 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1443 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1447 //else if( plane_idx == 1 )
1450 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1451 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1455 //else if (plane_idx == 2 )
1458 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1459 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1474 * @brief get the size of the surface with a format.
1475 * @param[in] surface : the surface
1476 * @param[in] width : the width of the surface
1477 * @param[in] height : the height of the surface
1478 * @param[in] format : the format of the surface
1479 * @return size of the surface if this function succeeds, otherwise 0.
1483 tbm_exynos4412_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1489 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1494 case TBM_FORMAT_XRGB4444:
1495 case TBM_FORMAT_XBGR4444:
1496 case TBM_FORMAT_RGBX4444:
1497 case TBM_FORMAT_BGRX4444:
1498 case TBM_FORMAT_ARGB4444:
1499 case TBM_FORMAT_ABGR4444:
1500 case TBM_FORMAT_RGBA4444:
1501 case TBM_FORMAT_BGRA4444:
1502 case TBM_FORMAT_XRGB1555:
1503 case TBM_FORMAT_XBGR1555:
1504 case TBM_FORMAT_RGBX5551:
1505 case TBM_FORMAT_BGRX5551:
1506 case TBM_FORMAT_ARGB1555:
1507 case TBM_FORMAT_ABGR1555:
1508 case TBM_FORMAT_RGBA5551:
1509 case TBM_FORMAT_BGRA5551:
1510 case TBM_FORMAT_RGB565:
1512 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1513 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1516 case TBM_FORMAT_RGB888:
1517 case TBM_FORMAT_BGR888:
1519 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1520 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1523 case TBM_FORMAT_XRGB8888:
1524 case TBM_FORMAT_XBGR8888:
1525 case TBM_FORMAT_RGBX8888:
1526 case TBM_FORMAT_BGRX8888:
1527 case TBM_FORMAT_ARGB8888:
1528 case TBM_FORMAT_ABGR8888:
1529 case TBM_FORMAT_RGBA8888:
1530 case TBM_FORMAT_BGRA8888:
1532 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1533 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1536 case TBM_FORMAT_YUYV:
1537 case TBM_FORMAT_YVYU:
1538 case TBM_FORMAT_UYVY:
1539 case TBM_FORMAT_VYUY:
1540 case TBM_FORMAT_AYUV:
1542 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1543 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1547 * index 0 = Y plane, [7:0] Y
1548 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1550 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1552 case TBM_FORMAT_NV12:
1553 case TBM_FORMAT_NV21:
1557 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1558 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1562 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1563 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1568 case TBM_FORMAT_NV16:
1569 case TBM_FORMAT_NV61:
1573 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1574 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1578 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1579 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1585 * index 0: Y plane, [7:0] Y
1586 * index 1: Cb plane, [7:0] Cb
1587 * index 2: Cr plane, [7:0] Cr
1589 * index 1: Cr plane, [7:0] Cr
1590 * index 2: Cb plane, [7:0] Cb
1592 case TBM_FORMAT_YUV410:
1593 case TBM_FORMAT_YVU410:
1595 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1597 case TBM_FORMAT_YUV411:
1598 case TBM_FORMAT_YVU411:
1599 case TBM_FORMAT_YUV420:
1600 case TBM_FORMAT_YVU420:
1604 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1605 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1609 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1610 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1614 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1615 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1619 case TBM_FORMAT_YUV422:
1620 case TBM_FORMAT_YVU422:
1624 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1625 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1629 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1630 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1634 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1635 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1638 case TBM_FORMAT_YUV444:
1639 case TBM_FORMAT_YVU444:
1641 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1652 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1658 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1660 static TBMModuleVersionInfo Exynos4412VersRec =
1667 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
1670 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1672 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1673 tbm_bufmgr_backend bufmgr_backend;
1678 bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
1679 if (!bufmgr_exynos4412)
1681 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to alloc bufmgr_exynos4412!\n", getpid());
1685 bufmgr_exynos4412->fd = fd;
1686 if (bufmgr_exynos4412->fd < 0)
1688 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
1689 free (bufmgr_exynos4412);
1694 bufmgr_exynos4412->hashBos = drmHashCreate ();
1696 //Check if the tbm manager supports dma fence or not.
1697 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1702 length = read(fp, buf, 1);
1704 if (length == 1 && buf[0] == '1')
1705 bufmgr_exynos4412->use_dma_fence = 1;
1710 bufmgr_backend = tbm_backend_alloc();
1711 if (!bufmgr_backend)
1713 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
1714 free (bufmgr_exynos4412);
1718 bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1719 bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1720 bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1721 bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1722 bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1723 bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1724 bufmgr_backend->bo_import_fd = tbm_exynos4412_bo_import_fd,
1725 bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1726 bufmgr_backend->bo_export_fd = tbm_exynos4412_bo_export_fd,
1727 bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1728 bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1729 bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1730 bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1731 bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1732 bufmgr_backend->surface_get_plane_data = tbm_exynos4412_surface_get_plane_data;
1733 bufmgr_backend->surface_get_size = tbm_exynos4412_surface_get_size;
1734 bufmgr_backend->surface_supported_format = tbm_exynos4412_surface_supported_format;
1736 if (bufmgr_exynos4412->use_dma_fence)
1738 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1739 bufmgr_backend->bo_lock = NULL;
1740 bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1741 bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1745 bufmgr_backend->flags = 0;
1746 bufmgr_backend->bo_lock = NULL;
1747 bufmgr_backend->bo_unlock = NULL;
1750 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1752 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to init backend!\n", getpid());
1753 tbm_backend_free (bufmgr_backend);
1754 free (bufmgr_exynos4412);
1761 env = getenv ("TBM_EXYNOS4412_DEBUG");
1764 bDebug = atoi (env);
1765 TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1774 DBG ("[libtbm-exynos4412:%d] %s DMABUF FENCE is %s\n", getpid(),
1775 __FUNCTION__, bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1777 DBG ("[libtbm-exynos4412:%d] %s fd:%d\n", getpid(),
1778 __FUNCTION__, bufmgr_exynos4412->fd);