Fix prevent issues
[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)
1249 {
1250     int ret = 1;
1251     int bpp;
1252     int _offset =0;
1253     int _pitch =0;
1254     int _size =0;
1255
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             break;
1282         /* 24 bpp RGB */
1283         case TBM_FORMAT_RGB888:
1284         case TBM_FORMAT_BGR888:
1285             bpp = 24;
1286             _offset = 0;
1287                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1288             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1289             break;
1290         /* 32 bpp RGB */
1291         case TBM_FORMAT_XRGB8888:
1292         case TBM_FORMAT_XBGR8888:
1293         case TBM_FORMAT_RGBX8888:
1294         case TBM_FORMAT_BGRX8888:
1295         case TBM_FORMAT_ARGB8888:
1296         case TBM_FORMAT_ABGR8888:
1297         case TBM_FORMAT_RGBA8888:
1298         case TBM_FORMAT_BGRA8888:
1299             bpp = 32;
1300             _offset = 0;
1301                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1302             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1303             break;
1304
1305         /* packed YCbCr */
1306         case TBM_FORMAT_YUYV:
1307         case TBM_FORMAT_YVYU:
1308         case TBM_FORMAT_UYVY:
1309         case TBM_FORMAT_VYUY:
1310         case TBM_FORMAT_AYUV:
1311             bpp = 32;
1312             _offset = 0;
1313                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1314             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1315             break;
1316
1317         /*
1318         * 2 plane YCbCr
1319         * index 0 = Y plane, [7:0] Y
1320         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1321         * or
1322         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1323         */
1324         case TBM_FORMAT_NV12:
1325         case TBM_FORMAT_NV21:
1326             bpp = 12;
1327             if(plane_idx == 0)
1328             {
1329                 _offset = 0;
1330                                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1331                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1332             }
1333             else if( plane_idx ==1 )
1334             {
1335                 _offset = width*height;
1336                                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1337                                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1338             }
1339             break;
1340
1341         case TBM_FORMAT_NV16:
1342         case TBM_FORMAT_NV61:
1343                         bpp = 16;
1344             //if(plane_idx == 0)
1345             {
1346                 _offset = 0;
1347                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1348                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1349                 if(plane_idx == 0)
1350                         break;
1351             }
1352             //else if( plane_idx ==1 )
1353             {
1354                 _offset += _size;
1355                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1356                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1357             }
1358             break;
1359
1360         /*
1361         * 3 plane YCbCr
1362         * index 0: Y plane, [7:0] Y
1363         * index 1: Cb plane, [7:0] Cb
1364         * index 2: Cr plane, [7:0] Cr
1365         * or
1366         * index 1: Cr plane, [7:0] Cr
1367         * index 2: Cb plane, [7:0] Cb
1368         */
1369         /*
1370         NATIVE_BUFFER_FORMAT_YV12
1371         NATIVE_BUFFER_FORMAT_I420
1372         */
1373         case TBM_FORMAT_YUV410:
1374         case TBM_FORMAT_YVU410:
1375             bpp = 9;
1376             break;
1377         case TBM_FORMAT_YUV411:
1378         case TBM_FORMAT_YVU411:
1379         case TBM_FORMAT_YUV420:
1380         case TBM_FORMAT_YVU420:
1381             bpp = 12;
1382             //if(plane_idx == 0)
1383             {
1384                 _offset = 0;
1385                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1386                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1387                         if(plane_idx == 0)
1388                                 break;
1389             }
1390             //else if( plane_idx == 1 )
1391             {
1392                 _offset += _size;
1393                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1394                         _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1395                         if(plane_idx == 1)
1396                                 break;
1397             }
1398             //else if (plane_idx == 2 )
1399             {
1400                 _offset += _size;
1401                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1402                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1403             }
1404             break;
1405         case TBM_FORMAT_YUV422:
1406         case TBM_FORMAT_YVU422:
1407             bpp = 16;
1408             //if(plane_idx == 0)
1409             {
1410                 _offset = 0;
1411                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1412                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
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),TBM_SURFACE_ALIGNMENT_PLANE);
1421                         if(plane_idx == 1)
1422                                 break;
1423             }
1424             //else if (plane_idx == 2 )
1425             {
1426                 _offset += _size;
1427                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1428                 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1429             }
1430             break;
1431         case TBM_FORMAT_YUV444:
1432         case TBM_FORMAT_YVU444:
1433             bpp = 24;
1434             //if(plane_idx == 0)
1435             {
1436                 _offset = 0;
1437                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1438                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1439                         if(plane_idx == 0)
1440                                 break;
1441             }
1442             //else if( plane_idx == 1 )
1443             {
1444                 _offset += _size;
1445                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1446                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1447                         if(plane_idx == 1)
1448                                 break;
1449             }
1450             //else if (plane_idx == 2 )
1451             {
1452                 _offset += _size;
1453                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1454                _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1455             }
1456             break;
1457         default:
1458             bpp = 0;
1459             break;
1460     }
1461
1462     *size = _size;
1463     *offset = _offset;
1464     *pitch = _pitch;
1465
1466     return ret;
1467 }
1468 /**
1469 * @brief get the size of the surface with a format.
1470 * @param[in] surface : the surface
1471 * @param[in] width : the width of the surface
1472 * @param[in] height : the height of the surface
1473 * @param[in] format : the format of the surface
1474 * @return size of the surface if this function succeeds, otherwise 0.
1475 */
1476
1477 int
1478 tbm_exynos4412_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1479 {
1480         int ret = 0;
1481         int bpp = 0;
1482         int _pitch =0;
1483         int _size =0;
1484         int align =TBM_SURFACE_ALIGNMENT_PLANE;
1485
1486     switch(format)
1487     {
1488         /* 16 bpp RGB */
1489         case TBM_FORMAT_XRGB4444:
1490         case TBM_FORMAT_XBGR4444:
1491         case TBM_FORMAT_RGBX4444:
1492         case TBM_FORMAT_BGRX4444:
1493         case TBM_FORMAT_ARGB4444:
1494         case TBM_FORMAT_ABGR4444:
1495         case TBM_FORMAT_RGBA4444:
1496         case TBM_FORMAT_BGRA4444:
1497         case TBM_FORMAT_XRGB1555:
1498         case TBM_FORMAT_XBGR1555:
1499         case TBM_FORMAT_RGBX5551:
1500         case TBM_FORMAT_BGRX5551:
1501         case TBM_FORMAT_ARGB1555:
1502         case TBM_FORMAT_ABGR1555:
1503         case TBM_FORMAT_RGBA5551:
1504         case TBM_FORMAT_BGRA5551:
1505         case TBM_FORMAT_RGB565:
1506             bpp = 16;
1507                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1508             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1509             break;
1510         /* 24 bpp RGB */
1511         case TBM_FORMAT_RGB888:
1512         case TBM_FORMAT_BGR888:
1513             bpp = 24;
1514                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1515             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1516             break;
1517         /* 32 bpp RGB */
1518         case TBM_FORMAT_XRGB8888:
1519         case TBM_FORMAT_XBGR8888:
1520         case TBM_FORMAT_RGBX8888:
1521         case TBM_FORMAT_BGRX8888:
1522         case TBM_FORMAT_ARGB8888:
1523         case TBM_FORMAT_ABGR8888:
1524         case TBM_FORMAT_RGBA8888:
1525         case TBM_FORMAT_BGRA8888:
1526             bpp = 32;
1527                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1528             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1529             break;
1530         /* packed YCbCr */
1531         case TBM_FORMAT_YUYV:
1532         case TBM_FORMAT_YVYU:
1533         case TBM_FORMAT_UYVY:
1534         case TBM_FORMAT_VYUY:
1535         case TBM_FORMAT_AYUV:
1536             bpp = 32;
1537                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1538             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1539             break;
1540         /*
1541         * 2 plane YCbCr
1542         * index 0 = Y plane, [7:0] Y
1543         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1544         * or
1545         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1546         */
1547         case TBM_FORMAT_NV12:
1548         case TBM_FORMAT_NV21:
1549                         bpp = 12;
1550                          //plane_idx == 0
1551                          {
1552                                  _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1553                                  _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1554                          }
1555                          //plane_idx ==1
1556                          {
1557                                  _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1558                                  _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1559                          }
1560                          break;
1561
1562             break;
1563         case TBM_FORMAT_NV16:
1564         case TBM_FORMAT_NV61:
1565             bpp = 16;
1566             //plane_idx == 0
1567             {
1568                                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1569                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1570             }
1571             //plane_idx ==1
1572             {
1573                             _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1574                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1575             }
1576
1577             break;
1578         /*
1579         * 3 plane YCbCr
1580         * index 0: Y plane, [7:0] Y
1581         * index 1: Cb plane, [7:0] Cb
1582         * index 2: Cr plane, [7:0] Cr
1583         * or
1584         * index 1: Cr plane, [7:0] Cr
1585         * index 2: Cb plane, [7:0] Cb
1586         */
1587         case TBM_FORMAT_YUV410:
1588         case TBM_FORMAT_YVU410:
1589             bpp = 9;
1590             align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1591             break;
1592         case TBM_FORMAT_YUV411:
1593         case TBM_FORMAT_YVU411:
1594         case TBM_FORMAT_YUV420:
1595         case TBM_FORMAT_YVU420:
1596             bpp = 12;
1597             //plane_idx == 0
1598             {
1599                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1600                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1601             }
1602             //plane_idx == 1
1603             {
1604                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1605                 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1606             }
1607             //plane_idx == 2
1608             {
1609                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1610                 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1611             }
1612
1613             break;
1614         case TBM_FORMAT_YUV422:
1615         case TBM_FORMAT_YVU422:
1616             bpp = 16;
1617             //plane_idx == 0
1618             {
1619                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1620                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1621             }
1622             //plane_idx == 1
1623             {
1624                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1625                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1626             }
1627             //plane_idx == 2
1628             {
1629                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1630                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1631             }
1632             break;
1633         case TBM_FORMAT_YUV444:
1634         case TBM_FORMAT_YVU444:
1635             bpp = 24;
1636             align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1637             break;
1638
1639         default:
1640             bpp = 0;
1641             break;
1642     }
1643
1644         if(_size > 0)
1645                 ret = _size;
1646         else
1647             ret =  SIZE_ALIGN( (width * height * bpp) >> 3, align);
1648
1649     return ret;
1650
1651 }
1652
1653 tbm_bo_handle
1654 tbm_exynos4412_fd_to_handle(tbm_bufmgr bufmgr, tbm_fd fd, int device)
1655 {
1656     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr!=NULL, (tbm_bo_handle) NULL);
1657     EXYNOS4412_RETURN_VAL_IF_FAIL (fd > 0, (tbm_bo_handle) NULL);
1658
1659     tbm_bo_handle bo_handle;
1660     memset (&bo_handle, 0x0, sizeof (uint64_t));
1661
1662     tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_priv_from_bufmgr(bufmgr);
1663
1664     switch(device)
1665     {
1666     case TBM_DEVICE_DEFAULT:
1667     case TBM_DEVICE_2D:
1668     {
1669         //getting handle from fd
1670         struct drm_prime_handle arg = {0, };
1671
1672         arg.fd = fd;
1673         arg.flags = 0;
1674         if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
1675         {
1676             TBM_EXYNOS4412_LOG ("error Cannot get gem handle from fd:%d (%s)\n",
1677                      arg.fd, strerror(errno));
1678             return (tbm_bo_handle) NULL;
1679         }
1680
1681         bo_handle.u32 = (uint32_t)arg.handle;;
1682         break;
1683     }
1684     case TBM_DEVICE_CPU:
1685         TBM_EXYNOS4412_LOG ("Not supported device:%d\n", device);
1686         bo_handle.ptr = (void *) NULL;
1687         break;
1688     case TBM_DEVICE_3D:
1689     case TBM_DEVICE_MM:
1690         bo_handle.u32 = (uint32_t)fd;
1691         break;
1692     default:
1693         TBM_EXYNOS4412_LOG ("error Not supported device:%d\n", device);
1694         bo_handle.ptr = (void *) NULL;
1695         break;
1696     }
1697
1698     return bo_handle;
1699 }
1700
1701
1702 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1703
1704 static TBMModuleVersionInfo Exynos4412VersRec =
1705 {
1706     "exynos4412",
1707     "Samsung",
1708     TBM_ABI_VERSION,
1709 };
1710
1711 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
1712
1713 int
1714 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1715 {
1716     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1717     tbm_bufmgr_backend bufmgr_backend;
1718
1719     if (!bufmgr)
1720         return 0;
1721
1722     bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
1723     if (!bufmgr_exynos4412)
1724     {
1725         TBM_EXYNOS4412_LOG ("error: Fail to alloc bufmgr_exynos4412!\n");
1726         return 0;
1727     }
1728
1729     bufmgr_exynos4412->fd = fd;
1730     if (bufmgr_exynos4412->fd < 0)
1731     {
1732         TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1733         free (bufmgr_exynos4412);
1734         return 0;
1735     }
1736
1737     //Create Hash Table
1738     bufmgr_exynos4412->hashBos = drmHashCreate ();
1739
1740     //Check if the tbm manager supports dma fence or not.
1741     int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1742     int length;
1743     char buf[1];
1744     if (fp != -1)
1745     {
1746         length = read(fp, buf, 1);
1747
1748         if (length == 1 && buf[0] == '1')
1749             bufmgr_exynos4412->use_dma_fence = 1;
1750
1751         close(fp);
1752     }
1753
1754     bufmgr_backend = tbm_backend_alloc();
1755     if (!bufmgr_backend)
1756     {
1757         TBM_EXYNOS4412_LOG ("error: Fail to create drm!\n");
1758         if (bufmgr_exynos4412->hashBos)
1759             drmHashDestroy (bufmgr_exynos4412->hashBos);
1760         free (bufmgr_exynos4412);
1761         return 0;
1762     }
1763
1764     bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1765     bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1766     bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1767     bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1768     bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1769     bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1770     bufmgr_backend->bo_import_fd = tbm_exynos4412_bo_import_fd,
1771     bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1772     bufmgr_backend->bo_export_fd = tbm_exynos4412_bo_export_fd,
1773     bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1774     bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1775     bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1776     bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1777     bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1778     bufmgr_backend->surface_get_plane_data = tbm_exynos4412_surface_get_plane_data;
1779     bufmgr_backend->surface_get_size = tbm_exynos4412_surface_get_size;
1780     bufmgr_backend->surface_supported_format = tbm_exynos4412_surface_supported_format;
1781     bufmgr_backend->fd_to_handle = tbm_exynos4412_fd_to_handle;
1782
1783     if (bufmgr_exynos4412->use_dma_fence)
1784     {
1785         bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1786         bufmgr_backend->bo_lock = NULL;
1787         bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1788         bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1789     }
1790     else
1791     {
1792         bufmgr_backend->flags = 0;
1793         bufmgr_backend->bo_lock = NULL;
1794         bufmgr_backend->bo_unlock = NULL;
1795     }
1796
1797     if (!tbm_backend_init (bufmgr, bufmgr_backend))
1798     {
1799         TBM_EXYNOS4412_LOG ("error: Fail to init backend!\n");
1800         tbm_backend_free (bufmgr_backend);
1801         free (bufmgr_exynos4412);
1802         return 0;
1803     }
1804
1805 #ifdef DEBUG
1806     {
1807         char* env;
1808         env = getenv ("TBM_EXYNOS4412_DEBUG");
1809         if (env)
1810         {
1811             bDebug = atoi (env);
1812             TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1813         }
1814         else
1815         {
1816             bDebug = 0;
1817         }
1818     }
1819 #endif
1820
1821     DBG ("[%s] DMABUF FENCE is %s\n", target_name(),
1822           bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1823
1824     DBG ("[%s] drm_fd:%d\n", target_name(),
1825           bufmgr_exynos4412->fd);
1826
1827     return 1;
1828 }
1829
1830