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);
161 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
163 struct _tbm_bufmgr *mgr;
166 _tbm_surface_mutex_lock();
168 if (!g_surface_bufmgr)
170 _init_surface_bufmgr();
171 LIST_INITHEAD (&g_surface_list);
174 mgr = g_surface_bufmgr;
176 if (!mgr->backend->surface_supported_format)
178 _tbm_surface_mutex_unlock();
182 ret = mgr->backend->surface_supported_format (formats, num);
184 _tbm_surface_mutex_unlock();
190 int tbm_surface_internal_get_num_planes (tbm_format format)
197 case TBM_FORMAT_RGB332:
198 case TBM_FORMAT_BGR233:
199 case TBM_FORMAT_XRGB4444:
200 case TBM_FORMAT_XBGR4444:
201 case TBM_FORMAT_RGBX4444:
202 case TBM_FORMAT_BGRX4444:
203 case TBM_FORMAT_ARGB4444:
204 case TBM_FORMAT_ABGR4444:
205 case TBM_FORMAT_RGBA4444:
206 case TBM_FORMAT_BGRA4444:
207 case TBM_FORMAT_XRGB1555:
208 case TBM_FORMAT_XBGR1555:
209 case TBM_FORMAT_RGBX5551:
210 case TBM_FORMAT_BGRX5551:
211 case TBM_FORMAT_ARGB1555:
212 case TBM_FORMAT_ABGR1555:
213 case TBM_FORMAT_RGBA5551:
214 case TBM_FORMAT_BGRA5551:
215 case TBM_FORMAT_RGB565:
216 case TBM_FORMAT_BGR565:
217 case TBM_FORMAT_RGB888:
218 case TBM_FORMAT_BGR888:
219 case TBM_FORMAT_XRGB8888:
220 case TBM_FORMAT_XBGR8888:
221 case TBM_FORMAT_RGBX8888:
222 case TBM_FORMAT_BGRX8888:
223 case TBM_FORMAT_ARGB8888:
224 case TBM_FORMAT_ABGR8888:
225 case TBM_FORMAT_RGBA8888:
226 case TBM_FORMAT_BGRA8888:
227 case TBM_FORMAT_XRGB2101010:
228 case TBM_FORMAT_XBGR2101010:
229 case TBM_FORMAT_RGBX1010102:
230 case TBM_FORMAT_BGRX1010102:
231 case TBM_FORMAT_ARGB2101010:
232 case TBM_FORMAT_ABGR2101010:
233 case TBM_FORMAT_RGBA1010102:
234 case TBM_FORMAT_BGRA1010102:
235 case TBM_FORMAT_YUYV:
236 case TBM_FORMAT_YVYU:
237 case TBM_FORMAT_UYVY:
238 case TBM_FORMAT_VYUY:
239 case TBM_FORMAT_AYUV:
242 case TBM_FORMAT_NV12:
243 case TBM_FORMAT_NV21:
244 case TBM_FORMAT_NV16:
245 case TBM_FORMAT_NV61:
248 case TBM_FORMAT_YUV410:
249 case TBM_FORMAT_YVU410:
250 case TBM_FORMAT_YUV411:
251 case TBM_FORMAT_YVU411:
252 case TBM_FORMAT_YUV420:
253 case TBM_FORMAT_YVU420:
254 case TBM_FORMAT_YUV422:
255 case TBM_FORMAT_YVU422:
256 case TBM_FORMAT_YUV444:
257 case TBM_FORMAT_YVU444:
268 int tbm_surface_internal_get_bpp (tbm_format format)
275 case TBM_FORMAT_RGB332:
276 case TBM_FORMAT_BGR233:
279 case TBM_FORMAT_XRGB4444:
280 case TBM_FORMAT_XBGR4444:
281 case TBM_FORMAT_RGBX4444:
282 case TBM_FORMAT_BGRX4444:
283 case TBM_FORMAT_ARGB4444:
284 case TBM_FORMAT_ABGR4444:
285 case TBM_FORMAT_RGBA4444:
286 case TBM_FORMAT_BGRA4444:
287 case TBM_FORMAT_XRGB1555:
288 case TBM_FORMAT_XBGR1555:
289 case TBM_FORMAT_RGBX5551:
290 case TBM_FORMAT_BGRX5551:
291 case TBM_FORMAT_ARGB1555:
292 case TBM_FORMAT_ABGR1555:
293 case TBM_FORMAT_RGBA5551:
294 case TBM_FORMAT_BGRA5551:
295 case TBM_FORMAT_RGB565:
296 case TBM_FORMAT_BGR565:
299 case TBM_FORMAT_RGB888:
300 case TBM_FORMAT_BGR888:
303 case TBM_FORMAT_XRGB8888:
304 case TBM_FORMAT_XBGR8888:
305 case TBM_FORMAT_RGBX8888:
306 case TBM_FORMAT_BGRX8888:
307 case TBM_FORMAT_ARGB8888:
308 case TBM_FORMAT_ABGR8888:
309 case TBM_FORMAT_RGBA8888:
310 case TBM_FORMAT_BGRA8888:
311 case TBM_FORMAT_XRGB2101010:
312 case TBM_FORMAT_XBGR2101010:
313 case TBM_FORMAT_RGBX1010102:
314 case TBM_FORMAT_BGRX1010102:
315 case TBM_FORMAT_ARGB2101010:
316 case TBM_FORMAT_ABGR2101010:
317 case TBM_FORMAT_RGBA1010102:
318 case TBM_FORMAT_BGRA1010102:
319 case TBM_FORMAT_YUYV:
320 case TBM_FORMAT_YVYU:
321 case TBM_FORMAT_UYVY:
322 case TBM_FORMAT_VYUY:
323 case TBM_FORMAT_AYUV:
326 case TBM_FORMAT_NV12:
327 case TBM_FORMAT_NV21:
330 case TBM_FORMAT_NV16:
331 case TBM_FORMAT_NV61:
334 case TBM_FORMAT_YUV410:
335 case TBM_FORMAT_YVU410:
338 case TBM_FORMAT_YUV411:
339 case TBM_FORMAT_YVU411:
340 case TBM_FORMAT_YUV420:
341 case TBM_FORMAT_YVU420:
344 case TBM_FORMAT_YUV422:
345 case TBM_FORMAT_YVU422:
348 case TBM_FORMAT_YUV444:
349 case TBM_FORMAT_YVU444:
360 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
362 TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
363 TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
365 struct _tbm_bufmgr *mgr;
366 struct _tbm_surface *surf = NULL;
370 uint32_t bo_size = 0;
374 _tbm_surface_mutex_lock();
376 if (!g_surface_bufmgr)
378 _init_surface_bufmgr();
379 LIST_INITHEAD (&g_surface_list);
382 mgr = g_surface_bufmgr;
383 if (!TBM_BUFMGR_IS_VALID(mgr))
385 _tbm_surface_mutex_unlock();
388 surf = calloc (1, sizeof(struct _tbm_surface));
391 _tbm_surface_mutex_unlock();
396 surf->info.width = width;
397 surf->info.height = height;
398 surf->info.format = format;
399 surf->info.bpp = tbm_surface_internal_get_bpp (format);
400 surf->info.size = _tbm_surface_internal_query_size (surf);
401 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
402 surf->num_bos = _tbm_surface_internal_query_num_bos(format);
404 /* get size, stride and offset bo_idx*/
405 for (i = 0; i < surf->info.num_planes; i++)
407 _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride, &bo_idx);
408 surf->info.planes[i].size = size;
409 surf->info.planes[i].offset = offset;
410 surf->info.planes[i].stride = stride;
411 surf->planes_bo_idx[i] = bo_idx;
416 for (i = 0; i < surf->num_bos; i++)
419 for (j = 0; j < surf->info.num_planes; j++)
421 if (surf->planes_bo_idx[i] == i)
422 bo_size += surf->info.planes[i].size;
425 surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
427 for (j = 0; j < i; j++)
428 tbm_bo_unref (surf->bos[j]);
433 if(LIST_IS_EMPTY (&g_surface_list))
435 _deinit_surface_bufmgr ();
436 LIST_DELINIT (&g_surface_list);
437 _tbm_surface_mutex_unlock();
443 LIST_ADD (&surf->item_link, &g_surface_list);
445 _tbm_surface_mutex_unlock();
451 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
453 TBM_RETURN_VAL_IF_FAIL (bos, NULL);
454 TBM_RETURN_VAL_IF_FAIL (info, NULL);
456 struct _tbm_bufmgr *mgr;
457 struct _tbm_surface *surf = NULL;
460 _tbm_surface_mutex_lock();
462 if (!g_surface_bufmgr)
464 _init_surface_bufmgr();
465 LIST_INITHEAD (&g_surface_list);
468 mgr = g_surface_bufmgr;
469 if (!TBM_BUFMGR_IS_VALID(mgr))
471 _tbm_surface_mutex_unlock();
474 surf = calloc (1, sizeof(struct _tbm_surface));
477 _tbm_surface_mutex_unlock();
482 surf->info.width = info->width;
483 surf->info.height = info->height;
484 surf->info.format = info->format;
485 surf->info.bpp = info->bpp;
486 surf->info.size = info->size;
487 surf->info.num_planes = info->num_planes;
489 /* get size, stride and offset */
490 for (i = 0; i < info->num_planes; i++)
492 surf->info.planes[i].size = info->planes[i].size;
493 surf->info.planes[i].offset = info->planes[i].offset;
494 surf->info.planes[i].stride = info->planes[i].stride;
497 surf->flags = TBM_BO_DEFAULT;
499 /* create only one bo */
501 for (i = 0; i < num; i++)
506 surf->bos[i] = tbm_bo_ref(bos[i]);
509 LIST_ADD (&surf->item_link, &g_surface_list);
511 _tbm_surface_mutex_unlock();
515 for (i = 0; i < num; i++)
519 tbm_bo_unref (surf->bos[i]);
527 if(LIST_IS_EMPTY (&g_surface_list))
529 _deinit_surface_bufmgr ();
530 LIST_DELINIT (&g_surface_list);
533 _tbm_surface_mutex_unlock();
540 tbm_surface_internal_destroy (tbm_surface_h surface)
547 _tbm_surface_mutex_lock();
549 surface = (struct _tbm_surface *)surface;
551 for (i = 0; i < surface->num_bos; i++)
553 tbm_bo_unref (surface->bos[i]);
554 surface->bos[i] = NULL;
557 LIST_DEL (&surface->item_link);
562 if(LIST_IS_EMPTY (&g_surface_list))
564 _deinit_surface_bufmgr ();
565 LIST_DELINIT (&g_surface_list);
568 _tbm_surface_mutex_unlock();
573 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
575 TBM_RETURN_VAL_IF_FAIL (surface, 0);
577 struct _tbm_surface *surf;
580 _tbm_surface_mutex_lock();
582 surf = (struct _tbm_surface *) surface;
585 _tbm_surface_mutex_unlock();
591 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
593 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
594 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
596 struct _tbm_surface *surf;
599 _tbm_surface_mutex_lock();
601 surf = (struct _tbm_surface *) surface;
602 bo = surf->bos[bo_idx];
604 _tbm_surface_mutex_unlock();
610 tbm_surface_internal_get_size (tbm_surface_h surface)
612 TBM_RETURN_VAL_IF_FAIL (surface, 0);
614 struct _tbm_surface *surf;
617 _tbm_surface_mutex_lock();
619 surf = (struct _tbm_surface *) surface;
620 size = surf->info.size;
622 _tbm_surface_mutex_unlock();
628 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
630 TBM_RETURN_VAL_IF_FAIL (surface, 0);
631 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
633 struct _tbm_surface *surf;
635 _tbm_surface_mutex_lock();
637 surf = (struct _tbm_surface *) surface;
639 if (plane_idx >= surf->info.num_planes)
641 _tbm_surface_mutex_unlock();
645 *size = surf->info.planes[plane_idx].size;
646 *offset = surf->info.planes[plane_idx].offset;
647 *pitch = surf->info.planes[plane_idx].stride;
649 _tbm_surface_mutex_unlock();
655 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
657 struct _tbm_surface *surf;
658 tbm_bo_handle bo_handles[4];
661 _tbm_surface_mutex_lock();
663 surf = (struct _tbm_surface *)surface;
665 info->width = surf->info.width;
666 info->height = surf->info.height;
667 info->format = surf->info.format;
668 info->bpp = surf->info.bpp;
669 info->size = surf->info.size;
670 info->num_planes = surf->info.num_planes;
674 for (i = 0; i < surf->num_bos; i++)
676 bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
677 if (bo_handles[i].ptr == NULL)
679 for (j = 0; j < i; j++)
680 tbm_bo_unmap (surf->bos[j]);
682 _tbm_surface_mutex_unlock();
689 for (i = 0; i < surf->num_bos; i++)
691 bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
692 if (bo_handles[i].ptr == NULL)
694 _tbm_surface_mutex_unlock();
700 for (i = 0; i < surf->info.num_planes; i++)
702 info->planes[i].size = surf->info.planes[i].size;
703 info->planes[i].offset = surf->info.planes[i].offset;
704 info->planes[i].stride = surf->info.planes[i].stride;
705 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
708 _tbm_surface_mutex_unlock();
714 tbm_surface_internal_unmap (tbm_surface_h surface)
716 struct _tbm_surface *surf;
719 _tbm_surface_mutex_lock();
721 surf = (struct _tbm_surface *)surface;
723 for (i = 0; i < surf->num_bos; i++)
724 tbm_bo_unmap (surf->bos[i]);
726 _tbm_surface_mutex_unlock();
730 tbm_surface_internal_get_width (tbm_surface_h surface)
732 struct _tbm_surface *surf;
735 _tbm_surface_mutex_lock();
737 surf = (struct _tbm_surface *)surface;
738 width = surf->info.width;
740 _tbm_surface_mutex_unlock();
746 tbm_surface_internal_get_height (tbm_surface_h surface)
748 struct _tbm_surface *surf;
751 _tbm_surface_mutex_lock();
753 surf = (struct _tbm_surface *)surface;
754 height = surf->info.height;
756 _tbm_surface_mutex_unlock();
763 tbm_surface_internal_get_format (tbm_surface_h surface)
765 struct _tbm_surface *surf;
768 _tbm_surface_mutex_lock();
770 surf = (struct _tbm_surface *)surface;
771 format = surf->info.format;
773 _tbm_surface_mutex_unlock();
779 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
781 TBM_RETURN_VAL_IF_FAIL (surface, 0);
782 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
783 struct _tbm_surface *surf;
786 _tbm_surface_mutex_lock();
788 surf = (struct _tbm_surface *)surface;
789 bo_idx = surf->planes_bo_idx[plane_idx];
791 _tbm_surface_mutex_unlock();