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_mode_map_dumb arg = {0,};
300 arg.handle = bo_exynos4412->gem;
301 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg))
303 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
304 "error %s:%d Cannot map_dumb gem=%d\n",
305 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
306 return (tbm_bo_handle) NULL;
309 map = mmap (NULL, bo_exynos4412->size, PROT_READ|PROT_WRITE, MAP_SHARED,
310 bo_exynos4412->fd, arg.offset);
311 if (map == MAP_FAILED)
313 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
314 "error %s:%d Cannot usrptr gem=%d\n",
315 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
316 return (tbm_bo_handle) NULL;
318 bo_exynos4412->pBase = map;
321 bo_handle.ptr = (void *)bo_exynos4412->pBase;
325 if (bo_exynos4412->dmabuf)
327 bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
331 if (!bo_exynos4412->dmabuf)
333 struct drm_prime_handle arg = {0, };
335 arg.handle = bo_exynos4412->gem;
336 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
338 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
339 "error %s:%d Cannot dmabuf=%d\n",
340 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
341 return (tbm_bo_handle) NULL;
343 bo_exynos4412->dmabuf = arg.fd;
346 bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
350 if (!bo_exynos4412->dmabuf)
352 struct drm_prime_handle arg = {0, };
354 arg.handle = bo_exynos4412->gem;
355 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
357 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
358 "error %s:%d Cannot dmabuf=%d\n",
359 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
360 return (tbm_bo_handle) NULL;
362 bo_exynos4412->dmabuf = arg.fd;
365 bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
368 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
369 "error %s:%d Not supported device:%d\n",
370 getpid(), __FUNCTION__, __LINE__, device);
371 bo_handle.ptr = (void *) NULL;
379 _exynos4412_cache_flush (int fd, tbm_bo_exynos4412 bo_exynos4412, int flags)
381 #ifdef ENABLE_CACHECRTL
382 struct drm_exynos_gem_cache_op cache_op = {0, };
385 /* if bo_exynos4412 is null, do cache_flush_all */
389 cache_op.usr_addr = (uint64_t)((uint32_t)bo_exynos4412->pBase);
390 cache_op.size = bo_exynos4412->size;
394 flags = TBM_CACHE_FLUSH_ALL;
396 cache_op.usr_addr = 0;
400 if (flags & TBM_CACHE_INV)
402 if(flags & TBM_CACHE_ALL)
403 cache_op.flags |= EXYNOS_DRM_CACHE_INV_ALL;
405 cache_op.flags |= EXYNOS_DRM_CACHE_INV_RANGE;
408 if (flags & TBM_CACHE_CLN)
410 if(flags & TBM_CACHE_ALL)
411 cache_op.flags |= EXYNOS_DRM_CACHE_CLN_ALL;
413 cache_op.flags |= EXYNOS_DRM_CACHE_CLN_RANGE;
416 if(flags & TBM_CACHE_ALL)
417 cache_op.flags |= EXYNOS_DRM_ALL_CACHES_CORES;
419 ret = drmCommandWriteRead (fd, DRM_EXYNOS_GEM_CACHE_OP, &cache_op, sizeof(cache_op));
422 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
423 "error %s:%d fail to flush the cache.\n",
424 getpid(), __FUNCTION__, __LINE__);
428 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
429 "warning %s:%d fail to enable the cache flush.\n",
430 getpid(), __FUNCTION__, __LINE__);
436 tbm_exynos4412_bo_size (tbm_bo bo)
438 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
440 tbm_bo_exynos4412 bo_exynos4412;
442 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
444 return bo_exynos4412->size;
448 tbm_exynos4412_bo_alloc (tbm_bo bo, int size, int flags)
450 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
452 tbm_bo_exynos4412 bo_exynos4412;
453 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
454 unsigned int exynos_flags;
456 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
457 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
459 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
462 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
463 "error %s:%d fail to allocate the bo private\n",
464 getpid(), __FUNCTION__, __LINE__);
468 exynos_flags = _get_exynos_flag_from_tbm (flags);
469 if((flags & TBM_BO_SCANOUT) &&
472 exynos_flags |= EXYNOS_BO_NONCONTIG;
475 struct drm_exynos_gem_create arg = {0, };
477 arg.flags = exynos_flags;
478 if (drmCommandWriteRead(bufmgr_exynos4412->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg)))
480 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
481 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
482 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
483 free (bo_exynos4412);
487 bo_exynos4412->fd = bufmgr_exynos4412->fd;
488 bo_exynos4412->gem = arg.handle;
489 bo_exynos4412->size = size;
490 bo_exynos4412->flags_tbm = flags;
491 bo_exynos4412->flags_exynos = exynos_flags;
492 bo_exynos4412->name = _get_name (bo_exynos4412->fd, bo_exynos4412->gem);
494 pthread_mutex_init(&bo_exynos4412->mutex, NULL);
496 if (bufmgr_exynos4412->use_dma_fence
497 && !bo_exynos4412->dmabuf)
499 struct drm_prime_handle arg = {0, };
501 arg.handle = bo_exynos4412->gem;
502 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
504 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
505 "error %s:%d Cannot dmabuf=%d\n",
506 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
507 free (bo_exynos4412);
510 bo_exynos4412->dmabuf = arg.fd;
514 PrivGem* privGem = calloc (1, sizeof(PrivGem));
515 privGem->ref_count = 1;
516 if (drmHashInsert(bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
518 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
519 "error %s:%d Cannot insert bo to Hash(%d)\n",
520 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
523 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
524 __FUNCTION__, bo_exynos4412->size,
525 bo_exynos4412->gem, bo_exynos4412->name,
526 flags, exynos_flags);
528 return (void *)bo_exynos4412;
532 tbm_exynos4412_bo_free(tbm_bo bo)
534 tbm_bo_exynos4412 bo_exynos4412;
535 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
540 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
541 EXYNOS4412_RETURN_IF_FAIL (bufmgr_exynos4412!=NULL);
543 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
544 EXYNOS4412_RETURN_IF_FAIL (bo_exynos4412!=NULL);
546 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d)\n",
547 getpid(), __FUNCTION__, bo_exynos4412->size, bo_exynos4412->gem, bo_exynos4412->name);
549 if (bo_exynos4412->pBase)
551 if (munmap(bo_exynos4412->pBase, bo_exynos4412->size) == -1)
553 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
555 getpid(), __FUNCTION__, __LINE__);
560 if (bo_exynos4412->dmabuf)
562 close (bo_exynos4412->dmabuf);
563 bo_exynos4412->dmabuf = 0;
566 /* delete bo from hash */
567 PrivGem *privGem = NULL;
570 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
573 privGem->ref_count--;
574 if (privGem->ref_count == 0)
576 drmHashDelete (bufmgr_exynos4412->hashBos, bo_exynos4412->name);
583 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
584 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
585 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name, ret);
588 /* Free gem handle */
589 struct drm_gem_close arg = {0, };
590 memset (&arg, 0, sizeof(arg));
591 arg.handle = bo_exynos4412->gem;
592 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_GEM_CLOSE, &arg))
594 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
596 getpid(), __FUNCTION__, __LINE__);
599 free (bo_exynos4412);
604 tbm_exynos4412_bo_import (tbm_bo bo, unsigned int key)
606 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
608 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
609 tbm_bo_exynos4412 bo_exynos4412;
611 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
612 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
614 struct drm_gem_open arg = {0, };
615 struct drm_exynos_gem_info info = {0, };
618 if (drmIoctl(bufmgr_exynos4412->fd, DRM_IOCTL_GEM_OPEN, &arg))
620 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
621 "error %s:%d Cannot open gem name=%d\n",
622 getpid(), __FUNCTION__, __LINE__, key);
626 info.handle = arg.handle;
627 if (drmCommandWriteRead(bufmgr_exynos4412->fd,
630 sizeof(struct drm_exynos_gem_info)))
632 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
633 "error %s:%d Cannot get gem info=%d\n",
634 getpid(), __FUNCTION__, __LINE__, key);
638 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
641 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
642 "error %s:%d fail to allocate the bo private\n",
643 getpid(), __FUNCTION__, __LINE__);
647 bo_exynos4412->fd = bufmgr_exynos4412->fd;
648 bo_exynos4412->gem = arg.handle;
649 bo_exynos4412->size = arg.size;
650 bo_exynos4412->flags_exynos = info.flags;
651 bo_exynos4412->name = key;
652 bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
654 if (!bo_exynos4412->dmabuf)
656 struct drm_prime_handle arg = {0, };
658 arg.handle = bo_exynos4412->gem;
659 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
661 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
662 "error %s:%d Cannot dmabuf=%d\n",
663 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
664 free (bo_exynos4412);
667 bo_exynos4412->dmabuf = arg.fd;
671 PrivGem *privGem = NULL;
674 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
677 privGem->ref_count++;
681 privGem = calloc (1, sizeof(PrivGem));
682 privGem->ref_count = 1;
683 if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
685 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
686 "error %s:%d Cannot insert bo to Hash(%d)\n",
687 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
692 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
693 "error %s:%d Cannot insert bo to Hash(%d)\n",
694 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
697 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d, %d), flags:%d(%d)\n", getpid(),
698 __FUNCTION__, bo_exynos4412->size,
699 bo_exynos4412->gem, bo_exynos4412->name, bo_exynos4412->dmabuf,
700 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
702 return (void *)bo_exynos4412;
706 tbm_exynos4412_bo_import_fd (tbm_bo bo, tbm_fd key)
708 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
710 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
711 tbm_bo_exynos4412 bo_exynos4412;
713 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
714 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
716 unsigned int gem = 0;
717 unsigned int real_size = -1;
718 struct drm_exynos_gem_info info = {0, };
720 //getting handle from fd
721 struct drm_prime_handle arg = {0, };
725 if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
727 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
728 "error %s:%d Cannot getting gem from prime fd=%d\n",
729 getpid(), __FUNCTION__, __LINE__, arg.fd);
734 /* Determine size of bo. The fd-to-handle ioctl really should
735 * return the size, but it doesn't. If we have kernel 3.12 or
736 * later, we can lseek on the prime fd to get the size. Older
737 * kernels will just fail, in which case we fall back to the
738 * provided (estimated or guess size). */
739 real_size = lseek(key, 0, SEEK_END);
742 if (drmCommandWriteRead(bufmgr_exynos4412->fd,
745 sizeof(struct drm_exynos_gem_info)))
747 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
748 "error %s:%d Cannot get gem info=%d\n",
749 getpid(), __FUNCTION__, __LINE__, key);
754 real_size = info.size;
756 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
759 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
760 "error %s:%d fail to allocate the bo private\n",
761 getpid(), __FUNCTION__, __LINE__);
765 bo_exynos4412->fd = bufmgr_exynos4412->fd;
766 bo_exynos4412->gem = gem;
767 bo_exynos4412->size = real_size;
768 bo_exynos4412->flags_exynos = info.flags;
769 bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
771 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
772 if (!bo_exynos4412->name)
774 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
775 "error %s:%d Cannot get name\n",
776 getpid(), __FUNCTION__, __LINE__);
780 bo_exynos4412->dmabuf = (unsigned int)key;
783 PrivGem *privGem = NULL;
786 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
789 privGem->ref_count++;
793 privGem = calloc (1, sizeof(PrivGem));
794 privGem->ref_count = 1;
795 if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
797 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
798 "error %s:%d Cannot insert bo to Hash(%d)\n",
799 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
804 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
805 "error %s:%d Cannot insert bo to Hash(%d)\n",
806 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
809 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d,%d), flags:%d(%d)\n", getpid(),
810 __FUNCTION__, bo_exynos4412->size,
811 bo_exynos4412->gem, bo_exynos4412->name, bo_exynos4412->dmabuf,
812 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
814 return (void *)bo_exynos4412;
818 tbm_exynos4412_bo_export (tbm_bo bo)
820 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
822 tbm_bo_exynos4412 bo_exynos4412;
824 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
825 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
827 if (!bo_exynos4412->name)
829 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
830 if (!bo_exynos4412->name)
832 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
833 "error %s:%d Cannot get name\n",
834 getpid(), __FUNCTION__, __LINE__);
839 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
840 __FUNCTION__, bo_exynos4412->size,
841 bo_exynos4412->gem, bo_exynos4412->name,
842 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
844 return (unsigned int)bo_exynos4412->name;
848 tbm_exynos4412_bo_export_fd (tbm_bo bo)
850 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
852 tbm_bo_exynos4412 bo_exynos4412;
854 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
855 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
857 if (!bo_exynos4412->dmabuf)
859 struct drm_prime_handle arg = {0, };
861 arg.handle = bo_exynos4412->gem;
862 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
864 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
865 "error %s:%d Cannot dmabuf=%d\n",
866 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
869 bo_exynos4412->dmabuf = arg.fd;
872 DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d, %d), flags:%d(%d)\n", getpid(),
873 __FUNCTION__, bo_exynos4412->size,
874 bo_exynos4412->gem, bo_exynos4412->name, bo_exynos4412->dmabuf,
875 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
877 return (tbm_fd)bo_exynos4412->dmabuf;
881 tbm_exynos4412_bo_get_handle (tbm_bo bo, int device)
883 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
885 tbm_bo_handle bo_handle;
886 tbm_bo_exynos4412 bo_exynos4412;
888 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
889 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
891 if (!bo_exynos4412->gem)
893 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
894 "error %s:%d Cannot map gem=%d\n",
895 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
896 return (tbm_bo_handle) NULL;
899 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s\n", getpid(),
900 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device]);
902 /*Get mapped bo_handle*/
903 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
904 if (bo_handle.ptr == NULL)
906 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
907 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
908 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device);
909 return (tbm_bo_handle) NULL;
916 tbm_exynos4412_bo_map (tbm_bo bo, int device, int opt)
918 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
920 tbm_bo_handle bo_handle;
921 tbm_bo_exynos4412 bo_exynos4412;
923 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
924 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
926 if (!bo_exynos4412->gem)
928 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
929 "error %s:%d Cannot map gem=%d\n",
930 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
931 return (tbm_bo_handle) NULL;
934 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s, %s\n", getpid(),
935 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device], STR_OPT[opt]);
937 /*Get mapped bo_handle*/
938 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
939 if (bo_handle.ptr == NULL)
941 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
942 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
943 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device, opt);
944 return (tbm_bo_handle) NULL;
951 tbm_exynos4412_bo_unmap (tbm_bo bo)
953 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
955 tbm_bo_exynos4412 bo_exynos4412;
957 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
958 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
960 if (!bo_exynos4412->gem)
963 DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d) \n", getpid(),
964 __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name);
970 tbm_exynos4412_bo_cache_flush (tbm_bo bo, int flags)
972 tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
973 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
975 /* cache flush is managed by kernel side when using dma-fence. */
976 if (bufmgr_exynos4412->use_dma_fence)
979 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
981 tbm_bo_exynos4412 bo_exynos4412;
983 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
984 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
986 if (!_exynos4412_cache_flush(bo_exynos4412->fd, bo_exynos4412, flags))
993 tbm_exynos4412_bo_get_global_key (tbm_bo bo)
995 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
997 tbm_bo_exynos4412 bo_exynos4412;
999 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1000 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1002 if (!bo_exynos4412->name)
1004 if (!bo_exynos4412->gem)
1007 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
1010 return bo_exynos4412->name;
1014 tbm_exynos4412_bo_lock(tbm_bo bo, int device, int opt)
1016 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1018 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1019 tbm_bo_exynos4412 bo_exynos4412;
1020 struct dma_buf_fence fence;
1021 struct flock filelock;
1024 if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU)
1026 DBG ("[libtbm-exynos4412:%d] %s not support device type,\n", getpid(), __FUNCTION__);
1030 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1031 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1033 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
1034 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
1036 memset(&fence, 0, sizeof(struct dma_buf_fence));
1038 /* Check if the given type is valid or not. */
1039 if (opt & TBM_OPTION_WRITE)
1041 if (device == TBM_DEVICE_3D)
1042 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1044 else if (opt & TBM_OPTION_READ)
1046 if (device == TBM_DEVICE_3D)
1047 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1051 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__);
1055 /* Check if the tbm manager supports dma fence or not. */
1056 if (!bufmgr_exynos4412->use_dma_fence)
1058 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1059 "error %s:%d Not support DMA FENCE(%s)\n",
1060 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1065 if (device == TBM_DEVICE_3D)
1067 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1070 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1071 "error %s:%d Can not set GET FENCE(%s)\n",
1072 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1077 if (opt & TBM_OPTION_WRITE)
1078 filelock.l_type = F_WRLCK;
1080 filelock.l_type = F_RDLCK;
1082 filelock.l_whence = SEEK_CUR;
1083 filelock.l_start = 0;
1086 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1092 pthread_mutex_lock(&bo_exynos4412->mutex);
1094 if (device == TBM_DEVICE_3D)
1097 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1099 if (bo_exynos4412->dma_fence[i].ctx == 0)
1101 bo_exynos4412->dma_fence[i].type = fence.type;
1102 bo_exynos4412->dma_fence[i].ctx = fence.ctx;
1107 if (i == DMA_FENCE_LIST_MAX)
1109 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1110 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1111 "error %s:%d fence list is full\n",
1112 getpid(), __FUNCTION__, __LINE__);
1116 pthread_mutex_unlock(&bo_exynos4412->mutex);
1118 DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1119 __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
1125 tbm_exynos4412_bo_unlock(tbm_bo bo)
1127 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1129 tbm_bo_exynos4412 bo_exynos4412;
1130 struct dma_buf_fence fence;
1131 struct flock filelock;
1132 unsigned int dma_type = 0;
1135 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1136 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1138 if (bo_exynos4412->dma_fence[0].type & DMA_BUF_ACCESS_DMA)
1141 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1143 DBG ("[libtbm-exynos4412:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1147 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1149 DBG ("[libtbm-exynos4412:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1153 pthread_mutex_lock(&bo_exynos4412->mutex);
1157 fence.type = bo_exynos4412->dma_fence[0].type;
1158 fence.ctx = bo_exynos4412->dma_fence[0].ctx;
1160 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1162 bo_exynos4412->dma_fence[i-1].type = bo_exynos4412->dma_fence[i].type;
1163 bo_exynos4412->dma_fence[i-1].ctx = bo_exynos4412->dma_fence[i].ctx;
1165 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1166 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1168 pthread_mutex_unlock(&bo_exynos4412->mutex);
1172 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1175 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1176 "error %s:%d Can not set PUT FENCE(%s)\n",
1177 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1182 filelock.l_type = F_UNLCK;
1183 filelock.l_whence = SEEK_CUR;
1184 filelock.l_start = 0;
1187 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1193 DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1194 __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
1200 tbm_exynos4412_bufmgr_deinit (void *priv)
1202 EXYNOS4412_RETURN_IF_FAIL (priv!=NULL);
1204 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1206 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)priv;
1208 if (bufmgr_exynos4412->hashBos)
1213 while (drmHashFirst(bufmgr_exynos4412->hashBos, &key, &value) > 0)
1216 drmHashDelete (bufmgr_exynos4412->hashBos, key);
1219 drmHashDestroy (bufmgr_exynos4412->hashBos);
1220 bufmgr_exynos4412->hashBos = NULL;
1223 free (bufmgr_exynos4412);
1227 tbm_exynos4412_surface_supported_format(uint32_t **formats, uint32_t *num)
1229 uint32_t* color_formats=NULL;
1231 color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1233 if( color_formats == NULL )
1237 memcpy( color_formats, tbm_exynos4412_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1240 *formats = color_formats;
1241 *num = TBM_COLOR_FORMAT_COUNT;
1243 fprintf (stderr, "tbm_exynos4412_surface_supported_format count = %d \n",*num);
1250 * @brief get the plane data of the surface.
1251 * @param[in] surface : the surface
1252 * @param[in] width : the width of the surface
1253 * @param[in] height : the height of the surface
1254 * @param[in] format : the format of the surface
1255 * @param[in] plane_idx : the format of the surface
1256 * @param[out] size : the size of the plane
1257 * @param[out] offset : the offset of the plane
1258 * @param[out] pitch : the pitch of the plane
1259 * @param[out] padding : the padding of the plane
1260 * @return 1 if this function succeeds, otherwise 0.
1263 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)
1275 case TBM_FORMAT_XRGB4444:
1276 case TBM_FORMAT_XBGR4444:
1277 case TBM_FORMAT_RGBX4444:
1278 case TBM_FORMAT_BGRX4444:
1279 case TBM_FORMAT_ARGB4444:
1280 case TBM_FORMAT_ABGR4444:
1281 case TBM_FORMAT_RGBA4444:
1282 case TBM_FORMAT_BGRA4444:
1283 case TBM_FORMAT_XRGB1555:
1284 case TBM_FORMAT_XBGR1555:
1285 case TBM_FORMAT_RGBX5551:
1286 case TBM_FORMAT_BGRX5551:
1287 case TBM_FORMAT_ARGB1555:
1288 case TBM_FORMAT_ABGR1555:
1289 case TBM_FORMAT_RGBA5551:
1290 case TBM_FORMAT_BGRA5551:
1291 case TBM_FORMAT_RGB565:
1294 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1295 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1298 case TBM_FORMAT_RGB888:
1299 case TBM_FORMAT_BGR888:
1302 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1303 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1306 case TBM_FORMAT_XRGB8888:
1307 case TBM_FORMAT_XBGR8888:
1308 case TBM_FORMAT_RGBX8888:
1309 case TBM_FORMAT_BGRX8888:
1310 case TBM_FORMAT_ARGB8888:
1311 case TBM_FORMAT_ABGR8888:
1312 case TBM_FORMAT_RGBA8888:
1313 case TBM_FORMAT_BGRA8888:
1316 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1317 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1321 case TBM_FORMAT_YUYV:
1322 case TBM_FORMAT_YVYU:
1323 case TBM_FORMAT_UYVY:
1324 case TBM_FORMAT_VYUY:
1325 case TBM_FORMAT_AYUV:
1328 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1329 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1334 * index 0 = Y plane, [7:0] Y
1335 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1337 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1339 case TBM_FORMAT_NV12:
1340 case TBM_FORMAT_NV21:
1345 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1346 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1348 else if( plane_idx ==1 )
1350 _offset = width*height;
1351 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1352 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1356 case TBM_FORMAT_NV16:
1357 case TBM_FORMAT_NV61:
1359 //if(plane_idx == 0)
1362 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1363 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1367 //else if( plane_idx ==1 )
1370 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1371 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1377 * index 0: Y plane, [7:0] Y
1378 * index 1: Cb plane, [7:0] Cb
1379 * index 2: Cr plane, [7:0] Cr
1381 * index 1: Cr plane, [7:0] Cr
1382 * index 2: Cb plane, [7:0] Cb
1385 NATIVE_BUFFER_FORMAT_YV12
1386 NATIVE_BUFFER_FORMAT_I420
1388 case TBM_FORMAT_YUV410:
1389 case TBM_FORMAT_YVU410:
1392 case TBM_FORMAT_YUV411:
1393 case TBM_FORMAT_YVU411:
1394 case TBM_FORMAT_YUV420:
1395 case TBM_FORMAT_YVU420:
1397 //if(plane_idx == 0)
1400 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1401 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1405 //else if( plane_idx == 1 )
1408 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1409 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1413 //else if (plane_idx == 2 )
1416 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1417 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1420 case TBM_FORMAT_YUV422:
1421 case TBM_FORMAT_YVU422:
1423 //if(plane_idx == 0)
1426 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1427 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1431 //else if( plane_idx == 1 )
1434 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1435 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1439 //else if (plane_idx == 2 )
1442 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1443 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1446 case TBM_FORMAT_YUV444:
1447 case TBM_FORMAT_YVU444:
1449 //if(plane_idx == 0)
1452 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1453 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1457 //else if( plane_idx == 1 )
1460 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1461 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1465 //else if (plane_idx == 2 )
1468 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1469 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1484 * @brief get the size of the surface with a format.
1485 * @param[in] surface : the surface
1486 * @param[in] width : the width of the surface
1487 * @param[in] height : the height of the surface
1488 * @param[in] format : the format of the surface
1489 * @return size of the surface if this function succeeds, otherwise 0.
1493 tbm_exynos4412_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1499 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1504 case TBM_FORMAT_XRGB4444:
1505 case TBM_FORMAT_XBGR4444:
1506 case TBM_FORMAT_RGBX4444:
1507 case TBM_FORMAT_BGRX4444:
1508 case TBM_FORMAT_ARGB4444:
1509 case TBM_FORMAT_ABGR4444:
1510 case TBM_FORMAT_RGBA4444:
1511 case TBM_FORMAT_BGRA4444:
1512 case TBM_FORMAT_XRGB1555:
1513 case TBM_FORMAT_XBGR1555:
1514 case TBM_FORMAT_RGBX5551:
1515 case TBM_FORMAT_BGRX5551:
1516 case TBM_FORMAT_ARGB1555:
1517 case TBM_FORMAT_ABGR1555:
1518 case TBM_FORMAT_RGBA5551:
1519 case TBM_FORMAT_BGRA5551:
1520 case TBM_FORMAT_RGB565:
1522 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1523 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1526 case TBM_FORMAT_RGB888:
1527 case TBM_FORMAT_BGR888:
1529 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1530 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1533 case TBM_FORMAT_XRGB8888:
1534 case TBM_FORMAT_XBGR8888:
1535 case TBM_FORMAT_RGBX8888:
1536 case TBM_FORMAT_BGRX8888:
1537 case TBM_FORMAT_ARGB8888:
1538 case TBM_FORMAT_ABGR8888:
1539 case TBM_FORMAT_RGBA8888:
1540 case TBM_FORMAT_BGRA8888:
1542 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1543 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1546 case TBM_FORMAT_YUYV:
1547 case TBM_FORMAT_YVYU:
1548 case TBM_FORMAT_UYVY:
1549 case TBM_FORMAT_VYUY:
1550 case TBM_FORMAT_AYUV:
1552 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1553 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1557 * index 0 = Y plane, [7:0] Y
1558 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1560 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1562 case TBM_FORMAT_NV12:
1563 case TBM_FORMAT_NV21:
1567 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1568 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1572 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1573 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1578 case TBM_FORMAT_NV16:
1579 case TBM_FORMAT_NV61:
1583 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1584 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1588 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1589 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1595 * index 0: Y plane, [7:0] Y
1596 * index 1: Cb plane, [7:0] Cb
1597 * index 2: Cr plane, [7:0] Cr
1599 * index 1: Cr plane, [7:0] Cr
1600 * index 2: Cb plane, [7:0] Cb
1602 case TBM_FORMAT_YUV410:
1603 case TBM_FORMAT_YVU410:
1605 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1607 case TBM_FORMAT_YUV411:
1608 case TBM_FORMAT_YVU411:
1609 case TBM_FORMAT_YUV420:
1610 case TBM_FORMAT_YVU420:
1614 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1615 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1619 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1620 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1624 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1625 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1629 case TBM_FORMAT_YUV422:
1630 case TBM_FORMAT_YVU422:
1634 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1635 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1639 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1640 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1644 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1645 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1648 case TBM_FORMAT_YUV444:
1649 case TBM_FORMAT_YVU444:
1651 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1662 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1668 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1670 static TBMModuleVersionInfo Exynos4412VersRec =
1677 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
1680 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1682 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1683 tbm_bufmgr_backend bufmgr_backend;
1688 bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
1689 if (!bufmgr_exynos4412)
1691 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to alloc bufmgr_exynos4412!\n", getpid());
1695 bufmgr_exynos4412->fd = fd;
1696 if (bufmgr_exynos4412->fd < 0)
1698 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
1699 free (bufmgr_exynos4412);
1704 bufmgr_exynos4412->hashBos = drmHashCreate ();
1706 //Check if the tbm manager supports dma fence or not.
1707 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1712 length = read(fp, buf, 1);
1714 if (length == 1 && buf[0] == '1')
1715 bufmgr_exynos4412->use_dma_fence = 1;
1720 bufmgr_backend = tbm_backend_alloc();
1721 if (!bufmgr_backend)
1723 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
1724 free (bufmgr_exynos4412);
1728 bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1729 bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1730 bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1731 bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1732 bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1733 bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1734 bufmgr_backend->bo_import_fd = tbm_exynos4412_bo_import_fd,
1735 bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1736 bufmgr_backend->bo_export_fd = tbm_exynos4412_bo_export_fd,
1737 bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1738 bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1739 bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1740 bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1741 bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1742 bufmgr_backend->surface_get_plane_data = tbm_exynos4412_surface_get_plane_data;
1743 bufmgr_backend->surface_get_size = tbm_exynos4412_surface_get_size;
1744 bufmgr_backend->surface_supported_format = tbm_exynos4412_surface_supported_format;
1746 if (bufmgr_exynos4412->use_dma_fence)
1748 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1749 bufmgr_backend->bo_lock = NULL;
1750 bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1751 bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1755 bufmgr_backend->flags = 0;
1756 bufmgr_backend->bo_lock = NULL;
1757 bufmgr_backend->bo_unlock = NULL;
1760 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1762 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to init backend!\n", getpid());
1763 tbm_backend_free (bufmgr_backend);
1764 free (bufmgr_exynos4412);
1771 env = getenv ("TBM_EXYNOS4412_DEBUG");
1774 bDebug = atoi (env);
1775 TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1784 DBG ("[libtbm-exynos4412:%d] %s DMABUF FENCE is %s\n", getpid(),
1785 __FUNCTION__, bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1787 DBG ("[libtbm-exynos4412:%d] %s fd:%d\n", getpid(),
1788 __FUNCTION__, bufmgr_exynos4412->fd);