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, int *bo_idx)
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);
1284 case TBM_FORMAT_RGB888:
1285 case TBM_FORMAT_BGR888:
1288 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1289 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1293 case TBM_FORMAT_XRGB8888:
1294 case TBM_FORMAT_XBGR8888:
1295 case TBM_FORMAT_RGBX8888:
1296 case TBM_FORMAT_BGRX8888:
1297 case TBM_FORMAT_ARGB8888:
1298 case TBM_FORMAT_ABGR8888:
1299 case TBM_FORMAT_RGBA8888:
1300 case TBM_FORMAT_BGRA8888:
1303 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1304 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1309 case TBM_FORMAT_YUYV:
1310 case TBM_FORMAT_YVYU:
1311 case TBM_FORMAT_UYVY:
1312 case TBM_FORMAT_VYUY:
1313 case TBM_FORMAT_AYUV:
1316 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1317 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1323 * index 0 = Y plane, [7:0] Y
1324 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1326 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1328 case TBM_FORMAT_NV12:
1333 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1334 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1337 else if( plane_idx ==1 )
1340 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1341 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1345 case TBM_FORMAT_NV21:
1350 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1351 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1354 else if( plane_idx ==1 )
1356 _offset = width*height;
1357 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1358 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1363 case TBM_FORMAT_NV16:
1364 case TBM_FORMAT_NV61:
1366 //if(plane_idx == 0)
1369 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1370 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1375 //else if( plane_idx ==1 )
1378 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1379 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1386 * index 0: Y plane, [7:0] Y
1387 * index 1: Cb plane, [7:0] Cb
1388 * index 2: Cr plane, [7:0] Cr
1390 * index 1: Cr plane, [7:0] Cr
1391 * index 2: Cb plane, [7:0] Cb
1394 NATIVE_BUFFER_FORMAT_YV12
1395 NATIVE_BUFFER_FORMAT_I420
1397 case TBM_FORMAT_YUV410:
1398 case TBM_FORMAT_YVU410:
1402 case TBM_FORMAT_YUV411:
1403 case TBM_FORMAT_YVU411:
1404 case TBM_FORMAT_YUV420:
1405 case TBM_FORMAT_YVU420:
1407 //if(plane_idx == 0)
1410 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1411 _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/2),TBM_SURFACE_ALIGNMENT_PLANE);
1425 //else if (plane_idx == 2 )
1428 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1429 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1433 case TBM_FORMAT_YUV422:
1434 case TBM_FORMAT_YVU422:
1436 //if(plane_idx == 0)
1439 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1440 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1445 //else if( plane_idx == 1 )
1448 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1449 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1454 //else if (plane_idx == 2 )
1457 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1458 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1462 case TBM_FORMAT_YUV444:
1463 case TBM_FORMAT_YVU444:
1465 //if(plane_idx == 0)
1468 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1469 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1474 //else if( plane_idx == 1 )
1477 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1478 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1483 //else if (plane_idx == 2 )
1486 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1487 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1505 tbm_exynos4412_surface_get_num_bos(tbm_format format)
1512 case TBM_FORMAT_XRGB4444:
1513 case TBM_FORMAT_XBGR4444:
1514 case TBM_FORMAT_RGBX4444:
1515 case TBM_FORMAT_BGRX4444:
1516 case TBM_FORMAT_ARGB4444:
1517 case TBM_FORMAT_ABGR4444:
1518 case TBM_FORMAT_RGBA4444:
1519 case TBM_FORMAT_BGRA4444:
1520 case TBM_FORMAT_XRGB1555:
1521 case TBM_FORMAT_XBGR1555:
1522 case TBM_FORMAT_RGBX5551:
1523 case TBM_FORMAT_BGRX5551:
1524 case TBM_FORMAT_ARGB1555:
1525 case TBM_FORMAT_ABGR1555:
1526 case TBM_FORMAT_RGBA5551:
1527 case TBM_FORMAT_BGRA5551:
1528 case TBM_FORMAT_RGB565:
1530 case TBM_FORMAT_RGB888:
1531 case TBM_FORMAT_BGR888:
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 case TBM_FORMAT_YUYV:
1543 case TBM_FORMAT_YVYU:
1544 case TBM_FORMAT_UYVY:
1545 case TBM_FORMAT_VYUY:
1546 case TBM_FORMAT_AYUV:
1549 * index 0 = Y plane, [7:0] Y
1550 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1552 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1554 case TBM_FORMAT_NV21:
1555 case TBM_FORMAT_NV16:
1556 case TBM_FORMAT_NV61:
1559 * index 0: Y plane, [7:0] Y
1560 * index 1: Cb plane, [7:0] Cb
1561 * index 2: Cr plane, [7:0] Cr
1563 * index 1: Cr plane, [7:0] Cr
1564 * index 2: Cb plane, [7:0] Cb
1566 case TBM_FORMAT_YUV410:
1567 case TBM_FORMAT_YVU410:
1568 case TBM_FORMAT_YUV411:
1569 case TBM_FORMAT_YVU411:
1570 case TBM_FORMAT_YUV420:
1571 case TBM_FORMAT_YVU420:
1572 case TBM_FORMAT_YUV422:
1573 case TBM_FORMAT_YVU422:
1574 case TBM_FORMAT_YUV444:
1575 case TBM_FORMAT_YVU444:
1579 case TBM_FORMAT_NV12:
1592 * @brief get the size of the surface with a format.
1593 * @param[in] surface : the surface
1594 * @param[in] width : the width of the surface
1595 * @param[in] height : the height of the surface
1596 * @param[in] format : the format of the surface
1597 * @return size of the surface if this function succeeds, otherwise 0.
1601 tbm_exynos4412_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1607 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1612 case TBM_FORMAT_XRGB4444:
1613 case TBM_FORMAT_XBGR4444:
1614 case TBM_FORMAT_RGBX4444:
1615 case TBM_FORMAT_BGRX4444:
1616 case TBM_FORMAT_ARGB4444:
1617 case TBM_FORMAT_ABGR4444:
1618 case TBM_FORMAT_RGBA4444:
1619 case TBM_FORMAT_BGRA4444:
1620 case TBM_FORMAT_XRGB1555:
1621 case TBM_FORMAT_XBGR1555:
1622 case TBM_FORMAT_RGBX5551:
1623 case TBM_FORMAT_BGRX5551:
1624 case TBM_FORMAT_ARGB1555:
1625 case TBM_FORMAT_ABGR1555:
1626 case TBM_FORMAT_RGBA5551:
1627 case TBM_FORMAT_BGRA5551:
1628 case TBM_FORMAT_RGB565:
1630 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1631 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1634 case TBM_FORMAT_RGB888:
1635 case TBM_FORMAT_BGR888:
1637 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1638 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1641 case TBM_FORMAT_XRGB8888:
1642 case TBM_FORMAT_XBGR8888:
1643 case TBM_FORMAT_RGBX8888:
1644 case TBM_FORMAT_BGRX8888:
1645 case TBM_FORMAT_ARGB8888:
1646 case TBM_FORMAT_ABGR8888:
1647 case TBM_FORMAT_RGBA8888:
1648 case TBM_FORMAT_BGRA8888:
1650 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1651 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1654 case TBM_FORMAT_YUYV:
1655 case TBM_FORMAT_YVYU:
1656 case TBM_FORMAT_UYVY:
1657 case TBM_FORMAT_VYUY:
1658 case TBM_FORMAT_AYUV:
1660 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1661 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1665 * index 0 = Y plane, [7:0] Y
1666 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1668 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1670 case TBM_FORMAT_NV12:
1671 case TBM_FORMAT_NV21:
1675 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1676 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1680 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1681 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1686 case TBM_FORMAT_NV16:
1687 case TBM_FORMAT_NV61:
1691 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1692 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1696 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1697 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1703 * index 0: Y plane, [7:0] Y
1704 * index 1: Cb plane, [7:0] Cb
1705 * index 2: Cr plane, [7:0] Cr
1707 * index 1: Cr plane, [7:0] Cr
1708 * index 2: Cb plane, [7:0] Cb
1710 case TBM_FORMAT_YUV410:
1711 case TBM_FORMAT_YVU410:
1713 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1715 case TBM_FORMAT_YUV411:
1716 case TBM_FORMAT_YVU411:
1717 case TBM_FORMAT_YUV420:
1718 case TBM_FORMAT_YVU420:
1722 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1723 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1727 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1728 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1732 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1733 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1737 case TBM_FORMAT_YUV422:
1738 case TBM_FORMAT_YVU422:
1742 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1743 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1747 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1748 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1752 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1753 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1756 case TBM_FORMAT_YUV444:
1757 case TBM_FORMAT_YVU444:
1759 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1770 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1777 tbm_exynos4412_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1779 EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1780 EXYNOS4412_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1782 tbm_bo_handle bo_handle;
1783 memset (&bo_handle, 0x0, sizeof (uint64_t));
1785 tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_priv_from_bufmgr(bufmgr);
1789 case TBM_DEVICE_DEFAULT:
1792 //getting handle from fd
1793 struct drm_prime_handle arg = {0, };
1797 if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1799 TBM_EXYNOS4412_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1800 arg.fd, strerror(errno));
1801 return (tbm_bo_handle) NULL;
1804 bo_handle.u32 = (uint32_t)arg.handle;;
1807 case TBM_DEVICE_CPU:
1808 TBM_EXYNOS4412_LOG ("Not supported device:%d\n", device);
1809 bo_handle.ptr = (void *) NULL;
1813 bo_handle.u32 = (uint32_t)fd;
1816 TBM_EXYNOS4412_LOG ("error Not supported device:%d\n", device);
1817 bo_handle.ptr = (void *) NULL;
1825 tbm_exynos4412_bo_get_flags (tbm_bo bo)
1827 EXYNOS4412_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1829 tbm_bo_exynos4412 bo_exynos4412;
1831 bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1832 EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412 != NULL, 0);
1834 return bo_exynos4412->flags_tbm;
1837 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1839 static TBMModuleVersionInfo Exynos4412VersRec =
1846 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
1849 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1851 tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1852 tbm_bufmgr_backend bufmgr_backend;
1857 bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
1858 if (!bufmgr_exynos4412)
1860 TBM_EXYNOS4412_LOG ("error: Fail to alloc bufmgr_exynos4412!\n");
1864 bufmgr_exynos4412->fd = fd;
1865 if (bufmgr_exynos4412->fd < 0)
1867 TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1868 free (bufmgr_exynos4412);
1873 bufmgr_exynos4412->hashBos = drmHashCreate ();
1875 //Check if the tbm manager supports dma fence or not.
1876 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1881 length = read(fp, buf, 1);
1883 if (length == 1 && buf[0] == '1')
1884 bufmgr_exynos4412->use_dma_fence = 1;
1889 bufmgr_backend = tbm_backend_alloc();
1890 if (!bufmgr_backend)
1892 TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1893 if (bufmgr_exynos4412->hashBos)
1894 drmHashDestroy (bufmgr_exynos4412->hashBos);
1895 free (bufmgr_exynos4412);
1899 bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1900 bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1901 bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1902 bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1903 bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1904 bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1905 bufmgr_backend->bo_import_fd = tbm_exynos4412_bo_import_fd,
1906 bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1907 bufmgr_backend->bo_export_fd = tbm_exynos4412_bo_export_fd,
1908 bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1909 bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1910 bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1911 bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1912 bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1913 bufmgr_backend->surface_get_plane_data = tbm_exynos4412_surface_get_plane_data;
1914 bufmgr_backend->surface_get_size = tbm_exynos4412_surface_get_size;
1915 bufmgr_backend->surface_supported_format = tbm_exynos4412_surface_supported_format;
1916 bufmgr_backend->fd_to_handle = tbm_exynos4412_fd_to_handle;
1917 bufmgr_backend->surface_get_num_bos = tbm_exynos4412_surface_get_num_bos;
1918 bufmgr_backend->bo_get_flags = tbm_exynos4412_bo_get_flags;
1920 if (bufmgr_exynos4412->use_dma_fence)
1922 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1923 bufmgr_backend->bo_lock = NULL;
1924 bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1925 bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1929 bufmgr_backend->flags = 0;
1930 bufmgr_backend->bo_lock = NULL;
1931 bufmgr_backend->bo_unlock = NULL;
1934 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1936 TBM_EXYNOS4412_LOG ("error: Fail to init backend!\n");
1937 tbm_backend_free (bufmgr_backend);
1938 free (bufmgr_exynos4412);
1945 env = getenv ("TBM_EXYNOS4412_DEBUG");
1948 bDebug = atoi (env);
1949 TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1958 DBG ("[%s] DMABUF FENCE is %s\n", target_name(),
1959 bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1961 DBG ("[%s] drm_fd:%d\n", target_name(),
1962 bufmgr_exynos4412->fd);