Add tbm_bo_get_flags backend function
[archive/platform/adaptation/samsung_exynos/libtbm-exynos4412.git] / src / tbm_bufmgr_exynos4412.c
1 /**************************************************************************
2
3 libtbm_exynos4412
4
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8
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:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
19 of the Software.
20
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.
28
29 **************************************************************************/
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <sys/ioctl.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42 #include <sys/mman.h>
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <errno.h>
46 #include <xf86drm.h>
47 #include <tbm_bufmgr.h>
48 #include <tbm_bufmgr_backend.h>
49 #include <exynos_drm.h>
50 #include <pthread.h>
51 #include <tbm_surface.h>
52 #include <tbm_surface_internal.h>
53
54 #define DEBUG
55 #define USE_DMAIMPORT
56 #define TBM_COLOR_FORMAT_COUNT 8
57
58 #ifdef DEBUG
59 #define LOG_TAG "TBM_BACKEND"
60 #include <dlog.h>
61 static int bDebug=0;
62
63 char* target_name()
64 {
65     FILE *f;
66     char *slash;
67     static int  initialized = 0;
68     static char app_name[128];
69
70     if ( initialized )
71         return app_name;
72
73     /* get the application name */
74     f = fopen("/proc/self/cmdline", "r");
75
76     if ( !f )
77     {
78         return 0;
79     }
80
81     memset(app_name, 0x00, sizeof(app_name));
82
83     if ( fgets(app_name, 100, f) == NULL )
84     {
85         fclose(f);
86         return 0;
87     }
88
89     fclose(f);
90
91     if ( (slash=strrchr(app_name, '/')) != NULL )
92     {
93         memmove(app_name, slash+1, strlen(slash));
94     }
95
96     initialized = 1;
97
98     return app_name;
99 }
100 #define TBM_EXYNOS4412_LOG(fmt, args...) LOGE("\033[31m"  "[%s]" fmt "\033[0m", target_name(), ##args)
101 #define DBG(fmt, args...)  if(bDebug&01) LOGE(fmt, ##args)
102 #else
103 #define TBM_EXYNOS4412_LOG(...)
104 #define DBG(...)
105 #endif
106
107 #define SIZE_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1))
108
109 #define TBM_SURFACE_ALIGNMENT_PLANE (64)
110 #define TBM_SURFACE_ALIGNMENT_PITCH_RGB (64)
111 #define TBM_SURFACE_ALIGNMENT_PITCH_YUV (16)
112
113
114 /* check condition */
115 #define EXYNOS4412_RETURN_IF_FAIL(cond) {\
116     if (!(cond)) {\
117         TBM_EXYNOS4412_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
118         return;\
119     }\
120 }
121 #define EXYNOS4412_RETURN_VAL_IF_FAIL(cond, val) {\
122     if (!(cond)) {\
123         TBM_EXYNOS4412_LOG ("[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
124         return val;\
125     }\
126 }
127
128 struct dma_buf_info {
129         unsigned long   size;
130         unsigned int    fence_supported;
131         unsigned int    padding;
132 };
133
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
138
139 #define DMA_FENCE_LIST_MAX              5
140
141 struct dma_buf_fence {
142         unsigned long           ctx;
143         unsigned int            type;
144 };
145
146 #define DMABUF_IOCTL_BASE       'F'
147 #define DMABUF_IOWR(nr, type)   _IOWR(DMABUF_IOCTL_BASE, nr, type)
148
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)
152
153 typedef struct _tbm_bufmgr_exynos4412 *tbm_bufmgr_exynos4412;
154 typedef struct _tbm_bo_exynos4412 *tbm_bo_exynos4412;
155
156 typedef struct _exynos4412_private
157 {
158     int ref_count;
159 } PrivGem;
160
161 /* tbm buffor object for exynos4412 */
162 struct _tbm_bo_exynos4412
163 {
164     int fd;
165
166     unsigned int name;    /* FLINK ID */
167
168     unsigned int gem;     /* GEM Handle */
169
170     unsigned int dmabuf;  /* fd for dmabuf */
171
172     void *pBase;          /* virtual address */
173
174     unsigned int size;
175
176     unsigned int flags_exynos;
177     unsigned int flags_tbm;
178
179     PrivGem* private;
180
181     pthread_mutex_t mutex;
182     struct dma_buf_fence dma_fence[DMA_FENCE_LIST_MAX];
183     int device;
184     int opt;
185 };
186
187 /* tbm bufmgr private for exynos4412 */
188 struct _tbm_bufmgr_exynos4412
189 {
190     int fd;
191     int isLocal;
192     void* hashBos;
193
194     int use_dma_fence;
195 };
196
197 char *STR_DEVICE[]=
198 {
199     "DEF",
200     "CPU",
201     "2D",
202     "3D",
203     "MM"
204 };
205
206 char *STR_OPT[]=
207 {
208     "NONE",
209     "RD",
210     "WR",
211     "RDWR"
212 };
213
214
215 uint32_t tbm_exynos4412_color_format_list[TBM_COLOR_FORMAT_COUNT] = {   TBM_FORMAT_RGBA8888,
216                                                                                                                                                 TBM_FORMAT_BGRA8888,
217                                                                                                                                                 TBM_FORMAT_RGBX8888,
218                                                                                                                                                 TBM_FORMAT_RGB888,
219                                                                                                                                                 TBM_FORMAT_NV12,
220                                                                                                                                                 TBM_FORMAT_NV21,
221                                                                                                                                                 TBM_FORMAT_YUV420,
222                                                                                                                                                 TBM_FORMAT_YVU420 };
223
224
225 static unsigned int
226 _get_exynos_flag_from_tbm (unsigned int ftbm)
227 {
228     unsigned int flags = 0;
229
230     if (ftbm & TBM_BO_SCANOUT)
231         flags |= EXYNOS_BO_CONTIG;
232     else
233         flags |= EXYNOS_BO_NONCONTIG;
234
235     if (ftbm & TBM_BO_WC)
236         flags |= EXYNOS_BO_WC;
237     else if (ftbm & TBM_BO_NONCACHABLE)
238         flags |= EXYNOS_BO_NONCACHABLE;
239     else
240         flags |= EXYNOS_BO_CACHABLE;
241
242     return flags;
243 }
244
245 static unsigned int
246 _get_tbm_flag_from_exynos (unsigned int fexynos)
247 {
248     unsigned int flags = 0;
249
250     if (fexynos & EXYNOS_BO_NONCONTIG)
251         flags |= TBM_BO_DEFAULT;
252     else
253         flags |= TBM_BO_SCANOUT;
254
255     if (fexynos & EXYNOS_BO_WC)
256         flags |= TBM_BO_WC;
257     else if (fexynos & EXYNOS_BO_CACHABLE)
258         flags |= TBM_BO_DEFAULT;
259     else
260         flags |= TBM_BO_NONCACHABLE;
261
262     return flags;
263 }
264
265 static unsigned int
266 _get_name (int fd, unsigned int gem)
267 {
268     struct drm_gem_flink arg = {0,};
269
270     arg.handle = gem;
271     if (drmIoctl (fd, DRM_IOCTL_GEM_FLINK, &arg))
272     {
273         TBM_EXYNOS4412_LOG ("error fail to get flink from gem:%d (DRM_IOCTL_GEM_FLINK)\n",
274                 gem);
275         return 0;
276     }
277
278     return (unsigned int)arg.name;
279 }
280
281 static tbm_bo_handle
282 _exynos4412_bo_handle (tbm_bo_exynos4412 bo_exynos4412, int device)
283 {
284     tbm_bo_handle bo_handle;
285     memset (&bo_handle, 0x0, sizeof (uint64_t));
286
287     switch(device)
288     {
289     case TBM_DEVICE_DEFAULT:
290     case TBM_DEVICE_2D:
291         bo_handle.u32 = (uint32_t)bo_exynos4412->gem;
292         break;
293     case TBM_DEVICE_CPU:
294         if (!bo_exynos4412->pBase)
295         {
296             struct drm_mode_map_dumb arg = {0,};
297             void *map = NULL;
298
299             arg.handle = bo_exynos4412->gem;
300             if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg))
301             {
302                TBM_EXYNOS4412_LOG ("error Cannot map_dumb gem=%d\n", bo_exynos4412->gem);
303                return (tbm_bo_handle) NULL;
304             }
305
306             map = mmap (NULL, bo_exynos4412->size, PROT_READ|PROT_WRITE, MAP_SHARED,
307                               bo_exynos4412->fd, arg.offset);
308             if (map == MAP_FAILED)
309             {
310                 TBM_EXYNOS4412_LOG ("error Cannot usrptr gem=%d\n", bo_exynos4412->gem);
311                 return (tbm_bo_handle) NULL;
312             }
313             bo_exynos4412->pBase = map;
314         }
315         bo_handle.ptr = (void *)bo_exynos4412->pBase;
316         break;
317     case TBM_DEVICE_3D:
318 #ifdef USE_DMAIMPORT
319         if (bo_exynos4412->dmabuf)
320         {
321             bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
322             break;
323         }
324
325         if (!bo_exynos4412->dmabuf)
326         {
327             struct drm_prime_handle arg = {0, };
328
329             arg.handle = bo_exynos4412->gem;
330             if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
331             {
332                 TBM_EXYNOS4412_LOG ("error Cannot dmabuf=%d\n", bo_exynos4412->gem);
333                 return (tbm_bo_handle) NULL;
334             }
335             bo_exynos4412->dmabuf = arg.fd;
336         }
337
338         bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
339 #endif
340         break;
341     case TBM_DEVICE_MM:
342         if (!bo_exynos4412->dmabuf)
343         {
344             struct drm_prime_handle arg = {0, };
345
346             arg.handle = bo_exynos4412->gem;
347             if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
348             {
349                 TBM_EXYNOS4412_LOG ("error Cannot dmabuf=%d\n", bo_exynos4412->gem);
350                 return (tbm_bo_handle) NULL;
351             }
352             bo_exynos4412->dmabuf = arg.fd;
353         }
354
355         bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
356         break;
357     default:
358         TBM_EXYNOS4412_LOG ("error Not supported device:%d\n", device);
359         bo_handle.ptr = (void *) NULL;
360         break;
361     }
362
363     return bo_handle;
364 }
365
366 static int
367 _exynos4412_cache_flush (int fd, tbm_bo_exynos4412 bo_exynos4412, int flags)
368 {
369 #ifdef ENABLE_CACHECRTL
370     struct drm_exynos_gem_cache_op cache_op = {0, };
371     int ret;
372
373     /* if bo_exynos4412 is null, do cache_flush_all */
374     if(bo_exynos4412)
375     {
376         cache_op.flags = 0;
377         cache_op.usr_addr = (uint64_t)((uint32_t)bo_exynos4412->pBase);
378         cache_op.size = bo_exynos4412->size;
379     }
380     else
381     {
382         flags = TBM_CACHE_FLUSH_ALL;
383         cache_op.flags = 0;
384         cache_op.usr_addr = 0;
385         cache_op.size = 0;
386     }
387
388     if (flags & TBM_CACHE_INV)
389     {
390         if(flags & TBM_CACHE_ALL)
391             cache_op.flags |= EXYNOS_DRM_CACHE_INV_ALL;
392         else
393             cache_op.flags |= EXYNOS_DRM_CACHE_INV_RANGE;
394     }
395
396     if (flags & TBM_CACHE_CLN)
397     {
398         if(flags & TBM_CACHE_ALL)
399             cache_op.flags |= EXYNOS_DRM_CACHE_CLN_ALL;
400         else
401             cache_op.flags |= EXYNOS_DRM_CACHE_CLN_RANGE;
402     }
403
404     if(flags & TBM_CACHE_ALL)
405         cache_op.flags |= EXYNOS_DRM_ALL_CACHES_CORES;
406
407     ret = drmCommandWriteRead (fd, DRM_EXYNOS_GEM_CACHE_OP, &cache_op, sizeof(cache_op));
408     if (ret)
409     {
410         TBM_EXYNOS4412_LOG ("error fail to flush the cache.\n");
411         return 0;
412     }
413 #else
414     TBM_EXYNOS4412_LOG ("warning fail to enable the cache flush.\n");
415 #endif
416     return 1;
417 }
418
419 static int
420 tbm_exynos4412_bo_size (tbm_bo bo)
421 {
422     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
423
424     tbm_bo_exynos4412 bo_exynos4412;
425
426     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
427
428     return bo_exynos4412->size;
429 }
430
431 static void *
432 tbm_exynos4412_bo_alloc (tbm_bo bo, int size, int flags)
433 {
434     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
435
436     tbm_bo_exynos4412 bo_exynos4412;
437     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
438     unsigned int exynos_flags;
439
440     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
441     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
442
443     bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
444     if (!bo_exynos4412)
445     {
446         TBM_EXYNOS4412_LOG ("error fail to allocate the bo private\n");
447         return 0;
448     }
449
450     exynos_flags = _get_exynos_flag_from_tbm (flags);
451     if((flags & TBM_BO_SCANOUT) &&
452         size <= 4*1024)
453     {
454         exynos_flags |= EXYNOS_BO_NONCONTIG;
455     }
456
457     struct drm_exynos_gem_create arg = {0, };
458     arg.size = size;
459     arg.flags = exynos_flags;
460     if (drmCommandWriteRead(bufmgr_exynos4412->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg)))
461     {
462         TBM_EXYNOS4412_LOG ("error Cannot create bo(flag:%x, size:%d)\n", arg.flags, (unsigned int)arg.size);
463         free (bo_exynos4412);
464         return 0;
465     }
466
467     bo_exynos4412->fd = bufmgr_exynos4412->fd;
468     bo_exynos4412->gem = arg.handle;
469     bo_exynos4412->size = size;
470     bo_exynos4412->flags_tbm = flags;
471     bo_exynos4412->flags_exynos = exynos_flags;
472     bo_exynos4412->name = _get_name (bo_exynos4412->fd, bo_exynos4412->gem);
473
474     pthread_mutex_init(&bo_exynos4412->mutex, NULL);
475
476     if (bufmgr_exynos4412->use_dma_fence
477         && !bo_exynos4412->dmabuf)
478     {
479         struct drm_prime_handle arg = {0, };
480
481         arg.handle = bo_exynos4412->gem;
482         if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
483         {
484             TBM_EXYNOS4412_LOG ("error Cannot dmabuf=%d\n", bo_exynos4412->gem);
485             free (bo_exynos4412);
486             return 0;
487         }
488         bo_exynos4412->dmabuf = arg.fd;
489     }
490
491     /* add bo to hash */
492     PrivGem* privGem = calloc (1, sizeof(PrivGem));
493     if (!privGem)
494     {
495         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
496                 "error %s:%d Fail to calloc privGem\n",
497                 getpid(), __FUNCTION__, __LINE__);
498         free (bo_exynos4412);
499         return 0;
500     }
501
502     privGem->ref_count = 1;
503     if (drmHashInsert(bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
504     {
505         TBM_EXYNOS4412_LOG ("error Cannot insert bo to Hash(%d)\n", bo_exynos4412->name);
506     }
507
508     DBG ("     [%s] bo:%p, gem:%d(%d), flags:%d(%d), size:%d\n", target_name(),
509          bo,
510          bo_exynos4412->gem, bo_exynos4412->name,
511          flags, exynos_flags,
512          bo_exynos4412->size);
513
514     return (void *)bo_exynos4412;
515 }
516
517 static void
518 tbm_exynos4412_bo_free(tbm_bo bo)
519 {
520     tbm_bo_exynos4412 bo_exynos4412;
521     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
522
523     if (!bo)
524         return;
525
526     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
527     EXYNOS4412_RETURN_IF_FAIL (bufmgr_exynos4412!=NULL);
528
529     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
530     EXYNOS4412_RETURN_IF_FAIL (bo_exynos4412!=NULL);
531
532     DBG ("      [%s] bo:%p, gem:%d(%d), fd:%d, size:%d\n",target_name(),
533          bo,
534          bo_exynos4412->gem, bo_exynos4412->name,
535          bo_exynos4412->dmabuf,
536          bo_exynos4412->size);
537
538     if (bo_exynos4412->pBase)
539     {
540         if (munmap(bo_exynos4412->pBase, bo_exynos4412->size) == -1)
541         {
542             TBM_EXYNOS4412_LOG ("error bo:%p fail to munmap(%s)\n",
543                 bo, strerror(errno));
544         }
545     }
546
547     /* close dmabuf */
548     if (bo_exynos4412->dmabuf)
549     {
550         close (bo_exynos4412->dmabuf);
551         bo_exynos4412->dmabuf = 0;
552     }
553
554     /* delete bo from hash */
555     PrivGem *privGem = NULL;
556     int ret;
557
558     ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
559     if (ret == 0)
560     {
561         privGem->ref_count--;
562         if (privGem->ref_count == 0)
563         {
564             drmHashDelete (bufmgr_exynos4412->hashBos, bo_exynos4412->name);
565             free (privGem);
566             privGem = NULL;
567         }
568     }
569     else
570     {
571         TBM_EXYNOS4412_LOG ("warning Cannot find bo to Hash(%d), ret=%d\n", bo_exynos4412->name, ret);
572     }
573
574     /* Free gem handle */
575     struct drm_gem_close arg = {0, };
576     memset (&arg, 0, sizeof(arg));
577     arg.handle = bo_exynos4412->gem;
578     if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_GEM_CLOSE, &arg))
579     {
580         TBM_EXYNOS4412_LOG ("error bo:%p fail to gem close.(%s)\n",
581             bo, strerror(errno));
582     }
583
584     free (bo_exynos4412);
585 }
586
587
588 static void *
589 tbm_exynos4412_bo_import (tbm_bo bo, unsigned int key)
590 {
591     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
592
593     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
594     tbm_bo_exynos4412 bo_exynos4412;
595
596     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
597     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
598
599     struct drm_gem_open arg = {0, };
600     struct drm_exynos_gem_info info = {0, };
601
602     arg.name = key;
603     if (drmIoctl(bufmgr_exynos4412->fd, DRM_IOCTL_GEM_OPEN, &arg))
604     {
605         TBM_EXYNOS4412_LOG ("error Cannot open gem name=%d\n", key);
606         return 0;
607     }
608
609     info.handle = arg.handle;
610     if (drmCommandWriteRead(bufmgr_exynos4412->fd,
611                            DRM_EXYNOS_GEM_GET,
612                            &info,
613                            sizeof(struct drm_exynos_gem_info)))
614     {
615         TBM_EXYNOS4412_LOG ("error Cannot get gem info=%d\n", key);
616         return 0;
617     }
618
619     bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
620     if (!bo_exynos4412)
621     {
622         TBM_EXYNOS4412_LOG ("error fail to allocate the bo private\n");
623         return 0;
624     }
625
626     bo_exynos4412->fd = bufmgr_exynos4412->fd;
627     bo_exynos4412->gem = arg.handle;
628     bo_exynos4412->size = arg.size;
629     bo_exynos4412->flags_exynos = info.flags;
630     bo_exynos4412->name = key;
631     bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
632
633     if (!bo_exynos4412->dmabuf)
634     {
635         struct drm_prime_handle arg = {0, };
636
637         arg.handle = bo_exynos4412->gem;
638         if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
639         {
640             TBM_EXYNOS4412_LOG ("error Cannot dmabuf=%d\n", bo_exynos4412->gem);
641             free (bo_exynos4412);
642             return 0;
643         }
644         bo_exynos4412->dmabuf = arg.fd;
645     }
646
647     /* add bo to hash */
648     PrivGem *privGem = NULL;
649     int ret;
650
651     ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
652     if (ret == 0)
653     {
654         privGem->ref_count++;
655     }
656     else if (ret == 1)
657     {
658         privGem = calloc (1, sizeof(PrivGem));
659         if (!privGem)
660         {
661             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
662                     "error %s:%d Fail to calloc privGem\n",
663                     getpid(), __FUNCTION__, __LINE__);
664             free (bo_exynos4412);
665             return 0;
666         }
667
668         privGem->ref_count = 1;
669         if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
670         {
671             TBM_EXYNOS4412_LOG ("error Cannot insert bo to Hash(%d)\n", bo_exynos4412->name);
672         }
673     }
674     else
675     {
676         TBM_EXYNOS4412_LOG ("error Cannot insert bo to Hash(%d)\n", bo_exynos4412->name);
677     }
678
679     DBG ("    [%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", target_name(),
680          bo,
681          bo_exynos4412->gem, bo_exynos4412->name,
682          bo_exynos4412->dmabuf,
683          bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
684          bo_exynos4412->size);
685
686     return (void *)bo_exynos4412;
687 }
688
689 static void *
690 tbm_exynos4412_bo_import_fd (tbm_bo bo, tbm_fd key)
691 {
692     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
693
694     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
695     tbm_bo_exynos4412 bo_exynos4412;
696
697     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
698     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
699
700     unsigned int gem = 0;
701     unsigned int real_size = -1;
702     struct drm_exynos_gem_info info = {0, };
703
704         //getting handle from fd
705     struct drm_prime_handle arg = {0, };
706
707         arg.fd = key;
708         arg.flags = 0;
709     if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
710     {
711         TBM_EXYNOS4412_LOG ("error bo:%p Cannot get gem handle from fd:%d (%s)\n",
712                  bo, arg.fd, strerror(errno));
713         return NULL;
714     }
715     gem = arg.handle;
716
717         /* Determine size of bo.  The fd-to-handle ioctl really should
718          * return the size, but it doesn't.  If we have kernel 3.12 or
719          * later, we can lseek on the prime fd to get the size.  Older
720          * kernels will just fail, in which case we fall back to the
721          * provided (estimated or guess size). */
722         real_size = lseek(key, 0, SEEK_END);
723
724     info.handle = gem;
725     if (drmCommandWriteRead(bufmgr_exynos4412->fd,
726                            DRM_EXYNOS_GEM_GET,
727                            &info,
728                            sizeof(struct drm_exynos_gem_info)))
729     {
730         TBM_EXYNOS4412_LOG ("error bo:%p Cannot get gem info from gem:%d, fd:%d (%s)\n",
731                 bo, gem, key, strerror(errno));
732         return 0;
733     }
734
735     if (real_size == -1)
736         real_size = info.size;
737
738     bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
739     if (!bo_exynos4412)
740     {
741         TBM_EXYNOS4412_LOG ("error bo:%p fail to allocate the bo private\n", bo);
742         return 0;
743     }
744
745     bo_exynos4412->fd = bufmgr_exynos4412->fd;
746     bo_exynos4412->gem = gem;
747     bo_exynos4412->size = real_size;
748     bo_exynos4412->flags_exynos = info.flags;
749     bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
750
751     bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
752     if (!bo_exynos4412->name)
753     {
754         TBM_EXYNOS4412_LOG ("error bo:%p Cannot get name from gem:%d, fd:%d (%s)\n",
755             bo, gem, key, strerror(errno));
756         free (bo_exynos4412);
757         return 0;
758     }
759
760     /* add bo to hash */
761     PrivGem *privGem = NULL;
762     int ret;
763
764     ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
765     if (ret == 0)
766     {
767         privGem->ref_count++;
768     }
769     else if (ret == 1)
770     {
771         privGem = calloc (1, sizeof(PrivGem));
772         if (!privGem)
773         {
774             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
775                     "error %s:%d Fail to calloc privGem\n",
776                     getpid(), __FUNCTION__, __LINE__);
777             free (bo_exynos4412);
778             return 0;
779         }
780
781         privGem->ref_count = 1;
782         if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
783         {
784             TBM_EXYNOS4412_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
785                 bo, bo_exynos4412->name, gem, key);
786         }
787     }
788     else
789     {
790         TBM_EXYNOS4412_LOG ("error bo:%p Cannot insert bo to Hash(%d) from gem:%d, fd:%d\n",
791                 bo, bo_exynos4412->name, gem, key);
792     }
793
794     DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
795          bo,
796          bo_exynos4412->gem, bo_exynos4412->name,
797          bo_exynos4412->dmabuf,
798          key,
799          bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
800          bo_exynos4412->size);
801
802     return (void *)bo_exynos4412;
803 }
804
805 static unsigned int
806 tbm_exynos4412_bo_export (tbm_bo bo)
807 {
808     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
809
810     tbm_bo_exynos4412 bo_exynos4412;
811
812     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
813     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
814
815     if (!bo_exynos4412->name)
816     {
817         bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
818         if (!bo_exynos4412->name)
819         {
820             TBM_EXYNOS4412_LOG ("error Cannot get name\n");
821             return 0;
822         }
823     }
824
825     DBG ("    [%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d\n", target_name(),
826          bo,
827          bo_exynos4412->gem, bo_exynos4412->name,
828          bo_exynos4412->dmabuf,
829          bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
830          bo_exynos4412->size);
831
832     return (unsigned int)bo_exynos4412->name;
833 }
834
835 tbm_fd
836 tbm_exynos4412_bo_export_fd (tbm_bo bo)
837 {
838     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
839
840     tbm_bo_exynos4412 bo_exynos4412;
841
842     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
843     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
844
845     struct drm_prime_handle arg = {0, };
846
847     arg.handle = bo_exynos4412->gem;
848     if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
849     {
850         TBM_EXYNOS4412_LOG ("error bo:%p Cannot dmabuf=%d (%s)\n",
851             bo, bo_exynos4412->gem, strerror(errno));
852         return (tbm_fd) 0;
853     }
854
855     DBG (" [%s] bo:%p, gem:%d(%d), fd:%d, key_fd:%d, flags:%d(%d), size:%d\n", target_name(),
856          bo,
857          bo_exynos4412->gem, bo_exynos4412->name,
858          bo_exynos4412->dmabuf,
859          arg.fd,
860          bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
861          bo_exynos4412->size);
862
863     return (tbm_fd)arg.fd;
864 }
865
866 static tbm_bo_handle
867 tbm_exynos4412_bo_get_handle (tbm_bo bo, int device)
868 {
869     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
870
871     tbm_bo_handle bo_handle;
872     tbm_bo_exynos4412 bo_exynos4412;
873
874     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
875     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
876
877     if (!bo_exynos4412->gem)
878     {
879         TBM_EXYNOS4412_LOG ("error Cannot map gem=%d\n", bo_exynos4412->gem);
880         return (tbm_bo_handle) NULL;
881     }
882
883     DBG ("[%s] bo:%p, gem:%d(%d), fd:%d, flags:%d(%d), size:%d, %s\n", target_name(),
884          bo,
885          bo_exynos4412->gem, bo_exynos4412->name,
886          bo_exynos4412->dmabuf,
887          bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos,
888          bo_exynos4412->size,
889          STR_DEVICE[device]);
890
891     /*Get mapped bo_handle*/
892     bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
893     if (bo_handle.ptr == NULL)
894     {
895         TBM_EXYNOS4412_LOG ("error Cannot get handle: gem:%d, device:%d\n", bo_exynos4412->gem, device);
896         return (tbm_bo_handle) NULL;
897     }
898
899     return bo_handle;
900 }
901
902 static tbm_bo_handle
903 tbm_exynos4412_bo_map (tbm_bo bo, int device, int opt)
904 {
905     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
906
907     tbm_bo_handle bo_handle;
908     tbm_bo_exynos4412 bo_exynos4412;
909
910     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
911     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
912
913     if (!bo_exynos4412->gem)
914     {
915         TBM_EXYNOS4412_LOG ("error Cannot map gem=%d\n", bo_exynos4412->gem);
916         return (tbm_bo_handle) NULL;
917     }
918
919     DBG ("       [%s] bo:%p, gem:%d(%d), fd:%d, %s, %s\n", target_name(),
920          bo,
921          bo_exynos4412->gem, bo_exynos4412->name,
922          bo_exynos4412->dmabuf,
923          STR_DEVICE[device],
924          STR_OPT[opt]);
925
926     /*Get mapped bo_handle*/
927     bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
928     if (bo_handle.ptr == NULL)
929     {
930         TBM_EXYNOS4412_LOG ("error Cannot get handle: gem:%d, device:%d, opt:%d\n", bo_exynos4412->gem, device, opt);
931         return (tbm_bo_handle) NULL;
932     }
933
934     return bo_handle;
935 }
936
937 static int
938 tbm_exynos4412_bo_unmap (tbm_bo bo)
939 {
940     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
941
942     tbm_bo_exynos4412 bo_exynos4412;
943
944     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
945     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
946
947     if (!bo_exynos4412->gem)
948         return 0;
949
950     DBG ("     [%s] bo:%p, gem:%d(%d), fd:%d\n", target_name(),
951           bo,
952           bo_exynos4412->gem, bo_exynos4412->name,
953           bo_exynos4412->dmabuf);
954
955     return 1;
956 }
957
958 static int
959 tbm_exynos4412_bo_cache_flush (tbm_bo bo, int flags)
960 {
961     tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
962     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
963
964     /* cache flush is managed by kernel side when using dma-fence. */
965     if (bufmgr_exynos4412->use_dma_fence)
966        return 1;
967
968     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
969
970     tbm_bo_exynos4412 bo_exynos4412;
971
972     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
973     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
974
975     if (!_exynos4412_cache_flush(bo_exynos4412->fd, bo_exynos4412, flags))
976         return 0;
977
978     return 1;
979 }
980
981 static int
982 tbm_exynos4412_bo_get_global_key (tbm_bo bo)
983 {
984     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
985
986     tbm_bo_exynos4412 bo_exynos4412;
987
988     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
989     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
990
991     if (!bo_exynos4412->name)
992     {
993         if (!bo_exynos4412->gem)
994             return 0;
995
996         bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
997     }
998
999     return bo_exynos4412->name;
1000 }
1001
1002 static int
1003 tbm_exynos4412_bo_lock(tbm_bo bo, int device, int opt)
1004 {
1005     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1006
1007     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1008     tbm_bo_exynos4412 bo_exynos4412;
1009     struct dma_buf_fence fence;
1010     struct flock filelock;
1011     int ret=0;
1012
1013     if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU)
1014     {
1015         DBG ("[libtbm-exynos4412:%d] %s not support device type,\n", getpid(), __FUNCTION__);
1016             return 0;
1017     }
1018
1019     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1020     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1021
1022     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
1023     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
1024
1025     memset(&fence, 0, sizeof(struct dma_buf_fence));
1026
1027     /* Check if the given type is valid or not. */
1028     if (opt & TBM_OPTION_WRITE)
1029     {
1030         if (device == TBM_DEVICE_3D)
1031             fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1032     }
1033     else if (opt & TBM_OPTION_READ)
1034     {
1035         if (device == TBM_DEVICE_3D)
1036             fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1037     }
1038     else
1039     {
1040         TBM_EXYNOS4412_LOG ("error Invalid argument\n");
1041         return 0;
1042     }
1043
1044     /* Check if the tbm manager supports dma fence or not. */
1045     if (!bufmgr_exynos4412->use_dma_fence)
1046     {
1047         TBM_EXYNOS4412_LOG ("error Not support DMA FENCE(%s)\n", strerror(errno) );
1048         return 0;
1049
1050     }
1051
1052     if (device == TBM_DEVICE_3D)
1053     {
1054         ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1055         if (ret < 0)
1056         {
1057             TBM_EXYNOS4412_LOG ("error Cannot set GET FENCE(%s)\n", strerror(errno) );
1058             return 0;
1059         }
1060     } else
1061     {
1062         if (opt & TBM_OPTION_WRITE)
1063             filelock.l_type = F_WRLCK;
1064         else
1065             filelock.l_type = F_RDLCK;
1066
1067         filelock.l_whence = SEEK_CUR;
1068         filelock.l_start = 0;
1069         filelock.l_len = 0;
1070
1071         if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1072         {
1073             return 0;
1074         }
1075     }
1076
1077     pthread_mutex_lock(&bo_exynos4412->mutex);
1078
1079     if (device == TBM_DEVICE_3D)
1080     {
1081         int i;
1082         for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1083         {
1084             if (bo_exynos4412->dma_fence[i].ctx == 0)
1085             {
1086                 bo_exynos4412->dma_fence[i].type = fence.type;
1087                 bo_exynos4412->dma_fence[i].ctx = fence.ctx;
1088                 break;
1089             }
1090         }
1091
1092         if (i == DMA_FENCE_LIST_MAX)
1093         {
1094             //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1095             TBM_EXYNOS4412_LOG ("error fence list is full\n");
1096         }
1097     }
1098
1099     pthread_mutex_unlock(&bo_exynos4412->mutex);
1100
1101     DBG ("[%s] DMABUF_IOCTL_GET_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(),
1102           bo,
1103           bo_exynos4412->gem, bo_exynos4412->name,
1104           bo_exynos4412->dmabuf);
1105
1106     return 1;
1107 }
1108
1109 static int
1110 tbm_exynos4412_bo_unlock(tbm_bo bo)
1111 {
1112     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1113
1114     tbm_bo_exynos4412 bo_exynos4412;
1115     struct dma_buf_fence fence;
1116     struct flock filelock;
1117     unsigned int dma_type = 0;
1118     int ret=0;
1119
1120     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1121     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1122
1123     if (bo_exynos4412->dma_fence[0].type & DMA_BUF_ACCESS_DMA)
1124             dma_type = 1;
1125
1126     if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1127     {
1128         DBG ("[libtbm-exynos4412:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1129         return 0;
1130     }
1131
1132     if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1133     {
1134         DBG ("[libtbm-exynos4412:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1135         return 0;
1136     }
1137
1138     pthread_mutex_lock(&bo_exynos4412->mutex);
1139
1140     if (dma_type)
1141     {
1142         fence.type = bo_exynos4412->dma_fence[0].type;
1143         fence.ctx = bo_exynos4412->dma_fence[0].ctx;
1144         int i;
1145         for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1146         {
1147             bo_exynos4412->dma_fence[i-1].type = bo_exynos4412->dma_fence[i].type;
1148             bo_exynos4412->dma_fence[i-1].ctx = bo_exynos4412->dma_fence[i].ctx;
1149         }
1150         bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1151         bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1152     }
1153     pthread_mutex_unlock(&bo_exynos4412->mutex);
1154
1155     if (dma_type)
1156     {
1157         ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1158         if (ret < 0)
1159         {
1160             TBM_EXYNOS4412_LOG ("error Can not set PUT FENCE(%s)\n", strerror(errno));
1161             return 0;
1162         }
1163     } else
1164     {
1165         filelock.l_type = F_UNLCK;
1166         filelock.l_whence = SEEK_CUR;
1167         filelock.l_start = 0;
1168         filelock.l_len = 0;
1169
1170         if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1171         {
1172             return 0;
1173         }
1174     }
1175
1176     DBG ("[%s] DMABUF_IOCTL_PUT_FENCE! bo:%p, gem:%d(%d), fd:%ds\n", target_name(),
1177           bo,
1178           bo_exynos4412->gem, bo_exynos4412->name,
1179           bo_exynos4412->dmabuf);
1180
1181     return 1;
1182 }
1183
1184 static void
1185 tbm_exynos4412_bufmgr_deinit (void *priv)
1186 {
1187     EXYNOS4412_RETURN_IF_FAIL (priv!=NULL);
1188
1189     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1190
1191     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)priv;
1192
1193     if (bufmgr_exynos4412->hashBos)
1194     {
1195         unsigned long key;
1196         void *value;
1197
1198         while (drmHashFirst(bufmgr_exynos4412->hashBos, &key, &value) > 0)
1199         {
1200             free (value);
1201             drmHashDelete (bufmgr_exynos4412->hashBos, key);
1202         }
1203
1204         drmHashDestroy (bufmgr_exynos4412->hashBos);
1205         bufmgr_exynos4412->hashBos = NULL;
1206     }
1207
1208     free (bufmgr_exynos4412);
1209 }
1210
1211 int
1212 tbm_exynos4412_surface_supported_format(uint32_t **formats, uint32_t *num)
1213 {
1214     uint32_t* color_formats=NULL;
1215
1216     color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1217
1218     if( color_formats == NULL )
1219     {
1220         return 0;
1221     }
1222     memcpy( color_formats, tbm_exynos4412_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1223
1224
1225     *formats = color_formats;
1226     *num = TBM_COLOR_FORMAT_COUNT;
1227
1228     fprintf (stderr, "tbm_exynos4412_surface_supported_format  count = %d \n",*num);
1229
1230     return 1;
1231 }
1232
1233
1234 /**
1235  * @brief get the plane data of the surface.
1236  * @param[in] surface : the surface
1237  * @param[in] width : the width of the surface
1238  * @param[in] height : the height of the surface
1239  * @param[in] format : the format of the surface
1240  * @param[in] plane_idx : the format of the surface
1241  * @param[out] size : the size of the plane
1242  * @param[out] offset : the offset of the plane
1243  * @param[out] pitch : the pitch of the plane
1244  * @param[out] padding : the padding of the plane
1245  * @return 1 if this function succeeds, otherwise 0.
1246  */
1247 int
1248 tbm_exynos4412_surface_get_plane_data(tbm_surface_h surface, int width, int height, tbm_format format, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
1249 {
1250     int ret = 1;
1251     int bpp;
1252     int _offset =0;
1253     int _pitch =0;
1254     int _size =0;
1255     int _bo_idx = 0;
1256
1257     switch(format)
1258     {
1259         /* 16 bpp RGB */
1260         case TBM_FORMAT_XRGB4444:
1261         case TBM_FORMAT_XBGR4444:
1262         case TBM_FORMAT_RGBX4444:
1263         case TBM_FORMAT_BGRX4444:
1264         case TBM_FORMAT_ARGB4444:
1265         case TBM_FORMAT_ABGR4444:
1266         case TBM_FORMAT_RGBA4444:
1267         case TBM_FORMAT_BGRA4444:
1268         case TBM_FORMAT_XRGB1555:
1269         case TBM_FORMAT_XBGR1555:
1270         case TBM_FORMAT_RGBX5551:
1271         case TBM_FORMAT_BGRX5551:
1272         case TBM_FORMAT_ARGB1555:
1273         case TBM_FORMAT_ABGR1555:
1274         case TBM_FORMAT_RGBA5551:
1275         case TBM_FORMAT_BGRA5551:
1276         case TBM_FORMAT_RGB565:
1277             bpp = 16;
1278             _offset = 0;
1279                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1280             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1281             _bo_idx = 0;
1282             break;
1283         /* 24 bpp RGB */
1284         case TBM_FORMAT_RGB888:
1285         case TBM_FORMAT_BGR888:
1286             bpp = 24;
1287             _offset = 0;
1288                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1289             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1290             _bo_idx = 0;
1291             break;
1292         /* 32 bpp RGB */
1293         case TBM_FORMAT_XRGB8888:
1294         case TBM_FORMAT_XBGR8888:
1295         case TBM_FORMAT_RGBX8888:
1296         case TBM_FORMAT_BGRX8888:
1297         case TBM_FORMAT_ARGB8888:
1298         case TBM_FORMAT_ABGR8888:
1299         case TBM_FORMAT_RGBA8888:
1300         case TBM_FORMAT_BGRA8888:
1301             bpp = 32;
1302             _offset = 0;
1303                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1304             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1305             _bo_idx = 0;
1306             break;
1307
1308         /* packed YCbCr */
1309         case TBM_FORMAT_YUYV:
1310         case TBM_FORMAT_YVYU:
1311         case TBM_FORMAT_UYVY:
1312         case TBM_FORMAT_VYUY:
1313         case TBM_FORMAT_AYUV:
1314             bpp = 32;
1315             _offset = 0;
1316                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1317             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1318             _bo_idx = 0;
1319             break;
1320
1321         /*
1322         * 2 plane YCbCr
1323         * index 0 = Y plane, [7:0] Y
1324         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1325         * or
1326         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1327         */
1328         case TBM_FORMAT_NV12:
1329             bpp = 12;
1330             if(plane_idx == 0)
1331             {
1332                 _offset = 0;
1333                                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1334                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1335                 _bo_idx = 0;
1336             }
1337             else if( plane_idx ==1 )
1338             {
1339                 _offset = 0;
1340                                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1341                                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1342                 _bo_idx = 1;
1343             }
1344             break;
1345         case TBM_FORMAT_NV21:
1346             bpp = 12;
1347             if(plane_idx == 0)
1348             {
1349                 _offset = 0;
1350                                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1351                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1352                 _bo_idx = 0;
1353             }
1354             else if( plane_idx ==1 )
1355             {
1356                 _offset = width*height;
1357                                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1358                                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1359                 _bo_idx = 0;
1360             }
1361             break;
1362
1363         case TBM_FORMAT_NV16:
1364         case TBM_FORMAT_NV61:
1365                         bpp = 16;
1366             //if(plane_idx == 0)
1367             {
1368                 _offset = 0;
1369                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1370                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1371                 _bo_idx = 0;
1372                 if(plane_idx == 0)
1373                         break;
1374             }
1375             //else if( plane_idx ==1 )
1376             {
1377                 _offset += _size;
1378                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1379                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1380                 _bo_idx = 0;
1381             }
1382             break;
1383
1384         /*
1385         * 3 plane YCbCr
1386         * index 0: Y plane, [7:0] Y
1387         * index 1: Cb plane, [7:0] Cb
1388         * index 2: Cr plane, [7:0] Cr
1389         * or
1390         * index 1: Cr plane, [7:0] Cr
1391         * index 2: Cb plane, [7:0] Cb
1392         */
1393         /*
1394         NATIVE_BUFFER_FORMAT_YV12
1395         NATIVE_BUFFER_FORMAT_I420
1396         */
1397         case TBM_FORMAT_YUV410:
1398         case TBM_FORMAT_YVU410:
1399             bpp = 9;
1400             _bo_idx = 0;
1401             break;
1402         case TBM_FORMAT_YUV411:
1403         case TBM_FORMAT_YVU411:
1404         case TBM_FORMAT_YUV420:
1405         case TBM_FORMAT_YVU420:
1406             bpp = 12;
1407             //if(plane_idx == 0)
1408             {
1409                 _offset = 0;
1410                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1411                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1412                 _bo_idx = 0;
1413                         if(plane_idx == 0)
1414                                 break;
1415             }
1416             //else if( plane_idx == 1 )
1417             {
1418                 _offset += _size;
1419                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1420                         _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1421                 _bo_idx = 0;
1422                         if(plane_idx == 1)
1423                                 break;
1424             }
1425             //else if (plane_idx == 2 )
1426             {
1427                 _offset += _size;
1428                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1429                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1430                 _bo_idx = 0;
1431             }
1432             break;
1433         case TBM_FORMAT_YUV422:
1434         case TBM_FORMAT_YVU422:
1435             bpp = 16;
1436             //if(plane_idx == 0)
1437             {
1438                 _offset = 0;
1439                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1440                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1441                 _bo_idx = 0;
1442                         if(plane_idx == 0)
1443                                 break;
1444             }
1445             //else if( plane_idx == 1 )
1446             {
1447                 _offset += _size;
1448                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1449                         _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1450                 _bo_idx = 0;
1451                         if(plane_idx == 1)
1452                                 break;
1453             }
1454             //else if (plane_idx == 2 )
1455             {
1456                 _offset += _size;
1457                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1458                 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1459                 _bo_idx = 0;
1460             }
1461             break;
1462         case TBM_FORMAT_YUV444:
1463         case TBM_FORMAT_YVU444:
1464             bpp = 24;
1465             //if(plane_idx == 0)
1466             {
1467                 _offset = 0;
1468                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1469                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1470                 _bo_idx = 0;
1471                         if(plane_idx == 0)
1472                                 break;
1473             }
1474             //else if( plane_idx == 1 )
1475             {
1476                 _offset += _size;
1477                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1478                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1479                 _bo_idx = 0;
1480                         if(plane_idx == 1)
1481                                 break;
1482             }
1483             //else if (plane_idx == 2 )
1484             {
1485                 _offset += _size;
1486                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1487                _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1488                _bo_idx = 0;
1489             }
1490             break;
1491         default:
1492             bpp = 0;
1493             break;
1494     }
1495
1496     *size = _size;
1497     *offset = _offset;
1498     *pitch = _pitch;
1499     *bo_idx = _bo_idx;
1500
1501     return ret;
1502 }
1503
1504 int
1505 tbm_exynos4412_surface_get_num_bos(tbm_format format)
1506 {
1507         int num = 0;
1508
1509     switch(format)
1510     {
1511         /* 16 bpp RGB */
1512         case TBM_FORMAT_XRGB4444:
1513         case TBM_FORMAT_XBGR4444:
1514         case TBM_FORMAT_RGBX4444:
1515         case TBM_FORMAT_BGRX4444:
1516         case TBM_FORMAT_ARGB4444:
1517         case TBM_FORMAT_ABGR4444:
1518         case TBM_FORMAT_RGBA4444:
1519         case TBM_FORMAT_BGRA4444:
1520         case TBM_FORMAT_XRGB1555:
1521         case TBM_FORMAT_XBGR1555:
1522         case TBM_FORMAT_RGBX5551:
1523         case TBM_FORMAT_BGRX5551:
1524         case TBM_FORMAT_ARGB1555:
1525         case TBM_FORMAT_ABGR1555:
1526         case TBM_FORMAT_RGBA5551:
1527         case TBM_FORMAT_BGRA5551:
1528         case TBM_FORMAT_RGB565:
1529         /* 24 bpp RGB */
1530         case TBM_FORMAT_RGB888:
1531         case TBM_FORMAT_BGR888:
1532         /* 32 bpp RGB */
1533         case TBM_FORMAT_XRGB8888:
1534         case TBM_FORMAT_XBGR8888:
1535         case TBM_FORMAT_RGBX8888:
1536         case TBM_FORMAT_BGRX8888:
1537         case TBM_FORMAT_ARGB8888:
1538         case TBM_FORMAT_ABGR8888:
1539         case TBM_FORMAT_RGBA8888:
1540         case TBM_FORMAT_BGRA8888:
1541         /* packed YCbCr */
1542         case TBM_FORMAT_YUYV:
1543         case TBM_FORMAT_YVYU:
1544         case TBM_FORMAT_UYVY:
1545         case TBM_FORMAT_VYUY:
1546         case TBM_FORMAT_AYUV:
1547         /*
1548         * 2 plane YCbCr
1549         * index 0 = Y plane, [7:0] Y
1550         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1551         * or
1552         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1553         */
1554         case TBM_FORMAT_NV21:
1555         case TBM_FORMAT_NV16:
1556         case TBM_FORMAT_NV61:
1557         /*
1558         * 3 plane YCbCr
1559         * index 0: Y plane, [7:0] Y
1560         * index 1: Cb plane, [7:0] Cb
1561         * index 2: Cr plane, [7:0] Cr
1562         * or
1563         * index 1: Cr plane, [7:0] Cr
1564         * index 2: Cb plane, [7:0] Cb
1565         */
1566         case TBM_FORMAT_YUV410:
1567         case TBM_FORMAT_YVU410:
1568         case TBM_FORMAT_YUV411:
1569         case TBM_FORMAT_YVU411:
1570         case TBM_FORMAT_YUV420:
1571         case TBM_FORMAT_YVU420:
1572         case TBM_FORMAT_YUV422:
1573         case TBM_FORMAT_YVU422:
1574         case TBM_FORMAT_YUV444:
1575         case TBM_FORMAT_YVU444:
1576             num = 1;
1577             break;
1578
1579         case TBM_FORMAT_NV12:
1580             num = 2;
1581             break;
1582
1583         default:
1584             num = 0;
1585             break;
1586     }
1587
1588     return num;
1589 }
1590
1591 /**
1592 * @brief get the size of the surface with a format.
1593 * @param[in] surface : the surface
1594 * @param[in] width : the width of the surface
1595 * @param[in] height : the height of the surface
1596 * @param[in] format : the format of the surface
1597 * @return size of the surface if this function succeeds, otherwise 0.
1598 */
1599
1600 int
1601 tbm_exynos4412_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1602 {
1603         int ret = 0;
1604         int bpp = 0;
1605         int _pitch =0;
1606         int _size =0;
1607         int align =TBM_SURFACE_ALIGNMENT_PLANE;
1608
1609     switch(format)
1610     {
1611         /* 16 bpp RGB */
1612         case TBM_FORMAT_XRGB4444:
1613         case TBM_FORMAT_XBGR4444:
1614         case TBM_FORMAT_RGBX4444:
1615         case TBM_FORMAT_BGRX4444:
1616         case TBM_FORMAT_ARGB4444:
1617         case TBM_FORMAT_ABGR4444:
1618         case TBM_FORMAT_RGBA4444:
1619         case TBM_FORMAT_BGRA4444:
1620         case TBM_FORMAT_XRGB1555:
1621         case TBM_FORMAT_XBGR1555:
1622         case TBM_FORMAT_RGBX5551:
1623         case TBM_FORMAT_BGRX5551:
1624         case TBM_FORMAT_ARGB1555:
1625         case TBM_FORMAT_ABGR1555:
1626         case TBM_FORMAT_RGBA5551:
1627         case TBM_FORMAT_BGRA5551:
1628         case TBM_FORMAT_RGB565:
1629             bpp = 16;
1630                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1631             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1632             break;
1633         /* 24 bpp RGB */
1634         case TBM_FORMAT_RGB888:
1635         case TBM_FORMAT_BGR888:
1636             bpp = 24;
1637                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1638             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1639             break;
1640         /* 32 bpp RGB */
1641         case TBM_FORMAT_XRGB8888:
1642         case TBM_FORMAT_XBGR8888:
1643         case TBM_FORMAT_RGBX8888:
1644         case TBM_FORMAT_BGRX8888:
1645         case TBM_FORMAT_ARGB8888:
1646         case TBM_FORMAT_ABGR8888:
1647         case TBM_FORMAT_RGBA8888:
1648         case TBM_FORMAT_BGRA8888:
1649             bpp = 32;
1650                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1651             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1652             break;
1653         /* packed YCbCr */
1654         case TBM_FORMAT_YUYV:
1655         case TBM_FORMAT_YVYU:
1656         case TBM_FORMAT_UYVY:
1657         case TBM_FORMAT_VYUY:
1658         case TBM_FORMAT_AYUV:
1659             bpp = 32;
1660                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1661             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1662             break;
1663         /*
1664         * 2 plane YCbCr
1665         * index 0 = Y plane, [7:0] Y
1666         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1667         * or
1668         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1669         */
1670         case TBM_FORMAT_NV12:
1671         case TBM_FORMAT_NV21:
1672                         bpp = 12;
1673                          //plane_idx == 0
1674                          {
1675                                  _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1676                                  _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1677                          }
1678                          //plane_idx ==1
1679                          {
1680                                  _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1681                                  _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1682                          }
1683                          break;
1684
1685             break;
1686         case TBM_FORMAT_NV16:
1687         case TBM_FORMAT_NV61:
1688             bpp = 16;
1689             //plane_idx == 0
1690             {
1691                                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1692                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1693             }
1694             //plane_idx ==1
1695             {
1696                             _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1697                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1698             }
1699
1700             break;
1701         /*
1702         * 3 plane YCbCr
1703         * index 0: Y plane, [7:0] Y
1704         * index 1: Cb plane, [7:0] Cb
1705         * index 2: Cr plane, [7:0] Cr
1706         * or
1707         * index 1: Cr plane, [7:0] Cr
1708         * index 2: Cb plane, [7:0] Cb
1709         */
1710         case TBM_FORMAT_YUV410:
1711         case TBM_FORMAT_YVU410:
1712             bpp = 9;
1713             align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1714             break;
1715         case TBM_FORMAT_YUV411:
1716         case TBM_FORMAT_YVU411:
1717         case TBM_FORMAT_YUV420:
1718         case TBM_FORMAT_YVU420:
1719             bpp = 12;
1720             //plane_idx == 0
1721             {
1722                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1723                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1724             }
1725             //plane_idx == 1
1726             {
1727                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1728                 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1729             }
1730             //plane_idx == 2
1731             {
1732                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1733                 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1734             }
1735
1736             break;
1737         case TBM_FORMAT_YUV422:
1738         case TBM_FORMAT_YVU422:
1739             bpp = 16;
1740             //plane_idx == 0
1741             {
1742                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1743                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1744             }
1745             //plane_idx == 1
1746             {
1747                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1748                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1749             }
1750             //plane_idx == 2
1751             {
1752                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1753                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1754             }
1755             break;
1756         case TBM_FORMAT_YUV444:
1757         case TBM_FORMAT_YVU444:
1758             bpp = 24;
1759             align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1760             break;
1761
1762         default:
1763             bpp = 0;
1764             break;
1765     }
1766
1767         if(_size > 0)
1768                 ret = _size;
1769         else
1770             ret =  SIZE_ALIGN( (width * height * bpp) >> 3, align);
1771
1772     return ret;
1773
1774 }
1775
1776 tbm_bo_handle
1777 tbm_exynos4412_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1778 {
1779     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1780     EXYNOS4412_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1781
1782     tbm_bo_handle bo_handle;
1783     memset (&bo_handle, 0x0, sizeof (uint64_t));
1784
1785     tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_priv_from_bufmgr(bufmgr);
1786
1787     switch(device)
1788     {
1789     case TBM_DEVICE_DEFAULT:
1790     case TBM_DEVICE_2D:
1791     {
1792         //getting handle from fd
1793         struct drm_prime_handle arg = {0, };
1794
1795         arg.fd = fd;
1796         arg.flags = 0;
1797         if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1798         {
1799             TBM_EXYNOS4412_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1800                      arg.fd, strerror(errno));
1801             return (tbm_bo_handle) NULL;
1802         }
1803
1804         bo_handle.u32 = (uint32_t)arg.handle;;
1805         break;
1806     }
1807     case TBM_DEVICE_CPU:
1808         TBM_EXYNOS4412_LOG ("Not supported device:%d\n", device);
1809         bo_handle.ptr = (void *) NULL;
1810         break;
1811     case TBM_DEVICE_3D:
1812     case TBM_DEVICE_MM:
1813         bo_handle.u32 = (uint32_t)fd;
1814         break;
1815     default:
1816         TBM_EXYNOS4412_LOG ("error Not supported device:%d\n", device);
1817         bo_handle.ptr = (void *) NULL;
1818         break;
1819     }
1820
1821     return bo_handle;
1822 }
1823
1824 int
1825 tbm_exynos4412_bo_get_flags (tbm_bo bo)
1826 {
1827     EXYNOS4412_RETURN_VAL_IF_FAIL (bo != NULL, 0);
1828
1829     tbm_bo_exynos4412 bo_exynos4412;
1830
1831     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1832     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412 != NULL, 0);
1833
1834     return bo_exynos4412->flags_tbm;
1835 }
1836
1837 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1838
1839 static TBMModuleVersionInfo Exynos4412VersRec =
1840 {
1841     "exynos4412",
1842     "Samsung",
1843     TBM_ABI_VERSION,
1844 };
1845
1846 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
1847
1848 int
1849 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1850 {
1851     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1852     tbm_bufmgr_backend bufmgr_backend;
1853
1854     if (!bufmgr)
1855         return 0;
1856
1857     bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
1858     if (!bufmgr_exynos4412)
1859     {
1860         TBM_EXYNOS4412_LOG ("error: Fail to alloc bufmgr_exynos4412!\n");
1861         return 0;
1862     }
1863
1864     bufmgr_exynos4412->fd = fd;
1865     if (bufmgr_exynos4412->fd < 0)
1866     {
1867         TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1868         free (bufmgr_exynos4412);
1869         return 0;
1870     }
1871
1872     //Create Hash Table
1873     bufmgr_exynos4412->hashBos = drmHashCreate ();
1874
1875     //Check if the tbm manager supports dma fence or not.
1876     int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1877     int length;
1878     char buf[1];
1879     if (fp != -1)
1880     {
1881         length = read(fp, buf, 1);
1882
1883         if (length == 1 && buf[0] == '1')
1884             bufmgr_exynos4412->use_dma_fence = 1;
1885
1886         close(fp);
1887     }
1888
1889     bufmgr_backend = tbm_backend_alloc();
1890     if (!bufmgr_backend)
1891     {
1892         TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1893         if (bufmgr_exynos4412->hashBos)
1894             drmHashDestroy (bufmgr_exynos4412->hashBos);
1895         free (bufmgr_exynos4412);
1896         return 0;
1897     }
1898
1899     bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1900     bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1901     bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1902     bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1903     bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1904     bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1905     bufmgr_backend->bo_import_fd = tbm_exynos4412_bo_import_fd,
1906     bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1907     bufmgr_backend->bo_export_fd = tbm_exynos4412_bo_export_fd,
1908     bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1909     bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1910     bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1911     bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1912     bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1913     bufmgr_backend->surface_get_plane_data = tbm_exynos4412_surface_get_plane_data;
1914     bufmgr_backend->surface_get_size = tbm_exynos4412_surface_get_size;
1915     bufmgr_backend->surface_supported_format = tbm_exynos4412_surface_supported_format;
1916     bufmgr_backend->fd_to_handle = tbm_exynos4412_fd_to_handle;
1917     bufmgr_backend->surface_get_num_bos = tbm_exynos4412_surface_get_num_bos;
1918     bufmgr_backend->bo_get_flags = tbm_exynos4412_bo_get_flags;
1919
1920     if (bufmgr_exynos4412->use_dma_fence)
1921     {
1922         bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1923         bufmgr_backend->bo_lock = NULL;
1924         bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1925         bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1926     }
1927     else
1928     {
1929         bufmgr_backend->flags = 0;
1930         bufmgr_backend->bo_lock = NULL;
1931         bufmgr_backend->bo_unlock = NULL;
1932     }
1933
1934     if (!tbm_backend_init (bufmgr, bufmgr_backend))
1935     {
1936         TBM_EXYNOS4412_LOG ("error: Fail to init backend!\n");
1937         tbm_backend_free (bufmgr_backend);
1938         free (bufmgr_exynos4412);
1939         return 0;
1940     }
1941
1942 #ifdef DEBUG
1943     {
1944         char* env;
1945         env = getenv ("TBM_EXYNOS4412_DEBUG");
1946         if (env)
1947         {
1948             bDebug = atoi (env);
1949             TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1950         }
1951         else
1952         {
1953             bDebug = 0;
1954         }
1955     }
1956 #endif
1957
1958     DBG ("[%s] DMABUF FENCE is %s\n", target_name(),
1959           bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1960
1961     DBG ("[%s] drm_fd:%d\n", target_name(),
1962           bufmgr_exynos4412->fd);
1963
1964     return 1;
1965 }
1966
1967