d4eb022fcdc6ce8be5271d12537bb472f64a709c
[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 struct list_head g_surface_list; /* list of surfaces belonging to bufmgr */
40
41 static pthread_mutex_t tbm_surface_lock;
42
43 static bool
44 _tbm_surface_mutex_init (void)
45 {
46     static bool tbm_surface_mutex_init = false;
47
48     if (tbm_surface_mutex_init)
49         return true;
50
51     if (pthread_mutex_init (&tbm_surface_lock, NULL))
52     {
53         TBM_LOG ("[libtbm] fail: tbm_surface mutex init\n");
54         return false;
55     }
56
57     tbm_surface_mutex_init = true;
58
59     return true;
60 }
61
62 void
63 _tbm_surface_mutex_lock (void)
64 {
65     if (!_tbm_surface_mutex_init ())
66         return;
67
68     pthread_mutex_lock (&tbm_surface_lock);
69 }
70
71 void
72 _tbm_surface_mutex_unlock (void)
73 {
74     pthread_mutex_unlock (&tbm_surface_lock);
75 }
76
77 static void
78 _init_surface_bufmgr()
79 {
80     g_surface_bufmgr = tbm_bufmgr_init (-1);
81 }
82
83 static void
84 _deinit_surface_bufmgr()
85 {
86     if (!g_surface_bufmgr)
87         return;
88
89     tbm_bufmgr_deinit (g_surface_bufmgr);
90     g_surface_bufmgr = NULL;
91 }
92
93 static int
94 _tbm_surface_internal_query_size (tbm_surface_h surface)
95 {
96     TBM_RETURN_VAL_IF_FAIL (surface, 0);
97
98     struct _tbm_surface *surf = (struct _tbm_surface *) surface;
99     struct _tbm_bufmgr *mgr = surf->bufmgr;
100     int size = 0;
101
102     TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
103     TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
104     TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
105     TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
106
107     if (!mgr->backend->surface_get_size)
108         return 0;
109
110     size = mgr->backend->surface_get_size (surf, surf->info.width, surf->info.height, surf->info.format);
111
112     return size;
113 }
114
115 static int
116 _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)
117 {
118     TBM_RETURN_VAL_IF_FAIL (surface, 0);
119     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
120
121     struct _tbm_surface *surf = (struct _tbm_surface *) surface;
122     struct _tbm_bufmgr *mgr = surf->bufmgr;
123     int ret = 0;
124
125     TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
126     TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
127     TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
128     TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
129
130     if (!mgr->backend->surface_get_plane_data)
131         return 0;
132
133     ret = mgr->backend->surface_get_plane_data (surf, surf->info.width, surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
134     if (!ret)
135         return 0;
136
137     return 1;
138 }
139
140 static int
141 _tbm_surface_internal_query_num_bos (tbm_format format)
142 {
143     TBM_RETURN_VAL_IF_FAIL (format > 0, 0);
144     struct _tbm_bufmgr *mgr;
145     int ret = 0;
146
147     mgr = g_surface_bufmgr;
148
149     if (!mgr->backend->surface_get_num_bos)
150         return 0;
151
152     ret = mgr->backend->surface_get_num_bos (format);
153     if (!ret)
154         return 0;
155
156     return ret;
157 }
158
159
160 int
161 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
162 {
163     struct _tbm_bufmgr *mgr;
164     int ret = 0;
165
166     _tbm_surface_mutex_lock();
167
168     if (!g_surface_bufmgr)
169     {
170         _init_surface_bufmgr();
171         LIST_INITHEAD (&g_surface_list);
172     }
173
174     mgr = g_surface_bufmgr;
175
176     if (!mgr->backend->surface_supported_format)
177     {
178         _tbm_surface_mutex_unlock();
179         return 0;
180     }
181
182     ret = mgr->backend->surface_supported_format (formats, num);
183
184     _tbm_surface_mutex_unlock();
185
186     return ret;
187 }
188
189
190 int tbm_surface_internal_get_num_planes (tbm_format format)
191 {
192     int num_planes = 0;
193
194     switch (format)
195     {
196         case TBM_FORMAT_C8:
197         case TBM_FORMAT_RGB332:
198         case TBM_FORMAT_BGR233:
199         case TBM_FORMAT_XRGB4444:
200         case TBM_FORMAT_XBGR4444:
201         case TBM_FORMAT_RGBX4444:
202         case TBM_FORMAT_BGRX4444:
203         case TBM_FORMAT_ARGB4444:
204         case TBM_FORMAT_ABGR4444:
205         case TBM_FORMAT_RGBA4444:
206         case TBM_FORMAT_BGRA4444:
207         case TBM_FORMAT_XRGB1555:
208         case TBM_FORMAT_XBGR1555:
209         case TBM_FORMAT_RGBX5551:
210         case TBM_FORMAT_BGRX5551:
211         case TBM_FORMAT_ARGB1555:
212         case TBM_FORMAT_ABGR1555:
213         case TBM_FORMAT_RGBA5551:
214         case TBM_FORMAT_BGRA5551:
215         case TBM_FORMAT_RGB565:
216         case TBM_FORMAT_BGR565:
217         case TBM_FORMAT_RGB888:
218         case TBM_FORMAT_BGR888:
219         case TBM_FORMAT_XRGB8888:
220         case TBM_FORMAT_XBGR8888:
221         case TBM_FORMAT_RGBX8888:
222         case TBM_FORMAT_BGRX8888:
223         case TBM_FORMAT_ARGB8888:
224         case TBM_FORMAT_ABGR8888:
225         case TBM_FORMAT_RGBA8888:
226         case TBM_FORMAT_BGRA8888:
227         case TBM_FORMAT_XRGB2101010:
228         case TBM_FORMAT_XBGR2101010:
229         case TBM_FORMAT_RGBX1010102:
230         case TBM_FORMAT_BGRX1010102:
231         case TBM_FORMAT_ARGB2101010:
232         case TBM_FORMAT_ABGR2101010:
233         case TBM_FORMAT_RGBA1010102:
234         case TBM_FORMAT_BGRA1010102:
235         case TBM_FORMAT_YUYV:
236         case TBM_FORMAT_YVYU:
237         case TBM_FORMAT_UYVY:
238         case TBM_FORMAT_VYUY:
239         case TBM_FORMAT_AYUV:
240             num_planes = 1;
241             break;
242         case TBM_FORMAT_NV12:
243         case TBM_FORMAT_NV21:
244         case TBM_FORMAT_NV16:
245         case TBM_FORMAT_NV61:
246             num_planes = 2;
247             break;
248         case TBM_FORMAT_YUV410:
249         case TBM_FORMAT_YVU410:
250         case TBM_FORMAT_YUV411:
251         case TBM_FORMAT_YVU411:
252         case TBM_FORMAT_YUV420:
253         case TBM_FORMAT_YVU420:
254         case TBM_FORMAT_YUV422:
255         case TBM_FORMAT_YVU422:
256         case TBM_FORMAT_YUV444:
257         case TBM_FORMAT_YVU444:
258             num_planes = 3;
259             break;
260
261         default :
262             break;
263     }
264
265     return num_planes;
266 }
267
268 int tbm_surface_internal_get_bpp (tbm_format format)
269 {
270     int bpp = 0;
271
272     switch (format)
273     {
274         case TBM_FORMAT_C8:
275         case TBM_FORMAT_RGB332:
276         case TBM_FORMAT_BGR233:
277             bpp = 8;
278             break;
279         case TBM_FORMAT_XRGB4444:
280         case TBM_FORMAT_XBGR4444:
281         case TBM_FORMAT_RGBX4444:
282         case TBM_FORMAT_BGRX4444:
283         case TBM_FORMAT_ARGB4444:
284         case TBM_FORMAT_ABGR4444:
285         case TBM_FORMAT_RGBA4444:
286         case TBM_FORMAT_BGRA4444:
287         case TBM_FORMAT_XRGB1555:
288         case TBM_FORMAT_XBGR1555:
289         case TBM_FORMAT_RGBX5551:
290         case TBM_FORMAT_BGRX5551:
291         case TBM_FORMAT_ARGB1555:
292         case TBM_FORMAT_ABGR1555:
293         case TBM_FORMAT_RGBA5551:
294         case TBM_FORMAT_BGRA5551:
295         case TBM_FORMAT_RGB565:
296         case TBM_FORMAT_BGR565:
297             bpp = 16;
298             break;
299         case TBM_FORMAT_RGB888:
300         case TBM_FORMAT_BGR888:
301             bpp = 24;
302             break;
303         case TBM_FORMAT_XRGB8888:
304         case TBM_FORMAT_XBGR8888:
305         case TBM_FORMAT_RGBX8888:
306         case TBM_FORMAT_BGRX8888:
307         case TBM_FORMAT_ARGB8888:
308         case TBM_FORMAT_ABGR8888:
309         case TBM_FORMAT_RGBA8888:
310         case TBM_FORMAT_BGRA8888:
311         case TBM_FORMAT_XRGB2101010:
312         case TBM_FORMAT_XBGR2101010:
313         case TBM_FORMAT_RGBX1010102:
314         case TBM_FORMAT_BGRX1010102:
315         case TBM_FORMAT_ARGB2101010:
316         case TBM_FORMAT_ABGR2101010:
317         case TBM_FORMAT_RGBA1010102:
318         case TBM_FORMAT_BGRA1010102:
319         case TBM_FORMAT_YUYV:
320         case TBM_FORMAT_YVYU:
321         case TBM_FORMAT_UYVY:
322         case TBM_FORMAT_VYUY:
323         case TBM_FORMAT_AYUV:
324             bpp = 32;
325             break;
326         case TBM_FORMAT_NV12:
327         case TBM_FORMAT_NV21:
328             bpp = 12;
329             break;
330         case TBM_FORMAT_NV16:
331         case TBM_FORMAT_NV61:
332             bpp = 16;
333             break;
334         case TBM_FORMAT_YUV410:
335         case TBM_FORMAT_YVU410:
336             bpp = 9;
337             break;
338         case TBM_FORMAT_YUV411:
339         case TBM_FORMAT_YVU411:
340         case TBM_FORMAT_YUV420:
341         case TBM_FORMAT_YVU420:
342             bpp = 12;
343             break;
344         case TBM_FORMAT_YUV422:
345         case TBM_FORMAT_YVU422:
346             bpp = 16;
347             break;
348         case TBM_FORMAT_YUV444:
349         case TBM_FORMAT_YVU444:
350             bpp = 24;
351             break;
352         default :
353             break;
354     }
355
356     return bpp;
357 }
358
359 tbm_surface_h
360 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
361 {
362     TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
363     TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
364
365     struct _tbm_bufmgr *mgr;
366     struct _tbm_surface *surf = NULL;
367     uint32_t size = 0;
368     uint32_t offset = 0;
369     uint32_t stride = 0;
370     uint32_t bo_size = 0;
371     int bo_idx;
372     int i, j;
373
374     _tbm_surface_mutex_lock();
375
376     if (!g_surface_bufmgr)
377     {
378         _init_surface_bufmgr();
379         LIST_INITHEAD (&g_surface_list);
380     }
381
382     mgr = g_surface_bufmgr;
383     if (!TBM_BUFMGR_IS_VALID(mgr))
384     {
385         _tbm_surface_mutex_unlock();
386         return NULL;
387     }
388     surf = calloc (1, sizeof(struct _tbm_surface));
389     if (!surf)
390     {
391         _tbm_surface_mutex_unlock();
392         return NULL;
393     }
394
395     surf->bufmgr = mgr;
396     surf->info.width = width;
397     surf->info.height = height;
398     surf->info.format = format;
399     surf->info.bpp = tbm_surface_internal_get_bpp (format);
400     surf->info.size = _tbm_surface_internal_query_size (surf);
401     surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
402     surf->num_bos = _tbm_surface_internal_query_num_bos(format);
403
404     /* get size, stride and offset bo_idx*/
405     for (i = 0; i < surf->info.num_planes; i++)
406     {
407         _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride, &bo_idx);
408         surf->info.planes[i].size = size;
409         surf->info.planes[i].offset = offset;
410         surf->info.planes[i].stride = stride;
411         surf->planes_bo_idx[i] = bo_idx;
412     }
413
414     surf->flags = flags;
415
416     for (i = 0; i < surf->num_bos; i++)
417     {
418         bo_size = 0;
419         for (j = 0; j < surf->info.num_planes; j++)
420         {
421             if (surf->planes_bo_idx[i] == i)
422                 bo_size += surf->info.planes[i].size;
423         }
424
425         surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
426         if (!surf->bos[i]) {
427             for (j = 0; j < i; j++)
428                 tbm_bo_unref (surf->bos[j]);
429
430             free (surf);
431             surf = NULL;
432
433             if(LIST_IS_EMPTY (&g_surface_list))
434             {
435                 _deinit_surface_bufmgr ();
436                 LIST_DELINIT (&g_surface_list);
437             }
438
439             _tbm_surface_mutex_unlock();
440             return NULL;
441         }
442     }
443
444     LIST_ADD (&surf->item_link, &g_surface_list);
445
446     _tbm_surface_mutex_unlock();
447
448     return surf;
449 }
450
451 tbm_surface_h
452 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
453 {
454     TBM_RETURN_VAL_IF_FAIL (bos, NULL);
455     TBM_RETURN_VAL_IF_FAIL (info, NULL);
456
457     struct _tbm_bufmgr *mgr;
458     struct _tbm_surface *surf = NULL;
459     int i;
460
461     _tbm_surface_mutex_lock();
462
463     if (!g_surface_bufmgr)
464     {
465         _init_surface_bufmgr();
466         LIST_INITHEAD (&g_surface_list);
467     }
468
469     mgr = g_surface_bufmgr;
470     if (!TBM_BUFMGR_IS_VALID(mgr))
471     {
472         _tbm_surface_mutex_unlock();
473         return NULL;
474     }
475     surf = calloc (1, sizeof(struct _tbm_surface));
476     if (!surf)
477     {
478         _tbm_surface_mutex_unlock();
479         return NULL;
480     }
481
482     surf->bufmgr = mgr;
483     surf->info.width = info->width;
484     surf->info.height = info->height;
485     surf->info.format = info->format;
486     surf->info.bpp = info->bpp;
487     surf->info.size = info->size;
488     surf->info.num_planes = info->num_planes;
489
490     /* get size, stride and offset */
491     for (i = 0; i < info->num_planes; i++)
492     {
493         surf->info.planes[i].size = info->planes[i].size;
494         surf->info.planes[i].offset = info->planes[i].offset;
495         surf->info.planes[i].stride = info->planes[i].stride;
496     }
497
498     surf->flags = TBM_BO_DEFAULT;
499
500     /* create only one bo */
501     surf->num_bos = num;
502     for (i = 0; i < num; i++)
503     {
504         if (bos[i] == NULL)
505             goto bail1;
506
507         surf->bos[i] = tbm_bo_ref(bos[i]);
508     }
509
510     LIST_ADD (&surf->item_link, &g_surface_list);
511
512     _tbm_surface_mutex_unlock();
513
514     return surf;
515 bail1:
516     for (i = 0; i < num; i++)
517     {
518         if (surf->bos[i])
519         {
520             tbm_bo_unref (surf->bos[i]);
521             surf->bos[i] = NULL;
522         }
523     }
524
525     free (surf);
526     surf = NULL;
527
528     if(LIST_IS_EMPTY (&g_surface_list))
529     {
530         _deinit_surface_bufmgr ();
531         LIST_DELINIT (&g_surface_list);
532     }
533
534     _tbm_surface_mutex_unlock();
535
536     return NULL;
537 }
538
539
540 void
541 tbm_surface_internal_destroy (tbm_surface_h surface)
542 {
543     int i;
544
545     if (!surface)
546         return;
547
548     _tbm_surface_mutex_lock();
549
550     surface = (struct _tbm_surface *)surface;
551
552     for (i = 0; i < surface->num_bos; i++)
553     {
554         tbm_bo_unref (surface->bos[i]);
555         surface->bos[i] = NULL;
556     }
557
558     LIST_DEL (&surface->item_link);
559
560     free (surface);
561     surface = NULL;
562
563     if(LIST_IS_EMPTY (&g_surface_list))
564     {
565         _deinit_surface_bufmgr ();
566         LIST_DELINIT (&g_surface_list);
567     }
568
569     _tbm_surface_mutex_unlock();
570 }
571
572
573 int
574 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
575 {
576     TBM_RETURN_VAL_IF_FAIL (surface, 0);
577
578     struct _tbm_surface *surf;
579     int num;
580
581     _tbm_surface_mutex_lock();
582
583     surf = (struct _tbm_surface *) surface;
584     num = surf->num_bos;
585
586     _tbm_surface_mutex_unlock();
587
588     return num;
589 }
590
591 tbm_bo
592 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
593 {
594     TBM_RETURN_VAL_IF_FAIL (surface, NULL);
595     TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
596
597     struct _tbm_surface *surf;
598     tbm_bo bo;
599
600     _tbm_surface_mutex_lock();
601
602     surf = (struct _tbm_surface *) surface;
603     bo = surf->bos[bo_idx];
604
605     _tbm_surface_mutex_unlock();
606
607     return bo;
608 }
609
610 int
611 tbm_surface_internal_get_size (tbm_surface_h surface)
612 {
613     TBM_RETURN_VAL_IF_FAIL (surface, 0);
614
615     struct _tbm_surface *surf;
616     unsigned int size;
617
618     _tbm_surface_mutex_lock();
619
620     surf = (struct _tbm_surface *) surface;
621     size = surf->info.size;
622
623     _tbm_surface_mutex_unlock();
624
625     return size;
626 }
627
628 int
629 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
630 {
631     TBM_RETURN_VAL_IF_FAIL (surface, 0);
632     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
633
634     struct _tbm_surface *surf;
635
636     _tbm_surface_mutex_lock();
637
638     surf = (struct _tbm_surface *) surface;
639
640     if (plane_idx >= surf->info.num_planes)
641     {
642         _tbm_surface_mutex_unlock();
643         return 0;
644     }
645
646     *size = surf->info.planes[plane_idx].size;
647     *offset = surf->info.planes[plane_idx].offset;
648     *pitch = surf->info.planes[plane_idx].stride;
649
650     _tbm_surface_mutex_unlock();
651
652     return 1;
653 }
654
655 int
656 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
657 {
658     struct _tbm_surface *surf;
659     tbm_bo_handle bo_handles[4];
660     int i, j;
661
662     _tbm_surface_mutex_lock();
663
664     memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
665
666     surf = (struct _tbm_surface *)surface;
667
668     info->width = surf->info.width;
669     info->height = surf->info.height;
670     info->format = surf->info.format;
671     info->bpp = surf->info.bpp;
672     info->size = surf->info.size;
673     info->num_planes = surf->info.num_planes;
674
675     if (map == 1)
676     {
677         for (i = 0; i < surf->num_bos; i++)
678         {
679             bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
680             if (bo_handles[i].ptr == NULL)
681             {
682                 for (j = 0; j < i; j++)
683                     tbm_bo_unmap (surf->bos[j]);
684
685                 _tbm_surface_mutex_unlock();
686                 return 0;
687             }
688         }
689     }
690     else
691     {
692         for (i = 0; i < surf->num_bos; i++)
693         {
694             bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
695             if (bo_handles[i].ptr == NULL)
696             {
697                 _tbm_surface_mutex_unlock();
698                 return 0;
699             }
700         }
701     }
702
703     for (i = 0; i < surf->info.num_planes; i++)
704     {
705         info->planes[i].size = surf->info.planes[i].size;
706         info->planes[i].offset = surf->info.planes[i].offset;
707         info->planes[i].stride = surf->info.planes[i].stride;
708         info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
709     }
710
711     _tbm_surface_mutex_unlock();
712
713     return 1;
714 }
715
716 void
717 tbm_surface_internal_unmap (tbm_surface_h surface)
718 {
719     struct _tbm_surface *surf;
720     int i;
721
722     _tbm_surface_mutex_lock();
723
724     surf = (struct _tbm_surface *)surface;
725
726     for (i = 0; i < surf->num_bos; i++)
727         tbm_bo_unmap (surf->bos[i]);
728
729     _tbm_surface_mutex_unlock();
730 }
731
732 unsigned int
733 tbm_surface_internal_get_width (tbm_surface_h surface)
734 {
735     struct _tbm_surface *surf;
736     unsigned int width;
737
738     _tbm_surface_mutex_lock();
739
740     surf = (struct _tbm_surface *)surface;
741     width = surf->info.width;
742
743     _tbm_surface_mutex_unlock();
744
745     return width;
746 }
747
748 unsigned int
749 tbm_surface_internal_get_height (tbm_surface_h surface)
750 {
751     struct _tbm_surface *surf;
752     unsigned int height;
753
754     _tbm_surface_mutex_lock();
755
756     surf = (struct _tbm_surface *)surface;
757     height = surf->info.height;
758
759     _tbm_surface_mutex_unlock();
760
761     return height;
762
763 }
764
765 tbm_format
766 tbm_surface_internal_get_format (tbm_surface_h surface)
767 {
768     struct _tbm_surface *surf;
769     tbm_format format;
770
771     _tbm_surface_mutex_lock();
772
773     surf = (struct _tbm_surface *)surface;
774     format = surf->info.format;
775
776     _tbm_surface_mutex_unlock();
777
778     return format;
779 }
780
781 int
782 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
783 {
784     TBM_RETURN_VAL_IF_FAIL (surface, 0);
785     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
786     struct _tbm_surface *surf;
787     int bo_idx;
788
789     _tbm_surface_mutex_lock();
790
791     surf = (struct _tbm_surface *)surface;
792     bo_idx = surf->planes_bo_idx[plane_idx];
793
794     _tbm_surface_mutex_unlock();
795
796     return bo_idx;
797 }
798