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 **************************************************************************/
37 #include "tbm_bufmgr.h"
38 #include "tbm_bufmgr_int.h"
39 #include "tbm_surface_internal.h"
44 static tbm_bufmgr g_surface_bufmgr;
45 static pthread_mutex_t tbm_surface_lock;
46 void _tbm_surface_mutex_unlock(void);
48 #define C(b, m) (((b) >> (m)) & 0xFF)
49 #define B(c, s) ((((unsigned int)(c)) & 0xff) << (s))
50 #define FOURCC(a, b, c, d) (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
51 #define FOURCC_STR(id) C(id, 0), C(id, 8), C(id, 16), C(id, 24)
52 #define FOURCC_ID(str) FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
55 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
57 TBM_ERR("'%s' failed.\n", #cond);\
58 _tbm_surface_mutex_unlock();\
63 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
65 TBM_ERR("'%s' failed.\n", #cond);\
66 _tbm_surface_mutex_unlock();\
73 _tbm_surface_internal_get_time(void)
78 clock_gettime(CLOCK_MONOTONIC, &tp);
79 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
85 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
87 LIST_DEL(&debug_data->item_link);
89 if (debug_data->key) free(debug_data->key);
90 if (debug_data->value) free(debug_data->value);
95 _tbm_surface_internal_format_to_str(tbm_format format)
99 return "TBM_FORMAT_C8";
100 case TBM_FORMAT_RGB332:
101 return "TBM_FORMAT_RGB332";
102 case TBM_FORMAT_BGR233:
103 return "TBM_FORMAT_BGR233";
104 case TBM_FORMAT_XRGB4444:
105 return "TBM_FORMAT_XRGB4444";
106 case TBM_FORMAT_XBGR4444:
107 return "TBM_FORMAT_XBGR4444";
108 case TBM_FORMAT_RGBX4444:
109 return "TBM_FORMAT_RGBX4444";
110 case TBM_FORMAT_BGRX4444:
111 return "TBM_FORMAT_BGRX4444";
112 case TBM_FORMAT_ARGB4444:
113 return "TBM_FORMAT_ARGB4444";
114 case TBM_FORMAT_ABGR4444:
115 return "TBM_FORMAT_ABGR4444";
116 case TBM_FORMAT_RGBA4444:
117 return "TBM_FORMAT_RGBA4444";
118 case TBM_FORMAT_BGRA4444:
119 return "TBM_FORMAT_BGRA4444";
120 case TBM_FORMAT_XRGB1555:
121 return "TBM_FORMAT_XRGB1555";
122 case TBM_FORMAT_XBGR1555:
123 return "TBM_FORMAT_XBGR1555";
124 case TBM_FORMAT_RGBX5551:
125 return "TBM_FORMAT_RGBX5551";
126 case TBM_FORMAT_BGRX5551:
127 return "TBM_FORMAT_BGRX5551";
128 case TBM_FORMAT_ARGB1555:
129 return "TBM_FORMAT_ARGB1555";
130 case TBM_FORMAT_ABGR1555:
131 return "TBM_FORMAT_ABGR1555";
132 case TBM_FORMAT_RGBA5551:
133 return "TBM_FORMAT_RGBA5551";
134 case TBM_FORMAT_BGRA5551:
135 return "TBM_FORMAT_BGRA5551";
136 case TBM_FORMAT_RGB565:
137 return "TBM_FORMAT_RGB565";
138 case TBM_FORMAT_BGR565:
139 return "TBM_FORMAT_BGR565";
140 case TBM_FORMAT_RGB888:
141 return "TBM_FORMAT_RGB888";
142 case TBM_FORMAT_BGR888:
143 return "TBM_FORMAT_BGR888";
144 case TBM_FORMAT_XRGB8888:
145 return "TBM_FORMAT_XRGB8888";
146 case TBM_FORMAT_XBGR8888:
147 return "TBM_FORMAT_XBGR8888";
148 case TBM_FORMAT_RGBX8888:
149 return "TBM_FORMAT_RGBX8888";
150 case TBM_FORMAT_BGRX8888:
151 return "TBM_FORMAT_BGRX8888";
152 case TBM_FORMAT_ARGB8888:
153 return "TBM_FORMAT_ARGB8888";
154 case TBM_FORMAT_ABGR8888:
155 return "TBM_FORMAT_ABGR8888";
156 case TBM_FORMAT_RGBA8888:
157 return "TBM_FORMAT_RGBA8888";
158 case TBM_FORMAT_BGRA8888:
159 return "TBM_FORMAT_BGRA8888";
160 case TBM_FORMAT_XRGB2101010:
161 return "TBM_FORMAT_XRGB2101010";
162 case TBM_FORMAT_XBGR2101010:
163 return "TBM_FORMAT_XBGR2101010";
164 case TBM_FORMAT_RGBX1010102:
165 return "TBM_FORMAT_RGBX1010102";
166 case TBM_FORMAT_BGRX1010102:
167 return "TBM_FORMAT_BGRX1010102";
168 case TBM_FORMAT_ARGB2101010:
169 return "TBM_FORMAT_ARGB2101010";
170 case TBM_FORMAT_ABGR2101010:
171 return "TBM_FORMAT_ABGR2101010";
172 case TBM_FORMAT_RGBA1010102:
173 return "TBM_FORMAT_RGBA1010102";
174 case TBM_FORMAT_BGRA1010102:
175 return "TBM_FORMAT_BGRA1010102";
176 case TBM_FORMAT_YUYV:
177 return "TBM_FORMAT_YUYV";
178 case TBM_FORMAT_YVYU:
179 return "TBM_FORMAT_YVYU";
180 case TBM_FORMAT_UYVY:
181 return "TBM_FORMAT_UYVY";
182 case TBM_FORMAT_VYUY:
183 return "TBM_FORMAT_VYUY";
184 case TBM_FORMAT_AYUV:
185 return "TBM_FORMAT_AYUV";
186 case TBM_FORMAT_NV12:
187 return "TBM_FORMAT_NV12";
188 case TBM_FORMAT_NV21:
189 return "TBM_FORMAT_NV21";
190 case TBM_FORMAT_NV16:
191 return "TBM_FORMAT_NV16";
192 case TBM_FORMAT_NV61:
193 return "TBM_FORMAT_NV61";
194 case TBM_FORMAT_YUV410:
195 return "TBM_FORMAT_YUV410";
196 case TBM_FORMAT_YVU410:
197 return "TBM_FORMAT_YVU410";
198 case TBM_FORMAT_YUV411:
199 return "TBM_FORMAT_YUV411";
200 case TBM_FORMAT_YVU411:
201 return "TBM_FORMAT_YVU411";
202 case TBM_FORMAT_YUV420:
203 return "TBM_FORMAT_YUV420";
204 case TBM_FORMAT_YVU420:
205 return "TBM_FORMAT_YVU420";
206 case TBM_FORMAT_YUV422:
207 return "TBM_FORMAT_YUV422";
208 case TBM_FORMAT_YVU422:
209 return "TBM_FORMAT_YVU422";
210 case TBM_FORMAT_YUV444:
211 return "TBM_FORMAT_YUV444";
212 case TBM_FORMAT_YVU444:
213 return "TBM_FORMAT_YVU444";
214 case TBM_FORMAT_NV12MT:
215 return "TBM_FORMAT_NV12MT";
222 _tbm_surface_mutex_init(void)
224 static bool tbm_surface_mutex_init = false;
226 if (tbm_surface_mutex_init)
229 if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
230 TBM_ERR("fail: pthread_mutex_init for tbm_surface_lock.\n");
234 tbm_surface_mutex_init = true;
240 _tbm_surface_mutex_lock(void)
242 if (!_tbm_surface_mutex_init()) {
243 TBM_ERR("fail: _tbm_surface_mutex_init.\n");
247 pthread_mutex_lock(&tbm_surface_lock);
251 _tbm_surface_mutex_unlock(void)
253 pthread_mutex_unlock(&tbm_surface_lock);
257 _init_surface_bufmgr(void)
259 g_surface_bufmgr = tbm_bufmgr_init(-1);
263 _deinit_surface_bufmgr(void)
265 if (!g_surface_bufmgr)
268 tbm_bufmgr_deinit(g_surface_bufmgr);
269 g_surface_bufmgr = NULL;
274 _tbm_surface_internal_is_valid(tbm_surface_h surface)
276 tbm_surface_h old_data = NULL;
278 TBM_RETURN_VAL_IF_FAIL(g_surface_bufmgr, 0);
279 TBM_RETURN_VAL_IF_FAIL(surface, 0);
281 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
282 LIST_FOR_EACH_ENTRY(old_data, &g_surface_bufmgr->surf_list, item_link) {
283 if (old_data == surface) {
284 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
290 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
296 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
297 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
299 TBM_RETURN_VAL_IF_FAIL(surface, 0);
300 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
302 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
303 struct _tbm_bufmgr *mgr = surf->bufmgr;
306 TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
307 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
308 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
309 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
311 if (!mgr->backend->surface_get_plane_data)
314 ret = mgr->backend->surface_get_plane_data(surf->info.width,
315 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
317 /* LCOV_EXCL_START */
318 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
327 _tbm_surface_internal_destroy(tbm_surface_h surface)
330 tbm_bufmgr bufmgr = surface->bufmgr;
331 tbm_user_data *old_data = NULL, *tmp = NULL;
332 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
334 /* destory the user_data_list */
335 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
336 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
337 TBM_DBG("free user_data\n");
338 user_data_delete(old_data);
342 for (i = 0; i < surface->num_bos; i++) {
343 surface->bos[i]->surface = NULL;
345 tbm_bo_unref(surface->bos[i]);
346 surface->bos[i] = NULL;
349 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
350 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
351 _tbm_surface_internal_debug_data_delete(debug_old_data);
354 LIST_DEL(&surface->item_link);
359 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
360 LIST_DELINIT(&bufmgr->surf_list);
362 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
363 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
364 _tbm_surface_internal_debug_data_delete(debug_old_data);
368 _deinit_surface_bufmgr();
372 /* LCOV_EXCL_START */
374 _tbm_surface_check_file_is_symbolic_link(const char* path)
381 if (stat(path, &sb) != 0)
384 if (S_ISLNK(sb.st_mode))
392 tbm_surface_internal_is_valid(tbm_surface_h surface)
396 _tbm_surface_mutex_lock();
398 /* Return silently if surface is null. */
400 _tbm_surface_mutex_unlock();
404 ret = _tbm_surface_internal_is_valid(surface);
406 _tbm_surface_mutex_unlock();
412 tbm_surface_internal_query_supported_formats(uint32_t **formats,
415 TBM_RETURN_VAL_IF_FAIL(formats, 0);
416 TBM_RETURN_VAL_IF_FAIL(num, 0);
418 struct _tbm_bufmgr *bufmgr;
420 bool bufmgr_initialized = false;
422 _tbm_surface_mutex_lock();
424 if (!g_surface_bufmgr) {
425 _init_surface_bufmgr();
426 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
427 bufmgr_initialized = true;
430 bufmgr = g_surface_bufmgr;
432 if (!bufmgr->backend->surface_supported_format)
435 ret = bufmgr->backend->surface_supported_format(formats, num);
437 /* LCOV_EXCL_START */
438 TBM_ERR("Fail to surface_supported_format.\n");
440 /* LCOV_EXCL_START */
443 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
445 if (bufmgr_initialized) {
446 LIST_DELINIT(&g_surface_bufmgr->surf_list);
447 _deinit_surface_bufmgr();
450 _tbm_surface_mutex_unlock();
454 /* LCOV_EXCL_START */
456 if (bufmgr_initialized) {
457 LIST_DELINIT(&g_surface_bufmgr->surf_list);
458 _deinit_surface_bufmgr();
460 _tbm_surface_mutex_unlock();
462 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
469 tbm_surface_internal_get_num_planes(tbm_format format)
475 case TBM_FORMAT_RGB332:
476 case TBM_FORMAT_BGR233:
477 case TBM_FORMAT_XRGB4444:
478 case TBM_FORMAT_XBGR4444:
479 case TBM_FORMAT_RGBX4444:
480 case TBM_FORMAT_BGRX4444:
481 case TBM_FORMAT_ARGB4444:
482 case TBM_FORMAT_ABGR4444:
483 case TBM_FORMAT_RGBA4444:
484 case TBM_FORMAT_BGRA4444:
485 case TBM_FORMAT_XRGB1555:
486 case TBM_FORMAT_XBGR1555:
487 case TBM_FORMAT_RGBX5551:
488 case TBM_FORMAT_BGRX5551:
489 case TBM_FORMAT_ARGB1555:
490 case TBM_FORMAT_ABGR1555:
491 case TBM_FORMAT_RGBA5551:
492 case TBM_FORMAT_BGRA5551:
493 case TBM_FORMAT_RGB565:
494 case TBM_FORMAT_BGR565:
495 case TBM_FORMAT_RGB888:
496 case TBM_FORMAT_BGR888:
497 case TBM_FORMAT_XRGB8888:
498 case TBM_FORMAT_XBGR8888:
499 case TBM_FORMAT_RGBX8888:
500 case TBM_FORMAT_BGRX8888:
501 case TBM_FORMAT_ARGB8888:
502 case TBM_FORMAT_ABGR8888:
503 case TBM_FORMAT_RGBA8888:
504 case TBM_FORMAT_BGRA8888:
505 case TBM_FORMAT_XRGB2101010:
506 case TBM_FORMAT_XBGR2101010:
507 case TBM_FORMAT_RGBX1010102:
508 case TBM_FORMAT_BGRX1010102:
509 case TBM_FORMAT_ARGB2101010:
510 case TBM_FORMAT_ABGR2101010:
511 case TBM_FORMAT_RGBA1010102:
512 case TBM_FORMAT_BGRA1010102:
513 case TBM_FORMAT_YUYV:
514 case TBM_FORMAT_YVYU:
515 case TBM_FORMAT_UYVY:
516 case TBM_FORMAT_VYUY:
517 case TBM_FORMAT_AYUV:
520 case TBM_FORMAT_NV12:
521 case TBM_FORMAT_NV12MT:
522 case TBM_FORMAT_NV21:
523 case TBM_FORMAT_NV16:
524 case TBM_FORMAT_NV61:
527 case TBM_FORMAT_YUV410:
528 case TBM_FORMAT_YVU410:
529 case TBM_FORMAT_YUV411:
530 case TBM_FORMAT_YVU411:
531 case TBM_FORMAT_YUV420:
532 case TBM_FORMAT_YVU420:
533 case TBM_FORMAT_YUV422:
534 case TBM_FORMAT_YVU422:
535 case TBM_FORMAT_YUV444:
536 case TBM_FORMAT_YVU444:
544 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
550 tbm_surface_internal_get_bpp(tbm_format format)
557 case TBM_FORMAT_RGB332:
558 case TBM_FORMAT_BGR233:
561 case TBM_FORMAT_XRGB4444:
562 case TBM_FORMAT_XBGR4444:
563 case TBM_FORMAT_RGBX4444:
564 case TBM_FORMAT_BGRX4444:
565 case TBM_FORMAT_ARGB4444:
566 case TBM_FORMAT_ABGR4444:
567 case TBM_FORMAT_RGBA4444:
568 case TBM_FORMAT_BGRA4444:
569 case TBM_FORMAT_XRGB1555:
570 case TBM_FORMAT_XBGR1555:
571 case TBM_FORMAT_RGBX5551:
572 case TBM_FORMAT_BGRX5551:
573 case TBM_FORMAT_ARGB1555:
574 case TBM_FORMAT_ABGR1555:
575 case TBM_FORMAT_RGBA5551:
576 case TBM_FORMAT_BGRA5551:
577 case TBM_FORMAT_RGB565:
578 case TBM_FORMAT_BGR565:
581 case TBM_FORMAT_RGB888:
582 case TBM_FORMAT_BGR888:
585 case TBM_FORMAT_XRGB8888:
586 case TBM_FORMAT_XBGR8888:
587 case TBM_FORMAT_RGBX8888:
588 case TBM_FORMAT_BGRX8888:
589 case TBM_FORMAT_ARGB8888:
590 case TBM_FORMAT_ABGR8888:
591 case TBM_FORMAT_RGBA8888:
592 case TBM_FORMAT_BGRA8888:
593 case TBM_FORMAT_XRGB2101010:
594 case TBM_FORMAT_XBGR2101010:
595 case TBM_FORMAT_RGBX1010102:
596 case TBM_FORMAT_BGRX1010102:
597 case TBM_FORMAT_ARGB2101010:
598 case TBM_FORMAT_ABGR2101010:
599 case TBM_FORMAT_RGBA1010102:
600 case TBM_FORMAT_BGRA1010102:
601 case TBM_FORMAT_YUYV:
602 case TBM_FORMAT_YVYU:
603 case TBM_FORMAT_UYVY:
604 case TBM_FORMAT_VYUY:
605 case TBM_FORMAT_AYUV:
608 case TBM_FORMAT_NV12:
609 case TBM_FORMAT_NV12MT:
610 case TBM_FORMAT_NV21:
613 case TBM_FORMAT_NV16:
614 case TBM_FORMAT_NV61:
617 case TBM_FORMAT_YUV410:
618 case TBM_FORMAT_YVU410:
621 case TBM_FORMAT_YUV411:
622 case TBM_FORMAT_YVU411:
623 case TBM_FORMAT_YUV420:
624 case TBM_FORMAT_YVU420:
627 case TBM_FORMAT_YUV422:
628 case TBM_FORMAT_YVU422:
631 case TBM_FORMAT_YUV444:
632 case TBM_FORMAT_YVU444:
639 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
645 tbm_surface_internal_create_with_flags(int width, int height,
646 int format, int flags)
648 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
649 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
651 struct _tbm_bufmgr *mgr;
652 struct _tbm_surface *surf = NULL;
656 uint32_t bo_size = 0;
659 bool bufmgr_initialized = false;
661 _tbm_surface_mutex_lock();
663 if (!g_surface_bufmgr) {
664 _init_surface_bufmgr();
665 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
666 bufmgr_initialized = true;
669 mgr = g_surface_bufmgr;
670 if (!TBM_BUFMGR_IS_VALID(mgr)) {
671 TBM_ERR("The bufmgr is invalid\n");
672 goto check_valid_fail;
675 surf = calloc(1, sizeof(struct _tbm_surface));
677 /* LCOV_EXCL_START */
678 TBM_ERR("fail to alloc surf\n");
679 goto alloc_surf_fail;
684 surf->info.width = width;
685 surf->info.height = height;
686 surf->info.format = format;
687 surf->info.bpp = tbm_surface_internal_get_bpp(format);
688 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
691 /* get size, stride and offset bo_idx */
692 for (i = 0; i < surf->info.num_planes; i++) {
693 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
694 &offset, &stride, &bo_idx)) {
695 TBM_ERR("fail to query plane data\n");
696 goto query_plane_data_fail;
699 surf->info.planes[i].size = size;
700 surf->info.planes[i].offset = offset;
701 surf->info.planes[i].stride = stride;
702 surf->planes_bo_idx[i] = bo_idx;
707 for (i = 0; i < surf->info.num_planes; i++) {
708 surf->info.size += surf->info.planes[i].size;
710 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
711 surf->num_bos = surf->planes_bo_idx[i] + 1;
716 for (i = 0; i < surf->num_bos; i++) {
718 for (j = 0; j < surf->info.num_planes; j++) {
719 if (surf->planes_bo_idx[j] == i)
720 bo_size += surf->info.planes[j].size;
723 if (mgr->backend->surface_bo_alloc) {
724 /* LCOV_EXCL_START */
726 void *bo_priv = NULL;
728 bo = calloc(1, sizeof(struct _tbm_bo));
730 TBM_ERR("fail to alloc bo struct\n");
734 bo->bufmgr = surf->bufmgr;
736 pthread_mutex_lock(&surf->bufmgr->lock);
738 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
740 TBM_ERR("fail to alloc bo priv\n");
742 pthread_mutex_unlock(&surf->bufmgr->lock);
750 LIST_INITHEAD(&bo->user_data_list);
752 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
754 pthread_mutex_unlock(&surf->bufmgr->lock);
759 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
761 TBM_ERR("fail to alloc bo idx:%d\n", i);
766 _tbm_bo_set_surface(surf->bos[i], surf);
769 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
770 _tbm_surface_internal_format_to_str(format), flags, surf);
772 LIST_INITHEAD(&surf->user_data_list);
773 LIST_INITHEAD(&surf->debug_data_list);
775 LIST_ADD(&surf->item_link, &mgr->surf_list);
777 _tbm_surface_mutex_unlock();
781 /* LCOV_EXCL_START */
783 for (j = 0; j < i; j++) {
785 tbm_bo_unref(surf->bos[j]);
787 query_plane_data_fail:
791 if (bufmgr_initialized && mgr) {
792 LIST_DELINIT(&mgr->surf_list);
793 _deinit_surface_bufmgr();
795 _tbm_surface_mutex_unlock();
797 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
799 _tbm_surface_internal_format_to_str(format), flags);
806 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
807 tbm_bo *bos, int num)
809 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
810 TBM_RETURN_VAL_IF_FAIL(info, NULL);
811 TBM_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
812 TBM_RETURN_VAL_IF_FAIL(num > 0, NULL);
813 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
815 struct _tbm_bufmgr *mgr;
816 struct _tbm_surface *surf = NULL;
818 bool bufmgr_initialized = false;
820 _tbm_surface_mutex_lock();
822 if (!g_surface_bufmgr) {
823 _init_surface_bufmgr();
824 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
825 bufmgr_initialized = true;
828 mgr = g_surface_bufmgr;
829 if (!TBM_BUFMGR_IS_VALID(mgr)) {
830 TBM_ERR("fail to validate the Bufmgr.\n");
831 goto check_valid_fail;
834 surf = calloc(1, sizeof(struct _tbm_surface));
836 /* LCOV_EXCL_START */
837 TBM_ERR("fail to allocate struct _tbm_surface.\n");
838 goto alloc_surf_fail;
843 surf->info.width = info->width;
844 surf->info.height = info->height;
845 surf->info.format = info->format;
847 surf->info.bpp = info->bpp;
849 surf->info.bpp = tbm_surface_internal_get_bpp(info->format);
850 surf->info.num_planes = info->num_planes;
853 /* get size, stride and offset */
854 for (i = 0; i < info->num_planes; i++) {
855 surf->info.planes[i].offset = info->planes[i].offset;
856 surf->info.planes[i].stride = info->planes[i].stride;
858 if (info->planes[i].size > 0)
859 surf->info.planes[i].size = info->planes[i].size;
861 uint32_t size = 0, offset = 0, stride = 0;
864 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
865 surf->info.planes[i].size = size;
869 surf->planes_bo_idx[i] = 0;
871 surf->planes_bo_idx[i] = i;
874 if (info->size > 0) {
875 surf->info.size = info->size;
878 for (i = 0; i < info->num_planes; i++)
879 surf->info.size += surf->info.planes[i].size;
882 surf->flags = TBM_BO_DEFAULT;
884 /* create only one bo */
886 for (i = 0; i < num; i++) {
887 if (bos[i] == NULL) {
888 TBM_ERR("bos[%d] is null.\n", i);
892 surf->bos[i] = tbm_bo_ref(bos[i]);
893 _tbm_bo_set_surface(bos[i], surf);
896 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
897 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
899 LIST_INITHEAD(&surf->user_data_list);
900 LIST_INITHEAD(&surf->debug_data_list);
902 LIST_ADD(&surf->item_link, &mgr->surf_list);
904 _tbm_surface_mutex_unlock();
908 /* LCOV_EXCL_START */
910 for (i = 0; i < num; i++) {
912 tbm_bo_unref(surf->bos[i]);
917 if (bufmgr_initialized && mgr) {
918 LIST_DELINIT(&mgr->surf_list);
919 _deinit_surface_bufmgr();
921 _tbm_surface_mutex_unlock();
923 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
924 info->width, info->height,
925 _tbm_surface_internal_format_to_str(info->format), num);
932 tbm_surface_internal_destroy(tbm_surface_h surface)
934 _tbm_surface_mutex_lock();
936 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
940 if (surface->refcnt > 0) {
941 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
942 _tbm_surface_mutex_unlock();
946 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
948 if (surface->refcnt == 0)
949 _tbm_surface_internal_destroy(surface);
951 _tbm_surface_mutex_unlock();
955 tbm_surface_internal_ref(tbm_surface_h surface)
957 _tbm_surface_mutex_lock();
959 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
963 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
965 _tbm_surface_mutex_unlock();
969 tbm_surface_internal_unref(tbm_surface_h surface)
971 _tbm_surface_mutex_lock();
973 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
977 if (surface->refcnt > 0) {
978 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
979 _tbm_surface_mutex_unlock();
983 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
985 if (surface->refcnt == 0)
986 _tbm_surface_internal_destroy(surface);
988 _tbm_surface_mutex_unlock();
992 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
994 struct _tbm_surface *surf;
997 _tbm_surface_mutex_lock();
999 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1001 surf = (struct _tbm_surface *)surface;
1002 num = surf->num_bos;
1004 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1006 _tbm_surface_mutex_unlock();
1012 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1014 struct _tbm_surface *surf;
1017 _tbm_surface_mutex_lock();
1019 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1020 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1022 surf = (struct _tbm_surface *)surface;
1023 bo = surf->bos[bo_idx];
1025 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1027 _tbm_surface_mutex_unlock();
1033 tbm_surface_internal_get_size(tbm_surface_h surface)
1035 struct _tbm_surface *surf;
1038 _tbm_surface_mutex_lock();
1040 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1042 surf = (struct _tbm_surface *)surface;
1043 size = surf->info.size;
1045 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1047 _tbm_surface_mutex_unlock();
1053 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1054 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1056 struct _tbm_surface *surf;
1058 _tbm_surface_mutex_lock();
1060 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1061 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1063 surf = (struct _tbm_surface *)surface;
1065 if (plane_idx >= surf->info.num_planes) {
1066 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1067 _tbm_surface_mutex_unlock();
1072 *size = surf->info.planes[plane_idx].size;
1075 *offset = surf->info.planes[plane_idx].offset;
1078 *pitch = surf->info.planes[plane_idx].stride;
1080 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1081 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1082 surf->info.planes[plane_idx].stride);
1084 _tbm_surface_mutex_unlock();
1090 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1091 tbm_surface_info_s *info, int map)
1093 struct _tbm_surface *surf;
1094 tbm_bo_handle bo_handles[4];
1097 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1100 _tbm_surface_mutex_lock();
1102 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1104 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1106 surf = (struct _tbm_surface *)surface;
1108 memset(info, 0x00, sizeof(tbm_surface_info_s));
1109 info->width = surf->info.width;
1110 info->height = surf->info.height;
1111 info->format = surf->info.format;
1112 info->bpp = surf->info.bpp;
1113 info->size = surf->info.size;
1114 info->num_planes = surf->info.num_planes;
1116 for (i = 0; i < surf->info.num_planes; i++) {
1117 info->planes[i].size = surf->info.planes[i].size;
1118 info->planes[i].offset = surf->info.planes[i].offset;
1119 info->planes[i].stride = surf->info.planes[i].stride;
1120 planes_bo_idx[i] = surf->planes_bo_idx[i];
1123 for (i = 0; i < surf->num_bos; i++)
1124 bos[i] = surf->bos[i];
1126 num_bos = surf->num_bos;
1129 _tbm_surface_mutex_unlock();
1130 for (i = 0; i < num_bos; i++) {
1131 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1132 if (bo_handles[i].ptr == NULL) {
1133 for (j = 0; j < i; j++)
1134 tbm_bo_unmap(bos[j]);
1136 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1140 _tbm_surface_mutex_lock();
1142 for (i = 0; i < num_bos; i++) {
1143 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1144 if (bo_handles[i].ptr == NULL) {
1145 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1146 _tbm_surface_mutex_unlock();
1152 for (i = 0; i < info->num_planes; i++) {
1153 if (bo_handles[planes_bo_idx[i]].ptr)
1154 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1157 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1159 _tbm_surface_mutex_unlock();
1165 tbm_surface_internal_unmap(tbm_surface_h surface)
1167 struct _tbm_surface *surf;
1170 _tbm_surface_mutex_lock();
1172 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1174 surf = (struct _tbm_surface *)surface;
1176 for (i = 0; i < surf->num_bos; i++)
1177 tbm_bo_unmap(surf->bos[i]);
1179 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1181 _tbm_surface_mutex_unlock();
1185 tbm_surface_internal_get_width(tbm_surface_h surface)
1187 struct _tbm_surface *surf;
1190 _tbm_surface_mutex_lock();
1192 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1194 surf = (struct _tbm_surface *)surface;
1195 width = surf->info.width;
1197 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1199 _tbm_surface_mutex_unlock();
1205 tbm_surface_internal_get_height(tbm_surface_h surface)
1207 struct _tbm_surface *surf;
1208 unsigned int height;
1210 _tbm_surface_mutex_lock();
1212 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1214 surf = (struct _tbm_surface *)surface;
1215 height = surf->info.height;
1217 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1219 _tbm_surface_mutex_unlock();
1226 tbm_surface_internal_get_format(tbm_surface_h surface)
1228 struct _tbm_surface *surf;
1231 _tbm_surface_mutex_lock();
1233 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1235 surf = (struct _tbm_surface *)surface;
1236 format = surf->info.format;
1238 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1240 _tbm_surface_mutex_unlock();
1246 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1248 struct _tbm_surface *surf;
1251 _tbm_surface_mutex_lock();
1253 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1254 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1256 surf = (struct _tbm_surface *)surface;
1257 bo_idx = surf->planes_bo_idx[plane_idx];
1259 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1261 _tbm_surface_mutex_unlock();
1267 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1268 tbm_data_free data_free_func)
1270 tbm_user_data *data;
1272 _tbm_surface_mutex_lock();
1274 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1276 /* check if the data according to the key exist if so, return false. */
1277 data = user_data_lookup(&surface->user_data_list, key);
1279 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1280 _tbm_surface_mutex_unlock();
1284 data = user_data_create(key, data_free_func);
1286 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1287 _tbm_surface_mutex_unlock();
1291 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1293 LIST_ADD(&data->item_link, &surface->user_data_list);
1295 _tbm_surface_mutex_unlock();
1301 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1304 tbm_user_data *old_data;
1306 _tbm_surface_mutex_lock();
1308 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1310 old_data = user_data_lookup(&surface->user_data_list, key);
1312 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1313 _tbm_surface_mutex_unlock();
1317 if (old_data->data && old_data->free_func)
1318 old_data->free_func(old_data->data);
1320 old_data->data = data;
1322 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1324 _tbm_surface_mutex_unlock();
1330 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1333 tbm_user_data *old_data;
1335 _tbm_surface_mutex_lock();
1337 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1340 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1341 _tbm_surface_mutex_unlock();
1346 old_data = user_data_lookup(&surface->user_data_list, key);
1348 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1349 _tbm_surface_mutex_unlock();
1353 *data = old_data->data;
1355 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1357 _tbm_surface_mutex_unlock();
1363 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1366 tbm_user_data *old_data = (void *)0;
1368 _tbm_surface_mutex_lock();
1370 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1372 old_data = user_data_lookup(&surface->user_data_list, key);
1374 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1375 _tbm_surface_mutex_unlock();
1379 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1381 user_data_delete(old_data);
1383 _tbm_surface_mutex_unlock();
1388 /* LCOV_EXCL_START */
1390 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1392 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1394 return surface->debug_pid;
1398 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1400 _tbm_surface_mutex_lock();
1402 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1404 surface->debug_pid = pid;
1406 _tbm_surface_mutex_unlock();
1409 static tbm_surface_debug_data *
1410 _tbm_surface_internal_debug_data_create(char *key, char *value)
1412 tbm_surface_debug_data *debug_data = NULL;
1414 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1418 if (key) debug_data->key = strdup(key);
1419 if (value) debug_data->value = strdup(value);
1425 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1427 tbm_surface_debug_data *debug_data = NULL;
1428 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1429 tbm_bufmgr bufmgr = NULL;
1431 _tbm_surface_mutex_lock();
1433 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1434 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1436 bufmgr = surface->bufmgr;
1438 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1440 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1441 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1443 if (!strcmp(old_data->key, key)) {
1444 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1445 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1446 goto add_debug_key_list;
1449 if (old_data->value)
1450 free(old_data->value);
1453 old_data->value = strdup(value);
1455 old_data->value = NULL;
1457 goto add_debug_key_list;
1463 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1465 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1466 _tbm_surface_mutex_unlock();
1470 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1472 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1475 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1476 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1477 if (!strcmp(old_data->key, key)) {
1478 _tbm_surface_mutex_unlock();
1484 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1485 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1487 _tbm_surface_mutex_unlock();
1493 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1495 tbm_surface_debug_data *old_data = NULL;
1497 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1499 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1500 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1501 if (!strcmp(old_data->key, key))
1502 return old_data->value;
1509 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1510 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1512 struct _tbm_surface_dump_buf_info {
1522 tbm_surface_info_s info;
1524 struct list_head link;
1527 struct _tbm_surface_dump_info {
1528 char *path; // copy???
1531 struct list_head *link;
1532 struct list_head surface_list; /* link of surface */
1535 static tbm_surface_dump_info *g_dump_info = NULL;
1536 static const char *dump_postfix[2] = {"png", "yuv"};
1537 static double scale_factor;
1540 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1541 void *data2, int size2, void *data3, int size3)
1544 unsigned int *blocks;
1546 if (_tbm_surface_check_file_is_symbolic_link(file))
1547 TBM_ERR("%s is symbolic link\n", file);
1549 fp = fopen(file, "w+");
1550 TBM_RETURN_IF_FAIL(fp != NULL);
1552 blocks = (unsigned int *)data1;
1553 fwrite(blocks, 1, size1, fp);
1556 blocks = (unsigned int *)data2;
1557 fwrite(blocks, 1, size2, fp);
1561 blocks = (unsigned int *)data3;
1562 fwrite(blocks, 1, size3, fp);
1569 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1571 unsigned int *blocks = (unsigned int *)data;
1574 png_bytep *row_pointers;
1577 if (_tbm_surface_check_file_is_symbolic_link(file))
1578 TBM_ERR("%s is symbolic link\n", file);
1580 fp = fopen(file, "wb");
1581 TBM_RETURN_IF_FAIL(fp != NULL);
1583 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1586 TBM_ERR("fail to create a png write structure.\n");
1591 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1593 TBM_ERR("fail to create a png info structure.\n");
1594 png_destroy_write_struct(&pPngStruct, NULL);
1599 png_init_io(pPngStruct, fp);
1600 if (format == TBM_FORMAT_XRGB8888) {
1602 png_set_IHDR(pPngStruct,
1609 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1612 png_set_IHDR(pPngStruct,
1617 PNG_COLOR_TYPE_RGBA,
1619 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1622 png_set_bgr(pPngStruct);
1623 png_write_info(pPngStruct, pPngInfo);
1625 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1626 if (!row_pointers) {
1627 TBM_ERR("fail to allocate the png row_pointers.\n");
1628 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1633 for (y = 0; y < height; ++y) {
1637 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1639 TBM_ERR("fail to allocate the png row.\n");
1640 for (x = 0; x < y; x++)
1641 png_free(pPngStruct, row_pointers[x]);
1642 png_free(pPngStruct, row_pointers);
1643 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1647 row_pointers[y] = (png_bytep)row;
1649 for (x = 0; x < width; ++x) {
1650 unsigned int curBlock = blocks[y * width + x];
1652 if (pixel_size == 3) { // XRGB8888
1653 row[x * pixel_size] = (curBlock & 0xFF);
1654 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1655 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1656 } else { // ARGB8888
1657 row[x * pixel_size] = (curBlock & 0xFF);
1658 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1659 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1660 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1665 png_write_image(pPngStruct, row_pointers);
1666 png_write_end(pPngStruct, pPngInfo);
1668 for (y = 0; y < height; y++)
1669 png_free(pPngStruct, row_pointers[y]);
1670 png_free(pPngStruct, row_pointers);
1672 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1678 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1680 TBM_RETURN_IF_FAIL(path != NULL);
1681 TBM_RETURN_IF_FAIL(w > 0);
1682 TBM_RETURN_IF_FAIL(h > 0);
1683 TBM_RETURN_IF_FAIL(count > 0);
1685 tbm_surface_dump_buf_info *buf_info = NULL;
1686 tbm_surface_h tbm_surface;
1687 tbm_surface_info_s info;
1692 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1696 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1697 TBM_RETURN_IF_FAIL(g_dump_info);
1699 LIST_INITHEAD(&g_dump_info->surface_list);
1700 g_dump_info->count = 0;
1701 g_dump_info->dump_max = count;
1703 /* get buffer size */
1704 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1705 if (tbm_surface == NULL) {
1706 TBM_ERR("tbm_surface_create fail\n");
1712 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1713 TBM_ERR("tbm_surface_get_info fail\n");
1714 tbm_surface_destroy(tbm_surface);
1719 buffer_size = info.size;
1720 tbm_surface_destroy(tbm_surface);
1722 /* create dump lists */
1723 for (i = 0; i < count; i++) {
1726 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1727 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1729 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1731 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1736 buf_info->index = i;
1738 buf_info->size = buffer_size;
1740 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1743 g_dump_info->path = path;
1744 g_dump_info->link = &g_dump_info->surface_list;
1748 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1753 /* free resources */
1754 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1755 tbm_surface_dump_buf_info *tmp;
1757 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1758 tbm_bo_unref(buf_info->bo);
1759 LIST_DEL(&buf_info->link);
1764 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1773 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1780 tbm_surface_internal_dump_start(path, w, h, count);
1781 scale_factor = scale;
1785 tbm_surface_internal_dump_end(void)
1787 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1788 tbm_bo_handle bo_handle;
1793 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1800 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1803 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1804 if (bo_handle.ptr == NULL) {
1805 tbm_bo_unref(buf_info->bo);
1806 LIST_DEL(&buf_info->link);
1811 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1812 TBM_INFO("Dump File.. %s generated.\n", file);
1814 if (buf_info->dirty) {
1815 void *ptr1 = NULL, *ptr2 = NULL;
1817 switch (buf_info->info.format) {
1818 case TBM_FORMAT_ARGB8888:
1819 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1820 buf_info->info.planes[0].stride >> 2,
1821 buf_info->info.height, TBM_FORMAT_ARGB8888);
1823 case TBM_FORMAT_XRGB8888:
1824 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1825 buf_info->info.planes[0].stride >> 2,
1826 buf_info->info.height, TBM_FORMAT_XRGB8888);
1828 case TBM_FORMAT_YVU420:
1829 case TBM_FORMAT_YUV420:
1830 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1831 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1832 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1833 buf_info->info.planes[0].stride * buf_info->info.height,
1835 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1837 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1839 case TBM_FORMAT_NV12:
1840 case TBM_FORMAT_NV21:
1841 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1842 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1843 buf_info->info.planes[0].stride * buf_info->info.height,
1845 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1848 case TBM_FORMAT_YUYV:
1849 case TBM_FORMAT_UYVY:
1850 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1851 buf_info->info.planes[0].stride * buf_info->info.height,
1855 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1858 } else if (buf_info->dirty_shm)
1859 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1860 buf_info->shm_stride >> 2,
1861 buf_info->shm_h, 0);
1863 tbm_bo_unmap(buf_info->bo);
1864 tbm_bo_unref(buf_info->bo);
1865 LIST_DEL(&buf_info->link);
1872 TBM_INFO("Dump End..\n");
1875 static pixman_format_code_t
1876 _tbm_surface_internal_pixman_format_get(tbm_format format)
1879 case TBM_FORMAT_ARGB8888:
1880 return PIXMAN_a8r8g8b8;
1881 case TBM_FORMAT_XRGB8888:
1882 return PIXMAN_x8r8g8b8;
1891 * This function supports only if a buffer has below formats.
1892 * - TBM_FORMAT_ARGB8888
1893 * - TBM_FORMAT_XRGB8888
1895 static tbm_surface_error_e
1896 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1897 int format, int src_stride, int src_w, int src_h,
1898 int dst_stride, int dst_w, int dst_h)
1900 pixman_image_t *src_img = NULL, *dst_img = NULL;
1901 pixman_format_code_t pixman_format;
1902 pixman_transform_t t;
1903 struct pixman_f_transform ft;
1904 double scale_x, scale_y;
1906 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1907 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1909 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1910 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1913 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1914 (uint32_t*)src_ptr, src_stride);
1915 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1918 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1919 (uint32_t*)dst_ptr, dst_stride);
1920 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1922 pixman_f_transform_init_identity(&ft);
1924 scale_x = (double)src_w / dst_w;
1925 scale_y = (double)src_h / dst_h;
1927 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
1928 pixman_f_transform_translate(&ft, NULL, 0, 0);
1929 pixman_transform_from_pixman_f_transform(&t, &ft);
1930 pixman_image_set_transform(src_img, &t);
1932 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
1933 0, 0, 0, 0, 0, 0, dst_w, dst_h);
1935 pixman_image_unref(src_img);
1936 pixman_image_unref(dst_img);
1938 return TBM_SURFACE_ERROR_NONE;
1942 pixman_image_unref(src_img);
1944 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1947 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
1948 #define KEY_LEN 5 // "_XXXX"
1949 #define KEYS_LEN KEY_LEN * MAX_BOS
1951 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
1953 char *keys, temp_key[KEY_LEN + 1];
1954 struct _tbm_surface *surf;
1958 _tbm_surface_mutex_lock();
1960 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1962 surf = (struct _tbm_surface *)surface;
1964 num_bos = surf->num_bos;
1965 if (num_bos > MAX_BOS)
1968 keys = calloc(KEYS_LEN + 1, sizeof(char));
1970 TBM_ERR("Failed to alloc memory");
1971 _tbm_surface_mutex_unlock();
1975 for (i = 0; i < num_bos; i++) {
1976 memset(temp_key, 0x00, KEY_LEN + 1);
1978 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
1979 strncat(keys, temp_key, KEY_LEN);
1982 _tbm_surface_mutex_unlock();
1987 static void _tbm_surface_internal_put_keys(char *keys)
1994 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1996 TBM_RETURN_IF_FAIL(surface != NULL);
1997 TBM_RETURN_IF_FAIL(type != NULL);
1999 tbm_surface_dump_buf_info *buf_info;
2000 struct list_head *next_link;
2001 tbm_surface_info_s info;
2002 tbm_bo_handle bo_handle;
2003 const char *postfix;
2004 const char *format = NULL;
2011 next_link = g_dump_info->link->next;
2012 TBM_RETURN_IF_FAIL(next_link != NULL);
2014 if (next_link == &g_dump_info->surface_list) {
2015 next_link = next_link->next;
2016 TBM_RETURN_IF_FAIL(next_link != NULL);
2019 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2020 TBM_RETURN_IF_FAIL(buf_info != NULL);
2022 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2023 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2025 if (scale_factor > 0.0) {
2028 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2029 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2030 _tbm_surface_internal_format_to_str(info.format));
2031 tbm_surface_unmap(surface);
2035 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2037 buf_info->info.width = info.width * scale_factor;
2038 buf_info->info.height = info.height * scale_factor;
2039 buf_info->info.format = info.format;
2040 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2041 buf_info->info.num_planes = 1;
2042 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2043 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2045 if (buf_info->info.size > buf_info->size) {
2046 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2047 buf_info->info.size, buf_info->size);
2048 tbm_surface_unmap(surface);
2052 if (info.size > buf_info->size) {
2053 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2054 info.size, buf_info->size);
2055 tbm_surface_unmap(surface);
2059 /* make the file information */
2060 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2063 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2064 postfix = dump_postfix[0];
2065 format = _tbm_surface_internal_format_to_str(info.format);
2067 postfix = dump_postfix[1];
2069 keys = _tbm_surface_internal_get_keys(surface);
2071 TBM_ERR("fail to get keys");
2072 tbm_surface_unmap(surface);
2077 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2078 if (!bo_handle.ptr) {
2079 TBM_ERR("fail to map bo");
2080 _tbm_surface_internal_put_keys(keys);
2081 tbm_surface_unmap(surface);
2084 memset(bo_handle.ptr, 0x00, buf_info->size);
2086 switch (info.format) {
2087 case TBM_FORMAT_ARGB8888:
2088 case TBM_FORMAT_XRGB8888:
2089 snprintf(buf_info->name, sizeof(buf_info->name),
2090 "%10.3f_%03d%s_%p_%s-%s.%s",
2091 _tbm_surface_internal_get_time(),
2092 g_dump_info->count++, keys, surface, format, type, postfix);
2094 if (scale_factor > 0.0) {
2095 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2097 buf_info->info.format,
2098 info.planes[0].stride,
2099 info.width, info.height,
2100 buf_info->info.planes[0].stride,
2101 buf_info->info.width,
2102 buf_info->info.height);
2103 if (ret != TBM_SURFACE_ERROR_NONE) {
2104 TBM_ERR("fail to scale buffer");
2105 tbm_bo_unmap(buf_info->bo);
2106 _tbm_surface_internal_put_keys(keys);
2107 tbm_surface_unmap(surface);
2111 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2113 case TBM_FORMAT_YVU420:
2114 case TBM_FORMAT_YUV420:
2115 snprintf(buf_info->name, sizeof(buf_info->name),
2116 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2117 _tbm_surface_internal_get_time(),
2118 g_dump_info->count++, keys, type, info.planes[0].stride,
2119 info.height, FOURCC_STR(info.format), postfix);
2120 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2121 bo_handle.ptr += info.planes[0].stride * info.height;
2122 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2123 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2124 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2126 case TBM_FORMAT_NV12:
2127 case TBM_FORMAT_NV21:
2128 snprintf(buf_info->name, sizeof(buf_info->name),
2129 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2130 _tbm_surface_internal_get_time(),
2131 g_dump_info->count++, keys, type, info.planes[0].stride,
2132 info.height, FOURCC_STR(info.format), postfix);
2133 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2134 bo_handle.ptr += info.planes[0].stride * info.height;
2135 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2137 case TBM_FORMAT_YUYV:
2138 case TBM_FORMAT_UYVY:
2139 snprintf(buf_info->name, sizeof(buf_info->name),
2140 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2141 _tbm_surface_internal_get_time(),
2142 g_dump_info->count++, keys, type, info.planes[0].stride,
2143 info.height, FOURCC_STR(info.format), postfix);
2144 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2147 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2148 tbm_bo_unmap(buf_info->bo);
2149 _tbm_surface_internal_put_keys(keys);
2150 tbm_surface_unmap(surface);
2154 tbm_bo_unmap(buf_info->bo);
2156 _tbm_surface_internal_put_keys(keys);
2158 tbm_surface_unmap(surface);
2160 buf_info->dirty = 1;
2161 buf_info->dirty_shm = 0;
2163 if (g_dump_info->count == 1000)
2164 g_dump_info->count = 0;
2166 g_dump_info->link = next_link;
2168 TBM_INFO("Dump %s \n", buf_info->name);
2171 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2174 TBM_RETURN_IF_FAIL(ptr != NULL);
2175 TBM_RETURN_IF_FAIL(w > 0);
2176 TBM_RETURN_IF_FAIL(h > 0);
2177 TBM_RETURN_IF_FAIL(stride > 0);
2178 TBM_RETURN_IF_FAIL(type != NULL);
2180 tbm_surface_dump_buf_info *buf_info;
2181 struct list_head *next_link;
2182 tbm_bo_handle bo_handle;
2183 int ret, size, dw = 0, dh = 0, dstride = 0;
2188 next_link = g_dump_info->link->next;
2189 TBM_RETURN_IF_FAIL(next_link != NULL);
2191 if (next_link == &g_dump_info->surface_list) {
2192 next_link = next_link->next;
2193 TBM_RETURN_IF_FAIL(next_link != NULL);
2196 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2197 TBM_RETURN_IF_FAIL(buf_info != NULL);
2199 if (scale_factor > 0.0) {
2202 dw = w * scale_factor;
2203 dh = h * scale_factor;
2205 size = dstride * dh;
2209 if (size > buf_info->size) {
2210 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2211 size, buf_info->size);
2216 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2217 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2219 memset(bo_handle.ptr, 0x00, buf_info->size);
2220 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2222 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2223 _tbm_surface_internal_get_time(),
2224 g_dump_info->count++, type, dump_postfix[0]);
2225 if (scale_factor > 0.0) {
2226 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2227 TBM_FORMAT_ARGB8888, stride,
2228 w, h, dstride, dw, dh);
2229 if (ret != TBM_SURFACE_ERROR_NONE) {
2230 TBM_ERR("fail to scale buffer");
2231 tbm_bo_unmap(buf_info->bo);
2234 buf_info->shm_stride = dstride;
2235 buf_info->shm_h = dh;
2237 memcpy(bo_handle.ptr, ptr, size);
2238 buf_info->shm_stride = stride;
2239 buf_info->shm_h = h;
2242 tbm_bo_unmap(buf_info->bo);
2244 buf_info->dirty = 0;
2245 buf_info->dirty_shm = 1;
2247 if (g_dump_info->count == 1000)
2248 g_dump_info->count = 0;
2250 g_dump_info->link = next_link;
2252 TBM_INFO("Dump %s \n", buf_info->name);
2256 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2258 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2259 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2260 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2262 tbm_surface_info_s info;
2263 const char *postfix;
2267 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2268 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2270 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2271 postfix = dump_postfix[0];
2273 postfix = dump_postfix[1];
2275 if (strcmp(postfix, type)) {
2276 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2277 tbm_surface_unmap(surface);
2281 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2283 if (!access(file, 0)) {
2284 TBM_ERR("can't capture buffer, exist file %s", file);
2285 tbm_surface_unmap(surface);
2289 switch (info.format) {
2290 case TBM_FORMAT_ARGB8888:
2291 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2292 info.planes[0].stride >> 2,
2293 info.height, TBM_FORMAT_ARGB8888);
2295 case TBM_FORMAT_XRGB8888:
2296 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2297 info.planes[0].stride >> 2,
2298 info.height, TBM_FORMAT_XRGB8888);
2300 case TBM_FORMAT_YVU420:
2301 case TBM_FORMAT_YUV420:
2302 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2303 info.planes[0].stride * info.height,
2305 info.planes[1].stride * (info.height >> 1),
2307 info.planes[2].stride * (info.height >> 1));
2309 case TBM_FORMAT_NV12:
2310 case TBM_FORMAT_NV21:
2311 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2312 info.planes[0].stride * info.height,
2314 info.planes[1].stride * (info.height >> 1),
2317 case TBM_FORMAT_YUYV:
2318 case TBM_FORMAT_UYVY:
2319 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2320 info.planes[0].stride * info.height,
2324 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2325 tbm_surface_unmap(surface);
2329 tbm_surface_unmap(surface);
2331 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2337 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2338 const char *path, const char *name, const char *type)
2340 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2341 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2342 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2343 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2344 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2345 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2349 if (strcmp(dump_postfix[0], type)) {
2350 TBM_ERR("Not supported type:%s'", type);
2354 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2356 if (!access(file, 0)) {
2357 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2361 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2363 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);