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->dmabuf = key;
777 bo_sprd->size = real_size;
778 bo_sprd->flags_sprd = info.flags;
779 bo_sprd->flags_tbm = _get_tbm_flag_from_sprd (bo_sprd->flags_sprd);
781 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
784 TBM_SPRD_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
785 bo, gem, key, strerror(errno));
791 PrivGem *privGem = NULL;
794 ret = drmHashLookup (bufmgr_sprd->hashBos, bo_sprd->name, (void**)&privGem);
797 privGem->ref_count++;
801 privGem = calloc (1, sizeof(PrivGem));
804 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
805 "error %s:%d Fail to calloc privGem\n",
806 getpid(), __FUNCTION__, __LINE__);
811 privGem->ref_count = 1;
812 if (drmHashInsert (bufmgr_sprd->hashBos, bo_sprd->name, (void *)privGem) < 0)
814 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
815 bo, bo_sprd->name, gem, key);
820 TBM_SPRD_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
821 bo, bo_sprd->name, gem, key);
824 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
826 bo_sprd->gem, bo_sprd->name,
829 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
832 return (void *)bo_sprd;
836 tbm_sprd_bo_export (tbm_bo bo)
838 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
842 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
843 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
847 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
850 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
851 "error %s:%d Cannot get name\n",
852 getpid(), __FUNCTION__, __LINE__);
857 DBG ("[libtbm-sprd:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
858 __FUNCTION__, bo_sprd->size,
859 bo_sprd->gem, bo_sprd->name,
860 bo_sprd->flags_tbm, bo_sprd->flags_sprd);
862 return (unsigned int)bo_sprd->name;
866 tbm_sprd_bo_export_fd (tbm_bo bo)
868 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, -1);
873 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
874 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, -1);
876 struct drm_prime_handle arg = {0, };
878 arg.handle = bo_sprd->gem;
879 ret = drmIoctl (bo_sprd->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
882 TBM_SPRD_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
883 bo, bo_sprd->gem, strerror(errno));
887 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
889 bo_sprd->gem, bo_sprd->name,
892 bo_sprd->flags_tbm, bo_sprd->flags_sprd,
895 return (tbm_fd)arg.fd;
900 tbm_sprd_bo_get_handle (tbm_bo bo, int device)
902 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
904 tbm_bo_handle bo_handle;
907 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
908 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL);
912 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
913 "error %s:%d Cannot map gem=%d\n",
914 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
915 return (tbm_bo_handle) NULL;
918 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s\n", getpid(),
919 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device]);
921 /*Get mapped bo_handle*/
922 bo_handle = _sprd_bo_handle (bo_sprd, device);
923 if (bo_handle.ptr == NULL)
925 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
926 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
927 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device);
928 return (tbm_bo_handle) NULL;
935 tbm_sprd_bo_map (tbm_bo bo, int device, int opt)
937 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
939 tbm_bo_handle bo_handle;
942 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
943 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, (tbm_bo_handle) NULL);
947 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
948 "error %s:%d Cannot map gem=%d\n",
949 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem);
950 return (tbm_bo_handle) NULL;
953 DBG ("[libtbm-sprd:%d] %s gem:%d(%d), %s, %s\n", getpid(),
954 __FUNCTION__, bo_sprd->gem, bo_sprd->name, STR_DEVICE[device], STR_OPT[opt]);
956 /*Get mapped bo_handle*/
957 bo_handle = _sprd_bo_handle (bo_sprd, device);
958 if (bo_handle.ptr == NULL)
960 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
961 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
962 getpid(), __FUNCTION__, __LINE__, bo_sprd->gem, device, opt);
963 return (tbm_bo_handle) NULL;
970 tbm_sprd_bo_unmap (tbm_bo bo)
972 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
976 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
977 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
982 DBG ("[libtbm-sprd:%d] %s gem:%d(%d) \n", getpid(),
983 __FUNCTION__, bo_sprd->gem, bo_sprd->name);
989 tbm_sprd_bo_cache_flush (tbm_bo bo, int flags)
991 tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
992 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
994 /* cache flush is managed by kernel side when using dma-fence. */
995 if (bufmgr_sprd->use_dma_fence)
998 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1000 tbm_bo_sprd bo_sprd;
1002 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1003 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1006 if (!_sprd_cache_flush(bo_sprd->fd, bo_sprd, flags))
1014 tbm_sprd_bo_get_global_key (tbm_bo bo)
1016 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1018 tbm_bo_sprd bo_sprd;
1020 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1021 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1028 bo_sprd->name = _get_name(bo_sprd->fd, bo_sprd->gem);
1031 return bo_sprd->name;
1035 tbm_sprd_bo_lock(tbm_bo bo, int device, int opt)
1037 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1039 #if USE_BACKEND_LOCK
1040 tbm_bufmgr_sprd bufmgr_sprd;
1041 tbm_bo_sprd bo_sprd;
1042 struct dma_buf_fence fence;
1045 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1046 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1048 bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_bufmgr_priv(bo);
1049 SPRD_RETURN_VAL_IF_FAIL (bufmgr_sprd!=NULL, 0);
1051 memset(&fence, 0, sizeof(struct dma_buf_fence));
1053 /* Check if the given type is valid or not. */
1054 if (opt & TBM_OPTION_WRITE)
1056 if (device == TBM_DEVICE_CPU)
1057 fence.type = DMA_BUF_ACCESS_WRITE;
1058 else if (device == TBM_DEVICE_3D)
1059 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1062 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
1066 else if (opt & TBM_OPTION_READ)
1068 if (device == TBM_DEVICE_CPU)
1069 fence.type = DMA_BUF_ACCESS_READ;
1070 else if (device == TBM_DEVICE_3D)
1071 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1074 DBG ("[libtbm-sprd:%d] %s GET_FENCE is ignored(device type is not 3D/CPU),\n", getpid(), __FUNCTION__);
1080 TBM_SPRD_LOG ("[libtbm-sprd:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__);
1084 /* Check if the tbm manager supports dma fence or not. */
1085 if (!bufmgr_sprd->use_dma_fence)
1087 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1088 "error %s:%d Not support DMA FENCE(%s)\n",
1089 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1094 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1097 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1098 "error %s:%d Can not set GET FENCE(%s)\n",
1099 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1103 pthread_mutex_lock(&bo_sprd->mutex);
1105 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1107 if (bo_sprd->dma_fence[i].ctx == 0)
1109 bo_sprd->dma_fence[i].type = fence.type;
1110 bo_sprd->dma_fence[i].ctx = fence.ctx;
1114 if (i == DMA_FENCE_LIST_MAX)
1116 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1117 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1118 "error %s:%d fence list is full\n",
1119 getpid(), __FUNCTION__, __LINE__);
1121 pthread_mutex_unlock(&bo_sprd->mutex);
1123 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1124 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1131 tbm_sprd_bo_unlock(tbm_bo bo)
1133 SPRD_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1135 #if USE_BACKEND_LOCK
1136 tbm_bo_sprd bo_sprd;
1137 struct dma_buf_fence fence;
1140 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1141 SPRD_RETURN_VAL_IF_FAIL (bo_sprd!=NULL, 0);
1143 if (!bo_sprd->dma_fence[0].ctx)
1145 DBG ("[libtbm-sprd:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1149 if (!bo_sprd->dma_fence[0].type)
1151 DBG ("[libtbm-sprd:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1155 pthread_mutex_lock(&bo_sprd->mutex);
1156 fence.type = bo_sprd->dma_fence[0].type;
1157 fence.ctx = bo_sprd->dma_fence[0].ctx;
1159 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1161 bo_sprd->dma_fence[i-1].type = bo_sprd->dma_fence[i].type;
1162 bo_sprd->dma_fence[i-1].ctx = bo_sprd->dma_fence[i].ctx;
1164 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1165 bo_sprd->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1166 pthread_mutex_unlock(&bo_sprd->mutex);
1168 ret = ioctl(bo_sprd->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1171 TBM_SPRD_LOG ("[libtbm-sprd:%d] "
1172 "error %s:%d Can not set PUT FENCE(%s)\n",
1173 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1177 DBG ("[libtbm-sprd:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1178 __FUNCTION__, bo_sprd->name, bo_sprd->dmabuf);
1185 tbm_sprd_bufmgr_deinit (void *priv)
1187 SPRD_RETURN_IF_FAIL (priv!=NULL);
1189 tbm_bufmgr_sprd bufmgr_sprd;
1191 bufmgr_sprd = (tbm_bufmgr_sprd)priv;
1193 if (bufmgr_sprd->hashBos)
1198 while (drmHashFirst(bufmgr_sprd->hashBos, &key, &value) > 0)
1201 drmHashDelete (bufmgr_sprd->hashBos, key);
1204 drmHashDestroy (bufmgr_sprd->hashBos);
1205 bufmgr_sprd->hashBos = NULL;
1208 if (bufmgr_sprd->fd_owner)
1209 close (bufmgr_sprd->fd_owner);
1215 tbm_sprd_surface_supported_format(uint32_t **formats, uint32_t *num)
1217 uint32_t* color_formats=NULL;
1219 color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1221 if( color_formats == NULL )
1225 memcpy( color_formats, tbm_sprd_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1228 *formats = color_formats;
1229 *num = TBM_COLOR_FORMAT_COUNT;
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_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)
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:
1331 case TBM_FORMAT_NV21:
1336 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1337 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1340 else if( plane_idx ==1 )
1342 _offset = width*height;
1343 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1344 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1349 case TBM_FORMAT_NV16:
1350 case TBM_FORMAT_NV61:
1352 //if(plane_idx == 0)
1355 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1356 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1361 //else if( plane_idx ==1 )
1364 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1365 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1372 * index 0: Y plane, [7:0] Y
1373 * index 1: Cb plane, [7:0] Cb
1374 * index 2: Cr plane, [7:0] Cr
1376 * index 1: Cr plane, [7:0] Cr
1377 * index 2: Cb plane, [7:0] Cb
1380 NATIVE_BUFFER_FORMAT_YV12
1381 NATIVE_BUFFER_FORMAT_I420
1383 case TBM_FORMAT_YUV410:
1384 case TBM_FORMAT_YVU410:
1387 case TBM_FORMAT_YUV411:
1388 case TBM_FORMAT_YVU411:
1389 case TBM_FORMAT_YUV420:
1390 case TBM_FORMAT_YVU420:
1392 //if(plane_idx == 0)
1395 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1396 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1401 //else if( plane_idx == 1 )
1404 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1405 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1410 //else if (plane_idx == 2 )
1413 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1414 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1418 case TBM_FORMAT_YUV422:
1419 case TBM_FORMAT_YVU422:
1421 //if(plane_idx == 0)
1424 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1425 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1430 //else if( plane_idx == 1 )
1433 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1434 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1439 //else if (plane_idx == 2 )
1442 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1443 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1447 case TBM_FORMAT_YUV444:
1448 case TBM_FORMAT_YVU444:
1450 //if(plane_idx == 0)
1453 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1454 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1459 //else if( plane_idx == 1 )
1462 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1463 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1468 //else if (plane_idx == 2 )
1471 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1472 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1489 * @brief get the size of the surface with a format.
1490 * @param[in] surface : the surface
1491 * @param[in] width : the width of the surface
1492 * @param[in] height : the height of the surface
1493 * @param[in] format : the format of the surface
1494 * @return size of the surface if this function succeeds, otherwise 0.
1498 tbm_sprd_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1504 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1510 case TBM_FORMAT_XRGB4444:
1511 case TBM_FORMAT_XBGR4444:
1512 case TBM_FORMAT_RGBX4444:
1513 case TBM_FORMAT_BGRX4444:
1514 case TBM_FORMAT_ARGB4444:
1515 case TBM_FORMAT_ABGR4444:
1516 case TBM_FORMAT_RGBA4444:
1517 case TBM_FORMAT_BGRA4444:
1518 case TBM_FORMAT_XRGB1555:
1519 case TBM_FORMAT_XBGR1555:
1520 case TBM_FORMAT_RGBX5551:
1521 case TBM_FORMAT_BGRX5551:
1522 case TBM_FORMAT_ARGB1555:
1523 case TBM_FORMAT_ABGR1555:
1524 case TBM_FORMAT_RGBA5551:
1525 case TBM_FORMAT_BGRA5551:
1526 case TBM_FORMAT_RGB565:
1528 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1529 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1532 case TBM_FORMAT_RGB888:
1533 case TBM_FORMAT_BGR888:
1535 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1536 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1539 case TBM_FORMAT_XRGB8888:
1540 case TBM_FORMAT_XBGR8888:
1541 case TBM_FORMAT_RGBX8888:
1542 case TBM_FORMAT_BGRX8888:
1543 case TBM_FORMAT_ARGB8888:
1544 case TBM_FORMAT_ABGR8888:
1545 case TBM_FORMAT_RGBA8888:
1546 case TBM_FORMAT_BGRA8888:
1548 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1549 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1552 case TBM_FORMAT_YUYV:
1553 case TBM_FORMAT_YVYU:
1554 case TBM_FORMAT_UYVY:
1555 case TBM_FORMAT_VYUY:
1556 case TBM_FORMAT_AYUV:
1558 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1559 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1563 * index 0 = Y plane, [7:0] Y
1564 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1566 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1568 case TBM_FORMAT_NV12:
1569 case TBM_FORMAT_NV21:
1573 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1574 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1578 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1579 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1582 case TBM_FORMAT_NV16:
1583 case TBM_FORMAT_NV61:
1587 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1588 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1592 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1593 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1599 * index 0: Y plane, [7:0] Y
1600 * index 1: Cb plane, [7:0] Cb
1601 * index 2: Cr plane, [7:0] Cr
1603 * index 1: Cr plane, [7:0] Cr
1604 * index 2: Cb plane, [7:0] Cb
1606 case TBM_FORMAT_YUV410:
1607 case TBM_FORMAT_YVU410:
1609 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1611 case TBM_FORMAT_YUV411:
1612 case TBM_FORMAT_YVU411:
1613 case TBM_FORMAT_YUV420:
1614 case TBM_FORMAT_YVU420:
1618 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1619 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1623 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1624 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1628 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1629 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1633 case TBM_FORMAT_YUV422:
1634 case TBM_FORMAT_YVU422:
1638 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1639 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1643 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1644 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1648 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1649 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1652 case TBM_FORMAT_YUV444:
1653 case TBM_FORMAT_YVU444:
1655 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1666 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1673 tbm_sprd_surface_get_num_bos(tbm_format format)
1680 case TBM_FORMAT_XRGB4444:
1681 case TBM_FORMAT_XBGR4444:
1682 case TBM_FORMAT_RGBX4444:
1683 case TBM_FORMAT_BGRX4444:
1684 case TBM_FORMAT_ARGB4444:
1685 case TBM_FORMAT_ABGR4444:
1686 case TBM_FORMAT_RGBA4444:
1687 case TBM_FORMAT_BGRA4444:
1688 case TBM_FORMAT_XRGB1555:
1689 case TBM_FORMAT_XBGR1555:
1690 case TBM_FORMAT_RGBX5551:
1691 case TBM_FORMAT_BGRX5551:
1692 case TBM_FORMAT_ARGB1555:
1693 case TBM_FORMAT_ABGR1555:
1694 case TBM_FORMAT_RGBA5551:
1695 case TBM_FORMAT_BGRA5551:
1696 case TBM_FORMAT_RGB565:
1698 case TBM_FORMAT_RGB888:
1699 case TBM_FORMAT_BGR888:
1701 case TBM_FORMAT_XRGB8888:
1702 case TBM_FORMAT_XBGR8888:
1703 case TBM_FORMAT_RGBX8888:
1704 case TBM_FORMAT_BGRX8888:
1705 case TBM_FORMAT_ARGB8888:
1706 case TBM_FORMAT_ABGR8888:
1707 case TBM_FORMAT_RGBA8888:
1708 case TBM_FORMAT_BGRA8888:
1710 case TBM_FORMAT_YUYV:
1711 case TBM_FORMAT_YVYU:
1712 case TBM_FORMAT_UYVY:
1713 case TBM_FORMAT_VYUY:
1714 case TBM_FORMAT_AYUV:
1717 * index 0 = Y plane, [7:0] Y
1718 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1720 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1722 case TBM_FORMAT_NV12:
1723 case TBM_FORMAT_NV21:
1724 case TBM_FORMAT_NV16:
1725 case TBM_FORMAT_NV61:
1728 * index 0: Y plane, [7:0] Y
1729 * index 1: Cb plane, [7:0] Cb
1730 * index 2: Cr plane, [7:0] Cr
1732 * index 1: Cr plane, [7:0] Cr
1733 * index 2: Cb plane, [7:0] Cb
1735 case TBM_FORMAT_YUV410:
1736 case TBM_FORMAT_YVU410:
1737 case TBM_FORMAT_YUV411:
1738 case TBM_FORMAT_YVU411:
1739 case TBM_FORMAT_YUV420:
1740 case TBM_FORMAT_YVU420:
1741 case TBM_FORMAT_YUV422:
1742 case TBM_FORMAT_YVU422:
1743 case TBM_FORMAT_YUV444:
1744 case TBM_FORMAT_YVU444:
1757 tbm_sprd_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1759 SPRD_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1760 SPRD_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1762 tbm_bo_handle bo_handle;
1763 memset (&bo_handle, 0x0, sizeof (uint64_t));
1765 tbm_bufmgr_sprd bufmgr_sprd = (tbm_bufmgr_sprd)tbm_backend_get_priv_from_bufmgr(bufmgr);
1769 case TBM_DEVICE_DEFAULT:
1772 //getting handle from fd
1773 struct drm_prime_handle arg = {0, };
1777 if (drmIoctl (bufmgr_sprd->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1779 TBM_SPRD_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1780 arg.fd, strerror(errno));
1781 return (tbm_bo_handle) NULL;
1784 bo_handle.u32 = (uint32_t)arg.handle;;
1787 case TBM_DEVICE_CPU:
1788 TBM_SPRD_LOG ("Not supported device:%d\n", device);
1789 bo_handle.ptr = (void *) NULL;
1793 bo_handle.u32 = (uint32_t)fd;
1796 TBM_SPRD_LOG ("error Not supported device:%d\n", device);
1797 bo_handle.ptr = (void *) NULL;
1805 tbm_sprd_bo_get_flags (tbm_bo bo)
1807 SPRD_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1809 tbm_bo_sprd bo_sprd;
1811 bo_sprd = (tbm_bo_sprd)tbm_backend_get_bo_priv(bo);
1812 SPRD_RETURN_VAL_IF_FAIL (bo_sprd != NULL, 0);
1814 return bo_sprd->flags_tbm;
1818 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1820 static TBMModuleVersionInfo SprdVersRec =
1827 TBMModuleData tbmModuleData = { &SprdVersRec, init_tbm_bufmgr_priv};
1830 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1832 tbm_bufmgr_sprd bufmgr_sprd;
1833 tbm_bufmgr_backend bufmgr_backend;
1838 bufmgr_sprd = calloc (1, sizeof(struct _tbm_bufmgr_sprd));
1841 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to alloc bufmgr_sprd!\n", getpid());
1847 bufmgr_sprd->fd = tbm_bufmgr_get_drm_fd_wayland();
1848 bufmgr_sprd->fd_owner = 1;
1851 bufmgr_sprd->fd = fd;
1853 if (bufmgr_sprd->fd < 0)
1855 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1861 bufmgr_sprd->hashBos = drmHashCreate ();
1863 //Check if the tbm manager supports dma fence or not.
1864 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1869 length = read(fp, buf, 1);
1871 if (length == 1 && buf[0] == '1')
1872 bufmgr_sprd->use_dma_fence = 1;
1877 bufmgr_backend = tbm_backend_alloc();
1878 if (!bufmgr_backend)
1880 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to create drm!\n", getpid());
1882 if (bufmgr_sprd->fd_owner)
1883 close(bufmgr_sprd->fd);
1889 bufmgr_backend->priv = (void *)bufmgr_sprd;
1890 bufmgr_backend->bufmgr_deinit = tbm_sprd_bufmgr_deinit,
1891 bufmgr_backend->bo_size = tbm_sprd_bo_size,
1892 bufmgr_backend->bo_alloc = tbm_sprd_bo_alloc,
1893 bufmgr_backend->bo_free = tbm_sprd_bo_free,
1894 bufmgr_backend->bo_import = tbm_sprd_bo_import,
1895 bufmgr_backend->bo_import_fd = tbm_sprd_bo_import_fd,
1896 bufmgr_backend->bo_export = tbm_sprd_bo_export,
1897 bufmgr_backend->bo_export_fd = tbm_sprd_bo_export_fd,
1898 bufmgr_backend->bo_get_handle = tbm_sprd_bo_get_handle,
1899 bufmgr_backend->bo_map = tbm_sprd_bo_map,
1900 bufmgr_backend->bo_unmap = tbm_sprd_bo_unmap,
1901 bufmgr_backend->bo_cache_flush = tbm_sprd_bo_cache_flush,
1902 bufmgr_backend->bo_get_global_key = tbm_sprd_bo_get_global_key;
1903 bufmgr_backend->surface_get_plane_data = tbm_sprd_surface_get_plane_data;
1904 bufmgr_backend->surface_get_size = tbm_sprd_surface_get_size;
1905 bufmgr_backend->surface_supported_format = tbm_sprd_surface_supported_format;
1906 bufmgr_backend->fd_to_handle = tbm_sprd_fd_to_handle;
1907 bufmgr_backend->surface_get_num_bos = tbm_sprd_surface_get_num_bos;
1908 bufmgr_backend->bo_get_flags = tbm_sprd_bo_get_flags;
1910 if (bufmgr_sprd->use_dma_fence)
1912 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1913 bufmgr_backend->bo_lock = NULL;
1914 bufmgr_backend->bo_lock2 = tbm_sprd_bo_lock;
1915 bufmgr_backend->bo_unlock = tbm_sprd_bo_unlock;
1919 bufmgr_backend->flags = 0;
1920 bufmgr_backend->bo_lock = NULL;
1921 bufmgr_backend->bo_unlock = NULL;
1924 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1926 TBM_SPRD_LOG ("[libtbm-sprd:%d] error: Fail to init backend!\n", getpid());
1927 tbm_backend_free (bufmgr_backend);
1929 if (bufmgr_sprd->fd_owner)
1930 close(bufmgr_sprd->fd);
1939 env = getenv ("TBM_SPRD_DEBUG");
1942 bDebug = atoi (env);
1943 TBM_SPRD_LOG ("TBM_SPRD_DEBUG=%s\n", env);
1952 DBG ("[libtbm-sprd:%d] %s DMABUF FENCE is %s\n", getpid(),
1953 __FUNCTION__, bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
1955 DBG ("[libtbm-sprd:%d] %s fd:%d\n", getpid(),
1956 __FUNCTION__, bufmgr_sprd->fd);