Fix type casting error at 64bit system
[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("[%s]" fmt, target_name(), ##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 ("[libtbm-exynos4412:%d] "
274                  "error %s:%d fail to get flink gem=%d\n",
275                  getpid(), __FUNCTION__, __LINE__, gem);
276         return 0;
277     }
278
279     return (unsigned int)arg.name;
280 }
281
282 static tbm_bo_handle
283 _exynos4412_bo_handle (tbm_bo_exynos4412 bo_exynos4412, int device)
284 {
285     tbm_bo_handle bo_handle;
286     memset (&bo_handle, 0x0, sizeof (uint64_t));
287
288     switch(device)
289     {
290     case TBM_DEVICE_DEFAULT:
291     case TBM_DEVICE_2D:
292         bo_handle.u32 = (uint32_t)bo_exynos4412->gem;
293         break;
294     case TBM_DEVICE_CPU:
295         if (!bo_exynos4412->pBase)
296         {
297             struct drm_exynos_gem_mmap arg = {0,};
298
299             arg.handle = bo_exynos4412->gem;
300             arg.size = bo_exynos4412->size;
301             if (drmCommandWriteRead (bo_exynos4412->fd, DRM_EXYNOS_GEM_MMAP, &arg, sizeof(arg)))
302             {
303                 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
304                          "error %s:%d Cannot usrptr gem=%d\n",
305                          getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
306                 return (tbm_bo_handle) NULL;
307             }
308             bo_exynos4412->pBase = (void*)((unsigned long)arg.mapped);
309         }
310
311         bo_handle.ptr = (void *)bo_exynos4412->pBase;
312         break;
313     case TBM_DEVICE_3D:
314 #ifdef USE_DMAIMPORT
315         if (bo_exynos4412->dmabuf)
316         {
317             bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
318             break;
319         }
320
321         if (!bo_exynos4412->dmabuf)
322         {
323             struct drm_prime_handle arg = {0, };
324
325             arg.handle = bo_exynos4412->gem;
326             if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
327             {
328                 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
329                          "error %s:%d Cannot dmabuf=%d\n",
330                          getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
331                 return (tbm_bo_handle) NULL;
332             }
333             bo_exynos4412->dmabuf = arg.fd;
334         }
335
336         bo_handle.u32 = (uint32_t)bo_exynos4412->dmabuf;
337 #endif
338         break;
339     case TBM_DEVICE_MM:
340         if (!bo_exynos4412->dmabuf)
341         {
342             struct drm_prime_handle arg = {0, };
343
344             arg.handle = bo_exynos4412->gem;
345             if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
346             {
347                 TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
348                          "error %s:%d Cannot dmabuf=%d\n",
349                          getpid(), __FUNCTION__, __LINE__, 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 ("[libtbm-exynos4412:%d] "
359                  "error %s:%d Not supported device:%d\n",
360                  getpid(), __FUNCTION__, __LINE__, device);
361         bo_handle.ptr = (void *) NULL;
362         break;
363     }
364
365     return bo_handle;
366 }
367
368 static int
369 _exynos4412_cache_flush (int fd, tbm_bo_exynos4412 bo_exynos4412, int flags)
370 {
371 #ifdef ENABLE_CACHECRTL
372     struct drm_exynos_gem_cache_op cache_op = {0, };
373     int ret;
374
375     /* if bo_exynos4412 is null, do cache_flush_all */
376     if(bo_exynos4412)
377     {
378         cache_op.flags = 0;
379         cache_op.usr_addr = (uint64_t)((uint32_t)bo_exynos4412->pBase);
380         cache_op.size = bo_exynos4412->size;
381     }
382     else
383     {
384         flags = TBM_CACHE_FLUSH_ALL;
385         cache_op.flags = 0;
386         cache_op.usr_addr = 0;
387         cache_op.size = 0;
388     }
389
390     if (flags & TBM_CACHE_INV)
391     {
392         if(flags & TBM_CACHE_ALL)
393             cache_op.flags |= EXYNOS_DRM_CACHE_INV_ALL;
394         else
395             cache_op.flags |= EXYNOS_DRM_CACHE_INV_RANGE;
396     }
397
398     if (flags & TBM_CACHE_CLN)
399     {
400         if(flags & TBM_CACHE_ALL)
401             cache_op.flags |= EXYNOS_DRM_CACHE_CLN_ALL;
402         else
403             cache_op.flags |= EXYNOS_DRM_CACHE_CLN_RANGE;
404     }
405
406     if(flags & TBM_CACHE_ALL)
407         cache_op.flags |= EXYNOS_DRM_ALL_CACHES_CORES;
408
409     ret = drmCommandWriteRead (fd, DRM_EXYNOS_GEM_CACHE_OP, &cache_op, sizeof(cache_op));
410     if (ret)
411     {
412         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
413                  "error %s:%d fail to flush the cache.\n",
414                  getpid(), __FUNCTION__, __LINE__);
415         return 0;
416     }
417 #else
418     TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
419              "warning %s:%d fail to enable the cache flush.\n",
420              getpid(), __FUNCTION__, __LINE__);
421 #endif
422     return 1;
423 }
424
425 static int
426 tbm_exynos4412_bo_size (tbm_bo bo)
427 {
428     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
429
430     tbm_bo_exynos4412 bo_exynos4412;
431
432     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
433
434     return bo_exynos4412->size;
435 }
436
437 static void *
438 tbm_exynos4412_bo_alloc (tbm_bo bo, int size, int flags)
439 {
440     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
441
442     tbm_bo_exynos4412 bo_exynos4412;
443     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
444     unsigned int exynos_flags;
445
446     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
447     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
448
449     bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
450     if (!bo_exynos4412)
451     {
452         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
453                  "error %s:%d fail to allocate the bo private\n",
454                  getpid(), __FUNCTION__, __LINE__);
455         return 0;
456     }
457
458     exynos_flags = _get_exynos_flag_from_tbm (flags);
459     if((flags & TBM_BO_SCANOUT) &&
460         size <= 4*1024)
461     {
462         exynos_flags |= EXYNOS_BO_NONCONTIG;
463     }
464
465     struct drm_exynos_gem_create arg = {0, };
466     arg.size = size;
467     arg.flags = exynos_flags;
468     if (drmCommandWriteRead(bufmgr_exynos4412->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg)))
469     {
470         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
471                  "error %s:%d Cannot create bo(flag:%x, size:%d)\n",
472                  getpid(), __FUNCTION__, __LINE__, arg.flags, (unsigned int)arg.size);
473         free (bo_exynos4412);
474         return 0;
475     }
476
477     bo_exynos4412->fd = bufmgr_exynos4412->fd;
478     bo_exynos4412->gem = arg.handle;
479     bo_exynos4412->size = size;
480     bo_exynos4412->flags_tbm = flags;
481     bo_exynos4412->flags_exynos = exynos_flags;
482     bo_exynos4412->name = _get_name (bo_exynos4412->fd, bo_exynos4412->gem);
483
484     pthread_mutex_init(&bo_exynos4412->mutex, NULL);
485
486     if (bufmgr_exynos4412->use_dma_fence
487         && !bo_exynos4412->dmabuf)
488     {
489         struct drm_prime_handle arg = {0, };
490
491         arg.handle = bo_exynos4412->gem;
492         if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
493         {
494             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
495                     "error %s:%d Cannot dmabuf=%d\n",
496                     getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
497             free (bo_exynos4412);
498             return 0;
499         }
500         bo_exynos4412->dmabuf = arg.fd;
501     }
502
503     /* add bo to hash */
504     PrivGem* privGem = calloc (1, sizeof(PrivGem));
505     privGem->ref_count = 1;
506     if (drmHashInsert(bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
507     {
508         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
509                  "error %s:%d Cannot insert bo to Hash(%d)\n",
510                  getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
511     }
512
513     DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
514          __FUNCTION__, bo_exynos4412->size,
515          bo_exynos4412->gem, bo_exynos4412->name,
516          flags, exynos_flags);
517
518     return (void *)bo_exynos4412;
519 }
520
521 static void
522 tbm_exynos4412_bo_free(tbm_bo bo)
523 {
524     tbm_bo_exynos4412 bo_exynos4412;
525     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
526
527     if (!bo)
528         return;
529
530     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
531     EXYNOS4412_RETURN_IF_FAIL (bufmgr_exynos4412!=NULL);
532
533     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
534     EXYNOS4412_RETURN_IF_FAIL (bo_exynos4412!=NULL);
535
536     DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d)\n",
537          getpid(), __FUNCTION__, bo_exynos4412->size, bo_exynos4412->gem, bo_exynos4412->name);
538
539     if (bo_exynos4412->pBase)
540     {
541         if (munmap(bo_exynos4412->pBase, bo_exynos4412->size) == -1)
542         {
543             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
544                      "error %s:%d\n",
545                      getpid(), __FUNCTION__, __LINE__);
546         }
547     }
548
549     /* close dmabuf */
550     if (bo_exynos4412->dmabuf)
551     {
552         close (bo_exynos4412->dmabuf);
553         bo_exynos4412->dmabuf = 0;
554     }
555
556     /* delete bo from hash */
557     PrivGem *privGem = NULL;
558     int ret;
559
560     ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
561     if (ret == 0)
562     {
563         privGem->ref_count--;
564         if (privGem->ref_count == 0)
565         {
566             drmHashDelete (bufmgr_exynos4412->hashBos, bo_exynos4412->name);
567             free (privGem);
568             privGem = NULL;
569         }
570     }
571     else
572     {
573         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
574                  "warning %s:%d Cannot find bo to Hash(%d), ret=%d\n",
575                  getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name, ret);
576     }
577
578     /* Free gem handle */
579     struct drm_gem_close arg = {0, };
580     memset (&arg, 0, sizeof(arg));
581     arg.handle = bo_exynos4412->gem;
582     if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_GEM_CLOSE, &arg))
583     {
584         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
585                  "error %s:%d\n",
586                  getpid(), __FUNCTION__, __LINE__);
587     }
588
589     free (bo_exynos4412);
590 }
591
592
593 static void *
594 tbm_exynos4412_bo_import (tbm_bo bo, unsigned int key)
595 {
596     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
597
598     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
599     tbm_bo_exynos4412 bo_exynos4412;
600
601     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
602     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
603
604     struct drm_gem_open arg = {0, };
605     struct drm_exynos_gem_info info = {0, };
606
607     arg.name = key;
608     if (drmIoctl(bufmgr_exynos4412->fd, DRM_IOCTL_GEM_OPEN, &arg))
609     {
610         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
611                 "error %s:%d Cannot open gem name=%d\n",
612                 getpid(), __FUNCTION__, __LINE__, key);
613         return 0;
614     }
615
616     info.handle = arg.handle;
617     if (drmCommandWriteRead(bufmgr_exynos4412->fd,
618                            DRM_EXYNOS_GEM_GET,
619                            &info,
620                            sizeof(struct drm_exynos_gem_info)))
621     {
622         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
623                 "error %s:%d Cannot get gem info=%d\n",
624                 getpid(), __FUNCTION__, __LINE__, key);
625         return 0;
626     }
627
628     bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
629     if (!bo_exynos4412)
630     {
631         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
632                 "error %s:%d fail to allocate the bo private\n",
633                 getpid(), __FUNCTION__, __LINE__);
634         return 0;
635     }
636
637     bo_exynos4412->fd = bufmgr_exynos4412->fd;
638     bo_exynos4412->gem = arg.handle;
639     bo_exynos4412->size = arg.size;
640     bo_exynos4412->flags_exynos = info.flags;
641     bo_exynos4412->name = key;
642     bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
643
644     if (!bo_exynos4412->dmabuf)
645     {
646         struct drm_prime_handle arg = {0, };
647
648         arg.handle = bo_exynos4412->gem;
649         if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
650         {
651             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
652                     "error %s:%d Cannot dmabuf=%d\n",
653                     getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
654             free (bo_exynos4412);
655             return 0;
656         }
657         bo_exynos4412->dmabuf = arg.fd;
658     }
659
660     /* add bo to hash */
661     PrivGem *privGem = NULL;
662     int ret;
663
664     ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
665     if (ret == 0)
666     {
667         privGem->ref_count++;
668     }
669     else if (ret == 1)
670     {
671         privGem = calloc (1, sizeof(PrivGem));
672         privGem->ref_count = 1;
673         if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
674         {
675             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
676                     "error %s:%d Cannot insert bo to Hash(%d)\n",
677                     getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
678         }
679     }
680     else
681     {
682         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
683                 "error %s:%d Cannot insert bo to Hash(%d)\n",
684                 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
685     }
686
687     DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d, %d), flags:%d(%d)\n", getpid(),
688          __FUNCTION__, bo_exynos4412->size,
689          bo_exynos4412->gem, bo_exynos4412->name, bo_exynos4412->dmabuf,
690          bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
691
692     return (void *)bo_exynos4412;
693 }
694
695 static void *
696 tbm_exynos4412_bo_import_fd (tbm_bo bo, tbm_fd key)
697 {
698     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
699
700     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
701     tbm_bo_exynos4412 bo_exynos4412;
702
703     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
704     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
705
706     unsigned int gem = 0;
707     unsigned int real_size = -1;
708     struct drm_exynos_gem_info info = {0, };
709
710         //getting handle from fd
711     struct drm_prime_handle arg = {0, };
712
713         arg.fd = key;
714         arg.flags = 0;
715     if (drmIoctl (bufmgr_exynos4412->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &arg))
716     {
717         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
718                  "error %s:%d Cannot getting gem from prime fd=%d\n",
719                  getpid(), __FUNCTION__, __LINE__, arg.fd);
720         return NULL;
721     }
722     gem = arg.handle;
723
724         /* Determine size of bo.  The fd-to-handle ioctl really should
725          * return the size, but it doesn't.  If we have kernel 3.12 or
726          * later, we can lseek on the prime fd to get the size.  Older
727          * kernels will just fail, in which case we fall back to the
728          * provided (estimated or guess size). */
729         real_size = lseek(key, 0, SEEK_END);
730
731     info.handle = gem;
732     if (drmCommandWriteRead(bufmgr_exynos4412->fd,
733                            DRM_EXYNOS_GEM_GET,
734                            &info,
735                            sizeof(struct drm_exynos_gem_info)))
736     {
737         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
738                 "error %s:%d Cannot get gem info=%d\n",
739                 getpid(), __FUNCTION__, __LINE__, key);
740         return 0;
741     }
742
743     if (real_size == -1)
744         real_size = info.size;
745
746     bo_exynos4412 = calloc (1, sizeof(struct _tbm_bo_exynos4412));
747     if (!bo_exynos4412)
748     {
749         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
750                 "error %s:%d fail to allocate the bo private\n",
751                 getpid(), __FUNCTION__, __LINE__);
752         return 0;
753     }
754
755     bo_exynos4412->fd = bufmgr_exynos4412->fd;
756     bo_exynos4412->gem = gem;
757     bo_exynos4412->size = real_size;
758     bo_exynos4412->flags_exynos = info.flags;
759     bo_exynos4412->flags_tbm = _get_tbm_flag_from_exynos (bo_exynos4412->flags_exynos);
760
761     bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
762     if (!bo_exynos4412->name)
763     {
764         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
765                 "error %s:%d Cannot get name\n",
766                 getpid(), __FUNCTION__, __LINE__);
767         return 0;
768     }
769
770         bo_exynos4412->dmabuf = (unsigned int)key;
771
772     /* add bo to hash */
773     PrivGem *privGem = NULL;
774     int ret;
775
776     ret = drmHashLookup (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void**)&privGem);
777     if (ret == 0)
778     {
779         privGem->ref_count++;
780     }
781     else if (ret == 1)
782     {
783         privGem = calloc (1, sizeof(PrivGem));
784         privGem->ref_count = 1;
785         if (drmHashInsert (bufmgr_exynos4412->hashBos, bo_exynos4412->name, (void *)privGem) < 0)
786         {
787             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
788                     "error %s:%d Cannot insert bo to Hash(%d)\n",
789                     getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
790         }
791     }
792     else
793     {
794         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
795                 "error %s:%d Cannot insert bo to Hash(%d)\n",
796                 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->name);
797     }
798
799     DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d,%d), flags:%d(%d)\n", getpid(),
800          __FUNCTION__, bo_exynos4412->size,
801          bo_exynos4412->gem, bo_exynos4412->name, bo_exynos4412->dmabuf,
802          bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
803
804     return (void *)bo_exynos4412;
805 }
806
807 static unsigned int
808 tbm_exynos4412_bo_export (tbm_bo bo)
809 {
810     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
811
812     tbm_bo_exynos4412 bo_exynos4412;
813
814     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
815     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
816
817     if (!bo_exynos4412->name)
818     {
819         bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
820         if (!bo_exynos4412->name)
821         {
822             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
823                     "error %s:%d Cannot get name\n",
824                     getpid(), __FUNCTION__, __LINE__);
825             return 0;
826         }
827     }
828
829     DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d), flags:%d(%d)\n", getpid(),
830          __FUNCTION__, bo_exynos4412->size,
831          bo_exynos4412->gem, bo_exynos4412->name,
832          bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
833
834     return (unsigned int)bo_exynos4412->name;
835 }
836
837 tbm_fd
838 tbm_exynos4412_bo_export_fd (tbm_bo bo)
839 {
840     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
841
842     tbm_bo_exynos4412 bo_exynos4412;
843
844     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
845     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
846
847     if (!bo_exynos4412->dmabuf)
848     {
849         struct drm_prime_handle arg = {0, };
850
851         arg.handle = bo_exynos4412->gem;
852         if (drmIoctl (bo_exynos4412->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg))
853         {
854             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
855                      "error %s:%d Cannot dmabuf=%d\n",
856                      getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
857             return (tbm_fd) 0;
858         }
859         bo_exynos4412->dmabuf = arg.fd;
860     }
861
862     DBG ("[libtbm-exynos4412:%d] %s size:%d, gem:%d(%d, %d), flags:%d(%d)\n", getpid(),
863          __FUNCTION__, bo_exynos4412->size,
864          bo_exynos4412->gem, bo_exynos4412->name, bo_exynos4412->dmabuf,
865          bo_exynos4412->flags_tbm, bo_exynos4412->flags_exynos);
866
867     return (tbm_fd)bo_exynos4412->dmabuf;
868 }
869
870 static tbm_bo_handle
871 tbm_exynos4412_bo_get_handle (tbm_bo bo, int device)
872 {
873     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
874
875     tbm_bo_handle bo_handle;
876     tbm_bo_exynos4412 bo_exynos4412;
877
878     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
879     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
880
881     if (!bo_exynos4412->gem)
882     {
883         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
884                 "error %s:%d Cannot map gem=%d\n",
885                 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
886         return (tbm_bo_handle) NULL;
887     }
888
889     DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s\n", getpid(),
890          __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device]);
891
892     /*Get mapped bo_handle*/
893     bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
894     if (bo_handle.ptr == NULL)
895     {
896         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
897                 "error %s:%d Cannot get handle: gem:%d, device:%d\n",
898                 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device);
899         return (tbm_bo_handle) NULL;
900     }
901
902     return bo_handle;
903 }
904
905 static tbm_bo_handle
906 tbm_exynos4412_bo_map (tbm_bo bo, int device, int opt)
907 {
908     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, (tbm_bo_handle) NULL);
909
910     tbm_bo_handle bo_handle;
911     tbm_bo_exynos4412 bo_exynos4412;
912
913     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
914     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, (tbm_bo_handle) NULL);
915
916     if (!bo_exynos4412->gem)
917     {
918         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
919                 "error %s:%d Cannot map gem=%d\n",
920                 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem);
921         return (tbm_bo_handle) NULL;
922     }
923
924     DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d), %s, %s\n", getpid(),
925          __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name, STR_DEVICE[device], STR_OPT[opt]);
926
927     /*Get mapped bo_handle*/
928     bo_handle = _exynos4412_bo_handle (bo_exynos4412, device);
929     if (bo_handle.ptr == NULL)
930     {
931         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
932                 "error %s:%d Cannot get handle: gem:%d, device:%d, opt:%d\n",
933                 getpid(), __FUNCTION__, __LINE__, bo_exynos4412->gem, device, opt);
934         return (tbm_bo_handle) NULL;
935     }
936
937     return bo_handle;
938 }
939
940 static int
941 tbm_exynos4412_bo_unmap (tbm_bo bo)
942 {
943     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
944
945     tbm_bo_exynos4412 bo_exynos4412;
946
947     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
948     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
949
950     if (!bo_exynos4412->gem)
951         return 0;
952
953     DBG ("[libtbm-exynos4412:%d] %s gem:%d(%d) \n", getpid(),
954          __FUNCTION__, bo_exynos4412->gem, bo_exynos4412->name);
955
956     return 1;
957 }
958
959 static int
960 tbm_exynos4412_bo_cache_flush (tbm_bo bo, int flags)
961 {
962     tbm_bufmgr_exynos4412 bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
963     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
964
965     /* cache flush is managed by kernel side when using dma-fence. */
966     if (bufmgr_exynos4412->use_dma_fence)
967        return 1;
968
969     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
970
971     tbm_bo_exynos4412 bo_exynos4412;
972
973     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
974     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
975
976     if (!_exynos4412_cache_flush(bo_exynos4412->fd, bo_exynos4412, flags))
977         return 0;
978
979     return 1;
980 }
981
982 static int
983 tbm_exynos4412_bo_get_global_key (tbm_bo bo)
984 {
985     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
986
987     tbm_bo_exynos4412 bo_exynos4412;
988
989     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
990     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
991
992     if (!bo_exynos4412->name)
993     {
994         if (!bo_exynos4412->gem)
995             return 0;
996
997         bo_exynos4412->name = _get_name(bo_exynos4412->fd, bo_exynos4412->gem);
998     }
999
1000     return bo_exynos4412->name;
1001 }
1002
1003 static int
1004 tbm_exynos4412_bo_lock(tbm_bo bo, int device, int opt)
1005 {
1006     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1007
1008     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1009     tbm_bo_exynos4412 bo_exynos4412;
1010     struct dma_buf_fence fence;
1011     struct flock filelock;
1012     int ret=0;
1013
1014     if (device != TBM_DEVICE_3D && device != TBM_DEVICE_CPU)
1015     {
1016         DBG ("[libtbm-exynos4412:%d] %s not support device type,\n", getpid(), __FUNCTION__);
1017             return 0;
1018     }
1019
1020     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1021     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1022
1023     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)tbm_backend_get_bufmgr_priv(bo);
1024     EXYNOS4412_RETURN_VAL_IF_FAIL (bufmgr_exynos4412!=NULL, 0);
1025
1026     memset(&fence, 0, sizeof(struct dma_buf_fence));
1027
1028     /* Check if the given type is valid or not. */
1029     if (opt & TBM_OPTION_WRITE)
1030     {
1031         if (device == TBM_DEVICE_3D)
1032             fence.type = DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA;
1033     }
1034     else if (opt & TBM_OPTION_READ)
1035     {
1036         if (device == TBM_DEVICE_3D)
1037             fence.type = DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA;
1038     }
1039     else
1040     {
1041         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error %s:%d Invalid argument\n", getpid(), __FUNCTION__, __LINE__);
1042         return 0;
1043     }
1044
1045     /* Check if the tbm manager supports dma fence or not. */
1046     if (!bufmgr_exynos4412->use_dma_fence)
1047     {
1048         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1049                 "error %s:%d  Not support DMA FENCE(%s)\n",
1050                 getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1051         return 0;
1052
1053     }
1054
1055     if (device == TBM_DEVICE_3D)
1056     {
1057         ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_GET_FENCE, &fence);
1058         if (ret < 0)
1059         {
1060             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1061                     "error %s:%d  Can not set GET FENCE(%s)\n",
1062                     getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1063             return 0;
1064         }
1065     } else
1066     {
1067         if (opt & TBM_OPTION_WRITE)
1068             filelock.l_type = F_WRLCK;
1069         else
1070             filelock.l_type = F_RDLCK;
1071
1072         filelock.l_whence = SEEK_CUR;
1073         filelock.l_start = 0;
1074         filelock.l_len = 0;
1075
1076         if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1077         {
1078             return 0;
1079         }
1080     }
1081
1082     pthread_mutex_lock(&bo_exynos4412->mutex);
1083
1084     if (device == TBM_DEVICE_3D)
1085     {
1086         int i;
1087         for (i = 0; i < DMA_FENCE_LIST_MAX; i++)
1088         {
1089             if (bo_exynos4412->dma_fence[i].ctx == 0)
1090             {
1091                 bo_exynos4412->dma_fence[i].type = fence.type;
1092                 bo_exynos4412->dma_fence[i].ctx = fence.ctx;
1093                 break;
1094             }
1095         }
1096
1097         if (i == DMA_FENCE_LIST_MAX)
1098         {
1099             //TODO: if dma_fence list is full, it needs realloc. I will fix this. by minseok3.kim
1100             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1101                     "error %s:%d  fence list is full\n",
1102                     getpid(), __FUNCTION__, __LINE__);
1103         }
1104     }
1105
1106     pthread_mutex_unlock(&bo_exynos4412->mutex);
1107
1108     DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_GET_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1109             __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
1110
1111     return 1;
1112 }
1113
1114 static int
1115 tbm_exynos4412_bo_unlock(tbm_bo bo)
1116 {
1117     EXYNOS4412_RETURN_VAL_IF_FAIL (bo!=NULL, 0);
1118
1119     tbm_bo_exynos4412 bo_exynos4412;
1120     struct dma_buf_fence fence;
1121     struct flock filelock;
1122     unsigned int dma_type = 0;
1123     int ret=0;
1124
1125     bo_exynos4412 = (tbm_bo_exynos4412)tbm_backend_get_bo_priv(bo);
1126     EXYNOS4412_RETURN_VAL_IF_FAIL (bo_exynos4412!=NULL, 0);
1127
1128     if (bo_exynos4412->dma_fence[0].type & DMA_BUF_ACCESS_DMA)
1129             dma_type = 1;
1130
1131     if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1132     {
1133         DBG ("[libtbm-exynos4412:%d] %s FENCE not support or ignored,\n", getpid(), __FUNCTION__);
1134         return 0;
1135     }
1136
1137     if (!bo_exynos4412->dma_fence[0].ctx && dma_type)
1138     {
1139         DBG ("[libtbm-exynos4412:%d] %s device type is not 3D/CPU,\n", getpid(), __FUNCTION__);
1140         return 0;
1141     }
1142
1143     pthread_mutex_lock(&bo_exynos4412->mutex);
1144
1145     if (dma_type)
1146     {
1147         fence.type = bo_exynos4412->dma_fence[0].type;
1148         fence.ctx = bo_exynos4412->dma_fence[0].ctx;
1149         int i;
1150         for (i = 1; i < DMA_FENCE_LIST_MAX; i++)
1151         {
1152             bo_exynos4412->dma_fence[i-1].type = bo_exynos4412->dma_fence[i].type;
1153             bo_exynos4412->dma_fence[i-1].ctx = bo_exynos4412->dma_fence[i].ctx;
1154         }
1155         bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].type = 0;
1156         bo_exynos4412->dma_fence[DMA_FENCE_LIST_MAX-1].ctx = 0;
1157     }
1158     pthread_mutex_unlock(&bo_exynos4412->mutex);
1159
1160     if (dma_type)
1161     {
1162         ret = ioctl(bo_exynos4412->dmabuf, DMABUF_IOCTL_PUT_FENCE, &fence);
1163         if (ret < 0)
1164         {
1165             TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] "
1166                     "error %s:%d  Can not set PUT FENCE(%s)\n",
1167                     getpid(), __FUNCTION__, __LINE__, strerror(errno) );
1168             return 0;
1169         }
1170     } else
1171     {
1172         filelock.l_type = F_UNLCK;
1173         filelock.l_whence = SEEK_CUR;
1174         filelock.l_start = 0;
1175         filelock.l_len = 0;
1176
1177         if (-1 == fcntl(bo_exynos4412->dmabuf, F_SETLKW, &filelock))
1178         {
1179             return 0;
1180         }
1181     }
1182
1183     DBG ("[libtbm-exynos4412:%d] %s DMABUF_IOCTL_PUT_FENCE! flink_id=%d dmabuf=%d\n", getpid(),
1184             __FUNCTION__, bo_exynos4412->name, bo_exynos4412->dmabuf);
1185
1186     return 1;
1187 }
1188
1189 static void
1190 tbm_exynos4412_bufmgr_deinit (void *priv)
1191 {
1192     EXYNOS4412_RETURN_IF_FAIL (priv!=NULL);
1193
1194     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1195
1196     bufmgr_exynos4412 = (tbm_bufmgr_exynos4412)priv;
1197
1198     if (bufmgr_exynos4412->hashBos)
1199     {
1200         unsigned long key;
1201         void *value;
1202
1203         while (drmHashFirst(bufmgr_exynos4412->hashBos, &key, &value) > 0)
1204         {
1205             free (value);
1206             drmHashDelete (bufmgr_exynos4412->hashBos, key);
1207         }
1208
1209         drmHashDestroy (bufmgr_exynos4412->hashBos);
1210         bufmgr_exynos4412->hashBos = NULL;
1211     }
1212
1213     free (bufmgr_exynos4412);
1214 }
1215
1216 int
1217 tbm_exynos4412_surface_supported_format(uint32_t **formats, uint32_t *num)
1218 {
1219     uint32_t* color_formats=NULL;
1220
1221     color_formats = (uint32_t*)calloc (1,sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT);
1222
1223     if( color_formats == NULL )
1224     {
1225         return 0;
1226     }
1227     memcpy( color_formats, tbm_exynos4412_color_format_list , sizeof(uint32_t)*TBM_COLOR_FORMAT_COUNT );
1228
1229
1230     *formats = color_formats;
1231     *num = TBM_COLOR_FORMAT_COUNT;
1232
1233     fprintf (stderr, "tbm_exynos4412_surface_supported_format  count = %d \n",*num);
1234
1235     return 1;
1236 }
1237
1238
1239 /**
1240  * @brief get the plane data of the surface.
1241  * @param[in] surface : the surface
1242  * @param[in] width : the width of the surface
1243  * @param[in] height : the height of the surface
1244  * @param[in] format : the format of the surface
1245  * @param[in] plane_idx : the format of the surface
1246  * @param[out] size : the size of the plane
1247  * @param[out] offset : the offset of the plane
1248  * @param[out] pitch : the pitch of the plane
1249  * @param[out] padding : the padding of the plane
1250  * @return 1 if this function succeeds, otherwise 0.
1251  */
1252 int
1253 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)
1254 {
1255     int ret = 1;
1256     int bpp;
1257     int _offset =0;
1258     int _pitch =0;
1259     int _size =0;
1260
1261
1262     switch(format)
1263     {
1264         /* 16 bpp RGB */
1265         case TBM_FORMAT_XRGB4444:
1266         case TBM_FORMAT_XBGR4444:
1267         case TBM_FORMAT_RGBX4444:
1268         case TBM_FORMAT_BGRX4444:
1269         case TBM_FORMAT_ARGB4444:
1270         case TBM_FORMAT_ABGR4444:
1271         case TBM_FORMAT_RGBA4444:
1272         case TBM_FORMAT_BGRA4444:
1273         case TBM_FORMAT_XRGB1555:
1274         case TBM_FORMAT_XBGR1555:
1275         case TBM_FORMAT_RGBX5551:
1276         case TBM_FORMAT_BGRX5551:
1277         case TBM_FORMAT_ARGB1555:
1278         case TBM_FORMAT_ABGR1555:
1279         case TBM_FORMAT_RGBA5551:
1280         case TBM_FORMAT_BGRA5551:
1281         case TBM_FORMAT_RGB565:
1282             bpp = 16;
1283             _offset = 0;
1284                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1285             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1286             break;
1287         /* 24 bpp RGB */
1288         case TBM_FORMAT_RGB888:
1289         case TBM_FORMAT_BGR888:
1290             bpp = 24;
1291             _offset = 0;
1292                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1293             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1294             break;
1295         /* 32 bpp RGB */
1296         case TBM_FORMAT_XRGB8888:
1297         case TBM_FORMAT_XBGR8888:
1298         case TBM_FORMAT_RGBX8888:
1299         case TBM_FORMAT_BGRX8888:
1300         case TBM_FORMAT_ARGB8888:
1301         case TBM_FORMAT_ABGR8888:
1302         case TBM_FORMAT_RGBA8888:
1303         case TBM_FORMAT_BGRA8888:
1304             bpp = 32;
1305             _offset = 0;
1306                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1307             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1308             break;
1309
1310         /* packed YCbCr */
1311         case TBM_FORMAT_YUYV:
1312         case TBM_FORMAT_YVYU:
1313         case TBM_FORMAT_UYVY:
1314         case TBM_FORMAT_VYUY:
1315         case TBM_FORMAT_AYUV:
1316             bpp = 32;
1317             _offset = 0;
1318                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1319             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1320             break;
1321
1322         /*
1323         * 2 plane YCbCr
1324         * index 0 = Y plane, [7:0] Y
1325         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1326         * or
1327         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1328         */
1329         case TBM_FORMAT_NV12:
1330         case TBM_FORMAT_NV21:
1331             bpp = 12;
1332             if(plane_idx == 0)
1333             {
1334                 _offset = 0;
1335                                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1336                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1337             }
1338             else if( plane_idx ==1 )
1339             {
1340                 _offset = width*height;
1341                                 _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1342                                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1343             }
1344             break;
1345
1346         case TBM_FORMAT_NV16:
1347         case TBM_FORMAT_NV61:
1348                         bpp = 16;
1349             //if(plane_idx == 0)
1350             {
1351                 _offset = 0;
1352                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1353                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1354                 if(plane_idx == 0)
1355                         break;
1356             }
1357             //else if( plane_idx ==1 )
1358             {
1359                 _offset += _size;
1360                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1361                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1362             }
1363             break;
1364
1365         /*
1366         * 3 plane YCbCr
1367         * index 0: Y plane, [7:0] Y
1368         * index 1: Cb plane, [7:0] Cb
1369         * index 2: Cr plane, [7:0] Cr
1370         * or
1371         * index 1: Cr plane, [7:0] Cr
1372         * index 2: Cb plane, [7:0] Cb
1373         */
1374         /*
1375         NATIVE_BUFFER_FORMAT_YV12
1376         NATIVE_BUFFER_FORMAT_I420
1377         */
1378         case TBM_FORMAT_YUV410:
1379         case TBM_FORMAT_YVU410:
1380             bpp = 9;
1381             break;
1382         case TBM_FORMAT_YUV411:
1383         case TBM_FORMAT_YVU411:
1384         case TBM_FORMAT_YUV420:
1385         case TBM_FORMAT_YVU420:
1386             bpp = 12;
1387             //if(plane_idx == 0)
1388             {
1389                 _offset = 0;
1390                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1391                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1392                         if(plane_idx == 0)
1393                                 break;
1394             }
1395             //else if( plane_idx == 1 )
1396             {
1397                 _offset += _size;
1398                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1399                         _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1400                         if(plane_idx == 1)
1401                                 break;
1402             }
1403             //else if (plane_idx == 2 )
1404             {
1405                 _offset += _size;
1406                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1407                 _size = SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1408             }
1409             break;
1410         case TBM_FORMAT_YUV422:
1411         case TBM_FORMAT_YVU422:
1412             bpp = 16;
1413             //if(plane_idx == 0)
1414             {
1415                 _offset = 0;
1416                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1417                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1418                         if(plane_idx == 0)
1419                                 break;
1420             }
1421             //else if( plane_idx == 1 )
1422             {
1423                 _offset += _size;
1424                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1425                         _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1426                         if(plane_idx == 1)
1427                                 break;
1428             }
1429             //else if (plane_idx == 2 )
1430             {
1431                 _offset += _size;
1432                         _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1433                 _size = SIZE_ALIGN(_pitch*(height),TBM_SURFACE_ALIGNMENT_PLANE);
1434             }
1435             break;
1436         case TBM_FORMAT_YUV444:
1437         case TBM_FORMAT_YVU444:
1438             bpp = 24;
1439             //if(plane_idx == 0)
1440             {
1441                 _offset = 0;
1442                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1443                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1444                         if(plane_idx == 0)
1445                                 break;
1446             }
1447             //else if( plane_idx == 1 )
1448             {
1449                 _offset += _size;
1450                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1451                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1452                         if(plane_idx == 1)
1453                                 break;
1454             }
1455             //else if (plane_idx == 2 )
1456             {
1457                 _offset += _size;
1458                         _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1459                _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1460             }
1461             break;
1462         default:
1463             bpp = 0;
1464             break;
1465     }
1466
1467     *size = _size;
1468     *offset = _offset;
1469     *pitch = _pitch;
1470
1471     return ret;
1472 }
1473 /**
1474 * @brief get the size of the surface with a format.
1475 * @param[in] surface : the surface
1476 * @param[in] width : the width of the surface
1477 * @param[in] height : the height of the surface
1478 * @param[in] format : the format of the surface
1479 * @return size of the surface if this function succeeds, otherwise 0.
1480 */
1481
1482 int
1483 tbm_exynos4412_surface_get_size(tbm_surface_h surface, int width, int height, tbm_format format)
1484 {
1485         int ret = 0;
1486         int bpp = 0;
1487         int _pitch =0;
1488         int _size =0;
1489         int align =TBM_SURFACE_ALIGNMENT_PLANE;
1490
1491     switch(format)
1492     {
1493         /* 16 bpp RGB */
1494         case TBM_FORMAT_XRGB4444:
1495         case TBM_FORMAT_XBGR4444:
1496         case TBM_FORMAT_RGBX4444:
1497         case TBM_FORMAT_BGRX4444:
1498         case TBM_FORMAT_ARGB4444:
1499         case TBM_FORMAT_ABGR4444:
1500         case TBM_FORMAT_RGBA4444:
1501         case TBM_FORMAT_BGRA4444:
1502         case TBM_FORMAT_XRGB1555:
1503         case TBM_FORMAT_XBGR1555:
1504         case TBM_FORMAT_RGBX5551:
1505         case TBM_FORMAT_BGRX5551:
1506         case TBM_FORMAT_ARGB1555:
1507         case TBM_FORMAT_ABGR1555:
1508         case TBM_FORMAT_RGBA5551:
1509         case TBM_FORMAT_BGRA5551:
1510         case TBM_FORMAT_RGB565:
1511             bpp = 16;
1512                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1513             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1514             break;
1515         /* 24 bpp RGB */
1516         case TBM_FORMAT_RGB888:
1517         case TBM_FORMAT_BGR888:
1518             bpp = 24;
1519                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1520             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1521             break;
1522         /* 32 bpp RGB */
1523         case TBM_FORMAT_XRGB8888:
1524         case TBM_FORMAT_XBGR8888:
1525         case TBM_FORMAT_RGBX8888:
1526         case TBM_FORMAT_BGRX8888:
1527         case TBM_FORMAT_ARGB8888:
1528         case TBM_FORMAT_ABGR8888:
1529         case TBM_FORMAT_RGBA8888:
1530         case TBM_FORMAT_BGRA8888:
1531             bpp = 32;
1532                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_RGB);
1533             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1534             break;
1535         /* packed YCbCr */
1536         case TBM_FORMAT_YUYV:
1537         case TBM_FORMAT_YVYU:
1538         case TBM_FORMAT_UYVY:
1539         case TBM_FORMAT_VYUY:
1540         case TBM_FORMAT_AYUV:
1541             bpp = 32;
1542                         _pitch = SIZE_ALIGN((width*bpp)>>3,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1543             _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1544             break;
1545         /*
1546         * 2 plane YCbCr
1547         * index 0 = Y plane, [7:0] Y
1548         * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
1549         * or
1550         * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
1551         */
1552         case TBM_FORMAT_NV12:
1553         case TBM_FORMAT_NV21:
1554                         bpp = 12;
1555                          //plane_idx == 0
1556                          {
1557                                  _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1558                                  _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1559                          }
1560                          //plane_idx ==1
1561                          {
1562                                  _pitch = SIZE_ALIGN( width ,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1563                                  _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1564                          }
1565                          break;
1566
1567             break;
1568         case TBM_FORMAT_NV16:
1569         case TBM_FORMAT_NV61:
1570             bpp = 16;
1571             //plane_idx == 0
1572             {
1573                                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1574                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1575             }
1576             //plane_idx ==1
1577             {
1578                             _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1579                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1580             }
1581
1582             break;
1583         /*
1584         * 3 plane YCbCr
1585         * index 0: Y plane, [7:0] Y
1586         * index 1: Cb plane, [7:0] Cb
1587         * index 2: Cr plane, [7:0] Cr
1588         * or
1589         * index 1: Cr plane, [7:0] Cr
1590         * index 2: Cb plane, [7:0] Cb
1591         */
1592         case TBM_FORMAT_YUV410:
1593         case TBM_FORMAT_YVU410:
1594             bpp = 9;
1595             align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1596             break;
1597         case TBM_FORMAT_YUV411:
1598         case TBM_FORMAT_YVU411:
1599         case TBM_FORMAT_YUV420:
1600         case TBM_FORMAT_YVU420:
1601             bpp = 12;
1602             //plane_idx == 0
1603             {
1604                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1605                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1606             }
1607             //plane_idx == 1
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             //plane_idx == 2
1613             {
1614                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1615                 _size += SIZE_ALIGN(_pitch*(height/2),TBM_SURFACE_ALIGNMENT_PLANE);
1616             }
1617
1618             break;
1619         case TBM_FORMAT_YUV422:
1620         case TBM_FORMAT_YVU422:
1621             bpp = 16;
1622             //plane_idx == 0
1623             {
1624                 _pitch = SIZE_ALIGN(width,TBM_SURFACE_ALIGNMENT_PITCH_YUV);
1625                 _size = SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1626             }
1627             //plane_idx == 1
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             //plane_idx == 2
1633             {
1634                 _pitch = SIZE_ALIGN(width/2,TBM_SURFACE_ALIGNMENT_PITCH_YUV/2);
1635                 _size += SIZE_ALIGN(_pitch*height,TBM_SURFACE_ALIGNMENT_PLANE);
1636             }
1637             break;
1638         case TBM_FORMAT_YUV444:
1639         case TBM_FORMAT_YVU444:
1640             bpp = 24;
1641             align = TBM_SURFACE_ALIGNMENT_PITCH_YUV;
1642             break;
1643
1644         default:
1645             bpp = 0;
1646             break;
1647     }
1648
1649         if(_size > 0)
1650                 ret = _size;
1651         else
1652             ret =  SIZE_ALIGN( (width * height * bpp) >> 3, align);
1653
1654     return ret;
1655
1656 }
1657
1658 MODULEINITPPROTO (init_tbm_bufmgr_priv);
1659
1660 static TBMModuleVersionInfo Exynos4412VersRec =
1661 {
1662     "exynos4412",
1663     "Samsung",
1664     TBM_ABI_VERSION,
1665 };
1666
1667 TBMModuleData tbmModuleData = { &Exynos4412VersRec, init_tbm_bufmgr_priv};
1668
1669 int
1670 init_tbm_bufmgr_priv (tbm_bufmgr bufmgr, int fd)
1671 {
1672     tbm_bufmgr_exynos4412 bufmgr_exynos4412;
1673     tbm_bufmgr_backend bufmgr_backend;
1674
1675     if (!bufmgr)
1676         return 0;
1677
1678     bufmgr_exynos4412 = calloc (1, sizeof(struct _tbm_bufmgr_exynos4412));
1679     if (!bufmgr_exynos4412)
1680     {
1681         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to alloc bufmgr_exynos4412!\n", getpid());
1682         return 0;
1683     }
1684
1685     bufmgr_exynos4412->fd = fd;
1686     if (bufmgr_exynos4412->fd < 0)
1687     {
1688         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
1689         free (bufmgr_exynos4412);
1690         return 0;
1691     }
1692
1693     //Create Hash Table
1694     bufmgr_exynos4412->hashBos = drmHashCreate ();
1695
1696     //Check if the tbm manager supports dma fence or not.
1697     int fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
1698     int length;
1699     char buf[1];
1700     if (fp != -1)
1701     {
1702         length = read(fp, buf, 1);
1703
1704         if (length == 1 && buf[0] == '1')
1705             bufmgr_exynos4412->use_dma_fence = 1;
1706
1707         close(fp);
1708     }
1709
1710     bufmgr_backend = tbm_backend_alloc();
1711     if (!bufmgr_backend)
1712     {
1713         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to create drm!\n", getpid());
1714         free (bufmgr_exynos4412);
1715         return 0;
1716     }
1717
1718     bufmgr_backend->priv = (void *)bufmgr_exynos4412;
1719     bufmgr_backend->bufmgr_deinit = tbm_exynos4412_bufmgr_deinit,
1720     bufmgr_backend->bo_size = tbm_exynos4412_bo_size,
1721     bufmgr_backend->bo_alloc = tbm_exynos4412_bo_alloc,
1722     bufmgr_backend->bo_free = tbm_exynos4412_bo_free,
1723     bufmgr_backend->bo_import = tbm_exynos4412_bo_import,
1724     bufmgr_backend->bo_import_fd = tbm_exynos4412_bo_import_fd,
1725     bufmgr_backend->bo_export = tbm_exynos4412_bo_export,
1726     bufmgr_backend->bo_export_fd = tbm_exynos4412_bo_export_fd,
1727     bufmgr_backend->bo_get_handle = tbm_exynos4412_bo_get_handle,
1728     bufmgr_backend->bo_map = tbm_exynos4412_bo_map,
1729     bufmgr_backend->bo_unmap = tbm_exynos4412_bo_unmap,
1730     bufmgr_backend->bo_cache_flush = tbm_exynos4412_bo_cache_flush,
1731     bufmgr_backend->bo_get_global_key = tbm_exynos4412_bo_get_global_key;
1732     bufmgr_backend->surface_get_plane_data = tbm_exynos4412_surface_get_plane_data;
1733     bufmgr_backend->surface_get_size = tbm_exynos4412_surface_get_size;
1734     bufmgr_backend->surface_supported_format = tbm_exynos4412_surface_supported_format;
1735
1736     if (bufmgr_exynos4412->use_dma_fence)
1737     {
1738         bufmgr_backend->flags = (TBM_LOCK_CTRL_BACKEND | TBM_CACHE_CTRL_BACKEND);
1739         bufmgr_backend->bo_lock = NULL;
1740         bufmgr_backend->bo_lock2 = tbm_exynos4412_bo_lock;
1741         bufmgr_backend->bo_unlock = tbm_exynos4412_bo_unlock;
1742     }
1743     else
1744     {
1745         bufmgr_backend->flags = 0;
1746         bufmgr_backend->bo_lock = NULL;
1747         bufmgr_backend->bo_unlock = NULL;
1748     }
1749
1750     if (!tbm_backend_init (bufmgr, bufmgr_backend))
1751     {
1752         TBM_EXYNOS4412_LOG ("[libtbm-exynos4412:%d] error: Fail to init backend!\n", getpid());
1753         tbm_backend_free (bufmgr_backend);
1754         free (bufmgr_exynos4412);
1755         return 0;
1756     }
1757
1758 #ifdef DEBUG
1759     {
1760         char* env;
1761         env = getenv ("TBM_EXYNOS4412_DEBUG");
1762         if (env)
1763         {
1764             bDebug = atoi (env);
1765             TBM_EXYNOS4412_LOG ("TBM_EXYNOS4412_DEBUG=%s\n", env);
1766         }
1767         else
1768         {
1769             bDebug = 0;
1770         }
1771     }
1772 #endif
1773
1774     DBG ("[libtbm-exynos4412:%d] %s DMABUF FENCE is %s\n", getpid(),
1775          __FUNCTION__, bufmgr_exynos4412->use_dma_fence ? "supported!" : "NOT supported!");
1776
1777     DBG ("[libtbm-exynos4412:%d] %s fd:%d\n", getpid(),
1778          __FUNCTION__, bufmgr_exynos4412->fd);
1779
1780     return 1;
1781 }
1782
1783