1 /**************************************************************************
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
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>
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:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
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.
30 **************************************************************************/
33 #include "tbm_bufmgr.h"
34 #include "tbm_bufmgr_int.h"
35 #include "tbm_surface_internal.h"
38 static tbm_bufmgr g_surface_bufmgr = NULL;
39 struct list_head g_surface_list; /* list of surfaces belonging to bufmgr */
41 static pthread_mutex_t tbm_surface_lock;
44 _tbm_surface_mutex_init (void)
46 static bool tbm_surface_mutex_init = false;
48 if (tbm_surface_mutex_init)
51 if (pthread_mutex_init (&tbm_surface_lock, NULL))
53 TBM_LOG ("[libtbm] fail: tbm_surface mutex init\n");
57 tbm_surface_mutex_init = true;
63 _tbm_surface_mutex_lock (void)
65 if (!_tbm_surface_mutex_init ())
68 pthread_mutex_lock (&tbm_surface_lock);
72 _tbm_surface_mutex_unlock (void)
74 pthread_mutex_unlock (&tbm_surface_lock);
78 _init_surface_bufmgr()
80 g_surface_bufmgr = tbm_bufmgr_init (-1);
84 _deinit_surface_bufmgr()
86 if (!g_surface_bufmgr)
89 tbm_bufmgr_deinit (g_surface_bufmgr);
90 g_surface_bufmgr = NULL;
94 _tbm_surface_internal_query_size (tbm_surface_h surface)
96 TBM_RETURN_VAL_IF_FAIL (surface, 0);
98 struct _tbm_surface *surf = (struct _tbm_surface *) surface;
99 struct _tbm_bufmgr *mgr = surf->bufmgr;
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);
107 if (!mgr->backend->surface_get_size)
110 size = mgr->backend->surface_get_size (surf, surf->info.width, surf->info.height, surf->info.format);
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)
118 TBM_RETURN_VAL_IF_FAIL (surface, 0);
119 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
121 struct _tbm_surface *surf = (struct _tbm_surface *) surface;
122 struct _tbm_bufmgr *mgr = surf->bufmgr;
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);
130 if (!mgr->backend->surface_get_plane_data)
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);
141 _tbm_surface_internal_query_num_bos (tbm_format format)
143 TBM_RETURN_VAL_IF_FAIL (format > 0, 0);
144 struct _tbm_bufmgr *mgr;
147 mgr = g_surface_bufmgr;
149 if (!mgr->backend->surface_get_num_bos)
152 ret = mgr->backend->surface_get_num_bos (format);
161 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
163 struct _tbm_bufmgr *mgr;
166 _tbm_surface_mutex_lock();
168 if (!g_surface_bufmgr)
170 _init_surface_bufmgr();
171 LIST_INITHEAD (&g_surface_list);
174 mgr = g_surface_bufmgr;
176 if (!mgr->backend->surface_supported_format)
178 _tbm_surface_mutex_unlock();
182 ret = mgr->backend->surface_supported_format (formats, num);
184 _tbm_surface_mutex_unlock();
190 int tbm_surface_internal_get_num_planes (tbm_format format)
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:
242 case TBM_FORMAT_NV12:
243 case TBM_FORMAT_NV21:
244 case TBM_FORMAT_NV16:
245 case TBM_FORMAT_NV61:
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:
268 int tbm_surface_internal_get_bpp (tbm_format format)
275 case TBM_FORMAT_RGB332:
276 case TBM_FORMAT_BGR233:
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:
299 case TBM_FORMAT_RGB888:
300 case TBM_FORMAT_BGR888:
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:
326 case TBM_FORMAT_NV12:
327 case TBM_FORMAT_NV21:
330 case TBM_FORMAT_NV16:
331 case TBM_FORMAT_NV61:
334 case TBM_FORMAT_YUV410:
335 case TBM_FORMAT_YVU410:
338 case TBM_FORMAT_YUV411:
339 case TBM_FORMAT_YVU411:
340 case TBM_FORMAT_YUV420:
341 case TBM_FORMAT_YVU420:
344 case TBM_FORMAT_YUV422:
345 case TBM_FORMAT_YVU422:
348 case TBM_FORMAT_YUV444:
349 case TBM_FORMAT_YVU444:
360 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
362 TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
363 TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
365 struct _tbm_bufmgr *mgr;
366 struct _tbm_surface *surf = NULL;
370 uint32_t bo_size = 0;
374 _tbm_surface_mutex_lock();
376 if (!g_surface_bufmgr)
378 _init_surface_bufmgr();
379 LIST_INITHEAD (&g_surface_list);
382 mgr = g_surface_bufmgr;
383 if (!TBM_BUFMGR_IS_VALID(mgr))
385 _tbm_surface_mutex_unlock();
388 surf = calloc (1, sizeof(struct _tbm_surface));
391 _tbm_surface_mutex_unlock();
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);
404 /* get size, stride and offset bo_idx*/
405 for (i = 0; i < surf->info.num_planes; i++)
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;
416 for (i = 0; i < surf->num_bos; i++)
419 for (j = 0; j < surf->info.num_planes; j++)
421 if (surf->planes_bo_idx[i] == i)
422 bo_size += surf->info.planes[i].size;
425 surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
427 for (j = 0; j < i; j++)
428 tbm_bo_unref (surf->bos[j]);
433 if(LIST_IS_EMPTY (&g_surface_list))
435 _deinit_surface_bufmgr ();
436 LIST_DELINIT (&g_surface_list);
439 _tbm_surface_mutex_unlock();
444 LIST_ADD (&surf->item_link, &g_surface_list);
446 _tbm_surface_mutex_unlock();
452 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
454 TBM_RETURN_VAL_IF_FAIL (bos, NULL);
455 TBM_RETURN_VAL_IF_FAIL (info, NULL);
457 struct _tbm_bufmgr *mgr;
458 struct _tbm_surface *surf = NULL;
461 _tbm_surface_mutex_lock();
463 if (!g_surface_bufmgr)
465 _init_surface_bufmgr();
466 LIST_INITHEAD (&g_surface_list);
469 mgr = g_surface_bufmgr;
470 if (!TBM_BUFMGR_IS_VALID(mgr))
472 _tbm_surface_mutex_unlock();
475 surf = calloc (1, sizeof(struct _tbm_surface));
478 _tbm_surface_mutex_unlock();
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;
490 /* get size, stride and offset */
491 for (i = 0; i < info->num_planes; i++)
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;
498 surf->flags = TBM_BO_DEFAULT;
500 /* create only one bo */
502 for (i = 0; i < num; i++)
507 surf->bos[i] = tbm_bo_ref(bos[i]);
510 LIST_ADD (&surf->item_link, &g_surface_list);
512 _tbm_surface_mutex_unlock();
516 for (i = 0; i < num; i++)
520 tbm_bo_unref (surf->bos[i]);
528 if(LIST_IS_EMPTY (&g_surface_list))
530 _deinit_surface_bufmgr ();
531 LIST_DELINIT (&g_surface_list);
534 _tbm_surface_mutex_unlock();
541 tbm_surface_internal_destroy (tbm_surface_h surface)
548 _tbm_surface_mutex_lock();
550 surface = (struct _tbm_surface *)surface;
552 for (i = 0; i < surface->num_bos; i++)
554 tbm_bo_unref (surface->bos[i]);
555 surface->bos[i] = NULL;
558 LIST_DEL (&surface->item_link);
563 if(LIST_IS_EMPTY (&g_surface_list))
565 _deinit_surface_bufmgr ();
566 LIST_DELINIT (&g_surface_list);
569 _tbm_surface_mutex_unlock();
574 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
576 TBM_RETURN_VAL_IF_FAIL (surface, 0);
578 struct _tbm_surface *surf;
581 _tbm_surface_mutex_lock();
583 surf = (struct _tbm_surface *) surface;
586 _tbm_surface_mutex_unlock();
592 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
594 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
595 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
597 struct _tbm_surface *surf;
600 _tbm_surface_mutex_lock();
602 surf = (struct _tbm_surface *) surface;
603 bo = surf->bos[bo_idx];
605 _tbm_surface_mutex_unlock();
611 tbm_surface_internal_get_size (tbm_surface_h surface)
613 TBM_RETURN_VAL_IF_FAIL (surface, 0);
615 struct _tbm_surface *surf;
618 _tbm_surface_mutex_lock();
620 surf = (struct _tbm_surface *) surface;
621 size = surf->info.size;
623 _tbm_surface_mutex_unlock();
629 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
631 TBM_RETURN_VAL_IF_FAIL (surface, 0);
632 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
634 struct _tbm_surface *surf;
636 _tbm_surface_mutex_lock();
638 surf = (struct _tbm_surface *) surface;
640 if (plane_idx >= surf->info.num_planes)
642 _tbm_surface_mutex_unlock();
646 *size = surf->info.planes[plane_idx].size;
647 *offset = surf->info.planes[plane_idx].offset;
648 *pitch = surf->info.planes[plane_idx].stride;
650 _tbm_surface_mutex_unlock();
656 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
658 struct _tbm_surface *surf;
659 tbm_bo_handle bo_handles[4];
662 _tbm_surface_mutex_lock();
664 memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
666 surf = (struct _tbm_surface *)surface;
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;
677 for (i = 0; i < surf->num_bos; i++)
679 bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
680 if (bo_handles[i].ptr == NULL)
682 for (j = 0; j < i; j++)
683 tbm_bo_unmap (surf->bos[j]);
685 _tbm_surface_mutex_unlock();
692 for (i = 0; i < surf->num_bos; i++)
694 bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
695 if (bo_handles[i].ptr == NULL)
697 _tbm_surface_mutex_unlock();
703 for (i = 0; i < surf->info.num_planes; i++)
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;
711 _tbm_surface_mutex_unlock();
717 tbm_surface_internal_unmap (tbm_surface_h surface)
719 struct _tbm_surface *surf;
722 _tbm_surface_mutex_lock();
724 surf = (struct _tbm_surface *)surface;
726 for (i = 0; i < surf->num_bos; i++)
727 tbm_bo_unmap (surf->bos[i]);
729 _tbm_surface_mutex_unlock();
733 tbm_surface_internal_get_width (tbm_surface_h surface)
735 struct _tbm_surface *surf;
738 _tbm_surface_mutex_lock();
740 surf = (struct _tbm_surface *)surface;
741 width = surf->info.width;
743 _tbm_surface_mutex_unlock();
749 tbm_surface_internal_get_height (tbm_surface_h surface)
751 struct _tbm_surface *surf;
754 _tbm_surface_mutex_lock();
756 surf = (struct _tbm_surface *)surface;
757 height = surf->info.height;
759 _tbm_surface_mutex_unlock();
766 tbm_surface_internal_get_format (tbm_surface_h surface)
768 struct _tbm_surface *surf;
771 _tbm_surface_mutex_lock();
773 surf = (struct _tbm_surface *)surface;
774 format = surf->info.format;
776 _tbm_surface_mutex_unlock();
782 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
784 TBM_RETURN_VAL_IF_FAIL (surface, 0);
785 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
786 struct _tbm_surface *surf;
789 _tbm_surface_mutex_lock();
791 surf = (struct _tbm_surface *)surface;
792 bo_idx = surf->planes_bo_idx[plane_idx];
794 _tbm_surface_mutex_unlock();