Surpport multiple bo surface
[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                 _tbm_surface_mutex_unlock();
438                 return NULL;
439             }
440         }
441     }
442
443     LIST_ADD (&surf->item_link, &g_surface_list);
444
445     _tbm_surface_mutex_unlock();
446
447     return surf;
448 }
449
450 tbm_surface_h
451 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
452 {
453     TBM_RETURN_VAL_IF_FAIL (bos, NULL);
454     TBM_RETURN_VAL_IF_FAIL (info, NULL);
455
456     struct _tbm_bufmgr *mgr;
457     struct _tbm_surface *surf = NULL;
458     int i;
459
460     _tbm_surface_mutex_lock();
461
462     if (!g_surface_bufmgr)
463     {
464         _init_surface_bufmgr();
465         LIST_INITHEAD (&g_surface_list);
466     }
467
468     mgr = g_surface_bufmgr;
469     if (!TBM_BUFMGR_IS_VALID(mgr))
470     {
471         _tbm_surface_mutex_unlock();
472         return NULL;
473     }
474     surf = calloc (1, sizeof(struct _tbm_surface));
475     if (!surf)
476     {
477         _tbm_surface_mutex_unlock();
478         return NULL;
479     }
480
481     surf->bufmgr = mgr;
482     surf->info.width = info->width;
483     surf->info.height = info->height;
484     surf->info.format = info->format;
485     surf->info.bpp = info->bpp;
486     surf->info.size = info->size;
487     surf->info.num_planes = info->num_planes;
488
489     /* get size, stride and offset */
490     for (i = 0; i < info->num_planes; i++)
491     {
492         surf->info.planes[i].size = info->planes[i].size;
493         surf->info.planes[i].offset = info->planes[i].offset;
494         surf->info.planes[i].stride = info->planes[i].stride;
495     }
496
497     surf->flags = TBM_BO_DEFAULT;
498
499     /* create only one bo */
500     surf->num_bos = num;
501     for (i = 0; i < num; i++)
502     {
503         if (bos[i] == NULL)
504             goto bail1;
505
506         surf->bos[i] = tbm_bo_ref(bos[i]);
507     }
508
509     LIST_ADD (&surf->item_link, &g_surface_list);
510
511     _tbm_surface_mutex_unlock();
512
513     return surf;
514 bail1:
515     for (i = 0; i < num; i++)
516     {
517         if (surf->bos[i])
518         {
519             tbm_bo_unref (surf->bos[i]);
520             surf->bos[i] = NULL;
521         }
522     }
523
524     free (surf);
525     surf = NULL;
526
527     if(LIST_IS_EMPTY (&g_surface_list))
528     {
529         _deinit_surface_bufmgr ();
530         LIST_DELINIT (&g_surface_list);
531     }
532
533     _tbm_surface_mutex_unlock();
534
535     return NULL;
536 }
537
538
539 void
540 tbm_surface_internal_destroy (tbm_surface_h surface)
541 {
542     int i;
543
544     if (!surface)
545         return;
546
547     _tbm_surface_mutex_lock();
548
549     surface = (struct _tbm_surface *)surface;
550
551     for (i = 0; i < surface->num_bos; i++)
552     {
553         tbm_bo_unref (surface->bos[i]);
554         surface->bos[i] = NULL;
555     }
556
557     LIST_DEL (&surface->item_link);
558
559     free (surface);
560     surface = NULL;
561
562     if(LIST_IS_EMPTY (&g_surface_list))
563     {
564         _deinit_surface_bufmgr ();
565         LIST_DELINIT (&g_surface_list);
566     }
567
568     _tbm_surface_mutex_unlock();
569 }
570
571
572 int
573 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
574 {
575     TBM_RETURN_VAL_IF_FAIL (surface, 0);
576
577     struct _tbm_surface *surf;
578     int num;
579
580     _tbm_surface_mutex_lock();
581
582     surf = (struct _tbm_surface *) surface;
583     num = surf->num_bos;
584
585     _tbm_surface_mutex_unlock();
586
587     return num;
588 }
589
590 tbm_bo
591 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
592 {
593     TBM_RETURN_VAL_IF_FAIL (surface, NULL);
594     TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
595
596     struct _tbm_surface *surf;
597     tbm_bo bo;
598
599     _tbm_surface_mutex_lock();
600
601     surf = (struct _tbm_surface *) surface;
602     bo = surf->bos[bo_idx];
603
604     _tbm_surface_mutex_unlock();
605
606     return bo;
607 }
608
609 int
610 tbm_surface_internal_get_size (tbm_surface_h surface)
611 {
612     TBM_RETURN_VAL_IF_FAIL (surface, 0);
613
614     struct _tbm_surface *surf;
615     unsigned int size;
616
617     _tbm_surface_mutex_lock();
618
619     surf = (struct _tbm_surface *) surface;
620     size = surf->info.size;
621
622     _tbm_surface_mutex_unlock();
623
624     return size;
625 }
626
627 int
628 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
629 {
630     TBM_RETURN_VAL_IF_FAIL (surface, 0);
631     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
632
633     struct _tbm_surface *surf;
634
635     _tbm_surface_mutex_lock();
636
637     surf = (struct _tbm_surface *) surface;
638
639     if (plane_idx >= surf->info.num_planes)
640     {
641         _tbm_surface_mutex_unlock();
642         return 0;
643     }
644
645     *size = surf->info.planes[plane_idx].size;
646     *offset = surf->info.planes[plane_idx].offset;
647     *pitch = surf->info.planes[plane_idx].stride;
648
649     _tbm_surface_mutex_unlock();
650
651     return 1;
652 }
653
654 int
655 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
656 {
657     struct _tbm_surface *surf;
658     tbm_bo_handle bo_handles[4];
659     int i, j;
660
661     _tbm_surface_mutex_lock();
662
663     surf = (struct _tbm_surface *)surface;
664
665     info->width = surf->info.width;
666     info->height = surf->info.height;
667     info->format = surf->info.format;
668     info->bpp = surf->info.bpp;
669     info->size = surf->info.size;
670     info->num_planes = surf->info.num_planes;
671
672     if (map == 1)
673     {
674         for (i = 0; i < surf->num_bos; i++)
675         {
676             bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
677             if (bo_handles[i].ptr == NULL)
678             {
679                 for (j = 0; j < i; j++)
680                     tbm_bo_unmap (surf->bos[j]);
681
682                 _tbm_surface_mutex_unlock();
683                 return 0;
684             }
685         }
686     }
687     else
688     {
689         for (i = 0; i < surf->num_bos; i++)
690         {
691             bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
692             if (bo_handles[i].ptr == NULL)
693             {
694                 _tbm_surface_mutex_unlock();
695                 return 0;
696             }
697         }
698     }
699
700     for (i = 0; i < surf->info.num_planes; i++)
701     {
702         info->planes[i].size = surf->info.planes[i].size;
703         info->planes[i].offset = surf->info.planes[i].offset;
704         info->planes[i].stride = surf->info.planes[i].stride;
705         info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
706     }
707
708     _tbm_surface_mutex_unlock();
709
710     return 1;
711 }
712
713 void
714 tbm_surface_internal_unmap (tbm_surface_h surface)
715 {
716     struct _tbm_surface *surf;
717     int i;
718
719     _tbm_surface_mutex_lock();
720
721     surf = (struct _tbm_surface *)surface;
722
723     for (i = 0; i < surf->num_bos; i++)
724         tbm_bo_unmap (surf->bos[i]);
725
726     _tbm_surface_mutex_unlock();
727 }
728
729 unsigned int
730 tbm_surface_internal_get_width (tbm_surface_h surface)
731 {
732     struct _tbm_surface *surf;
733     unsigned int width;
734
735     _tbm_surface_mutex_lock();
736
737     surf = (struct _tbm_surface *)surface;
738     width = surf->info.width;
739
740     _tbm_surface_mutex_unlock();
741
742     return width;
743 }
744
745 unsigned int
746 tbm_surface_internal_get_height (tbm_surface_h surface)
747 {
748     struct _tbm_surface *surf;
749     unsigned int height;
750
751     _tbm_surface_mutex_lock();
752
753     surf = (struct _tbm_surface *)surface;
754     height = surf->info.height;
755
756     _tbm_surface_mutex_unlock();
757
758     return height;
759
760 }
761
762 tbm_format
763 tbm_surface_internal_get_format (tbm_surface_h surface)
764 {
765     struct _tbm_surface *surf;
766     tbm_format format;
767
768     _tbm_surface_mutex_lock();
769
770     surf = (struct _tbm_surface *)surface;
771     format = surf->info.format;
772
773     _tbm_surface_mutex_unlock();
774
775     return format;
776 }
777