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);
439 _tbm_surface_mutex_unlock();
444 LIST_ADD (&surf->item_link, &g_surface_list);
446 _tbm_surface_mutex_unlock();
452 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
454 TBM_RETURN_VAL_IF_FAIL (bos, NULL);
455 TBM_RETURN_VAL_IF_FAIL (info, NULL);
457 struct _tbm_bufmgr *mgr;
458 struct _tbm_surface *surf = NULL;
461 _tbm_surface_mutex_lock();
463 if (!g_surface_bufmgr)
465 _init_surface_bufmgr();
466 LIST_INITHEAD (&g_surface_list);
469 mgr = g_surface_bufmgr;
470 if (!TBM_BUFMGR_IS_VALID(mgr))
472 _tbm_surface_mutex_unlock();
475 surf = calloc (1, sizeof(struct _tbm_surface));
478 _tbm_surface_mutex_unlock();
483 surf->info.width = info->width;
484 surf->info.height = info->height;
485 surf->info.format = info->format;
486 surf->info.bpp = info->bpp;
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].offset = info->planes[i].offset;
493 surf->info.planes[i].stride = info->planes[i].stride;
495 if (info->planes[i].size > 0)
496 surf->info.planes[i].size = info->planes[i].size;
498 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
503 surf->info.size = info->size;
508 for (i = 0; i < info->num_planes; i++)
510 surf->info.size += surf->info.planes[i].size;
514 surf->flags = TBM_BO_DEFAULT;
516 /* create only one bo */
518 for (i = 0; i < num; i++)
523 surf->bos[i] = tbm_bo_ref(bos[i]);
526 LIST_ADD (&surf->item_link, &g_surface_list);
528 _tbm_surface_mutex_unlock();
532 for (i = 0; i < num; i++)
536 tbm_bo_unref (surf->bos[i]);
544 if(LIST_IS_EMPTY (&g_surface_list))
546 _deinit_surface_bufmgr ();
547 LIST_DELINIT (&g_surface_list);
550 _tbm_surface_mutex_unlock();
557 tbm_surface_internal_destroy (tbm_surface_h surface)
564 _tbm_surface_mutex_lock();
566 surface = (struct _tbm_surface *)surface;
568 for (i = 0; i < surface->num_bos; i++)
570 tbm_bo_unref (surface->bos[i]);
571 surface->bos[i] = NULL;
574 LIST_DEL (&surface->item_link);
579 if(LIST_IS_EMPTY (&g_surface_list))
581 _deinit_surface_bufmgr ();
582 LIST_DELINIT (&g_surface_list);
585 _tbm_surface_mutex_unlock();
590 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
592 TBM_RETURN_VAL_IF_FAIL (surface, 0);
594 struct _tbm_surface *surf;
597 _tbm_surface_mutex_lock();
599 surf = (struct _tbm_surface *) surface;
602 _tbm_surface_mutex_unlock();
608 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
610 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
611 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
613 struct _tbm_surface *surf;
616 _tbm_surface_mutex_lock();
618 surf = (struct _tbm_surface *) surface;
619 bo = surf->bos[bo_idx];
621 _tbm_surface_mutex_unlock();
627 tbm_surface_internal_get_size (tbm_surface_h surface)
629 TBM_RETURN_VAL_IF_FAIL (surface, 0);
631 struct _tbm_surface *surf;
634 _tbm_surface_mutex_lock();
636 surf = (struct _tbm_surface *) surface;
637 size = surf->info.size;
639 _tbm_surface_mutex_unlock();
645 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
647 TBM_RETURN_VAL_IF_FAIL (surface, 0);
648 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
650 struct _tbm_surface *surf;
652 _tbm_surface_mutex_lock();
654 surf = (struct _tbm_surface *) surface;
656 if (plane_idx >= surf->info.num_planes)
658 _tbm_surface_mutex_unlock();
662 *size = surf->info.planes[plane_idx].size;
663 *offset = surf->info.planes[plane_idx].offset;
664 *pitch = surf->info.planes[plane_idx].stride;
666 _tbm_surface_mutex_unlock();
672 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
674 struct _tbm_surface *surf;
675 tbm_bo_handle bo_handles[4];
678 _tbm_surface_mutex_lock();
680 memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
682 surf = (struct _tbm_surface *)surface;
684 info->width = surf->info.width;
685 info->height = surf->info.height;
686 info->format = surf->info.format;
687 info->bpp = surf->info.bpp;
688 info->size = surf->info.size;
689 info->num_planes = surf->info.num_planes;
693 for (i = 0; i < surf->num_bos; i++)
695 bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
696 if (bo_handles[i].ptr == NULL)
698 for (j = 0; j < i; j++)
699 tbm_bo_unmap (surf->bos[j]);
701 _tbm_surface_mutex_unlock();
708 for (i = 0; i < surf->num_bos; i++)
710 bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
711 if (bo_handles[i].ptr == NULL)
713 _tbm_surface_mutex_unlock();
719 for (i = 0; i < surf->info.num_planes; i++)
721 info->planes[i].size = surf->info.planes[i].size;
722 info->planes[i].offset = surf->info.planes[i].offset;
723 info->planes[i].stride = surf->info.planes[i].stride;
724 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
727 _tbm_surface_mutex_unlock();
733 tbm_surface_internal_unmap (tbm_surface_h surface)
735 struct _tbm_surface *surf;
738 _tbm_surface_mutex_lock();
740 surf = (struct _tbm_surface *)surface;
742 for (i = 0; i < surf->num_bos; i++)
743 tbm_bo_unmap (surf->bos[i]);
745 _tbm_surface_mutex_unlock();
749 tbm_surface_internal_get_width (tbm_surface_h surface)
751 struct _tbm_surface *surf;
754 _tbm_surface_mutex_lock();
756 surf = (struct _tbm_surface *)surface;
757 width = surf->info.width;
759 _tbm_surface_mutex_unlock();
765 tbm_surface_internal_get_height (tbm_surface_h surface)
767 struct _tbm_surface *surf;
770 _tbm_surface_mutex_lock();
772 surf = (struct _tbm_surface *)surface;
773 height = surf->info.height;
775 _tbm_surface_mutex_unlock();
782 tbm_surface_internal_get_format (tbm_surface_h surface)
784 struct _tbm_surface *surf;
787 _tbm_surface_mutex_lock();
789 surf = (struct _tbm_surface *)surface;
790 format = surf->info.format;
792 _tbm_surface_mutex_unlock();
798 tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
800 TBM_RETURN_VAL_IF_FAIL (surface, 0);
801 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
802 struct _tbm_surface *surf;
805 _tbm_surface_mutex_lock();
807 surf = (struct _tbm_surface *)surface;
808 bo_idx = surf->planes_bo_idx[plane_idx];
810 _tbm_surface_mutex_unlock();