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