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 surface = (struct _tbm_surface *)surface;
166 for (i = 0; i < surface->num_bos; i++)
168 tbm_bo_unref (surface->bos[i]);
169 surface->bos[i] = NULL;
172 LIST_DEL (&surface->item_link);
177 if(LIST_IS_EMPTY (&g_surface_list))
179 _deinit_surface_bufmgr ();
180 LIST_DELINIT (&g_surface_list);
187 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
189 struct _tbm_bufmgr *mgr;
192 _tbm_surface_mutex_lock();
194 if (!g_surface_bufmgr)
196 _init_surface_bufmgr();
197 LIST_INITHEAD (&g_surface_list);
200 mgr = g_surface_bufmgr;
202 if (!mgr->backend->surface_supported_format)
204 _tbm_surface_mutex_unlock();
208 ret = mgr->backend->surface_supported_format (formats, num);
210 _tbm_surface_mutex_unlock();
216 int tbm_surface_internal_get_num_planes (tbm_format format)
223 case TBM_FORMAT_RGB332:
224 case TBM_FORMAT_BGR233:
225 case TBM_FORMAT_XRGB4444:
226 case TBM_FORMAT_XBGR4444:
227 case TBM_FORMAT_RGBX4444:
228 case TBM_FORMAT_BGRX4444:
229 case TBM_FORMAT_ARGB4444:
230 case TBM_FORMAT_ABGR4444:
231 case TBM_FORMAT_RGBA4444:
232 case TBM_FORMAT_BGRA4444:
233 case TBM_FORMAT_XRGB1555:
234 case TBM_FORMAT_XBGR1555:
235 case TBM_FORMAT_RGBX5551:
236 case TBM_FORMAT_BGRX5551:
237 case TBM_FORMAT_ARGB1555:
238 case TBM_FORMAT_ABGR1555:
239 case TBM_FORMAT_RGBA5551:
240 case TBM_FORMAT_BGRA5551:
241 case TBM_FORMAT_RGB565:
242 case TBM_FORMAT_BGR565:
243 case TBM_FORMAT_RGB888:
244 case TBM_FORMAT_BGR888:
245 case TBM_FORMAT_XRGB8888:
246 case TBM_FORMAT_XBGR8888:
247 case TBM_FORMAT_RGBX8888:
248 case TBM_FORMAT_BGRX8888:
249 case TBM_FORMAT_ARGB8888:
250 case TBM_FORMAT_ABGR8888:
251 case TBM_FORMAT_RGBA8888:
252 case TBM_FORMAT_BGRA8888:
253 case TBM_FORMAT_XRGB2101010:
254 case TBM_FORMAT_XBGR2101010:
255 case TBM_FORMAT_RGBX1010102:
256 case TBM_FORMAT_BGRX1010102:
257 case TBM_FORMAT_ARGB2101010:
258 case TBM_FORMAT_ABGR2101010:
259 case TBM_FORMAT_RGBA1010102:
260 case TBM_FORMAT_BGRA1010102:
261 case TBM_FORMAT_YUYV:
262 case TBM_FORMAT_YVYU:
263 case TBM_FORMAT_UYVY:
264 case TBM_FORMAT_VYUY:
265 case TBM_FORMAT_AYUV:
268 case TBM_FORMAT_NV12:
269 case TBM_FORMAT_NV21:
270 case TBM_FORMAT_NV16:
271 case TBM_FORMAT_NV61:
274 case TBM_FORMAT_YUV410:
275 case TBM_FORMAT_YVU410:
276 case TBM_FORMAT_YUV411:
277 case TBM_FORMAT_YVU411:
278 case TBM_FORMAT_YUV420:
279 case TBM_FORMAT_YVU420:
280 case TBM_FORMAT_YUV422:
281 case TBM_FORMAT_YVU422:
282 case TBM_FORMAT_YUV444:
283 case TBM_FORMAT_YVU444:
294 int tbm_surface_internal_get_bpp (tbm_format format)
301 case TBM_FORMAT_RGB332:
302 case TBM_FORMAT_BGR233:
305 case TBM_FORMAT_XRGB4444:
306 case TBM_FORMAT_XBGR4444:
307 case TBM_FORMAT_RGBX4444:
308 case TBM_FORMAT_BGRX4444:
309 case TBM_FORMAT_ARGB4444:
310 case TBM_FORMAT_ABGR4444:
311 case TBM_FORMAT_RGBA4444:
312 case TBM_FORMAT_BGRA4444:
313 case TBM_FORMAT_XRGB1555:
314 case TBM_FORMAT_XBGR1555:
315 case TBM_FORMAT_RGBX5551:
316 case TBM_FORMAT_BGRX5551:
317 case TBM_FORMAT_ARGB1555:
318 case TBM_FORMAT_ABGR1555:
319 case TBM_FORMAT_RGBA5551:
320 case TBM_FORMAT_BGRA5551:
321 case TBM_FORMAT_RGB565:
322 case TBM_FORMAT_BGR565:
325 case TBM_FORMAT_RGB888:
326 case TBM_FORMAT_BGR888:
329 case TBM_FORMAT_XRGB8888:
330 case TBM_FORMAT_XBGR8888:
331 case TBM_FORMAT_RGBX8888:
332 case TBM_FORMAT_BGRX8888:
333 case TBM_FORMAT_ARGB8888:
334 case TBM_FORMAT_ABGR8888:
335 case TBM_FORMAT_RGBA8888:
336 case TBM_FORMAT_BGRA8888:
337 case TBM_FORMAT_XRGB2101010:
338 case TBM_FORMAT_XBGR2101010:
339 case TBM_FORMAT_RGBX1010102:
340 case TBM_FORMAT_BGRX1010102:
341 case TBM_FORMAT_ARGB2101010:
342 case TBM_FORMAT_ABGR2101010:
343 case TBM_FORMAT_RGBA1010102:
344 case TBM_FORMAT_BGRA1010102:
345 case TBM_FORMAT_YUYV:
346 case TBM_FORMAT_YVYU:
347 case TBM_FORMAT_UYVY:
348 case TBM_FORMAT_VYUY:
349 case TBM_FORMAT_AYUV:
352 case TBM_FORMAT_NV12:
353 case TBM_FORMAT_NV21:
356 case TBM_FORMAT_NV16:
357 case TBM_FORMAT_NV61:
360 case TBM_FORMAT_YUV410:
361 case TBM_FORMAT_YVU410:
364 case TBM_FORMAT_YUV411:
365 case TBM_FORMAT_YVU411:
366 case TBM_FORMAT_YUV420:
367 case TBM_FORMAT_YVU420:
370 case TBM_FORMAT_YUV422:
371 case TBM_FORMAT_YVU422:
374 case TBM_FORMAT_YUV444:
375 case TBM_FORMAT_YVU444:
386 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
388 TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
389 TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
391 struct _tbm_bufmgr *mgr;
392 struct _tbm_surface *surf = NULL;
396 uint32_t bo_size = 0;
400 _tbm_surface_mutex_lock();
402 if (!g_surface_bufmgr)
404 _init_surface_bufmgr();
405 LIST_INITHEAD (&g_surface_list);
408 mgr = g_surface_bufmgr;
409 if (!TBM_BUFMGR_IS_VALID(mgr))
411 _tbm_surface_mutex_unlock();
414 surf = calloc (1, sizeof(struct _tbm_surface));
417 _tbm_surface_mutex_unlock();
422 surf->info.width = width;
423 surf->info.height = height;
424 surf->info.format = format;
425 surf->info.bpp = tbm_surface_internal_get_bpp (format);
426 surf->info.size = _tbm_surface_internal_query_size (surf);
427 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
428 surf->num_bos = _tbm_surface_internal_query_num_bos(format);
431 /* get size, stride and offset bo_idx*/
432 for (i = 0; i < surf->info.num_planes; i++)
434 _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride, &bo_idx);
435 surf->info.planes[i].size = size;
436 surf->info.planes[i].offset = offset;
437 surf->info.planes[i].stride = stride;
438 surf->planes_bo_idx[i] = bo_idx;
443 for (i = 0; i < surf->num_bos; i++)
446 for (j = 0; j < surf->info.num_planes; j++)
448 if (surf->planes_bo_idx[i] == i)
449 bo_size += surf->info.planes[i].size;
452 surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
454 for (j = 0; j < i; j++)
455 tbm_bo_unref (surf->bos[j]);
460 if(LIST_IS_EMPTY (&g_surface_list))
462 _deinit_surface_bufmgr ();
463 LIST_DELINIT (&g_surface_list);
466 _tbm_surface_mutex_unlock();
471 LIST_ADD (&surf->item_link, &g_surface_list);
473 _tbm_surface_mutex_unlock();
479 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
481 TBM_RETURN_VAL_IF_FAIL (bos, NULL);
482 TBM_RETURN_VAL_IF_FAIL (info, NULL);
484 struct _tbm_bufmgr *mgr;
485 struct _tbm_surface *surf = NULL;
488 _tbm_surface_mutex_lock();
490 if (!g_surface_bufmgr)
492 _init_surface_bufmgr();
493 LIST_INITHEAD (&g_surface_list);
496 mgr = g_surface_bufmgr;
497 if (!TBM_BUFMGR_IS_VALID(mgr))
499 _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;
531 surf->info.size = info->size;
536 for (i = 0; i < info->num_planes; i++)
538 surf->info.size += surf->info.planes[i].size;
542 surf->flags = TBM_BO_DEFAULT;
544 /* create only one bo */
546 for (i = 0; i < num; i++)
551 surf->bos[i] = tbm_bo_ref(bos[i]);
554 LIST_ADD (&surf->item_link, &g_surface_list);
556 _tbm_surface_mutex_unlock();
560 for (i = 0; i < num; i++)
564 tbm_bo_unref (surf->bos[i]);
572 if(LIST_IS_EMPTY (&g_surface_list))
574 _deinit_surface_bufmgr ();
575 LIST_DELINIT (&g_surface_list);
578 _tbm_surface_mutex_unlock();
585 tbm_surface_internal_destroy (tbm_surface_h surface)
590 _tbm_surface_mutex_lock();
594 if (surface->refcnt > 0) {
595 _tbm_surface_mutex_unlock();
599 if (surface->refcnt == 0)
600 _tbm_surface_internal_destroy(surface);
602 _tbm_surface_mutex_unlock();
607 tbm_surface_internal_ref (tbm_surface_h surface)
609 TBM_RETURN_IF_FAIL (surface);
611 _tbm_surface_mutex_lock();
615 _tbm_surface_mutex_unlock();
619 tbm_surface_internal_unref (tbm_surface_h surface)
621 TBM_RETURN_IF_FAIL (surface);
623 _tbm_surface_mutex_lock();
627 if (surface->refcnt > 0) {
628 _tbm_surface_mutex_unlock();
632 if (surface->refcnt == 0)
633 _tbm_surface_internal_destroy(surface);
635 _tbm_surface_mutex_unlock();
639 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
641 TBM_RETURN_VAL_IF_FAIL (surface, 0);
643 struct _tbm_surface *surf;
646 _tbm_surface_mutex_lock();
648 surf = (struct _tbm_surface *) surface;
651 _tbm_surface_mutex_unlock();
657 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
659 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
660 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
662 struct _tbm_surface *surf;
665 _tbm_surface_mutex_lock();
667 surf = (struct _tbm_surface *) surface;
668 bo = surf->bos[bo_idx];
670 _tbm_surface_mutex_unlock();
676 tbm_surface_internal_get_size (tbm_surface_h surface)
678 TBM_RETURN_VAL_IF_FAIL (surface, 0);
680 struct _tbm_surface *surf;
683 _tbm_surface_mutex_lock();
685 surf = (struct _tbm_surface *) surface;
686 size = surf->info.size;
688 _tbm_surface_mutex_unlock();
694 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
696 TBM_RETURN_VAL_IF_FAIL (surface, 0);
697 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
699 struct _tbm_surface *surf;
701 _tbm_surface_mutex_lock();
703 surf = (struct _tbm_surface *) surface;
705 if (plane_idx >= surf->info.num_planes)
707 _tbm_surface_mutex_unlock();
711 *size = surf->info.planes[plane_idx].size;
712 *offset = surf->info.planes[plane_idx].offset;
713 *pitch = surf->info.planes[plane_idx].stride;
715 _tbm_surface_mutex_unlock();
721 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
723 struct _tbm_surface *surf;
724 tbm_bo_handle bo_handles[4];
727 _tbm_surface_mutex_lock();
729 memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
731 surf = (struct _tbm_surface *)surface;
733 info->width = surf->info.width;
734 info->height = surf->info.height;
735 info->format = surf->info.format;
736 info->bpp = surf->info.bpp;
737 info->size = surf->info.size;
738 info->num_planes = surf->info.num_planes;
742 for (i = 0; i < surf->num_bos; i++)
744 bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
745 if (bo_handles[i].ptr == NULL)
747 for (j = 0; j < i; j++)
748 tbm_bo_unmap (surf->bos[j]);
750 _tbm_surface_mutex_unlock();
757 for (i = 0; i < surf->num_bos; i++)
759 bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
760 if (bo_handles[i].ptr == NULL)
762 _tbm_surface_mutex_unlock();
768 for (i = 0; i < surf->info.num_planes; i++)
770 info->planes[i].size = surf->info.planes[i].size;
771 info->planes[i].offset = surf->info.planes[i].offset;
772 info->planes[i].stride = surf->info.planes[i].stride;
773 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
776 _tbm_surface_mutex_unlock();
782 tbm_surface_internal_unmap (tbm_surface_h surface)
784 struct _tbm_surface *surf;
787 _tbm_surface_mutex_lock();
789 surf = (struct _tbm_surface *)surface;
791 for (i = 0; i < surf->num_bos; i++)
792 tbm_bo_unmap (surf->bos[i]);
794 _tbm_surface_mutex_unlock();
798 tbm_surface_internal_get_width (tbm_surface_h surface)
800 struct _tbm_surface *surf;
803 _tbm_surface_mutex_lock();
805 surf = (struct _tbm_surface *)surface;
806 width = surf->info.width;
808 _tbm_surface_mutex_unlock();
814 tbm_surface_internal_get_height (tbm_surface_h surface)
816 struct _tbm_surface *surf;
819 _tbm_surface_mutex_lock();
821 surf = (struct _tbm_surface *)surface;
822 height = surf->info.height;
824 _tbm_surface_mutex_unlock();
831 tbm_surface_internal_get_format (tbm_surface_h surface)
833 struct _tbm_surface *surf;
836 _tbm_surface_mutex_lock();
838 surf = (struct _tbm_surface *)surface;
839 format = surf->info.format;
841 _tbm_surface_mutex_unlock();
847 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
849 TBM_RETURN_VAL_IF_FAIL (surface, 0);
850 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
851 struct _tbm_surface *surf;
854 _tbm_surface_mutex_lock();
856 surf = (struct _tbm_surface *)surface;
857 bo_idx = surf->planes_bo_idx[plane_idx];
859 _tbm_surface_mutex_unlock();