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, int format)
1556 unsigned int *blocks = (unsigned int *)data;
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 if (format == TBM_FORMAT_XRGB8888) {
1587 png_set_IHDR(pPngStruct,
1594 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1597 png_set_IHDR(pPngStruct,
1602 PNG_COLOR_TYPE_RGBA,
1604 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1607 png_set_bgr(pPngStruct);
1608 png_write_info(pPngStruct, pPngInfo);
1610 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1611 if (!row_pointers) {
1612 TBM_LOG_E("fail to allocate the png row_pointers.\n");
1613 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1618 for (y = 0; y < height; ++y) {
1622 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1624 TBM_LOG_E("fail to allocate the png row.\n");
1625 for (x = 0; x < y; x++)
1626 png_free(pPngStruct, row_pointers[x]);
1627 png_free(pPngStruct, row_pointers);
1628 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1632 row_pointers[y] = (png_bytep)row;
1634 for (x = 0; x < width; ++x) {
1635 unsigned int curBlock = blocks[y * width + x];
1637 if (pixel_size == 3) { // XRGB8888
1638 row[x * pixel_size] = (curBlock & 0xFF);
1639 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1640 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1641 } else { // ARGB8888
1642 row[x * pixel_size] = (curBlock & 0xFF);
1643 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1644 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1645 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1650 png_write_image(pPngStruct, row_pointers);
1651 png_write_end(pPngStruct, pPngInfo);
1653 for (y = 0; y < height; y++)
1654 png_free(pPngStruct, row_pointers[y]);
1655 png_free(pPngStruct, row_pointers);
1657 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1663 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1665 TBM_RETURN_IF_FAIL(path != NULL);
1666 TBM_RETURN_IF_FAIL(w > 0);
1667 TBM_RETURN_IF_FAIL(h > 0);
1668 TBM_RETURN_IF_FAIL(count > 0);
1670 tbm_surface_dump_buf_info *buf_info = NULL;
1671 tbm_surface_h tbm_surface;
1672 tbm_surface_info_s info;
1677 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1681 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1682 TBM_RETURN_IF_FAIL(g_dump_info);
1684 LIST_INITHEAD(&g_dump_info->surface_list);
1685 g_dump_info->count = 0;
1686 g_dump_info->dump_max = count;
1688 /* get buffer size */
1689 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1690 if (tbm_surface == NULL) {
1691 TBM_LOG_E("tbm_surface_create fail\n");
1697 if (TBM_SURFACE_ERROR_NONE != tbm_surface_map(tbm_surface,
1698 TBM_SURF_OPTION_READ, &info)) {
1699 TBM_LOG_E("tbm_surface_map fail\n");
1700 tbm_surface_destroy(tbm_surface);
1705 buffer_size = info.planes[0].stride * h;
1707 tbm_surface_unmap(tbm_surface);
1708 tbm_surface_destroy(tbm_surface);
1710 /* create dump lists */
1711 for (i = 0; i < count; i++) {
1714 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1715 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1717 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1719 TBM_LOG_E("fail to allocate the tbm_bo[%d]\n", i);
1724 buf_info->index = i;
1726 buf_info->size = buffer_size;
1728 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1731 g_dump_info->path = path;
1732 g_dump_info->link = &g_dump_info->surface_list;
1736 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1741 /* free resources */
1742 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1743 tbm_surface_dump_buf_info *tmp;
1745 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1746 tbm_bo_unref(buf_info->bo);
1747 LIST_DEL(&buf_info->link);
1752 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1761 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1768 tbm_surface_internal_dump_start(path, w, h, count);
1769 scale_factor = scale;
1773 tbm_surface_internal_dump_end(void)
1775 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1776 tbm_bo_handle bo_handle;
1781 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1788 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1791 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1792 if (bo_handle.ptr == NULL) {
1793 tbm_bo_unref(buf_info->bo);
1794 LIST_DEL(&buf_info->link);
1799 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1800 TBM_LOG_I("Dump File.. %s generated.\n", file);
1802 if (buf_info->dirty) {
1803 void *ptr1 = NULL, *ptr2 = NULL;
1805 switch (buf_info->info.format) {
1806 case TBM_FORMAT_ARGB8888:
1807 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1808 buf_info->info.planes[0].stride >> 2,
1809 buf_info->info.height, TBM_FORMAT_ARGB8888);
1811 case TBM_FORMAT_XRGB8888:
1812 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1813 buf_info->info.planes[0].stride >> 2,
1814 buf_info->info.height, TBM_FORMAT_XRGB8888);
1816 case TBM_FORMAT_YVU420:
1817 case TBM_FORMAT_YUV420:
1818 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1819 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1820 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1821 buf_info->info.planes[0].stride * buf_info->info.height,
1823 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1825 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1827 case TBM_FORMAT_NV12:
1828 case TBM_FORMAT_NV21:
1829 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1830 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1831 buf_info->info.planes[0].stride * buf_info->info.height,
1833 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1836 case TBM_FORMAT_YUYV:
1837 case TBM_FORMAT_UYVY:
1838 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1839 buf_info->info.planes[0].stride * buf_info->info.height,
1843 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1846 } else if (buf_info->dirty_shm)
1847 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1848 buf_info->shm_stride >> 2,
1849 buf_info->shm_h, 0);
1851 tbm_bo_unmap(buf_info->bo);
1852 tbm_bo_unref(buf_info->bo);
1853 LIST_DEL(&buf_info->link);
1860 TBM_LOG_I("Dump End..\n");
1863 static pixman_format_code_t
1864 _tbm_surface_internal_pixman_format_get(tbm_format format)
1867 case TBM_FORMAT_ARGB8888:
1868 return PIXMAN_a8r8g8b8;
1869 case TBM_FORMAT_XRGB8888:
1870 return PIXMAN_x8r8g8b8;
1879 * This function supports only if a buffer has below formats.
1880 * - TBM_FORMAT_ARGB8888
1881 * - TBM_FORMAT_XRGB8888
1883 static tbm_surface_error_e
1884 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1885 int format, int src_stride, int src_w, int src_h,
1886 int dst_stride, int dst_w, int dst_h)
1888 pixman_image_t *src_img = NULL, *dst_img = NULL;
1889 pixman_format_code_t pixman_format;
1890 pixman_transform_t t;
1891 struct pixman_f_transform ft;
1892 double scale_x, scale_y;
1894 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1895 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1897 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1898 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1901 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1902 (uint32_t*)src_ptr, src_stride);
1903 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1906 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1907 (uint32_t*)dst_ptr, dst_stride);
1908 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1910 pixman_f_transform_init_identity(&ft);
1912 scale_x = (double)src_w / dst_w;
1913 scale_y = (double)src_h / dst_h;
1915 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
1916 pixman_f_transform_translate(&ft, NULL, 0, 0);
1917 pixman_transform_from_pixman_f_transform(&t, &ft);
1918 pixman_image_set_transform(src_img, &t);
1920 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
1921 0, 0, 0, 0, 0, 0, dst_w, dst_h);
1923 pixman_image_unref(src_img);
1924 pixman_image_unref(dst_img);
1926 return TBM_SURFACE_ERROR_NONE;
1930 pixman_image_unref(src_img);
1932 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1935 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
1936 #define KEY_LEN 5 // "_XXXX"
1937 #define KEYS_LEN KEY_LEN * MAX_BOS
1939 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
1941 char *keys, temp_key[KEY_LEN + 1];
1942 struct _tbm_surface *surf;
1946 _tbm_surface_mutex_lock();
1948 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1950 surf = (struct _tbm_surface *)surface;
1952 num_bos = surf->num_bos;
1953 if (num_bos > MAX_BOS)
1956 keys = calloc(KEYS_LEN + 1, sizeof(char));
1958 TBM_LOG_E("Failed to alloc memory");
1959 _tbm_surface_mutex_unlock();
1963 for (i = 0; i < num_bos; i++) {
1964 memset(temp_key, 0x00, KEY_LEN + 1);
1966 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
1967 strncat(keys, temp_key, KEY_LEN);
1970 _tbm_surface_mutex_unlock();
1975 static void _tbm_surface_internal_put_keys(char *keys)
1982 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1984 TBM_RETURN_IF_FAIL(surface != NULL);
1985 TBM_RETURN_IF_FAIL(type != NULL);
1987 tbm_surface_dump_buf_info *buf_info;
1988 struct list_head *next_link;
1989 tbm_surface_info_s info;
1990 tbm_bo_handle bo_handle;
1991 const char *postfix;
1998 next_link = g_dump_info->link->next;
1999 TBM_RETURN_IF_FAIL(next_link != NULL);
2001 if (next_link == &g_dump_info->surface_list) {
2002 next_link = next_link->next;
2003 TBM_RETURN_IF_FAIL(next_link != NULL);
2006 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2007 TBM_RETURN_IF_FAIL(buf_info != NULL);
2009 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2010 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2012 if (scale_factor > 0.0) {
2015 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2016 TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n",
2017 _tbm_surface_internal_format_to_str(info.format));
2018 tbm_surface_unmap(surface);
2022 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2024 buf_info->info.width = info.width * scale_factor;
2025 buf_info->info.height = info.height * scale_factor;
2026 buf_info->info.format = info.format;
2027 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2028 buf_info->info.num_planes = 1;
2029 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2030 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2032 if (buf_info->info.size > buf_info->size) {
2033 TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2034 buf_info->info.size, buf_info->size);
2035 tbm_surface_unmap(surface);
2039 if (info.size > buf_info->size) {
2040 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
2041 info.size, buf_info->size);
2042 tbm_surface_unmap(surface);
2046 /* make the file information */
2047 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2050 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2051 postfix = dump_postfix[0];
2053 postfix = dump_postfix[1];
2055 keys = _tbm_surface_internal_get_keys(surface);
2057 TBM_LOG_E("fail to get keys");
2058 tbm_surface_unmap(surface);
2063 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2064 if (!bo_handle.ptr) {
2065 TBM_LOG_E("fail to map bo");
2066 _tbm_surface_internal_put_keys(keys);
2067 tbm_surface_unmap(surface);
2070 memset(bo_handle.ptr, 0x00, buf_info->size);
2072 switch (info.format) {
2073 case TBM_FORMAT_ARGB8888:
2074 case TBM_FORMAT_XRGB8888:
2075 snprintf(buf_info->name, sizeof(buf_info->name),
2076 "%10.3f_%03d%s_%p-%s.%s",
2077 _tbm_surface_internal_get_time(),
2078 g_dump_info->count++, keys, surface, type, postfix);
2080 if (scale_factor > 0.0) {
2081 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2083 buf_info->info.format,
2084 info.planes[0].stride,
2085 info.width, info.height,
2086 buf_info->info.planes[0].stride,
2087 buf_info->info.width,
2088 buf_info->info.height);
2089 if (ret != TBM_SURFACE_ERROR_NONE) {
2090 TBM_LOG_E("fail to scale buffer");
2091 tbm_bo_unmap(buf_info->bo);
2092 _tbm_surface_internal_put_keys(keys);
2093 tbm_surface_unmap(surface);
2097 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2099 case TBM_FORMAT_YVU420:
2100 case TBM_FORMAT_YUV420:
2101 snprintf(buf_info->name, sizeof(buf_info->name),
2102 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2103 _tbm_surface_internal_get_time(),
2104 g_dump_info->count++, keys, type, info.planes[0].stride,
2105 info.height, FOURCC_STR(info.format), postfix);
2106 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2107 bo_handle.ptr += info.planes[0].stride * info.height;
2108 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2109 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2110 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2112 case TBM_FORMAT_NV12:
2113 case TBM_FORMAT_NV21:
2114 snprintf(buf_info->name, sizeof(buf_info->name),
2115 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2116 _tbm_surface_internal_get_time(),
2117 g_dump_info->count++, keys, type, info.planes[0].stride,
2118 info.height, FOURCC_STR(info.format), postfix);
2119 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2120 bo_handle.ptr += info.planes[0].stride * info.height;
2121 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2123 case TBM_FORMAT_YUYV:
2124 case TBM_FORMAT_UYVY:
2125 snprintf(buf_info->name, sizeof(buf_info->name),
2126 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2127 _tbm_surface_internal_get_time(),
2128 g_dump_info->count++, keys, type, info.planes[0].stride,
2129 info.height, FOURCC_STR(info.format), postfix);
2130 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2133 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2134 tbm_bo_unmap(buf_info->bo);
2135 _tbm_surface_internal_put_keys(keys);
2136 tbm_surface_unmap(surface);
2140 tbm_bo_unmap(buf_info->bo);
2142 _tbm_surface_internal_put_keys(keys);
2144 tbm_surface_unmap(surface);
2146 buf_info->dirty = 1;
2147 buf_info->dirty_shm = 0;
2149 if (g_dump_info->count == 1000)
2150 g_dump_info->count = 0;
2152 g_dump_info->link = next_link;
2154 TBM_LOG_I("Dump %s \n", buf_info->name);
2157 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2160 TBM_RETURN_IF_FAIL(ptr != NULL);
2161 TBM_RETURN_IF_FAIL(w > 0);
2162 TBM_RETURN_IF_FAIL(h > 0);
2163 TBM_RETURN_IF_FAIL(stride > 0);
2164 TBM_RETURN_IF_FAIL(type != NULL);
2166 tbm_surface_dump_buf_info *buf_info;
2167 struct list_head *next_link;
2168 tbm_bo_handle bo_handle;
2169 int ret, size, dw = 0, dh = 0, dstride = 0;
2174 next_link = g_dump_info->link->next;
2175 TBM_RETURN_IF_FAIL(next_link != NULL);
2177 if (next_link == &g_dump_info->surface_list) {
2178 next_link = next_link->next;
2179 TBM_RETURN_IF_FAIL(next_link != NULL);
2182 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2183 TBM_RETURN_IF_FAIL(buf_info != NULL);
2185 if (scale_factor > 0.0) {
2188 dw = w * scale_factor;
2189 dh = h * scale_factor;
2191 size = dstride * dh;
2195 if (size > buf_info->size) {
2196 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2197 size, buf_info->size);
2202 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2203 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2205 memset(bo_handle.ptr, 0x00, buf_info->size);
2206 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2208 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2209 _tbm_surface_internal_get_time(),
2210 g_dump_info->count++, type, dump_postfix[0]);
2211 if (scale_factor > 0.0) {
2212 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2213 TBM_FORMAT_ARGB8888, stride,
2214 w, h, dstride, dw, dh);
2215 if (ret != TBM_SURFACE_ERROR_NONE) {
2216 TBM_LOG_E("fail to scale buffer");
2217 tbm_bo_unmap(buf_info->bo);
2220 buf_info->shm_stride = dstride;
2221 buf_info->shm_h = dh;
2223 memcpy(bo_handle.ptr, ptr, size);
2224 buf_info->shm_stride = stride;
2225 buf_info->shm_h = h;
2228 tbm_bo_unmap(buf_info->bo);
2230 buf_info->dirty = 0;
2231 buf_info->dirty_shm = 1;
2233 if (g_dump_info->count == 1000)
2234 g_dump_info->count = 0;
2236 g_dump_info->link = next_link;
2238 TBM_LOG_I("Dump %s \n", buf_info->name);
2242 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2244 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2245 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2246 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2248 tbm_surface_info_s info;
2249 const char *postfix;
2253 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2254 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2256 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2257 postfix = dump_postfix[0];
2259 postfix = dump_postfix[1];
2261 if (strcmp(postfix, type)) {
2262 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2263 tbm_surface_unmap(surface);
2267 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2269 if (!access(file, 0)) {
2270 TBM_LOG_E("can't capture buffer, exist file %s", file);
2271 tbm_surface_unmap(surface);
2275 switch (info.format) {
2276 case TBM_FORMAT_ARGB8888:
2277 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2278 info.planes[0].stride >> 2,
2279 info.height, TBM_FORMAT_ARGB8888);
2281 case TBM_FORMAT_XRGB8888:
2282 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2283 info.planes[0].stride >> 2,
2284 info.height, TBM_FORMAT_XRGB8888);
2286 case TBM_FORMAT_YVU420:
2287 case TBM_FORMAT_YUV420:
2288 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2289 info.planes[0].stride * info.height,
2291 info.planes[1].stride * (info.height >> 1),
2293 info.planes[2].stride * (info.height >> 1));
2295 case TBM_FORMAT_NV12:
2296 case TBM_FORMAT_NV21:
2297 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2298 info.planes[0].stride * info.height,
2300 info.planes[1].stride * (info.height >> 1),
2303 case TBM_FORMAT_YUYV:
2304 case TBM_FORMAT_UYVY:
2305 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2306 info.planes[0].stride * info.height,
2310 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2311 tbm_surface_unmap(surface);
2315 tbm_surface_unmap(surface);
2317 TBM_TRACE("Capture %s \n", file);
2323 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2324 const char *path, const char *name, const char *type)
2326 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2327 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2328 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2329 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2330 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2331 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2335 if (strcmp(dump_postfix[0], type)) {
2336 TBM_LOG_E("Not supported type:%s'", type);
2340 if (!access(file, 0)) {
2341 TBM_LOG_E("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2345 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2347 _tbm_surface_internal_dump_file_png(file, ptr, stride, h, 0);
2349 TBM_TRACE("Capture %s \n", file);