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_LOG_E("'%s' failed.\n", #cond);\
58 _tbm_surface_mutex_unlock();\
63 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
65 TBM_LOG_E("'%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_LOG_E("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_LOG_E("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("tbm_surface(%p)\n", surface);
290 TBM_LOG_E("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_LOG_E("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();
373 _tbm_surface_check_file_is_valid(const char* path, int del_link)
380 real_path = realpath(path, NULL);
381 if (real_path && strncmp(path, real_path, strlen(path))) {
396 tbm_surface_internal_is_valid(tbm_surface_h surface)
400 _tbm_surface_mutex_lock();
402 /* Return silently if surface is null. */
404 _tbm_surface_mutex_unlock();
408 ret = _tbm_surface_internal_is_valid(surface);
410 _tbm_surface_mutex_unlock();
416 tbm_surface_internal_query_supported_formats(uint32_t **formats,
419 struct _tbm_bufmgr *mgr;
421 bool bufmgr_initialized = false;
423 _tbm_surface_mutex_lock();
425 if (!g_surface_bufmgr) {
426 _init_surface_bufmgr();
427 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
428 bufmgr_initialized = true;
431 mgr = g_surface_bufmgr;
433 if (!mgr->backend->surface_supported_format)
436 ret = mgr->backend->surface_supported_format(formats, num);
438 /* LCOV_EXCL_START */
439 TBM_LOG_E("Fail to surface_supported_format.\n");
441 /* LCOV_EXCL_START */
444 TBM_TRACE("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
446 _tbm_surface_mutex_unlock();
450 /* LCOV_EXCL_START */
452 if (bufmgr_initialized) {
453 LIST_DELINIT(&g_surface_bufmgr->surf_list);
454 _deinit_surface_bufmgr();
456 _tbm_surface_mutex_unlock();
458 TBM_LOG_E("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
465 tbm_surface_internal_get_num_planes(tbm_format format)
471 case TBM_FORMAT_RGB332:
472 case TBM_FORMAT_BGR233:
473 case TBM_FORMAT_XRGB4444:
474 case TBM_FORMAT_XBGR4444:
475 case TBM_FORMAT_RGBX4444:
476 case TBM_FORMAT_BGRX4444:
477 case TBM_FORMAT_ARGB4444:
478 case TBM_FORMAT_ABGR4444:
479 case TBM_FORMAT_RGBA4444:
480 case TBM_FORMAT_BGRA4444:
481 case TBM_FORMAT_XRGB1555:
482 case TBM_FORMAT_XBGR1555:
483 case TBM_FORMAT_RGBX5551:
484 case TBM_FORMAT_BGRX5551:
485 case TBM_FORMAT_ARGB1555:
486 case TBM_FORMAT_ABGR1555:
487 case TBM_FORMAT_RGBA5551:
488 case TBM_FORMAT_BGRA5551:
489 case TBM_FORMAT_RGB565:
490 case TBM_FORMAT_BGR565:
491 case TBM_FORMAT_RGB888:
492 case TBM_FORMAT_BGR888:
493 case TBM_FORMAT_XRGB8888:
494 case TBM_FORMAT_XBGR8888:
495 case TBM_FORMAT_RGBX8888:
496 case TBM_FORMAT_BGRX8888:
497 case TBM_FORMAT_ARGB8888:
498 case TBM_FORMAT_ABGR8888:
499 case TBM_FORMAT_RGBA8888:
500 case TBM_FORMAT_BGRA8888:
501 case TBM_FORMAT_XRGB2101010:
502 case TBM_FORMAT_XBGR2101010:
503 case TBM_FORMAT_RGBX1010102:
504 case TBM_FORMAT_BGRX1010102:
505 case TBM_FORMAT_ARGB2101010:
506 case TBM_FORMAT_ABGR2101010:
507 case TBM_FORMAT_RGBA1010102:
508 case TBM_FORMAT_BGRA1010102:
509 case TBM_FORMAT_YUYV:
510 case TBM_FORMAT_YVYU:
511 case TBM_FORMAT_UYVY:
512 case TBM_FORMAT_VYUY:
513 case TBM_FORMAT_AYUV:
516 case TBM_FORMAT_NV12:
517 case TBM_FORMAT_NV12MT:
518 case TBM_FORMAT_NV21:
519 case TBM_FORMAT_NV16:
520 case TBM_FORMAT_NV61:
523 case TBM_FORMAT_YUV410:
524 case TBM_FORMAT_YVU410:
525 case TBM_FORMAT_YUV411:
526 case TBM_FORMAT_YVU411:
527 case TBM_FORMAT_YUV420:
528 case TBM_FORMAT_YVU420:
529 case TBM_FORMAT_YUV422:
530 case TBM_FORMAT_YVU422:
531 case TBM_FORMAT_YUV444:
532 case TBM_FORMAT_YVU444:
540 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
546 tbm_surface_internal_get_bpp(tbm_format format)
553 case TBM_FORMAT_RGB332:
554 case TBM_FORMAT_BGR233:
557 case TBM_FORMAT_XRGB4444:
558 case TBM_FORMAT_XBGR4444:
559 case TBM_FORMAT_RGBX4444:
560 case TBM_FORMAT_BGRX4444:
561 case TBM_FORMAT_ARGB4444:
562 case TBM_FORMAT_ABGR4444:
563 case TBM_FORMAT_RGBA4444:
564 case TBM_FORMAT_BGRA4444:
565 case TBM_FORMAT_XRGB1555:
566 case TBM_FORMAT_XBGR1555:
567 case TBM_FORMAT_RGBX5551:
568 case TBM_FORMAT_BGRX5551:
569 case TBM_FORMAT_ARGB1555:
570 case TBM_FORMAT_ABGR1555:
571 case TBM_FORMAT_RGBA5551:
572 case TBM_FORMAT_BGRA5551:
573 case TBM_FORMAT_RGB565:
574 case TBM_FORMAT_BGR565:
577 case TBM_FORMAT_RGB888:
578 case TBM_FORMAT_BGR888:
581 case TBM_FORMAT_XRGB8888:
582 case TBM_FORMAT_XBGR8888:
583 case TBM_FORMAT_RGBX8888:
584 case TBM_FORMAT_BGRX8888:
585 case TBM_FORMAT_ARGB8888:
586 case TBM_FORMAT_ABGR8888:
587 case TBM_FORMAT_RGBA8888:
588 case TBM_FORMAT_BGRA8888:
589 case TBM_FORMAT_XRGB2101010:
590 case TBM_FORMAT_XBGR2101010:
591 case TBM_FORMAT_RGBX1010102:
592 case TBM_FORMAT_BGRX1010102:
593 case TBM_FORMAT_ARGB2101010:
594 case TBM_FORMAT_ABGR2101010:
595 case TBM_FORMAT_RGBA1010102:
596 case TBM_FORMAT_BGRA1010102:
597 case TBM_FORMAT_YUYV:
598 case TBM_FORMAT_YVYU:
599 case TBM_FORMAT_UYVY:
600 case TBM_FORMAT_VYUY:
601 case TBM_FORMAT_AYUV:
604 case TBM_FORMAT_NV12:
605 case TBM_FORMAT_NV12MT:
606 case TBM_FORMAT_NV21:
609 case TBM_FORMAT_NV16:
610 case TBM_FORMAT_NV61:
613 case TBM_FORMAT_YUV410:
614 case TBM_FORMAT_YVU410:
617 case TBM_FORMAT_YUV411:
618 case TBM_FORMAT_YVU411:
619 case TBM_FORMAT_YUV420:
620 case TBM_FORMAT_YVU420:
623 case TBM_FORMAT_YUV422:
624 case TBM_FORMAT_YVU422:
627 case TBM_FORMAT_YUV444:
628 case TBM_FORMAT_YVU444:
635 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
641 tbm_surface_internal_create_with_flags(int width, int height,
642 int format, int flags)
644 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
645 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
647 struct _tbm_bufmgr *mgr;
648 struct _tbm_surface *surf = NULL;
652 uint32_t bo_size = 0;
655 bool bufmgr_initialized = false;
657 _tbm_surface_mutex_lock();
659 if (!g_surface_bufmgr) {
660 _init_surface_bufmgr();
661 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
662 bufmgr_initialized = true;
665 mgr = g_surface_bufmgr;
666 if (!TBM_BUFMGR_IS_VALID(mgr)) {
667 TBM_LOG_E("The bufmgr is invalid\n");
668 goto check_valid_fail;
671 surf = calloc(1, sizeof(struct _tbm_surface));
673 /* LCOV_EXCL_START */
674 TBM_LOG_E("fail to alloc surf\n");
675 goto alloc_surf_fail;
680 surf->info.width = width;
681 surf->info.height = height;
682 surf->info.format = format;
683 surf->info.bpp = tbm_surface_internal_get_bpp(format);
684 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
687 /* get size, stride and offset bo_idx */
688 for (i = 0; i < surf->info.num_planes; i++) {
689 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
690 &offset, &stride, &bo_idx)) {
691 TBM_LOG_E("fail to query plane data\n");
692 goto query_plane_data_fail;
695 surf->info.planes[i].size = size;
696 surf->info.planes[i].offset = offset;
697 surf->info.planes[i].stride = stride;
698 surf->planes_bo_idx[i] = bo_idx;
703 for (i = 0; i < surf->info.num_planes; i++) {
704 surf->info.size += surf->info.planes[i].size;
706 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
707 surf->num_bos = surf->planes_bo_idx[i] + 1;
712 for (i = 0; i < surf->num_bos; i++) {
714 for (j = 0; j < surf->info.num_planes; j++) {
715 if (surf->planes_bo_idx[j] == i)
716 bo_size += surf->info.planes[j].size;
719 if (mgr->backend->surface_bo_alloc) {
720 /* LCOV_EXCL_START */
722 void *bo_priv = NULL;
724 bo = calloc(1, sizeof(struct _tbm_bo));
726 TBM_LOG_E("fail to alloc bo struct\n");
730 bo->bufmgr = surf->bufmgr;
732 pthread_mutex_lock(&surf->bufmgr->lock);
734 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
736 TBM_LOG_E("fail to alloc bo priv\n");
738 pthread_mutex_unlock(&surf->bufmgr->lock);
746 LIST_INITHEAD(&bo->user_data_list);
748 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
750 pthread_mutex_unlock(&surf->bufmgr->lock);
755 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
757 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
762 _tbm_bo_set_surface(surf->bos[i], surf);
765 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
766 _tbm_surface_internal_format_to_str(format), flags, surf);
768 LIST_INITHEAD(&surf->user_data_list);
769 LIST_INITHEAD(&surf->debug_data_list);
771 LIST_ADD(&surf->item_link, &mgr->surf_list);
773 _tbm_surface_mutex_unlock();
777 /* LCOV_EXCL_START */
779 for (j = 0; j < i; j++) {
781 tbm_bo_unref(surf->bos[j]);
783 query_plane_data_fail:
787 if (bufmgr_initialized && mgr) {
788 LIST_DELINIT(&mgr->surf_list);
789 _deinit_surface_bufmgr();
791 _tbm_surface_mutex_unlock();
793 TBM_LOG_E("error: width(%d) height(%d) format(%s) flags(%d)\n",
795 _tbm_surface_internal_format_to_str(format), flags);
802 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
803 tbm_bo *bos, int num)
805 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
806 TBM_RETURN_VAL_IF_FAIL(info, NULL);
807 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
809 struct _tbm_bufmgr *mgr;
810 struct _tbm_surface *surf = NULL;
812 bool bufmgr_initialized = false;
814 _tbm_surface_mutex_lock();
816 if (!g_surface_bufmgr) {
817 _init_surface_bufmgr();
818 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
819 bufmgr_initialized = true;
822 mgr = g_surface_bufmgr;
823 if (!TBM_BUFMGR_IS_VALID(mgr)) {
824 TBM_LOG_E("fail to validate the Bufmgr.\n");
825 goto check_valid_fail;
828 surf = calloc(1, sizeof(struct _tbm_surface));
830 /* LCOV_EXCL_START */
831 TBM_LOG_E("fail to allocate struct _tbm_surface.\n");
832 goto alloc_surf_fail;
837 surf->info.width = info->width;
838 surf->info.height = info->height;
839 surf->info.format = info->format;
841 surf->info.bpp = info->bpp;
843 surf->info.bpp = tbm_surface_internal_get_bpp(info->format);
844 surf->info.num_planes = info->num_planes;
847 /* get size, stride and offset */
848 for (i = 0; i < info->num_planes; i++) {
849 surf->info.planes[i].offset = info->planes[i].offset;
850 surf->info.planes[i].stride = info->planes[i].stride;
852 if (info->planes[i].size > 0)
853 surf->info.planes[i].size = info->planes[i].size;
855 uint32_t size = 0, offset = 0, stride = 0;
858 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
859 surf->info.planes[i].size = size;
863 surf->planes_bo_idx[i] = 0;
865 surf->planes_bo_idx[i] = i;
868 if (info->size > 0) {
869 surf->info.size = info->size;
872 for (i = 0; i < info->num_planes; i++)
873 surf->info.size += surf->info.planes[i].size;
876 surf->flags = TBM_BO_DEFAULT;
878 /* create only one bo */
880 for (i = 0; i < num; i++) {
881 if (bos[i] == NULL) {
882 TBM_LOG_E("bos[%d] is null.\n", i);
886 surf->bos[i] = tbm_bo_ref(bos[i]);
887 _tbm_bo_set_surface(bos[i], surf);
890 TBM_TRACE("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
891 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
893 LIST_INITHEAD(&surf->user_data_list);
894 LIST_INITHEAD(&surf->debug_data_list);
896 LIST_ADD(&surf->item_link, &mgr->surf_list);
898 _tbm_surface_mutex_unlock();
902 /* LCOV_EXCL_START */
904 for (i = 0; i < num; i++) {
906 tbm_bo_unref(surf->bos[i]);
911 if (bufmgr_initialized && mgr) {
912 LIST_DELINIT(&mgr->surf_list);
913 _deinit_surface_bufmgr();
915 _tbm_surface_mutex_unlock();
917 TBM_LOG_E("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
918 info->width, info->height,
919 _tbm_surface_internal_format_to_str(info->format), num);
926 tbm_surface_internal_destroy(tbm_surface_h surface)
928 _tbm_surface_mutex_lock();
930 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
934 if (surface->refcnt > 0) {
935 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
936 _tbm_surface_mutex_unlock();
940 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
942 if (surface->refcnt == 0)
943 _tbm_surface_internal_destroy(surface);
945 _tbm_surface_mutex_unlock();
949 tbm_surface_internal_ref(tbm_surface_h surface)
951 _tbm_surface_mutex_lock();
953 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
957 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
959 _tbm_surface_mutex_unlock();
963 tbm_surface_internal_unref(tbm_surface_h surface)
965 _tbm_surface_mutex_lock();
967 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
971 if (surface->refcnt > 0) {
972 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
973 _tbm_surface_mutex_unlock();
977 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
979 if (surface->refcnt == 0)
980 _tbm_surface_internal_destroy(surface);
982 _tbm_surface_mutex_unlock();
986 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
988 struct _tbm_surface *surf;
991 _tbm_surface_mutex_lock();
993 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
995 surf = (struct _tbm_surface *)surface;
998 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
1000 _tbm_surface_mutex_unlock();
1006 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1008 struct _tbm_surface *surf;
1011 _tbm_surface_mutex_lock();
1013 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1014 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1016 surf = (struct _tbm_surface *)surface;
1017 bo = surf->bos[bo_idx];
1019 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1021 _tbm_surface_mutex_unlock();
1027 tbm_surface_internal_get_size(tbm_surface_h surface)
1029 struct _tbm_surface *surf;
1032 _tbm_surface_mutex_lock();
1034 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1036 surf = (struct _tbm_surface *)surface;
1037 size = surf->info.size;
1039 TBM_TRACE("tbm_surface(%p) size(%u)\n", surface, size);
1041 _tbm_surface_mutex_unlock();
1047 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1048 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1050 struct _tbm_surface *surf;
1052 _tbm_surface_mutex_lock();
1054 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1055 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1057 surf = (struct _tbm_surface *)surface;
1059 if (plane_idx >= surf->info.num_planes) {
1060 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1061 _tbm_surface_mutex_unlock();
1066 *size = surf->info.planes[plane_idx].size;
1069 *offset = surf->info.planes[plane_idx].offset;
1072 *pitch = surf->info.planes[plane_idx].stride;
1074 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1075 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1076 surf->info.planes[plane_idx].stride);
1078 _tbm_surface_mutex_unlock();
1084 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1085 tbm_surface_info_s *info, int map)
1087 struct _tbm_surface *surf;
1088 tbm_bo_handle bo_handles[4];
1091 _tbm_surface_mutex_lock();
1093 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1095 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1097 surf = (struct _tbm_surface *)surface;
1099 memset(info, 0x00, sizeof(tbm_surface_info_s));
1100 info->width = surf->info.width;
1101 info->height = surf->info.height;
1102 info->format = surf->info.format;
1103 info->bpp = surf->info.bpp;
1104 info->size = surf->info.size;
1105 info->num_planes = surf->info.num_planes;
1108 for (i = 0; i < surf->num_bos; i++) {
1109 _tbm_surface_mutex_unlock();
1110 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1111 _tbm_surface_mutex_lock();
1112 if (bo_handles[i].ptr == NULL) {
1113 for (j = 0; j < i; j++)
1114 tbm_bo_unmap(surf->bos[j]);
1116 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1117 _tbm_surface_mutex_unlock();
1122 for (i = 0; i < surf->num_bos; i++) {
1123 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1124 if (bo_handles[i].ptr == NULL) {
1125 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1126 _tbm_surface_mutex_unlock();
1132 for (i = 0; i < surf->info.num_planes; i++) {
1133 info->planes[i].size = surf->info.planes[i].size;
1134 info->planes[i].offset = surf->info.planes[i].offset;
1135 info->planes[i].stride = surf->info.planes[i].stride;
1137 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1138 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1139 surf->info.planes[i].offset;
1142 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1144 _tbm_surface_mutex_unlock();
1150 tbm_surface_internal_unmap(tbm_surface_h surface)
1152 struct _tbm_surface *surf;
1155 _tbm_surface_mutex_lock();
1157 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1159 surf = (struct _tbm_surface *)surface;
1161 for (i = 0; i < surf->num_bos; i++)
1162 tbm_bo_unmap(surf->bos[i]);
1164 TBM_TRACE("tbm_surface(%p)\n", surface);
1166 _tbm_surface_mutex_unlock();
1170 tbm_surface_internal_get_width(tbm_surface_h surface)
1172 struct _tbm_surface *surf;
1175 _tbm_surface_mutex_lock();
1177 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1179 surf = (struct _tbm_surface *)surface;
1180 width = surf->info.width;
1182 TBM_TRACE("tbm_surface(%p) width(%u)\n", surface, width);
1184 _tbm_surface_mutex_unlock();
1190 tbm_surface_internal_get_height(tbm_surface_h surface)
1192 struct _tbm_surface *surf;
1193 unsigned int height;
1195 _tbm_surface_mutex_lock();
1197 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1199 surf = (struct _tbm_surface *)surface;
1200 height = surf->info.height;
1202 TBM_TRACE("tbm_surface(%p) height(%u)\n", surface, height);
1204 _tbm_surface_mutex_unlock();
1211 tbm_surface_internal_get_format(tbm_surface_h surface)
1213 struct _tbm_surface *surf;
1216 _tbm_surface_mutex_lock();
1218 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1220 surf = (struct _tbm_surface *)surface;
1221 format = surf->info.format;
1223 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1225 _tbm_surface_mutex_unlock();
1231 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1233 struct _tbm_surface *surf;
1236 _tbm_surface_mutex_lock();
1238 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1239 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1241 surf = (struct _tbm_surface *)surface;
1242 bo_idx = surf->planes_bo_idx[plane_idx];
1244 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1246 _tbm_surface_mutex_unlock();
1252 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1253 tbm_data_free data_free_func)
1255 tbm_user_data *data;
1257 _tbm_surface_mutex_lock();
1259 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1261 /* check if the data according to the key exist if so, return false. */
1262 data = user_data_lookup(&surface->user_data_list, key);
1264 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1265 _tbm_surface_mutex_unlock();
1269 data = user_data_create(key, data_free_func);
1271 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1272 _tbm_surface_mutex_unlock();
1276 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1278 LIST_ADD(&data->item_link, &surface->user_data_list);
1280 _tbm_surface_mutex_unlock();
1286 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1289 tbm_user_data *old_data;
1291 _tbm_surface_mutex_lock();
1293 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1295 old_data = user_data_lookup(&surface->user_data_list, key);
1297 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1298 _tbm_surface_mutex_unlock();
1302 if (old_data->data && old_data->free_func)
1303 old_data->free_func(old_data->data);
1305 old_data->data = data;
1307 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1309 _tbm_surface_mutex_unlock();
1315 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1318 tbm_user_data *old_data;
1320 _tbm_surface_mutex_lock();
1322 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1325 TBM_LOG_E("error: tbm_surface(%p) key(%lu)\n", surface, key);
1326 _tbm_surface_mutex_unlock();
1331 old_data = user_data_lookup(&surface->user_data_list, key);
1333 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1334 _tbm_surface_mutex_unlock();
1338 *data = old_data->data;
1340 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1342 _tbm_surface_mutex_unlock();
1348 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1351 tbm_user_data *old_data = (void *)0;
1353 _tbm_surface_mutex_lock();
1355 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1357 old_data = user_data_lookup(&surface->user_data_list, key);
1359 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1360 _tbm_surface_mutex_unlock();
1364 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1366 user_data_delete(old_data);
1368 _tbm_surface_mutex_unlock();
1373 /* LCOV_EXCL_START */
1375 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1377 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1379 return surface->debug_pid;
1383 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1385 _tbm_surface_mutex_lock();
1387 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1389 surface->debug_pid = pid;
1391 _tbm_surface_mutex_unlock();
1394 static tbm_surface_debug_data *
1395 _tbm_surface_internal_debug_data_create(char *key, char *value)
1397 tbm_surface_debug_data *debug_data = NULL;
1399 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1403 if (key) debug_data->key = strdup(key);
1404 if (value) debug_data->value = strdup(value);
1410 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1412 tbm_surface_debug_data *debug_data = NULL;
1413 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1414 tbm_bufmgr bufmgr = NULL;
1416 _tbm_surface_mutex_lock();
1418 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1419 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1421 bufmgr = surface->bufmgr;
1423 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1425 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1426 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1428 if (!strcmp(old_data->key, key)) {
1429 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1430 TBM_TRACE("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1431 goto add_debug_key_list;
1434 if (old_data->value)
1435 free(old_data->value);
1438 old_data->value = strdup(value);
1440 old_data->value = NULL;
1442 goto add_debug_key_list;
1448 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1450 TBM_LOG_E("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1451 _tbm_surface_mutex_unlock();
1455 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1457 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1460 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1461 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1462 if (!strcmp(old_data->key, key)) {
1463 _tbm_surface_mutex_unlock();
1469 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1470 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1472 _tbm_surface_mutex_unlock();
1478 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1480 tbm_surface_debug_data *old_data = NULL;
1482 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1484 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1485 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1486 if (!strcmp(old_data->key, key))
1487 return old_data->value;
1494 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1495 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1497 struct _tbm_surface_dump_buf_info {
1507 tbm_surface_info_s info;
1509 struct list_head link;
1512 struct _tbm_surface_dump_info {
1513 char *path; // copy???
1516 struct list_head *link;
1517 struct list_head surface_list; /* link of surface */
1520 static tbm_surface_dump_info *g_dump_info = NULL;
1521 static const char *dump_postfix[2] = {"png", "yuv"};
1522 static double scale_factor;
1525 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1526 void *data2, int size2, void *data3, int size3)
1529 unsigned int *blocks;
1531 if (!_tbm_surface_check_file_is_valid(file, 1))
1532 TBM_LOG_E("%s is symbolic link\n", file);
1534 fp = fopen(file, "w+");
1535 TBM_RETURN_IF_FAIL(fp != NULL);
1537 blocks = (unsigned int *)data1;
1538 fwrite(blocks, 1, size1, fp);
1541 blocks = (unsigned int *)data2;
1542 fwrite(blocks, 1, size2, fp);
1546 blocks = (unsigned int *)data3;
1547 fwrite(blocks, 1, size3, fp);
1554 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height)
1556 unsigned int *blocks = (unsigned int *)data;
1558 const int pixel_size = 4; // RGBA
1559 png_bytep *row_pointers;
1562 if (!_tbm_surface_check_file_is_valid(file, 1))
1563 TBM_LOG_E("%s is symbolic link\n", file);
1565 fp = fopen(file, "wb");
1566 TBM_RETURN_IF_FAIL(fp != NULL);
1568 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1571 TBM_LOG_E("fail to create a png write structure.\n");
1576 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1578 TBM_LOG_E("fail to create a png info structure.\n");
1579 png_destroy_write_struct(&pPngStruct, NULL);
1584 png_init_io(pPngStruct, fp);
1585 png_set_IHDR(pPngStruct,
1590 PNG_COLOR_TYPE_RGBA,
1592 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1594 png_set_bgr(pPngStruct);
1595 png_write_info(pPngStruct, pPngInfo);
1597 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1598 if (!row_pointers) {
1599 TBM_LOG_E("fail to allocate the png row_pointers.\n");
1600 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1605 for (y = 0; y < height; ++y) {
1609 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1611 TBM_LOG_E("fail to allocate the png row.\n");
1612 for (x = 0; x < y; x++)
1613 png_free(pPngStruct, row_pointers[x]);
1614 png_free(pPngStruct, row_pointers);
1615 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1619 row_pointers[y] = (png_bytep)row;
1621 for (x = 0; x < width; ++x) {
1622 unsigned int curBlock = blocks[y * width + x];
1624 row[x * pixel_size] = (curBlock & 0xFF);
1625 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1626 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1627 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1631 png_write_image(pPngStruct, row_pointers);
1632 png_write_end(pPngStruct, pPngInfo);
1634 for (y = 0; y < height; y++)
1635 png_free(pPngStruct, row_pointers[y]);
1636 png_free(pPngStruct, row_pointers);
1638 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1644 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1646 TBM_RETURN_IF_FAIL(path != NULL);
1647 TBM_RETURN_IF_FAIL(w > 0);
1648 TBM_RETURN_IF_FAIL(h > 0);
1649 TBM_RETURN_IF_FAIL(count > 0);
1651 tbm_surface_dump_buf_info *buf_info = NULL;
1652 tbm_surface_h tbm_surface;
1653 tbm_surface_info_s info;
1658 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1662 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1663 TBM_RETURN_IF_FAIL(g_dump_info);
1665 LIST_INITHEAD(&g_dump_info->surface_list);
1666 g_dump_info->count = 0;
1667 g_dump_info->dump_max = count;
1669 /* get buffer size */
1670 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1671 if (tbm_surface == NULL) {
1672 TBM_LOG_E("tbm_surface_create fail\n");
1678 if (TBM_SURFACE_ERROR_NONE != tbm_surface_map(tbm_surface,
1679 TBM_SURF_OPTION_READ, &info)) {
1680 TBM_LOG_E("tbm_surface_map fail\n");
1681 tbm_surface_destroy(tbm_surface);
1686 buffer_size = info.planes[0].stride * h;
1688 tbm_surface_unmap(tbm_surface);
1689 tbm_surface_destroy(tbm_surface);
1691 /* create dump lists */
1692 for (i = 0; i < count; i++) {
1695 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1696 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1698 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1700 TBM_LOG_E("fail to allocate the tbm_bo[%d]\n", i);
1705 buf_info->index = i;
1707 buf_info->size = buffer_size;
1709 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1712 g_dump_info->path = path;
1713 g_dump_info->link = &g_dump_info->surface_list;
1717 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1722 /* free resources */
1723 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1724 tbm_surface_dump_buf_info *tmp;
1726 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1727 tbm_bo_unref(buf_info->bo);
1728 LIST_DEL(&buf_info->link);
1733 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1742 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1749 tbm_surface_internal_dump_start(path, w, h, count);
1750 scale_factor = scale;
1754 tbm_surface_internal_dump_end(void)
1756 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1757 tbm_bo_handle bo_handle;
1762 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1769 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1772 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1773 if (bo_handle.ptr == NULL) {
1774 tbm_bo_unref(buf_info->bo);
1775 LIST_DEL(&buf_info->link);
1780 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1781 TBM_LOG_I("Dump File.. %s generated.\n", file);
1783 if (buf_info->dirty) {
1784 void *ptr1 = NULL, *ptr2 = NULL;
1786 switch (buf_info->info.format) {
1787 case TBM_FORMAT_ARGB8888:
1788 case TBM_FORMAT_XRGB8888:
1789 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1790 buf_info->info.planes[0].stride >> 2,
1791 buf_info->info.height);
1793 case TBM_FORMAT_YVU420:
1794 case TBM_FORMAT_YUV420:
1795 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1796 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1797 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1798 buf_info->info.planes[0].stride * buf_info->info.height,
1800 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1802 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1804 case TBM_FORMAT_NV12:
1805 case TBM_FORMAT_NV21:
1806 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1807 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1808 buf_info->info.planes[0].stride * buf_info->info.height,
1810 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1813 case TBM_FORMAT_YUYV:
1814 case TBM_FORMAT_UYVY:
1815 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1816 buf_info->info.planes[0].stride * buf_info->info.height,
1820 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1823 } else if (buf_info->dirty_shm)
1824 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1825 buf_info->shm_stride >> 2,
1828 tbm_bo_unmap(buf_info->bo);
1829 tbm_bo_unref(buf_info->bo);
1830 LIST_DEL(&buf_info->link);
1837 TBM_LOG_I("Dump End..\n");
1840 static pixman_format_code_t
1841 _tbm_surface_internal_pixman_format_get(tbm_format format)
1844 case TBM_FORMAT_ARGB8888:
1845 return PIXMAN_a8r8g8b8;
1846 case TBM_FORMAT_XRGB8888:
1847 return PIXMAN_x8r8g8b8;
1856 * This function supports only if a buffer has below formats.
1857 * - TBM_FORMAT_ARGB8888
1858 * - TBM_FORMAT_XRGB8888
1860 static tbm_surface_error_e
1861 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1862 int format, int src_stride, int src_w, int src_h,
1863 int dst_stride, int dst_w, int dst_h)
1865 pixman_image_t *src_img = NULL, *dst_img = NULL;
1866 pixman_format_code_t pixman_format;
1867 pixman_transform_t t;
1868 struct pixman_f_transform ft;
1869 double scale_x, scale_y;
1871 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1872 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1874 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1875 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1878 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1879 (uint32_t*)src_ptr, src_stride);
1880 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1883 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1884 (uint32_t*)dst_ptr, dst_stride);
1885 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1887 pixman_f_transform_init_identity(&ft);
1889 scale_x = (double)src_w / dst_w;
1890 scale_y = (double)src_h / dst_h;
1892 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
1893 pixman_f_transform_translate(&ft, NULL, 0, 0);
1894 pixman_transform_from_pixman_f_transform(&t, &ft);
1895 pixman_image_set_transform(src_img, &t);
1897 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
1898 0, 0, 0, 0, 0, 0, dst_w, dst_h);
1900 pixman_image_unref(src_img);
1901 pixman_image_unref(dst_img);
1903 return TBM_SURFACE_ERROR_NONE;
1907 pixman_image_unref(src_img);
1909 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1912 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
1913 #define KEY_LEN 5 // "_XXXX"
1914 #define KEYS_LEN KEY_LEN * MAX_BOS
1916 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
1918 char *keys, temp_key[KEY_LEN + 1];
1919 struct _tbm_surface *surf;
1923 _tbm_surface_mutex_lock();
1925 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1927 surf = (struct _tbm_surface *)surface;
1929 num_bos = surf->num_bos;
1930 if (num_bos > MAX_BOS)
1933 keys = calloc(KEYS_LEN + 1, sizeof(char));
1935 TBM_LOG_E("Failed to alloc memory");
1936 _tbm_surface_mutex_unlock();
1940 for (i = 0; i < num_bos; i++) {
1941 memset(temp_key, 0x00, KEY_LEN + 1);
1943 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
1944 strncat(keys, temp_key, KEY_LEN);
1947 _tbm_surface_mutex_unlock();
1952 static void _tbm_surface_internal_put_keys(char *keys)
1959 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1961 TBM_RETURN_IF_FAIL(surface != NULL);
1962 TBM_RETURN_IF_FAIL(type != NULL);
1964 tbm_surface_dump_buf_info *buf_info;
1965 struct list_head *next_link;
1966 tbm_surface_info_s info;
1967 tbm_bo_handle bo_handle;
1968 const char *postfix;
1975 next_link = g_dump_info->link->next;
1976 TBM_RETURN_IF_FAIL(next_link != NULL);
1978 if (next_link == &g_dump_info->surface_list) {
1979 next_link = next_link->next;
1980 TBM_RETURN_IF_FAIL(next_link != NULL);
1983 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1984 TBM_RETURN_IF_FAIL(buf_info != NULL);
1986 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1987 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1989 if (scale_factor > 0.0) {
1992 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
1993 TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n",
1994 _tbm_surface_internal_format_to_str(info.format));
1995 tbm_surface_unmap(surface);
1999 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2001 buf_info->info.width = info.width * scale_factor;
2002 buf_info->info.height = info.height * scale_factor;
2003 buf_info->info.format = info.format;
2004 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2005 buf_info->info.num_planes = 1;
2006 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2007 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2009 if (buf_info->info.size > buf_info->size) {
2010 TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2011 buf_info->info.size, buf_info->size);
2012 tbm_surface_unmap(surface);
2016 if (info.size > buf_info->size) {
2017 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
2018 info.size, buf_info->size);
2019 tbm_surface_unmap(surface);
2023 /* make the file information */
2024 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2027 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2028 postfix = dump_postfix[0];
2030 postfix = dump_postfix[1];
2032 keys = _tbm_surface_internal_get_keys(surface);
2034 TBM_LOG_E("fail to get keys");
2035 tbm_surface_unmap(surface);
2040 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2041 if (!bo_handle.ptr) {
2042 TBM_LOG_E("fail to map bo");
2043 _tbm_surface_internal_put_keys(keys);
2044 tbm_surface_unmap(surface);
2047 memset(bo_handle.ptr, 0x00, buf_info->size);
2049 switch (info.format) {
2050 case TBM_FORMAT_ARGB8888:
2051 case TBM_FORMAT_XRGB8888:
2052 snprintf(buf_info->name, sizeof(buf_info->name),
2053 "%10.3f_%03d%s_%p-%s.%s",
2054 _tbm_surface_internal_get_time(),
2055 g_dump_info->count++, keys, surface, type, postfix);
2057 if (scale_factor > 0.0) {
2058 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2060 buf_info->info.format,
2061 info.planes[0].stride,
2062 info.width, info.height,
2063 buf_info->info.planes[0].stride,
2064 buf_info->info.width,
2065 buf_info->info.height);
2066 if (ret != TBM_SURFACE_ERROR_NONE) {
2067 TBM_LOG_E("fail to scale buffer");
2068 tbm_bo_unmap(buf_info->bo);
2069 _tbm_surface_internal_put_keys(keys);
2070 tbm_surface_unmap(surface);
2074 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2076 case TBM_FORMAT_YVU420:
2077 case TBM_FORMAT_YUV420:
2078 snprintf(buf_info->name, sizeof(buf_info->name),
2079 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2080 _tbm_surface_internal_get_time(),
2081 g_dump_info->count++, keys, type, info.planes[0].stride,
2082 info.height, FOURCC_STR(info.format), postfix);
2083 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2084 bo_handle.ptr += info.planes[0].stride * info.height;
2085 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2086 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2087 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2089 case TBM_FORMAT_NV12:
2090 case TBM_FORMAT_NV21:
2091 snprintf(buf_info->name, sizeof(buf_info->name),
2092 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2093 _tbm_surface_internal_get_time(),
2094 g_dump_info->count++, keys, type, info.planes[0].stride,
2095 info.height, FOURCC_STR(info.format), postfix);
2096 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2097 bo_handle.ptr += info.planes[0].stride * info.height;
2098 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2100 case TBM_FORMAT_YUYV:
2101 case TBM_FORMAT_UYVY:
2102 snprintf(buf_info->name, sizeof(buf_info->name),
2103 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2104 _tbm_surface_internal_get_time(),
2105 g_dump_info->count++, keys, type, info.planes[0].stride,
2106 info.height, FOURCC_STR(info.format), postfix);
2107 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2110 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2111 tbm_bo_unmap(buf_info->bo);
2112 _tbm_surface_internal_put_keys(keys);
2113 tbm_surface_unmap(surface);
2117 tbm_bo_unmap(buf_info->bo);
2119 _tbm_surface_internal_put_keys(keys);
2121 tbm_surface_unmap(surface);
2123 buf_info->dirty = 1;
2124 buf_info->dirty_shm = 0;
2126 if (g_dump_info->count == 1000)
2127 g_dump_info->count = 0;
2129 g_dump_info->link = next_link;
2131 TBM_LOG_I("Dump %s \n", buf_info->name);
2134 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2137 TBM_RETURN_IF_FAIL(ptr != NULL);
2138 TBM_RETURN_IF_FAIL(w > 0);
2139 TBM_RETURN_IF_FAIL(h > 0);
2140 TBM_RETURN_IF_FAIL(stride > 0);
2141 TBM_RETURN_IF_FAIL(type != NULL);
2143 tbm_surface_dump_buf_info *buf_info;
2144 struct list_head *next_link;
2145 tbm_bo_handle bo_handle;
2146 int ret, size, dw = 0, dh = 0, dstride = 0;
2151 next_link = g_dump_info->link->next;
2152 TBM_RETURN_IF_FAIL(next_link != NULL);
2154 if (next_link == &g_dump_info->surface_list) {
2155 next_link = next_link->next;
2156 TBM_RETURN_IF_FAIL(next_link != NULL);
2159 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2160 TBM_RETURN_IF_FAIL(buf_info != NULL);
2162 if (scale_factor > 0.0) {
2165 dw = w * scale_factor;
2166 dh = h * scale_factor;
2168 size = dstride * dh;
2172 if (size > buf_info->size) {
2173 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2174 size, buf_info->size);
2179 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2180 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2182 memset(bo_handle.ptr, 0x00, buf_info->size);
2183 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2185 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2186 _tbm_surface_internal_get_time(),
2187 g_dump_info->count++, type, dump_postfix[0]);
2188 if (scale_factor > 0.0) {
2189 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2190 TBM_FORMAT_ARGB8888, stride,
2191 w, h, dstride, dw, dh);
2192 if (ret != TBM_SURFACE_ERROR_NONE) {
2193 TBM_LOG_E("fail to scale buffer");
2194 tbm_bo_unmap(buf_info->bo);
2197 buf_info->shm_stride = dstride;
2198 buf_info->shm_h = dh;
2200 memcpy(bo_handle.ptr, ptr, size);
2201 buf_info->shm_stride = stride;
2202 buf_info->shm_h = h;
2205 tbm_bo_unmap(buf_info->bo);
2207 buf_info->dirty = 0;
2208 buf_info->dirty_shm = 1;
2210 if (g_dump_info->count == 1000)
2211 g_dump_info->count = 0;
2213 g_dump_info->link = next_link;
2215 TBM_LOG_I("Dump %s \n", buf_info->name);
2219 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2221 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2222 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2223 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2225 tbm_surface_info_s info;
2226 const char *postfix;
2230 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2231 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2233 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2234 postfix = dump_postfix[0];
2236 postfix = dump_postfix[1];
2238 if (strcmp(postfix, type)) {
2239 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2240 tbm_surface_unmap(surface);
2244 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2246 if (!access(file, 0)) {
2247 TBM_LOG_E("can't capture buffer, exist file %s", file);
2248 tbm_surface_unmap(surface);
2252 switch (info.format) {
2253 case TBM_FORMAT_ARGB8888:
2254 case TBM_FORMAT_XRGB8888:
2255 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2256 info.planes[0].stride >> 2,
2259 case TBM_FORMAT_YVU420:
2260 case TBM_FORMAT_YUV420:
2261 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2262 info.planes[0].stride * info.height,
2264 info.planes[1].stride * (info.height >> 1),
2266 info.planes[2].stride * (info.height >> 1));
2268 case TBM_FORMAT_NV12:
2269 case TBM_FORMAT_NV21:
2270 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2271 info.planes[0].stride * info.height,
2273 info.planes[1].stride * (info.height >> 1),
2276 case TBM_FORMAT_YUYV:
2277 case TBM_FORMAT_UYVY:
2278 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2279 info.planes[0].stride * info.height,
2283 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2284 tbm_surface_unmap(surface);
2288 tbm_surface_unmap(surface);
2290 TBM_TRACE("Capture %s \n", file);
2296 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2297 const char *path, const char *name, const char *type)
2299 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2300 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2301 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2302 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2303 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2304 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2308 if (strcmp(dump_postfix[0], type)) {
2309 TBM_LOG_E("Not supported type:%s'", type);
2313 if (!access(file, 0)) {
2314 TBM_LOG_E("can't capture buffer, exist file %s", file);
2318 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2320 _tbm_surface_internal_dump_file_png(file, ptr, stride, h);
2322 TBM_TRACE("Capture %s \n", file);