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_exynos_gem_map arg = {0,};
299 arg.handle = bo_exynos4412->gem;
300 if (drmCommandWriteRead (bo_exynos4412->fd, DRM_EXYNOS_GEM_MAP, &arg, sizeof(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, -1);
840 tbm_bo_exynos4412 bo_exynos4412;
843 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
844 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, -1);
846 struct drm_prime_handle arg = {0, };
848 arg.handle = bo_exynos4412->gem;
849 ret = drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
852 TBM_EXYNOS4412_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
853 bo, bo_exynos4412->gem, strerror(errno));
857 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
859 bo_exynos4412->gem, bo_exynos4412->name,
860 bo_exynos4412->dmabuf,
862 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
863 bo_exynos4412->size);
865 return (tbm_fd)arg.fd;
869 tbm_exynos4412_bo_get_handle (tbm_bo bo, int device)
871 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
873 tbm_bo_handle bo_handle;
874 tbm_bo_exynos4412 bo_exynos4412;
876 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
877 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
879 if (!bo_exynos4412->gem)
881 TBM_EXYNOS4412_LOG ("error Cannot map gem=%d\n", bo_exynos4412->gem);
882 return (tbm_bo_handle) NULL;
885 DBG ("[%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d, %s\n", target_name(),
887 bo_exynos4412->gem, bo_exynos4412->name,
888 bo_exynos4412->dmabuf,
889 bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
893 /*Get mapped bo_handle*/
894 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
895 if (bo_handle.ptr == NULL)
897 TBM_EXYNOS4412_LOG ("error Cannot get handle: gem:%d, device:%d\n", bo_exynos4412->gem, device);
898 return (tbm_bo_handle) NULL;
905 tbm_exynos4412_bo_map (tbm_bo bo, int device, int opt)
907 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
909 tbm_bo_handle bo_handle;
910 tbm_bo_exynos4412 bo_exynos4412;
912 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
913 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
915 if (!bo_exynos4412->gem)
917 TBM_EXYNOS4412_LOG ("error Cannot map gem=%d\n", bo_exynos4412->gem);
918 return (tbm_bo_handle) NULL;
921 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, %s, %s\n", target_name(),
923 bo_exynos4412->gem, bo_exynos4412->name,
924 bo_exynos4412->dmabuf,
928 /*Get mapped bo_handle*/
929 bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
930 if (bo_handle.ptr == NULL)
932 TBM_EXYNOS4412_LOG ("error Cannot get handle: gem:%d, device:%d, opt:%d\n", bo_exynos4412->gem, device, opt);
933 return (tbm_bo_handle) NULL;
940 tbm_exynos4412_bo_unmap (tbm_bo bo)
942 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
944 tbm_bo_exynos4412 bo_exynos4412;
946 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
947 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
949 if (!bo_exynos4412->gem)
952 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d\n", target_name(),
954 bo_exynos4412->gem, bo_exynos4412->name,
955 bo_exynos4412->dmabuf);
961 tbm_exynos4412_bo_cache_flush (tbm_bo bo, int flags)
963 tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
964 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
966 /* cache flush is managed by kernel side when using dma-fence. */
967 if (bufmgr_exynos4412->use_dma_fence)
970 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
972 tbm_bo_exynos4412 bo_exynos4412;
974 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
975 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
977 if (!_exynos4412_cache_flush(bo_exynos4412->fd, bo_exynos4412, flags))
984 tbm_exynos4412_bo_get_global_key (tbm_bo bo)
986 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
988 tbm_bo_exynos4412 bo_exynos4412;
990 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
991 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
993 if (!bo_exynos4412->name)
995 if (!bo_exynos4412->gem)
998 bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
1001 return bo_exynos4412->name;
1005 tbm_exynos4412_bo_lock(tbm_bo bo, int device, int opt)
1007 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1009 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1010 tbm_bo_exynos4412 bo_exynos4412;
1011 struct dma_buf_fence fence;
1012 struct flock filelock;
1015 if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU)
1017 DBG ("[libtbm-exynos4412:%d] %s not support device type,\n", getpid(), __FUNCTION__);
1021 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1022 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1024 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
1025 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
1027 memset(&fence, 0, sizeof(struct dma_buf_fence));
1029 /* Check if the given type is valid or not. */
1030 if (opt & TBM_OPTION_WRITE)
1032 if (device == TBM_DEVICE_3D)
1033 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1035 else if (opt & TBM_OPTION_READ)
1037 if (device == TBM_DEVICE_3D)
1038 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1042 TBM_EXYNOS4412_LOG ("error Invalid argument\n");
1046 /* Check if the tbm manager supports dma fence or not. */
1047 if (!bufmgr_exynos4412->use_dma_fence)
1049 TBM_EXYNOS4412_LOG ("error Not support DMA FENCE(%s)\n", strerror(errno) );
1054 if (device == TBM_DEVICE_3D)
1056 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1059 TBM_EXYNOS4412_LOG ("error Cannot set GET FENCE(%s)\n", strerror(errno) );
1064 if (opt & TBM_OPTION_WRITE)
1065 filelock.l_type = F_WRLCK;
1067 filelock.l_type = F_RDLCK;
1069 filelock.l_whence = SEEK_CUR;
1070 filelock.l_start = 0;
1073 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1079 pthread_mutex_lock(&bo_exynos4412->mutex);
1081 if (device == TBM_DEVICE_3D)
1084 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1086 if (bo_exynos4412->dma_fence[i].ctx == 0)
1088 bo_exynos4412->dma_fence[i].type = fence.type;
1089 bo_exynos4412->dma_fence[i].ctx = fence.ctx;
1094 if (i == DMA_FENCE_LIST_MAX)
1096 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1097 TBM_EXYNOS4412_LOG ("error fence list is full\n");
1101 pthread_mutex_unlock(&bo_exynos4412->mutex);
1103 DBG ("[%s] DMABUF_IOCTL_GET_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(),
1105 bo_exynos4412->gem, bo_exynos4412->name,
1106 bo_exynos4412->dmabuf);
1112 tbm_exynos4412_bo_unlock(tbm_bo bo)
1114 EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1116 tbm_bo_exynos4412 bo_exynos4412;
1117 struct dma_buf_fence fence;
1118 struct flock filelock;
1119 unsigned int dma_type = 0;
1122 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1123 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1125 if (bo_exynos4412->dma_fence[0].type & DMA_BUF_ACCESS_DMA)
1128 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1130 DBG ("[libtbm-exynos4412:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1134 if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1136 DBG ("[libtbm-exynos4412:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1140 pthread_mutex_lock(&bo_exynos4412->mutex);
1144 fence.type = bo_exynos4412->dma_fence[0].type;
1145 fence.ctx = bo_exynos4412->dma_fence[0].ctx;
1147 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1149 bo_exynos4412->dma_fence[i-1].type = bo_exynos4412->dma_fence[i].type;
1150 bo_exynos4412->dma_fence[i-1].ctx = bo_exynos4412->dma_fence[i].ctx;
1152 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1153 bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1155 pthread_mutex_unlock(&bo_exynos4412->mutex);
1159 ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1162 TBM_EXYNOS4412_LOG ("error Can not set PUT FENCE(%s)\n", strerror(errno));
1167 filelock.l_type = F_UNLCK;
1168 filelock.l_whence = SEEK_CUR;
1169 filelock.l_start = 0;
1172 if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1178 DBG ("[%s] DMABUF_IOCTL_PUT_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(),
1180 bo_exynos4412->gem, bo_exynos4412->name,
1181 bo_exynos4412->dmabuf);
1187 tbm_exynos4412_bufmgr_deinit (void *priv)
1189 EXYNOS4412_RETURN_IF_FAIL (priv!=NULL);
1191 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1193 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)priv;
1195 if (bufmgr_exynos4412->hashBos)
1200 while (drmHashFirst(bufmgr_exynos4412->hashBos, &key, &value) > 0)
1203 drmHashDelete (bufmgr_exynos4412->hashBos, key);
1206 drmHashDestroy (bufmgr_exynos4412->hashBos);
1207 bufmgr_exynos4412->hashBos = NULL;
1210 free (bufmgr_exynos4412);
1214 tbm_exynos4412_surface_supported_format(uint32_t **formats, uint32_t *num)
1216 uint32_t* color_formats=NULL;
1218 color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1220 if( color_formats == NULL )
1224 memcpy( color_formats, tbm_exynos4412_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1227 *formats = color_formats;
1228 *num = TBM_COLOR_FORMAT_COUNT;
1230 fprintf (stderr, "tbm_exynos4412_surface_supported_format count = %d \n",*num);
1237 * @brief get the plane data of the surface.
1238 * @param[in] surface : the surface
1239 * @param[in] width : the width of the surface
1240 * @param[in] height : the height of the surface
1241 * @param[in] format : the format of the surface
1242 * @param[in] plane_idx : the format of the surface
1243 * @param[out] size : the size of the plane
1244 * @param[out] offset : the offset of the plane
1245 * @param[out] pitch : the pitch of the plane
1246 * @param[out] padding : the padding of the plane
1247 * @return 1 if this function succeeds, otherwise 0.
1250 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, int *bo_idx)
1262 case TBM_FORMAT_XRGB4444:
1263 case TBM_FORMAT_XBGR4444:
1264 case TBM_FORMAT_RGBX4444:
1265 case TBM_FORMAT_BGRX4444:
1266 case TBM_FORMAT_ARGB4444:
1267 case TBM_FORMAT_ABGR4444:
1268 case TBM_FORMAT_RGBA4444:
1269 case TBM_FORMAT_BGRA4444:
1270 case TBM_FORMAT_XRGB1555:
1271 case TBM_FORMAT_XBGR1555:
1272 case TBM_FORMAT_RGBX5551:
1273 case TBM_FORMAT_BGRX5551:
1274 case TBM_FORMAT_ARGB1555:
1275 case TBM_FORMAT_ABGR1555:
1276 case TBM_FORMAT_RGBA5551:
1277 case TBM_FORMAT_BGRA5551:
1278 case TBM_FORMAT_RGB565:
1281 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1282 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1286 case TBM_FORMAT_RGB888:
1287 case TBM_FORMAT_BGR888:
1290 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1291 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1295 case TBM_FORMAT_XRGB8888:
1296 case TBM_FORMAT_XBGR8888:
1297 case TBM_FORMAT_RGBX8888:
1298 case TBM_FORMAT_BGRX8888:
1299 case TBM_FORMAT_ARGB8888:
1300 case TBM_FORMAT_ABGR8888:
1301 case TBM_FORMAT_RGBA8888:
1302 case TBM_FORMAT_BGRA8888:
1305 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1306 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1311 case TBM_FORMAT_YUYV:
1312 case TBM_FORMAT_YVYU:
1313 case TBM_FORMAT_UYVY:
1314 case TBM_FORMAT_VYUY:
1315 case TBM_FORMAT_AYUV:
1318 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1319 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1325 * index 0 = Y plane, [7:0] Y
1326 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1328 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1330 case TBM_FORMAT_NV12:
1335 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1336 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1339 else if( plane_idx ==1 )
1342 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1343 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1347 case TBM_FORMAT_NV21:
1352 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1353 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1356 else if( plane_idx ==1 )
1358 _offset = width*height;
1359 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1360 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1365 case TBM_FORMAT_NV16:
1366 case TBM_FORMAT_NV61:
1368 //if(plane_idx == 0)
1371 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1372 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1377 //else if( plane_idx ==1 )
1380 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1381 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1388 * index 0: Y plane, [7:0] Y
1389 * index 1: Cb plane, [7:0] Cb
1390 * index 2: Cr plane, [7:0] Cr
1392 * index 1: Cr plane, [7:0] Cr
1393 * index 2: Cb plane, [7:0] Cb
1396 NATIVE_BUFFER_FORMAT_YV12
1397 NATIVE_BUFFER_FORMAT_I420
1399 case TBM_FORMAT_YUV410:
1400 case TBM_FORMAT_YVU410:
1404 case TBM_FORMAT_YUV411:
1405 case TBM_FORMAT_YVU411:
1406 case TBM_FORMAT_YUV420:
1407 case TBM_FORMAT_YVU420:
1409 //if(plane_idx == 0)
1412 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1413 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1418 //else if( plane_idx == 1 )
1421 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1422 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1427 //else if (plane_idx == 2 )
1430 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1431 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1435 case TBM_FORMAT_YUV422:
1436 case TBM_FORMAT_YVU422:
1438 //if(plane_idx == 0)
1441 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1442 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1447 //else if( plane_idx == 1 )
1450 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1451 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1456 //else if (plane_idx == 2 )
1459 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1460 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1464 case TBM_FORMAT_YUV444:
1465 case TBM_FORMAT_YVU444:
1467 //if(plane_idx == 0)
1470 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1471 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1476 //else if( plane_idx == 1 )
1479 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1480 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1485 //else if (plane_idx == 2 )
1488 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1489 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1507 tbm_exynos4412_surface_get_num_bos(tbm_format format)
1514 case TBM_FORMAT_XRGB4444:
1515 case TBM_FORMAT_XBGR4444:
1516 case TBM_FORMAT_RGBX4444:
1517 case TBM_FORMAT_BGRX4444:
1518 case TBM_FORMAT_ARGB4444:
1519 case TBM_FORMAT_ABGR4444:
1520 case TBM_FORMAT_RGBA4444:
1521 case TBM_FORMAT_BGRA4444:
1522 case TBM_FORMAT_XRGB1555:
1523 case TBM_FORMAT_XBGR1555:
1524 case TBM_FORMAT_RGBX5551:
1525 case TBM_FORMAT_BGRX5551:
1526 case TBM_FORMAT_ARGB1555:
1527 case TBM_FORMAT_ABGR1555:
1528 case TBM_FORMAT_RGBA5551:
1529 case TBM_FORMAT_BGRA5551:
1530 case TBM_FORMAT_RGB565:
1532 case TBM_FORMAT_RGB888:
1533 case TBM_FORMAT_BGR888:
1535 case TBM_FORMAT_XRGB8888:
1536 case TBM_FORMAT_XBGR8888:
1537 case TBM_FORMAT_RGBX8888:
1538 case TBM_FORMAT_BGRX8888:
1539 case TBM_FORMAT_ARGB8888:
1540 case TBM_FORMAT_ABGR8888:
1541 case TBM_FORMAT_RGBA8888:
1542 case TBM_FORMAT_BGRA8888:
1544 case TBM_FORMAT_YUYV:
1545 case TBM_FORMAT_YVYU:
1546 case TBM_FORMAT_UYVY:
1547 case TBM_FORMAT_VYUY:
1548 case TBM_FORMAT_AYUV:
1551 * index 0 = Y plane, [7:0] Y
1552 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1554 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1556 case TBM_FORMAT_NV21:
1557 case TBM_FORMAT_NV16:
1558 case TBM_FORMAT_NV61:
1561 * index 0: Y plane, [7:0] Y
1562 * index 1: Cb plane, [7:0] Cb
1563 * index 2: Cr plane, [7:0] Cr
1565 * index 1: Cr plane, [7:0] Cr
1566 * index 2: Cb plane, [7:0] Cb
1568 case TBM_FORMAT_YUV410:
1569 case TBM_FORMAT_YVU410:
1570 case TBM_FORMAT_YUV411:
1571 case TBM_FORMAT_YVU411:
1572 case TBM_FORMAT_YUV420:
1573 case TBM_FORMAT_YVU420:
1574 case TBM_FORMAT_YUV422:
1575 case TBM_FORMAT_YVU422:
1576 case TBM_FORMAT_YUV444:
1577 case TBM_FORMAT_YVU444:
1581 case TBM_FORMAT_NV12:
1594 * @brief get the size of the surface with a format.
1595 * @param[in] surface : the surface
1596 * @param[in] width : the width of the surface
1597 * @param[in] height : the height of the surface
1598 * @param[in] format : the format of the surface
1599 * @return size of the surface if this function succeeds, otherwise 0.
1603 tbm_exynos4412_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1609 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1614 case TBM_FORMAT_XRGB4444:
1615 case TBM_FORMAT_XBGR4444:
1616 case TBM_FORMAT_RGBX4444:
1617 case TBM_FORMAT_BGRX4444:
1618 case TBM_FORMAT_ARGB4444:
1619 case TBM_FORMAT_ABGR4444:
1620 case TBM_FORMAT_RGBA4444:
1621 case TBM_FORMAT_BGRA4444:
1622 case TBM_FORMAT_XRGB1555:
1623 case TBM_FORMAT_XBGR1555:
1624 case TBM_FORMAT_RGBX5551:
1625 case TBM_FORMAT_BGRX5551:
1626 case TBM_FORMAT_ARGB1555:
1627 case TBM_FORMAT_ABGR1555:
1628 case TBM_FORMAT_RGBA5551:
1629 case TBM_FORMAT_BGRA5551:
1630 case TBM_FORMAT_RGB565:
1632 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1633 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1636 case TBM_FORMAT_RGB888:
1637 case TBM_FORMAT_BGR888:
1639 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1640 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1643 case TBM_FORMAT_XRGB8888:
1644 case TBM_FORMAT_XBGR8888:
1645 case TBM_FORMAT_RGBX8888:
1646 case TBM_FORMAT_BGRX8888:
1647 case TBM_FORMAT_ARGB8888:
1648 case TBM_FORMAT_ABGR8888:
1649 case TBM_FORMAT_RGBA8888:
1650 case TBM_FORMAT_BGRA8888:
1652 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1653 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1656 case TBM_FORMAT_YUYV:
1657 case TBM_FORMAT_YVYU:
1658 case TBM_FORMAT_UYVY:
1659 case TBM_FORMAT_VYUY:
1660 case TBM_FORMAT_AYUV:
1662 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1663 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1667 * index 0 = Y plane, [7:0] Y
1668 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1670 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1672 case TBM_FORMAT_NV12:
1673 case TBM_FORMAT_NV21:
1677 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1678 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1682 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1683 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1688 case TBM_FORMAT_NV16:
1689 case TBM_FORMAT_NV61:
1693 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1694 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1698 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1699 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1705 * index 0: Y plane, [7:0] Y
1706 * index 1: Cb plane, [7:0] Cb
1707 * index 2: Cr plane, [7:0] Cr
1709 * index 1: Cr plane, [7:0] Cr
1710 * index 2: Cb plane, [7:0] Cb
1712 case TBM_FORMAT_YUV410:
1713 case TBM_FORMAT_YVU410:
1715 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1717 case TBM_FORMAT_YUV411:
1718 case TBM_FORMAT_YVU411:
1719 case TBM_FORMAT_YUV420:
1720 case TBM_FORMAT_YVU420:
1724 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1725 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1729 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1730 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1734 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1735 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1739 case TBM_FORMAT_YUV422:
1740 case TBM_FORMAT_YVU422:
1744 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1745 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1749 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1750 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1754 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1755 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1758 case TBM_FORMAT_YUV444:
1759 case TBM_FORMAT_YVU444:
1761 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1772 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1779 tbm_exynos4412_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1781 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1782 EXYNOS4412_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1784 tbm_bo_handle bo_handle;
1785 memset (&bo_handle, 0x0, sizeof (uint64_t));
1787 tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_priv_from_bufmgr(bufmgr);
1791 case TBM_DEVICE_DEFAULT:
1794 //getting handle from fd
1795 struct drm_prime_handle arg = {0, };
1799 if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1801 TBM_EXYNOS4412_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1802 arg.fd, strerror(errno));
1803 return (tbm_bo_handle) NULL;
1806 bo_handle.u32 = (uint32_t)arg.handle;;
1809 case TBM_DEVICE_CPU:
1810 TBM_EXYNOS4412_LOG ("Not supported device:%d\n", device);
1811 bo_handle.ptr = (void *) NULL;
1815 bo_handle.u32 = (uint32_t)fd;
1818 TBM_EXYNOS4412_LOG ("error Not supported device:%d\n", device);
1819 bo_handle.ptr = (void *) NULL;
1827 tbm_exynos4412_bo_get_flags (tbm_bo bo)
1829 EXYNOS4412_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1831 tbm_bo_exynos4412 bo_exynos4412;
1833 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1834 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412 != NULL, 0);
1836 return bo_exynos4412->flags_tbm;
1839 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1841 static TBMModuleVersionInfo Exynos4412VersRec =
1848 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
1851 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1853 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1854 tbm_bufmgr_backend bufmgr_backend;
1859 bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
1860 if (!bufmgr_exynos4412)
1862 TBM_EXYNOS4412_LOG ("error: Fail to alloc bufmgr_exynos4412!\n");
1866 bufmgr_exynos4412->fd = fd;
1867 if (bufmgr_exynos4412->fd < 0)
1869 TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1870 free (bufmgr_exynos4412);
1875 bufmgr_exynos4412->hashBos = drmHashCreate ();
1877 //Check if the tbm manager supports dma fence or not.
1878 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1883 length = read(fp, buf, 1);
1885 if (length == 1 && buf[0] == '1')
1886 bufmgr_exynos4412->use_dma_fence = 1;
1891 bufmgr_backend = tbm_backend_alloc();
1892 if (!bufmgr_backend)
1894 TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1895 if (bufmgr_exynos4412->hashBos)
1896 drmHashDestroy (bufmgr_exynos4412->hashBos);
1897 free (bufmgr_exynos4412);
1901 bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1902 bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1903 bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1904 bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1905 bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1906 bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1907 bufmgr_backend->bo_import_fd = tbm_exynos4412_bo_import_fd,
1908 bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1909 bufmgr_backend->bo_export_fd = tbm_exynos4412_bo_export_fd,
1910 bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1911 bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1912 bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1913 bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1914 bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1915 bufmgr_backend->surface_get_plane_data = tbm_exynos4412_surface_get_plane_data;
1916 bufmgr_backend->surface_get_size = tbm_exynos4412_surface_get_size;
1917 bufmgr_backend->surface_supported_format = tbm_exynos4412_surface_supported_format;
1918 bufmgr_backend->fd_to_handle = tbm_exynos4412_fd_to_handle;
1919 bufmgr_backend->surface_get_num_bos = tbm_exynos4412_surface_get_num_bos;
1920 bufmgr_backend->bo_get_flags = tbm_exynos4412_bo_get_flags;
1922 if (bufmgr_exynos4412->use_dma_fence)
1924 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1925 bufmgr_backend->bo_lock = NULL;
1926 bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1927 bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1931 bufmgr_backend->flags = 0;
1932 bufmgr_backend->bo_lock = NULL;
1933 bufmgr_backend->bo_unlock = NULL;
1936 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1938 TBM_EXYNOS4412_LOG ("error: Fail to init backend!\n");
1939 tbm_backend_free (bufmgr_backend);
1940 free (bufmgr_exynos4412);
1947 env = getenv ("TBM_EXYNOS4412_DEBUG");
1950 bDebug = atoi (env);
1951 TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1960 DBG ("[%s] DMABUF FENCE is %s\n", target_name(),
1961 bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1963 DBG ("[%s] drm_fd:%d\n", target_name(),
1964 bufmgr_exynos4412->fd);