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_get_info(tbm_surface, &info)) {
1698 TBM_LOG_E("tbm_surface_get_info fail\n");
1699 tbm_surface_destroy(tbm_surface);
1704 buffer_size = info.size;
1705 tbm_surface_destroy(tbm_surface);
1707 /* create dump lists */
1708 for (i = 0; i < count; i++) {
1711 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1712 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1714 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1716 TBM_LOG_E("fail to allocate the tbm_bo[%d]\n", i);
1721 buf_info->index = i;
1723 buf_info->size = buffer_size;
1725 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1728 g_dump_info->path = path;
1729 g_dump_info->link = &g_dump_info->surface_list;
1733 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1738 /* free resources */
1739 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1740 tbm_surface_dump_buf_info *tmp;
1742 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1743 tbm_bo_unref(buf_info->bo);
1744 LIST_DEL(&buf_info->link);
1749 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1758 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1765 tbm_surface_internal_dump_start(path, w, h, count);
1766 scale_factor = scale;
1770 tbm_surface_internal_dump_end(void)
1772 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1773 tbm_bo_handle bo_handle;
1778 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1785 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1788 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1789 if (bo_handle.ptr == NULL) {
1790 tbm_bo_unref(buf_info->bo);
1791 LIST_DEL(&buf_info->link);
1796 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1797 TBM_LOG_I("Dump File.. %s generated.\n", file);
1799 if (buf_info->dirty) {
1800 void *ptr1 = NULL, *ptr2 = NULL;
1802 switch (buf_info->info.format) {
1803 case TBM_FORMAT_ARGB8888:
1804 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1805 buf_info->info.planes[0].stride >> 2,
1806 buf_info->info.height, TBM_FORMAT_ARGB8888);
1808 case TBM_FORMAT_XRGB8888:
1809 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1810 buf_info->info.planes[0].stride >> 2,
1811 buf_info->info.height, TBM_FORMAT_XRGB8888);
1813 case TBM_FORMAT_YVU420:
1814 case TBM_FORMAT_YUV420:
1815 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1816 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1817 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1818 buf_info->info.planes[0].stride * buf_info->info.height,
1820 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1822 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1824 case TBM_FORMAT_NV12:
1825 case TBM_FORMAT_NV21:
1826 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1827 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1828 buf_info->info.planes[0].stride * buf_info->info.height,
1830 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1833 case TBM_FORMAT_YUYV:
1834 case TBM_FORMAT_UYVY:
1835 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1836 buf_info->info.planes[0].stride * buf_info->info.height,
1840 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1843 } else if (buf_info->dirty_shm)
1844 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1845 buf_info->shm_stride >> 2,
1846 buf_info->shm_h, 0);
1848 tbm_bo_unmap(buf_info->bo);
1849 tbm_bo_unref(buf_info->bo);
1850 LIST_DEL(&buf_info->link);
1857 TBM_LOG_I("Dump End..\n");
1860 static pixman_format_code_t
1861 _tbm_surface_internal_pixman_format_get(tbm_format format)
1864 case TBM_FORMAT_ARGB8888:
1865 return PIXMAN_a8r8g8b8;
1866 case TBM_FORMAT_XRGB8888:
1867 return PIXMAN_x8r8g8b8;
1876 * This function supports only if a buffer has below formats.
1877 * - TBM_FORMAT_ARGB8888
1878 * - TBM_FORMAT_XRGB8888
1880 static tbm_surface_error_e
1881 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1882 int format, int src_stride, int src_w, int src_h,
1883 int dst_stride, int dst_w, int dst_h)
1885 pixman_image_t *src_img = NULL, *dst_img = NULL;
1886 pixman_format_code_t pixman_format;
1887 pixman_transform_t t;
1888 struct pixman_f_transform ft;
1889 double scale_x, scale_y;
1891 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1892 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1894 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1895 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1898 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1899 (uint32_t*)src_ptr, src_stride);
1900 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1903 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1904 (uint32_t*)dst_ptr, dst_stride);
1905 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1907 pixman_f_transform_init_identity(&ft);
1909 scale_x = (double)src_w / dst_w;
1910 scale_y = (double)src_h / dst_h;
1912 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
1913 pixman_f_transform_translate(&ft, NULL, 0, 0);
1914 pixman_transform_from_pixman_f_transform(&t, &ft);
1915 pixman_image_set_transform(src_img, &t);
1917 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
1918 0, 0, 0, 0, 0, 0, dst_w, dst_h);
1920 pixman_image_unref(src_img);
1921 pixman_image_unref(dst_img);
1923 return TBM_SURFACE_ERROR_NONE;
1927 pixman_image_unref(src_img);
1929 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1932 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
1933 #define KEY_LEN 5 // "_XXXX"
1934 #define KEYS_LEN KEY_LEN * MAX_BOS
1936 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
1938 char *keys, temp_key[KEY_LEN + 1];
1939 struct _tbm_surface *surf;
1943 _tbm_surface_mutex_lock();
1945 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1947 surf = (struct _tbm_surface *)surface;
1949 num_bos = surf->num_bos;
1950 if (num_bos > MAX_BOS)
1953 keys = calloc(KEYS_LEN + 1, sizeof(char));
1955 TBM_LOG_E("Failed to alloc memory");
1956 _tbm_surface_mutex_unlock();
1960 for (i = 0; i < num_bos; i++) {
1961 memset(temp_key, 0x00, KEY_LEN + 1);
1963 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
1964 strncat(keys, temp_key, KEY_LEN);
1967 _tbm_surface_mutex_unlock();
1972 static void _tbm_surface_internal_put_keys(char *keys)
1979 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1981 TBM_RETURN_IF_FAIL(surface != NULL);
1982 TBM_RETURN_IF_FAIL(type != NULL);
1984 tbm_surface_dump_buf_info *buf_info;
1985 struct list_head *next_link;
1986 tbm_surface_info_s info;
1987 tbm_bo_handle bo_handle;
1988 const char *postfix;
1989 const char *format = NULL;
1996 next_link = g_dump_info->link->next;
1997 TBM_RETURN_IF_FAIL(next_link != NULL);
1999 if (next_link == &g_dump_info->surface_list) {
2000 next_link = next_link->next;
2001 TBM_RETURN_IF_FAIL(next_link != NULL);
2004 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2005 TBM_RETURN_IF_FAIL(buf_info != NULL);
2007 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2008 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2010 if (scale_factor > 0.0) {
2013 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2014 TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n",
2015 _tbm_surface_internal_format_to_str(info.format));
2016 tbm_surface_unmap(surface);
2020 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2022 buf_info->info.width = info.width * scale_factor;
2023 buf_info->info.height = info.height * scale_factor;
2024 buf_info->info.format = info.format;
2025 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2026 buf_info->info.num_planes = 1;
2027 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2028 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2030 if (buf_info->info.size > buf_info->size) {
2031 TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2032 buf_info->info.size, buf_info->size);
2033 tbm_surface_unmap(surface);
2037 if (info.size > buf_info->size) {
2038 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
2039 info.size, buf_info->size);
2040 tbm_surface_unmap(surface);
2044 /* make the file information */
2045 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2048 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2049 postfix = dump_postfix[0];
2050 format = _tbm_surface_internal_format_to_str(info.format);
2052 postfix = dump_postfix[1];
2054 keys = _tbm_surface_internal_get_keys(surface);
2056 TBM_LOG_E("fail to get keys");
2057 tbm_surface_unmap(surface);
2062 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2063 if (!bo_handle.ptr) {
2064 TBM_LOG_E("fail to map bo");
2065 _tbm_surface_internal_put_keys(keys);
2066 tbm_surface_unmap(surface);
2069 memset(bo_handle.ptr, 0x00, buf_info->size);
2071 switch (info.format) {
2072 case TBM_FORMAT_ARGB8888:
2073 case TBM_FORMAT_XRGB8888:
2074 snprintf(buf_info->name, sizeof(buf_info->name),
2075 "%10.3f_%03d%s_%p_%s-%s.%s",
2076 _tbm_surface_internal_get_time(),
2077 g_dump_info->count++, keys, surface, format, type, postfix);
2079 if (scale_factor > 0.0) {
2080 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2082 buf_info->info.format,
2083 info.planes[0].stride,
2084 info.width, info.height,
2085 buf_info->info.planes[0].stride,
2086 buf_info->info.width,
2087 buf_info->info.height);
2088 if (ret != TBM_SURFACE_ERROR_NONE) {
2089 TBM_LOG_E("fail to scale buffer");
2090 tbm_bo_unmap(buf_info->bo);
2091 _tbm_surface_internal_put_keys(keys);
2092 tbm_surface_unmap(surface);
2096 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2098 case TBM_FORMAT_YVU420:
2099 case TBM_FORMAT_YUV420:
2100 snprintf(buf_info->name, sizeof(buf_info->name),
2101 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2102 _tbm_surface_internal_get_time(),
2103 g_dump_info->count++, keys, type, info.planes[0].stride,
2104 info.height, FOURCC_STR(info.format), postfix);
2105 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2106 bo_handle.ptr += info.planes[0].stride * info.height;
2107 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2108 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2109 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2111 case TBM_FORMAT_NV12:
2112 case TBM_FORMAT_NV21:
2113 snprintf(buf_info->name, sizeof(buf_info->name),
2114 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2115 _tbm_surface_internal_get_time(),
2116 g_dump_info->count++, keys, type, info.planes[0].stride,
2117 info.height, FOURCC_STR(info.format), postfix);
2118 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2119 bo_handle.ptr += info.planes[0].stride * info.height;
2120 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2122 case TBM_FORMAT_YUYV:
2123 case TBM_FORMAT_UYVY:
2124 snprintf(buf_info->name, sizeof(buf_info->name),
2125 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2126 _tbm_surface_internal_get_time(),
2127 g_dump_info->count++, keys, type, info.planes[0].stride,
2128 info.height, FOURCC_STR(info.format), postfix);
2129 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2132 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2133 tbm_bo_unmap(buf_info->bo);
2134 _tbm_surface_internal_put_keys(keys);
2135 tbm_surface_unmap(surface);
2139 tbm_bo_unmap(buf_info->bo);
2141 _tbm_surface_internal_put_keys(keys);
2143 tbm_surface_unmap(surface);
2145 buf_info->dirty = 1;
2146 buf_info->dirty_shm = 0;
2148 if (g_dump_info->count == 1000)
2149 g_dump_info->count = 0;
2151 g_dump_info->link = next_link;
2153 TBM_LOG_I("Dump %s \n", buf_info->name);
2156 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2159 TBM_RETURN_IF_FAIL(ptr != NULL);
2160 TBM_RETURN_IF_FAIL(w > 0);
2161 TBM_RETURN_IF_FAIL(h > 0);
2162 TBM_RETURN_IF_FAIL(stride > 0);
2163 TBM_RETURN_IF_FAIL(type != NULL);
2165 tbm_surface_dump_buf_info *buf_info;
2166 struct list_head *next_link;
2167 tbm_bo_handle bo_handle;
2168 int ret, size, dw = 0, dh = 0, dstride = 0;
2173 next_link = g_dump_info->link->next;
2174 TBM_RETURN_IF_FAIL(next_link != NULL);
2176 if (next_link == &g_dump_info->surface_list) {
2177 next_link = next_link->next;
2178 TBM_RETURN_IF_FAIL(next_link != NULL);
2181 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2182 TBM_RETURN_IF_FAIL(buf_info != NULL);
2184 if (scale_factor > 0.0) {
2187 dw = w * scale_factor;
2188 dh = h * scale_factor;
2190 size = dstride * dh;
2194 if (size > buf_info->size) {
2195 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2196 size, buf_info->size);
2201 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2202 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2204 memset(bo_handle.ptr, 0x00, buf_info->size);
2205 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2207 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2208 _tbm_surface_internal_get_time(),
2209 g_dump_info->count++, type, dump_postfix[0]);
2210 if (scale_factor > 0.0) {
2211 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2212 TBM_FORMAT_ARGB8888, stride,
2213 w, h, dstride, dw, dh);
2214 if (ret != TBM_SURFACE_ERROR_NONE) {
2215 TBM_LOG_E("fail to scale buffer");
2216 tbm_bo_unmap(buf_info->bo);
2219 buf_info->shm_stride = dstride;
2220 buf_info->shm_h = dh;
2222 memcpy(bo_handle.ptr, ptr, size);
2223 buf_info->shm_stride = stride;
2224 buf_info->shm_h = h;
2227 tbm_bo_unmap(buf_info->bo);
2229 buf_info->dirty = 0;
2230 buf_info->dirty_shm = 1;
2232 if (g_dump_info->count == 1000)
2233 g_dump_info->count = 0;
2235 g_dump_info->link = next_link;
2237 TBM_LOG_I("Dump %s \n", buf_info->name);
2241 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2243 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2244 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2245 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2247 tbm_surface_info_s info;
2248 const char *postfix;
2252 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2253 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2255 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2256 postfix = dump_postfix[0];
2258 postfix = dump_postfix[1];
2260 if (strcmp(postfix, type)) {
2261 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2262 tbm_surface_unmap(surface);
2266 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2268 if (!access(file, 0)) {
2269 TBM_LOG_E("can't capture buffer, exist file %s", file);
2270 tbm_surface_unmap(surface);
2274 switch (info.format) {
2275 case TBM_FORMAT_ARGB8888:
2276 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2277 info.planes[0].stride >> 2,
2278 info.height, TBM_FORMAT_ARGB8888);
2280 case TBM_FORMAT_XRGB8888:
2281 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2282 info.planes[0].stride >> 2,
2283 info.height, TBM_FORMAT_XRGB8888);
2285 case TBM_FORMAT_YVU420:
2286 case TBM_FORMAT_YUV420:
2287 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2288 info.planes[0].stride * info.height,
2290 info.planes[1].stride * (info.height >> 1),
2292 info.planes[2].stride * (info.height >> 1));
2294 case TBM_FORMAT_NV12:
2295 case TBM_FORMAT_NV21:
2296 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2297 info.planes[0].stride * info.height,
2299 info.planes[1].stride * (info.height >> 1),
2302 case TBM_FORMAT_YUYV:
2303 case TBM_FORMAT_UYVY:
2304 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2305 info.planes[0].stride * info.height,
2309 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2310 tbm_surface_unmap(surface);
2314 tbm_surface_unmap(surface);
2316 TBM_TRACE("Capture %s \n", file);
2322 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2323 const char *path, const char *name, const char *type)
2325 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2326 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2327 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2328 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2329 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2330 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2334 if (strcmp(dump_postfix[0], type)) {
2335 TBM_LOG_E("Not supported type:%s'", type);
2339 if (!access(file, 0)) {
2340 TBM_LOG_E("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2344 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2346 _tbm_surface_internal_dump_file_png(file, ptr, stride, h, 0);
2348 TBM_TRACE("Capture %s \n", file);