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();
372 /* LCOV_EXCL_START */
374 _tbm_surface_check_file_is_symbolic_link(const char* path)
381 if (stat(path, &sb) != 0)
384 if (S_ISLNK(sb.st_mode))
392 tbm_surface_internal_is_valid(tbm_surface_h surface)
396 _tbm_surface_mutex_lock();
398 /* Return silently if surface is null. */
400 _tbm_surface_mutex_unlock();
404 ret = _tbm_surface_internal_is_valid(surface);
406 _tbm_surface_mutex_unlock();
412 tbm_surface_internal_query_supported_formats(uint32_t **formats,
415 TBM_RETURN_VAL_IF_FAIL(formats, 0);
416 TBM_RETURN_VAL_IF_FAIL(num, 0);
418 struct _tbm_bufmgr *mgr;
420 bool bufmgr_initialized = false;
422 _tbm_surface_mutex_lock();
424 if (!g_surface_bufmgr) {
425 _init_surface_bufmgr();
426 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
427 bufmgr_initialized = true;
430 mgr = g_surface_bufmgr;
432 if (!mgr->backend->surface_supported_format)
435 ret = mgr->backend->surface_supported_format(formats, num);
437 /* LCOV_EXCL_START */
438 TBM_LOG_E("Fail to surface_supported_format.\n");
440 /* LCOV_EXCL_START */
443 TBM_TRACE("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
445 _tbm_surface_mutex_unlock();
449 /* LCOV_EXCL_START */
451 if (bufmgr_initialized) {
452 LIST_DELINIT(&g_surface_bufmgr->surf_list);
453 _deinit_surface_bufmgr();
455 _tbm_surface_mutex_unlock();
457 TBM_LOG_E("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
464 tbm_surface_internal_get_num_planes(tbm_format format)
470 case TBM_FORMAT_RGB332:
471 case TBM_FORMAT_BGR233:
472 case TBM_FORMAT_XRGB4444:
473 case TBM_FORMAT_XBGR4444:
474 case TBM_FORMAT_RGBX4444:
475 case TBM_FORMAT_BGRX4444:
476 case TBM_FORMAT_ARGB4444:
477 case TBM_FORMAT_ABGR4444:
478 case TBM_FORMAT_RGBA4444:
479 case TBM_FORMAT_BGRA4444:
480 case TBM_FORMAT_XRGB1555:
481 case TBM_FORMAT_XBGR1555:
482 case TBM_FORMAT_RGBX5551:
483 case TBM_FORMAT_BGRX5551:
484 case TBM_FORMAT_ARGB1555:
485 case TBM_FORMAT_ABGR1555:
486 case TBM_FORMAT_RGBA5551:
487 case TBM_FORMAT_BGRA5551:
488 case TBM_FORMAT_RGB565:
489 case TBM_FORMAT_BGR565:
490 case TBM_FORMAT_RGB888:
491 case TBM_FORMAT_BGR888:
492 case TBM_FORMAT_XRGB8888:
493 case TBM_FORMAT_XBGR8888:
494 case TBM_FORMAT_RGBX8888:
495 case TBM_FORMAT_BGRX8888:
496 case TBM_FORMAT_ARGB8888:
497 case TBM_FORMAT_ABGR8888:
498 case TBM_FORMAT_RGBA8888:
499 case TBM_FORMAT_BGRA8888:
500 case TBM_FORMAT_XRGB2101010:
501 case TBM_FORMAT_XBGR2101010:
502 case TBM_FORMAT_RGBX1010102:
503 case TBM_FORMAT_BGRX1010102:
504 case TBM_FORMAT_ARGB2101010:
505 case TBM_FORMAT_ABGR2101010:
506 case TBM_FORMAT_RGBA1010102:
507 case TBM_FORMAT_BGRA1010102:
508 case TBM_FORMAT_YUYV:
509 case TBM_FORMAT_YVYU:
510 case TBM_FORMAT_UYVY:
511 case TBM_FORMAT_VYUY:
512 case TBM_FORMAT_AYUV:
515 case TBM_FORMAT_NV12:
516 case TBM_FORMAT_NV12MT:
517 case TBM_FORMAT_NV21:
518 case TBM_FORMAT_NV16:
519 case TBM_FORMAT_NV61:
522 case TBM_FORMAT_YUV410:
523 case TBM_FORMAT_YVU410:
524 case TBM_FORMAT_YUV411:
525 case TBM_FORMAT_YVU411:
526 case TBM_FORMAT_YUV420:
527 case TBM_FORMAT_YVU420:
528 case TBM_FORMAT_YUV422:
529 case TBM_FORMAT_YVU422:
530 case TBM_FORMAT_YUV444:
531 case TBM_FORMAT_YVU444:
539 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
545 tbm_surface_internal_get_bpp(tbm_format format)
552 case TBM_FORMAT_RGB332:
553 case TBM_FORMAT_BGR233:
556 case TBM_FORMAT_XRGB4444:
557 case TBM_FORMAT_XBGR4444:
558 case TBM_FORMAT_RGBX4444:
559 case TBM_FORMAT_BGRX4444:
560 case TBM_FORMAT_ARGB4444:
561 case TBM_FORMAT_ABGR4444:
562 case TBM_FORMAT_RGBA4444:
563 case TBM_FORMAT_BGRA4444:
564 case TBM_FORMAT_XRGB1555:
565 case TBM_FORMAT_XBGR1555:
566 case TBM_FORMAT_RGBX5551:
567 case TBM_FORMAT_BGRX5551:
568 case TBM_FORMAT_ARGB1555:
569 case TBM_FORMAT_ABGR1555:
570 case TBM_FORMAT_RGBA5551:
571 case TBM_FORMAT_BGRA5551:
572 case TBM_FORMAT_RGB565:
573 case TBM_FORMAT_BGR565:
576 case TBM_FORMAT_RGB888:
577 case TBM_FORMAT_BGR888:
580 case TBM_FORMAT_XRGB8888:
581 case TBM_FORMAT_XBGR8888:
582 case TBM_FORMAT_RGBX8888:
583 case TBM_FORMAT_BGRX8888:
584 case TBM_FORMAT_ARGB8888:
585 case TBM_FORMAT_ABGR8888:
586 case TBM_FORMAT_RGBA8888:
587 case TBM_FORMAT_BGRA8888:
588 case TBM_FORMAT_XRGB2101010:
589 case TBM_FORMAT_XBGR2101010:
590 case TBM_FORMAT_RGBX1010102:
591 case TBM_FORMAT_BGRX1010102:
592 case TBM_FORMAT_ARGB2101010:
593 case TBM_FORMAT_ABGR2101010:
594 case TBM_FORMAT_RGBA1010102:
595 case TBM_FORMAT_BGRA1010102:
596 case TBM_FORMAT_YUYV:
597 case TBM_FORMAT_YVYU:
598 case TBM_FORMAT_UYVY:
599 case TBM_FORMAT_VYUY:
600 case TBM_FORMAT_AYUV:
603 case TBM_FORMAT_NV12:
604 case TBM_FORMAT_NV12MT:
605 case TBM_FORMAT_NV21:
608 case TBM_FORMAT_NV16:
609 case TBM_FORMAT_NV61:
612 case TBM_FORMAT_YUV410:
613 case TBM_FORMAT_YVU410:
616 case TBM_FORMAT_YUV411:
617 case TBM_FORMAT_YVU411:
618 case TBM_FORMAT_YUV420:
619 case TBM_FORMAT_YVU420:
622 case TBM_FORMAT_YUV422:
623 case TBM_FORMAT_YVU422:
626 case TBM_FORMAT_YUV444:
627 case TBM_FORMAT_YVU444:
634 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
640 tbm_surface_internal_create_with_flags(int width, int height,
641 int format, int flags)
643 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
644 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
646 struct _tbm_bufmgr *mgr;
647 struct _tbm_surface *surf = NULL;
651 uint32_t bo_size = 0;
654 bool bufmgr_initialized = false;
656 _tbm_surface_mutex_lock();
658 if (!g_surface_bufmgr) {
659 _init_surface_bufmgr();
660 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
661 bufmgr_initialized = true;
664 mgr = g_surface_bufmgr;
665 if (!TBM_BUFMGR_IS_VALID(mgr)) {
666 TBM_LOG_E("The bufmgr is invalid\n");
667 goto check_valid_fail;
670 surf = calloc(1, sizeof(struct _tbm_surface));
672 /* LCOV_EXCL_START */
673 TBM_LOG_E("fail to alloc surf\n");
674 goto alloc_surf_fail;
679 surf->info.width = width;
680 surf->info.height = height;
681 surf->info.format = format;
682 surf->info.bpp = tbm_surface_internal_get_bpp(format);
683 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
686 /* get size, stride and offset bo_idx */
687 for (i = 0; i < surf->info.num_planes; i++) {
688 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
689 &offset, &stride, &bo_idx)) {
690 TBM_LOG_E("fail to query plane data\n");
691 goto query_plane_data_fail;
694 surf->info.planes[i].size = size;
695 surf->info.planes[i].offset = offset;
696 surf->info.planes[i].stride = stride;
697 surf->planes_bo_idx[i] = bo_idx;
702 for (i = 0; i < surf->info.num_planes; i++) {
703 surf->info.size += surf->info.planes[i].size;
705 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
706 surf->num_bos = surf->planes_bo_idx[i] + 1;
711 for (i = 0; i < surf->num_bos; i++) {
713 for (j = 0; j < surf->info.num_planes; j++) {
714 if (surf->planes_bo_idx[j] == i)
715 bo_size += surf->info.planes[j].size;
718 if (mgr->backend->surface_bo_alloc) {
719 /* LCOV_EXCL_START */
721 void *bo_priv = NULL;
723 bo = calloc(1, sizeof(struct _tbm_bo));
725 TBM_LOG_E("fail to alloc bo struct\n");
729 bo->bufmgr = surf->bufmgr;
731 pthread_mutex_lock(&surf->bufmgr->lock);
733 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
735 TBM_LOG_E("fail to alloc bo priv\n");
737 pthread_mutex_unlock(&surf->bufmgr->lock);
745 LIST_INITHEAD(&bo->user_data_list);
747 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
749 pthread_mutex_unlock(&surf->bufmgr->lock);
754 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
756 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
761 _tbm_bo_set_surface(surf->bos[i], surf);
764 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
765 _tbm_surface_internal_format_to_str(format), flags, surf);
767 LIST_INITHEAD(&surf->user_data_list);
768 LIST_INITHEAD(&surf->debug_data_list);
770 LIST_ADD(&surf->item_link, &mgr->surf_list);
772 _tbm_surface_mutex_unlock();
776 /* LCOV_EXCL_START */
778 for (j = 0; j < i; j++) {
780 tbm_bo_unref(surf->bos[j]);
782 query_plane_data_fail:
786 if (bufmgr_initialized && mgr) {
787 LIST_DELINIT(&mgr->surf_list);
788 _deinit_surface_bufmgr();
790 _tbm_surface_mutex_unlock();
792 TBM_LOG_E("error: width(%d) height(%d) format(%s) flags(%d)\n",
794 _tbm_surface_internal_format_to_str(format), flags);
801 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
802 tbm_bo *bos, int num)
804 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
805 TBM_RETURN_VAL_IF_FAIL(info, NULL);
806 TBM_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
807 TBM_RETURN_VAL_IF_FAIL(num > 0, NULL);
808 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
810 struct _tbm_bufmgr *mgr;
811 struct _tbm_surface *surf = NULL;
813 bool bufmgr_initialized = false;
815 _tbm_surface_mutex_lock();
817 if (!g_surface_bufmgr) {
818 _init_surface_bufmgr();
819 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
820 bufmgr_initialized = true;
823 mgr = g_surface_bufmgr;
824 if (!TBM_BUFMGR_IS_VALID(mgr)) {
825 TBM_LOG_E("fail to validate the Bufmgr.\n");
826 goto check_valid_fail;
829 surf = calloc(1, sizeof(struct _tbm_surface));
831 /* LCOV_EXCL_START */
832 TBM_LOG_E("fail to allocate struct _tbm_surface.\n");
833 goto alloc_surf_fail;
838 surf->info.width = info->width;
839 surf->info.height = info->height;
840 surf->info.format = info->format;
842 surf->info.bpp = info->bpp;
844 surf->info.bpp = tbm_surface_internal_get_bpp(info->format);
845 surf->info.num_planes = info->num_planes;
848 /* get size, stride and offset */
849 for (i = 0; i < info->num_planes; i++) {
850 surf->info.planes[i].offset = info->planes[i].offset;
851 surf->info.planes[i].stride = info->planes[i].stride;
853 if (info->planes[i].size > 0)
854 surf->info.planes[i].size = info->planes[i].size;
856 uint32_t size = 0, offset = 0, stride = 0;
859 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
860 surf->info.planes[i].size = size;
864 surf->planes_bo_idx[i] = 0;
866 surf->planes_bo_idx[i] = i;
869 if (info->size > 0) {
870 surf->info.size = info->size;
873 for (i = 0; i < info->num_planes; i++)
874 surf->info.size += surf->info.planes[i].size;
877 surf->flags = TBM_BO_DEFAULT;
879 /* create only one bo */
881 for (i = 0; i < num; i++) {
882 if (bos[i] == NULL) {
883 TBM_LOG_E("bos[%d] is null.\n", i);
887 surf->bos[i] = tbm_bo_ref(bos[i]);
888 _tbm_bo_set_surface(bos[i], surf);
891 TBM_TRACE("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
892 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
894 LIST_INITHEAD(&surf->user_data_list);
895 LIST_INITHEAD(&surf->debug_data_list);
897 LIST_ADD(&surf->item_link, &mgr->surf_list);
899 _tbm_surface_mutex_unlock();
903 /* LCOV_EXCL_START */
905 for (i = 0; i < num; i++) {
907 tbm_bo_unref(surf->bos[i]);
912 if (bufmgr_initialized && mgr) {
913 LIST_DELINIT(&mgr->surf_list);
914 _deinit_surface_bufmgr();
916 _tbm_surface_mutex_unlock();
918 TBM_LOG_E("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
919 info->width, info->height,
920 _tbm_surface_internal_format_to_str(info->format), num);
927 tbm_surface_internal_destroy(tbm_surface_h surface)
929 _tbm_surface_mutex_lock();
931 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
935 if (surface->refcnt > 0) {
936 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
937 _tbm_surface_mutex_unlock();
941 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
943 if (surface->refcnt == 0)
944 _tbm_surface_internal_destroy(surface);
946 _tbm_surface_mutex_unlock();
950 tbm_surface_internal_ref(tbm_surface_h surface)
952 _tbm_surface_mutex_lock();
954 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
958 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
960 _tbm_surface_mutex_unlock();
964 tbm_surface_internal_unref(tbm_surface_h surface)
966 _tbm_surface_mutex_lock();
968 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
972 if (surface->refcnt > 0) {
973 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
974 _tbm_surface_mutex_unlock();
978 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
980 if (surface->refcnt == 0)
981 _tbm_surface_internal_destroy(surface);
983 _tbm_surface_mutex_unlock();
987 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
989 struct _tbm_surface *surf;
992 _tbm_surface_mutex_lock();
994 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
996 surf = (struct _tbm_surface *)surface;
999 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
1001 _tbm_surface_mutex_unlock();
1007 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1009 struct _tbm_surface *surf;
1012 _tbm_surface_mutex_lock();
1014 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1015 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1017 surf = (struct _tbm_surface *)surface;
1018 bo = surf->bos[bo_idx];
1020 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1022 _tbm_surface_mutex_unlock();
1028 tbm_surface_internal_get_size(tbm_surface_h surface)
1030 struct _tbm_surface *surf;
1033 _tbm_surface_mutex_lock();
1035 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1037 surf = (struct _tbm_surface *)surface;
1038 size = surf->info.size;
1040 TBM_TRACE("tbm_surface(%p) size(%u)\n", surface, size);
1042 _tbm_surface_mutex_unlock();
1048 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1049 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1051 struct _tbm_surface *surf;
1053 _tbm_surface_mutex_lock();
1055 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1056 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1058 surf = (struct _tbm_surface *)surface;
1060 if (plane_idx >= surf->info.num_planes) {
1061 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1062 _tbm_surface_mutex_unlock();
1067 *size = surf->info.planes[plane_idx].size;
1070 *offset = surf->info.planes[plane_idx].offset;
1073 *pitch = surf->info.planes[plane_idx].stride;
1075 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1076 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1077 surf->info.planes[plane_idx].stride);
1079 _tbm_surface_mutex_unlock();
1085 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1086 tbm_surface_info_s *info, int map)
1088 struct _tbm_surface *surf;
1089 tbm_bo_handle bo_handles[4];
1092 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1095 _tbm_surface_mutex_lock();
1097 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1099 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1101 surf = (struct _tbm_surface *)surface;
1103 memset(info, 0x00, sizeof(tbm_surface_info_s));
1104 info->width = surf->info.width;
1105 info->height = surf->info.height;
1106 info->format = surf->info.format;
1107 info->bpp = surf->info.bpp;
1108 info->size = surf->info.size;
1109 info->num_planes = surf->info.num_planes;
1111 for (i = 0; i < surf->info.num_planes; i++) {
1112 info->planes[i].size = surf->info.planes[i].size;
1113 info->planes[i].offset = surf->info.planes[i].offset;
1114 info->planes[i].stride = surf->info.planes[i].stride;
1115 planes_bo_idx[i] = surf->planes_bo_idx[i];
1118 for (i = 0; i < surf->num_bos; i++)
1119 bos[i] = surf->bos[i];
1121 num_bos = surf->num_bos;
1124 _tbm_surface_mutex_unlock();
1125 for (i = 0; i < num_bos; i++) {
1126 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1127 if (bo_handles[i].ptr == NULL) {
1128 for (j = 0; j < i; j++)
1129 tbm_bo_unmap(bos[j]);
1131 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1135 _tbm_surface_mutex_lock();
1137 for (i = 0; i < num_bos; i++) {
1138 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1139 if (bo_handles[i].ptr == NULL) {
1140 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1141 _tbm_surface_mutex_unlock();
1147 for (i = 0; i < info->num_planes; i++) {
1148 if (bo_handles[planes_bo_idx[i]].ptr)
1149 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1152 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1154 _tbm_surface_mutex_unlock();
1160 tbm_surface_internal_unmap(tbm_surface_h surface)
1162 struct _tbm_surface *surf;
1165 _tbm_surface_mutex_lock();
1167 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1169 surf = (struct _tbm_surface *)surface;
1171 for (i = 0; i < surf->num_bos; i++)
1172 tbm_bo_unmap(surf->bos[i]);
1174 TBM_TRACE("tbm_surface(%p)\n", surface);
1176 _tbm_surface_mutex_unlock();
1180 tbm_surface_internal_get_width(tbm_surface_h surface)
1182 struct _tbm_surface *surf;
1185 _tbm_surface_mutex_lock();
1187 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1189 surf = (struct _tbm_surface *)surface;
1190 width = surf->info.width;
1192 TBM_TRACE("tbm_surface(%p) width(%u)\n", surface, width);
1194 _tbm_surface_mutex_unlock();
1200 tbm_surface_internal_get_height(tbm_surface_h surface)
1202 struct _tbm_surface *surf;
1203 unsigned int height;
1205 _tbm_surface_mutex_lock();
1207 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1209 surf = (struct _tbm_surface *)surface;
1210 height = surf->info.height;
1212 TBM_TRACE("tbm_surface(%p) height(%u)\n", surface, height);
1214 _tbm_surface_mutex_unlock();
1221 tbm_surface_internal_get_format(tbm_surface_h surface)
1223 struct _tbm_surface *surf;
1226 _tbm_surface_mutex_lock();
1228 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1230 surf = (struct _tbm_surface *)surface;
1231 format = surf->info.format;
1233 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1235 _tbm_surface_mutex_unlock();
1241 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1243 struct _tbm_surface *surf;
1246 _tbm_surface_mutex_lock();
1248 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1249 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1251 surf = (struct _tbm_surface *)surface;
1252 bo_idx = surf->planes_bo_idx[plane_idx];
1254 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1256 _tbm_surface_mutex_unlock();
1262 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1263 tbm_data_free data_free_func)
1265 tbm_user_data *data;
1267 _tbm_surface_mutex_lock();
1269 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1271 /* check if the data according to the key exist if so, return false. */
1272 data = user_data_lookup(&surface->user_data_list, key);
1274 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1275 _tbm_surface_mutex_unlock();
1279 data = user_data_create(key, data_free_func);
1281 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1282 _tbm_surface_mutex_unlock();
1286 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1288 LIST_ADD(&data->item_link, &surface->user_data_list);
1290 _tbm_surface_mutex_unlock();
1296 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1299 tbm_user_data *old_data;
1301 _tbm_surface_mutex_lock();
1303 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1305 old_data = user_data_lookup(&surface->user_data_list, key);
1307 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1308 _tbm_surface_mutex_unlock();
1312 if (old_data->data && old_data->free_func)
1313 old_data->free_func(old_data->data);
1315 old_data->data = data;
1317 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1319 _tbm_surface_mutex_unlock();
1325 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1328 tbm_user_data *old_data;
1330 _tbm_surface_mutex_lock();
1332 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1335 TBM_LOG_E("error: tbm_surface(%p) key(%lu)\n", surface, key);
1336 _tbm_surface_mutex_unlock();
1341 old_data = user_data_lookup(&surface->user_data_list, key);
1343 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1344 _tbm_surface_mutex_unlock();
1348 *data = old_data->data;
1350 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1352 _tbm_surface_mutex_unlock();
1358 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1361 tbm_user_data *old_data = (void *)0;
1363 _tbm_surface_mutex_lock();
1365 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1367 old_data = user_data_lookup(&surface->user_data_list, key);
1369 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1370 _tbm_surface_mutex_unlock();
1374 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1376 user_data_delete(old_data);
1378 _tbm_surface_mutex_unlock();
1383 /* LCOV_EXCL_START */
1385 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1387 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1389 return surface->debug_pid;
1393 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1395 _tbm_surface_mutex_lock();
1397 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1399 surface->debug_pid = pid;
1401 _tbm_surface_mutex_unlock();
1404 static tbm_surface_debug_data *
1405 _tbm_surface_internal_debug_data_create(char *key, char *value)
1407 tbm_surface_debug_data *debug_data = NULL;
1409 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1413 if (key) debug_data->key = strdup(key);
1414 if (value) debug_data->value = strdup(value);
1420 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1422 tbm_surface_debug_data *debug_data = NULL;
1423 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1424 tbm_bufmgr bufmgr = NULL;
1426 _tbm_surface_mutex_lock();
1428 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1429 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1431 bufmgr = surface->bufmgr;
1433 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1435 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1436 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1438 if (!strcmp(old_data->key, key)) {
1439 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1440 TBM_TRACE("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1441 goto add_debug_key_list;
1444 if (old_data->value)
1445 free(old_data->value);
1448 old_data->value = strdup(value);
1450 old_data->value = NULL;
1452 goto add_debug_key_list;
1458 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1460 TBM_LOG_E("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1461 _tbm_surface_mutex_unlock();
1465 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1467 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1470 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1471 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1472 if (!strcmp(old_data->key, key)) {
1473 _tbm_surface_mutex_unlock();
1479 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1480 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1482 _tbm_surface_mutex_unlock();
1488 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1490 tbm_surface_debug_data *old_data = NULL;
1492 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1494 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1495 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1496 if (!strcmp(old_data->key, key))
1497 return old_data->value;
1504 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1505 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1507 struct _tbm_surface_dump_buf_info {
1517 tbm_surface_info_s info;
1519 struct list_head link;
1522 struct _tbm_surface_dump_info {
1523 char *path; // copy???
1526 struct list_head *link;
1527 struct list_head surface_list; /* link of surface */
1530 static tbm_surface_dump_info *g_dump_info = NULL;
1531 static const char *dump_postfix[2] = {"png", "yuv"};
1532 static double scale_factor;
1535 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1536 void *data2, int size2, void *data3, int size3)
1539 unsigned int *blocks;
1541 if (_tbm_surface_check_file_is_symbolic_link(file))
1542 TBM_LOG_E("%s is symbolic link\n", file);
1544 fp = fopen(file, "w+");
1545 TBM_RETURN_IF_FAIL(fp != NULL);
1547 blocks = (unsigned int *)data1;
1548 fwrite(blocks, 1, size1, fp);
1551 blocks = (unsigned int *)data2;
1552 fwrite(blocks, 1, size2, fp);
1556 blocks = (unsigned int *)data3;
1557 fwrite(blocks, 1, size3, fp);
1564 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1566 unsigned int *blocks = (unsigned int *)data;
1569 png_bytep *row_pointers;
1572 if (_tbm_surface_check_file_is_symbolic_link(file))
1573 TBM_LOG_E("%s is symbolic link\n", file);
1575 fp = fopen(file, "wb");
1576 TBM_RETURN_IF_FAIL(fp != NULL);
1578 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1581 TBM_LOG_E("fail to create a png write structure.\n");
1586 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1588 TBM_LOG_E("fail to create a png info structure.\n");
1589 png_destroy_write_struct(&pPngStruct, NULL);
1594 png_init_io(pPngStruct, fp);
1595 if (format == TBM_FORMAT_XRGB8888) {
1597 png_set_IHDR(pPngStruct,
1604 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1607 png_set_IHDR(pPngStruct,
1612 PNG_COLOR_TYPE_RGBA,
1614 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1617 png_set_bgr(pPngStruct);
1618 png_write_info(pPngStruct, pPngInfo);
1620 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1621 if (!row_pointers) {
1622 TBM_LOG_E("fail to allocate the png row_pointers.\n");
1623 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1628 for (y = 0; y < height; ++y) {
1632 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1634 TBM_LOG_E("fail to allocate the png row.\n");
1635 for (x = 0; x < y; x++)
1636 png_free(pPngStruct, row_pointers[x]);
1637 png_free(pPngStruct, row_pointers);
1638 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1642 row_pointers[y] = (png_bytep)row;
1644 for (x = 0; x < width; ++x) {
1645 unsigned int curBlock = blocks[y * width + x];
1647 if (pixel_size == 3) { // XRGB8888
1648 row[x * pixel_size] = (curBlock & 0xFF);
1649 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1650 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1651 } else { // ARGB8888
1652 row[x * pixel_size] = (curBlock & 0xFF);
1653 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1654 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1655 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1660 png_write_image(pPngStruct, row_pointers);
1661 png_write_end(pPngStruct, pPngInfo);
1663 for (y = 0; y < height; y++)
1664 png_free(pPngStruct, row_pointers[y]);
1665 png_free(pPngStruct, row_pointers);
1667 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1673 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1675 TBM_RETURN_IF_FAIL(path != NULL);
1676 TBM_RETURN_IF_FAIL(w > 0);
1677 TBM_RETURN_IF_FAIL(h > 0);
1678 TBM_RETURN_IF_FAIL(count > 0);
1680 tbm_surface_dump_buf_info *buf_info = NULL;
1681 tbm_surface_h tbm_surface;
1682 tbm_surface_info_s info;
1687 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1691 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1692 TBM_RETURN_IF_FAIL(g_dump_info);
1694 LIST_INITHEAD(&g_dump_info->surface_list);
1695 g_dump_info->count = 0;
1696 g_dump_info->dump_max = count;
1698 /* get buffer size */
1699 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1700 if (tbm_surface == NULL) {
1701 TBM_LOG_E("tbm_surface_create fail\n");
1707 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1708 TBM_LOG_E("tbm_surface_get_info fail\n");
1709 tbm_surface_destroy(tbm_surface);
1714 buffer_size = info.size;
1715 tbm_surface_destroy(tbm_surface);
1717 /* create dump lists */
1718 for (i = 0; i < count; i++) {
1721 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1722 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1724 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1726 TBM_LOG_E("fail to allocate the tbm_bo[%d]\n", i);
1731 buf_info->index = i;
1733 buf_info->size = buffer_size;
1735 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1738 g_dump_info->path = path;
1739 g_dump_info->link = &g_dump_info->surface_list;
1743 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1748 /* free resources */
1749 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1750 tbm_surface_dump_buf_info *tmp;
1752 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1753 tbm_bo_unref(buf_info->bo);
1754 LIST_DEL(&buf_info->link);
1759 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1768 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1775 tbm_surface_internal_dump_start(path, w, h, count);
1776 scale_factor = scale;
1780 tbm_surface_internal_dump_end(void)
1782 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1783 tbm_bo_handle bo_handle;
1788 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1795 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1798 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1799 if (bo_handle.ptr == NULL) {
1800 tbm_bo_unref(buf_info->bo);
1801 LIST_DEL(&buf_info->link);
1806 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1807 TBM_LOG_I("Dump File.. %s generated.\n", file);
1809 if (buf_info->dirty) {
1810 void *ptr1 = NULL, *ptr2 = NULL;
1812 switch (buf_info->info.format) {
1813 case TBM_FORMAT_ARGB8888:
1814 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1815 buf_info->info.planes[0].stride >> 2,
1816 buf_info->info.height, TBM_FORMAT_ARGB8888);
1818 case TBM_FORMAT_XRGB8888:
1819 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1820 buf_info->info.planes[0].stride >> 2,
1821 buf_info->info.height, TBM_FORMAT_XRGB8888);
1823 case TBM_FORMAT_YVU420:
1824 case TBM_FORMAT_YUV420:
1825 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1826 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
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),
1832 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1834 case TBM_FORMAT_NV12:
1835 case TBM_FORMAT_NV21:
1836 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1837 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1838 buf_info->info.planes[0].stride * buf_info->info.height,
1840 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1843 case TBM_FORMAT_YUYV:
1844 case TBM_FORMAT_UYVY:
1845 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1846 buf_info->info.planes[0].stride * buf_info->info.height,
1850 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1853 } else if (buf_info->dirty_shm)
1854 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1855 buf_info->shm_stride >> 2,
1856 buf_info->shm_h, 0);
1858 tbm_bo_unmap(buf_info->bo);
1859 tbm_bo_unref(buf_info->bo);
1860 LIST_DEL(&buf_info->link);
1867 TBM_LOG_I("Dump End..\n");
1870 static pixman_format_code_t
1871 _tbm_surface_internal_pixman_format_get(tbm_format format)
1874 case TBM_FORMAT_ARGB8888:
1875 return PIXMAN_a8r8g8b8;
1876 case TBM_FORMAT_XRGB8888:
1877 return PIXMAN_x8r8g8b8;
1886 * This function supports only if a buffer has below formats.
1887 * - TBM_FORMAT_ARGB8888
1888 * - TBM_FORMAT_XRGB8888
1890 static tbm_surface_error_e
1891 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1892 int format, int src_stride, int src_w, int src_h,
1893 int dst_stride, int dst_w, int dst_h)
1895 pixman_image_t *src_img = NULL, *dst_img = NULL;
1896 pixman_format_code_t pixman_format;
1897 pixman_transform_t t;
1898 struct pixman_f_transform ft;
1899 double scale_x, scale_y;
1901 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1902 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1904 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1905 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1908 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1909 (uint32_t*)src_ptr, src_stride);
1910 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1913 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1914 (uint32_t*)dst_ptr, dst_stride);
1915 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1917 pixman_f_transform_init_identity(&ft);
1919 scale_x = (double)src_w / dst_w;
1920 scale_y = (double)src_h / dst_h;
1922 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
1923 pixman_f_transform_translate(&ft, NULL, 0, 0);
1924 pixman_transform_from_pixman_f_transform(&t, &ft);
1925 pixman_image_set_transform(src_img, &t);
1927 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
1928 0, 0, 0, 0, 0, 0, dst_w, dst_h);
1930 pixman_image_unref(src_img);
1931 pixman_image_unref(dst_img);
1933 return TBM_SURFACE_ERROR_NONE;
1937 pixman_image_unref(src_img);
1939 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1942 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
1943 #define KEY_LEN 5 // "_XXXX"
1944 #define KEYS_LEN KEY_LEN * MAX_BOS
1946 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
1948 char *keys, temp_key[KEY_LEN + 1];
1949 struct _tbm_surface *surf;
1953 _tbm_surface_mutex_lock();
1955 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1957 surf = (struct _tbm_surface *)surface;
1959 num_bos = surf->num_bos;
1960 if (num_bos > MAX_BOS)
1963 keys = calloc(KEYS_LEN + 1, sizeof(char));
1965 TBM_LOG_E("Failed to alloc memory");
1966 _tbm_surface_mutex_unlock();
1970 for (i = 0; i < num_bos; i++) {
1971 memset(temp_key, 0x00, KEY_LEN + 1);
1973 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
1974 strncat(keys, temp_key, KEY_LEN);
1977 _tbm_surface_mutex_unlock();
1982 static void _tbm_surface_internal_put_keys(char *keys)
1989 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1991 TBM_RETURN_IF_FAIL(surface != NULL);
1992 TBM_RETURN_IF_FAIL(type != NULL);
1994 tbm_surface_dump_buf_info *buf_info;
1995 struct list_head *next_link;
1996 tbm_surface_info_s info;
1997 tbm_bo_handle bo_handle;
1998 const char *postfix;
1999 const char *format = NULL;
2006 next_link = g_dump_info->link->next;
2007 TBM_RETURN_IF_FAIL(next_link != NULL);
2009 if (next_link == &g_dump_info->surface_list) {
2010 next_link = next_link->next;
2011 TBM_RETURN_IF_FAIL(next_link != NULL);
2014 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2015 TBM_RETURN_IF_FAIL(buf_info != NULL);
2017 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2018 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2020 if (scale_factor > 0.0) {
2023 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2024 TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n",
2025 _tbm_surface_internal_format_to_str(info.format));
2026 tbm_surface_unmap(surface);
2030 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2032 buf_info->info.width = info.width * scale_factor;
2033 buf_info->info.height = info.height * scale_factor;
2034 buf_info->info.format = info.format;
2035 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2036 buf_info->info.num_planes = 1;
2037 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2038 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2040 if (buf_info->info.size > buf_info->size) {
2041 TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2042 buf_info->info.size, buf_info->size);
2043 tbm_surface_unmap(surface);
2047 if (info.size > buf_info->size) {
2048 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
2049 info.size, buf_info->size);
2050 tbm_surface_unmap(surface);
2054 /* make the file information */
2055 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2058 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2059 postfix = dump_postfix[0];
2060 format = _tbm_surface_internal_format_to_str(info.format);
2062 postfix = dump_postfix[1];
2064 keys = _tbm_surface_internal_get_keys(surface);
2066 TBM_LOG_E("fail to get keys");
2067 tbm_surface_unmap(surface);
2072 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2073 if (!bo_handle.ptr) {
2074 TBM_LOG_E("fail to map bo");
2075 _tbm_surface_internal_put_keys(keys);
2076 tbm_surface_unmap(surface);
2079 memset(bo_handle.ptr, 0x00, buf_info->size);
2081 switch (info.format) {
2082 case TBM_FORMAT_ARGB8888:
2083 case TBM_FORMAT_XRGB8888:
2084 snprintf(buf_info->name, sizeof(buf_info->name),
2085 "%10.3f_%03d%s_%p_%s-%s.%s",
2086 _tbm_surface_internal_get_time(),
2087 g_dump_info->count++, keys, surface, format, type, postfix);
2089 if (scale_factor > 0.0) {
2090 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2092 buf_info->info.format,
2093 info.planes[0].stride,
2094 info.width, info.height,
2095 buf_info->info.planes[0].stride,
2096 buf_info->info.width,
2097 buf_info->info.height);
2098 if (ret != TBM_SURFACE_ERROR_NONE) {
2099 TBM_LOG_E("fail to scale buffer");
2100 tbm_bo_unmap(buf_info->bo);
2101 _tbm_surface_internal_put_keys(keys);
2102 tbm_surface_unmap(surface);
2106 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2108 case TBM_FORMAT_YVU420:
2109 case TBM_FORMAT_YUV420:
2110 snprintf(buf_info->name, sizeof(buf_info->name),
2111 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2112 _tbm_surface_internal_get_time(),
2113 g_dump_info->count++, keys, type, info.planes[0].stride,
2114 info.height, FOURCC_STR(info.format), postfix);
2115 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2116 bo_handle.ptr += info.planes[0].stride * info.height;
2117 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2118 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2119 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2121 case TBM_FORMAT_NV12:
2122 case TBM_FORMAT_NV21:
2123 snprintf(buf_info->name, sizeof(buf_info->name),
2124 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2125 _tbm_surface_internal_get_time(),
2126 g_dump_info->count++, keys, type, info.planes[0].stride,
2127 info.height, FOURCC_STR(info.format), postfix);
2128 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2129 bo_handle.ptr += info.planes[0].stride * info.height;
2130 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2132 case TBM_FORMAT_YUYV:
2133 case TBM_FORMAT_UYVY:
2134 snprintf(buf_info->name, sizeof(buf_info->name),
2135 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2136 _tbm_surface_internal_get_time(),
2137 g_dump_info->count++, keys, type, info.planes[0].stride,
2138 info.height, FOURCC_STR(info.format), postfix);
2139 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2142 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2143 tbm_bo_unmap(buf_info->bo);
2144 _tbm_surface_internal_put_keys(keys);
2145 tbm_surface_unmap(surface);
2149 tbm_bo_unmap(buf_info->bo);
2151 _tbm_surface_internal_put_keys(keys);
2153 tbm_surface_unmap(surface);
2155 buf_info->dirty = 1;
2156 buf_info->dirty_shm = 0;
2158 if (g_dump_info->count == 1000)
2159 g_dump_info->count = 0;
2161 g_dump_info->link = next_link;
2163 TBM_LOG_I("Dump %s \n", buf_info->name);
2166 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2169 TBM_RETURN_IF_FAIL(ptr != NULL);
2170 TBM_RETURN_IF_FAIL(w > 0);
2171 TBM_RETURN_IF_FAIL(h > 0);
2172 TBM_RETURN_IF_FAIL(stride > 0);
2173 TBM_RETURN_IF_FAIL(type != NULL);
2175 tbm_surface_dump_buf_info *buf_info;
2176 struct list_head *next_link;
2177 tbm_bo_handle bo_handle;
2178 int ret, size, dw = 0, dh = 0, dstride = 0;
2183 next_link = g_dump_info->link->next;
2184 TBM_RETURN_IF_FAIL(next_link != NULL);
2186 if (next_link == &g_dump_info->surface_list) {
2187 next_link = next_link->next;
2188 TBM_RETURN_IF_FAIL(next_link != NULL);
2191 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2192 TBM_RETURN_IF_FAIL(buf_info != NULL);
2194 if (scale_factor > 0.0) {
2197 dw = w * scale_factor;
2198 dh = h * scale_factor;
2200 size = dstride * dh;
2204 if (size > buf_info->size) {
2205 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2206 size, buf_info->size);
2211 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2212 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2214 memset(bo_handle.ptr, 0x00, buf_info->size);
2215 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2217 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2218 _tbm_surface_internal_get_time(),
2219 g_dump_info->count++, type, dump_postfix[0]);
2220 if (scale_factor > 0.0) {
2221 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2222 TBM_FORMAT_ARGB8888, stride,
2223 w, h, dstride, dw, dh);
2224 if (ret != TBM_SURFACE_ERROR_NONE) {
2225 TBM_LOG_E("fail to scale buffer");
2226 tbm_bo_unmap(buf_info->bo);
2229 buf_info->shm_stride = dstride;
2230 buf_info->shm_h = dh;
2232 memcpy(bo_handle.ptr, ptr, size);
2233 buf_info->shm_stride = stride;
2234 buf_info->shm_h = h;
2237 tbm_bo_unmap(buf_info->bo);
2239 buf_info->dirty = 0;
2240 buf_info->dirty_shm = 1;
2242 if (g_dump_info->count == 1000)
2243 g_dump_info->count = 0;
2245 g_dump_info->link = next_link;
2247 TBM_LOG_I("Dump %s \n", buf_info->name);
2251 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2253 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2254 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2255 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2257 tbm_surface_info_s info;
2258 const char *postfix;
2262 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2263 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2265 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2266 postfix = dump_postfix[0];
2268 postfix = dump_postfix[1];
2270 if (strcmp(postfix, type)) {
2271 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2272 tbm_surface_unmap(surface);
2276 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2278 if (!access(file, 0)) {
2279 TBM_LOG_E("can't capture buffer, exist file %s", file);
2280 tbm_surface_unmap(surface);
2284 switch (info.format) {
2285 case TBM_FORMAT_ARGB8888:
2286 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2287 info.planes[0].stride >> 2,
2288 info.height, TBM_FORMAT_ARGB8888);
2290 case TBM_FORMAT_XRGB8888:
2291 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2292 info.planes[0].stride >> 2,
2293 info.height, TBM_FORMAT_XRGB8888);
2295 case TBM_FORMAT_YVU420:
2296 case TBM_FORMAT_YUV420:
2297 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2298 info.planes[0].stride * info.height,
2300 info.planes[1].stride * (info.height >> 1),
2302 info.planes[2].stride * (info.height >> 1));
2304 case TBM_FORMAT_NV12:
2305 case TBM_FORMAT_NV21:
2306 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2307 info.planes[0].stride * info.height,
2309 info.planes[1].stride * (info.height >> 1),
2312 case TBM_FORMAT_YUYV:
2313 case TBM_FORMAT_UYVY:
2314 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2315 info.planes[0].stride * info.height,
2319 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2320 tbm_surface_unmap(surface);
2324 tbm_surface_unmap(surface);
2326 TBM_TRACE("Capture %s \n", file);
2332 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2333 const char *path, const char *name, const char *type)
2335 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2336 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2337 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2338 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2339 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2340 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2344 if (strcmp(dump_postfix[0], type)) {
2345 TBM_LOG_E("Not supported type:%s'", type);
2349 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2351 if (!access(file, 0)) {
2352 TBM_LOG_E("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2356 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2358 TBM_TRACE("Capture %s \n", file);