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"
39 static tbm_bufmgr g_surface_bufmgr;
40 static pthread_mutex_t tbm_surface_lock;
43 _tbm_surface_internal_format_to_str(tbm_format format)
47 return "TBM_FORMAT_C8";
48 case TBM_FORMAT_RGB332:
49 return "TBM_FORMAT_RGB332";
50 case TBM_FORMAT_BGR233:
51 return "TBM_FORMAT_BGR233";
52 case TBM_FORMAT_XRGB4444:
53 return "TBM_FORMAT_XRGB4444";
54 case TBM_FORMAT_XBGR4444:
55 return "TBM_FORMAT_XBGR4444";
56 case TBM_FORMAT_RGBX4444:
57 return "TBM_FORMAT_RGBX4444";
58 case TBM_FORMAT_BGRX4444:
59 return "TBM_FORMAT_BGRX4444";
60 case TBM_FORMAT_ARGB4444:
61 return "TBM_FORMAT_ARGB4444";
62 case TBM_FORMAT_ABGR4444:
63 return "TBM_FORMAT_ABGR4444";
64 case TBM_FORMAT_RGBA4444:
65 return "TBM_FORMAT_RGBA4444";
66 case TBM_FORMAT_BGRA4444:
67 return "TBM_FORMAT_BGRA4444";
68 case TBM_FORMAT_XRGB1555:
69 return "TBM_FORMAT_XRGB1555";
70 case TBM_FORMAT_XBGR1555:
71 return "TBM_FORMAT_XBGR1555";
72 case TBM_FORMAT_RGBX5551:
73 return "TBM_FORMAT_RGBX5551";
74 case TBM_FORMAT_BGRX5551:
75 return "TBM_FORMAT_BGRX5551";
76 case TBM_FORMAT_ARGB1555:
77 return "TBM_FORMAT_ARGB1555";
78 case TBM_FORMAT_ABGR1555:
79 return "TBM_FORMAT_ABGR1555";
80 case TBM_FORMAT_RGBA5551:
81 return "TBM_FORMAT_RGBA5551";
82 case TBM_FORMAT_BGRA5551:
83 return "TBM_FORMAT_BGRA5551";
84 case TBM_FORMAT_RGB565:
85 return "TBM_FORMAT_RGB565";
86 case TBM_FORMAT_BGR565:
87 return "TBM_FORMAT_BGR565";
88 case TBM_FORMAT_RGB888:
89 return "TBM_FORMAT_RGB888";
90 case TBM_FORMAT_BGR888:
91 return "TBM_FORMAT_BGR888";
92 case TBM_FORMAT_XRGB8888:
93 return "TBM_FORMAT_XRGB8888";
94 case TBM_FORMAT_XBGR8888:
95 return "TBM_FORMAT_XBGR8888";
96 case TBM_FORMAT_RGBX8888:
97 return "TBM_FORMAT_RGBX8888";
98 case TBM_FORMAT_BGRX8888:
99 return "TBM_FORMAT_BGRX8888";
100 case TBM_FORMAT_ARGB8888:
101 return "TBM_FORMAT_ARGB8888";
102 case TBM_FORMAT_ABGR8888:
103 return "TBM_FORMAT_ABGR8888";
104 case TBM_FORMAT_RGBA8888:
105 return "TBM_FORMAT_RGBA8888";
106 case TBM_FORMAT_BGRA8888:
107 return "TBM_FORMAT_BGRA8888";
108 case TBM_FORMAT_XRGB2101010:
109 return "TBM_FORMAT_XRGB2101010";
110 case TBM_FORMAT_XBGR2101010:
111 return "TBM_FORMAT_XBGR2101010";
112 case TBM_FORMAT_RGBX1010102:
113 return "TBM_FORMAT_RGBX1010102";
114 case TBM_FORMAT_BGRX1010102:
115 return "TBM_FORMAT_BGRX1010102";
116 case TBM_FORMAT_ARGB2101010:
117 return "TBM_FORMAT_ARGB2101010";
118 case TBM_FORMAT_ABGR2101010:
119 return "TBM_FORMAT_ABGR2101010";
120 case TBM_FORMAT_RGBA1010102:
121 return "TBM_FORMAT_RGBA1010102";
122 case TBM_FORMAT_BGRA1010102:
123 return "TBM_FORMAT_BGRA1010102";
124 case TBM_FORMAT_YUYV:
125 return "TBM_FORMAT_YUYV";
126 case TBM_FORMAT_YVYU:
127 return "TBM_FORMAT_YVYU";
128 case TBM_FORMAT_UYVY:
129 return "TBM_FORMAT_UYVY";
130 case TBM_FORMAT_VYUY:
131 return "TBM_FORMAT_VYUY";
132 case TBM_FORMAT_AYUV:
133 return "TBM_FORMAT_AYUV";
134 case TBM_FORMAT_NV12:
135 return "TBM_FORMAT_NV12";
136 case TBM_FORMAT_NV21:
137 return "TBM_FORMAT_NV21";
138 case TBM_FORMAT_NV16:
139 return "TBM_FORMAT_NV16";
140 case TBM_FORMAT_NV61:
141 return "TBM_FORMAT_NV61";
142 case TBM_FORMAT_YUV410:
143 return "TBM_FORMAT_YUV410";
144 case TBM_FORMAT_YVU410:
145 return "TBM_FORMAT_YVU410";
146 case TBM_FORMAT_YUV411:
147 return "TBM_FORMAT_YUV411";
148 case TBM_FORMAT_YVU411:
149 return "TBM_FORMAT_YVU411";
150 case TBM_FORMAT_YUV420:
151 return "TBM_FORMAT_YUV420";
152 case TBM_FORMAT_YVU420:
153 return "TBM_FORMAT_YVU420";
154 case TBM_FORMAT_YUV422:
155 return "TBM_FORMAT_YUV422";
156 case TBM_FORMAT_YVU422:
157 return "TBM_FORMAT_YVU422";
158 case TBM_FORMAT_YUV444:
159 return "TBM_FORMAT_YUV444";
160 case TBM_FORMAT_YVU444:
161 return "TBM_FORMAT_YVU444";
162 case TBM_FORMAT_NV12MT:
163 return "TBM_FORMAT_NV12MT";
170 _tbm_surface_mutex_init(void)
172 static bool tbm_surface_mutex_init = false;
174 if (tbm_surface_mutex_init)
177 if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
178 TBM_LOG("[libtbm] fail: tbm_surface mutex init\n");
182 tbm_surface_mutex_init = true;
188 _tbm_surface_mutex_lock(void)
190 if (!_tbm_surface_mutex_init())
193 pthread_mutex_lock(&tbm_surface_lock);
197 _tbm_surface_mutex_unlock(void)
199 pthread_mutex_unlock(&tbm_surface_lock);
203 _init_surface_bufmgr(void)
205 g_surface_bufmgr = tbm_bufmgr_init(-1);
209 _deinit_surface_bufmgr(void)
211 if (!g_surface_bufmgr)
214 tbm_bufmgr_deinit(g_surface_bufmgr);
215 g_surface_bufmgr = NULL;
219 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
220 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
222 TBM_RETURN_VAL_IF_FAIL(surface, 0);
223 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
225 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
226 struct _tbm_bufmgr *mgr = surf->bufmgr;
229 TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
230 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
231 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
232 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
234 if (!mgr->backend->surface_get_plane_data)
237 ret = mgr->backend->surface_get_plane_data(surf->info.width,
238 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
246 _tbm_surface_internal_destroy(tbm_surface_h surface)
249 tbm_bufmgr bufmgr = surface->bufmgr;
250 tbm_user_data *old_data = NULL, *tmp = NULL;
252 for (i = 0; i < surface->num_bos; i++) {
253 surface->bos[i]->surface = NULL;
255 tbm_bo_unref(surface->bos[i]);
256 surface->bos[i] = NULL;
259 /* destory the user_data_list */
260 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
261 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
262 TBM_LOG("[tbm_surface:%d] free user_data\n",
264 user_data_delete(old_data);
268 LIST_DEL(&surface->item_link);
273 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
274 LIST_DELINIT(&bufmgr->surf_list);
275 _deinit_surface_bufmgr();
280 tbm_surface_internal_is_valid(tbm_surface_h surface)
282 tbm_surface_h old_data = NULL, tmp = NULL;
284 if (surface == NULL || g_surface_bufmgr == NULL)
287 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
288 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &g_surface_bufmgr->surf_list, item_link) {
289 if (old_data == surface)
297 tbm_surface_internal_query_supported_formats(uint32_t **formats,
300 struct _tbm_bufmgr *mgr;
303 _tbm_surface_mutex_lock();
305 if (!g_surface_bufmgr) {
306 _init_surface_bufmgr();
307 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
310 mgr = g_surface_bufmgr;
312 if (!mgr->backend->surface_supported_format) {
313 _tbm_surface_mutex_unlock();
317 ret = mgr->backend->surface_supported_format(formats, num);
319 _tbm_surface_mutex_unlock();
325 tbm_surface_internal_get_num_planes(tbm_format format)
331 case TBM_FORMAT_RGB332:
332 case TBM_FORMAT_BGR233:
333 case TBM_FORMAT_XRGB4444:
334 case TBM_FORMAT_XBGR4444:
335 case TBM_FORMAT_RGBX4444:
336 case TBM_FORMAT_BGRX4444:
337 case TBM_FORMAT_ARGB4444:
338 case TBM_FORMAT_ABGR4444:
339 case TBM_FORMAT_RGBA4444:
340 case TBM_FORMAT_BGRA4444:
341 case TBM_FORMAT_XRGB1555:
342 case TBM_FORMAT_XBGR1555:
343 case TBM_FORMAT_RGBX5551:
344 case TBM_FORMAT_BGRX5551:
345 case TBM_FORMAT_ARGB1555:
346 case TBM_FORMAT_ABGR1555:
347 case TBM_FORMAT_RGBA5551:
348 case TBM_FORMAT_BGRA5551:
349 case TBM_FORMAT_RGB565:
350 case TBM_FORMAT_BGR565:
351 case TBM_FORMAT_RGB888:
352 case TBM_FORMAT_BGR888:
353 case TBM_FORMAT_XRGB8888:
354 case TBM_FORMAT_XBGR8888:
355 case TBM_FORMAT_RGBX8888:
356 case TBM_FORMAT_BGRX8888:
357 case TBM_FORMAT_ARGB8888:
358 case TBM_FORMAT_ABGR8888:
359 case TBM_FORMAT_RGBA8888:
360 case TBM_FORMAT_BGRA8888:
361 case TBM_FORMAT_XRGB2101010:
362 case TBM_FORMAT_XBGR2101010:
363 case TBM_FORMAT_RGBX1010102:
364 case TBM_FORMAT_BGRX1010102:
365 case TBM_FORMAT_ARGB2101010:
366 case TBM_FORMAT_ABGR2101010:
367 case TBM_FORMAT_RGBA1010102:
368 case TBM_FORMAT_BGRA1010102:
369 case TBM_FORMAT_YUYV:
370 case TBM_FORMAT_YVYU:
371 case TBM_FORMAT_UYVY:
372 case TBM_FORMAT_VYUY:
373 case TBM_FORMAT_AYUV:
376 case TBM_FORMAT_NV12:
377 case TBM_FORMAT_NV12MT:
378 case TBM_FORMAT_NV21:
379 case TBM_FORMAT_NV16:
380 case TBM_FORMAT_NV61:
383 case TBM_FORMAT_YUV410:
384 case TBM_FORMAT_YVU410:
385 case TBM_FORMAT_YUV411:
386 case TBM_FORMAT_YVU411:
387 case TBM_FORMAT_YUV420:
388 case TBM_FORMAT_YVU420:
389 case TBM_FORMAT_YUV422:
390 case TBM_FORMAT_YVU422:
391 case TBM_FORMAT_YUV444:
392 case TBM_FORMAT_YVU444:
404 tbm_surface_internal_get_bpp(tbm_format format)
410 case TBM_FORMAT_RGB332:
411 case TBM_FORMAT_BGR233:
414 case TBM_FORMAT_XRGB4444:
415 case TBM_FORMAT_XBGR4444:
416 case TBM_FORMAT_RGBX4444:
417 case TBM_FORMAT_BGRX4444:
418 case TBM_FORMAT_ARGB4444:
419 case TBM_FORMAT_ABGR4444:
420 case TBM_FORMAT_RGBA4444:
421 case TBM_FORMAT_BGRA4444:
422 case TBM_FORMAT_XRGB1555:
423 case TBM_FORMAT_XBGR1555:
424 case TBM_FORMAT_RGBX5551:
425 case TBM_FORMAT_BGRX5551:
426 case TBM_FORMAT_ARGB1555:
427 case TBM_FORMAT_ABGR1555:
428 case TBM_FORMAT_RGBA5551:
429 case TBM_FORMAT_BGRA5551:
430 case TBM_FORMAT_RGB565:
431 case TBM_FORMAT_BGR565:
434 case TBM_FORMAT_RGB888:
435 case TBM_FORMAT_BGR888:
438 case TBM_FORMAT_XRGB8888:
439 case TBM_FORMAT_XBGR8888:
440 case TBM_FORMAT_RGBX8888:
441 case TBM_FORMAT_BGRX8888:
442 case TBM_FORMAT_ARGB8888:
443 case TBM_FORMAT_ABGR8888:
444 case TBM_FORMAT_RGBA8888:
445 case TBM_FORMAT_BGRA8888:
446 case TBM_FORMAT_XRGB2101010:
447 case TBM_FORMAT_XBGR2101010:
448 case TBM_FORMAT_RGBX1010102:
449 case TBM_FORMAT_BGRX1010102:
450 case TBM_FORMAT_ARGB2101010:
451 case TBM_FORMAT_ABGR2101010:
452 case TBM_FORMAT_RGBA1010102:
453 case TBM_FORMAT_BGRA1010102:
454 case TBM_FORMAT_YUYV:
455 case TBM_FORMAT_YVYU:
456 case TBM_FORMAT_UYVY:
457 case TBM_FORMAT_VYUY:
458 case TBM_FORMAT_AYUV:
461 case TBM_FORMAT_NV12:
462 case TBM_FORMAT_NV12MT:
463 case TBM_FORMAT_NV21:
466 case TBM_FORMAT_NV16:
467 case TBM_FORMAT_NV61:
470 case TBM_FORMAT_YUV410:
471 case TBM_FORMAT_YVU410:
474 case TBM_FORMAT_YUV411:
475 case TBM_FORMAT_YVU411:
476 case TBM_FORMAT_YUV420:
477 case TBM_FORMAT_YVU420:
480 case TBM_FORMAT_YUV422:
481 case TBM_FORMAT_YVU422:
484 case TBM_FORMAT_YUV444:
485 case TBM_FORMAT_YVU444:
496 tbm_surface_internal_create_with_flags(int width, int height,
497 int format, int flags)
499 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
500 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
502 struct _tbm_bufmgr *mgr;
503 struct _tbm_surface *surf = NULL;
507 uint32_t bo_size = 0;
511 _tbm_surface_mutex_lock();
513 if (!g_surface_bufmgr) {
514 _init_surface_bufmgr();
515 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
518 mgr = g_surface_bufmgr;
519 if (!TBM_BUFMGR_IS_VALID(mgr)) {
520 _tbm_surface_mutex_unlock();
523 surf = calloc(1, sizeof(struct _tbm_surface));
525 _tbm_surface_mutex_unlock();
530 surf->info.width = width;
531 surf->info.height = height;
532 surf->info.format = format;
533 surf->info.bpp = tbm_surface_internal_get_bpp(format);
534 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
537 /* get size, stride and offset bo_idx */
538 for (i = 0; i < surf->info.num_planes; i++) {
539 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride,
541 surf->info.planes[i].size = size;
542 surf->info.planes[i].offset = offset;
543 surf->info.planes[i].stride = stride;
544 surf->planes_bo_idx[i] = bo_idx;
549 for (i = 0; i < surf->info.num_planes; i++) {
550 surf->info.size += surf->info.planes[i].size;
552 if (surf->num_bos -1 > surf->planes_bo_idx[i])
553 surf->num_bos = surf->planes_bo_idx[i]++;
558 for (i = 0; i < surf->num_bos; i++) {
560 for (j = 0; j < surf->info.num_planes; j++) {
561 if (surf->planes_bo_idx[j] == i)
562 bo_size += surf->info.planes[j].size;
565 if (mgr->backend->surface_bo_alloc) {
568 void *bo_priv = NULL;
570 bo = calloc(1, sizeof(struct _tbm_bo));
572 TBM_LOG("[libtbm:%d] "
573 "error %s:%d fail to alloc bo struct\n",
574 getpid(), __func__, __LINE__);
578 bo->bufmgr = surf->bufmgr;
580 pthread_mutex_lock(&surf->bufmgr->lock);
582 bo_priv = mgr->backend->surface_bo_alloc (bo, width, height, format, flags, i);
584 TBM_LOG("[libtbm:%d] "
585 "error %s:%d fail to alloc bo priv\n",
586 getpid(), __func__, __LINE__);
588 pthread_mutex_unlock(&surf->bufmgr->lock);
596 LIST_INITHEAD(&bo->user_data_list);
598 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
600 pthread_mutex_unlock(&surf->bufmgr->lock);
605 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
609 TBM_LOG("[libtbm:%d] "
610 "error %s:%d fail to alloc bo\n",
611 getpid(), __func__, __LINE__);
615 _tbm_bo_set_surface(surf->bos[i], surf);
619 LIST_INITHEAD(&surf->user_data_list);
621 LIST_ADD(&surf->item_link, &mgr->surf_list);
623 _tbm_surface_mutex_unlock();
628 for (j = 0; j < i; j++) {
630 tbm_bo_unref(surf->bos[j]);
636 if (LIST_IS_EMPTY(&mgr->surf_list)) {
637 LIST_DELINIT(&mgr->surf_list);
638 _deinit_surface_bufmgr();
641 _tbm_surface_mutex_unlock();
646 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
647 tbm_bo *bos, int num)
649 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
650 TBM_RETURN_VAL_IF_FAIL(info, NULL);
651 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
653 struct _tbm_bufmgr *mgr;
654 struct _tbm_surface *surf = NULL;
657 _tbm_surface_mutex_lock();
659 if (!g_surface_bufmgr) {
660 _init_surface_bufmgr();
661 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
664 mgr = g_surface_bufmgr;
665 if (!TBM_BUFMGR_IS_VALID(mgr)) {
666 _tbm_surface_mutex_unlock();
670 surf = calloc(1, sizeof(struct _tbm_surface));
672 _tbm_surface_mutex_unlock();
677 surf->info.width = info->width;
678 surf->info.height = info->height;
679 surf->info.format = info->format;
680 surf->info.bpp = info->bpp;
681 surf->info.num_planes = info->num_planes;
684 /* get size, stride and offset */
685 for (i = 0; i < info->num_planes; i++) {
686 surf->info.planes[i].offset = info->planes[i].offset;
687 surf->info.planes[i].stride = info->planes[i].stride;
689 if (info->planes[i].size > 0)
690 surf->info.planes[i].size = info->planes[i].size;
692 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
695 surf->planes_bo_idx[i] = 0;
697 surf->planes_bo_idx[i] = i;
700 if (info->size > 0) {
701 surf->info.size = info->size;
704 for (i = 0; i < info->num_planes; i++)
705 surf->info.size += surf->info.planes[i].size;
708 surf->flags = TBM_BO_DEFAULT;
710 /* create only one bo */
712 for (i = 0; i < num; i++) {
716 surf->bos[i] = tbm_bo_ref(bos[i]);
717 _tbm_bo_set_surface(bos[i], surf);
720 LIST_INITHEAD(&surf->user_data_list);
722 LIST_ADD(&surf->item_link, &mgr->surf_list);
724 _tbm_surface_mutex_unlock();
728 for (i = 0; i < num; i++) {
730 tbm_bo_unref(surf->bos[i]);
738 if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
739 LIST_DELINIT(&g_surface_bufmgr->surf_list);
740 _deinit_surface_bufmgr();
743 _tbm_surface_mutex_unlock();
749 tbm_surface_internal_destroy(tbm_surface_h surface)
751 if (!tbm_surface_internal_is_valid(surface))
754 _tbm_surface_mutex_lock();
758 if (surface->refcnt > 0) {
759 _tbm_surface_mutex_unlock();
763 if (surface->refcnt == 0)
764 _tbm_surface_internal_destroy(surface);
766 _tbm_surface_mutex_unlock();
770 tbm_surface_internal_ref(tbm_surface_h surface)
772 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
774 _tbm_surface_mutex_lock();
778 _tbm_surface_mutex_unlock();
782 tbm_surface_internal_unref(tbm_surface_h surface)
784 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
786 _tbm_surface_mutex_lock();
790 if (surface->refcnt > 0) {
791 _tbm_surface_mutex_unlock();
795 if (surface->refcnt == 0)
796 _tbm_surface_internal_destroy(surface);
798 _tbm_surface_mutex_unlock();
802 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
804 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
806 struct _tbm_surface *surf;
809 _tbm_surface_mutex_lock();
811 surf = (struct _tbm_surface *)surface;
814 _tbm_surface_mutex_unlock();
820 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
822 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
823 TBM_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
825 struct _tbm_surface *surf;
828 _tbm_surface_mutex_lock();
830 surf = (struct _tbm_surface *)surface;
831 bo = surf->bos[bo_idx];
833 _tbm_surface_mutex_unlock();
839 tbm_surface_internal_get_size(tbm_surface_h surface)
841 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
843 struct _tbm_surface *surf;
846 _tbm_surface_mutex_lock();
848 surf = (struct _tbm_surface *)surface;
849 size = surf->info.size;
851 _tbm_surface_mutex_unlock();
857 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
858 uint32_t *size, uint32_t *offset, uint32_t *pitch)
860 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
861 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
863 struct _tbm_surface *surf;
865 _tbm_surface_mutex_lock();
867 surf = (struct _tbm_surface *)surface;
869 if (plane_idx >= surf->info.num_planes) {
870 _tbm_surface_mutex_unlock();
875 *size = surf->info.planes[plane_idx].size;
878 *offset = surf->info.planes[plane_idx].offset;
881 *pitch = surf->info.planes[plane_idx].stride;
883 _tbm_surface_mutex_unlock();
889 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
890 tbm_surface_info_s *info, int map)
892 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
894 struct _tbm_surface *surf;
895 tbm_bo_handle bo_handles[4];
898 _tbm_surface_mutex_lock();
900 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
902 surf = (struct _tbm_surface *)surface;
904 memset(info, 0x00, sizeof(tbm_surface_info_s));
905 info->width = surf->info.width;
906 info->height = surf->info.height;
907 info->format = surf->info.format;
908 info->bpp = surf->info.bpp;
909 info->size = surf->info.size;
910 info->num_planes = surf->info.num_planes;
913 for (i = 0; i < surf->num_bos; i++) {
914 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
915 if (bo_handles[i].ptr == NULL) {
916 for (j = 0; j < i; j++)
917 tbm_bo_unmap(surf->bos[j]);
919 _tbm_surface_mutex_unlock();
924 for (i = 0; i < surf->num_bos; i++)
925 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
928 for (i = 0; i < surf->info.num_planes; i++) {
929 info->planes[i].size = surf->info.planes[i].size;
930 info->planes[i].offset = surf->info.planes[i].offset;
931 info->planes[i].stride = surf->info.planes[i].stride;
933 if (bo_handles[surf->planes_bo_idx[i]].ptr)
934 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
935 surf->info.planes[i].offset;
938 _tbm_surface_mutex_unlock();
944 tbm_surface_internal_unmap(tbm_surface_h surface)
946 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
948 struct _tbm_surface *surf;
951 _tbm_surface_mutex_lock();
953 surf = (struct _tbm_surface *)surface;
955 for (i = 0; i < surf->num_bos; i++)
956 tbm_bo_unmap(surf->bos[i]);
958 _tbm_surface_mutex_unlock();
962 tbm_surface_internal_get_width(tbm_surface_h surface)
964 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
966 struct _tbm_surface *surf;
969 _tbm_surface_mutex_lock();
971 surf = (struct _tbm_surface *)surface;
972 width = surf->info.width;
974 _tbm_surface_mutex_unlock();
980 tbm_surface_internal_get_height(tbm_surface_h surface)
982 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
984 struct _tbm_surface *surf;
987 _tbm_surface_mutex_lock();
989 surf = (struct _tbm_surface *)surface;
990 height = surf->info.height;
992 _tbm_surface_mutex_unlock();
999 tbm_surface_internal_get_format(tbm_surface_h surface)
1001 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1003 struct _tbm_surface *surf;
1006 _tbm_surface_mutex_lock();
1008 surf = (struct _tbm_surface *)surface;
1009 format = surf->info.format;
1011 _tbm_surface_mutex_unlock();
1017 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1019 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1020 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1021 struct _tbm_surface *surf;
1024 _tbm_surface_mutex_lock();
1026 surf = (struct _tbm_surface *)surface;
1027 bo_idx = surf->planes_bo_idx[plane_idx];
1029 _tbm_surface_mutex_unlock();
1035 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1037 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1039 return surface->debug_pid;
1043 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1045 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1047 surface->debug_pid = pid;
1051 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1052 tbm_data_free data_free_func)
1054 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1056 tbm_user_data *data;
1058 /* check if the data according to the key exist if so, return false. */
1059 data = user_data_lookup(&surface->user_data_list, key);
1061 TBM_LOG("[libtbm:%d] "
1062 "waring: %s:%d user data already exist. key:%ld\n",
1063 getpid(), __func__, __LINE__, key);
1067 data = user_data_create(key, data_free_func);
1071 LIST_ADD(&data->item_link, &surface->user_data_list);
1077 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1080 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1082 tbm_user_data *old_data;
1084 if (LIST_IS_EMPTY(&surface->user_data_list))
1087 old_data = user_data_lookup(&surface->user_data_list, key);
1091 if (old_data->data && old_data->free_func)
1092 old_data->free_func(old_data->data);
1094 old_data->data = data;
1100 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1103 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1105 tbm_user_data *old_data;
1107 if (!data || LIST_IS_EMPTY(&surface->user_data_list))
1110 old_data = user_data_lookup(&surface->user_data_list, key);
1116 *data = old_data->data;
1122 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1125 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1127 tbm_user_data *old_data = (void *)0;
1129 if (LIST_IS_EMPTY(&surface->user_data_list))
1132 old_data = user_data_lookup(&surface->user_data_list, key);
1136 user_data_delete(old_data);
1141 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1142 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1144 struct _tbm_surface_dump_buf_info
1152 tbm_surface_info_s info;
1154 struct list_head link;
1157 struct _tbm_surface_dump_info
1159 char *path; // copy???
1160 struct list_head *link;
1161 struct list_head surface_list; /* link of surface */
1164 static tbm_surface_dump_info *g_dump_info = NULL;
1165 static const char *dump_postfix[2] = {"png", "yuv"};
1169 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1170 int size2, void *data3, int size3)
1172 unsigned int *blocks;
1173 FILE *fp = fopen(file, "w+");
1174 TBM_RETURN_IF_FAIL(fp != NULL);
1176 blocks = (unsigned int *)data1;
1177 fwrite(blocks, 1, size1, fp);
1180 blocks = (unsigned int *)data2;
1181 fwrite(blocks, 1, size2, fp);
1185 blocks = (unsigned int *)data3;
1186 fwrite(blocks, 1, size3, fp);
1194 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1197 FILE *fp = fopen(file, "wb");
1198 TBM_RETURN_IF_FAIL(fp != NULL);
1201 png_structp pPngStruct =
1202 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1208 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1210 png_destroy_write_struct(&pPngStruct, NULL);
1215 png_init_io(pPngStruct, fp);
1216 png_set_IHDR(pPngStruct,
1221 PNG_COLOR_TYPE_RGBA,
1223 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1225 png_set_bgr(pPngStruct);
1226 png_write_info(pPngStruct, pPngInfo);
1228 const int pixel_size = 4; // RGBA
1229 png_bytep *row_pointers =
1230 png_malloc(pPngStruct, height * sizeof(png_byte *));
1232 unsigned int *blocks = (unsigned int *)data;
1236 for (; y < height; ++y) {
1238 png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1239 row_pointers[y] = (png_bytep)row;
1240 for (x = 0; x < width; ++x) {
1241 unsigned int curBlock = blocks[y * width + x];
1242 row[x * pixel_size] = (curBlock & 0xFF);
1243 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1244 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1245 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1249 png_write_image(pPngStruct, row_pointers);
1250 png_write_end(pPngStruct, pPngInfo);
1252 for (y = 0; y < height; y++)
1253 png_free(pPngStruct, row_pointers[y]);
1254 png_free(pPngStruct, row_pointers);
1256 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1262 tbm_surface_internal_dump_start(char *path, int buffer_size, int count)
1264 TBM_RETURN_IF_FAIL(path != NULL);
1265 TBM_RETURN_IF_FAIL(buffer_size > 0);
1266 TBM_RETURN_IF_FAIL(count > 0);
1268 tbm_surface_dump_buf_info *buf_info = NULL;
1270 tbm_bo_handle bo_handle;
1275 TBM_LOG("[libtbm:%d] "
1276 "waring: %s:%d already running the tbm_surface_internal_dump.\n",
1277 getpid(), __func__, __LINE__);
1281 g_dump_info = calloc(1, sizeof (buffer_size *count));
1282 TBM_RETURN_IF_FAIL(g_dump_info);
1284 LIST_INITHEAD(&g_dump_info->surface_list);
1286 for (i = 0; i < count; i++) {
1287 buf_info = calloc(1, sizeof (tbm_surface_dump_buf_info));
1288 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1289 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1290 TBM_GOTO_VAL_IF_FAIL(bo, fail);
1292 bo_handle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1293 memset(bo_handle.ptr, 0x00, buffer_size);
1296 buf_info->index = i;
1298 buf_info->size = buffer_size;
1300 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1303 g_dump_info->path = path;
1304 g_dump_info->link = &g_dump_info->surface_list;
1306 TBM_LOG("Dump Start.. path:%s\n", g_dump_info->path);
1315 tbm_surface_internal_dump_end(void)
1317 tbm_surface_dump_buf_info *buf_info, *tmp;
1318 char file[2048] = {0, };
1319 tbm_bo_handle bo_handle;
1325 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1326 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1327 if (buf_info->dirty) {
1328 switch (buf_info->info.format) {
1329 case TBM_FORMAT_ARGB8888:
1330 case TBM_FORMAT_XRGB8888:
1331 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1332 if (bo_handle.ptr == NULL)
1334 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1335 TBM_LOG("Dump File.. %s generated.\n", file);
1336 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1337 buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1339 case TBM_FORMAT_YVU420:
1340 case TBM_FORMAT_YUV420:
1343 case TBM_FORMAT_NV12:
1344 case TBM_FORMAT_NV21:
1347 case TBM_FORMAT_YUYV:
1348 case TBM_FORMAT_UYVY:
1352 //TDM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR (info.format));
1353 TBM_LOG("can't dump\n");
1354 tbm_bo_unmap(buf_info->bo);
1362 /* free resources */
1363 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1364 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1365 tbm_bo_unref(buf_info->bo);
1373 TBM_LOG("Dump End..\n");
1377 tbm_internal_surface_dump_buffer(tbm_surface_h surface, const char *type)
1379 TBM_RETURN_IF_FAIL(surface != NULL);
1380 TBM_RETURN_IF_FAIL(type != NULL);
1382 tbm_surface_dump_buf_info *buf_info;
1383 tbm_surface_info_s info;
1384 struct list_head *next_link;
1385 tbm_bo_handle bo_handle;
1387 const char *postfix;
1392 next_link = g_dump_info->link->next;
1393 TBM_RETURN_IF_FAIL(next_link != NULL);
1395 if (next_link == &g_dump_info->surface_list)
1397 next_link = next_link->next;
1398 TBM_RETURN_IF_FAIL(next_link != NULL);
1401 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1402 TBM_RETURN_IF_FAIL(buf_info != NULL);
1404 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1405 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1407 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1408 postfix = dump_postfix[0];
1410 postfix = dump_postfix[1];
1412 /* make the file information */
1413 snprintf(buf_info->name, sizeof(buf_info->name), "%d-%s.%s", buf_info->index, type, postfix);
1414 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1417 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1418 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1420 switch (info.format) {
1421 case TBM_FORMAT_ARGB8888:
1422 case TBM_FORMAT_XRGB8888:
1423 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1425 case TBM_FORMAT_YVU420:
1426 case TBM_FORMAT_YUV420:
1429 case TBM_FORMAT_NV12:
1430 case TBM_FORMAT_NV21:
1433 case TBM_FORMAT_YUYV:
1434 case TBM_FORMAT_UYVY:
1438 //TDM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR (info.format));
1439 TBM_LOG("can't dump\n");
1440 tbm_bo_unmap(buf_info->bo);
1444 tbm_bo_unmap(buf_info->bo);
1446 tbm_surface_unmap(surface);
1448 buf_info->dirty = 1;
1449 g_dump_info->link = next_link;
1451 TBM_LOG("Dump %s \n", buf_info->name);