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 <drm/sprd_drm.h>
51 #include <tbm_surface.h>
52 #include "tbm_wayland.h"
56 //#define USE_CONTIG_ONLY
59 #define TBM_COLOR_FORMAT_COUNT 8
64 #define LOG_TAG "TBM_BACKEND"
72 static int initialized = 0;
73 static char app_name[128];
78 /* get the application name */
79 f = fopen("/proc/self/cmdline", "r");
86 memset(app_name, 0x00, sizeof(app_name));
88 if ( fgets(app_name, 100, f) == NULL )
96 if ( (slash=strrchr(app_name, '/')) != NULL )
98 memmove(app_name, slash+1, strlen(slash));
105 #define TBM_SPRD_LOG(fmt, args...) LOGE("\033[31m" "[%s]" fmt "\033[0m", target_name(), ##args)
106 #define DBG(fmt, args...) if(bDebug&01) LOGE("[%s]" fmt, target_name(), ##args)
108 #define TBM_SPRD_LOG(...)
112 #define SIZE_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
114 #define TBM_SURFACE_ALIGNMENT_PLANE (64)
115 #define TBM_SURFACE_ALIGNMENT_PITCH_RGB (128)
116 #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16)
119 /* check condition */
120 #define SPRD_RETURN_IF_FAIL(cond) {\
122 TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
126 #define SPRD_RETURN_VAL_IF_FAIL(cond, val) {\
128 TBM_SPRD_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
133 struct dma_buf_info {
135 unsigned int fence_supported;
136 unsigned int padding;
139 #define DMA_BUF_ACCESS_READ 0x1
140 #define DMA_BUF_ACCESS_WRITE 0x2
141 #define DMA_BUF_ACCESS_DMA 0x4
142 #define DMA_BUF_ACCESS_MAX 0x8
144 #define DMA_FENCE_LIST_MAX 5
146 struct dma_buf_fence {
151 #define DMABUF_IOCTL_BASE 'F'
152 #define DMABUF_IOWR(nr, type) _IOWR(DMABUF_IOCTL_BASE, nr, type)
154 #define DMABUF_IOCTL_GET_INFO DMABUF_IOWR(0x00, struct dma_buf_info)
155 #define DMABUF_IOCTL_GET_FENCE DMABUF_IOWR(0x01, struct dma_buf_fence)
156 #define DMABUF_IOCTL_PUT_FENCE DMABUF_IOWR(0x02, struct dma_buf_fence)
158 typedef struct _tbm_bufmgr_sprd *tbm_bufmgr_sprd;
159 typedef struct _tbm_bo_sprd *tbm_bo_sprd;
161 typedef struct _sprd_private
166 /* tbm buffor object for sprd */
171 unsigned int name; /* FLINK ID */
173 unsigned int gem; /* GEM Handle */
175 unsigned int dmabuf; /* fd for dmabuf */
177 void *pBase; /* virtual address */
181 unsigned int flags_sprd;
182 unsigned int flags_tbm;
186 pthread_mutex_t mutex;
187 struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
192 /* tbm bufmgr private for sprd */
193 struct _tbm_bufmgr_sprd
221 uint32_t tbm_sprd_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888,
231 #ifndef USE_CONTIG_ONLY
233 _get_sprd_flag_from_tbm (unsigned int ftbm)
235 unsigned int flags = 0;
238 * TBM_BO_DEFAULT => ION_HEAP_ID_MASK_SYSTEM
239 * TBM_BO_SCANOUT => ION_HEAP_ID_MASK_MM
240 * TBM_BO_VENDOR => ION_HEAP_ID_MASK_OVERLAY
241 * To be updated appropriately once DRM-GEM supports different heap id masks.
244 if (ftbm & TBM_BO_SCANOUT)
246 flags = SPRD_BO_CONTIG;
250 flags = SPRD_BO_NONCONTIG | SPRD_BO_DEV_SYSTEM;
253 if (ftbm & TBM_BO_WC)
255 else if (ftbm & TBM_BO_NONCACHABLE)
256 flags |= SPRD_BO_NONCACHABLE;
262 _get_tbm_flag_from_sprd (unsigned int fsprd)
264 unsigned int flags = 0;
266 if (fsprd & SPRD_BO_NONCONTIG)
267 flags |= TBM_BO_DEFAULT;
269 flags |= TBM_BO_SCANOUT;
271 if (fsprd & SPRD_BO_WC)
273 else if (fsprd & SPRD_BO_CACHABLE)
274 flags |= TBM_BO_DEFAULT;
276 flags |= TBM_BO_NONCACHABLE;
283 _get_name (int fd, unsigned int gem)
285 struct drm_gem_flink arg = {0,};
288 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg))
290 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
291 "error %s:%d fail to get flink gem=%d\n",
292 getpid(), __FUNCTION__, __LINE__, gem);
296 return (unsigned int)arg.name;
300 _sprd_bo_handle (tbm_bo_sprd bo_sprd, int device)
302 tbm_bo_handle bo_handle;
303 memset (&bo_handle, 0x0, sizeof (uint64_t));
307 case TBM_DEVICE_DEFAULT:
309 bo_handle.u32 = (uint32_t)bo_sprd->gem;
314 struct drm_sprd_gem_mmap arg = {0,};
316 arg.handle = bo_sprd->gem;
317 arg.size = bo_sprd->size;
318 if (drmCommandWriteRead (bo_sprd->fd, DRM_SPRD_GEM_MMAP, &arg, sizeof(arg)))
320 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
321 "error %s:%d Cannot usrptr gem=%d\n",
322 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
323 return (tbm_bo_handle) NULL;
325 bo_sprd->pBase = (void*)((uint32_t)arg.mapped);
328 bo_handle.ptr = (void *)bo_sprd->pBase;
332 if (!bo_sprd->dmabuf)
334 struct drm_prime_handle arg = {0, };
335 arg.handle = bo_sprd->gem;
336 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
338 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
339 "error %s:%d Cannot dmabuf=%d\n",
340 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
341 return (tbm_bo_handle) NULL;
343 bo_sprd->dmabuf = arg.fd;
346 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
353 //TODO : Add ioctl for GSP MAP once available.
354 DBG ("[libtbm-sprd:%d] %s In case TBM_DEVICE_MM: \n", getpid(),
358 if (!bo_sprd->dmabuf)
360 struct drm_prime_handle arg = {0, };
362 arg.handle = bo_sprd->gem;
363 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
365 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
366 "error %s:%d Cannot dmabuf=%d\n",
367 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
368 return (tbm_bo_handle) NULL;
370 bo_sprd->dmabuf = arg.fd;
373 bo_handle.u32 = (uint32_t)bo_sprd->dmabuf;
377 bo_handle.ptr = (void *) NULL;
386 _sprd_cache_flush (int fd, tbm_bo_sprd bo_sprd, int flags)
388 struct drm_sprd_gem_cache_op cache_op = {0, };
391 /* if bo_sprd is null, do cache_flush_all */
395 cache_op.usr_addr = (uint64_t)((uint32_t)bo_sprd->pBase);
396 cache_op.size = bo_sprd->size;
400 flags = TBM_CACHE_FLUSH_ALL;
402 cache_op.usr_addr = 0;
406 if (flags & TBM_CACHE_INV)
408 if(flags & TBM_CACHE_ALL)
409 cache_op.flags |= SPRD_DRM_CACHE_INV_ALL;
411 cache_op.flags |= SPRD_DRM_CACHE_INV_RANGE;
414 if (flags & TBM_CACHE_CLN)
416 if(flags & TBM_CACHE_ALL)
417 cache_op.flags |= SPRD_DRM_CACHE_CLN_ALL;
419 cache_op.flags |= SPRD_DRM_CACHE_CLN_RANGE;
422 if(flags & TBM_CACHE_ALL)
423 cache_op.flags |= SPRD_DRM_ALL_CACHES_CORES;
425 ret = drmCommandWriteRead (fd, DRM_SPRD_GEM_CACHE_OP, &cache_op, sizeof(cache_op));
428 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
429 "error %s:%d fail to flush the cache.\n",
430 getpid(), __FUNCTION__, __LINE__);
439 tbm_sprd_bo_size (tbm_bo bo)
441 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
445 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
447 return bo_sprd->size;
451 tbm_sprd_bo_alloc (tbm_bo bo, int size, int flags)
453 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
456 tbm_bufmgr_sprd bufmgr_sprd;
457 unsigned int sprd_flags;
459 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
460 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
462 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
465 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
466 "error %s:%d fail to allocate the bo private\n",
467 getpid(), __FUNCTION__, __LINE__);
471 #ifdef USE_CONTIG_ONLY
472 flags = TBM_BO_SCANOUT;
473 sprd_flags = SPRD_BO_CONTIG;
475 sprd_flags = _get_sprd_flag_from_tbm (flags);
476 if((flags & TBM_BO_SCANOUT) &&
479 sprd_flags |= SPRD_BO_NONCONTIG;
481 #endif // USE_CONTIG_ONLY
482 struct drm_sprd_gem_create arg = {0, };
484 arg.flags = sprd_flags;
485 if (drmCommandWriteRead(bufmgr_sprd->fd, DRM_SPRD_GEM_CREATE, &arg, sizeof(arg)))
487 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
488 "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
489 getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
494 bo_sprd->fd = bufmgr_sprd->fd;
495 bo_sprd->gem = arg.handle;
496 bo_sprd->size = size;
497 bo_sprd->flags_tbm = flags;
498 bo_sprd->flags_sprd = sprd_flags;
499 bo_sprd->name = _get_name (bo_sprd->fd, bo_sprd->gem);
501 pthread_mutex_init(&bo_sprd->mutex, NULL);
503 if (bufmgr_sprd->use_dma_fence
506 struct drm_prime_handle arg = {0, };
508 arg.handle = bo_sprd->gem;
509 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
511 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
512 "error %s:%d Cannot dmabuf=%d\n",
513 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
517 bo_sprd->dmabuf = arg.fd;
521 PrivGem* privGem = calloc (1, sizeof(PrivGem));
522 privGem->ref_count = 1;
523 if (drmHashInsert(bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
525 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
526 "error %s:%d Cannot insert bo to Hash(%d)\n",
527 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
530 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
531 __FUNCTION__, bo_sprd->size,
532 bo_sprd->gem, bo_sprd->name,
535 return (void *)bo_sprd;
539 tbm_sprd_bo_free(tbm_bo bo)
542 tbm_bufmgr_sprd bufmgr_sprd;
547 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
548 SPRD_RETURN_IF_FAIL (bufmgr_sprd!=NULL);
550 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
551 SPRD_RETURN_IF_FAIL (bo_sprd!=NULL);
553 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d)\n",
554 getpid(), __FUNCTION__, bo_sprd->size, bo_sprd->gem, bo_sprd->name);
558 if (munmap(bo_sprd->pBase, bo_sprd->size) == -1)
560 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
562 getpid(), __FUNCTION__, __LINE__);
569 close (bo_sprd->dmabuf);
573 /* delete bo from hash */
574 PrivGem *privGem = NULL;
577 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
580 privGem->ref_count--;
581 if (privGem->ref_count == 0)
583 drmHashDelete (bufmgr_sprd->hashBos, bo_sprd->name);
590 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
591 "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
592 getpid(), __FUNCTION__, __LINE__, bo_sprd->name, ret);
595 /* Free gem handle */
596 struct drm_gem_close arg = {0, };
597 memset (&arg, 0, sizeof(arg));
598 arg.handle = bo_sprd->gem;
599 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_GEM_CLOSE, &arg))
601 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
603 getpid(), __FUNCTION__, __LINE__);
611 tbm_sprd_bo_import (tbm_bo bo, unsigned int key)
613 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
615 tbm_bufmgr_sprd bufmgr_sprd;
618 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
619 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
621 struct drm_gem_open arg = {0, };
622 struct drm_sprd_gem_info info = {0, };
625 if (drmIoctl(bufmgr_sprd->fd, DRM_IOCTL_GEM_OPEN, &arg))
627 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
628 "error %s:%d Cannot open gem name=%d\n",
629 getpid(), __FUNCTION__, __LINE__, key);
633 info.handle = arg.handle;
634 if (drmCommandWriteRead(bufmgr_sprd->fd,
637 sizeof(struct drm_sprd_gem_info)))
639 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
640 "error %s:%d Cannot get gem info=%d\n",
641 getpid(), __FUNCTION__, __LINE__, key);
645 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
648 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
649 "error %s:%d fail to allocate the bo private\n",
650 getpid(), __FUNCTION__, __LINE__);
654 bo_sprd->fd = bufmgr_sprd->fd;
655 bo_sprd->gem = arg.handle;
656 bo_sprd->size = arg.size;
657 bo_sprd->flags_sprd = info.flags;
659 #ifdef USE_CONTIG_ONLY
660 bo_sprd->flags_sprd = SPRD_BO_CONTIG;
661 bo_sprd->flags_tbm |= TBM_BO_SCANOUT;
663 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
667 if (!bo_sprd->dmabuf)
669 struct drm_prime_handle arg = {0, };
671 arg.handle = bo_sprd->gem;
672 if (drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
674 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
675 "error %s:%d Cannot dmabuf=%d\n",
676 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
680 bo_sprd->dmabuf = arg.fd;
684 PrivGem *privGem = NULL;
687 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
690 privGem->ref_count++;
694 privGem = calloc (1, sizeof(PrivGem));
695 privGem->ref_count = 1;
696 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
698 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
699 "error %s:%d Cannot insert bo to Hash(%d)\n",
700 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
705 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
706 "error %s:%d Cannot insert bo to Hash(%d)\n",
707 getpid(), __FUNCTION__, __LINE__, bo_sprd->name);
710 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
711 __FUNCTION__, bo_sprd->size,
712 bo_sprd->gem, bo_sprd->name,
713 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
715 return (void *)bo_sprd;
719 tbm_sprd_bo_import_fd (tbm_bo bo, tbm_fd key)
721 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
723 tbm_bufmgr_sprd bufmgr_sprd;
726 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
727 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
729 unsigned int gem = 0;
730 unsigned int real_size = -1;
731 struct drm_sprd_gem_info info = {0, };
733 //getting handle from fd
734 struct drm_prime_handle arg = {0, };
738 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
740 TBM_SPRD_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
741 bo, arg.fd, strerror(errno));
746 /* Determine size of bo. The fd-to-handle ioctl really should
747 * return the size, but it doesn't. If we have kernel 3.12 or
748 * later, we can lseek on the prime fd to get the size. Older
749 * kernels will just fail, in which case we fall back to the
750 * provided (estimated or guess size). */
751 real_size = lseek(key, 0, SEEK_END);
754 if (drmCommandWriteRead(bufmgr_sprd->fd,
757 sizeof(struct drm_sprd_gem_info)))
759 TBM_SPRD_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
760 bo, gem, key, strerror(errno));
765 real_size = info.size;
767 bo_sprd = calloc (1, sizeof(struct _tbm_bo_sprd));
770 TBM_SPRD_LOG ("error bo:%p fail to allocate the bo private\n", bo);
774 bo_sprd->fd = bufmgr_sprd->fd;
776 bo_sprd->size = real_size;
777 bo_sprd->flags_sprd = info.flags;
778 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
780 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
783 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
784 bo, gem, key, strerror(errno));
790 PrivGem *privGem = NULL;
793 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
796 privGem->ref_count++;
800 privGem = calloc (1, sizeof(PrivGem));
803 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
804 "error %s:%d Fail to calloc privGem\n",
805 getpid(), __FUNCTION__, __LINE__);
810 privGem->ref_count = 1;
811 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
813 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
814 bo, bo_sprd->name, gem, key);
819 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
820 bo, bo_sprd->name, gem, key);
823 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
825 bo_sprd->gem, bo_sprd->name,
828 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
831 return (void *)bo_sprd;
835 tbm_sprd_bo_export (tbm_bo bo)
837 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
841 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
842 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
846 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
849 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
850 "error %s:%d Cannot get name\n",
851 getpid(), __FUNCTION__, __LINE__);
856 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
857 __FUNCTION__, bo_sprd->size,
858 bo_sprd->gem, bo_sprd->name,
859 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
861 return (unsigned int)bo_sprd->name;
865 tbm_sprd_bo_export_fd (tbm_bo bo)
867 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, -1);
872 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
873 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, -1);
875 struct drm_prime_handle arg = {0, };
877 arg.handle = bo_sprd->gem;
878 ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
881 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
882 bo, bo_sprd->gem, strerror(errno));
886 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
888 bo_sprd->gem, bo_sprd->name,
891 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
894 return (tbm_fd)arg.fd;
899 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
901 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
903 tbm_bo_handle bo_handle;
906 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
907 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL);
911 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
912 "error %s:%d Cannot map gem=%d\n",
913 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
914 return (tbm_bo_handle) NULL;
917 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
918 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
920 /*Get mapped bo_handle*/
921 bo_handle = _sprd_bo_handle (bo_sprd, device);
922 if (bo_handle.ptr == NULL)
924 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
925 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
926 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
927 return (tbm_bo_handle) NULL;
934 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
936 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
938 tbm_bo_handle bo_handle;
941 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
942 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL);
946 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
947 "error %s:%d Cannot map gem=%d\n",
948 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
949 return (tbm_bo_handle) NULL;
952 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
953 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
955 /*Get mapped bo_handle*/
956 bo_handle = _sprd_bo_handle (bo_sprd, device);
957 if (bo_handle.ptr == NULL)
959 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
960 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
961 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
962 return (tbm_bo_handle) NULL;
969 tbm_sprd_bo_unmap (tbm_bo bo)
971 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
975 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
976 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
981 DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
982 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
988 tbm_sprd_bo_cache_flush (tbm_bo bo, int flags)
990 tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
991 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
993 /* cache flush is managed by kernel side when using dma-fence. */
994 if (bufmgr_sprd->use_dma_fence)
997 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1001 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1002 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1005 if (!_sprd_cache_flush(bo_sprd->fd, bo_sprd, flags))
1013 tbm_sprd_bo_get_global_key (tbm_bo bo)
1015 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1017 tbm_bo_sprd bo_sprd;
1019 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1020 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1027 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1030 return bo_sprd->name;
1034 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1036 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1038 #if USE_BACKEND_LOCK
1039 tbm_bufmgr_sprd bufmgr_sprd;
1040 tbm_bo_sprd bo_sprd;
1041 struct dma_buf_fence fence;
1044 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1045 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1047 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1048 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
1050 memset(&fence, 0, sizeof(struct dma_buf_fence));
1052 /* Check if the given type is valid or not. */
1053 if (opt & TBM_OPTION_WRITE)
1055 if (device == TBM_DEVICE_CPU)
1056 fence.type = DMA_BUF_ACCESS_WRITE;
1057 else if (device == TBM_DEVICE_3D)
1058 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1061 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
1065 else if (opt & TBM_OPTION_READ)
1067 if (device == TBM_DEVICE_CPU)
1068 fence.type = DMA_BUF_ACCESS_READ;
1069 else if (device == TBM_DEVICE_3D)
1070 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1073 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
1079 TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__);
1083 /* Check if the tbm manager supports dma fence or not. */
1084 if (!bufmgr_sprd->use_dma_fence)
1086 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1087 "error %s:%d Not support DMA FENCE(%s)\n",
1088 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1093 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1096 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1097 "error %s:%d Can not set GET FENCE(%s)\n",
1098 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1102 pthread_mutex_lock(&bo_sprd->mutex);
1104 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1106 if (bo_sprd->dma_fence[i].ctx == 0)
1108 bo_sprd->dma_fence[i].type = fence.type;
1109 bo_sprd->dma_fence[i].ctx = fence.ctx;
1113 if (i == DMA_FENCE_LIST_MAX)
1115 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1116 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1117 "error %s:%d fence list is full\n",
1118 getpid(), __FUNCTION__, __LINE__);
1120 pthread_mutex_unlock(&bo_sprd->mutex);
1122 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1123 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1130 tbm_sprd_bo_unlock(tbm_bo bo)
1132 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1134 #if USE_BACKEND_LOCK
1135 tbm_bo_sprd bo_sprd;
1136 struct dma_buf_fence fence;
1139 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1140 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1142 if (!bo_sprd->dma_fence[0].ctx)
1144 DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1148 if (!bo_sprd->dma_fence[0].type)
1150 DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1154 pthread_mutex_lock(&bo_sprd->mutex);
1155 fence.type = bo_sprd->dma_fence[0].type;
1156 fence.ctx = bo_sprd->dma_fence[0].ctx;
1158 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1160 bo_sprd->dma_fence[i-1].type = bo_sprd->dma_fence[i].type;
1161 bo_sprd->dma_fence[i-1].ctx = bo_sprd->dma_fence[i].ctx;
1163 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1164 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1165 pthread_mutex_unlock(&bo_sprd->mutex);
1167 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1170 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1171 "error %s:%d Can not set PUT FENCE(%s)\n",
1172 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1176 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1177 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1184 tbm_sprd_bufmgr_deinit (void *priv)
1186 SPRD_RETURN_IF_FAIL (priv!=NULL);
1188 tbm_bufmgr_sprd bufmgr_sprd;
1190 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1192 if (bufmgr_sprd->hashBos)
1197 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0)
1200 drmHashDelete (bufmgr_sprd->hashBos, key);
1203 drmHashDestroy (bufmgr_sprd->hashBos);
1204 bufmgr_sprd->hashBos = NULL;
1207 if (bufmgr_sprd->fd_owner)
1208 close (bufmgr_sprd->fd_owner);
1214 tbm_sprd_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_sprd_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1227 *formats = color_formats;
1228 *num = TBM_COLOR_FORMAT_COUNT;
1236 * @brief get the plane data of the surface.
1237 * @param[in] surface : the surface
1238 * @param[in] width : the width of the surface
1239 * @param[in] height : the height of the surface
1240 * @param[in] format : the format of the surface
1241 * @param[in] plane_idx : the format of the surface
1242 * @param[out] size : the size of the plane
1243 * @param[out] offset : the offset of the plane
1244 * @param[out] pitch : the pitch of the plane
1245 * @param[out] padding : the padding of the plane
1246 * @return 1 if this function succeeds, otherwise 0.
1249 tbm_sprd_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)
1261 case TBM_FORMAT_XRGB4444:
1262 case TBM_FORMAT_XBGR4444:
1263 case TBM_FORMAT_RGBX4444:
1264 case TBM_FORMAT_BGRX4444:
1265 case TBM_FORMAT_ARGB4444:
1266 case TBM_FORMAT_ABGR4444:
1267 case TBM_FORMAT_RGBA4444:
1268 case TBM_FORMAT_BGRA4444:
1269 case TBM_FORMAT_XRGB1555:
1270 case TBM_FORMAT_XBGR1555:
1271 case TBM_FORMAT_RGBX5551:
1272 case TBM_FORMAT_BGRX5551:
1273 case TBM_FORMAT_ARGB1555:
1274 case TBM_FORMAT_ABGR1555:
1275 case TBM_FORMAT_RGBA5551:
1276 case TBM_FORMAT_BGRA5551:
1277 case TBM_FORMAT_RGB565:
1280 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1281 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1285 case TBM_FORMAT_RGB888:
1286 case TBM_FORMAT_BGR888:
1289 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1290 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1294 case TBM_FORMAT_XRGB8888:
1295 case TBM_FORMAT_XBGR8888:
1296 case TBM_FORMAT_RGBX8888:
1297 case TBM_FORMAT_BGRX8888:
1298 case TBM_FORMAT_ARGB8888:
1299 case TBM_FORMAT_ABGR8888:
1300 case TBM_FORMAT_RGBA8888:
1301 case TBM_FORMAT_BGRA8888:
1304 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1305 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1310 case TBM_FORMAT_YUYV:
1311 case TBM_FORMAT_YVYU:
1312 case TBM_FORMAT_UYVY:
1313 case TBM_FORMAT_VYUY:
1314 case TBM_FORMAT_AYUV:
1317 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1318 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1324 * index 0 = Y plane, [7:0] Y
1325 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1327 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1329 case TBM_FORMAT_NV12:
1330 case TBM_FORMAT_NV21:
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 )
1341 _offset = width*height;
1342 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1343 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1348 case TBM_FORMAT_NV16:
1349 case TBM_FORMAT_NV61:
1351 //if(plane_idx == 0)
1354 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1355 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1360 //else if( plane_idx ==1 )
1363 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1364 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1371 * index 0: Y plane, [7:0] Y
1372 * index 1: Cb plane, [7:0] Cb
1373 * index 2: Cr plane, [7:0] Cr
1375 * index 1: Cr plane, [7:0] Cr
1376 * index 2: Cb plane, [7:0] Cb
1379 NATIVE_BUFFER_FORMAT_YV12
1380 NATIVE_BUFFER_FORMAT_I420
1382 case TBM_FORMAT_YUV410:
1383 case TBM_FORMAT_YVU410:
1386 case TBM_FORMAT_YUV411:
1387 case TBM_FORMAT_YVU411:
1388 case TBM_FORMAT_YUV420:
1389 case TBM_FORMAT_YVU420:
1391 //if(plane_idx == 0)
1394 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1395 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1400 //else if( plane_idx == 1 )
1403 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1404 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1409 //else if (plane_idx == 2 )
1412 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1413 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1417 case TBM_FORMAT_YUV422:
1418 case TBM_FORMAT_YVU422:
1420 //if(plane_idx == 0)
1423 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1424 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1429 //else if( plane_idx == 1 )
1432 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1433 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1438 //else if (plane_idx == 2 )
1441 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1442 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1446 case TBM_FORMAT_YUV444:
1447 case TBM_FORMAT_YVU444:
1449 //if(plane_idx == 0)
1452 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1453 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1458 //else if( plane_idx == 1 )
1461 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1462 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1467 //else if (plane_idx == 2 )
1470 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1471 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1488 * @brief get the size of the surface with a format.
1489 * @param[in] surface : the surface
1490 * @param[in] width : the width of the surface
1491 * @param[in] height : the height of the surface
1492 * @param[in] format : the format of the surface
1493 * @return size of the surface if this function succeeds, otherwise 0.
1497 tbm_sprd_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1503 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1509 case TBM_FORMAT_XRGB4444:
1510 case TBM_FORMAT_XBGR4444:
1511 case TBM_FORMAT_RGBX4444:
1512 case TBM_FORMAT_BGRX4444:
1513 case TBM_FORMAT_ARGB4444:
1514 case TBM_FORMAT_ABGR4444:
1515 case TBM_FORMAT_RGBA4444:
1516 case TBM_FORMAT_BGRA4444:
1517 case TBM_FORMAT_XRGB1555:
1518 case TBM_FORMAT_XBGR1555:
1519 case TBM_FORMAT_RGBX5551:
1520 case TBM_FORMAT_BGRX5551:
1521 case TBM_FORMAT_ARGB1555:
1522 case TBM_FORMAT_ABGR1555:
1523 case TBM_FORMAT_RGBA5551:
1524 case TBM_FORMAT_BGRA5551:
1525 case TBM_FORMAT_RGB565:
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_RGB888:
1532 case TBM_FORMAT_BGR888:
1534 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1535 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1538 case TBM_FORMAT_XRGB8888:
1539 case TBM_FORMAT_XBGR8888:
1540 case TBM_FORMAT_RGBX8888:
1541 case TBM_FORMAT_BGRX8888:
1542 case TBM_FORMAT_ARGB8888:
1543 case TBM_FORMAT_ABGR8888:
1544 case TBM_FORMAT_RGBA8888:
1545 case TBM_FORMAT_BGRA8888:
1547 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1548 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1551 case TBM_FORMAT_YUYV:
1552 case TBM_FORMAT_YVYU:
1553 case TBM_FORMAT_UYVY:
1554 case TBM_FORMAT_VYUY:
1555 case TBM_FORMAT_AYUV:
1557 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1558 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1562 * index 0 = Y plane, [7:0] Y
1563 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1565 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1567 case TBM_FORMAT_NV12:
1568 case TBM_FORMAT_NV21:
1572 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1573 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1577 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1578 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1581 case TBM_FORMAT_NV16:
1582 case TBM_FORMAT_NV61:
1586 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1587 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1591 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1592 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1598 * index 0: Y plane, [7:0] Y
1599 * index 1: Cb plane, [7:0] Cb
1600 * index 2: Cr plane, [7:0] Cr
1602 * index 1: Cr plane, [7:0] Cr
1603 * index 2: Cb plane, [7:0] Cb
1605 case TBM_FORMAT_YUV410:
1606 case TBM_FORMAT_YVU410:
1608 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1610 case TBM_FORMAT_YUV411:
1611 case TBM_FORMAT_YVU411:
1612 case TBM_FORMAT_YUV420:
1613 case TBM_FORMAT_YVU420:
1617 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1618 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1622 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1623 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1627 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1628 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1632 case TBM_FORMAT_YUV422:
1633 case TBM_FORMAT_YVU422:
1637 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1638 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1642 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1643 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1647 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1648 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1651 case TBM_FORMAT_YUV444:
1652 case TBM_FORMAT_YVU444:
1654 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1665 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1672 tbm_sprd_surface_get_num_bos(tbm_format format)
1679 case TBM_FORMAT_XRGB4444:
1680 case TBM_FORMAT_XBGR4444:
1681 case TBM_FORMAT_RGBX4444:
1682 case TBM_FORMAT_BGRX4444:
1683 case TBM_FORMAT_ARGB4444:
1684 case TBM_FORMAT_ABGR4444:
1685 case TBM_FORMAT_RGBA4444:
1686 case TBM_FORMAT_BGRA4444:
1687 case TBM_FORMAT_XRGB1555:
1688 case TBM_FORMAT_XBGR1555:
1689 case TBM_FORMAT_RGBX5551:
1690 case TBM_FORMAT_BGRX5551:
1691 case TBM_FORMAT_ARGB1555:
1692 case TBM_FORMAT_ABGR1555:
1693 case TBM_FORMAT_RGBA5551:
1694 case TBM_FORMAT_BGRA5551:
1695 case TBM_FORMAT_RGB565:
1697 case TBM_FORMAT_RGB888:
1698 case TBM_FORMAT_BGR888:
1700 case TBM_FORMAT_XRGB8888:
1701 case TBM_FORMAT_XBGR8888:
1702 case TBM_FORMAT_RGBX8888:
1703 case TBM_FORMAT_BGRX8888:
1704 case TBM_FORMAT_ARGB8888:
1705 case TBM_FORMAT_ABGR8888:
1706 case TBM_FORMAT_RGBA8888:
1707 case TBM_FORMAT_BGRA8888:
1709 case TBM_FORMAT_YUYV:
1710 case TBM_FORMAT_YVYU:
1711 case TBM_FORMAT_UYVY:
1712 case TBM_FORMAT_VYUY:
1713 case TBM_FORMAT_AYUV:
1716 * index 0 = Y plane, [7:0] Y
1717 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1719 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1721 case TBM_FORMAT_NV12:
1722 case TBM_FORMAT_NV21:
1723 case TBM_FORMAT_NV16:
1724 case TBM_FORMAT_NV61:
1727 * index 0: Y plane, [7:0] Y
1728 * index 1: Cb plane, [7:0] Cb
1729 * index 2: Cr plane, [7:0] Cr
1731 * index 1: Cr plane, [7:0] Cr
1732 * index 2: Cb plane, [7:0] Cb
1734 case TBM_FORMAT_YUV410:
1735 case TBM_FORMAT_YVU410:
1736 case TBM_FORMAT_YUV411:
1737 case TBM_FORMAT_YVU411:
1738 case TBM_FORMAT_YUV420:
1739 case TBM_FORMAT_YVU420:
1740 case TBM_FORMAT_YUV422:
1741 case TBM_FORMAT_YVU422:
1742 case TBM_FORMAT_YUV444:
1743 case TBM_FORMAT_YVU444:
1756 tbm_sprd_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1758 SPRD_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1759 SPRD_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1761 tbm_bo_handle bo_handle;
1762 memset (&bo_handle, 0x0, sizeof (uint64_t));
1764 tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_priv_from_bufmgr(bufmgr);
1768 case TBM_DEVICE_DEFAULT:
1771 //getting handle from fd
1772 struct drm_prime_handle arg = {0, };
1776 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1778 TBM_SPRD_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1779 arg.fd, strerror(errno));
1780 return (tbm_bo_handle) NULL;
1783 bo_handle.u32 = (uint32_t)arg.handle;;
1786 case TBM_DEVICE_CPU:
1787 TBM_SPRD_LOG ("Not supported device:%d\n", device);
1788 bo_handle.ptr = (void *) NULL;
1792 bo_handle.u32 = (uint32_t)fd;
1795 TBM_SPRD_LOG ("error Not supported device:%d\n", device);
1796 bo_handle.ptr = (void *) NULL;
1804 tbm_sprd_bo_get_flags (tbm_bo bo)
1806 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1808 tbm_bo_sprd bo_sprd;
1810 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1811 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1813 return bo_sprd->flags_tbm;
1817 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1819 static TBMModuleVersionInfo SprdVersRec =
1826 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1829 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1831 tbm_bufmgr_sprd bufmgr_sprd;
1832 tbm_bufmgr_backend bufmgr_backend;
1837 bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1840 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1846 bufmgr_sprd->fd = tbm_bufmgr_get_drm_fd_wayland();
1847 bufmgr_sprd->fd_owner = 1;
1850 bufmgr_sprd->fd = fd;
1852 if (bufmgr_sprd->fd < 0)
1854 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1860 bufmgr_sprd->hashBos = drmHashCreate ();
1862 //Check if the tbm manager supports dma fence or not.
1863 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1868 length = read(fp, buf, 1);
1870 if (length == 1 && buf[0] == '1')
1871 bufmgr_sprd->use_dma_fence = 1;
1876 bufmgr_backend = tbm_backend_alloc();
1877 if (!bufmgr_backend)
1879 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1881 if (bufmgr_sprd->fd_owner)
1882 close(bufmgr_sprd->fd);
1888 bufmgr_backend->priv = (void *)bufmgr_sprd;
1889 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit,
1890 bufmgr_backend->bo_size = tbm_sprd_bo_size,
1891 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc,
1892 bufmgr_backend->bo_free = tbm_sprd_bo_free,
1893 bufmgr_backend->bo_import = tbm_sprd_bo_import,
1894 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd,
1895 bufmgr_backend->bo_export = tbm_sprd_bo_export,
1896 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd,
1897 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle,
1898 bufmgr_backend->bo_map = tbm_sprd_bo_map,
1899 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap,
1900 bufmgr_backend->bo_cache_flush = tbm_sprd_bo_cache_flush,
1901 bufmgr_backend->bo_get_global_key = tbm_sprd_bo_get_global_key;
1902 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1903 bufmgr_backend->surface_get_size = tbm_sprd_surface_get_size;
1904 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1905 bufmgr_backend->fd_to_handle = tbm_sprd_fd_to_handle;
1906 bufmgr_backend->surface_get_num_bos = tbm_sprd_surface_get_num_bos;
1907 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1909 if (bufmgr_sprd->use_dma_fence)
1911 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1912 bufmgr_backend->bo_lock = NULL;
1913 bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1914 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1918 bufmgr_backend->flags = 0;
1919 bufmgr_backend->bo_lock = NULL;
1920 bufmgr_backend->bo_unlock = NULL;
1923 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1925 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1926 tbm_backend_free (bufmgr_backend);
1928 if (bufmgr_sprd->fd_owner)
1929 close(bufmgr_sprd->fd);
1938 env = getenv ("TBM_SPRD_DEBUG");
1941 bDebug = atoi (env);
1942 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
1951 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
1952 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
1954 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
1955 __FUNCTION__, bufmgr_sprd->fd);