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>
50 #include <tbm_surface.h>
51 #include <tbm_surface_internal.h>
52 #include "tbm_wayland.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_DUMB_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_DUMB_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 DUMB_RETURN_IF_FAIL(cond) {\
117 TBM_DUMB_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
121 #define DUMB_RETURN_VAL_IF_FAIL(cond, val) {\
123 TBM_DUMB_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_dumb *tbm_bufmgr_dumb;
154 typedef struct _tbm_bo_dumb *tbm_bo_dumb;
156 typedef struct _dumb_private
161 /* tbm buffor object for dumb */
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_dumb;
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 dumb */
188 struct _tbm_bufmgr_dumb
217 uint32_t tbm_dumb_color_format_list[TBM_COLOR_FORMAT_COUNT] = { TBM_FORMAT_RGBA8888,
228 _get_dumb_flag_from_tbm (unsigned int ftbm)
230 unsigned int flags = 0;
235 _get_tbm_flag_from_dumb (unsigned int fdumb)
237 unsigned int flags = 0;
239 flags |= TBM_BO_DEFAULT;
240 flags |= TBM_BO_SCANOUT;
241 flags |= TBM_BO_NONCACHABLE;
247 _get_name (int fd, unsigned int gem)
249 struct drm_gem_flink arg = {0,};
252 if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg))
254 TBM_DUMB_LOG ("error fail to get flink from gem:%d (DRM_IOCTL_GEM_FLINK)\n",
259 return (unsigned int)arg.name;
263 _dumb_bo_handle (tbm_bo_dumb bo_dumb, int device)
265 tbm_bo_handle bo_handle;
266 memset (&bo_handle, 0x0, sizeof (uint64_t));
270 case TBM_DEVICE_DEFAULT:
272 bo_handle.u32 = (uint32_t)bo_dumb->gem;
277 struct drm_mode_map_dumb arg = {0,};
280 arg.handle = bo_dumb->gem;
281 if (drmIoctl (bo_dumb->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg))
283 TBM_DUMB_LOG ("error Cannot map_ gem=%d\n", bo_dumb->gem);
284 return (tbm_bo_handle) NULL;
287 map = mmap (NULL, bo_dumb->size, PROT_READ|PROT_WRITE, MAP_SHARED,
288 bo_dumb->fd, arg.offset);
289 if (map == MAP_FAILED)
291 TBM_DUMB_LOG ("error Cannot usrptr gem=%d\n", bo_dumb->gem);
292 return (tbm_bo_handle) NULL;
294 bo_dumb->pBase = map;
296 bo_handle.ptr = (void *)bo_dumb->pBase;
302 bo_handle.u32 = (uint32_t)bo_dumb->dmabuf;
306 if (!bo_dumb->dmabuf)
308 struct drm_prime_handle arg = {0, };
310 arg.handle = bo_dumb->gem;
311 if (drmIoctl (bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
313 TBM_DUMB_LOG ("error Cannot dmabuf=%d\n", bo_dumb->gem);
314 return (tbm_bo_handle) NULL;
316 bo_dumb->dmabuf = arg.fd;
319 bo_handle.u32 = (uint32_t)bo_dumb->dmabuf;
323 if (!bo_dumb->dmabuf)
325 struct drm_prime_handle arg = {0, };
327 arg.handle = bo_dumb->gem;
328 if (drmIoctl (bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
330 TBM_DUMB_LOG ("error Cannot dmabuf=%d\n", bo_dumb->gem);
331 return (tbm_bo_handle) NULL;
333 bo_dumb->dmabuf = arg.fd;
336 bo_handle.u32 = (uint32_t)bo_dumb->dmabuf;
339 TBM_DUMB_LOG ("error Not supported device:%d\n", device);
340 bo_handle.ptr = (void *) NULL;
348 _dumb_cache_flush (int fd, tbm_bo_dumb bo_dumb, int flags)
350 #ifdef ENABLE_CACHECRTL
351 TBM_DUMB_LOG ("warning fail to enable the cache flush.\n");
353 TBM_DUMB_LOG ("warning fail to enable the cache flush.\n");
359 tbm_dumb_bo_size (tbm_bo bo)
361 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
365 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
367 return bo_dumb->size;
371 tbm_dumb_bo_alloc (tbm_bo bo, int size, int flags)
373 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
376 tbm_bufmgr_dumb bufmgr_dumb;
377 unsigned int dumb_flags;
379 bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo);
380 DUMB_RETURN_VAL_IF_FAIL (bufmgr_dumb!=NULL, 0);
382 bo_dumb = calloc (1, sizeof(struct _tbm_bo_dumb));
385 TBM_DUMB_LOG ("error fail to allocate the bo private\n");
389 dumb_flags = _get_dumb_flag_from_tbm (flags);
391 struct drm_mode_create_dumb arg = {0, };
392 //as we know only size for new bo set height=1 and bpp=8 and in this case
393 //width will by equal to size in bytes;
397 arg.flags = dumb_flags;
398 if (drmIoctl (bufmgr_dumb->fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg))
400 TBM_DUMB_LOG ("error Cannot create bo(flag:%x, size:%d)\n", arg.flags, (unsigned int)size);
405 bo_dumb->fd = bufmgr_dumb->fd;
406 bo_dumb->gem = arg.handle;
407 bo_dumb->size = size;
408 bo_dumb->flags_tbm = flags;
409 bo_dumb->flags_dumb = dumb_flags;
410 bo_dumb->name = _get_name (bo_dumb->fd, bo_dumb->gem);
412 pthread_mutex_init(&bo_dumb->mutex, NULL);
414 if (bufmgr_dumb->use_dma_fence
417 struct drm_prime_handle arg = {0, };
419 arg.handle = bo_dumb->gem;
420 if (drmIoctl (bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
422 TBM_DUMB_LOG ("error Cannot dmabuf=%d\n", bo_dumb->gem);
426 bo_dumb->dmabuf = arg.fd;
430 PrivGem* privGem = calloc (1, sizeof(PrivGem));
433 TBM_DUMB_LOG ("[libtbm-dumb:%d] "
434 "error %s:%d Fail to calloc privGem\n",
435 getpid(), __FUNCTION__, __LINE__);
440 privGem->ref_count = 1;
441 if (drmHashInsert(bufmgr_dumb->hashBos, bo_dumb->name, (void *)privGem) < 0)
443 TBM_DUMB_LOG ("error Cannot insert bo to Hash(%d)\n", bo_dumb->name);
446 DBG (" [%s] bo:%p, gem:%d(%d), flags:%d(%d), size:%d\n", target_name(),
448 bo_dumb->gem, bo_dumb->name,
452 return (void *)bo_dumb;
456 tbm_dumb_bo_free(tbm_bo bo)
459 tbm_bufmgr_dumb bufmgr_dumb;
464 bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo);
465 DUMB_RETURN_IF_FAIL (bufmgr_dumb!=NULL);
467 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
468 DUMB_RETURN_IF_FAIL (bo_dumb!=NULL);
470 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, size:%d\n",target_name(),
472 bo_dumb->gem, bo_dumb->name,
478 if (munmap(bo_dumb->pBase, bo_dumb->size) == -1)
480 TBM_DUMB_LOG ("error bo:%p fail to munmap(%s)\n",
481 bo, strerror(errno));
488 close (bo_dumb->dmabuf);
492 /* delete bo from hash */
493 PrivGem *privGem = NULL;
496 ret = drmHashLookup (bufmgr_dumb->hashBos, bo_dumb->name, (void**)&privGem);
499 privGem->ref_count--;
500 if (privGem->ref_count == 0)
502 drmHashDelete (bufmgr_dumb->hashBos, bo_dumb->name);
509 TBM_DUMB_LOG ("warning Cannot find bo to Hash(%d), ret=%d\n", bo_dumb->name, ret);
512 /* Free gem handle */
513 struct drm_gem_close arg = {0, };
514 memset (&arg, 0, sizeof(arg));
515 arg.handle = bo_dumb->gem;
516 if (drmIoctl (bo_dumb->fd, DRM_IOCTL_GEM_CLOSE, &arg))
518 TBM_DUMB_LOG ("error bo:%p fail to gem close.(%s)\n",
519 bo, strerror(errno));
527 tbm_dumb_bo_import (tbm_bo bo, unsigned int key)
529 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
531 tbm_bufmgr_dumb bufmgr_dumb;
534 bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo);
535 DUMB_RETURN_VAL_IF_FAIL (bufmgr_dumb!=NULL, 0);
537 struct drm_gem_open arg = {0, };
540 if (drmIoctl(bufmgr_dumb->fd, DRM_IOCTL_GEM_OPEN, &arg))
542 TBM_DUMB_LOG ("error Cannot open gem name=%d\n", key);
546 bo_dumb = calloc (1, sizeof(struct _tbm_bo_dumb));
549 TBM_DUMB_LOG ("error fail to allocate the bo private\n");
553 bo_dumb->fd = bufmgr_dumb->fd;
554 bo_dumb->gem = arg.handle;
555 bo_dumb->size = arg.size;
556 bo_dumb->flags_dumb = 0;
558 bo_dumb->flags_tbm = _get_tbm_flag_from_dumb (bo_dumb->flags_dumb);
560 if (!bo_dumb->dmabuf)
562 struct drm_prime_handle arg = {0, };
564 arg.handle = bo_dumb->gem;
565 if (drmIoctl (bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
567 TBM_DUMB_LOG ("error Cannot dmabuf=%d\n", bo_dumb->gem);
571 bo_dumb->dmabuf = arg.fd;
575 PrivGem *privGem = NULL;
578 ret = drmHashLookup (bufmgr_dumb->hashBos, bo_dumb->name, (void**)&privGem);
581 privGem->ref_count++;
585 privGem = calloc (1, sizeof(PrivGem));
588 TBM_DUMB_LOG ("[libtbm-dumb:%d] "
589 "error %s:%d Fail to calloc privGem\n",
590 getpid(), __FUNCTION__, __LINE__);
595 privGem->ref_count = 1;
596 if (drmHashInsert (bufmgr_dumb->hashBos, bo_dumb->name, (void *)privGem) < 0)
598 TBM_DUMB_LOG ("error Cannot insert bo to Hash(%d)\n", bo_dumb->name);
603 TBM_DUMB_LOG ("error Cannot insert bo to Hash(%d)\n", bo_dumb->name);
606 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", target_name(),
608 bo_dumb->gem, bo_dumb->name,
610 bo_dumb->flags_tbm, bo_dumb->flags_dumb,
613 return (void *)bo_dumb;
617 tbm_dumb_bo_import_fd (tbm_bo bo, tbm_fd key)
619 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
621 tbm_bufmgr_dumb bufmgr_dumb;
624 bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo);
625 DUMB_RETURN_VAL_IF_FAIL (bufmgr_dumb!=NULL, 0);
627 unsigned int gem = 0;
628 unsigned int name = 0;
629 unsigned int real_size = -1;
631 //getting handle from fd
632 struct drm_prime_handle arg = {0, };
633 struct drm_gem_open gem_open = {0, };
637 if (drmIoctl (bufmgr_dumb->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
639 TBM_DUMB_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
640 bo, arg.fd, strerror(errno));
645 name = _get_name(bufmgr_dumb->fd, gem);
648 TBM_DUMB_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
649 bo, gem, key, strerror(errno));
653 /* Open the same GEM object only for finding out its size */
654 gem_open.name = name;
655 if (drmIoctl(bufmgr_dumb->fd, DRM_IOCTL_GEM_OPEN, &gem_open))
657 TBM_DUMB_LOG ("error Cannot open gem name=%d\n", key);
660 /* Free gem handle to avoid a memory leak*/
661 struct drm_gem_close gem_close;
662 gem_close.handle = gem_open.handle;
663 if (drmIoctl (bufmgr_dumb->fd, DRM_IOCTL_GEM_CLOSE, &gem_close))
665 TBM_DUMB_LOG ("error bo:%p fail to gem close.(%s)\n",
666 bo, strerror(errno));
669 /* Determine size of bo. The fd-to-handle ioctl really should
670 * return the size, but it doesn't. If we have kernel 3.12 or
671 * later, we can lseek on the prime fd to get the size. Older
672 * kernels will just fail, in which case we fall back to the
673 * provided (estimated or guess size). */
674 real_size = lseek(key, 0, SEEK_END);
676 if (real_size == -1) {
677 real_size = gem_open.size;
680 bo_dumb = calloc (1, sizeof(struct _tbm_bo_dumb));
683 TBM_DUMB_LOG ("error bo:%p fail to allocate the bo private\n", bo);
687 bo_dumb->fd = bufmgr_dumb->fd;
689 bo_dumb->dmabuf = key;
690 bo_dumb->size = real_size;
691 bo_dumb->flags_dumb = 0;
692 bo_dumb->flags_tbm = _get_tbm_flag_from_dumb (bo_dumb->flags_dumb);
693 bo_dumb->name = name;
696 PrivGem *privGem = NULL;
699 ret = drmHashLookup (bufmgr_dumb->hashBos, bo_dumb->name, (void**)&privGem);
702 privGem->ref_count++;
706 privGem = calloc (1, sizeof(PrivGem));
709 TBM_DUMB_LOG ("[libtbm-dumb:%d] "
710 "error %s:%d Fail to calloc privGem\n",
711 getpid(), __FUNCTION__, __LINE__);
716 privGem->ref_count = 1;
717 if (drmHashInsert (bufmgr_dumb->hashBos, bo_dumb->name, (void *)privGem) < 0)
719 TBM_DUMB_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
720 bo, bo_dumb->name, gem, key);
725 TBM_DUMB_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
726 bo, bo_dumb->name, gem, key);
729 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
731 bo_dumb->gem, bo_dumb->name,
734 bo_dumb->flags_tbm, bo_dumb->flags_dumb,
737 return (void *)bo_dumb;
741 tbm_dumb_bo_export (tbm_bo bo)
743 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
747 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
748 DUMB_RETURN_VAL_IF_FAIL (bo_dumb!=NULL, 0);
752 bo_dumb->name = _get_name(bo_dumb->fd, bo_dumb->gem);
755 TBM_DUMB_LOG ("error Cannot get name\n");
760 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", target_name(),
762 bo_dumb->gem, bo_dumb->name,
764 bo_dumb->flags_tbm, bo_dumb->flags_dumb,
767 return (unsigned int)bo_dumb->name;
771 tbm_dumb_bo_export_fd (tbm_bo bo)
773 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
777 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
778 DUMB_RETURN_VAL_IF_FAIL (bo_dumb!=NULL, 0);
780 struct drm_prime_handle arg = {0, };
782 arg.handle = bo_dumb->gem;
783 if (drmIoctl (bo_dumb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
785 TBM_DUMB_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
786 bo, bo_dumb->gem, strerror(errno));
790 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
792 bo_dumb->gem, bo_dumb->name,
795 bo_dumb->flags_tbm, bo_dumb->flags_dumb,
798 return (tbm_fd)arg.fd;
802 tbm_dumb_bo_get_handle (tbm_bo bo, int device)
804 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
806 tbm_bo_handle bo_handle;
809 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
810 DUMB_RETURN_VAL_IF_FAIL (bo_dumb!=NULL, (tbm_bo_handle) NULL);
814 TBM_DUMB_LOG ("error Cannot map gem=%d\n", bo_dumb->gem);
815 return (tbm_bo_handle) NULL;
818 DBG ("[%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d, %s\n", target_name(),
820 bo_dumb->gem, bo_dumb->name,
822 bo_dumb->flags_tbm, bo_dumb->flags_dumb,
826 /*Get mapped bo_handle*/
827 bo_handle = _dumb_bo_handle (bo_dumb, device);
828 if (bo_handle.ptr == NULL)
830 TBM_DUMB_LOG ("error Cannot get handle: gem:%d, device:%d\n", bo_dumb->gem, device);
831 return (tbm_bo_handle) NULL;
838 tbm_dumb_bo_map (tbm_bo bo, int device, int opt)
840 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
842 tbm_bo_handle bo_handle;
845 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
846 DUMB_RETURN_VAL_IF_FAIL (bo_dumb!=NULL, (tbm_bo_handle) NULL);
850 TBM_DUMB_LOG ("error Cannot map gem=%d\n", bo_dumb->gem);
851 return (tbm_bo_handle) NULL;
854 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, %s, %s\n", target_name(),
856 bo_dumb->gem, bo_dumb->name,
861 /*Get mapped bo_handle*/
862 bo_handle = _dumb_bo_handle (bo_dumb, device);
863 if (bo_handle.ptr == NULL)
865 TBM_DUMB_LOG ("error Cannot get handle: gem:%d, device:%d, opt:%d\n", bo_dumb->gem, device, opt);
866 return (tbm_bo_handle) NULL;
873 tbm_dumb_bo_unmap (tbm_bo bo)
875 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
879 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
880 DUMB_RETURN_VAL_IF_FAIL (bo_dumb!=NULL, 0);
885 DBG (" [%s] bo:%p, gem:%d(%d), fd:%d\n", target_name(),
887 bo_dumb->gem, bo_dumb->name,
894 tbm_dumb_bo_cache_flush (tbm_bo bo, int flags)
896 tbm_bufmgr_dumb bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo);
897 DUMB_RETURN_VAL_IF_FAIL (bufmgr_dumb!=NULL, 0);
899 /* cache flush is managed by kernel side when using dma-fence. */
900 if (bufmgr_dumb->use_dma_fence)
903 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
907 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
908 DUMB_RETURN_VAL_IF_FAIL (bo_dumb!=NULL, 0);
910 if (!_dumb_cache_flush(bo_dumb->fd, bo_dumb, flags))
917 tbm_dumb_bo_get_global_key (tbm_bo bo)
919 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
923 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
924 DUMB_RETURN_VAL_IF_FAIL (bo_dumb!=NULL, 0);
931 bo_dumb->name = _get_name(bo_dumb->fd, bo_dumb->gem);
934 return bo_dumb->name;
938 tbm_dumb_bo_lock(tbm_bo bo, int device, int opt)
940 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
942 tbm_bufmgr_dumb bufmgr_dumb;
944 struct dma_buf_fence fence;
945 struct flock filelock;
948 if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU)
950 DBG ("[libtbm-dumb:%d] %s not support device type,\n", getpid(), __FUNCTION__);
954 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
955 DUMB_RETURN_VAL_IF_FAIL (bo_dumb!=NULL, 0);
957 bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_bufmgr_priv(bo);
958 DUMB_RETURN_VAL_IF_FAIL (bufmgr_dumb!=NULL, 0);
960 memset(&fence, 0, sizeof(struct dma_buf_fence));
962 /* Check if the given type is valid or not. */
963 if (opt & TBM_OPTION_WRITE)
965 if (device == TBM_DEVICE_3D)
966 fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
968 else if (opt & TBM_OPTION_READ)
970 if (device == TBM_DEVICE_3D)
971 fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
975 TBM_DUMB_LOG ("error Invalid argument\n");
979 /* Check if the tbm manager supports dma fence or not. */
980 if (!bufmgr_dumb->use_dma_fence)
982 TBM_DUMB_LOG ("error Not support DMA FENCE(%s)\n", strerror(errno) );
987 if (device == TBM_DEVICE_3D)
989 ret = ioctl(bo_dumb->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
992 TBM_DUMB_LOG ("error Cannot set GET FENCE(%s)\n", strerror(errno) );
997 if (opt & TBM_OPTION_WRITE)
998 filelock.l_type = F_WRLCK;
1000 filelock.l_type = F_RDLCK;
1002 filelock.l_whence = SEEK_CUR;
1003 filelock.l_start = 0;
1006 if (-1 == fcntl(bo_dumb->dmabuf, F_SETLKW, &filelock))
1012 pthread_mutex_lock(&bo_dumb->mutex);
1014 if (device == TBM_DEVICE_3D)
1017 for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1019 if (bo_dumb->dma_fence[i].ctx == 0)
1021 bo_dumb->dma_fence[i].type = fence.type;
1022 bo_dumb->dma_fence[i].ctx = fence.ctx;
1027 if (i == DMA_FENCE_LIST_MAX)
1029 //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1030 TBM_DUMB_LOG ("error fence list is full\n");
1034 pthread_mutex_unlock(&bo_dumb->mutex);
1036 DBG ("[%s] DMABUF_IOCTL_GET_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(),
1038 bo_dumb->gem, bo_dumb->name,
1045 tbm_dumb_bo_unlock(tbm_bo bo)
1047 DUMB_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1049 tbm_bo_dumb bo_dumb;
1050 struct dma_buf_fence fence;
1051 struct flock filelock;
1052 unsigned int dma_type = 0;
1055 bo_dumb = (tbm_bo_dumb)tbm_backend_get_bo_priv(bo);
1056 DUMB_RETURN_VAL_IF_FAIL (bo_dumb!=NULL, 0);
1058 if (bo_dumb->dma_fence[0].type & DMA_BUF_ACCESS_DMA)
1061 if (!bo_dumb->dma_fence[0].ctx && dma_type)
1063 DBG ("[libtbm-dumb:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1067 if (!bo_dumb->dma_fence[0].ctx && dma_type)
1069 DBG ("[libtbm-dumb:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1073 pthread_mutex_lock(&bo_dumb->mutex);
1077 fence.type = bo_dumb->dma_fence[0].type;
1078 fence.ctx = bo_dumb->dma_fence[0].ctx;
1080 for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1082 bo_dumb->dma_fence[i-1].type = bo_dumb->dma_fence[i].type;
1083 bo_dumb->dma_fence[i-1].ctx = bo_dumb->dma_fence[i].ctx;
1085 bo_dumb->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1086 bo_dumb->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1088 pthread_mutex_unlock(&bo_dumb->mutex);
1092 ret = ioctl(bo_dumb->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1095 TBM_DUMB_LOG ("error Can not set PUT FENCE(%s)\n", strerror(errno));
1100 filelock.l_type = F_UNLCK;
1101 filelock.l_whence = SEEK_CUR;
1102 filelock.l_start = 0;
1105 if (-1 == fcntl(bo_dumb->dmabuf, F_SETLKW, &filelock))
1111 DBG ("[%s] DMABUF_IOCTL_PUT_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(),
1113 bo_dumb->gem, bo_dumb->name,
1120 tbm_dumb_bufmgr_deinit (void *priv)
1122 DUMB_RETURN_IF_FAIL (priv!=NULL);
1124 tbm_bufmgr_dumb bufmgr_dumb;
1126 bufmgr_dumb = (tbm_bufmgr_dumb)priv;
1128 if (bufmgr_dumb->hashBos)
1133 while (drmHashFirst(bufmgr_dumb->hashBos, &key, &value) > 0)
1136 drmHashDelete (bufmgr_dumb->hashBos, key);
1139 drmHashDestroy (bufmgr_dumb->hashBos);
1140 bufmgr_dumb->hashBos = NULL;
1143 if (bufmgr_dumb->fd_owner)
1144 close(bufmgr_dumb->fd);
1150 tbm_dumb_surface_supported_format(uint32_t **formats, uint32_t *num)
1152 uint32_t* color_formats=NULL;
1154 color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1156 if( color_formats == NULL )
1160 memcpy( color_formats, tbm_dumb_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1163 *formats = color_formats;
1164 *num = TBM_COLOR_FORMAT_COUNT;
1166 fprintf (stderr, "tbm_dumb_surface_supported_format count = %d \n",*num);
1173 * @brief get the plane data of the surface.
1174 * @param[in] surface : the surface
1175 * @param[in] width : the width of the surface
1176 * @param[in] height : the height of the surface
1177 * @param[in] format : the format of the surface
1178 * @param[in] plane_idx : the format of the surface
1179 * @param[out] size : the size of the plane
1180 * @param[out] offset : the offset of the plane
1181 * @param[out] pitch : the pitch of the plane
1182 * @param[out] padding : the padding of the plane
1183 * @return 1 if this function succeeds, otherwise 0.
1186 tbm_dumb_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)
1198 case TBM_FORMAT_XRGB4444:
1199 case TBM_FORMAT_XBGR4444:
1200 case TBM_FORMAT_RGBX4444:
1201 case TBM_FORMAT_BGRX4444:
1202 case TBM_FORMAT_ARGB4444:
1203 case TBM_FORMAT_ABGR4444:
1204 case TBM_FORMAT_RGBA4444:
1205 case TBM_FORMAT_BGRA4444:
1206 case TBM_FORMAT_XRGB1555:
1207 case TBM_FORMAT_XBGR1555:
1208 case TBM_FORMAT_RGBX5551:
1209 case TBM_FORMAT_BGRX5551:
1210 case TBM_FORMAT_ARGB1555:
1211 case TBM_FORMAT_ABGR1555:
1212 case TBM_FORMAT_RGBA5551:
1213 case TBM_FORMAT_BGRA5551:
1214 case TBM_FORMAT_RGB565:
1217 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1218 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1222 case TBM_FORMAT_RGB888:
1223 case TBM_FORMAT_BGR888:
1226 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1227 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1231 case TBM_FORMAT_XRGB8888:
1232 case TBM_FORMAT_XBGR8888:
1233 case TBM_FORMAT_RGBX8888:
1234 case TBM_FORMAT_BGRX8888:
1235 case TBM_FORMAT_ARGB8888:
1236 case TBM_FORMAT_ABGR8888:
1237 case TBM_FORMAT_RGBA8888:
1238 case TBM_FORMAT_BGRA8888:
1241 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1242 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1247 case TBM_FORMAT_YUYV:
1248 case TBM_FORMAT_YVYU:
1249 case TBM_FORMAT_UYVY:
1250 case TBM_FORMAT_VYUY:
1251 case TBM_FORMAT_AYUV:
1254 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1255 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1261 * index 0 = Y plane, [7:0] Y
1262 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1264 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1266 case TBM_FORMAT_NV12:
1271 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1272 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1275 else if( plane_idx ==1 )
1278 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1279 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1283 case TBM_FORMAT_NV21:
1288 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1289 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1292 else if( plane_idx ==1 )
1294 _offset = width*height;
1295 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1296 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1301 case TBM_FORMAT_NV16:
1302 case TBM_FORMAT_NV61:
1304 //if(plane_idx == 0)
1307 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1308 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1313 //else if( plane_idx ==1 )
1316 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1317 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1324 * index 0: Y plane, [7:0] Y
1325 * index 1: Cb plane, [7:0] Cb
1326 * index 2: Cr plane, [7:0] Cr
1328 * index 1: Cr plane, [7:0] Cr
1329 * index 2: Cb plane, [7:0] Cb
1332 NATIVE_BUFFER_FORMAT_YV12
1333 NATIVE_BUFFER_FORMAT_I420
1335 case TBM_FORMAT_YUV410:
1336 case TBM_FORMAT_YVU410:
1340 case TBM_FORMAT_YUV411:
1341 case TBM_FORMAT_YVU411:
1342 case TBM_FORMAT_YUV420:
1343 case TBM_FORMAT_YVU420:
1345 //if(plane_idx == 0)
1348 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1349 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1354 //else if( plane_idx == 1 )
1357 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1358 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1363 //else if (plane_idx == 2 )
1366 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1367 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1371 case TBM_FORMAT_YUV422:
1372 case TBM_FORMAT_YVU422:
1374 //if(plane_idx == 0)
1377 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1378 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1383 //else if( plane_idx == 1 )
1386 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1387 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1392 //else if (plane_idx == 2 )
1395 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1396 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1400 case TBM_FORMAT_YUV444:
1401 case TBM_FORMAT_YVU444:
1403 //if(plane_idx == 0)
1406 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1407 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1412 //else if( plane_idx == 1 )
1415 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1416 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1421 //else if (plane_idx == 2 )
1424 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1425 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1443 tbm_dumb_surface_get_num_bos(tbm_format format)
1450 case TBM_FORMAT_XRGB4444:
1451 case TBM_FORMAT_XBGR4444:
1452 case TBM_FORMAT_RGBX4444:
1453 case TBM_FORMAT_BGRX4444:
1454 case TBM_FORMAT_ARGB4444:
1455 case TBM_FORMAT_ABGR4444:
1456 case TBM_FORMAT_RGBA4444:
1457 case TBM_FORMAT_BGRA4444:
1458 case TBM_FORMAT_XRGB1555:
1459 case TBM_FORMAT_XBGR1555:
1460 case TBM_FORMAT_RGBX5551:
1461 case TBM_FORMAT_BGRX5551:
1462 case TBM_FORMAT_ARGB1555:
1463 case TBM_FORMAT_ABGR1555:
1464 case TBM_FORMAT_RGBA5551:
1465 case TBM_FORMAT_BGRA5551:
1466 case TBM_FORMAT_RGB565:
1468 case TBM_FORMAT_RGB888:
1469 case TBM_FORMAT_BGR888:
1471 case TBM_FORMAT_XRGB8888:
1472 case TBM_FORMAT_XBGR8888:
1473 case TBM_FORMAT_RGBX8888:
1474 case TBM_FORMAT_BGRX8888:
1475 case TBM_FORMAT_ARGB8888:
1476 case TBM_FORMAT_ABGR8888:
1477 case TBM_FORMAT_RGBA8888:
1478 case TBM_FORMAT_BGRA8888:
1480 case TBM_FORMAT_YUYV:
1481 case TBM_FORMAT_YVYU:
1482 case TBM_FORMAT_UYVY:
1483 case TBM_FORMAT_VYUY:
1484 case TBM_FORMAT_AYUV:
1487 * index 0 = Y plane, [7:0] Y
1488 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1490 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1492 case TBM_FORMAT_NV21:
1493 case TBM_FORMAT_NV16:
1494 case TBM_FORMAT_NV61:
1497 * index 0: Y plane, [7:0] Y
1498 * index 1: Cb plane, [7:0] Cb
1499 * index 2: Cr plane, [7:0] Cr
1501 * index 1: Cr plane, [7:0] Cr
1502 * index 2: Cb plane, [7:0] Cb
1504 case TBM_FORMAT_YUV410:
1505 case TBM_FORMAT_YVU410:
1506 case TBM_FORMAT_YUV411:
1507 case TBM_FORMAT_YVU411:
1508 case TBM_FORMAT_YUV420:
1509 case TBM_FORMAT_YVU420:
1510 case TBM_FORMAT_YUV422:
1511 case TBM_FORMAT_YVU422:
1512 case TBM_FORMAT_YUV444:
1513 case TBM_FORMAT_YVU444:
1517 case TBM_FORMAT_NV12:
1530 * @brief get the size of the surface with a format.
1531 * @param[in] surface : the surface
1532 * @param[in] width : the width of the surface
1533 * @param[in] height : the height of the surface
1534 * @param[in] format : the format of the surface
1535 * @return size of the surface if this function succeeds, otherwise 0.
1539 tbm_dumb_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1545 int align =TBM_SURFACE_ALIGNMENT_PLANE;
1550 case TBM_FORMAT_XRGB4444:
1551 case TBM_FORMAT_XBGR4444:
1552 case TBM_FORMAT_RGBX4444:
1553 case TBM_FORMAT_BGRX4444:
1554 case TBM_FORMAT_ARGB4444:
1555 case TBM_FORMAT_ABGR4444:
1556 case TBM_FORMAT_RGBA4444:
1557 case TBM_FORMAT_BGRA4444:
1558 case TBM_FORMAT_XRGB1555:
1559 case TBM_FORMAT_XBGR1555:
1560 case TBM_FORMAT_RGBX5551:
1561 case TBM_FORMAT_BGRX5551:
1562 case TBM_FORMAT_ARGB1555:
1563 case TBM_FORMAT_ABGR1555:
1564 case TBM_FORMAT_RGBA5551:
1565 case TBM_FORMAT_BGRA5551:
1566 case TBM_FORMAT_RGB565:
1568 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1569 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1572 case TBM_FORMAT_RGB888:
1573 case TBM_FORMAT_BGR888:
1575 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1576 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1579 case TBM_FORMAT_XRGB8888:
1580 case TBM_FORMAT_XBGR8888:
1581 case TBM_FORMAT_RGBX8888:
1582 case TBM_FORMAT_BGRX8888:
1583 case TBM_FORMAT_ARGB8888:
1584 case TBM_FORMAT_ABGR8888:
1585 case TBM_FORMAT_RGBA8888:
1586 case TBM_FORMAT_BGRA8888:
1588 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1589 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1592 case TBM_FORMAT_YUYV:
1593 case TBM_FORMAT_YVYU:
1594 case TBM_FORMAT_UYVY:
1595 case TBM_FORMAT_VYUY:
1596 case TBM_FORMAT_AYUV:
1598 _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1599 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1603 * index 0 = Y plane, [7:0] Y
1604 * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1606 * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1608 case TBM_FORMAT_NV12:
1609 case TBM_FORMAT_NV21:
1613 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1614 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1618 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1619 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1624 case TBM_FORMAT_NV16:
1625 case TBM_FORMAT_NV61:
1629 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1630 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1634 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1635 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1641 * index 0: Y plane, [7:0] Y
1642 * index 1: Cb plane, [7:0] Cb
1643 * index 2: Cr plane, [7:0] Cr
1645 * index 1: Cr plane, [7:0] Cr
1646 * index 2: Cb plane, [7:0] Cb
1648 case TBM_FORMAT_YUV410:
1649 case TBM_FORMAT_YVU410:
1651 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1653 case TBM_FORMAT_YUV411:
1654 case TBM_FORMAT_YVU411:
1655 case TBM_FORMAT_YUV420:
1656 case TBM_FORMAT_YVU420:
1660 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1661 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1665 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1666 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1670 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1671 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1675 case TBM_FORMAT_YUV422:
1676 case TBM_FORMAT_YVU422:
1680 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1681 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1685 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1686 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1690 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1691 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1694 case TBM_FORMAT_YUV444:
1695 case TBM_FORMAT_YVU444:
1697 align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1708 ret = SIZE_ALIGN( (width * height * bpp) >> 3, align);
1715 tbm_dumb_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1717 DUMB_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1718 DUMB_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1720 tbm_bo_handle bo_handle;
1721 memset (&bo_handle, 0x0, sizeof (uint64_t));
1723 tbm_bufmgr_dumb bufmgr_dumb = (tbm_bufmgr_dumb)tbm_backend_get_priv_from_bufmgr(bufmgr);
1727 case TBM_DEVICE_DEFAULT:
1730 //getting handle from fd
1731 struct drm_prime_handle arg = {0, };
1735 if (drmIoctl (bufmgr_dumb->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1737 TBM_DUMB_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1738 arg.fd, strerror(errno));
1739 return (tbm_bo_handle) NULL;
1742 bo_handle.u32 = (uint32_t)arg.handle;;
1745 case TBM_DEVICE_CPU:
1746 TBM_DUMB_LOG ("Not supported device:%d\n", device);
1747 bo_handle.ptr = (void *) NULL;
1751 bo_handle.u32 = (uint32_t)fd;
1754 TBM_DUMB_LOG ("error Not supported device:%d\n", device);
1755 bo_handle.ptr = (void *) NULL;
1763 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1765 static TBMModuleVersionInfo DumbVersRec =
1772 TBMModuleData tbmModuleData = { &DumbVersRec, init_tbm_bufmgr_priv};
1775 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1777 tbm_bufmgr_dumb bufmgr_dumb;
1778 tbm_bufmgr_backend bufmgr_backend;
1785 ret = drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &cap);
1786 if (ret || cap == 0) {
1787 TBM_DUMB_LOG ("error: drm buffer isn't supported !\n");
1791 bufmgr_dumb = calloc (1, sizeof(struct _tbm_bufmgr_dumb));
1794 TBM_DUMB_LOG ("error: Fail to alloc bufmgr_dumb!\n");
1800 bufmgr_dumb->fd = tbm_bufmgr_get_drm_fd_wayland();
1801 bufmgr_dumb->fd_owner = 1;
1804 bufmgr_dumb->fd = fd;
1806 if (bufmgr_dumb->fd < 0)
1808 TBM_DUMB_LOG ("error: Fail to create drm!\n");
1814 bufmgr_dumb->hashBos = drmHashCreate ();
1816 //Check if the tbm manager supports dma fence or not.
1817 int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1822 length = read(fp, buf, 1);
1824 if (length == 1 && buf[0] == '1')
1825 bufmgr_dumb->use_dma_fence = 1;
1830 bufmgr_backend = tbm_backend_alloc();
1831 if (!bufmgr_backend)
1833 TBM_DUMB_LOG ("error: Fail to create drm!\n");
1834 if (bufmgr_dumb->hashBos)
1835 drmHashDestroy (bufmgr_dumb->hashBos);
1837 if (bufmgr_dumb->fd_owner)
1838 close(bufmgr_dumb->fd);
1844 bufmgr_backend->priv = (void *)bufmgr_dumb;
1845 bufmgr_backend->bufmgr_deinit = tbm_dumb_bufmgr_deinit,
1846 bufmgr_backend->bo_size = tbm_dumb_bo_size,
1847 bufmgr_backend->bo_alloc = tbm_dumb_bo_alloc,
1848 bufmgr_backend->bo_free = tbm_dumb_bo_free,
1849 bufmgr_backend->bo_import = tbm_dumb_bo_import,
1850 bufmgr_backend->bo_import_fd = tbm_dumb_bo_import_fd,
1851 bufmgr_backend->bo_export = tbm_dumb_bo_export,
1852 bufmgr_backend->bo_export_fd = tbm_dumb_bo_export_fd,
1853 bufmgr_backend->bo_get_handle = tbm_dumb_bo_get_handle,
1854 bufmgr_backend->bo_map = tbm_dumb_bo_map,
1855 bufmgr_backend->bo_unmap = tbm_dumb_bo_unmap,
1856 bufmgr_backend->bo_cache_flush = tbm_dumb_bo_cache_flush,
1857 bufmgr_backend->bo_get_global_key = tbm_dumb_bo_get_global_key;
1858 bufmgr_backend->surface_get_plane_data = tbm_dumb_surface_get_plane_data;
1859 bufmgr_backend->surface_get_size = tbm_dumb_surface_get_size;
1860 bufmgr_backend->surface_supported_format = tbm_dumb_surface_supported_format;
1861 bufmgr_backend->fd_to_handle = tbm_dumb_fd_to_handle;
1862 bufmgr_backend->surface_get_num_bos = tbm_dumb_surface_get_num_bos;
1864 if (bufmgr_dumb->use_dma_fence)
1866 bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1867 bufmgr_backend->bo_lock = NULL;
1868 bufmgr_backend->bo_lock2 = tbm_dumb_bo_lock;
1869 bufmgr_backend->bo_unlock = tbm_dumb_bo_unlock;
1873 bufmgr_backend->flags = 0;
1874 bufmgr_backend->bo_lock = NULL;
1875 bufmgr_backend->bo_unlock = NULL;
1878 if (!tbm_backend_init (bufmgr, bufmgr_backend))
1880 TBM_DUMB_LOG ("error: Fail to init backend!\n");
1882 if (bufmgr_dumb->fd_owner)
1883 close(bufmgr_dumb->fd);
1885 tbm_backend_free (bufmgr_backend);
1893 env = getenv ("TBM_DUMB_DEBUG");
1896 bDebug = atoi (env);
1897 TBM_DUMB_LOG ("TBM_DUMB_DEBUG=%s\n", env);
1906 DBG ("[%s] DMABUF FENCE is %s\n", target_name(),
1907 bufmgr_dumb->use_dma_fence ? "supported!" : "NOT supported!");
1909 DBG ("[%s] drm_fd:%d\n", target_name(),