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 size = mgr->backend->surface_get_size (surf, surf->info.width, surf->info.height, surf->info.format);
113 _tbm_surface_internal_query_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
115 TBM_RETURN_VAL_IF_FAIL (surface, 0);
116 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
118 struct _tbm_surface *surf = (struct _tbm_surface *) surface;
119 struct _tbm_bufmgr *mgr = surf->bufmgr;
122 TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
123 TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
124 TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
125 TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
127 ret = mgr->backend->surface_get_plane_data (surf, surf->info.width, surf->info.height, surf->info.format, plane_idx, size, offset, pitch);
135 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
137 struct _tbm_bufmgr *mgr;
140 _tbm_surface_mutex_lock();
142 if (!g_surface_bufmgr)
144 _init_surface_bufmgr();
145 LIST_INITHEAD (&g_surface_list);
148 mgr = g_surface_bufmgr;
149 ret = mgr->backend->surface_supported_format (formats, num);
151 _tbm_surface_mutex_unlock();
156 int tbm_surface_internal_get_num_planes (tbm_format format)
163 case TBM_FORMAT_RGB332:
164 case TBM_FORMAT_BGR233:
165 case TBM_FORMAT_XRGB4444:
166 case TBM_FORMAT_XBGR4444:
167 case TBM_FORMAT_RGBX4444:
168 case TBM_FORMAT_BGRX4444:
169 case TBM_FORMAT_ARGB4444:
170 case TBM_FORMAT_ABGR4444:
171 case TBM_FORMAT_RGBA4444:
172 case TBM_FORMAT_BGRA4444:
173 case TBM_FORMAT_XRGB1555:
174 case TBM_FORMAT_XBGR1555:
175 case TBM_FORMAT_RGBX5551:
176 case TBM_FORMAT_BGRX5551:
177 case TBM_FORMAT_ARGB1555:
178 case TBM_FORMAT_ABGR1555:
179 case TBM_FORMAT_RGBA5551:
180 case TBM_FORMAT_BGRA5551:
181 case TBM_FORMAT_RGB565:
182 case TBM_FORMAT_BGR565:
183 case TBM_FORMAT_RGB888:
184 case TBM_FORMAT_BGR888:
185 case TBM_FORMAT_XRGB8888:
186 case TBM_FORMAT_XBGR8888:
187 case TBM_FORMAT_RGBX8888:
188 case TBM_FORMAT_BGRX8888:
189 case TBM_FORMAT_ARGB8888:
190 case TBM_FORMAT_ABGR8888:
191 case TBM_FORMAT_RGBA8888:
192 case TBM_FORMAT_BGRA8888:
193 case TBM_FORMAT_XRGB2101010:
194 case TBM_FORMAT_XBGR2101010:
195 case TBM_FORMAT_RGBX1010102:
196 case TBM_FORMAT_BGRX1010102:
197 case TBM_FORMAT_ARGB2101010:
198 case TBM_FORMAT_ABGR2101010:
199 case TBM_FORMAT_RGBA1010102:
200 case TBM_FORMAT_BGRA1010102:
201 case TBM_FORMAT_YUYV:
202 case TBM_FORMAT_YVYU:
203 case TBM_FORMAT_UYVY:
204 case TBM_FORMAT_VYUY:
205 case TBM_FORMAT_AYUV:
208 case TBM_FORMAT_NV12:
209 case TBM_FORMAT_NV21:
210 case TBM_FORMAT_NV16:
211 case TBM_FORMAT_NV61:
214 case TBM_FORMAT_YUV410:
215 case TBM_FORMAT_YVU410:
216 case TBM_FORMAT_YUV411:
217 case TBM_FORMAT_YVU411:
218 case TBM_FORMAT_YUV420:
219 case TBM_FORMAT_YVU420:
220 case TBM_FORMAT_YUV422:
221 case TBM_FORMAT_YVU422:
222 case TBM_FORMAT_YUV444:
223 case TBM_FORMAT_YVU444:
234 int tbm_surface_internal_get_bpp (tbm_format format)
241 case TBM_FORMAT_RGB332:
242 case TBM_FORMAT_BGR233:
245 case TBM_FORMAT_XRGB4444:
246 case TBM_FORMAT_XBGR4444:
247 case TBM_FORMAT_RGBX4444:
248 case TBM_FORMAT_BGRX4444:
249 case TBM_FORMAT_ARGB4444:
250 case TBM_FORMAT_ABGR4444:
251 case TBM_FORMAT_RGBA4444:
252 case TBM_FORMAT_BGRA4444:
253 case TBM_FORMAT_XRGB1555:
254 case TBM_FORMAT_XBGR1555:
255 case TBM_FORMAT_RGBX5551:
256 case TBM_FORMAT_BGRX5551:
257 case TBM_FORMAT_ARGB1555:
258 case TBM_FORMAT_ABGR1555:
259 case TBM_FORMAT_RGBA5551:
260 case TBM_FORMAT_BGRA5551:
261 case TBM_FORMAT_RGB565:
262 case TBM_FORMAT_BGR565:
265 case TBM_FORMAT_RGB888:
266 case TBM_FORMAT_BGR888:
269 case TBM_FORMAT_XRGB8888:
270 case TBM_FORMAT_XBGR8888:
271 case TBM_FORMAT_RGBX8888:
272 case TBM_FORMAT_BGRX8888:
273 case TBM_FORMAT_ARGB8888:
274 case TBM_FORMAT_ABGR8888:
275 case TBM_FORMAT_RGBA8888:
276 case TBM_FORMAT_BGRA8888:
277 case TBM_FORMAT_XRGB2101010:
278 case TBM_FORMAT_XBGR2101010:
279 case TBM_FORMAT_RGBX1010102:
280 case TBM_FORMAT_BGRX1010102:
281 case TBM_FORMAT_ARGB2101010:
282 case TBM_FORMAT_ABGR2101010:
283 case TBM_FORMAT_RGBA1010102:
284 case TBM_FORMAT_BGRA1010102:
285 case TBM_FORMAT_YUYV:
286 case TBM_FORMAT_YVYU:
287 case TBM_FORMAT_UYVY:
288 case TBM_FORMAT_VYUY:
289 case TBM_FORMAT_AYUV:
292 case TBM_FORMAT_NV12:
293 case TBM_FORMAT_NV21:
296 case TBM_FORMAT_NV16:
297 case TBM_FORMAT_NV61:
300 case TBM_FORMAT_YUV410:
301 case TBM_FORMAT_YVU410:
304 case TBM_FORMAT_YUV411:
305 case TBM_FORMAT_YVU411:
306 case TBM_FORMAT_YUV420:
307 case TBM_FORMAT_YVU420:
310 case TBM_FORMAT_YUV422:
311 case TBM_FORMAT_YVU422:
314 case TBM_FORMAT_YUV444:
315 case TBM_FORMAT_YVU444:
327 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
329 TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
330 TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
332 struct _tbm_bufmgr *mgr;
333 struct _tbm_surface *surf = NULL;
339 _tbm_surface_mutex_lock();
341 if (!g_surface_bufmgr)
343 _init_surface_bufmgr();
344 LIST_INITHEAD (&g_surface_list);
347 mgr = g_surface_bufmgr;
348 if (!TBM_BUFMGR_IS_VALID(mgr))
350 _tbm_surface_mutex_unlock();
353 surf = calloc (1, sizeof(struct _tbm_surface));
356 _tbm_surface_mutex_unlock();
361 surf->info.width = width;
362 surf->info.height = height;
363 surf->info.format = format;
364 surf->info.bpp = tbm_surface_internal_get_bpp (format);
365 surf->info.size = _tbm_surface_internal_query_size (surf);
366 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
368 /* get size, stride and offset */
369 for (i = 0; i < surf->info.num_planes; i++)
371 _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride);
372 surf->info.planes[i].size = size;
373 surf->info.planes[i].offset = offset;
374 surf->info.planes[i].stride = stride;
379 /* create only one bo */
381 surf->bos[0] = tbm_bo_alloc (mgr, surf->info.size, flags);
387 if(LIST_IS_EMPTY (&g_surface_list))
389 _deinit_surface_bufmgr ();
390 LIST_DELINIT (&g_surface_list);
391 _tbm_surface_mutex_unlock();
396 LIST_ADD (&surf->item_link, &g_surface_list);
398 _tbm_surface_mutex_unlock();
404 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
406 TBM_RETURN_VAL_IF_FAIL (bos, NULL);
407 TBM_RETURN_VAL_IF_FAIL (info, NULL);
409 struct _tbm_bufmgr *mgr;
410 struct _tbm_surface *surf = NULL;
413 _tbm_surface_mutex_lock();
415 if (!g_surface_bufmgr)
417 _init_surface_bufmgr();
418 LIST_INITHEAD (&g_surface_list);
421 mgr = g_surface_bufmgr;
422 if (!TBM_BUFMGR_IS_VALID(mgr))
424 _tbm_surface_mutex_unlock();
427 surf = calloc (1, sizeof(struct _tbm_surface));
430 _tbm_surface_mutex_unlock();
435 surf->info.width = info->width;
436 surf->info.height = info->height;
437 surf->info.format = info->format;
438 surf->info.bpp = info->bpp;
439 surf->info.size = info->size;
440 surf->info.num_planes = info->num_planes;
442 /* get size, stride and offset */
443 for (i = 0; i < info->num_planes; i++)
445 surf->info.planes[i].size = info->planes[i].size;
446 surf->info.planes[i].offset = info->planes[i].offset;
447 surf->info.planes[i].stride = info->planes[i].stride;
450 surf->flags = TBM_BO_DEFAULT;
452 /* create only one bo */
454 for (i = 0; i < num; i++)
459 surf->bos[i] = tbm_bo_ref(bos[i]);
462 LIST_ADD (&surf->item_link, &g_surface_list);
464 _tbm_surface_mutex_unlock();
468 for (i = 0; i < num; i++)
472 tbm_bo_unref (surf->bos[i]);
480 if(LIST_IS_EMPTY (&g_surface_list))
482 _deinit_surface_bufmgr ();
483 LIST_DELINIT (&g_surface_list);
486 _tbm_surface_mutex_unlock();
493 tbm_surface_internal_destroy (tbm_surface_h surface)
500 _tbm_surface_mutex_lock();
502 surface = (struct _tbm_surface *)surface;
504 for (i = 0; i < surface->num_bos; i++)
506 tbm_bo_unref (surface->bos[i]);
507 surface->bos[i] = NULL;
510 LIST_DEL (&surface->item_link);
515 if(LIST_IS_EMPTY (&g_surface_list))
517 _deinit_surface_bufmgr ();
518 LIST_DELINIT (&g_surface_list);
521 _tbm_surface_mutex_unlock();
526 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
528 TBM_RETURN_VAL_IF_FAIL (surface, 0);
530 struct _tbm_surface *surf;
533 _tbm_surface_mutex_lock();
535 surf = (struct _tbm_surface *) surface;
538 _tbm_surface_mutex_unlock();
544 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
546 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
547 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
549 struct _tbm_surface *surf;
552 _tbm_surface_mutex_lock();
554 surf = (struct _tbm_surface *) surface;
555 bo = surf->bos[bo_idx];
557 _tbm_surface_mutex_unlock();
563 tbm_surface_internal_get_size (tbm_surface_h surface)
565 TBM_RETURN_VAL_IF_FAIL (surface, 0);
567 struct _tbm_surface *surf;
570 _tbm_surface_mutex_lock();
572 surf = (struct _tbm_surface *) surface;
573 size = surf->info.size;
575 _tbm_surface_mutex_unlock();
581 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
583 TBM_RETURN_VAL_IF_FAIL (surface, 0);
584 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
586 struct _tbm_surface *surf;
588 _tbm_surface_mutex_lock();
590 surf = (struct _tbm_surface *) surface;
592 if (plane_idx >= surf->info.num_planes)
594 _tbm_surface_mutex_unlock();
598 *size = surf->info.planes[plane_idx].size;
599 *offset = surf->info.planes[plane_idx].offset;
600 *pitch = surf->info.planes[plane_idx].stride;
602 _tbm_surface_mutex_unlock();
608 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
610 struct _tbm_surface *surf;
611 tbm_bo_handle bo_handles[4];
614 _tbm_surface_mutex_lock();
616 surf = (struct _tbm_surface *)surface;
618 info->width = surf->info.width;
619 info->height = surf->info.height;
620 info->format = surf->info.format;
621 info->bpp = surf->info.bpp;
622 info->size = surf->info.size;
623 info->num_planes = surf->info.num_planes;
625 if (surf->num_bos == 1)
629 bo_handles[0] = tbm_bo_map (surf->bos[0], TBM_DEVICE_CPU, opt);
630 if (bo_handles[0].ptr == NULL)
632 _tbm_surface_mutex_unlock();
638 bo_handles[0] = tbm_bo_get_handle (surf->bos[0], TBM_DEVICE_CPU);
639 if (bo_handles[0].ptr == NULL)
641 _tbm_surface_mutex_unlock();
646 for (i = 0; i < surf->info.num_planes; i++)
648 info->planes[i].size = surf->info.planes[i].size;
649 info->planes[i].offset = surf->info.planes[i].offset;
650 info->planes[i].stride = surf->info.planes[i].stride;
651 info->planes[i].ptr = bo_handles[0].ptr + surf->info.planes[i].offset;
656 /* TODO: calculate the virtaul address when num_bos is over 1 */
659 _tbm_surface_mutex_unlock();
665 tbm_surface_internal_unmap (tbm_surface_h surface)
667 struct _tbm_surface *surf;
670 _tbm_surface_mutex_lock();
672 surf = (struct _tbm_surface *)surface;
674 for (i = 0; i < surf->num_bos; i++)
675 tbm_bo_unmap (surf->bos[i]);
677 _tbm_surface_mutex_unlock();
681 tbm_surface_internal_get_width (tbm_surface_h surface)
683 struct _tbm_surface *surf;
686 _tbm_surface_mutex_lock();
688 surf = (struct _tbm_surface *)surface;
689 width = surf->info.width;
691 _tbm_surface_mutex_unlock();
697 tbm_surface_internal_get_height (tbm_surface_h surface)
699 struct _tbm_surface *surf;
702 _tbm_surface_mutex_lock();
704 surf = (struct _tbm_surface *)surface;
705 height = surf->info.height;
707 _tbm_surface_mutex_unlock();
714 tbm_surface_internal_get_format (tbm_surface_h surface)
716 struct _tbm_surface *surf;
719 _tbm_surface_mutex_lock();
721 surf = (struct _tbm_surface *)surface;
722 format = surf->info.format;
724 _tbm_surface_mutex_unlock();