fef8118cb5a57559c1a81b57c08d0908789d8b84
[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 int _tbm_surface_internal_get_num_planes (tbm_format format)
42 {
43     int num_planes = 0;
44
45     switch (format)
46     {
47         case TBM_FORMAT_C8:
48         case TBM_FORMAT_RGB332:
49         case TBM_FORMAT_BGR233:
50         case TBM_FORMAT_XRGB4444:
51         case TBM_FORMAT_XBGR4444:
52         case TBM_FORMAT_RGBX4444:
53         case TBM_FORMAT_BGRX4444:
54         case TBM_FORMAT_ARGB4444:
55         case TBM_FORMAT_ABGR4444:
56         case TBM_FORMAT_RGBA4444:
57         case TBM_FORMAT_BGRA4444:
58         case TBM_FORMAT_XRGB1555:
59         case TBM_FORMAT_XBGR1555:
60         case TBM_FORMAT_RGBX5551:
61         case TBM_FORMAT_BGRX5551:
62         case TBM_FORMAT_ARGB1555:
63         case TBM_FORMAT_ABGR1555:
64         case TBM_FORMAT_RGBA5551:
65         case TBM_FORMAT_BGRA5551:
66         case TBM_FORMAT_RGB565:
67         case TBM_FORMAT_BGR565:
68         case TBM_FORMAT_RGB888:
69         case TBM_FORMAT_BGR888:
70         case TBM_FORMAT_XRGB8888:
71         case TBM_FORMAT_XBGR8888:
72         case TBM_FORMAT_RGBX8888:
73         case TBM_FORMAT_BGRX8888:
74         case TBM_FORMAT_ARGB8888:
75         case TBM_FORMAT_ABGR8888:
76         case TBM_FORMAT_RGBA8888:
77         case TBM_FORMAT_BGRA8888:
78         case TBM_FORMAT_XRGB2101010:
79         case TBM_FORMAT_XBGR2101010:
80         case TBM_FORMAT_RGBX1010102:
81         case TBM_FORMAT_BGRX1010102:
82         case TBM_FORMAT_ARGB2101010:
83         case TBM_FORMAT_ABGR2101010:
84         case TBM_FORMAT_RGBA1010102:
85         case TBM_FORMAT_BGRA1010102:
86         case TBM_FORMAT_YUYV:
87         case TBM_FORMAT_YVYU:
88         case TBM_FORMAT_UYVY:
89         case TBM_FORMAT_VYUY:
90         case TBM_FORMAT_AYUV:
91             num_planes = 1;
92             break;
93         case TBM_FORMAT_NV12:
94         case TBM_FORMAT_NV21:
95         case TBM_FORMAT_NV16:
96         case TBM_FORMAT_NV61:
97             num_planes = 2;
98             break;
99         case TBM_FORMAT_YUV410:
100         case TBM_FORMAT_YVU410:
101         case TBM_FORMAT_YUV411:
102         case TBM_FORMAT_YVU411:
103         case TBM_FORMAT_YUV420:
104         case TBM_FORMAT_YVU420:
105         case TBM_FORMAT_YUV422:
106         case TBM_FORMAT_YVU422:
107         case TBM_FORMAT_YUV444:
108         case TBM_FORMAT_YVU444:
109             num_planes = 3;
110             break;
111
112         default :
113             break;
114     }
115
116     return num_planes;
117 }
118
119
120 static int _tbm_surface_internal_get_bpp (tbm_format format)
121 {
122     int bpp = 0;
123
124     switch (format)
125     {
126         case TBM_FORMAT_C8:
127         case TBM_FORMAT_RGB332:
128         case TBM_FORMAT_BGR233:
129             bpp = 8;
130             break;
131         case TBM_FORMAT_XRGB4444:
132         case TBM_FORMAT_XBGR4444:
133         case TBM_FORMAT_RGBX4444:
134         case TBM_FORMAT_BGRX4444:
135         case TBM_FORMAT_ARGB4444:
136         case TBM_FORMAT_ABGR4444:
137         case TBM_FORMAT_RGBA4444:
138         case TBM_FORMAT_BGRA4444:
139         case TBM_FORMAT_XRGB1555:
140         case TBM_FORMAT_XBGR1555:
141         case TBM_FORMAT_RGBX5551:
142         case TBM_FORMAT_BGRX5551:
143         case TBM_FORMAT_ARGB1555:
144         case TBM_FORMAT_ABGR1555:
145         case TBM_FORMAT_RGBA5551:
146         case TBM_FORMAT_BGRA5551:
147         case TBM_FORMAT_RGB565:
148         case TBM_FORMAT_BGR565:
149             bpp = 16;
150             break;
151         case TBM_FORMAT_RGB888:
152         case TBM_FORMAT_BGR888:
153             bpp = 24;
154             break;
155         case TBM_FORMAT_XRGB8888:
156         case TBM_FORMAT_XBGR8888:
157         case TBM_FORMAT_RGBX8888:
158         case TBM_FORMAT_BGRX8888:
159         case TBM_FORMAT_ARGB8888:
160         case TBM_FORMAT_ABGR8888:
161         case TBM_FORMAT_RGBA8888:
162         case TBM_FORMAT_BGRA8888:
163         case TBM_FORMAT_XRGB2101010:
164         case TBM_FORMAT_XBGR2101010:
165         case TBM_FORMAT_RGBX1010102:
166         case TBM_FORMAT_BGRX1010102:
167         case TBM_FORMAT_ARGB2101010:
168         case TBM_FORMAT_ABGR2101010:
169         case TBM_FORMAT_RGBA1010102:
170         case TBM_FORMAT_BGRA1010102:
171         case TBM_FORMAT_YUYV:
172         case TBM_FORMAT_YVYU:
173         case TBM_FORMAT_UYVY:
174         case TBM_FORMAT_VYUY:
175         case TBM_FORMAT_AYUV:
176             bpp = 32;
177             break;
178         case TBM_FORMAT_NV12:
179         case TBM_FORMAT_NV21:
180             bpp = 12;
181             break;
182         case TBM_FORMAT_NV16:
183         case TBM_FORMAT_NV61:
184             bpp = 16;
185             break;
186         case TBM_FORMAT_YUV410:
187         case TBM_FORMAT_YVU410:
188             bpp = 9;
189             break;
190         case TBM_FORMAT_YUV411:
191         case TBM_FORMAT_YVU411:
192         case TBM_FORMAT_YUV420:
193         case TBM_FORMAT_YVU420:
194             bpp = 12;
195             break;
196         case TBM_FORMAT_YUV422:
197         case TBM_FORMAT_YVU422:
198             bpp = 16;
199             break;
200         case TBM_FORMAT_YUV444:
201         case TBM_FORMAT_YVU444:
202             bpp = 24;
203             break;
204         default :
205             break;
206     }
207
208     return bpp;
209 }
210
211 static void
212 _init_surface_bufmgr()
213 {
214     g_surface_bufmgr = tbm_bufmgr_init (-1);
215 }
216
217 static void
218 _deinit_surface_bufmgr()
219 {
220     if (!g_surface_bufmgr)
221         return;
222
223     tbm_bufmgr_deinit (g_surface_bufmgr);
224     g_surface_bufmgr = NULL;
225 }
226
227
228 int
229 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
230 {
231     if (!g_surface_bufmgr)
232     {
233         _init_surface_bufmgr();
234         LIST_INITHEAD (&g_surface_list);
235     }
236
237     struct _tbm_bufmgr *mgr = g_surface_bufmgr;
238     int ret = 0;
239
240     pthread_mutex_lock (&mgr->lock);
241
242     ret = mgr->backend->surface_supported_format (formats, num);
243
244     pthread_mutex_unlock (&mgr->lock);
245
246     return ret;
247 }
248
249 tbm_surface_h
250 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
251 {
252     TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
253     TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
254
255     if (!g_surface_bufmgr)
256     {
257         _init_surface_bufmgr();
258         LIST_INITHEAD (&g_surface_list);
259     }
260
261     struct _tbm_bufmgr *mgr = g_surface_bufmgr;
262
263
264     TBM_RETURN_VAL_IF_FAIL (TBM_BUFMGR_IS_VALID(mgr), NULL);
265
266     struct _tbm_surface *surf = NULL;
267     uint32_t size = 0;
268     uint32_t offset = 0;
269     uint32_t stride = 0;
270     int i;
271
272     surf = calloc (1, sizeof(struct _tbm_surface));
273     if (!surf)
274         return NULL;
275
276     surf->bufmgr = mgr;
277     surf->info.width = width;
278     surf->info.height = height;
279     surf->info.format = format;
280     surf->info.bpp = _tbm_surface_internal_get_bpp (format);
281     surf->info.size = tbm_surface_internal_get_size (surf);
282     surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
283
284     /* get size, stride and offset */
285     for (i = 0; i < surf->info.num_planes; i++)
286     {
287         tbm_surface_internal_get_plane_data (surf, i, &size, &offset, &stride);
288         surf->info.planes[i].size = size;
289         surf->info.planes[i].offset = offset;
290         surf->info.planes[i].stride = stride;
291     }
292
293     surf->flags = flags;
294
295     /* create only one bo */
296     surf->num_bos = 1;
297     surf->bos[0] = tbm_bo_alloc (mgr, surf->info.size, flags);
298     if (!surf->bos[0])
299     {
300         free (surf);
301         surf = NULL;
302
303         if(LIST_IS_EMPTY (&g_surface_list))
304         {
305             _deinit_surface_bufmgr ();
306             LIST_DELINIT (&g_surface_list);
307             return NULL;
308         }
309     }
310
311     LIST_ADD (&surf->item_link, &g_surface_list);
312
313     return surf;
314 }
315
316 tbm_surface_h
317 tbm_surface_internal_create_with_bos (int width, int height, int format, tbm_bo *bos, int num)
318 {
319     TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
320     TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
321     TBM_RETURN_VAL_IF_FAIL (bos, NULL);
322
323     if (!g_surface_bufmgr)
324     {
325         _init_surface_bufmgr();
326         LIST_INITHEAD (&g_surface_list);
327     }
328
329
330     struct _tbm_bufmgr *mgr = g_surface_bufmgr;
331
332     TBM_RETURN_VAL_IF_FAIL (TBM_BUFMGR_IS_VALID(mgr), NULL);
333
334     struct _tbm_surface *surf = NULL;
335     uint32_t size = 0;
336     uint32_t offset = 0;
337     uint32_t stride = 0;
338     int i;
339
340     surf = calloc (1, sizeof(struct _tbm_surface));
341     if (!surf)
342         return NULL;
343
344     surf->bufmgr = mgr;
345     surf->info.width = width;
346     surf->info.height = height;
347     surf->info.format = format;
348     surf->info.bpp = _tbm_surface_internal_get_bpp (format);
349     surf->info.size = tbm_surface_internal_get_size (surf);
350     surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
351
352     /* get size, stride and offset */
353     for (i = 0; i < surf->info.num_planes; i++)
354     {
355         tbm_surface_internal_get_plane_data (surf, i, &size, &offset, &stride);
356         surf->info.planes[i].size = size;
357         surf->info.planes[i].offset = offset;
358         surf->info.planes[i].stride = stride;
359     }
360
361     surf->flags = TBM_BO_DEFAULT;
362
363     /* create only one bo */
364     surf->num_bos = num;
365     for (i = 0; i < num; i++)
366     {
367         if (bos[i] == NULL)
368             goto bail1;
369
370         surf->bos[i] = tbm_bo_ref(bos[i]);
371     }
372
373     LIST_ADD (&surf->item_link, &g_surface_list);
374
375     return surf;
376 bail1:
377     for (i = 0; i < num; i++)
378     {
379         if (surf->bos[i])
380         {
381             tbm_bo_unref (surf->bos[i]);
382             surf->bos[i] = NULL;
383         }
384     }
385
386     free (surf);
387     surf = NULL;
388
389     if(LIST_IS_EMPTY (&g_surface_list))
390     {
391         _deinit_surface_bufmgr ();
392         LIST_DELINIT (&g_surface_list);
393     }
394
395     return NULL;
396 }
397
398
399 void
400 tbm_surface_internal_destroy (tbm_surface_h surface)
401 {
402     int i;
403
404     if (!surface)
405         return;
406
407     surface = (struct _tbm_surface *)surface;
408
409     for (i = 0; i < surface->num_bos; i++)
410     {
411         tbm_bo_unref (surface->bos[i]);
412         surface->bos[i] = NULL;
413     }
414
415     LIST_DEL (&surface->item_link);
416
417     free (surface);
418     surface = NULL;
419
420     if(LIST_IS_EMPTY (&g_surface_list))
421     {
422         _deinit_surface_bufmgr ();
423         LIST_DELINIT (&g_surface_list);
424     }
425 }
426
427
428 int
429 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
430 {
431     TBM_RETURN_VAL_IF_FAIL (surface, 0);
432
433     struct _tbm_surface *surf = (struct _tbm_surface *) surface;
434
435     return surf->num_bos;
436 }
437
438 tbm_bo
439 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
440 {
441     TBM_RETURN_VAL_IF_FAIL (surface, NULL);
442     TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
443
444     struct _tbm_surface *surf = (struct _tbm_surface *) surface;
445
446     return surf->bos[bo_idx];
447 }
448
449 int
450 tbm_surface_internal_get_size (tbm_surface_h surface)
451 {
452     TBM_RETURN_VAL_IF_FAIL (surface, 0);
453
454     struct _tbm_surface *surf = (struct _tbm_surface *) surface;
455     struct _tbm_bufmgr *mgr = surf->bufmgr;
456     int size = 0;
457
458     TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
459     TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
460     TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
461     TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
462
463     pthread_mutex_lock (&mgr->lock);
464
465     size = mgr->backend->surface_get_size (surf, surf->info.width, surf->info.height, surf->info.format);
466
467     pthread_mutex_unlock (&mgr->lock);
468
469     return size;
470 }
471
472 int
473 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
474 {
475     TBM_RETURN_VAL_IF_FAIL (surface, 0);
476     TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
477
478     struct _tbm_surface *surf = (struct _tbm_surface *) surface;
479     struct _tbm_bufmgr *mgr = surf->bufmgr;
480     int ret = 0;
481
482     TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
483     TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
484     TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
485     TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
486
487     pthread_mutex_lock (&mgr->lock);
488
489     ret = mgr->backend->surface_get_plane_data (surf, surf->info.width, surf->info.height, surf->info.format, plane_idx, size, offset, pitch);
490     if (!ret)
491     {
492         pthread_mutex_unlock (&mgr->lock);
493         return 0;
494     }
495
496     pthread_mutex_unlock (&mgr->lock);
497
498     return 1;
499 }
500
501
502