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[i] == i)
447 bo_size += surf->info.planes[i].size;
450 surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
452 for (j = 0; j < i; j++)
453 tbm_bo_unref (surf->bos[j]);
458 if(LIST_IS_EMPTY (&g_surface_list))
460 _deinit_surface_bufmgr ();
461 LIST_DELINIT (&g_surface_list);
464 _tbm_surface_mutex_unlock();
469 LIST_ADD (&surf->item_link, &g_surface_list);
471 _tbm_surface_mutex_unlock();
477 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
479 TBM_RETURN_VAL_IF_FAIL (bos, NULL);
480 TBM_RETURN_VAL_IF_FAIL (info, 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();
500 surf = calloc (1, sizeof(struct _tbm_surface));
503 _tbm_surface_mutex_unlock();
508 surf->info.width = info->width;
509 surf->info.height = info->height;
510 surf->info.format = info->format;
511 surf->info.bpp = info->bpp;
512 surf->info.num_planes = info->num_planes;
515 /* get size, stride and offset */
516 for (i = 0; i < info->num_planes; i++)
518 surf->info.planes[i].offset = info->planes[i].offset;
519 surf->info.planes[i].stride = info->planes[i].stride;
521 if (info->planes[i].size > 0)
522 surf->info.planes[i].size = info->planes[i].size;
524 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
529 surf->info.size = info->size;
534 for (i = 0; i < info->num_planes; i++)
536 surf->info.size += surf->info.planes[i].size;
540 surf->flags = TBM_BO_DEFAULT;
542 /* create only one bo */
544 for (i = 0; i < num; i++)
549 surf->bos[i] = tbm_bo_ref(bos[i]);
552 LIST_ADD (&surf->item_link, &g_surface_list);
554 _tbm_surface_mutex_unlock();
558 for (i = 0; i < num; i++)
562 tbm_bo_unref (surf->bos[i]);
570 if(LIST_IS_EMPTY (&g_surface_list))
572 _deinit_surface_bufmgr ();
573 LIST_DELINIT (&g_surface_list);
576 _tbm_surface_mutex_unlock();
583 tbm_surface_internal_destroy (tbm_surface_h surface)
588 _tbm_surface_mutex_lock();
592 if (surface->refcnt > 0) {
593 _tbm_surface_mutex_unlock();
597 if (surface->refcnt == 0)
598 _tbm_surface_internal_destroy(surface);
600 _tbm_surface_mutex_unlock();
605 tbm_surface_internal_ref (tbm_surface_h surface)
607 TBM_RETURN_IF_FAIL (surface);
609 _tbm_surface_mutex_lock();
613 _tbm_surface_mutex_unlock();
617 tbm_surface_internal_unref (tbm_surface_h surface)
619 TBM_RETURN_IF_FAIL (surface);
621 _tbm_surface_mutex_lock();
625 if (surface->refcnt > 0) {
626 _tbm_surface_mutex_unlock();
630 if (surface->refcnt == 0)
631 _tbm_surface_internal_destroy(surface);
633 _tbm_surface_mutex_unlock();
637 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
639 TBM_RETURN_VAL_IF_FAIL (surface, 0);
641 struct _tbm_surface *surf;
644 _tbm_surface_mutex_lock();
646 surf = (struct _tbm_surface *) surface;
649 _tbm_surface_mutex_unlock();
655 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
657 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
658 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
660 struct _tbm_surface *surf;
663 _tbm_surface_mutex_lock();
665 surf = (struct _tbm_surface *) surface;
666 bo = surf->bos[bo_idx];
668 _tbm_surface_mutex_unlock();
674 tbm_surface_internal_get_size (tbm_surface_h surface)
676 TBM_RETURN_VAL_IF_FAIL (surface, 0);
678 struct _tbm_surface *surf;
681 _tbm_surface_mutex_lock();
683 surf = (struct _tbm_surface *) surface;
684 size = surf->info.size;
686 _tbm_surface_mutex_unlock();
692 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
694 TBM_RETURN_VAL_IF_FAIL (surface, 0);
695 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
697 struct _tbm_surface *surf;
699 _tbm_surface_mutex_lock();
701 surf = (struct _tbm_surface *) surface;
703 if (plane_idx >= surf->info.num_planes)
705 _tbm_surface_mutex_unlock();
709 *size = surf->info.planes[plane_idx].size;
710 *offset = surf->info.planes[plane_idx].offset;
711 *pitch = surf->info.planes[plane_idx].stride;
713 _tbm_surface_mutex_unlock();
719 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
721 struct _tbm_surface *surf;
722 tbm_bo_handle bo_handles[4];
725 _tbm_surface_mutex_lock();
727 memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
729 surf = (struct _tbm_surface *)surface;
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;
740 for (i = 0; i < surf->num_bos; i++)
742 bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
743 if (bo_handles[i].ptr == NULL)
745 for (j = 0; j < i; j++)
746 tbm_bo_unmap (surf->bos[j]);
748 _tbm_surface_mutex_unlock();
755 for (i = 0; i < surf->num_bos; i++)
757 bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
758 if (bo_handles[i].ptr == NULL)
760 _tbm_surface_mutex_unlock();
766 for (i = 0; i < surf->info.num_planes; i++)
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;
774 _tbm_surface_mutex_unlock();
780 tbm_surface_internal_unmap (tbm_surface_h surface)
782 struct _tbm_surface *surf;
785 _tbm_surface_mutex_lock();
787 surf = (struct _tbm_surface *)surface;
789 for (i = 0; i < surf->num_bos; i++)
790 tbm_bo_unmap (surf->bos[i]);
792 _tbm_surface_mutex_unlock();
796 tbm_surface_internal_get_width (tbm_surface_h surface)
798 struct _tbm_surface *surf;
801 _tbm_surface_mutex_lock();
803 surf = (struct _tbm_surface *)surface;
804 width = surf->info.width;
806 _tbm_surface_mutex_unlock();
812 tbm_surface_internal_get_height (tbm_surface_h surface)
814 struct _tbm_surface *surf;
817 _tbm_surface_mutex_lock();
819 surf = (struct _tbm_surface *)surface;
820 height = surf->info.height;
822 _tbm_surface_mutex_unlock();
829 tbm_surface_internal_get_format (tbm_surface_h surface)
831 struct _tbm_surface *surf;
834 _tbm_surface_mutex_lock();
836 surf = (struct _tbm_surface *)surface;
837 format = surf->info.format;
839 _tbm_surface_mutex_unlock();
845 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
847 TBM_RETURN_VAL_IF_FAIL (surface, 0);
848 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
849 struct _tbm_surface *surf;
852 _tbm_surface_mutex_lock();
854 surf = (struct _tbm_surface *)surface;
855 bo_idx = surf->planes_bo_idx[plane_idx];
857 _tbm_surface_mutex_unlock();