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 static pthread_mutex_t tbm_surface_lock;
42 _tbm_surface_mutex_init (void)
44 static bool tbm_surface_mutex_init = false;
46 if (tbm_surface_mutex_init)
49 if (pthread_mutex_init (&tbm_surface_lock, NULL))
51 TBM_LOG ("[libtbm] fail: tbm_surface mutex init\n");
55 tbm_surface_mutex_init = true;
61 _tbm_surface_mutex_lock (void)
63 if (!_tbm_surface_mutex_init ())
66 pthread_mutex_lock (&tbm_surface_lock);
70 _tbm_surface_mutex_unlock (void)
72 pthread_mutex_unlock (&tbm_surface_lock);
76 _init_surface_bufmgr()
78 g_surface_bufmgr = tbm_bufmgr_init (-1);
82 _deinit_surface_bufmgr()
84 if (!g_surface_bufmgr)
87 tbm_bufmgr_deinit (g_surface_bufmgr);
88 g_surface_bufmgr = NULL;
92 _tbm_surface_internal_query_size (tbm_surface_h surface)
94 TBM_RETURN_VAL_IF_FAIL (surface, 0);
96 struct _tbm_surface *surf = (struct _tbm_surface *) surface;
97 struct _tbm_bufmgr *mgr = surf->bufmgr;
100 TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
101 TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
102 TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
103 TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
105 if (!mgr->backend->surface_get_size)
108 size = mgr->backend->surface_get_size (surf, surf->info.width, surf->info.height, surf->info.format);
114 _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)
116 TBM_RETURN_VAL_IF_FAIL (surface, 0);
117 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
119 struct _tbm_surface *surf = (struct _tbm_surface *) surface;
120 struct _tbm_bufmgr *mgr = surf->bufmgr;
123 TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
124 TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
125 TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
126 TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
128 if (!mgr->backend->surface_get_plane_data)
131 ret = mgr->backend->surface_get_plane_data (surf, surf->info.width, surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
139 _tbm_surface_internal_query_num_bos (tbm_format format)
141 TBM_RETURN_VAL_IF_FAIL (format > 0, 0);
142 struct _tbm_bufmgr *mgr;
145 mgr = g_surface_bufmgr;
147 if (!mgr->backend->surface_get_num_bos)
150 ret = mgr->backend->surface_get_num_bos (format);
158 _tbm_surface_internal_destroy (tbm_surface_h surface)
161 tbm_bufmgr bufmgr = surface->bufmgr;
163 for (i = 0; i < surface->num_bos; i++)
165 tbm_bo_unref (surface->bos[i]);
166 surface->bos[i] = NULL;
169 LIST_DEL (&surface->item_link);
174 if(LIST_IS_EMPTY (&bufmgr->surf_list))
176 LIST_DELINIT (&bufmgr->surf_list);
177 _deinit_surface_bufmgr ();
184 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
186 struct _tbm_bufmgr *mgr;
189 _tbm_surface_mutex_lock();
191 if (!g_surface_bufmgr)
193 _init_surface_bufmgr();
194 LIST_INITHEAD (&g_surface_bufmgr->surf_list);
197 mgr = g_surface_bufmgr;
199 if (!mgr->backend->surface_supported_format)
201 _tbm_surface_mutex_unlock();
205 ret = mgr->backend->surface_supported_format (formats, num);
207 _tbm_surface_mutex_unlock();
213 int tbm_surface_internal_get_num_planes (tbm_format format)
220 case TBM_FORMAT_RGB332:
221 case TBM_FORMAT_BGR233:
222 case TBM_FORMAT_XRGB4444:
223 case TBM_FORMAT_XBGR4444:
224 case TBM_FORMAT_RGBX4444:
225 case TBM_FORMAT_BGRX4444:
226 case TBM_FORMAT_ARGB4444:
227 case TBM_FORMAT_ABGR4444:
228 case TBM_FORMAT_RGBA4444:
229 case TBM_FORMAT_BGRA4444:
230 case TBM_FORMAT_XRGB1555:
231 case TBM_FORMAT_XBGR1555:
232 case TBM_FORMAT_RGBX5551:
233 case TBM_FORMAT_BGRX5551:
234 case TBM_FORMAT_ARGB1555:
235 case TBM_FORMAT_ABGR1555:
236 case TBM_FORMAT_RGBA5551:
237 case TBM_FORMAT_BGRA5551:
238 case TBM_FORMAT_RGB565:
239 case TBM_FORMAT_BGR565:
240 case TBM_FORMAT_RGB888:
241 case TBM_FORMAT_BGR888:
242 case TBM_FORMAT_XRGB8888:
243 case TBM_FORMAT_XBGR8888:
244 case TBM_FORMAT_RGBX8888:
245 case TBM_FORMAT_BGRX8888:
246 case TBM_FORMAT_ARGB8888:
247 case TBM_FORMAT_ABGR8888:
248 case TBM_FORMAT_RGBA8888:
249 case TBM_FORMAT_BGRA8888:
250 case TBM_FORMAT_XRGB2101010:
251 case TBM_FORMAT_XBGR2101010:
252 case TBM_FORMAT_RGBX1010102:
253 case TBM_FORMAT_BGRX1010102:
254 case TBM_FORMAT_ARGB2101010:
255 case TBM_FORMAT_ABGR2101010:
256 case TBM_FORMAT_RGBA1010102:
257 case TBM_FORMAT_BGRA1010102:
258 case TBM_FORMAT_YUYV:
259 case TBM_FORMAT_YVYU:
260 case TBM_FORMAT_UYVY:
261 case TBM_FORMAT_VYUY:
262 case TBM_FORMAT_AYUV:
265 case TBM_FORMAT_NV12:
266 case TBM_FORMAT_NV21:
267 case TBM_FORMAT_NV16:
268 case TBM_FORMAT_NV61:
271 case TBM_FORMAT_YUV410:
272 case TBM_FORMAT_YVU410:
273 case TBM_FORMAT_YUV411:
274 case TBM_FORMAT_YVU411:
275 case TBM_FORMAT_YUV420:
276 case TBM_FORMAT_YVU420:
277 case TBM_FORMAT_YUV422:
278 case TBM_FORMAT_YVU422:
279 case TBM_FORMAT_YUV444:
280 case TBM_FORMAT_YVU444:
291 int tbm_surface_internal_get_bpp (tbm_format format)
298 case TBM_FORMAT_RGB332:
299 case TBM_FORMAT_BGR233:
302 case TBM_FORMAT_XRGB4444:
303 case TBM_FORMAT_XBGR4444:
304 case TBM_FORMAT_RGBX4444:
305 case TBM_FORMAT_BGRX4444:
306 case TBM_FORMAT_ARGB4444:
307 case TBM_FORMAT_ABGR4444:
308 case TBM_FORMAT_RGBA4444:
309 case TBM_FORMAT_BGRA4444:
310 case TBM_FORMAT_XRGB1555:
311 case TBM_FORMAT_XBGR1555:
312 case TBM_FORMAT_RGBX5551:
313 case TBM_FORMAT_BGRX5551:
314 case TBM_FORMAT_ARGB1555:
315 case TBM_FORMAT_ABGR1555:
316 case TBM_FORMAT_RGBA5551:
317 case TBM_FORMAT_BGRA5551:
318 case TBM_FORMAT_RGB565:
319 case TBM_FORMAT_BGR565:
322 case TBM_FORMAT_RGB888:
323 case TBM_FORMAT_BGR888:
326 case TBM_FORMAT_XRGB8888:
327 case TBM_FORMAT_XBGR8888:
328 case TBM_FORMAT_RGBX8888:
329 case TBM_FORMAT_BGRX8888:
330 case TBM_FORMAT_ARGB8888:
331 case TBM_FORMAT_ABGR8888:
332 case TBM_FORMAT_RGBA8888:
333 case TBM_FORMAT_BGRA8888:
334 case TBM_FORMAT_XRGB2101010:
335 case TBM_FORMAT_XBGR2101010:
336 case TBM_FORMAT_RGBX1010102:
337 case TBM_FORMAT_BGRX1010102:
338 case TBM_FORMAT_ARGB2101010:
339 case TBM_FORMAT_ABGR2101010:
340 case TBM_FORMAT_RGBA1010102:
341 case TBM_FORMAT_BGRA1010102:
342 case TBM_FORMAT_YUYV:
343 case TBM_FORMAT_YVYU:
344 case TBM_FORMAT_UYVY:
345 case TBM_FORMAT_VYUY:
346 case TBM_FORMAT_AYUV:
349 case TBM_FORMAT_NV12:
350 case TBM_FORMAT_NV21:
353 case TBM_FORMAT_NV16:
354 case TBM_FORMAT_NV61:
357 case TBM_FORMAT_YUV410:
358 case TBM_FORMAT_YVU410:
361 case TBM_FORMAT_YUV411:
362 case TBM_FORMAT_YVU411:
363 case TBM_FORMAT_YUV420:
364 case TBM_FORMAT_YVU420:
367 case TBM_FORMAT_YUV422:
368 case TBM_FORMAT_YVU422:
371 case TBM_FORMAT_YUV444:
372 case TBM_FORMAT_YVU444:
383 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
385 TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
386 TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
388 struct _tbm_bufmgr *mgr;
389 struct _tbm_surface *surf = NULL;
393 uint32_t bo_size = 0;
397 _tbm_surface_mutex_lock();
399 if (!g_surface_bufmgr)
401 _init_surface_bufmgr();
402 LIST_INITHEAD (&g_surface_bufmgr->surf_list);
405 mgr = g_surface_bufmgr;
406 if (!TBM_BUFMGR_IS_VALID(mgr))
408 _tbm_surface_mutex_unlock();
411 surf = calloc (1, sizeof(struct _tbm_surface));
414 _tbm_surface_mutex_unlock();
419 surf->info.width = width;
420 surf->info.height = height;
421 surf->info.format = format;
422 surf->info.bpp = tbm_surface_internal_get_bpp (format);
423 surf->info.size = _tbm_surface_internal_query_size (surf);
424 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
425 surf->num_bos = _tbm_surface_internal_query_num_bos(format);
428 /* get size, stride and offset bo_idx*/
429 for (i = 0; i < surf->info.num_planes; i++)
431 _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride, &bo_idx);
432 surf->info.planes[i].size = size;
433 surf->info.planes[i].offset = offset;
434 surf->info.planes[i].stride = stride;
435 surf->planes_bo_idx[i] = bo_idx;
440 for (i = 0; i < surf->num_bos; i++)
443 for (j = 0; j < surf->info.num_planes; j++)
445 if (surf->planes_bo_idx[j] == i)
446 bo_size += surf->info.planes[j].size;
448 surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
450 for (j = 0; j < i; j++)
451 tbm_bo_unref (surf->bos[j]);
456 if(LIST_IS_EMPTY (&mgr->surf_list))
458 LIST_DELINIT (&mgr->surf_list);
459 _deinit_surface_bufmgr ();
462 _tbm_surface_mutex_unlock();
467 LIST_ADD (&surf->item_link, &mgr->surf_list);
469 _tbm_surface_mutex_unlock();
475 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
477 TBM_RETURN_VAL_IF_FAIL (bos, NULL);
478 TBM_RETURN_VAL_IF_FAIL (info, NULL);
479 TBM_RETURN_VAL_IF_FAIL (num == 1 || info->num_planes == num, NULL);
481 struct _tbm_bufmgr *mgr;
482 struct _tbm_surface *surf = NULL;
485 _tbm_surface_mutex_lock();
487 if (!g_surface_bufmgr)
489 _init_surface_bufmgr();
490 LIST_INITHEAD (&g_surface_bufmgr->surf_list);
493 mgr = g_surface_bufmgr;
494 if (!TBM_BUFMGR_IS_VALID(mgr))
496 _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;
527 surf->planes_bo_idx[i] = 0;
529 surf->planes_bo_idx[i] = i;
534 surf->info.size = info->size;
539 for (i = 0; i < info->num_planes; i++)
541 surf->info.size += surf->info.planes[i].size;
545 surf->flags = TBM_BO_DEFAULT;
547 /* create only one bo */
549 for (i = 0; i < num; i++)
554 surf->bos[i] = tbm_bo_ref(bos[i]);
557 LIST_ADD (&surf->item_link, &mgr->surf_list);
559 _tbm_surface_mutex_unlock();
563 for (i = 0; i < num; i++)
567 tbm_bo_unref (surf->bos[i]);
575 if(LIST_IS_EMPTY (&g_surface_bufmgr->surf_list))
577 LIST_DELINIT (&g_surface_bufmgr->surf_list);
578 _deinit_surface_bufmgr ();
581 _tbm_surface_mutex_unlock();
588 tbm_surface_internal_destroy (tbm_surface_h surface)
593 _tbm_surface_mutex_lock();
597 if (surface->refcnt > 0) {
598 _tbm_surface_mutex_unlock();
602 if (surface->refcnt == 0)
603 _tbm_surface_internal_destroy(surface);
605 _tbm_surface_mutex_unlock();
610 tbm_surface_internal_ref (tbm_surface_h surface)
612 TBM_RETURN_IF_FAIL (surface);
614 _tbm_surface_mutex_lock();
618 _tbm_surface_mutex_unlock();
622 tbm_surface_internal_unref (tbm_surface_h surface)
624 TBM_RETURN_IF_FAIL (surface);
626 _tbm_surface_mutex_lock();
630 if (surface->refcnt > 0) {
631 _tbm_surface_mutex_unlock();
635 if (surface->refcnt == 0)
636 _tbm_surface_internal_destroy(surface);
638 _tbm_surface_mutex_unlock();
642 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
644 TBM_RETURN_VAL_IF_FAIL (surface, 0);
646 struct _tbm_surface *surf;
649 _tbm_surface_mutex_lock();
651 surf = (struct _tbm_surface *) surface;
654 _tbm_surface_mutex_unlock();
660 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
662 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
663 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
665 struct _tbm_surface *surf;
668 _tbm_surface_mutex_lock();
670 surf = (struct _tbm_surface *) surface;
671 bo = surf->bos[bo_idx];
673 _tbm_surface_mutex_unlock();
679 tbm_surface_internal_get_size (tbm_surface_h surface)
681 TBM_RETURN_VAL_IF_FAIL (surface, 0);
683 struct _tbm_surface *surf;
686 _tbm_surface_mutex_lock();
688 surf = (struct _tbm_surface *) surface;
689 size = surf->info.size;
691 _tbm_surface_mutex_unlock();
697 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
699 TBM_RETURN_VAL_IF_FAIL (surface, 0);
700 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
702 struct _tbm_surface *surf;
704 _tbm_surface_mutex_lock();
706 surf = (struct _tbm_surface *) surface;
708 if (plane_idx >= surf->info.num_planes)
710 _tbm_surface_mutex_unlock();
714 *size = surf->info.planes[plane_idx].size;
715 *offset = surf->info.planes[plane_idx].offset;
716 *pitch = surf->info.planes[plane_idx].stride;
718 _tbm_surface_mutex_unlock();
724 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
726 struct _tbm_surface *surf;
727 tbm_bo_handle bo_handles[4];
730 _tbm_surface_mutex_lock();
732 memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
734 surf = (struct _tbm_surface *)surface;
736 info->width = surf->info.width;
737 info->height = surf->info.height;
738 info->format = surf->info.format;
739 info->bpp = surf->info.bpp;
740 info->size = surf->info.size;
741 info->num_planes = surf->info.num_planes;
745 for (i = 0; i < surf->num_bos; i++)
747 bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
748 if (bo_handles[i].ptr == NULL)
750 for (j = 0; j < i; j++)
751 tbm_bo_unmap (surf->bos[j]);
753 _tbm_surface_mutex_unlock();
760 for (i = 0; i < surf->num_bos; i++)
762 bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
763 if (bo_handles[i].ptr == NULL)
765 _tbm_surface_mutex_unlock();
771 for (i = 0; i < surf->info.num_planes; i++)
773 info->planes[i].size = surf->info.planes[i].size;
774 info->planes[i].offset = surf->info.planes[i].offset;
775 info->planes[i].stride = surf->info.planes[i].stride;
776 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
779 _tbm_surface_mutex_unlock();
785 tbm_surface_internal_unmap (tbm_surface_h surface)
787 struct _tbm_surface *surf;
790 _tbm_surface_mutex_lock();
792 surf = (struct _tbm_surface *)surface;
794 for (i = 0; i < surf->num_bos; i++)
795 tbm_bo_unmap (surf->bos[i]);
797 _tbm_surface_mutex_unlock();
801 tbm_surface_internal_get_width (tbm_surface_h surface)
803 struct _tbm_surface *surf;
806 _tbm_surface_mutex_lock();
808 surf = (struct _tbm_surface *)surface;
809 width = surf->info.width;
811 _tbm_surface_mutex_unlock();
817 tbm_surface_internal_get_height (tbm_surface_h surface)
819 struct _tbm_surface *surf;
822 _tbm_surface_mutex_lock();
824 surf = (struct _tbm_surface *)surface;
825 height = surf->info.height;
827 _tbm_surface_mutex_unlock();
834 tbm_surface_internal_get_format (tbm_surface_h surface)
836 struct _tbm_surface *surf;
839 _tbm_surface_mutex_lock();
841 surf = (struct _tbm_surface *)surface;
842 format = surf->info.format;
844 _tbm_surface_mutex_unlock();
850 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
852 TBM_RETURN_VAL_IF_FAIL (surface, 0);
853 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
854 struct _tbm_surface *surf;
857 _tbm_surface_mutex_lock();
859 surf = (struct _tbm_surface *)surface;
860 bo_idx = surf->planes_bo_idx[plane_idx];
862 _tbm_surface_mutex_unlock();