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*)((uint32_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), flags:%d(%d)\n", getpid(),
688 __FUNCTION__, bo_exynos4412->size,
689 bo_exynos4412->gem, bo_exynos4412->name,
690 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
692 return (void *)bo_exynos4412;
696 tbm_exynos4412_bo_export (tbm_bo bo)
698 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
700 tbm_bo_exynos4412 bo_exynos4412;
702 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
703 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
705 if (!bo_exynos4412->name)
707 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
708 if (!bo_exynos4412->name)
710 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
711 "error %s:%d Cannot get name\n",
712 getpid(), __FUNCTION__, __LINE__);
717 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
718 __FUNCTION__, bo_exynos4412->size,
719 bo_exynos4412->gem, bo_exynos4412->name,
720 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
722 return (unsigned int)bo_exynos4412->name;
726 tbm_exynos4412_bo_get_handle (tbm_bo bo, int device)
728 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
730 tbm_bo_handle bo_handle;
731 tbm_bo_exynos4412 bo_exynos4412;
733 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
734 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
736 if (!bo_exynos4412->gem)
738 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
739 "error %s:%d Cannot map gem=%d\n",
740 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
741 return (tbm_bo_handle) NULL;
744 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s\n", getpid(),
745 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device]);
747 /*Get mapped bo_handle*/
748 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
749 if (bo_handle.ptr == NULL)
751 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
752 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
753 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device);
754 return (tbm_bo_handle) NULL;
761 tbm_exynos4412_bo_map (tbm_bo bo, int device, int opt)
763 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
765 tbm_bo_handle bo_handle;
766 tbm_bo_exynos4412 bo_exynos4412;
768 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
769 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
771 if (!bo_exynos4412->gem)
773 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
774 "error %s:%d Cannot map gem=%d\n",
775 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
776 return (tbm_bo_handle) NULL;
779 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s, %s\n", getpid(),
780 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device], STR_OPT[opt]);
782 /*Get mapped bo_handle*/
783 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
784 if (bo_handle.ptr == NULL)
786 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
787 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
788 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device, opt);
789 return (tbm_bo_handle) NULL;
796 tbm_exynos4412_bo_unmap (tbm_bo bo)
798 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
800 tbm_bo_exynos4412 bo_exynos4412;
802 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
803 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
805 if (!bo_exynos4412->gem)
808 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d) \n", getpid(),
809 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name);
815 tbm_exynos4412_bo_cache_flush (tbm_bo bo, int flags)
817 tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
818 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
820 /* cache flush is managed by kernel side when using dma-fence. */
821 if (bufmgr_exynos4412->use_dma_fence)
824 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
826 tbm_bo_exynos4412 bo_exynos4412;
828 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
829 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
831 if (!_exynos4412_cache_flush(bo_exynos4412->fd, bo_exynos4412, flags))
838 tbm_exynos4412_bo_get_global_key (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->name)
849 if (!bo_exynos4412->gem)
852 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
855 return bo_exynos4412->name;
859 tbm_exynos4412_bo_lock(tbm_bo bo, int device, int opt)
861 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
863 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
864 tbm_bo_exynos4412 bo_exynos4412;
865 struct dma_buf_fence fence;
866 struct flock filelock;
869 if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU)
871 DBG ("[libtbm-exynos4412:%d] %s not support device type,\n", getpid(), __FUNCTION__);
875 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
876 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
878 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
879 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
881 memset(&fence, 0, sizeof(struct dma_buf_fence));
883 /* Check if the given type is valid or not. */
884 if (opt & TBM_OPTION_WRITE)
886 if (device == TBM_DEVICE_3D)
887 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
889 else if (opt & TBM_OPTION_READ)
891 if (device == TBM_DEVICE_3D)
892 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
896 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__);
900 /* Check if the tbm manager supports dma fence or not. */
901 if (!bufmgr_exynos4412->use_dma_fence)
903 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
904 "error %s:%d Not support DMA FENCE(%s)\n",
905 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
910 if (device == TBM_DEVICE_3D)
912 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
915 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
916 "error %s:%d Can not set GET FENCE(%s)\n",
917 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
922 if (opt & TBM_OPTION_WRITE)
923 filelock.l_type = F_WRLCK;
925 filelock.l_type = F_RDLCK;
927 filelock.l_whence = SEEK_CUR;
928 filelock.l_start = 0;
931 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
937 pthread_mutex_lock(&bo_exynos4412->mutex);
939 if (device == TBM_DEVICE_3D)
942 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
944 if (bo_exynos4412->dma_fence[i].ctx == 0)
946 bo_exynos4412->dma_fence[i].type = fence.type;
947 bo_exynos4412->dma_fence[i].ctx = fence.ctx;
952 if (i == DMA_FENCE_LIST_MAX)
954 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
955 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
956 "error %s:%d fence list is full\n",
957 getpid(), __FUNCTION__, __LINE__);
961 pthread_mutex_unlock(&bo_exynos4412->mutex);
963 DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
964 __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
970 tbm_exynos4412_bo_unlock(tbm_bo bo)
972 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
974 tbm_bo_exynos4412 bo_exynos4412;
975 struct dma_buf_fence fence;
976 struct flock filelock;
977 unsigned int dma_type = 0;
980 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
981 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
983 if (bo_exynos4412->dma_fence[0].type & DMA_BUF_ACCESS_DMA)
986 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
988 DBG ("[libtbm-exynos4412:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
992 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
994 DBG ("[libtbm-exynos4412:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
998 pthread_mutex_lock(&bo_exynos4412->mutex);
1002 fence.type = bo_exynos4412->dma_fence[0].type;
1003 fence.ctx = bo_exynos4412->dma_fence[0].ctx;
1005 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1007 bo_exynos4412->dma_fence[i-1].type = bo_exynos4412->dma_fence[i].type;
1008 bo_exynos4412->dma_fence[i-1].ctx = bo_exynos4412->dma_fence[i].ctx;
1010 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1011 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1013 pthread_mutex_unlock(&bo_exynos4412->mutex);
1017 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1020 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1021 "error %s:%d Can not set PUT FENCE(%s)\n",
1022 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1027 filelock.l_type = F_UNLCK;
1028 filelock.l_whence = SEEK_CUR;
1029 filelock.l_start = 0;
1032 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1038 DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1039 __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
1045 tbm_exynos4412_bufmgr_deinit (void *priv)
1047 EXYNOS4412_RETURN_IF_FAIL (priv!=NULL);
1049 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1051 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)priv;
1053 if (bufmgr_exynos4412->hashBos)
1058 while (drmHashFirst(bufmgr_exynos4412->hashBos, &key, &value) > 0)
1061 drmHashDelete (bufmgr_exynos4412->hashBos, key);
1064 drmHashDestroy (bufmgr_exynos4412->hashBos);
1065 bufmgr_exynos4412->hashBos = NULL;
1068 free (bufmgr_exynos4412);
1072 tbm_exynos4412_surface_supported_format(uint32_t **formats, uint32_t *num)
1074 uint32_t* color_formats=NULL;
1076 color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1078 if( color_formats == NULL )
1082 memcpy( color_formats, tbm_exynos4412_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1085 *formats = color_formats;
1086 *num = TBM_COLOR_FORMAT_COUNT;
1088 fprintf (stderr, "tbm_exynos4412_surface_supported_format count = %d \n",*num);
1095 * @brief get the plane data of the surface.
1096 * @param[in] surface : the surface
1097 * @param[in] width : the width of the surface
1098 * @param[in] height : the height of the surface
1099 * @param[in] format : the format of the surface
1100 * @param[in] plane_idx : the format of the surface
1101 * @param[out] size : the size of the plane
1102 * @param[out] offset : the offset of the plane
1103 * @param[out] pitch : the pitch of the plane
1104 * @param[out] padding : the padding of the plane
1105 * @return 1 if this function succeeds, otherwise 0.
1108 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)
1120 case TBM_FORMAT_XRGB4444:
1121 case TBM_FORMAT_XBGR4444:
1122 case TBM_FORMAT_RGBX4444:
1123 case TBM_FORMAT_BGRX4444:
1124 case TBM_FORMAT_ARGB4444:
1125 case TBM_FORMAT_ABGR4444:
1126 case TBM_FORMAT_RGBA4444:
1127 case TBM_FORMAT_BGRA4444:
1128 case TBM_FORMAT_XRGB1555:
1129 case TBM_FORMAT_XBGR1555:
1130 case TBM_FORMAT_RGBX5551:
1131 case TBM_FORMAT_BGRX5551:
1132 case TBM_FORMAT_ARGB1555:
1133 case TBM_FORMAT_ABGR1555:
1134 case TBM_FORMAT_RGBA5551:
1135 case TBM_FORMAT_BGRA5551:
1136 case TBM_FORMAT_RGB565:
1139 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1140 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1143 case TBM_FORMAT_RGB888:
1144 case TBM_FORMAT_BGR888:
1147 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1148 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1151 case TBM_FORMAT_XRGB8888:
1152 case TBM_FORMAT_XBGR8888:
1153 case TBM_FORMAT_RGBX8888:
1154 case TBM_FORMAT_BGRX8888:
1155 case TBM_FORMAT_ARGB8888:
1156 case TBM_FORMAT_ABGR8888:
1157 case TBM_FORMAT_RGBA8888:
1158 case TBM_FORMAT_BGRA8888:
1161 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1162 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1166 case TBM_FORMAT_YUYV:
1167 case TBM_FORMAT_YVYU:
1168 case TBM_FORMAT_UYVY:
1169 case TBM_FORMAT_VYUY:
1170 case TBM_FORMAT_AYUV:
1173 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1174 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1179 * index 0 = Y plane, [7:0] Y
1180 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1182 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1184 case TBM_FORMAT_NV12:
1185 case TBM_FORMAT_NV21:
1190 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1191 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1193 else if( plane_idx ==1 )
1195 _offset = width*height;
1196 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1197 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1201 case TBM_FORMAT_NV16:
1202 case TBM_FORMAT_NV61:
1204 //if(plane_idx == 0)
1207 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1208 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1212 //else if( plane_idx ==1 )
1215 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1216 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1222 * index 0: Y plane, [7:0] Y
1223 * index 1: Cb plane, [7:0] Cb
1224 * index 2: Cr plane, [7:0] Cr
1226 * index 1: Cr plane, [7:0] Cr
1227 * index 2: Cb plane, [7:0] Cb
1230 NATIVE_BUFFER_FORMAT_YV12
1231 NATIVE_BUFFER_FORMAT_I420
1233 case TBM_FORMAT_YUV410:
1234 case TBM_FORMAT_YVU410:
1237 case TBM_FORMAT_YUV411:
1238 case TBM_FORMAT_YVU411:
1239 case TBM_FORMAT_YUV420:
1240 case TBM_FORMAT_YVU420:
1242 //if(plane_idx == 0)
1245 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1246 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1250 //else if( plane_idx == 1 )
1253 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1254 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1258 //else if (plane_idx == 2 )
1261 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1262 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1265 case TBM_FORMAT_YUV422:
1266 case TBM_FORMAT_YVU422:
1268 //if(plane_idx == 0)
1271 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1272 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1276 //else if( plane_idx == 1 )
1279 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1280 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1284 //else if (plane_idx == 2 )
1287 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1288 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1291 case TBM_FORMAT_YUV444:
1292 case TBM_FORMAT_YVU444:
1294 //if(plane_idx == 0)
1297 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1298 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1302 //else if( plane_idx == 1 )
1305 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1306 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1310 //else if (plane_idx == 2 )
1313 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1314 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1329 * @brief get the size of the surface with a format.
1330 * @param[in] surface : the surface
1331 * @param[in] width : the width of the surface
1332 * @param[in] height : the height of the surface
1333 * @param[in] format : the format of the surface
1334 * @return size of the surface if this function succeeds, otherwise 0.
1338 tbm_exynos4412_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1344 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1349 case TBM_FORMAT_XRGB4444:
1350 case TBM_FORMAT_XBGR4444:
1351 case TBM_FORMAT_RGBX4444:
1352 case TBM_FORMAT_BGRX4444:
1353 case TBM_FORMAT_ARGB4444:
1354 case TBM_FORMAT_ABGR4444:
1355 case TBM_FORMAT_RGBA4444:
1356 case TBM_FORMAT_BGRA4444:
1357 case TBM_FORMAT_XRGB1555:
1358 case TBM_FORMAT_XBGR1555:
1359 case TBM_FORMAT_RGBX5551:
1360 case TBM_FORMAT_BGRX5551:
1361 case TBM_FORMAT_ARGB1555:
1362 case TBM_FORMAT_ABGR1555:
1363 case TBM_FORMAT_RGBA5551:
1364 case TBM_FORMAT_BGRA5551:
1365 case TBM_FORMAT_RGB565:
1367 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1368 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1371 case TBM_FORMAT_RGB888:
1372 case TBM_FORMAT_BGR888:
1374 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1375 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1378 case TBM_FORMAT_XRGB8888:
1379 case TBM_FORMAT_XBGR8888:
1380 case TBM_FORMAT_RGBX8888:
1381 case TBM_FORMAT_BGRX8888:
1382 case TBM_FORMAT_ARGB8888:
1383 case TBM_FORMAT_ABGR8888:
1384 case TBM_FORMAT_RGBA8888:
1385 case TBM_FORMAT_BGRA8888:
1387 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1388 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1391 case TBM_FORMAT_YUYV:
1392 case TBM_FORMAT_YVYU:
1393 case TBM_FORMAT_UYVY:
1394 case TBM_FORMAT_VYUY:
1395 case TBM_FORMAT_AYUV:
1397 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1398 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1402 * index 0 = Y plane, [7:0] Y
1403 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1405 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1407 case TBM_FORMAT_NV12:
1408 case TBM_FORMAT_NV21:
1412 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1413 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1417 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1418 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1423 case TBM_FORMAT_NV16:
1424 case TBM_FORMAT_NV61:
1428 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1429 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1433 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1434 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1440 * index 0: Y plane, [7:0] Y
1441 * index 1: Cb plane, [7:0] Cb
1442 * index 2: Cr plane, [7:0] Cr
1444 * index 1: Cr plane, [7:0] Cr
1445 * index 2: Cb plane, [7:0] Cb
1447 case TBM_FORMAT_YUV410:
1448 case TBM_FORMAT_YVU410:
1450 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1452 case TBM_FORMAT_YUV411:
1453 case TBM_FORMAT_YVU411:
1454 case TBM_FORMAT_YUV420:
1455 case TBM_FORMAT_YVU420:
1459 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1460 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1464 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1465 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1469 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1470 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1474 case TBM_FORMAT_YUV422:
1475 case TBM_FORMAT_YVU422:
1479 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1480 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1484 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1485 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1489 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1490 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1493 case TBM_FORMAT_YUV444:
1494 case TBM_FORMAT_YVU444:
1496 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1507 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1513 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1515 static TBMModuleVersionInfo Exynos4412VersRec =
1522 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
1525 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1527 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1528 tbm_bufmgr_backend bufmgr_backend;
1533 bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
1534 if (!bufmgr_exynos4412)
1536 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to alloc bufmgr_exynos4412!\n", getpid());
1540 bufmgr_exynos4412->fd = fd;
1541 if (bufmgr_exynos4412->fd < 0)
1543 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
1544 free (bufmgr_exynos4412);
1549 bufmgr_exynos4412->hashBos = drmHashCreate ();
1551 //Check if the tbm manager supports dma fence or not.
1552 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1557 length = read(fp, buf, 1);
1559 if (length == 1 && buf[0] == '1')
1560 bufmgr_exynos4412->use_dma_fence = 1;
1565 bufmgr_backend = tbm_backend_alloc();
1566 if (!bufmgr_backend)
1568 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
1569 free (bufmgr_exynos4412);
1573 bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1574 bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1575 bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1576 bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1577 bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1578 bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1579 bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1580 bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1581 bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1582 bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1583 bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1584 bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1585 bufmgr_backend->surface_get_plane_data = tbm_exynos4412_surface_get_plane_data;
1586 bufmgr_backend->surface_get_size = tbm_exynos4412_surface_get_size;
1587 bufmgr_backend->surface_supported_format = tbm_exynos4412_surface_supported_format;
1589 if (bufmgr_exynos4412->use_dma_fence)
1591 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1592 bufmgr_backend->bo_lock = NULL;
1593 bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1594 bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1598 bufmgr_backend->flags = 0;
1599 bufmgr_backend->bo_lock = NULL;
1600 bufmgr_backend->bo_unlock = NULL;
1603 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1605 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to init backend!\n", getpid());
1606 tbm_backend_free (bufmgr_backend);
1607 free (bufmgr_exynos4412);
1614 env = getenv ("TBM_EXYNOS4412_DEBUG");
1617 bDebug = atoi (env);
1618 TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1627 DBG ("[libtbm-exynos4412:%d] %s DMABUF FENCE is %s\n", getpid(),
1628 __FUNCTION__, bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1630 DBG ("[libtbm-exynos4412:%d] %s fd:%d\n", getpid(),
1631 __FUNCTION__, bufmgr_exynos4412->fd);