set the tbm_surface to the tbm_bo
[platform/core/uifw/libtbm.git] / src / tbm_surface_internal.c
1 /**************************************************************************
2
3 libtbm
4
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #include "config.h"
33 #include "tbm_bufmgr.h"
34 #include "tbm_bufmgr_int.h"
35 #include "tbm_surface_internal.h"
36 #include "list.h"
37
38 static tbm_bufmgr g_surface_bufmgr = NULL;
39 static pthread_mutex_t tbm_surface_lock;
40
41 char* _tbm_surface_internal_format_to_str(tbm_format format)
42 {
43         switch(format)
44     {
45     case TBM_FORMAT_C8              : return "TBM_FORMAT_C8";
46     case TBM_FORMAT_RGB332          : return "TBM_FORMAT_RGB332";
47     case TBM_FORMAT_BGR233                  : return "TBM_FORMAT_BGR233";
48     case TBM_FORMAT_XRGB4444            : return "TBM_FORMAT_XRGB4444";
49     case TBM_FORMAT_XBGR4444            : return "TBM_FORMAT_XBGR4444";
50     case TBM_FORMAT_RGBX4444            : return "TBM_FORMAT_RGBX4444";
51     case TBM_FORMAT_BGRX4444            : return "TBM_FORMAT_BGRX4444";
52     case TBM_FORMAT_ARGB4444            : return "TBM_FORMAT_ARGB4444";
53     case TBM_FORMAT_ABGR4444            : return "TBM_FORMAT_ABGR4444";
54     case TBM_FORMAT_RGBA4444            : return "TBM_FORMAT_RGBA4444";
55     case TBM_FORMAT_BGRA4444            : return "TBM_FORMAT_BGRA4444";
56     case TBM_FORMAT_XRGB1555            : return "TBM_FORMAT_XRGB1555";
57     case TBM_FORMAT_XBGR1555            : return "TBM_FORMAT_XBGR1555";
58     case TBM_FORMAT_RGBX5551            : return "TBM_FORMAT_RGBX5551";
59     case TBM_FORMAT_BGRX5551            : return "TBM_FORMAT_BGRX5551";
60     case TBM_FORMAT_ARGB1555            : return "TBM_FORMAT_ARGB1555";
61     case TBM_FORMAT_ABGR1555            : return "TBM_FORMAT_ABGR1555";
62     case TBM_FORMAT_RGBA5551            : return "TBM_FORMAT_RGBA5551";
63     case TBM_FORMAT_BGRA5551            : return "TBM_FORMAT_BGRA5551";
64     case TBM_FORMAT_RGB565                  : return "TBM_FORMAT_RGB565";
65     case TBM_FORMAT_BGR565                  : return "TBM_FORMAT_BGR565";
66     case TBM_FORMAT_RGB888                  : return "TBM_FORMAT_RGB888";
67     case TBM_FORMAT_BGR888                  : return "TBM_FORMAT_BGR888";
68     case TBM_FORMAT_XRGB8888            : return "TBM_FORMAT_XRGB8888";
69     case TBM_FORMAT_XBGR8888            : return "TBM_FORMAT_XBGR8888";
70     case TBM_FORMAT_RGBX8888            : return "TBM_FORMAT_RGBX8888";
71     case TBM_FORMAT_BGRX8888            : return "TBM_FORMAT_BGRX8888";
72     case TBM_FORMAT_ARGB8888            : return "TBM_FORMAT_ARGB8888";
73     case TBM_FORMAT_ABGR8888            : return "TBM_FORMAT_ABGR8888";
74     case TBM_FORMAT_RGBA8888            : return "TBM_FORMAT_RGBA8888";
75     case TBM_FORMAT_BGRA8888            : return "TBM_FORMAT_BGRA8888";
76     case TBM_FORMAT_XRGB2101010         : return "TBM_FORMAT_XRGB2101010";
77     case TBM_FORMAT_XBGR2101010         : return "TBM_FORMAT_XBGR2101010";
78     case TBM_FORMAT_RGBX1010102         : return "TBM_FORMAT_RGBX1010102";
79     case TBM_FORMAT_BGRX1010102         : return "TBM_FORMAT_BGRX1010102";
80     case TBM_FORMAT_ARGB2101010         : return "TBM_FORMAT_ARGB2101010";
81     case TBM_FORMAT_ABGR2101010         : return "TBM_FORMAT_ABGR2101010";
82     case TBM_FORMAT_RGBA1010102         : return "TBM_FORMAT_RGBA1010102";
83     case TBM_FORMAT_BGRA1010102         : return "TBM_FORMAT_BGRA1010102";
84     case TBM_FORMAT_YUYV                    : return "TBM_FORMAT_YUYV";
85     case TBM_FORMAT_YVYU                    : return "TBM_FORMAT_YVYU";
86     case TBM_FORMAT_UYVY                    : return "TBM_FORMAT_UYVY";
87     case TBM_FORMAT_VYUY                : return "TBM_FORMAT_VYUY";
88     case TBM_FORMAT_AYUV                : return "TBM_FORMAT_AYUV";
89     case TBM_FORMAT_NV12                : return "TBM_FORMAT_NV12";
90     case TBM_FORMAT_NV21                : return "TBM_FORMAT_NV21";
91     case TBM_FORMAT_NV16                : return "TBM_FORMAT_NV16";
92     case TBM_FORMAT_NV61                : return "TBM_FORMAT_NV61";
93     case TBM_FORMAT_YUV410              : return "TBM_FORMAT_YUV410";
94     case TBM_FORMAT_YVU410              : return "TBM_FORMAT_YVU410";
95     case TBM_FORMAT_YUV411                  : return "TBM_FORMAT_YUV411";
96     case TBM_FORMAT_YVU411              : return "TBM_FORMAT_YVU411";
97     case TBM_FORMAT_YUV420                  : return "TBM_FORMAT_YUV420";
98     case TBM_FORMAT_YVU420                  : return "TBM_FORMAT_YVU420";
99     case TBM_FORMAT_YUV422                  : return "TBM_FORMAT_YUV422";
100     case TBM_FORMAT_YVU422                  : return "TBM_FORMAT_YVU422";
101     case TBM_FORMAT_YUV444                  : return "TBM_FORMAT_YUV444";
102     case TBM_FORMAT_YVU444                  : return "TBM_FORMAT_YVU444";
103     case TBM_FORMAT_NV12MT                  : return "TBM_FORMAT_NV12MT";
104         default                         : return "unknwon";
105         }
106 }
107
108
109 static bool
110 _tbm_surface_mutex_init (void)
111 {
112     static bool tbm_surface_mutex_init = false;
113
114     if (tbm_surface_mutex_init)
115         return true;
116
117     if (pthread_mutex_init (&tbm_surface_lock, NULL))
118     {
119         TBM_LOG ("[libtbm] fail: tbm_surface mutex init\n");
120         return false;
121     }
122
123     tbm_surface_mutex_init = true;
124
125     return true;
126 }
127
128 void
129 _tbm_surface_mutex_lock (void)
130 {
131     if (!_tbm_surface_mutex_init ())
132         return;
133
134     pthread_mutex_lock (&tbm_surface_lock);
135 }
136
137 void
138 _tbm_surface_mutex_unlock (void)
139 {
140     pthread_mutex_unlock (&tbm_surface_lock);
141 }
142
143 static void
144 _init_surface_bufmgr()
145 {
146     g_surface_bufmgr = tbm_bufmgr_init (-1);
147 }
148
149 static void
150 _deinit_surface_bufmgr()
151 {
152     if (!g_surface_bufmgr)
153         return;
154
155     tbm_bufmgr_deinit (g_surface_bufmgr);
156     g_surface_bufmgr = NULL;
157 }
158
159 static int
160 _tbm_surface_internal_query_size (tbm_surface_h surface)
161 {
162     TBM_RETURN_VAL_IF_FAIL (surface, 0);
163
164     struct _tbm_surface *surf = (struct _tbm_surface *) surface;
165     struct _tbm_bufmgr *mgr = surf->bufmgr;
166     int size = 0;
167
168     TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
169     TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
170     TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
171     TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
172
173     if (!mgr->backend->surface_get_size)
174         return 0;
175
176     size = mgr->backend->surface_get_size (surf, surf->info.width, surf->info.height, surf->info.format);
177
178     return size;
179 }
180
181 static int
182 _tbm_surface_internal_query_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
183 {
184     TBM_RETURN_VAL_IF_FAIL (surface, 0);
185     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
186
187     struct _tbm_surface *surf = (struct _tbm_surface *) surface;
188     struct _tbm_bufmgr *mgr = surf->bufmgr;
189     int ret = 0;
190
191     TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
192     TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
193     TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
194     TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
195
196     if (!mgr->backend->surface_get_plane_data)
197         return 0;
198
199     ret = mgr->backend->surface_get_plane_data (surf, surf->info.width, surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
200     if (!ret)
201         return 0;
202
203     return 1;
204 }
205
206 static int
207 _tbm_surface_internal_query_num_bos (tbm_format format)
208 {
209     TBM_RETURN_VAL_IF_FAIL (format > 0, 0);
210     struct _tbm_bufmgr *mgr;
211     int ret = 0;
212
213     mgr = g_surface_bufmgr;
214
215     if (!mgr->backend->surface_get_num_bos)
216         return 0;
217
218     ret = mgr->backend->surface_get_num_bos (format);
219     if (!ret)
220         return 0;
221
222     return ret;
223 }
224
225 static void
226 _tbm_surface_internal_destroy (tbm_surface_h surface)
227 {
228     int i;
229         tbm_bufmgr bufmgr = surface->bufmgr;
230
231     for (i = 0; i < surface->num_bos; i++)
232     {
233                 surface->bos[i]->surface = NULL;
234
235         tbm_bo_unref (surface->bos[i]);
236         surface->bos[i] = NULL;
237     }
238
239     LIST_DEL (&surface->item_link);
240
241     free (surface);
242     surface = NULL;
243
244     if(LIST_IS_EMPTY (&bufmgr->surf_list))
245     {
246         LIST_DELINIT (&bufmgr->surf_list);
247         _deinit_surface_bufmgr ();
248     }
249
250 }
251
252
253 int
254 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
255 {
256     struct _tbm_bufmgr *mgr;
257     int ret = 0;
258
259     _tbm_surface_mutex_lock();
260
261     if (!g_surface_bufmgr)
262     {
263         _init_surface_bufmgr();
264         LIST_INITHEAD (&g_surface_bufmgr->surf_list);
265     }
266
267     mgr = g_surface_bufmgr;
268
269     if (!mgr->backend->surface_supported_format)
270     {
271         _tbm_surface_mutex_unlock();
272         return 0;
273     }
274
275     ret = mgr->backend->surface_supported_format (formats, num);
276
277     _tbm_surface_mutex_unlock();
278
279     return ret;
280 }
281
282
283 int tbm_surface_internal_get_num_planes (tbm_format format)
284 {
285     int num_planes = 0;
286
287     switch (format)
288     {
289         case TBM_FORMAT_C8:
290         case TBM_FORMAT_RGB332:
291         case TBM_FORMAT_BGR233:
292         case TBM_FORMAT_XRGB4444:
293         case TBM_FORMAT_XBGR4444:
294         case TBM_FORMAT_RGBX4444:
295         case TBM_FORMAT_BGRX4444:
296         case TBM_FORMAT_ARGB4444:
297         case TBM_FORMAT_ABGR4444:
298         case TBM_FORMAT_RGBA4444:
299         case TBM_FORMAT_BGRA4444:
300         case TBM_FORMAT_XRGB1555:
301         case TBM_FORMAT_XBGR1555:
302         case TBM_FORMAT_RGBX5551:
303         case TBM_FORMAT_BGRX5551:
304         case TBM_FORMAT_ARGB1555:
305         case TBM_FORMAT_ABGR1555:
306         case TBM_FORMAT_RGBA5551:
307         case TBM_FORMAT_BGRA5551:
308         case TBM_FORMAT_RGB565:
309         case TBM_FORMAT_BGR565:
310         case TBM_FORMAT_RGB888:
311         case TBM_FORMAT_BGR888:
312         case TBM_FORMAT_XRGB8888:
313         case TBM_FORMAT_XBGR8888:
314         case TBM_FORMAT_RGBX8888:
315         case TBM_FORMAT_BGRX8888:
316         case TBM_FORMAT_ARGB8888:
317         case TBM_FORMAT_ABGR8888:
318         case TBM_FORMAT_RGBA8888:
319         case TBM_FORMAT_BGRA8888:
320         case TBM_FORMAT_XRGB2101010:
321         case TBM_FORMAT_XBGR2101010:
322         case TBM_FORMAT_RGBX1010102:
323         case TBM_FORMAT_BGRX1010102:
324         case TBM_FORMAT_ARGB2101010:
325         case TBM_FORMAT_ABGR2101010:
326         case TBM_FORMAT_RGBA1010102:
327         case TBM_FORMAT_BGRA1010102:
328         case TBM_FORMAT_YUYV:
329         case TBM_FORMAT_YVYU:
330         case TBM_FORMAT_UYVY:
331         case TBM_FORMAT_VYUY:
332         case TBM_FORMAT_AYUV:
333             num_planes = 1;
334             break;
335         case TBM_FORMAT_NV12:
336         case TBM_FORMAT_NV21:
337         case TBM_FORMAT_NV16:
338         case TBM_FORMAT_NV61:
339             num_planes = 2;
340             break;
341         case TBM_FORMAT_YUV410:
342         case TBM_FORMAT_YVU410:
343         case TBM_FORMAT_YUV411:
344         case TBM_FORMAT_YVU411:
345         case TBM_FORMAT_YUV420:
346         case TBM_FORMAT_YVU420:
347         case TBM_FORMAT_YUV422:
348         case TBM_FORMAT_YVU422:
349         case TBM_FORMAT_YUV444:
350         case TBM_FORMAT_YVU444:
351             num_planes = 3;
352             break;
353
354         default :
355             break;
356     }
357
358     return num_planes;
359 }
360
361 int tbm_surface_internal_get_bpp (tbm_format format)
362 {
363     int bpp = 0;
364
365     switch (format)
366     {
367         case TBM_FORMAT_C8:
368         case TBM_FORMAT_RGB332:
369         case TBM_FORMAT_BGR233:
370             bpp = 8;
371             break;
372         case TBM_FORMAT_XRGB4444:
373         case TBM_FORMAT_XBGR4444:
374         case TBM_FORMAT_RGBX4444:
375         case TBM_FORMAT_BGRX4444:
376         case TBM_FORMAT_ARGB4444:
377         case TBM_FORMAT_ABGR4444:
378         case TBM_FORMAT_RGBA4444:
379         case TBM_FORMAT_BGRA4444:
380         case TBM_FORMAT_XRGB1555:
381         case TBM_FORMAT_XBGR1555:
382         case TBM_FORMAT_RGBX5551:
383         case TBM_FORMAT_BGRX5551:
384         case TBM_FORMAT_ARGB1555:
385         case TBM_FORMAT_ABGR1555:
386         case TBM_FORMAT_RGBA5551:
387         case TBM_FORMAT_BGRA5551:
388         case TBM_FORMAT_RGB565:
389         case TBM_FORMAT_BGR565:
390             bpp = 16;
391             break;
392         case TBM_FORMAT_RGB888:
393         case TBM_FORMAT_BGR888:
394             bpp = 24;
395             break;
396         case TBM_FORMAT_XRGB8888:
397         case TBM_FORMAT_XBGR8888:
398         case TBM_FORMAT_RGBX8888:
399         case TBM_FORMAT_BGRX8888:
400         case TBM_FORMAT_ARGB8888:
401         case TBM_FORMAT_ABGR8888:
402         case TBM_FORMAT_RGBA8888:
403         case TBM_FORMAT_BGRA8888:
404         case TBM_FORMAT_XRGB2101010:
405         case TBM_FORMAT_XBGR2101010:
406         case TBM_FORMAT_RGBX1010102:
407         case TBM_FORMAT_BGRX1010102:
408         case TBM_FORMAT_ARGB2101010:
409         case TBM_FORMAT_ABGR2101010:
410         case TBM_FORMAT_RGBA1010102:
411         case TBM_FORMAT_BGRA1010102:
412         case TBM_FORMAT_YUYV:
413         case TBM_FORMAT_YVYU:
414         case TBM_FORMAT_UYVY:
415         case TBM_FORMAT_VYUY:
416         case TBM_FORMAT_AYUV:
417             bpp = 32;
418             break;
419         case TBM_FORMAT_NV12:
420         case TBM_FORMAT_NV21:
421             bpp = 12;
422             break;
423         case TBM_FORMAT_NV16:
424         case TBM_FORMAT_NV61:
425             bpp = 16;
426             break;
427         case TBM_FORMAT_YUV410:
428         case TBM_FORMAT_YVU410:
429             bpp = 9;
430             break;
431         case TBM_FORMAT_YUV411:
432         case TBM_FORMAT_YVU411:
433         case TBM_FORMAT_YUV420:
434         case TBM_FORMAT_YVU420:
435             bpp = 12;
436             break;
437         case TBM_FORMAT_YUV422:
438         case TBM_FORMAT_YVU422:
439             bpp = 16;
440             break;
441         case TBM_FORMAT_YUV444:
442         case TBM_FORMAT_YVU444:
443             bpp = 24;
444             break;
445         default :
446             break;
447     }
448
449     return bpp;
450 }
451
452 tbm_surface_h
453 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
454 {
455     TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
456     TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
457
458     struct _tbm_bufmgr *mgr;
459     struct _tbm_surface *surf = NULL;
460     uint32_t size = 0;
461     uint32_t offset = 0;
462     uint32_t stride = 0;
463     uint32_t bo_size = 0;
464     int bo_idx;
465     int i, j;
466
467     _tbm_surface_mutex_lock();
468
469     if (!g_surface_bufmgr)
470     {
471         _init_surface_bufmgr();
472         LIST_INITHEAD (&g_surface_bufmgr->surf_list);
473     }
474
475     mgr = g_surface_bufmgr;
476     if (!TBM_BUFMGR_IS_VALID(mgr))
477     {
478         _tbm_surface_mutex_unlock();
479         return NULL;
480     }
481     surf = calloc (1, sizeof(struct _tbm_surface));
482     if (!surf)
483     {
484         _tbm_surface_mutex_unlock();
485         return NULL;
486     }
487
488     surf->bufmgr = mgr;
489     surf->info.width = width;
490     surf->info.height = height;
491     surf->info.format = format;
492     surf->info.bpp = tbm_surface_internal_get_bpp (format);
493     surf->info.size = _tbm_surface_internal_query_size (surf);
494     surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
495     surf->num_bos = _tbm_surface_internal_query_num_bos(format);
496     surf->refcnt = 1;
497
498     /* get size, stride and offset bo_idx*/
499     for (i = 0; i < surf->info.num_planes; i++)
500     {
501         _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride, &bo_idx);
502         surf->info.planes[i].size = size;
503         surf->info.planes[i].offset = offset;
504         surf->info.planes[i].stride = stride;
505         surf->planes_bo_idx[i] = bo_idx;
506     }
507
508     surf->flags = flags;
509
510     for (i = 0; i < surf->num_bos; i++)
511     {
512         bo_size = 0;
513         for (j = 0; j < surf->info.num_planes; j++)
514         {
515             if (surf->planes_bo_idx[j] == i)
516                 bo_size += surf->info.planes[j].size;
517         }
518         surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
519         if (!surf->bos[i]) {
520             for (j = 0; j < i; j++)
521                 tbm_bo_unref (surf->bos[j]);
522
523             free (surf);
524             surf = NULL;
525
526             if(LIST_IS_EMPTY (&mgr->surf_list))
527             {
528                 LIST_DELINIT (&mgr->surf_list);
529                 _deinit_surface_bufmgr ();
530             }
531
532             _tbm_surface_mutex_unlock();
533             return NULL;
534         }
535                 _tbm_bo_set_surface(surf->bos[i], surf);
536
537     }
538
539     LIST_ADD (&surf->item_link, &mgr->surf_list);
540
541     _tbm_surface_mutex_unlock();
542
543     return surf;
544 }
545
546 tbm_surface_h
547 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
548 {
549     TBM_RETURN_VAL_IF_FAIL (bos, NULL);
550     TBM_RETURN_VAL_IF_FAIL (info, NULL);
551     TBM_RETURN_VAL_IF_FAIL (num == 1 || info->num_planes == num, NULL);
552
553     struct _tbm_bufmgr *mgr;
554     struct _tbm_surface *surf = NULL;
555     int i;
556
557     _tbm_surface_mutex_lock();
558
559     if (!g_surface_bufmgr)
560     {
561         _init_surface_bufmgr();
562         LIST_INITHEAD (&g_surface_bufmgr->surf_list);
563     }
564
565     mgr = g_surface_bufmgr;
566     if (!TBM_BUFMGR_IS_VALID(mgr))
567     {
568         _tbm_surface_mutex_unlock();
569         return NULL;
570     }
571
572     surf = calloc (1, sizeof(struct _tbm_surface));
573     if (!surf)
574     {
575         _tbm_surface_mutex_unlock();
576         return NULL;
577     }
578
579     surf->bufmgr = mgr;
580     surf->info.width = info->width;
581     surf->info.height = info->height;
582     surf->info.format = info->format;
583     surf->info.bpp = info->bpp;
584     surf->info.num_planes = info->num_planes;
585     surf->refcnt = 1;
586
587     /* get size, stride and offset */
588     for (i = 0; i < info->num_planes; i++)
589     {
590         surf->info.planes[i].offset = info->planes[i].offset;
591         surf->info.planes[i].stride = info->planes[i].stride;
592
593         if (info->planes[i].size > 0)
594             surf->info.planes[i].size = info->planes[i].size;
595         else
596             surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
597
598         if (num == 1)
599             surf->planes_bo_idx[i] = 0;
600         else
601             surf->planes_bo_idx[i] = i;
602     }
603
604     if (info->size > 0)
605     {
606         surf->info.size = info->size;
607     }
608     else
609     {
610         surf->info.size = 0;
611         for (i = 0; i < info->num_planes; i++)
612         {
613             surf->info.size += surf->info.planes[i].size;
614         }
615     }
616
617     surf->flags = TBM_BO_DEFAULT;
618
619     /* create only one bo */
620     surf->num_bos = num;
621     for (i = 0; i < num; i++)
622     {
623         if (bos[i] == NULL)
624             goto bail1;
625
626         surf->bos[i] = tbm_bo_ref(bos[i]);
627                 _tbm_bo_set_surface(bos[i], surf);
628     }
629
630     LIST_ADD (&surf->item_link, &mgr->surf_list);
631
632     _tbm_surface_mutex_unlock();
633
634     return surf;
635 bail1:
636     for (i = 0; i < num; i++)
637     {
638         if (surf->bos[i])
639         {
640             tbm_bo_unref (surf->bos[i]);
641             surf->bos[i] = NULL;
642         }
643     }
644
645     free (surf);
646     surf = NULL;
647
648     if(LIST_IS_EMPTY (&g_surface_bufmgr->surf_list))
649     {
650         LIST_DELINIT (&g_surface_bufmgr->surf_list);
651         _deinit_surface_bufmgr ();
652     }
653
654     _tbm_surface_mutex_unlock();
655
656     return NULL;
657 }
658
659
660 void
661 tbm_surface_internal_destroy (tbm_surface_h surface)
662 {
663     if (!surface)
664         return;
665
666     _tbm_surface_mutex_lock();
667
668     surface->refcnt--;
669
670     if (surface->refcnt > 0) {
671         _tbm_surface_mutex_unlock();
672         return;
673     }
674
675     if (surface->refcnt == 0)
676         _tbm_surface_internal_destroy(surface);
677
678     _tbm_surface_mutex_unlock();
679 }
680
681
682 void
683 tbm_surface_internal_ref (tbm_surface_h surface)
684 {
685     TBM_RETURN_IF_FAIL (surface);
686
687     _tbm_surface_mutex_lock();
688
689     surface->refcnt++;
690
691     _tbm_surface_mutex_unlock();
692 }
693
694 void
695 tbm_surface_internal_unref (tbm_surface_h surface)
696 {
697     TBM_RETURN_IF_FAIL (surface);
698
699     _tbm_surface_mutex_lock();
700
701     surface->refcnt--;
702
703     if (surface->refcnt > 0) {
704         _tbm_surface_mutex_unlock();
705         return;
706     }
707
708     if (surface->refcnt == 0)
709         _tbm_surface_internal_destroy(surface);
710
711     _tbm_surface_mutex_unlock();
712 }
713
714 int
715 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
716 {
717     TBM_RETURN_VAL_IF_FAIL (surface, 0);
718
719     struct _tbm_surface *surf;
720     int num;
721
722     _tbm_surface_mutex_lock();
723
724     surf = (struct _tbm_surface *) surface;
725     num = surf->num_bos;
726
727     _tbm_surface_mutex_unlock();
728
729     return num;
730 }
731
732 tbm_bo
733 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
734 {
735     TBM_RETURN_VAL_IF_FAIL (surface, NULL);
736     TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
737
738     struct _tbm_surface *surf;
739     tbm_bo bo;
740
741     _tbm_surface_mutex_lock();
742
743     surf = (struct _tbm_surface *) surface;
744     bo = surf->bos[bo_idx];
745
746     _tbm_surface_mutex_unlock();
747
748     return bo;
749 }
750
751 int
752 tbm_surface_internal_get_size (tbm_surface_h surface)
753 {
754     TBM_RETURN_VAL_IF_FAIL (surface, 0);
755
756     struct _tbm_surface *surf;
757     unsigned int size;
758
759     _tbm_surface_mutex_lock();
760
761     surf = (struct _tbm_surface *) surface;
762     size = surf->info.size;
763
764     _tbm_surface_mutex_unlock();
765
766     return size;
767 }
768
769 int
770 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
771 {
772     TBM_RETURN_VAL_IF_FAIL (surface, 0);
773     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
774
775     struct _tbm_surface *surf;
776
777     _tbm_surface_mutex_lock();
778
779     surf = (struct _tbm_surface *) surface;
780
781     if (plane_idx >= surf->info.num_planes)
782     {
783         _tbm_surface_mutex_unlock();
784         return 0;
785     }
786
787     *size = surf->info.planes[plane_idx].size;
788     *offset = surf->info.planes[plane_idx].offset;
789     *pitch = surf->info.planes[plane_idx].stride;
790
791     _tbm_surface_mutex_unlock();
792
793     return 1;
794 }
795
796 int
797 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
798 {
799     struct _tbm_surface *surf;
800     tbm_bo_handle bo_handles[4];
801     int i, j;
802
803     _tbm_surface_mutex_lock();
804
805     memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
806
807     surf = (struct _tbm_surface *)surface;
808
809     info->width = surf->info.width;
810     info->height = surf->info.height;
811     info->format = surf->info.format;
812     info->bpp = surf->info.bpp;
813     info->size = surf->info.size;
814     info->num_planes = surf->info.num_planes;
815
816     if (map == 1)
817     {
818         for (i = 0; i < surf->num_bos; i++)
819         {
820             bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
821             if (bo_handles[i].ptr == NULL)
822             {
823                 for (j = 0; j < i; j++)
824                     tbm_bo_unmap (surf->bos[j]);
825
826                 _tbm_surface_mutex_unlock();
827                 return 0;
828             }
829         }
830     }
831     else
832     {
833         for (i = 0; i < surf->num_bos; i++)
834         {
835             bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
836             if (bo_handles[i].ptr == NULL)
837             {
838                 _tbm_surface_mutex_unlock();
839                 return 0;
840             }
841         }
842     }
843
844     for (i = 0; i < surf->info.num_planes; i++)
845     {
846         info->planes[i].size = surf->info.planes[i].size;
847         info->planes[i].offset = surf->info.planes[i].offset;
848         info->planes[i].stride = surf->info.planes[i].stride;
849         info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
850     }
851
852     _tbm_surface_mutex_unlock();
853
854     return 1;
855 }
856
857 void
858 tbm_surface_internal_unmap (tbm_surface_h surface)
859 {
860     struct _tbm_surface *surf;
861     int i;
862
863     _tbm_surface_mutex_lock();
864
865     surf = (struct _tbm_surface *)surface;
866
867     for (i = 0; i < surf->num_bos; i++)
868         tbm_bo_unmap (surf->bos[i]);
869
870     _tbm_surface_mutex_unlock();
871 }
872
873 unsigned int
874 tbm_surface_internal_get_width (tbm_surface_h surface)
875 {
876     struct _tbm_surface *surf;
877     unsigned int width;
878
879     _tbm_surface_mutex_lock();
880
881     surf = (struct _tbm_surface *)surface;
882     width = surf->info.width;
883
884     _tbm_surface_mutex_unlock();
885
886     return width;
887 }
888
889 unsigned int
890 tbm_surface_internal_get_height (tbm_surface_h surface)
891 {
892     struct _tbm_surface *surf;
893     unsigned int height;
894
895     _tbm_surface_mutex_lock();
896
897     surf = (struct _tbm_surface *)surface;
898     height = surf->info.height;
899
900     _tbm_surface_mutex_unlock();
901
902     return height;
903
904 }
905
906 tbm_format
907 tbm_surface_internal_get_format (tbm_surface_h surface)
908 {
909     struct _tbm_surface *surf;
910     tbm_format format;
911
912     _tbm_surface_mutex_lock();
913
914     surf = (struct _tbm_surface *)surface;
915     format = surf->info.format;
916
917     _tbm_surface_mutex_unlock();
918
919     return format;
920 }
921
922 int
923 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
924 {
925     TBM_RETURN_VAL_IF_FAIL (surface, 0);
926     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
927     struct _tbm_surface *surf;
928     int bo_idx;
929
930     _tbm_surface_mutex_lock();
931
932     surf = (struct _tbm_surface *)surface;
933     bo_idx = surf->planes_bo_idx[plane_idx];
934
935     _tbm_surface_mutex_unlock();
936
937     return bo_idx;
938 }
939