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(fmt, ##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 ("error fail to get flink from gem:%d (DRM_IOCTL_GEM_FLINK)\n",
278 return (unsigned int)arg.name;
282 _exynos4412_bo_handle (tbm_bo_exynos4412 bo_exynos4412, int device)
284 tbm_bo_handle bo_handle;
285 memset (&bo_handle, 0x0, sizeof (uint64_t));
289 case TBM_DEVICE_DEFAULT:
291 bo_handle.u32 = (uint32_t)bo_exynos4412->gem;
294 if (!bo_exynos4412->pBase)
296 struct drm_mode_map_dumb arg = {0,};
299 arg.handle = bo_exynos4412->gem;
300 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg))
302 TBM_EXYNOS4412_LOG ("error Cannot map_dumb gem=%d\n", bo_exynos4412->gem);
303 return (tbm_bo_handle) NULL;
306 map = mmap (NULL, bo_exynos4412->size, PROT_READ|PROT_WRITE, MAP_SHARED,
307 bo_exynos4412->fd, arg.offset);
308 if (map == MAP_FAILED)
310 TBM_EXYNOS4412_LOG ("error Cannot usrptr gem=%d\n", bo_exynos4412->gem);
311 return (tbm_bo_handle) NULL;
313 bo_exynos4412->pBase = map;
315 bo_handle.ptr = (void *)bo_exynos4412->pBase;
319 if (bo_exynos4412->dmabuf)
321 bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
325 if (!bo_exynos4412->dmabuf)
327 struct drm_prime_handle arg = {0, };
329 arg.handle = bo_exynos4412->gem;
330 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
332 TBM_EXYNOS4412_LOG ("error Cannot dmabuf=%d\n", bo_exynos4412->gem);
333 return (tbm_bo_handle) NULL;
335 bo_exynos4412->dmabuf = arg.fd;
338 bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
342 if (!bo_exynos4412->dmabuf)
344 struct drm_prime_handle arg = {0, };
346 arg.handle = bo_exynos4412->gem;
347 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
349 TBM_EXYNOS4412_LOG ("error Cannot dmabuf=%d\n", 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 ("error Not supported device:%d\n", device);
359 bo_handle.ptr = (void *) NULL;
367 _exynos4412_cache_flush (int fd, tbm_bo_exynos4412 bo_exynos4412, int flags)
369 #ifdef ENABLE_CACHECRTL
370 struct drm_exynos_gem_cache_op cache_op = {0, };
373 /* if bo_exynos4412 is null, do cache_flush_all */
377 cache_op.usr_addr = (uint64_t)((uint32_t)bo_exynos4412->pBase);
378 cache_op.size = bo_exynos4412->size;
382 flags = TBM_CACHE_FLUSH_ALL;
384 cache_op.usr_addr = 0;
388 if (flags & TBM_CACHE_INV)
390 if(flags & TBM_CACHE_ALL)
391 cache_op.flags |= EXYNOS_DRM_CACHE_INV_ALL;
393 cache_op.flags |= EXYNOS_DRM_CACHE_INV_RANGE;
396 if (flags & TBM_CACHE_CLN)
398 if(flags & TBM_CACHE_ALL)
399 cache_op.flags |= EXYNOS_DRM_CACHE_CLN_ALL;
401 cache_op.flags |= EXYNOS_DRM_CACHE_CLN_RANGE;
404 if(flags & TBM_CACHE_ALL)
405 cache_op.flags |= EXYNOS_DRM_ALL_CACHES_CORES;
407 ret = drmCommandWriteRead (fd, DRM_EXYNOS_GEM_CACHE_OP, &cache_op, sizeof(cache_op));
410 TBM_EXYNOS4412_LOG ("error fail to flush the cache.\n");
414 TBM_EXYNOS4412_LOG ("warning fail to enable the cache flush.\n");
420 tbm_exynos4412_bo_size (tbm_bo bo)
422 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
424 tbm_bo_exynos4412 bo_exynos4412;
426 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
428 return bo_exynos4412->size;
432 tbm_exynos4412_bo_alloc (tbm_bo bo, int size, int flags)
434 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
436 tbm_bo_exynos4412 bo_exynos4412;
437 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
438 unsigned int exynos_flags;
440 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
441 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
443 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
446 TBM_EXYNOS4412_LOG ("error fail to allocate the bo private\n");
450 exynos_flags = _get_exynos_flag_from_tbm (flags);
451 if((flags & TBM_BO_SCANOUT) &&
454 exynos_flags |= EXYNOS_BO_NONCONTIG;
457 struct drm_exynos_gem_create arg = {0, };
459 arg.flags = exynos_flags;
460 if (drmCommandWriteRead(bufmgr_exynos4412->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg)))
462 TBM_EXYNOS4412_LOG ("error Cannot create bo(flag:%x, size:%d)\n", arg.flags, (unsigned int)arg.size);
463 free (bo_exynos4412);
467 bo_exynos4412->fd = bufmgr_exynos4412->fd;
468 bo_exynos4412->gem = arg.handle;
469 bo_exynos4412->size = size;
470 bo_exynos4412->flags_tbm = flags;
471 bo_exynos4412->flags_exynos = exynos_flags;
472 bo_exynos4412->name = _get_name (bo_exynos4412->fd, bo_exynos4412->gem);
474 pthread_mutex_init(&bo_exynos4412->mutex, NULL);
476 if (bufmgr_exynos4412->use_dma_fence
477 && !bo_exynos4412->dmabuf)
479 struct drm_prime_handle arg = {0, };
481 arg.handle = bo_exynos4412->gem;
482 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
484 TBM_EXYNOS4412_LOG ("error Cannot dmabuf=%d\n", bo_exynos4412->gem);
485 free (bo_exynos4412);
488 bo_exynos4412->dmabuf = arg.fd;
492 PrivGem* privGem = calloc (1, sizeof(PrivGem));
495 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
496 "error %s:%d Fail to calloc privGem\n",
497 getpid(), __FUNCTION__, __LINE__);
498 free (bo_exynos4412);
502 privGem->ref_count = 1;
503 if (drmHashInsert(bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
505 TBM_EXYNOS4412_LOG ("error Cannot insert bo to Hash(%d)\n", bo_exynos4412->name);
508 DBG (" [%s] bo:%p, gem:%d(%d), flags:%d(%d), size:%d\n", target_name(),
510 bo_exynos4412->gem, bo_exynos4412->name,
512 bo_exynos4412->size);
514 return (void *)bo_exynos4412;
518 tbm_exynos4412_bo_free(tbm_bo bo)
520 tbm_bo_exynos4412 bo_exynos4412;
521 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
526 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
527 EXYNOS4412_RETURN_IF_FAIL (bufmgr_exynos4412!=NULL);
529 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
530 EXYNOS4412_RETURN_IF_FAIL (bo_exynos4412!=NULL);
532 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, size:%d\n",target_name(),
534 bo_exynos4412->gem, bo_exynos4412->name,
535 bo_exynos4412->dmabuf,
536 bo_exynos4412->size);
538 if (bo_exynos4412->pBase)
540 if (munmap(bo_exynos4412->pBase, bo_exynos4412->size) == -1)
542 TBM_EXYNOS4412_LOG ("error bo:%p fail to munmap(%s)\n",
543 bo, strerror(errno));
548 if (bo_exynos4412->dmabuf)
550 close (bo_exynos4412->dmabuf);
551 bo_exynos4412->dmabuf = 0;
554 /* delete bo from hash */
555 PrivGem *privGem = NULL;
558 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
561 privGem->ref_count--;
562 if (privGem->ref_count == 0)
564 drmHashDelete (bufmgr_exynos4412->hashBos, bo_exynos4412->name);
571 TBM_EXYNOS4412_LOG ("warning Cannot find bo to Hash(%d), ret=%d\n", bo_exynos4412->name, ret);
574 /* Free gem handle */
575 struct drm_gem_close arg = {0, };
576 memset (&arg, 0, sizeof(arg));
577 arg.handle = bo_exynos4412->gem;
578 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_GEM_CLOSE, &arg))
580 TBM_EXYNOS4412_LOG ("error bo:%p fail to gem close.(%s)\n",
581 bo, strerror(errno));
584 free (bo_exynos4412);
589 tbm_exynos4412_bo_import (tbm_bo bo, unsigned int key)
591 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
593 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
594 tbm_bo_exynos4412 bo_exynos4412;
596 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
597 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
599 struct drm_gem_open arg = {0, };
600 struct drm_exynos_gem_info info = {0, };
603 if (drmIoctl(bufmgr_exynos4412->fd, DRM_IOCTL_GEM_OPEN, &arg))
605 TBM_EXYNOS4412_LOG ("error Cannot open gem name=%d\n", key);
609 info.handle = arg.handle;
610 if (drmCommandWriteRead(bufmgr_exynos4412->fd,
613 sizeof(struct drm_exynos_gem_info)))
615 TBM_EXYNOS4412_LOG ("error Cannot get gem info=%d\n", key);
619 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
622 TBM_EXYNOS4412_LOG ("error fail to allocate the bo private\n");
626 bo_exynos4412->fd = bufmgr_exynos4412->fd;
627 bo_exynos4412->gem = arg.handle;
628 bo_exynos4412->size = arg.size;
629 bo_exynos4412->flags_exynos = info.flags;
630 bo_exynos4412->name = key;
631 bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
633 if (!bo_exynos4412->dmabuf)
635 struct drm_prime_handle arg = {0, };
637 arg.handle = bo_exynos4412->gem;
638 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
640 TBM_EXYNOS4412_LOG ("error Cannot dmabuf=%d\n", bo_exynos4412->gem);
641 free (bo_exynos4412);
644 bo_exynos4412->dmabuf = arg.fd;
648 PrivGem *privGem = NULL;
651 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
654 privGem->ref_count++;
658 privGem = calloc (1, sizeof(PrivGem));
661 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
662 "error %s:%d Fail to calloc privGem\n",
663 getpid(), __FUNCTION__, __LINE__);
664 free (bo_exynos4412);
668 privGem->ref_count = 1;
669 if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
671 TBM_EXYNOS4412_LOG ("error Cannot insert bo to Hash(%d)\n", bo_exynos4412->name);
676 TBM_EXYNOS4412_LOG ("error Cannot insert bo to Hash(%d)\n", bo_exynos4412->name);
679 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", target_name(),
681 bo_exynos4412->gem, bo_exynos4412->name,
682 bo_exynos4412->dmabuf,
683 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
684 bo_exynos4412->size);
686 return (void *)bo_exynos4412;
690 tbm_exynos4412_bo_import_fd (tbm_bo bo, tbm_fd key)
692 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
694 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
695 tbm_bo_exynos4412 bo_exynos4412;
697 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
698 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
700 unsigned int gem = 0;
701 unsigned int real_size = -1;
702 struct drm_exynos_gem_info info = {0, };
704 //getting handle from fd
705 struct drm_prime_handle arg = {0, };
709 if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
711 TBM_EXYNOS4412_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
712 bo, arg.fd, strerror(errno));
717 /* Determine size of bo. The fd-to-handle ioctl really should
718 * return the size, but it doesn't. If we have kernel 3.12 or
719 * later, we can lseek on the prime fd to get the size. Older
720 * kernels will just fail, in which case we fall back to the
721 * provided (estimated or guess size). */
722 real_size = lseek(key, 0, SEEK_END);
725 if (drmCommandWriteRead(bufmgr_exynos4412->fd,
728 sizeof(struct drm_exynos_gem_info)))
730 TBM_EXYNOS4412_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
731 bo, gem, key, strerror(errno));
736 real_size = info.size;
738 bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
741 TBM_EXYNOS4412_LOG ("error bo:%p fail to allocate the bo private\n", bo);
745 bo_exynos4412->fd = bufmgr_exynos4412->fd;
746 bo_exynos4412->gem = gem;
747 bo_exynos4412->size = real_size;
748 bo_exynos4412->flags_exynos = info.flags;
749 bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
751 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
752 if (!bo_exynos4412->name)
754 TBM_EXYNOS4412_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
755 bo, gem, key, strerror(errno));
756 free (bo_exynos4412);
761 PrivGem *privGem = NULL;
764 ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
767 privGem->ref_count++;
771 privGem = calloc (1, sizeof(PrivGem));
774 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
775 "error %s:%d Fail to calloc privGem\n",
776 getpid(), __FUNCTION__, __LINE__);
777 free (bo_exynos4412);
781 privGem->ref_count = 1;
782 if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
784 TBM_EXYNOS4412_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
785 bo, bo_exynos4412->name, gem, key);
790 TBM_EXYNOS4412_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
791 bo, bo_exynos4412->name, gem, key);
794 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
796 bo_exynos4412->gem, bo_exynos4412->name,
797 bo_exynos4412->dmabuf,
799 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
800 bo_exynos4412->size);
802 return (void *)bo_exynos4412;
806 tbm_exynos4412_bo_export (tbm_bo bo)
808 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
810 tbm_bo_exynos4412 bo_exynos4412;
812 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
813 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
815 if (!bo_exynos4412->name)
817 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
818 if (!bo_exynos4412->name)
820 TBM_EXYNOS4412_LOG ("error Cannot get name\n");
825 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", target_name(),
827 bo_exynos4412->gem, bo_exynos4412->name,
828 bo_exynos4412->dmabuf,
829 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
830 bo_exynos4412->size);
832 return (unsigned int)bo_exynos4412->name;
836 tbm_exynos4412_bo_export_fd (tbm_bo bo)
838 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
840 tbm_bo_exynos4412 bo_exynos4412;
842 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
843 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
845 struct drm_prime_handle arg = {0, };
847 arg.handle = bo_exynos4412->gem;
848 if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
850 TBM_EXYNOS4412_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
851 bo, bo_exynos4412->gem, strerror(errno));
855 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
857 bo_exynos4412->gem, bo_exynos4412->name,
858 bo_exynos4412->dmabuf,
860 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
861 bo_exynos4412->size);
863 return (tbm_fd)arg.fd;
867 tbm_exynos4412_bo_get_handle (tbm_bo bo, int device)
869 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
871 tbm_bo_handle bo_handle;
872 tbm_bo_exynos4412 bo_exynos4412;
874 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
875 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
877 if (!bo_exynos4412->gem)
879 TBM_EXYNOS4412_LOG ("error Cannot map gem=%d\n", bo_exynos4412->gem);
880 return (tbm_bo_handle) NULL;
883 DBG ("[%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d, %s\n", target_name(),
885 bo_exynos4412->gem, bo_exynos4412->name,
886 bo_exynos4412->dmabuf,
887 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
891 /*Get mapped bo_handle*/
892 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
893 if (bo_handle.ptr == NULL)
895 TBM_EXYNOS4412_LOG ("error Cannot get handle: gem:%d, device:%d\n", bo_exynos4412->gem, device);
896 return (tbm_bo_handle) NULL;
903 tbm_exynos4412_bo_map (tbm_bo bo, int device, int opt)
905 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
907 tbm_bo_handle bo_handle;
908 tbm_bo_exynos4412 bo_exynos4412;
910 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
911 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
913 if (!bo_exynos4412->gem)
915 TBM_EXYNOS4412_LOG ("error Cannot map gem=%d\n", bo_exynos4412->gem);
916 return (tbm_bo_handle) NULL;
919 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, %s, %s\n", target_name(),
921 bo_exynos4412->gem, bo_exynos4412->name,
922 bo_exynos4412->dmabuf,
926 /*Get mapped bo_handle*/
927 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
928 if (bo_handle.ptr == NULL)
930 TBM_EXYNOS4412_LOG ("error Cannot get handle: gem:%d, device:%d, opt:%d\n", bo_exynos4412->gem, device, opt);
931 return (tbm_bo_handle) NULL;
938 tbm_exynos4412_bo_unmap (tbm_bo bo)
940 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
942 tbm_bo_exynos4412 bo_exynos4412;
944 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
945 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
947 if (!bo_exynos4412->gem)
950 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d\n", target_name(),
952 bo_exynos4412->gem, bo_exynos4412->name,
953 bo_exynos4412->dmabuf);
959 tbm_exynos4412_bo_cache_flush (tbm_bo bo, int flags)
961 tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
962 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
964 /* cache flush is managed by kernel side when using dma-fence. */
965 if (bufmgr_exynos4412->use_dma_fence)
968 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
970 tbm_bo_exynos4412 bo_exynos4412;
972 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
973 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
975 if (!_exynos4412_cache_flush(bo_exynos4412->fd, bo_exynos4412, flags))
982 tbm_exynos4412_bo_get_global_key (tbm_bo bo)
984 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
986 tbm_bo_exynos4412 bo_exynos4412;
988 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
989 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
991 if (!bo_exynos4412->name)
993 if (!bo_exynos4412->gem)
996 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
999 return bo_exynos4412->name;
1003 tbm_exynos4412_bo_lock(tbm_bo bo, int device, int opt)
1005 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1007 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1008 tbm_bo_exynos4412 bo_exynos4412;
1009 struct dma_buf_fence fence;
1010 struct flock filelock;
1013 if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU)
1015 DBG ("[libtbm-exynos4412:%d] %s not support device type,\n", getpid(), __FUNCTION__);
1019 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1020 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1022 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
1023 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
1025 memset(&fence, 0, sizeof(struct dma_buf_fence));
1027 /* Check if the given type is valid or not. */
1028 if (opt & TBM_OPTION_WRITE)
1030 if (device == TBM_DEVICE_3D)
1031 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1033 else if (opt & TBM_OPTION_READ)
1035 if (device == TBM_DEVICE_3D)
1036 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1040 TBM_EXYNOS4412_LOG ("error Invalid argument\n");
1044 /* Check if the tbm manager supports dma fence or not. */
1045 if (!bufmgr_exynos4412->use_dma_fence)
1047 TBM_EXYNOS4412_LOG ("error Not support DMA FENCE(%s)\n", strerror(errno) );
1052 if (device == TBM_DEVICE_3D)
1054 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1057 TBM_EXYNOS4412_LOG ("error Cannot set GET FENCE(%s)\n", strerror(errno) );
1062 if (opt & TBM_OPTION_WRITE)
1063 filelock.l_type = F_WRLCK;
1065 filelock.l_type = F_RDLCK;
1067 filelock.l_whence = SEEK_CUR;
1068 filelock.l_start = 0;
1071 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1077 pthread_mutex_lock(&bo_exynos4412->mutex);
1079 if (device == TBM_DEVICE_3D)
1082 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1084 if (bo_exynos4412->dma_fence[i].ctx == 0)
1086 bo_exynos4412->dma_fence[i].type = fence.type;
1087 bo_exynos4412->dma_fence[i].ctx = fence.ctx;
1092 if (i == DMA_FENCE_LIST_MAX)
1094 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1095 TBM_EXYNOS4412_LOG ("error fence list is full\n");
1099 pthread_mutex_unlock(&bo_exynos4412->mutex);
1101 DBG ("[%s] DMABUF_IOCTL_GET_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(),
1103 bo_exynos4412->gem, bo_exynos4412->name,
1104 bo_exynos4412->dmabuf);
1110 tbm_exynos4412_bo_unlock(tbm_bo bo)
1112 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1114 tbm_bo_exynos4412 bo_exynos4412;
1115 struct dma_buf_fence fence;
1116 struct flock filelock;
1117 unsigned int dma_type = 0;
1120 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1121 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1123 if (bo_exynos4412->dma_fence[0].type & DMA_BUF_ACCESS_DMA)
1126 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1128 DBG ("[libtbm-exynos4412:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1132 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1134 DBG ("[libtbm-exynos4412:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1138 pthread_mutex_lock(&bo_exynos4412->mutex);
1142 fence.type = bo_exynos4412->dma_fence[0].type;
1143 fence.ctx = bo_exynos4412->dma_fence[0].ctx;
1145 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1147 bo_exynos4412->dma_fence[i-1].type = bo_exynos4412->dma_fence[i].type;
1148 bo_exynos4412->dma_fence[i-1].ctx = bo_exynos4412->dma_fence[i].ctx;
1150 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1151 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1153 pthread_mutex_unlock(&bo_exynos4412->mutex);
1157 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1160 TBM_EXYNOS4412_LOG ("error Can not set PUT FENCE(%s)\n", strerror(errno));
1165 filelock.l_type = F_UNLCK;
1166 filelock.l_whence = SEEK_CUR;
1167 filelock.l_start = 0;
1170 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1176 DBG ("[%s] DMABUF_IOCTL_PUT_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(),
1178 bo_exynos4412->gem, bo_exynos4412->name,
1179 bo_exynos4412->dmabuf);
1185 tbm_exynos4412_bufmgr_deinit (void *priv)
1187 EXYNOS4412_RETURN_IF_FAIL (priv!=NULL);
1189 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1191 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)priv;
1193 if (bufmgr_exynos4412->hashBos)
1198 while (drmHashFirst(bufmgr_exynos4412->hashBos, &key, &value) > 0)
1201 drmHashDelete (bufmgr_exynos4412->hashBos, key);
1204 drmHashDestroy (bufmgr_exynos4412->hashBos);
1205 bufmgr_exynos4412->hashBos = NULL;
1208 free (bufmgr_exynos4412);
1212 tbm_exynos4412_surface_supported_format(uint32_t **formats, uint32_t *num)
1214 uint32_t* color_formats=NULL;
1216 color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1218 if( color_formats == NULL )
1222 memcpy( color_formats, tbm_exynos4412_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1225 *formats = color_formats;
1226 *num = TBM_COLOR_FORMAT_COUNT;
1228 fprintf (stderr, "tbm_exynos4412_surface_supported_format count = %d \n",*num);
1235 * @brief get the plane data of the surface.
1236 * @param[in] surface : the surface
1237 * @param[in] width : the width of the surface
1238 * @param[in] height : the height of the surface
1239 * @param[in] format : the format of the surface
1240 * @param[in] plane_idx : the format of the surface
1241 * @param[out] size : the size of the plane
1242 * @param[out] offset : the offset of the plane
1243 * @param[out] pitch : the pitch of the plane
1244 * @param[out] padding : the padding of the plane
1245 * @return 1 if this function succeeds, otherwise 0.
1248 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)
1260 case TBM_FORMAT_XRGB4444:
1261 case TBM_FORMAT_XBGR4444:
1262 case TBM_FORMAT_RGBX4444:
1263 case TBM_FORMAT_BGRX4444:
1264 case TBM_FORMAT_ARGB4444:
1265 case TBM_FORMAT_ABGR4444:
1266 case TBM_FORMAT_RGBA4444:
1267 case TBM_FORMAT_BGRA4444:
1268 case TBM_FORMAT_XRGB1555:
1269 case TBM_FORMAT_XBGR1555:
1270 case TBM_FORMAT_RGBX5551:
1271 case TBM_FORMAT_BGRX5551:
1272 case TBM_FORMAT_ARGB1555:
1273 case TBM_FORMAT_ABGR1555:
1274 case TBM_FORMAT_RGBA5551:
1275 case TBM_FORMAT_BGRA5551:
1276 case TBM_FORMAT_RGB565:
1279 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1280 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1283 case TBM_FORMAT_RGB888:
1284 case TBM_FORMAT_BGR888:
1287 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1288 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1291 case TBM_FORMAT_XRGB8888:
1292 case TBM_FORMAT_XBGR8888:
1293 case TBM_FORMAT_RGBX8888:
1294 case TBM_FORMAT_BGRX8888:
1295 case TBM_FORMAT_ARGB8888:
1296 case TBM_FORMAT_ABGR8888:
1297 case TBM_FORMAT_RGBA8888:
1298 case TBM_FORMAT_BGRA8888:
1301 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1302 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1306 case TBM_FORMAT_YUYV:
1307 case TBM_FORMAT_YVYU:
1308 case TBM_FORMAT_UYVY:
1309 case TBM_FORMAT_VYUY:
1310 case TBM_FORMAT_AYUV:
1313 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1314 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1319 * index 0 = Y plane, [7:0] Y
1320 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1322 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1324 case TBM_FORMAT_NV12:
1325 case TBM_FORMAT_NV21:
1330 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1331 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1333 else if( plane_idx ==1 )
1335 _offset = width*height;
1336 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1337 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1341 case TBM_FORMAT_NV16:
1342 case TBM_FORMAT_NV61:
1344 //if(plane_idx == 0)
1347 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1348 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1352 //else if( plane_idx ==1 )
1355 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1356 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1362 * index 0: Y plane, [7:0] Y
1363 * index 1: Cb plane, [7:0] Cb
1364 * index 2: Cr plane, [7:0] Cr
1366 * index 1: Cr plane, [7:0] Cr
1367 * index 2: Cb plane, [7:0] Cb
1370 NATIVE_BUFFER_FORMAT_YV12
1371 NATIVE_BUFFER_FORMAT_I420
1373 case TBM_FORMAT_YUV410:
1374 case TBM_FORMAT_YVU410:
1377 case TBM_FORMAT_YUV411:
1378 case TBM_FORMAT_YVU411:
1379 case TBM_FORMAT_YUV420:
1380 case TBM_FORMAT_YVU420:
1382 //if(plane_idx == 0)
1385 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1386 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1390 //else if( plane_idx == 1 )
1393 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1394 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1398 //else if (plane_idx == 2 )
1401 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1402 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1405 case TBM_FORMAT_YUV422:
1406 case TBM_FORMAT_YVU422:
1408 //if(plane_idx == 0)
1411 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1412 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1416 //else if( plane_idx == 1 )
1419 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1420 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1424 //else if (plane_idx == 2 )
1427 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1428 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1431 case TBM_FORMAT_YUV444:
1432 case TBM_FORMAT_YVU444:
1434 //if(plane_idx == 0)
1437 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1438 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1442 //else if( plane_idx == 1 )
1445 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1446 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1450 //else if (plane_idx == 2 )
1453 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1454 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1469 * @brief get the size of the surface with a format.
1470 * @param[in] surface : the surface
1471 * @param[in] width : the width of the surface
1472 * @param[in] height : the height of the surface
1473 * @param[in] format : the format of the surface
1474 * @return size of the surface if this function succeeds, otherwise 0.
1478 tbm_exynos4412_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1484 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1489 case TBM_FORMAT_XRGB4444:
1490 case TBM_FORMAT_XBGR4444:
1491 case TBM_FORMAT_RGBX4444:
1492 case TBM_FORMAT_BGRX4444:
1493 case TBM_FORMAT_ARGB4444:
1494 case TBM_FORMAT_ABGR4444:
1495 case TBM_FORMAT_RGBA4444:
1496 case TBM_FORMAT_BGRA4444:
1497 case TBM_FORMAT_XRGB1555:
1498 case TBM_FORMAT_XBGR1555:
1499 case TBM_FORMAT_RGBX5551:
1500 case TBM_FORMAT_BGRX5551:
1501 case TBM_FORMAT_ARGB1555:
1502 case TBM_FORMAT_ABGR1555:
1503 case TBM_FORMAT_RGBA5551:
1504 case TBM_FORMAT_BGRA5551:
1505 case TBM_FORMAT_RGB565:
1507 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1508 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1511 case TBM_FORMAT_RGB888:
1512 case TBM_FORMAT_BGR888:
1514 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1515 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1518 case TBM_FORMAT_XRGB8888:
1519 case TBM_FORMAT_XBGR8888:
1520 case TBM_FORMAT_RGBX8888:
1521 case TBM_FORMAT_BGRX8888:
1522 case TBM_FORMAT_ARGB8888:
1523 case TBM_FORMAT_ABGR8888:
1524 case TBM_FORMAT_RGBA8888:
1525 case TBM_FORMAT_BGRA8888:
1527 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1528 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1531 case TBM_FORMAT_YUYV:
1532 case TBM_FORMAT_YVYU:
1533 case TBM_FORMAT_UYVY:
1534 case TBM_FORMAT_VYUY:
1535 case TBM_FORMAT_AYUV:
1537 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1538 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1542 * index 0 = Y plane, [7:0] Y
1543 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1545 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1547 case TBM_FORMAT_NV12:
1548 case TBM_FORMAT_NV21:
1552 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1553 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1557 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1558 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1563 case TBM_FORMAT_NV16:
1564 case TBM_FORMAT_NV61:
1568 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1569 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1573 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1574 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1580 * index 0: Y plane, [7:0] Y
1581 * index 1: Cb plane, [7:0] Cb
1582 * index 2: Cr plane, [7:0] Cr
1584 * index 1: Cr plane, [7:0] Cr
1585 * index 2: Cb plane, [7:0] Cb
1587 case TBM_FORMAT_YUV410:
1588 case TBM_FORMAT_YVU410:
1590 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1592 case TBM_FORMAT_YUV411:
1593 case TBM_FORMAT_YVU411:
1594 case TBM_FORMAT_YUV420:
1595 case TBM_FORMAT_YVU420:
1599 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1600 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1604 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1605 _size += SIZE_ALIGN(_pitch*(height/2),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 case TBM_FORMAT_YUV422:
1615 case TBM_FORMAT_YVU422:
1619 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1620 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1624 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
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);
1633 case TBM_FORMAT_YUV444:
1634 case TBM_FORMAT_YVU444:
1636 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1647 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1654 tbm_exynos4412_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1656 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1657 EXYNOS4412_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1659 tbm_bo_handle bo_handle;
1660 memset (&bo_handle, 0x0, sizeof (uint64_t));
1662 tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_priv_from_bufmgr(bufmgr);
1666 case TBM_DEVICE_DEFAULT:
1669 //getting handle from fd
1670 struct drm_prime_handle arg = {0, };
1674 if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1676 TBM_EXYNOS4412_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1677 arg.fd, strerror(errno));
1678 return (tbm_bo_handle) NULL;
1681 bo_handle.u32 = (uint32_t)arg.handle;;
1684 case TBM_DEVICE_CPU:
1685 TBM_EXYNOS4412_LOG ("Not supported device:%d\n", device);
1686 bo_handle.ptr = (void *) NULL;
1690 bo_handle.u32 = (uint32_t)fd;
1693 TBM_EXYNOS4412_LOG ("error Not supported device:%d\n", device);
1694 bo_handle.ptr = (void *) NULL;
1702 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1704 static TBMModuleVersionInfo Exynos4412VersRec =
1711 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
1714 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1716 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1717 tbm_bufmgr_backend bufmgr_backend;
1722 bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
1723 if (!bufmgr_exynos4412)
1725 TBM_EXYNOS4412_LOG ("error: Fail to alloc bufmgr_exynos4412!\n");
1729 bufmgr_exynos4412->fd = fd;
1730 if (bufmgr_exynos4412->fd < 0)
1732 TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1733 free (bufmgr_exynos4412);
1738 bufmgr_exynos4412->hashBos = drmHashCreate ();
1740 //Check if the tbm manager supports dma fence or not.
1741 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1746 length = read(fp, buf, 1);
1748 if (length == 1 && buf[0] == '1')
1749 bufmgr_exynos4412->use_dma_fence = 1;
1754 bufmgr_backend = tbm_backend_alloc();
1755 if (!bufmgr_backend)
1757 TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1758 if (bufmgr_exynos4412->hashBos)
1759 drmHashDestroy (bufmgr_exynos4412->hashBos);
1760 free (bufmgr_exynos4412);
1764 bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1765 bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1766 bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1767 bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1768 bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1769 bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1770 bufmgr_backend->bo_import_fd = tbm_exynos4412_bo_import_fd,
1771 bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1772 bufmgr_backend->bo_export_fd = tbm_exynos4412_bo_export_fd,
1773 bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1774 bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1775 bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1776 bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1777 bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1778 bufmgr_backend->surface_get_plane_data = tbm_exynos4412_surface_get_plane_data;
1779 bufmgr_backend->surface_get_size = tbm_exynos4412_surface_get_size;
1780 bufmgr_backend->surface_supported_format = tbm_exynos4412_surface_supported_format;
1781 bufmgr_backend->fd_to_handle = tbm_exynos4412_fd_to_handle;
1783 if (bufmgr_exynos4412->use_dma_fence)
1785 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1786 bufmgr_backend->bo_lock = NULL;
1787 bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1788 bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1792 bufmgr_backend->flags = 0;
1793 bufmgr_backend->bo_lock = NULL;
1794 bufmgr_backend->bo_unlock = NULL;
1797 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1799 TBM_EXYNOS4412_LOG ("error: Fail to init backend!\n");
1800 tbm_backend_free (bufmgr_backend);
1801 free (bufmgr_exynos4412);
1808 env = getenv ("TBM_EXYNOS4412_DEBUG");
1811 bDebug = atoi (env);
1812 TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1821 DBG ("[%s] DMABUF FENCE is %s\n", target_name(),
1822 bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1824 DBG ("[%s] drm_fd:%d\n", target_name(),
1825 bufmgr_exynos4412->fd);