add the reference count for tbm_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 static void
160 _tbm_surface_internal_destroy (tbm_surface_h surface)
161 {
162     int i;
163
164     surface = (struct _tbm_surface *)surface;
165
166     for (i = 0; i < surface->num_bos; i++)
167     {
168         tbm_bo_unref (surface->bos[i]);
169         surface->bos[i] = NULL;
170     }
171
172     LIST_DEL (&surface->item_link);
173
174     free (surface);
175     surface = NULL;
176
177     if(LIST_IS_EMPTY (&g_surface_list))
178     {
179         _deinit_surface_bufmgr ();
180         LIST_DELINIT (&g_surface_list);
181     }
182
183 }
184
185
186 int
187 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
188 {
189     struct _tbm_bufmgr *mgr;
190     int ret = 0;
191
192     _tbm_surface_mutex_lock();
193
194     if (!g_surface_bufmgr)
195     {
196         _init_surface_bufmgr();
197         LIST_INITHEAD (&g_surface_list);
198     }
199
200     mgr = g_surface_bufmgr;
201
202     if (!mgr->backend->surface_supported_format)
203     {
204         _tbm_surface_mutex_unlock();
205         return 0;
206     }
207
208     ret = mgr->backend->surface_supported_format (formats, num);
209
210     _tbm_surface_mutex_unlock();
211
212     return ret;
213 }
214
215
216 int tbm_surface_internal_get_num_planes (tbm_format format)
217 {
218     int num_planes = 0;
219
220     switch (format)
221     {
222         case TBM_FORMAT_C8:
223         case TBM_FORMAT_RGB332:
224         case TBM_FORMAT_BGR233:
225         case TBM_FORMAT_XRGB4444:
226         case TBM_FORMAT_XBGR4444:
227         case TBM_FORMAT_RGBX4444:
228         case TBM_FORMAT_BGRX4444:
229         case TBM_FORMAT_ARGB4444:
230         case TBM_FORMAT_ABGR4444:
231         case TBM_FORMAT_RGBA4444:
232         case TBM_FORMAT_BGRA4444:
233         case TBM_FORMAT_XRGB1555:
234         case TBM_FORMAT_XBGR1555:
235         case TBM_FORMAT_RGBX5551:
236         case TBM_FORMAT_BGRX5551:
237         case TBM_FORMAT_ARGB1555:
238         case TBM_FORMAT_ABGR1555:
239         case TBM_FORMAT_RGBA5551:
240         case TBM_FORMAT_BGRA5551:
241         case TBM_FORMAT_RGB565:
242         case TBM_FORMAT_BGR565:
243         case TBM_FORMAT_RGB888:
244         case TBM_FORMAT_BGR888:
245         case TBM_FORMAT_XRGB8888:
246         case TBM_FORMAT_XBGR8888:
247         case TBM_FORMAT_RGBX8888:
248         case TBM_FORMAT_BGRX8888:
249         case TBM_FORMAT_ARGB8888:
250         case TBM_FORMAT_ABGR8888:
251         case TBM_FORMAT_RGBA8888:
252         case TBM_FORMAT_BGRA8888:
253         case TBM_FORMAT_XRGB2101010:
254         case TBM_FORMAT_XBGR2101010:
255         case TBM_FORMAT_RGBX1010102:
256         case TBM_FORMAT_BGRX1010102:
257         case TBM_FORMAT_ARGB2101010:
258         case TBM_FORMAT_ABGR2101010:
259         case TBM_FORMAT_RGBA1010102:
260         case TBM_FORMAT_BGRA1010102:
261         case TBM_FORMAT_YUYV:
262         case TBM_FORMAT_YVYU:
263         case TBM_FORMAT_UYVY:
264         case TBM_FORMAT_VYUY:
265         case TBM_FORMAT_AYUV:
266             num_planes = 1;
267             break;
268         case TBM_FORMAT_NV12:
269         case TBM_FORMAT_NV21:
270         case TBM_FORMAT_NV16:
271         case TBM_FORMAT_NV61:
272             num_planes = 2;
273             break;
274         case TBM_FORMAT_YUV410:
275         case TBM_FORMAT_YVU410:
276         case TBM_FORMAT_YUV411:
277         case TBM_FORMAT_YVU411:
278         case TBM_FORMAT_YUV420:
279         case TBM_FORMAT_YVU420:
280         case TBM_FORMAT_YUV422:
281         case TBM_FORMAT_YVU422:
282         case TBM_FORMAT_YUV444:
283         case TBM_FORMAT_YVU444:
284             num_planes = 3;
285             break;
286
287         default :
288             break;
289     }
290
291     return num_planes;
292 }
293
294 int tbm_surface_internal_get_bpp (tbm_format format)
295 {
296     int bpp = 0;
297
298     switch (format)
299     {
300         case TBM_FORMAT_C8:
301         case TBM_FORMAT_RGB332:
302         case TBM_FORMAT_BGR233:
303             bpp = 8;
304             break;
305         case TBM_FORMAT_XRGB4444:
306         case TBM_FORMAT_XBGR4444:
307         case TBM_FORMAT_RGBX4444:
308         case TBM_FORMAT_BGRX4444:
309         case TBM_FORMAT_ARGB4444:
310         case TBM_FORMAT_ABGR4444:
311         case TBM_FORMAT_RGBA4444:
312         case TBM_FORMAT_BGRA4444:
313         case TBM_FORMAT_XRGB1555:
314         case TBM_FORMAT_XBGR1555:
315         case TBM_FORMAT_RGBX5551:
316         case TBM_FORMAT_BGRX5551:
317         case TBM_FORMAT_ARGB1555:
318         case TBM_FORMAT_ABGR1555:
319         case TBM_FORMAT_RGBA5551:
320         case TBM_FORMAT_BGRA5551:
321         case TBM_FORMAT_RGB565:
322         case TBM_FORMAT_BGR565:
323             bpp = 16;
324             break;
325         case TBM_FORMAT_RGB888:
326         case TBM_FORMAT_BGR888:
327             bpp = 24;
328             break;
329         case TBM_FORMAT_XRGB8888:
330         case TBM_FORMAT_XBGR8888:
331         case TBM_FORMAT_RGBX8888:
332         case TBM_FORMAT_BGRX8888:
333         case TBM_FORMAT_ARGB8888:
334         case TBM_FORMAT_ABGR8888:
335         case TBM_FORMAT_RGBA8888:
336         case TBM_FORMAT_BGRA8888:
337         case TBM_FORMAT_XRGB2101010:
338         case TBM_FORMAT_XBGR2101010:
339         case TBM_FORMAT_RGBX1010102:
340         case TBM_FORMAT_BGRX1010102:
341         case TBM_FORMAT_ARGB2101010:
342         case TBM_FORMAT_ABGR2101010:
343         case TBM_FORMAT_RGBA1010102:
344         case TBM_FORMAT_BGRA1010102:
345         case TBM_FORMAT_YUYV:
346         case TBM_FORMAT_YVYU:
347         case TBM_FORMAT_UYVY:
348         case TBM_FORMAT_VYUY:
349         case TBM_FORMAT_AYUV:
350             bpp = 32;
351             break;
352         case TBM_FORMAT_NV12:
353         case TBM_FORMAT_NV21:
354             bpp = 12;
355             break;
356         case TBM_FORMAT_NV16:
357         case TBM_FORMAT_NV61:
358             bpp = 16;
359             break;
360         case TBM_FORMAT_YUV410:
361         case TBM_FORMAT_YVU410:
362             bpp = 9;
363             break;
364         case TBM_FORMAT_YUV411:
365         case TBM_FORMAT_YVU411:
366         case TBM_FORMAT_YUV420:
367         case TBM_FORMAT_YVU420:
368             bpp = 12;
369             break;
370         case TBM_FORMAT_YUV422:
371         case TBM_FORMAT_YVU422:
372             bpp = 16;
373             break;
374         case TBM_FORMAT_YUV444:
375         case TBM_FORMAT_YVU444:
376             bpp = 24;
377             break;
378         default :
379             break;
380     }
381
382     return bpp;
383 }
384
385 tbm_surface_h
386 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
387 {
388     TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
389     TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
390
391     struct _tbm_bufmgr *mgr;
392     struct _tbm_surface *surf = NULL;
393     uint32_t size = 0;
394     uint32_t offset = 0;
395     uint32_t stride = 0;
396     uint32_t bo_size = 0;
397     int bo_idx;
398     int i, j;
399
400     _tbm_surface_mutex_lock();
401
402     if (!g_surface_bufmgr)
403     {
404         _init_surface_bufmgr();
405         LIST_INITHEAD (&g_surface_list);
406     }
407
408     mgr = g_surface_bufmgr;
409     if (!TBM_BUFMGR_IS_VALID(mgr))
410     {
411         _tbm_surface_mutex_unlock();
412         return NULL;
413     }
414     surf = calloc (1, sizeof(struct _tbm_surface));
415     if (!surf)
416     {
417         _tbm_surface_mutex_unlock();
418         return NULL;
419     }
420
421     surf->bufmgr = mgr;
422     surf->info.width = width;
423     surf->info.height = height;
424     surf->info.format = format;
425     surf->info.bpp = tbm_surface_internal_get_bpp (format);
426     surf->info.size = _tbm_surface_internal_query_size (surf);
427     surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
428     surf->num_bos = _tbm_surface_internal_query_num_bos(format);
429     surf->refcnt = 1;
430
431     /* get size, stride and offset bo_idx*/
432     for (i = 0; i < surf->info.num_planes; i++)
433     {
434         _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride, &bo_idx);
435         surf->info.planes[i].size = size;
436         surf->info.planes[i].offset = offset;
437         surf->info.planes[i].stride = stride;
438         surf->planes_bo_idx[i] = bo_idx;
439     }
440
441     surf->flags = flags;
442
443     for (i = 0; i < surf->num_bos; i++)
444     {
445         bo_size = 0;
446         for (j = 0; j < surf->info.num_planes; j++)
447         {
448             if (surf->planes_bo_idx[i] == i)
449                 bo_size += surf->info.planes[i].size;
450         }
451
452         surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
453         if (!surf->bos[i]) {
454             for (j = 0; j < i; j++)
455                 tbm_bo_unref (surf->bos[j]);
456
457             free (surf);
458             surf = NULL;
459
460             if(LIST_IS_EMPTY (&g_surface_list))
461             {
462                 _deinit_surface_bufmgr ();
463                 LIST_DELINIT (&g_surface_list);
464             }
465
466             _tbm_surface_mutex_unlock();
467             return NULL;
468         }
469     }
470
471     LIST_ADD (&surf->item_link, &g_surface_list);
472
473     _tbm_surface_mutex_unlock();
474
475     return surf;
476 }
477
478 tbm_surface_h
479 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
480 {
481     TBM_RETURN_VAL_IF_FAIL (bos, NULL);
482     TBM_RETURN_VAL_IF_FAIL (info, NULL);
483
484     struct _tbm_bufmgr *mgr;
485     struct _tbm_surface *surf = NULL;
486     int i;
487
488     _tbm_surface_mutex_lock();
489
490     if (!g_surface_bufmgr)
491     {
492         _init_surface_bufmgr();
493         LIST_INITHEAD (&g_surface_list);
494     }
495
496     mgr = g_surface_bufmgr;
497     if (!TBM_BUFMGR_IS_VALID(mgr))
498     {
499         _tbm_surface_mutex_unlock();
500         return NULL;
501     }
502     surf = calloc (1, sizeof(struct _tbm_surface));
503     if (!surf)
504     {
505         _tbm_surface_mutex_unlock();
506         return NULL;
507     }
508
509     surf->bufmgr = mgr;
510     surf->info.width = info->width;
511     surf->info.height = info->height;
512     surf->info.format = info->format;
513     surf->info.bpp = info->bpp;
514     surf->info.num_planes = info->num_planes;
515     surf->refcnt = 1;
516
517     /* get size, stride and offset */
518     for (i = 0; i < info->num_planes; i++)
519     {
520         surf->info.planes[i].offset = info->planes[i].offset;
521         surf->info.planes[i].stride = info->planes[i].stride;
522
523         if (info->planes[i].size > 0)
524             surf->info.planes[i].size = info->planes[i].size;
525         else
526             surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
527     }
528
529     if (info->size > 0)
530     {
531         surf->info.size = info->size;
532     }
533     else
534     {
535         surf->info.size = 0;
536         for (i = 0; i < info->num_planes; i++)
537         {
538             surf->info.size += surf->info.planes[i].size;
539         }
540     }
541
542     surf->flags = TBM_BO_DEFAULT;
543
544     /* create only one bo */
545     surf->num_bos = num;
546     for (i = 0; i < num; i++)
547     {
548         if (bos[i] == NULL)
549             goto bail1;
550
551         surf->bos[i] = tbm_bo_ref(bos[i]);
552     }
553
554     LIST_ADD (&surf->item_link, &g_surface_list);
555
556     _tbm_surface_mutex_unlock();
557
558     return surf;
559 bail1:
560     for (i = 0; i < num; i++)
561     {
562         if (surf->bos[i])
563         {
564             tbm_bo_unref (surf->bos[i]);
565             surf->bos[i] = NULL;
566         }
567     }
568
569     free (surf);
570     surf = NULL;
571
572     if(LIST_IS_EMPTY (&g_surface_list))
573     {
574         _deinit_surface_bufmgr ();
575         LIST_DELINIT (&g_surface_list);
576     }
577
578     _tbm_surface_mutex_unlock();
579
580     return NULL;
581 }
582
583
584 void
585 tbm_surface_internal_destroy (tbm_surface_h surface)
586 {
587     if (!surface)
588         return;
589
590     _tbm_surface_mutex_lock();
591
592     surface->refcnt--;
593
594     if (surface->refcnt > 0)
595         return;
596
597     if (surface->refcnt == 0)
598         _tbm_surface_internal_destroy(surface);
599
600     _tbm_surface_mutex_unlock();
601 }
602
603
604 void
605 tbm_surface_internal_ref (tbm_surface_h surface)
606 {
607     _tbm_surface_mutex_lock();
608
609     TBM_RETURN_IF_FAIL (surface);
610
611     _tbm_surface_mutex_lock();
612
613     surface->refcnt++;
614
615     _tbm_surface_mutex_unlock();
616 }
617
618 void
619 tbm_surface_internal_unref (tbm_surface_h surface)
620 {
621     _tbm_surface_mutex_lock();
622
623     TBM_RETURN_IF_FAIL (surface);
624
625     surface->refcnt--;
626
627     if (surface->refcnt > 0)
628         return;
629
630     if (surface->refcnt == 0)
631         _tbm_surface_internal_destroy(surface);
632
633     _tbm_surface_mutex_unlock();
634 }
635
636 int
637 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
638 {
639     TBM_RETURN_VAL_IF_FAIL (surface, 0);
640
641     struct _tbm_surface *surf;
642     int num;
643
644     _tbm_surface_mutex_lock();
645
646     surf = (struct _tbm_surface *) surface;
647     num = surf->num_bos;
648
649     _tbm_surface_mutex_unlock();
650
651     return num;
652 }
653
654 tbm_bo
655 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
656 {
657     TBM_RETURN_VAL_IF_FAIL (surface, NULL);
658     TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
659
660     struct _tbm_surface *surf;
661     tbm_bo bo;
662
663     _tbm_surface_mutex_lock();
664
665     surf = (struct _tbm_surface *) surface;
666     bo = surf->bos[bo_idx];
667
668     _tbm_surface_mutex_unlock();
669
670     return bo;
671 }
672
673 int
674 tbm_surface_internal_get_size (tbm_surface_h surface)
675 {
676     TBM_RETURN_VAL_IF_FAIL (surface, 0);
677
678     struct _tbm_surface *surf;
679     unsigned int size;
680
681     _tbm_surface_mutex_lock();
682
683     surf = (struct _tbm_surface *) surface;
684     size = surf->info.size;
685
686     _tbm_surface_mutex_unlock();
687
688     return size;
689 }
690
691 int
692 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
693 {
694     TBM_RETURN_VAL_IF_FAIL (surface, 0);
695     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
696
697     struct _tbm_surface *surf;
698
699     _tbm_surface_mutex_lock();
700
701     surf = (struct _tbm_surface *) surface;
702
703     if (plane_idx >= surf->info.num_planes)
704     {
705         _tbm_surface_mutex_unlock();
706         return 0;
707     }
708
709     *size = surf->info.planes[plane_idx].size;
710     *offset = surf->info.planes[plane_idx].offset;
711     *pitch = surf->info.planes[plane_idx].stride;
712
713     _tbm_surface_mutex_unlock();
714
715     return 1;
716 }
717
718 int
719 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
720 {
721     struct _tbm_surface *surf;
722     tbm_bo_handle bo_handles[4];
723     int i, j;
724
725     _tbm_surface_mutex_lock();
726
727     memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
728
729     surf = (struct _tbm_surface *)surface;
730
731     info->width = surf->info.width;
732     info->height = surf->info.height;
733     info->format = surf->info.format;
734     info->bpp = surf->info.bpp;
735     info->size = surf->info.size;
736     info->num_planes = surf->info.num_planes;
737
738     if (map == 1)
739     {
740         for (i = 0; i < surf->num_bos; i++)
741         {
742             bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
743             if (bo_handles[i].ptr == NULL)
744             {
745                 for (j = 0; j < i; j++)
746                     tbm_bo_unmap (surf->bos[j]);
747
748                 _tbm_surface_mutex_unlock();
749                 return 0;
750             }
751         }
752     }
753     else
754     {
755         for (i = 0; i < surf->num_bos; i++)
756         {
757             bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
758             if (bo_handles[i].ptr == NULL)
759             {
760                 _tbm_surface_mutex_unlock();
761                 return 0;
762             }
763         }
764     }
765
766     for (i = 0; i < surf->info.num_planes; i++)
767     {
768         info->planes[i].size = surf->info.planes[i].size;
769         info->planes[i].offset = surf->info.planes[i].offset;
770         info->planes[i].stride = surf->info.planes[i].stride;
771         info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
772     }
773
774     _tbm_surface_mutex_unlock();
775
776     return 1;
777 }
778
779 void
780 tbm_surface_internal_unmap (tbm_surface_h surface)
781 {
782     struct _tbm_surface *surf;
783     int i;
784
785     _tbm_surface_mutex_lock();
786
787     surf = (struct _tbm_surface *)surface;
788
789     for (i = 0; i < surf->num_bos; i++)
790         tbm_bo_unmap (surf->bos[i]);
791
792     _tbm_surface_mutex_unlock();
793 }
794
795 unsigned int
796 tbm_surface_internal_get_width (tbm_surface_h surface)
797 {
798     struct _tbm_surface *surf;
799     unsigned int width;
800
801     _tbm_surface_mutex_lock();
802
803     surf = (struct _tbm_surface *)surface;
804     width = surf->info.width;
805
806     _tbm_surface_mutex_unlock();
807
808     return width;
809 }
810
811 unsigned int
812 tbm_surface_internal_get_height (tbm_surface_h surface)
813 {
814     struct _tbm_surface *surf;
815     unsigned int height;
816
817     _tbm_surface_mutex_lock();
818
819     surf = (struct _tbm_surface *)surface;
820     height = surf->info.height;
821
822     _tbm_surface_mutex_unlock();
823
824     return height;
825
826 }
827
828 tbm_format
829 tbm_surface_internal_get_format (tbm_surface_h surface)
830 {
831     struct _tbm_surface *surf;
832     tbm_format format;
833
834     _tbm_surface_mutex_lock();
835
836     surf = (struct _tbm_surface *)surface;
837     format = surf->info.format;
838
839     _tbm_surface_mutex_unlock();
840
841     return format;
842 }
843
844 int
845 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
846 {
847     TBM_RETURN_VAL_IF_FAIL (surface, 0);
848     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
849     struct _tbm_surface *surf;
850     int bo_idx;
851
852     _tbm_surface_mutex_lock();
853
854     surf = (struct _tbm_surface *)surface;
855     bo_idx = surf->planes_bo_idx[plane_idx];
856
857     _tbm_surface_mutex_unlock();
858
859     return bo_idx;
860 }
861