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