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;
1992 const char *format = NULL;
1999 next_link = g_dump_info->link->next;
2000 TBM_RETURN_IF_FAIL(next_link != NULL);
2002 if (next_link == &g_dump_info->surface_list) {
2003 next_link = next_link->next;
2004 TBM_RETURN_IF_FAIL(next_link != NULL);
2007 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2008 TBM_RETURN_IF_FAIL(buf_info != NULL);
2010 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2011 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2013 if (scale_factor > 0.0) {
2016 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2017 TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n",
2018 _tbm_surface_internal_format_to_str(info.format));
2019 tbm_surface_unmap(surface);
2023 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2025 buf_info->info.width = info.width * scale_factor;
2026 buf_info->info.height = info.height * scale_factor;
2027 buf_info->info.format = info.format;
2028 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2029 buf_info->info.num_planes = 1;
2030 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2031 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2033 if (buf_info->info.size > buf_info->size) {
2034 TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2035 buf_info->info.size, buf_info->size);
2036 tbm_surface_unmap(surface);
2040 if (info.size > buf_info->size) {
2041 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
2042 info.size, buf_info->size);
2043 tbm_surface_unmap(surface);
2047 /* make the file information */
2048 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2051 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2052 postfix = dump_postfix[0];
2053 format = _tbm_surface_internal_format_to_str(info.format);
2055 postfix = dump_postfix[1];
2057 keys = _tbm_surface_internal_get_keys(surface);
2059 TBM_LOG_E("fail to get keys");
2060 tbm_surface_unmap(surface);
2065 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2066 if (!bo_handle.ptr) {
2067 TBM_LOG_E("fail to map bo");
2068 _tbm_surface_internal_put_keys(keys);
2069 tbm_surface_unmap(surface);
2072 memset(bo_handle.ptr, 0x00, buf_info->size);
2074 switch (info.format) {
2075 case TBM_FORMAT_ARGB8888:
2076 case TBM_FORMAT_XRGB8888:
2077 snprintf(buf_info->name, sizeof(buf_info->name),
2078 "%10.3f_%03d%s_%p_%s-%s.%s",
2079 _tbm_surface_internal_get_time(),
2080 g_dump_info->count++, keys, surface, format, type, postfix);
2082 if (scale_factor > 0.0) {
2083 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2085 buf_info->info.format,
2086 info.planes[0].stride,
2087 info.width, info.height,
2088 buf_info->info.planes[0].stride,
2089 buf_info->info.width,
2090 buf_info->info.height);
2091 if (ret != TBM_SURFACE_ERROR_NONE) {
2092 TBM_LOG_E("fail to scale buffer");
2093 tbm_bo_unmap(buf_info->bo);
2094 _tbm_surface_internal_put_keys(keys);
2095 tbm_surface_unmap(surface);
2099 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2101 case TBM_FORMAT_YVU420:
2102 case TBM_FORMAT_YUV420:
2103 snprintf(buf_info->name, sizeof(buf_info->name),
2104 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2105 _tbm_surface_internal_get_time(),
2106 g_dump_info->count++, keys, type, info.planes[0].stride,
2107 info.height, FOURCC_STR(info.format), postfix);
2108 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2109 bo_handle.ptr += info.planes[0].stride * info.height;
2110 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2111 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2112 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2114 case TBM_FORMAT_NV12:
2115 case TBM_FORMAT_NV21:
2116 snprintf(buf_info->name, sizeof(buf_info->name),
2117 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2118 _tbm_surface_internal_get_time(),
2119 g_dump_info->count++, keys, type, info.planes[0].stride,
2120 info.height, FOURCC_STR(info.format), postfix);
2121 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2122 bo_handle.ptr += info.planes[0].stride * info.height;
2123 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2125 case TBM_FORMAT_YUYV:
2126 case TBM_FORMAT_UYVY:
2127 snprintf(buf_info->name, sizeof(buf_info->name),
2128 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2129 _tbm_surface_internal_get_time(),
2130 g_dump_info->count++, keys, type, info.planes[0].stride,
2131 info.height, FOURCC_STR(info.format), postfix);
2132 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2135 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2136 tbm_bo_unmap(buf_info->bo);
2137 _tbm_surface_internal_put_keys(keys);
2138 tbm_surface_unmap(surface);
2142 tbm_bo_unmap(buf_info->bo);
2144 _tbm_surface_internal_put_keys(keys);
2146 tbm_surface_unmap(surface);
2148 buf_info->dirty = 1;
2149 buf_info->dirty_shm = 0;
2151 if (g_dump_info->count == 1000)
2152 g_dump_info->count = 0;
2154 g_dump_info->link = next_link;
2156 TBM_LOG_I("Dump %s \n", buf_info->name);
2159 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2162 TBM_RETURN_IF_FAIL(ptr != NULL);
2163 TBM_RETURN_IF_FAIL(w > 0);
2164 TBM_RETURN_IF_FAIL(h > 0);
2165 TBM_RETURN_IF_FAIL(stride > 0);
2166 TBM_RETURN_IF_FAIL(type != NULL);
2168 tbm_surface_dump_buf_info *buf_info;
2169 struct list_head *next_link;
2170 tbm_bo_handle bo_handle;
2171 int ret, size, dw = 0, dh = 0, dstride = 0;
2176 next_link = g_dump_info->link->next;
2177 TBM_RETURN_IF_FAIL(next_link != NULL);
2179 if (next_link == &g_dump_info->surface_list) {
2180 next_link = next_link->next;
2181 TBM_RETURN_IF_FAIL(next_link != NULL);
2184 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2185 TBM_RETURN_IF_FAIL(buf_info != NULL);
2187 if (scale_factor > 0.0) {
2190 dw = w * scale_factor;
2191 dh = h * scale_factor;
2193 size = dstride * dh;
2197 if (size > buf_info->size) {
2198 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2199 size, buf_info->size);
2204 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2205 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2207 memset(bo_handle.ptr, 0x00, buf_info->size);
2208 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2210 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2211 _tbm_surface_internal_get_time(),
2212 g_dump_info->count++, type, dump_postfix[0]);
2213 if (scale_factor > 0.0) {
2214 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2215 TBM_FORMAT_ARGB8888, stride,
2216 w, h, dstride, dw, dh);
2217 if (ret != TBM_SURFACE_ERROR_NONE) {
2218 TBM_LOG_E("fail to scale buffer");
2219 tbm_bo_unmap(buf_info->bo);
2222 buf_info->shm_stride = dstride;
2223 buf_info->shm_h = dh;
2225 memcpy(bo_handle.ptr, ptr, size);
2226 buf_info->shm_stride = stride;
2227 buf_info->shm_h = h;
2230 tbm_bo_unmap(buf_info->bo);
2232 buf_info->dirty = 0;
2233 buf_info->dirty_shm = 1;
2235 if (g_dump_info->count == 1000)
2236 g_dump_info->count = 0;
2238 g_dump_info->link = next_link;
2240 TBM_LOG_I("Dump %s \n", buf_info->name);
2244 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2246 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2247 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2248 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2250 tbm_surface_info_s info;
2251 const char *postfix;
2255 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2256 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2258 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2259 postfix = dump_postfix[0];
2261 postfix = dump_postfix[1];
2263 if (strcmp(postfix, type)) {
2264 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2265 tbm_surface_unmap(surface);
2269 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2271 if (!access(file, 0)) {
2272 TBM_LOG_E("can't capture buffer, exist file %s", file);
2273 tbm_surface_unmap(surface);
2277 switch (info.format) {
2278 case TBM_FORMAT_ARGB8888:
2279 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2280 info.planes[0].stride >> 2,
2281 info.height, TBM_FORMAT_ARGB8888);
2283 case TBM_FORMAT_XRGB8888:
2284 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2285 info.planes[0].stride >> 2,
2286 info.height, TBM_FORMAT_XRGB8888);
2288 case TBM_FORMAT_YVU420:
2289 case TBM_FORMAT_YUV420:
2290 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2291 info.planes[0].stride * info.height,
2293 info.planes[1].stride * (info.height >> 1),
2295 info.planes[2].stride * (info.height >> 1));
2297 case TBM_FORMAT_NV12:
2298 case TBM_FORMAT_NV21:
2299 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2300 info.planes[0].stride * info.height,
2302 info.planes[1].stride * (info.height >> 1),
2305 case TBM_FORMAT_YUYV:
2306 case TBM_FORMAT_UYVY:
2307 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2308 info.planes[0].stride * info.height,
2312 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2313 tbm_surface_unmap(surface);
2317 tbm_surface_unmap(surface);
2319 TBM_TRACE("Capture %s \n", file);
2325 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2326 const char *path, const char *name, const char *type)
2328 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2329 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2330 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2331 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2332 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2333 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2337 if (strcmp(dump_postfix[0], type)) {
2338 TBM_LOG_E("Not supported type:%s'", type);
2342 if (!access(file, 0)) {
2343 TBM_LOG_E("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2347 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2349 _tbm_surface_internal_dump_file_png(file, ptr, stride, h, 0);
2351 TBM_TRACE("Capture %s \n", file);