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);
160 _tbm_surface_internal_destroy (tbm_surface_h surface)
164 for (i = 0; i < surface->num_bos; i++)
166 tbm_bo_unref (surface->bos[i]);
167 surface->bos[i] = NULL;
170 LIST_DEL (&surface->item_link);
175 if(LIST_IS_EMPTY (&g_surface_list))
177 _deinit_surface_bufmgr ();
178 LIST_DELINIT (&g_surface_list);
185 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
187 struct _tbm_bufmgr *mgr;
190 _tbm_surface_mutex_lock();
192 if (!g_surface_bufmgr)
194 _init_surface_bufmgr();
195 LIST_INITHEAD (&g_surface_list);
198 mgr = g_surface_bufmgr;
200 if (!mgr->backend->surface_supported_format)
202 _tbm_surface_mutex_unlock();
206 ret = mgr->backend->surface_supported_format (formats, num);
208 _tbm_surface_mutex_unlock();
214 int tbm_surface_internal_get_num_planes (tbm_format format)
221 case TBM_FORMAT_RGB332:
222 case TBM_FORMAT_BGR233:
223 case TBM_FORMAT_XRGB4444:
224 case TBM_FORMAT_XBGR4444:
225 case TBM_FORMAT_RGBX4444:
226 case TBM_FORMAT_BGRX4444:
227 case TBM_FORMAT_ARGB4444:
228 case TBM_FORMAT_ABGR4444:
229 case TBM_FORMAT_RGBA4444:
230 case TBM_FORMAT_BGRA4444:
231 case TBM_FORMAT_XRGB1555:
232 case TBM_FORMAT_XBGR1555:
233 case TBM_FORMAT_RGBX5551:
234 case TBM_FORMAT_BGRX5551:
235 case TBM_FORMAT_ARGB1555:
236 case TBM_FORMAT_ABGR1555:
237 case TBM_FORMAT_RGBA5551:
238 case TBM_FORMAT_BGRA5551:
239 case TBM_FORMAT_RGB565:
240 case TBM_FORMAT_BGR565:
241 case TBM_FORMAT_RGB888:
242 case TBM_FORMAT_BGR888:
243 case TBM_FORMAT_XRGB8888:
244 case TBM_FORMAT_XBGR8888:
245 case TBM_FORMAT_RGBX8888:
246 case TBM_FORMAT_BGRX8888:
247 case TBM_FORMAT_ARGB8888:
248 case TBM_FORMAT_ABGR8888:
249 case TBM_FORMAT_RGBA8888:
250 case TBM_FORMAT_BGRA8888:
251 case TBM_FORMAT_XRGB2101010:
252 case TBM_FORMAT_XBGR2101010:
253 case TBM_FORMAT_RGBX1010102:
254 case TBM_FORMAT_BGRX1010102:
255 case TBM_FORMAT_ARGB2101010:
256 case TBM_FORMAT_ABGR2101010:
257 case TBM_FORMAT_RGBA1010102:
258 case TBM_FORMAT_BGRA1010102:
259 case TBM_FORMAT_YUYV:
260 case TBM_FORMAT_YVYU:
261 case TBM_FORMAT_UYVY:
262 case TBM_FORMAT_VYUY:
263 case TBM_FORMAT_AYUV:
266 case TBM_FORMAT_NV12:
267 case TBM_FORMAT_NV21:
268 case TBM_FORMAT_NV16:
269 case TBM_FORMAT_NV61:
272 case TBM_FORMAT_YUV410:
273 case TBM_FORMAT_YVU410:
274 case TBM_FORMAT_YUV411:
275 case TBM_FORMAT_YVU411:
276 case TBM_FORMAT_YUV420:
277 case TBM_FORMAT_YVU420:
278 case TBM_FORMAT_YUV422:
279 case TBM_FORMAT_YVU422:
280 case TBM_FORMAT_YUV444:
281 case TBM_FORMAT_YVU444:
292 int tbm_surface_internal_get_bpp (tbm_format format)
299 case TBM_FORMAT_RGB332:
300 case TBM_FORMAT_BGR233:
303 case TBM_FORMAT_XRGB4444:
304 case TBM_FORMAT_XBGR4444:
305 case TBM_FORMAT_RGBX4444:
306 case TBM_FORMAT_BGRX4444:
307 case TBM_FORMAT_ARGB4444:
308 case TBM_FORMAT_ABGR4444:
309 case TBM_FORMAT_RGBA4444:
310 case TBM_FORMAT_BGRA4444:
311 case TBM_FORMAT_XRGB1555:
312 case TBM_FORMAT_XBGR1555:
313 case TBM_FORMAT_RGBX5551:
314 case TBM_FORMAT_BGRX5551:
315 case TBM_FORMAT_ARGB1555:
316 case TBM_FORMAT_ABGR1555:
317 case TBM_FORMAT_RGBA5551:
318 case TBM_FORMAT_BGRA5551:
319 case TBM_FORMAT_RGB565:
320 case TBM_FORMAT_BGR565:
323 case TBM_FORMAT_RGB888:
324 case TBM_FORMAT_BGR888:
327 case TBM_FORMAT_XRGB8888:
328 case TBM_FORMAT_XBGR8888:
329 case TBM_FORMAT_RGBX8888:
330 case TBM_FORMAT_BGRX8888:
331 case TBM_FORMAT_ARGB8888:
332 case TBM_FORMAT_ABGR8888:
333 case TBM_FORMAT_RGBA8888:
334 case TBM_FORMAT_BGRA8888:
335 case TBM_FORMAT_XRGB2101010:
336 case TBM_FORMAT_XBGR2101010:
337 case TBM_FORMAT_RGBX1010102:
338 case TBM_FORMAT_BGRX1010102:
339 case TBM_FORMAT_ARGB2101010:
340 case TBM_FORMAT_ABGR2101010:
341 case TBM_FORMAT_RGBA1010102:
342 case TBM_FORMAT_BGRA1010102:
343 case TBM_FORMAT_YUYV:
344 case TBM_FORMAT_YVYU:
345 case TBM_FORMAT_UYVY:
346 case TBM_FORMAT_VYUY:
347 case TBM_FORMAT_AYUV:
350 case TBM_FORMAT_NV12:
351 case TBM_FORMAT_NV21:
354 case TBM_FORMAT_NV16:
355 case TBM_FORMAT_NV61:
358 case TBM_FORMAT_YUV410:
359 case TBM_FORMAT_YVU410:
362 case TBM_FORMAT_YUV411:
363 case TBM_FORMAT_YVU411:
364 case TBM_FORMAT_YUV420:
365 case TBM_FORMAT_YVU420:
368 case TBM_FORMAT_YUV422:
369 case TBM_FORMAT_YVU422:
372 case TBM_FORMAT_YUV444:
373 case TBM_FORMAT_YVU444:
384 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
386 TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
387 TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
389 struct _tbm_bufmgr *mgr;
390 struct _tbm_surface *surf = NULL;
394 uint32_t bo_size = 0;
398 _tbm_surface_mutex_lock();
400 if (!g_surface_bufmgr)
402 _init_surface_bufmgr();
403 LIST_INITHEAD (&g_surface_list);
406 mgr = g_surface_bufmgr;
407 if (!TBM_BUFMGR_IS_VALID(mgr))
409 _tbm_surface_mutex_unlock();
412 surf = calloc (1, sizeof(struct _tbm_surface));
415 _tbm_surface_mutex_unlock();
420 surf->info.width = width;
421 surf->info.height = height;
422 surf->info.format = format;
423 surf->info.bpp = tbm_surface_internal_get_bpp (format);
424 surf->info.size = _tbm_surface_internal_query_size (surf);
425 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
426 surf->num_bos = _tbm_surface_internal_query_num_bos(format);
429 /* get size, stride and offset bo_idx*/
430 for (i = 0; i < surf->info.num_planes; i++)
432 _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride, &bo_idx);
433 surf->info.planes[i].size = size;
434 surf->info.planes[i].offset = offset;
435 surf->info.planes[i].stride = stride;
436 surf->planes_bo_idx[i] = bo_idx;
441 for (i = 0; i < surf->num_bos; i++)
444 for (j = 0; j < surf->info.num_planes; j++)
446 if (surf->planes_bo_idx[j] == i)
447 bo_size += surf->info.planes[j].size;
449 surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
451 for (j = 0; j < i; j++)
452 tbm_bo_unref (surf->bos[j]);
457 if(LIST_IS_EMPTY (&g_surface_list))
459 _deinit_surface_bufmgr ();
460 LIST_DELINIT (&g_surface_list);
463 _tbm_surface_mutex_unlock();
468 LIST_ADD (&surf->item_link, &g_surface_list);
470 _tbm_surface_mutex_unlock();
476 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
478 TBM_RETURN_VAL_IF_FAIL (bos, NULL);
479 TBM_RETURN_VAL_IF_FAIL (info, NULL);
480 TBM_RETURN_VAL_IF_FAIL (num == 1 || info->num_planes == num, NULL);
482 struct _tbm_bufmgr *mgr;
483 struct _tbm_surface *surf = NULL;
486 _tbm_surface_mutex_lock();
488 if (!g_surface_bufmgr)
490 _init_surface_bufmgr();
491 LIST_INITHEAD (&g_surface_list);
494 mgr = g_surface_bufmgr;
495 if (!TBM_BUFMGR_IS_VALID(mgr))
497 _tbm_surface_mutex_unlock();
501 surf = calloc (1, sizeof(struct _tbm_surface));
504 _tbm_surface_mutex_unlock();
509 surf->info.width = info->width;
510 surf->info.height = info->height;
511 surf->info.format = info->format;
512 surf->info.bpp = info->bpp;
513 surf->info.num_planes = info->num_planes;
516 /* get size, stride and offset */
517 for (i = 0; i < info->num_planes; i++)
519 surf->info.planes[i].offset = info->planes[i].offset;
520 surf->info.planes[i].stride = info->planes[i].stride;
522 if (info->planes[i].size > 0)
523 surf->info.planes[i].size = info->planes[i].size;
525 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
528 surf->planes_bo_idx[i] = 0;
530 surf->planes_bo_idx[i] = i;
535 surf->info.size = info->size;
540 for (i = 0; i < info->num_planes; i++)
542 surf->info.size += surf->info.planes[i].size;
546 surf->flags = TBM_BO_DEFAULT;
548 /* create only one bo */
550 for (i = 0; i < num; i++)
555 surf->bos[i] = tbm_bo_ref(bos[i]);
558 LIST_ADD (&surf->item_link, &g_surface_list);
560 _tbm_surface_mutex_unlock();
564 for (i = 0; i < num; i++)
568 tbm_bo_unref (surf->bos[i]);
576 if(LIST_IS_EMPTY (&g_surface_list))
578 _deinit_surface_bufmgr ();
579 LIST_DELINIT (&g_surface_list);
582 _tbm_surface_mutex_unlock();
589 tbm_surface_internal_destroy (tbm_surface_h surface)
594 _tbm_surface_mutex_lock();
598 if (surface->refcnt > 0) {
599 _tbm_surface_mutex_unlock();
603 if (surface->refcnt == 0)
604 _tbm_surface_internal_destroy(surface);
606 _tbm_surface_mutex_unlock();
611 tbm_surface_internal_ref (tbm_surface_h surface)
613 TBM_RETURN_IF_FAIL (surface);
615 _tbm_surface_mutex_lock();
619 _tbm_surface_mutex_unlock();
623 tbm_surface_internal_unref (tbm_surface_h surface)
625 TBM_RETURN_IF_FAIL (surface);
627 _tbm_surface_mutex_lock();
631 if (surface->refcnt > 0) {
632 _tbm_surface_mutex_unlock();
636 if (surface->refcnt == 0)
637 _tbm_surface_internal_destroy(surface);
639 _tbm_surface_mutex_unlock();
643 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
645 TBM_RETURN_VAL_IF_FAIL (surface, 0);
647 struct _tbm_surface *surf;
650 _tbm_surface_mutex_lock();
652 surf = (struct _tbm_surface *) surface;
655 _tbm_surface_mutex_unlock();
661 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
663 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
664 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
666 struct _tbm_surface *surf;
669 _tbm_surface_mutex_lock();
671 surf = (struct _tbm_surface *) surface;
672 bo = surf->bos[bo_idx];
674 _tbm_surface_mutex_unlock();
680 tbm_surface_internal_get_size (tbm_surface_h surface)
682 TBM_RETURN_VAL_IF_FAIL (surface, 0);
684 struct _tbm_surface *surf;
687 _tbm_surface_mutex_lock();
689 surf = (struct _tbm_surface *) surface;
690 size = surf->info.size;
692 _tbm_surface_mutex_unlock();
698 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
700 TBM_RETURN_VAL_IF_FAIL (surface, 0);
701 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
703 struct _tbm_surface *surf;
705 _tbm_surface_mutex_lock();
707 surf = (struct _tbm_surface *) surface;
709 if (plane_idx >= surf->info.num_planes)
711 _tbm_surface_mutex_unlock();
715 *size = surf->info.planes[plane_idx].size;
716 *offset = surf->info.planes[plane_idx].offset;
717 *pitch = surf->info.planes[plane_idx].stride;
719 _tbm_surface_mutex_unlock();
725 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
727 struct _tbm_surface *surf;
728 tbm_bo_handle bo_handles[4];
731 _tbm_surface_mutex_lock();
733 memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
735 surf = (struct _tbm_surface *)surface;
737 info->width = surf->info.width;
738 info->height = surf->info.height;
739 info->format = surf->info.format;
740 info->bpp = surf->info.bpp;
741 info->size = surf->info.size;
742 info->num_planes = surf->info.num_planes;
746 for (i = 0; i < surf->num_bos; i++)
748 bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
749 if (bo_handles[i].ptr == NULL)
751 for (j = 0; j < i; j++)
752 tbm_bo_unmap (surf->bos[j]);
754 _tbm_surface_mutex_unlock();
761 for (i = 0; i < surf->num_bos; i++)
763 bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
764 if (bo_handles[i].ptr == NULL)
766 _tbm_surface_mutex_unlock();
772 for (i = 0; i < surf->info.num_planes; i++)
774 info->planes[i].size = surf->info.planes[i].size;
775 info->planes[i].offset = surf->info.planes[i].offset;
776 info->planes[i].stride = surf->info.planes[i].stride;
777 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
780 _tbm_surface_mutex_unlock();
786 tbm_surface_internal_unmap (tbm_surface_h surface)
788 struct _tbm_surface *surf;
791 _tbm_surface_mutex_lock();
793 surf = (struct _tbm_surface *)surface;
795 for (i = 0; i < surf->num_bos; i++)
796 tbm_bo_unmap (surf->bos[i]);
798 _tbm_surface_mutex_unlock();
802 tbm_surface_internal_get_width (tbm_surface_h surface)
804 struct _tbm_surface *surf;
807 _tbm_surface_mutex_lock();
809 surf = (struct _tbm_surface *)surface;
810 width = surf->info.width;
812 _tbm_surface_mutex_unlock();
818 tbm_surface_internal_get_height (tbm_surface_h surface)
820 struct _tbm_surface *surf;
823 _tbm_surface_mutex_lock();
825 surf = (struct _tbm_surface *)surface;
826 height = surf->info.height;
828 _tbm_surface_mutex_unlock();
835 tbm_surface_internal_get_format (tbm_surface_h surface)
837 struct _tbm_surface *surf;
840 _tbm_surface_mutex_lock();
842 surf = (struct _tbm_surface *)surface;
843 format = surf->info.format;
845 _tbm_surface_mutex_unlock();
851 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
853 TBM_RETURN_VAL_IF_FAIL (surface, 0);
854 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
855 struct _tbm_surface *surf;
858 _tbm_surface_mutex_lock();
860 surf = (struct _tbm_surface *)surface;
861 bo_idx = surf->planes_bo_idx[plane_idx];
863 _tbm_surface_mutex_unlock();