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);
481 TBM_RETURN_VAL_IF_FAIL (num == 1 || info->num_planes == num, NULL);
483 struct _tbm_bufmgr *mgr;
484 struct _tbm_surface *surf = NULL;
487 _tbm_surface_mutex_lock();
489 if (!g_surface_bufmgr)
491 _init_surface_bufmgr();
492 LIST_INITHEAD (&g_surface_list);
495 mgr = g_surface_bufmgr;
496 if (!TBM_BUFMGR_IS_VALID(mgr))
498 _tbm_surface_mutex_unlock();
502 surf = calloc (1, sizeof(struct _tbm_surface));
505 _tbm_surface_mutex_unlock();
510 surf->info.width = info->width;
511 surf->info.height = info->height;
512 surf->info.format = info->format;
513 surf->info.bpp = info->bpp;
514 surf->info.num_planes = info->num_planes;
517 /* get size, stride and offset */
518 for (i = 0; i < info->num_planes; i++)
520 surf->info.planes[i].offset = info->planes[i].offset;
521 surf->info.planes[i].stride = info->planes[i].stride;
523 if (info->planes[i].size > 0)
524 surf->info.planes[i].size = info->planes[i].size;
526 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
529 surf->planes_bo_idx[i] = 0;
531 surf->planes_bo_idx[i] = i;
536 surf->info.size = info->size;
541 for (i = 0; i < info->num_planes; i++)
543 surf->info.size += surf->info.planes[i].size;
547 surf->flags = TBM_BO_DEFAULT;
549 /* create only one bo */
551 for (i = 0; i < num; i++)
556 surf->bos[i] = tbm_bo_ref(bos[i]);
559 LIST_ADD (&surf->item_link, &g_surface_list);
561 _tbm_surface_mutex_unlock();
565 for (i = 0; i < num; i++)
569 tbm_bo_unref (surf->bos[i]);
577 if(LIST_IS_EMPTY (&g_surface_list))
579 _deinit_surface_bufmgr ();
580 LIST_DELINIT (&g_surface_list);
583 _tbm_surface_mutex_unlock();
590 tbm_surface_internal_destroy (tbm_surface_h surface)
595 _tbm_surface_mutex_lock();
599 if (surface->refcnt > 0) {
600 _tbm_surface_mutex_unlock();
604 if (surface->refcnt == 0)
605 _tbm_surface_internal_destroy(surface);
607 _tbm_surface_mutex_unlock();
612 tbm_surface_internal_ref (tbm_surface_h surface)
614 TBM_RETURN_IF_FAIL (surface);
616 _tbm_surface_mutex_lock();
620 _tbm_surface_mutex_unlock();
624 tbm_surface_internal_unref (tbm_surface_h surface)
626 TBM_RETURN_IF_FAIL (surface);
628 _tbm_surface_mutex_lock();
632 if (surface->refcnt > 0) {
633 _tbm_surface_mutex_unlock();
637 if (surface->refcnt == 0)
638 _tbm_surface_internal_destroy(surface);
640 _tbm_surface_mutex_unlock();
644 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
646 TBM_RETURN_VAL_IF_FAIL (surface, 0);
648 struct _tbm_surface *surf;
651 _tbm_surface_mutex_lock();
653 surf = (struct _tbm_surface *) surface;
656 _tbm_surface_mutex_unlock();
662 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
664 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
665 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
667 struct _tbm_surface *surf;
670 _tbm_surface_mutex_lock();
672 surf = (struct _tbm_surface *) surface;
673 bo = surf->bos[bo_idx];
675 _tbm_surface_mutex_unlock();
681 tbm_surface_internal_get_size (tbm_surface_h surface)
683 TBM_RETURN_VAL_IF_FAIL (surface, 0);
685 struct _tbm_surface *surf;
688 _tbm_surface_mutex_lock();
690 surf = (struct _tbm_surface *) surface;
691 size = surf->info.size;
693 _tbm_surface_mutex_unlock();
699 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
701 TBM_RETURN_VAL_IF_FAIL (surface, 0);
702 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
704 struct _tbm_surface *surf;
706 _tbm_surface_mutex_lock();
708 surf = (struct _tbm_surface *) surface;
710 if (plane_idx >= surf->info.num_planes)
712 _tbm_surface_mutex_unlock();
716 *size = surf->info.planes[plane_idx].size;
717 *offset = surf->info.planes[plane_idx].offset;
718 *pitch = surf->info.planes[plane_idx].stride;
720 _tbm_surface_mutex_unlock();
726 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
728 struct _tbm_surface *surf;
729 tbm_bo_handle bo_handles[4];
732 _tbm_surface_mutex_lock();
734 memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
736 surf = (struct _tbm_surface *)surface;
738 info->width = surf->info.width;
739 info->height = surf->info.height;
740 info->format = surf->info.format;
741 info->bpp = surf->info.bpp;
742 info->size = surf->info.size;
743 info->num_planes = surf->info.num_planes;
747 for (i = 0; i < surf->num_bos; i++)
749 bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
750 if (bo_handles[i].ptr == NULL)
752 for (j = 0; j < i; j++)
753 tbm_bo_unmap (surf->bos[j]);
755 _tbm_surface_mutex_unlock();
762 for (i = 0; i < surf->num_bos; i++)
764 bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
765 if (bo_handles[i].ptr == NULL)
767 _tbm_surface_mutex_unlock();
773 for (i = 0; i < surf->info.num_planes; i++)
775 info->planes[i].size = surf->info.planes[i].size;
776 info->planes[i].offset = surf->info.planes[i].offset;
777 info->planes[i].stride = surf->info.planes[i].stride;
778 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
781 _tbm_surface_mutex_unlock();
787 tbm_surface_internal_unmap (tbm_surface_h surface)
789 struct _tbm_surface *surf;
792 _tbm_surface_mutex_lock();
794 surf = (struct _tbm_surface *)surface;
796 for (i = 0; i < surf->num_bos; i++)
797 tbm_bo_unmap (surf->bos[i]);
799 _tbm_surface_mutex_unlock();
803 tbm_surface_internal_get_width (tbm_surface_h surface)
805 struct _tbm_surface *surf;
808 _tbm_surface_mutex_lock();
810 surf = (struct _tbm_surface *)surface;
811 width = surf->info.width;
813 _tbm_surface_mutex_unlock();
819 tbm_surface_internal_get_height (tbm_surface_h surface)
821 struct _tbm_surface *surf;
824 _tbm_surface_mutex_lock();
826 surf = (struct _tbm_surface *)surface;
827 height = surf->info.height;
829 _tbm_surface_mutex_unlock();
836 tbm_surface_internal_get_format (tbm_surface_h surface)
838 struct _tbm_surface *surf;
841 _tbm_surface_mutex_lock();
843 surf = (struct _tbm_surface *)surface;
844 format = surf->info.format;
846 _tbm_surface_mutex_unlock();
852 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
854 TBM_RETURN_VAL_IF_FAIL (surface, 0);
855 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
856 struct _tbm_surface *surf;
859 _tbm_surface_mutex_lock();
861 surf = (struct _tbm_surface *)surface;
862 bo_idx = surf->planes_bo_idx[plane_idx];
864 _tbm_surface_mutex_unlock();