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)
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);
141 tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
143 struct _tbm_bufmgr *mgr;
146 _tbm_surface_mutex_lock();
148 if (!g_surface_bufmgr)
150 _init_surface_bufmgr();
151 LIST_INITHEAD (&g_surface_list);
154 mgr = g_surface_bufmgr;
156 if (!mgr->backend->surface_supported_format)
158 _tbm_surface_mutex_unlock();
162 ret = mgr->backend->surface_supported_format (formats, num);
164 _tbm_surface_mutex_unlock();
169 int tbm_surface_internal_get_num_planes (tbm_format format)
176 case TBM_FORMAT_RGB332:
177 case TBM_FORMAT_BGR233:
178 case TBM_FORMAT_XRGB4444:
179 case TBM_FORMAT_XBGR4444:
180 case TBM_FORMAT_RGBX4444:
181 case TBM_FORMAT_BGRX4444:
182 case TBM_FORMAT_ARGB4444:
183 case TBM_FORMAT_ABGR4444:
184 case TBM_FORMAT_RGBA4444:
185 case TBM_FORMAT_BGRA4444:
186 case TBM_FORMAT_XRGB1555:
187 case TBM_FORMAT_XBGR1555:
188 case TBM_FORMAT_RGBX5551:
189 case TBM_FORMAT_BGRX5551:
190 case TBM_FORMAT_ARGB1555:
191 case TBM_FORMAT_ABGR1555:
192 case TBM_FORMAT_RGBA5551:
193 case TBM_FORMAT_BGRA5551:
194 case TBM_FORMAT_RGB565:
195 case TBM_FORMAT_BGR565:
196 case TBM_FORMAT_RGB888:
197 case TBM_FORMAT_BGR888:
198 case TBM_FORMAT_XRGB8888:
199 case TBM_FORMAT_XBGR8888:
200 case TBM_FORMAT_RGBX8888:
201 case TBM_FORMAT_BGRX8888:
202 case TBM_FORMAT_ARGB8888:
203 case TBM_FORMAT_ABGR8888:
204 case TBM_FORMAT_RGBA8888:
205 case TBM_FORMAT_BGRA8888:
206 case TBM_FORMAT_XRGB2101010:
207 case TBM_FORMAT_XBGR2101010:
208 case TBM_FORMAT_RGBX1010102:
209 case TBM_FORMAT_BGRX1010102:
210 case TBM_FORMAT_ARGB2101010:
211 case TBM_FORMAT_ABGR2101010:
212 case TBM_FORMAT_RGBA1010102:
213 case TBM_FORMAT_BGRA1010102:
214 case TBM_FORMAT_YUYV:
215 case TBM_FORMAT_YVYU:
216 case TBM_FORMAT_UYVY:
217 case TBM_FORMAT_VYUY:
218 case TBM_FORMAT_AYUV:
221 case TBM_FORMAT_NV12:
222 case TBM_FORMAT_NV21:
223 case TBM_FORMAT_NV16:
224 case TBM_FORMAT_NV61:
227 case TBM_FORMAT_YUV410:
228 case TBM_FORMAT_YVU410:
229 case TBM_FORMAT_YUV411:
230 case TBM_FORMAT_YVU411:
231 case TBM_FORMAT_YUV420:
232 case TBM_FORMAT_YVU420:
233 case TBM_FORMAT_YUV422:
234 case TBM_FORMAT_YVU422:
235 case TBM_FORMAT_YUV444:
236 case TBM_FORMAT_YVU444:
247 int tbm_surface_internal_get_bpp (tbm_format format)
254 case TBM_FORMAT_RGB332:
255 case TBM_FORMAT_BGR233:
258 case TBM_FORMAT_XRGB4444:
259 case TBM_FORMAT_XBGR4444:
260 case TBM_FORMAT_RGBX4444:
261 case TBM_FORMAT_BGRX4444:
262 case TBM_FORMAT_ARGB4444:
263 case TBM_FORMAT_ABGR4444:
264 case TBM_FORMAT_RGBA4444:
265 case TBM_FORMAT_BGRA4444:
266 case TBM_FORMAT_XRGB1555:
267 case TBM_FORMAT_XBGR1555:
268 case TBM_FORMAT_RGBX5551:
269 case TBM_FORMAT_BGRX5551:
270 case TBM_FORMAT_ARGB1555:
271 case TBM_FORMAT_ABGR1555:
272 case TBM_FORMAT_RGBA5551:
273 case TBM_FORMAT_BGRA5551:
274 case TBM_FORMAT_RGB565:
275 case TBM_FORMAT_BGR565:
278 case TBM_FORMAT_RGB888:
279 case TBM_FORMAT_BGR888:
282 case TBM_FORMAT_XRGB8888:
283 case TBM_FORMAT_XBGR8888:
284 case TBM_FORMAT_RGBX8888:
285 case TBM_FORMAT_BGRX8888:
286 case TBM_FORMAT_ARGB8888:
287 case TBM_FORMAT_ABGR8888:
288 case TBM_FORMAT_RGBA8888:
289 case TBM_FORMAT_BGRA8888:
290 case TBM_FORMAT_XRGB2101010:
291 case TBM_FORMAT_XBGR2101010:
292 case TBM_FORMAT_RGBX1010102:
293 case TBM_FORMAT_BGRX1010102:
294 case TBM_FORMAT_ARGB2101010:
295 case TBM_FORMAT_ABGR2101010:
296 case TBM_FORMAT_RGBA1010102:
297 case TBM_FORMAT_BGRA1010102:
298 case TBM_FORMAT_YUYV:
299 case TBM_FORMAT_YVYU:
300 case TBM_FORMAT_UYVY:
301 case TBM_FORMAT_VYUY:
302 case TBM_FORMAT_AYUV:
305 case TBM_FORMAT_NV12:
306 case TBM_FORMAT_NV21:
309 case TBM_FORMAT_NV16:
310 case TBM_FORMAT_NV61:
313 case TBM_FORMAT_YUV410:
314 case TBM_FORMAT_YVU410:
317 case TBM_FORMAT_YUV411:
318 case TBM_FORMAT_YVU411:
319 case TBM_FORMAT_YUV420:
320 case TBM_FORMAT_YVU420:
323 case TBM_FORMAT_YUV422:
324 case TBM_FORMAT_YVU422:
327 case TBM_FORMAT_YUV444:
328 case TBM_FORMAT_YVU444:
340 tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
342 TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
343 TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
345 struct _tbm_bufmgr *mgr;
346 struct _tbm_surface *surf = NULL;
352 _tbm_surface_mutex_lock();
354 if (!g_surface_bufmgr)
356 _init_surface_bufmgr();
357 LIST_INITHEAD (&g_surface_list);
360 mgr = g_surface_bufmgr;
361 if (!TBM_BUFMGR_IS_VALID(mgr))
363 _tbm_surface_mutex_unlock();
366 surf = calloc (1, sizeof(struct _tbm_surface));
369 _tbm_surface_mutex_unlock();
374 surf->info.width = width;
375 surf->info.height = height;
376 surf->info.format = format;
377 surf->info.bpp = tbm_surface_internal_get_bpp (format);
378 surf->info.size = _tbm_surface_internal_query_size (surf);
379 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
381 /* get size, stride and offset */
382 for (i = 0; i < surf->info.num_planes; i++)
384 _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride);
385 surf->info.planes[i].size = size;
386 surf->info.planes[i].offset = offset;
387 surf->info.planes[i].stride = stride;
392 /* create only one bo */
394 surf->bos[0] = tbm_bo_alloc (mgr, surf->info.size, flags);
400 if(LIST_IS_EMPTY (&g_surface_list))
402 _deinit_surface_bufmgr ();
403 LIST_DELINIT (&g_surface_list);
404 _tbm_surface_mutex_unlock();
409 LIST_ADD (&surf->item_link, &g_surface_list);
411 _tbm_surface_mutex_unlock();
417 tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
419 TBM_RETURN_VAL_IF_FAIL (bos, NULL);
420 TBM_RETURN_VAL_IF_FAIL (info, NULL);
422 struct _tbm_bufmgr *mgr;
423 struct _tbm_surface *surf = NULL;
426 _tbm_surface_mutex_lock();
428 if (!g_surface_bufmgr)
430 _init_surface_bufmgr();
431 LIST_INITHEAD (&g_surface_list);
434 mgr = g_surface_bufmgr;
435 if (!TBM_BUFMGR_IS_VALID(mgr))
437 _tbm_surface_mutex_unlock();
440 surf = calloc (1, sizeof(struct _tbm_surface));
443 _tbm_surface_mutex_unlock();
448 surf->info.width = info->width;
449 surf->info.height = info->height;
450 surf->info.format = info->format;
451 surf->info.bpp = info->bpp;
452 surf->info.size = info->size;
453 surf->info.num_planes = info->num_planes;
455 /* get size, stride and offset */
456 for (i = 0; i < info->num_planes; i++)
458 surf->info.planes[i].size = info->planes[i].size;
459 surf->info.planes[i].offset = info->planes[i].offset;
460 surf->info.planes[i].stride = info->planes[i].stride;
463 surf->flags = TBM_BO_DEFAULT;
465 /* create only one bo */
467 for (i = 0; i < num; i++)
472 surf->bos[i] = tbm_bo_ref(bos[i]);
475 LIST_ADD (&surf->item_link, &g_surface_list);
477 _tbm_surface_mutex_unlock();
481 for (i = 0; i < num; i++)
485 tbm_bo_unref (surf->bos[i]);
493 if(LIST_IS_EMPTY (&g_surface_list))
495 _deinit_surface_bufmgr ();
496 LIST_DELINIT (&g_surface_list);
499 _tbm_surface_mutex_unlock();
506 tbm_surface_internal_destroy (tbm_surface_h surface)
513 _tbm_surface_mutex_lock();
515 surface = (struct _tbm_surface *)surface;
517 for (i = 0; i < surface->num_bos; i++)
519 tbm_bo_unref (surface->bos[i]);
520 surface->bos[i] = NULL;
523 LIST_DEL (&surface->item_link);
528 if(LIST_IS_EMPTY (&g_surface_list))
530 _deinit_surface_bufmgr ();
531 LIST_DELINIT (&g_surface_list);
534 _tbm_surface_mutex_unlock();
539 tbm_surface_internal_get_num_bos (tbm_surface_h surface)
541 TBM_RETURN_VAL_IF_FAIL (surface, 0);
543 struct _tbm_surface *surf;
546 _tbm_surface_mutex_lock();
548 surf = (struct _tbm_surface *) surface;
551 _tbm_surface_mutex_unlock();
557 tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
559 TBM_RETURN_VAL_IF_FAIL (surface, NULL);
560 TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
562 struct _tbm_surface *surf;
565 _tbm_surface_mutex_lock();
567 surf = (struct _tbm_surface *) surface;
568 bo = surf->bos[bo_idx];
570 _tbm_surface_mutex_unlock();
576 tbm_surface_internal_get_size (tbm_surface_h surface)
578 TBM_RETURN_VAL_IF_FAIL (surface, 0);
580 struct _tbm_surface *surf;
583 _tbm_surface_mutex_lock();
585 surf = (struct _tbm_surface *) surface;
586 size = surf->info.size;
588 _tbm_surface_mutex_unlock();
594 tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
596 TBM_RETURN_VAL_IF_FAIL (surface, 0);
597 TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
599 struct _tbm_surface *surf;
601 _tbm_surface_mutex_lock();
603 surf = (struct _tbm_surface *) surface;
605 if (plane_idx >= surf->info.num_planes)
607 _tbm_surface_mutex_unlock();
611 *size = surf->info.planes[plane_idx].size;
612 *offset = surf->info.planes[plane_idx].offset;
613 *pitch = surf->info.planes[plane_idx].stride;
615 _tbm_surface_mutex_unlock();
621 tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
623 struct _tbm_surface *surf;
624 tbm_bo_handle bo_handles[4];
627 _tbm_surface_mutex_lock();
629 surf = (struct _tbm_surface *)surface;
631 info->width = surf->info.width;
632 info->height = surf->info.height;
633 info->format = surf->info.format;
634 info->bpp = surf->info.bpp;
635 info->size = surf->info.size;
636 info->num_planes = surf->info.num_planes;
638 if (surf->num_bos == 1)
642 bo_handles[0] = tbm_bo_map (surf->bos[0], TBM_DEVICE_CPU, opt);
643 if (bo_handles[0].ptr == NULL)
645 _tbm_surface_mutex_unlock();
651 bo_handles[0] = tbm_bo_get_handle (surf->bos[0], TBM_DEVICE_CPU);
652 if (bo_handles[0].ptr == NULL)
654 _tbm_surface_mutex_unlock();
659 for (i = 0; i < surf->info.num_planes; i++)
661 info->planes[i].size = surf->info.planes[i].size;
662 info->planes[i].offset = surf->info.planes[i].offset;
663 info->planes[i].stride = surf->info.planes[i].stride;
664 info->planes[i].ptr = bo_handles[0].ptr + surf->info.planes[i].offset;
669 /* TODO: calculate the virtaul address when num_bos is over 1 */
672 _tbm_surface_mutex_unlock();
678 tbm_surface_internal_unmap (tbm_surface_h surface)
680 struct _tbm_surface *surf;
683 _tbm_surface_mutex_lock();
685 surf = (struct _tbm_surface *)surface;
687 for (i = 0; i < surf->num_bos; i++)
688 tbm_bo_unmap (surf->bos[i]);
690 _tbm_surface_mutex_unlock();
694 tbm_surface_internal_get_width (tbm_surface_h surface)
696 struct _tbm_surface *surf;
699 _tbm_surface_mutex_lock();
701 surf = (struct _tbm_surface *)surface;
702 width = surf->info.width;
704 _tbm_surface_mutex_unlock();
710 tbm_surface_internal_get_height (tbm_surface_h surface)
712 struct _tbm_surface *surf;
715 _tbm_surface_mutex_lock();
717 surf = (struct _tbm_surface *)surface;
718 height = surf->info.height;
720 _tbm_surface_mutex_unlock();
727 tbm_surface_internal_get_format (tbm_surface_h surface)
729 struct _tbm_surface *surf;
732 _tbm_surface_mutex_lock();
734 surf = (struct _tbm_surface *)surface;
735 format = surf->info.format;
737 _tbm_surface_mutex_unlock();