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_valid(const char* path, int del_link)
381 real_path = realpath(path, NULL);
382 if (real_path && strncmp(path, real_path, strlen(path))) {
398 tbm_surface_internal_is_valid(tbm_surface_h surface)
402 _tbm_surface_mutex_lock();
404 /* Return silently if surface is null. */
406 _tbm_surface_mutex_unlock();
410 ret = _tbm_surface_internal_is_valid(surface);
412 _tbm_surface_mutex_unlock();
418 tbm_surface_internal_query_supported_formats(uint32_t **formats,
421 struct _tbm_bufmgr *mgr;
423 bool bufmgr_initialized = false;
425 _tbm_surface_mutex_lock();
427 if (!g_surface_bufmgr) {
428 _init_surface_bufmgr();
429 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
430 bufmgr_initialized = true;
433 mgr = g_surface_bufmgr;
435 if (!mgr->backend->surface_supported_format)
438 ret = mgr->backend->surface_supported_format(formats, num);
440 /* LCOV_EXCL_START */
441 TBM_LOG_E("Fail to surface_supported_format.\n");
443 /* LCOV_EXCL_START */
446 TBM_TRACE("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
448 _tbm_surface_mutex_unlock();
452 /* LCOV_EXCL_START */
454 if (bufmgr_initialized) {
455 LIST_DELINIT(&g_surface_bufmgr->surf_list);
456 _deinit_surface_bufmgr();
458 _tbm_surface_mutex_unlock();
460 TBM_LOG_E("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
467 tbm_surface_internal_get_num_planes(tbm_format format)
473 case TBM_FORMAT_RGB332:
474 case TBM_FORMAT_BGR233:
475 case TBM_FORMAT_XRGB4444:
476 case TBM_FORMAT_XBGR4444:
477 case TBM_FORMAT_RGBX4444:
478 case TBM_FORMAT_BGRX4444:
479 case TBM_FORMAT_ARGB4444:
480 case TBM_FORMAT_ABGR4444:
481 case TBM_FORMAT_RGBA4444:
482 case TBM_FORMAT_BGRA4444:
483 case TBM_FORMAT_XRGB1555:
484 case TBM_FORMAT_XBGR1555:
485 case TBM_FORMAT_RGBX5551:
486 case TBM_FORMAT_BGRX5551:
487 case TBM_FORMAT_ARGB1555:
488 case TBM_FORMAT_ABGR1555:
489 case TBM_FORMAT_RGBA5551:
490 case TBM_FORMAT_BGRA5551:
491 case TBM_FORMAT_RGB565:
492 case TBM_FORMAT_BGR565:
493 case TBM_FORMAT_RGB888:
494 case TBM_FORMAT_BGR888:
495 case TBM_FORMAT_XRGB8888:
496 case TBM_FORMAT_XBGR8888:
497 case TBM_FORMAT_RGBX8888:
498 case TBM_FORMAT_BGRX8888:
499 case TBM_FORMAT_ARGB8888:
500 case TBM_FORMAT_ABGR8888:
501 case TBM_FORMAT_RGBA8888:
502 case TBM_FORMAT_BGRA8888:
503 case TBM_FORMAT_XRGB2101010:
504 case TBM_FORMAT_XBGR2101010:
505 case TBM_FORMAT_RGBX1010102:
506 case TBM_FORMAT_BGRX1010102:
507 case TBM_FORMAT_ARGB2101010:
508 case TBM_FORMAT_ABGR2101010:
509 case TBM_FORMAT_RGBA1010102:
510 case TBM_FORMAT_BGRA1010102:
511 case TBM_FORMAT_YUYV:
512 case TBM_FORMAT_YVYU:
513 case TBM_FORMAT_UYVY:
514 case TBM_FORMAT_VYUY:
515 case TBM_FORMAT_AYUV:
518 case TBM_FORMAT_NV12:
519 case TBM_FORMAT_NV12MT:
520 case TBM_FORMAT_NV21:
521 case TBM_FORMAT_NV16:
522 case TBM_FORMAT_NV61:
525 case TBM_FORMAT_YUV410:
526 case TBM_FORMAT_YVU410:
527 case TBM_FORMAT_YUV411:
528 case TBM_FORMAT_YVU411:
529 case TBM_FORMAT_YUV420:
530 case TBM_FORMAT_YVU420:
531 case TBM_FORMAT_YUV422:
532 case TBM_FORMAT_YVU422:
533 case TBM_FORMAT_YUV444:
534 case TBM_FORMAT_YVU444:
542 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
548 tbm_surface_internal_get_bpp(tbm_format format)
555 case TBM_FORMAT_RGB332:
556 case TBM_FORMAT_BGR233:
559 case TBM_FORMAT_XRGB4444:
560 case TBM_FORMAT_XBGR4444:
561 case TBM_FORMAT_RGBX4444:
562 case TBM_FORMAT_BGRX4444:
563 case TBM_FORMAT_ARGB4444:
564 case TBM_FORMAT_ABGR4444:
565 case TBM_FORMAT_RGBA4444:
566 case TBM_FORMAT_BGRA4444:
567 case TBM_FORMAT_XRGB1555:
568 case TBM_FORMAT_XBGR1555:
569 case TBM_FORMAT_RGBX5551:
570 case TBM_FORMAT_BGRX5551:
571 case TBM_FORMAT_ARGB1555:
572 case TBM_FORMAT_ABGR1555:
573 case TBM_FORMAT_RGBA5551:
574 case TBM_FORMAT_BGRA5551:
575 case TBM_FORMAT_RGB565:
576 case TBM_FORMAT_BGR565:
579 case TBM_FORMAT_RGB888:
580 case TBM_FORMAT_BGR888:
583 case TBM_FORMAT_XRGB8888:
584 case TBM_FORMAT_XBGR8888:
585 case TBM_FORMAT_RGBX8888:
586 case TBM_FORMAT_BGRX8888:
587 case TBM_FORMAT_ARGB8888:
588 case TBM_FORMAT_ABGR8888:
589 case TBM_FORMAT_RGBA8888:
590 case TBM_FORMAT_BGRA8888:
591 case TBM_FORMAT_XRGB2101010:
592 case TBM_FORMAT_XBGR2101010:
593 case TBM_FORMAT_RGBX1010102:
594 case TBM_FORMAT_BGRX1010102:
595 case TBM_FORMAT_ARGB2101010:
596 case TBM_FORMAT_ABGR2101010:
597 case TBM_FORMAT_RGBA1010102:
598 case TBM_FORMAT_BGRA1010102:
599 case TBM_FORMAT_YUYV:
600 case TBM_FORMAT_YVYU:
601 case TBM_FORMAT_UYVY:
602 case TBM_FORMAT_VYUY:
603 case TBM_FORMAT_AYUV:
606 case TBM_FORMAT_NV12:
607 case TBM_FORMAT_NV12MT:
608 case TBM_FORMAT_NV21:
611 case TBM_FORMAT_NV16:
612 case TBM_FORMAT_NV61:
615 case TBM_FORMAT_YUV410:
616 case TBM_FORMAT_YVU410:
619 case TBM_FORMAT_YUV411:
620 case TBM_FORMAT_YVU411:
621 case TBM_FORMAT_YUV420:
622 case TBM_FORMAT_YVU420:
625 case TBM_FORMAT_YUV422:
626 case TBM_FORMAT_YVU422:
629 case TBM_FORMAT_YUV444:
630 case TBM_FORMAT_YVU444:
637 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
643 tbm_surface_internal_create_with_flags(int width, int height,
644 int format, int flags)
646 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
647 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
649 struct _tbm_bufmgr *mgr;
650 struct _tbm_surface *surf = NULL;
654 uint32_t bo_size = 0;
657 bool bufmgr_initialized = false;
659 _tbm_surface_mutex_lock();
661 if (!g_surface_bufmgr) {
662 _init_surface_bufmgr();
663 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
664 bufmgr_initialized = true;
667 mgr = g_surface_bufmgr;
668 if (!TBM_BUFMGR_IS_VALID(mgr)) {
669 TBM_LOG_E("The bufmgr is invalid\n");
670 goto check_valid_fail;
673 surf = calloc(1, sizeof(struct _tbm_surface));
675 /* LCOV_EXCL_START */
676 TBM_LOG_E("fail to alloc surf\n");
677 goto alloc_surf_fail;
682 surf->info.width = width;
683 surf->info.height = height;
684 surf->info.format = format;
685 surf->info.bpp = tbm_surface_internal_get_bpp(format);
686 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
689 /* get size, stride and offset bo_idx */
690 for (i = 0; i < surf->info.num_planes; i++) {
691 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
692 &offset, &stride, &bo_idx)) {
693 TBM_LOG_E("fail to query plane data\n");
694 goto query_plane_data_fail;
697 surf->info.planes[i].size = size;
698 surf->info.planes[i].offset = offset;
699 surf->info.planes[i].stride = stride;
700 surf->planes_bo_idx[i] = bo_idx;
705 for (i = 0; i < surf->info.num_planes; i++) {
706 surf->info.size += surf->info.planes[i].size;
708 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
709 surf->num_bos = surf->planes_bo_idx[i] + 1;
714 for (i = 0; i < surf->num_bos; i++) {
716 for (j = 0; j < surf->info.num_planes; j++) {
717 if (surf->planes_bo_idx[j] == i)
718 bo_size += surf->info.planes[j].size;
721 if (mgr->backend->surface_bo_alloc) {
722 /* LCOV_EXCL_START */
724 void *bo_priv = NULL;
726 bo = calloc(1, sizeof(struct _tbm_bo));
728 TBM_LOG_E("fail to alloc bo struct\n");
732 bo->bufmgr = surf->bufmgr;
734 pthread_mutex_lock(&surf->bufmgr->lock);
736 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
738 TBM_LOG_E("fail to alloc bo priv\n");
740 pthread_mutex_unlock(&surf->bufmgr->lock);
748 LIST_INITHEAD(&bo->user_data_list);
750 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
752 pthread_mutex_unlock(&surf->bufmgr->lock);
757 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
759 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
764 _tbm_bo_set_surface(surf->bos[i], surf);
767 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
768 _tbm_surface_internal_format_to_str(format), flags, surf);
770 LIST_INITHEAD(&surf->user_data_list);
771 LIST_INITHEAD(&surf->debug_data_list);
773 LIST_ADD(&surf->item_link, &mgr->surf_list);
775 _tbm_surface_mutex_unlock();
779 /* LCOV_EXCL_START */
781 for (j = 0; j < i; j++) {
783 tbm_bo_unref(surf->bos[j]);
785 query_plane_data_fail:
789 if (bufmgr_initialized && mgr) {
790 LIST_DELINIT(&mgr->surf_list);
791 _deinit_surface_bufmgr();
793 _tbm_surface_mutex_unlock();
795 TBM_LOG_E("error: width(%d) height(%d) format(%s) flags(%d)\n",
797 _tbm_surface_internal_format_to_str(format), flags);
804 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
805 tbm_bo *bos, int num)
807 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
808 TBM_RETURN_VAL_IF_FAIL(info, NULL);
809 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
811 struct _tbm_bufmgr *mgr;
812 struct _tbm_surface *surf = NULL;
814 bool bufmgr_initialized = false;
816 _tbm_surface_mutex_lock();
818 if (!g_surface_bufmgr) {
819 _init_surface_bufmgr();
820 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
821 bufmgr_initialized = true;
824 mgr = g_surface_bufmgr;
825 if (!TBM_BUFMGR_IS_VALID(mgr)) {
826 TBM_LOG_E("fail to validate the Bufmgr.\n");
827 goto check_valid_fail;
830 surf = calloc(1, sizeof(struct _tbm_surface));
832 /* LCOV_EXCL_START */
833 TBM_LOG_E("fail to allocate struct _tbm_surface.\n");
834 goto alloc_surf_fail;
839 surf->info.width = info->width;
840 surf->info.height = info->height;
841 surf->info.format = info->format;
843 surf->info.bpp = info->bpp;
845 surf->info.bpp = tbm_surface_internal_get_bpp(info->format);
846 surf->info.num_planes = info->num_planes;
849 /* get size, stride and offset */
850 for (i = 0; i < info->num_planes; i++) {
851 surf->info.planes[i].offset = info->planes[i].offset;
852 surf->info.planes[i].stride = info->planes[i].stride;
854 if (info->planes[i].size > 0)
855 surf->info.planes[i].size = info->planes[i].size;
857 uint32_t size = 0, offset = 0, stride = 0;
860 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
861 surf->info.planes[i].size = size;
865 surf->planes_bo_idx[i] = 0;
867 surf->planes_bo_idx[i] = i;
870 if (info->size > 0) {
871 surf->info.size = info->size;
874 for (i = 0; i < info->num_planes; i++)
875 surf->info.size += surf->info.planes[i].size;
878 surf->flags = TBM_BO_DEFAULT;
880 /* create only one bo */
882 for (i = 0; i < num; i++) {
883 if (bos[i] == NULL) {
884 TBM_LOG_E("bos[%d] is null.\n", i);
888 surf->bos[i] = tbm_bo_ref(bos[i]);
889 _tbm_bo_set_surface(bos[i], surf);
892 TBM_TRACE("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
893 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
895 LIST_INITHEAD(&surf->user_data_list);
896 LIST_INITHEAD(&surf->debug_data_list);
898 LIST_ADD(&surf->item_link, &mgr->surf_list);
900 _tbm_surface_mutex_unlock();
904 /* LCOV_EXCL_START */
906 for (i = 0; i < num; i++) {
908 tbm_bo_unref(surf->bos[i]);
913 if (bufmgr_initialized && mgr) {
914 LIST_DELINIT(&mgr->surf_list);
915 _deinit_surface_bufmgr();
917 _tbm_surface_mutex_unlock();
919 TBM_LOG_E("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
920 info->width, info->height,
921 _tbm_surface_internal_format_to_str(info->format), num);
928 tbm_surface_internal_destroy(tbm_surface_h surface)
930 _tbm_surface_mutex_lock();
932 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
936 if (surface->refcnt > 0) {
937 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
938 _tbm_surface_mutex_unlock();
942 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
944 if (surface->refcnt == 0)
945 _tbm_surface_internal_destroy(surface);
947 _tbm_surface_mutex_unlock();
951 tbm_surface_internal_ref(tbm_surface_h surface)
953 _tbm_surface_mutex_lock();
955 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
959 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
961 _tbm_surface_mutex_unlock();
965 tbm_surface_internal_unref(tbm_surface_h surface)
967 _tbm_surface_mutex_lock();
969 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
973 if (surface->refcnt > 0) {
974 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
975 _tbm_surface_mutex_unlock();
979 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
981 if (surface->refcnt == 0)
982 _tbm_surface_internal_destroy(surface);
984 _tbm_surface_mutex_unlock();
988 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
990 struct _tbm_surface *surf;
993 _tbm_surface_mutex_lock();
995 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
997 surf = (struct _tbm_surface *)surface;
1000 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
1002 _tbm_surface_mutex_unlock();
1008 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1010 struct _tbm_surface *surf;
1013 _tbm_surface_mutex_lock();
1015 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1016 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1018 surf = (struct _tbm_surface *)surface;
1019 bo = surf->bos[bo_idx];
1021 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1023 _tbm_surface_mutex_unlock();
1029 tbm_surface_internal_get_size(tbm_surface_h surface)
1031 struct _tbm_surface *surf;
1034 _tbm_surface_mutex_lock();
1036 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1038 surf = (struct _tbm_surface *)surface;
1039 size = surf->info.size;
1041 TBM_TRACE("tbm_surface(%p) size(%u)\n", surface, size);
1043 _tbm_surface_mutex_unlock();
1049 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1050 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1052 struct _tbm_surface *surf;
1054 _tbm_surface_mutex_lock();
1056 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1057 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1059 surf = (struct _tbm_surface *)surface;
1061 if (plane_idx >= surf->info.num_planes) {
1062 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1063 _tbm_surface_mutex_unlock();
1068 *size = surf->info.planes[plane_idx].size;
1071 *offset = surf->info.planes[plane_idx].offset;
1074 *pitch = surf->info.planes[plane_idx].stride;
1076 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1077 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1078 surf->info.planes[plane_idx].stride);
1080 _tbm_surface_mutex_unlock();
1086 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1087 tbm_surface_info_s *info, int map)
1089 struct _tbm_surface *surf;
1090 tbm_bo_handle bo_handles[4];
1093 _tbm_surface_mutex_lock();
1095 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1097 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1099 surf = (struct _tbm_surface *)surface;
1101 memset(info, 0x00, sizeof(tbm_surface_info_s));
1102 info->width = surf->info.width;
1103 info->height = surf->info.height;
1104 info->format = surf->info.format;
1105 info->bpp = surf->info.bpp;
1106 info->size = surf->info.size;
1107 info->num_planes = surf->info.num_planes;
1110 for (i = 0; i < surf->num_bos; i++) {
1111 _tbm_surface_mutex_unlock();
1112 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1113 _tbm_surface_mutex_lock();
1114 if (bo_handles[i].ptr == NULL) {
1115 for (j = 0; j < i; j++)
1116 tbm_bo_unmap(surf->bos[j]);
1118 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1119 _tbm_surface_mutex_unlock();
1124 for (i = 0; i < surf->num_bos; i++) {
1125 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1126 if (bo_handles[i].ptr == NULL) {
1127 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1128 _tbm_surface_mutex_unlock();
1134 for (i = 0; i < surf->info.num_planes; i++) {
1135 info->planes[i].size = surf->info.planes[i].size;
1136 info->planes[i].offset = surf->info.planes[i].offset;
1137 info->planes[i].stride = surf->info.planes[i].stride;
1139 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1140 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1141 surf->info.planes[i].offset;
1144 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1146 _tbm_surface_mutex_unlock();
1152 tbm_surface_internal_unmap(tbm_surface_h surface)
1154 struct _tbm_surface *surf;
1157 _tbm_surface_mutex_lock();
1159 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1161 surf = (struct _tbm_surface *)surface;
1163 for (i = 0; i < surf->num_bos; i++)
1164 tbm_bo_unmap(surf->bos[i]);
1166 TBM_TRACE("tbm_surface(%p)\n", surface);
1168 _tbm_surface_mutex_unlock();
1172 tbm_surface_internal_get_width(tbm_surface_h surface)
1174 struct _tbm_surface *surf;
1177 _tbm_surface_mutex_lock();
1179 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1181 surf = (struct _tbm_surface *)surface;
1182 width = surf->info.width;
1184 TBM_TRACE("tbm_surface(%p) width(%u)\n", surface, width);
1186 _tbm_surface_mutex_unlock();
1192 tbm_surface_internal_get_height(tbm_surface_h surface)
1194 struct _tbm_surface *surf;
1195 unsigned int height;
1197 _tbm_surface_mutex_lock();
1199 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1201 surf = (struct _tbm_surface *)surface;
1202 height = surf->info.height;
1204 TBM_TRACE("tbm_surface(%p) height(%u)\n", surface, height);
1206 _tbm_surface_mutex_unlock();
1213 tbm_surface_internal_get_format(tbm_surface_h surface)
1215 struct _tbm_surface *surf;
1218 _tbm_surface_mutex_lock();
1220 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1222 surf = (struct _tbm_surface *)surface;
1223 format = surf->info.format;
1225 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1227 _tbm_surface_mutex_unlock();
1233 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1235 struct _tbm_surface *surf;
1238 _tbm_surface_mutex_lock();
1240 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1241 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1243 surf = (struct _tbm_surface *)surface;
1244 bo_idx = surf->planes_bo_idx[plane_idx];
1246 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1248 _tbm_surface_mutex_unlock();
1254 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1255 tbm_data_free data_free_func)
1257 tbm_user_data *data;
1259 _tbm_surface_mutex_lock();
1261 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1263 /* check if the data according to the key exist if so, return false. */
1264 data = user_data_lookup(&surface->user_data_list, key);
1266 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1267 _tbm_surface_mutex_unlock();
1271 data = user_data_create(key, data_free_func);
1273 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1274 _tbm_surface_mutex_unlock();
1278 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1280 LIST_ADD(&data->item_link, &surface->user_data_list);
1282 _tbm_surface_mutex_unlock();
1288 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1291 tbm_user_data *old_data;
1293 _tbm_surface_mutex_lock();
1295 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1297 old_data = user_data_lookup(&surface->user_data_list, key);
1299 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1300 _tbm_surface_mutex_unlock();
1304 if (old_data->data && old_data->free_func)
1305 old_data->free_func(old_data->data);
1307 old_data->data = data;
1309 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1311 _tbm_surface_mutex_unlock();
1317 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1320 tbm_user_data *old_data;
1322 _tbm_surface_mutex_lock();
1324 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1327 TBM_LOG_E("error: tbm_surface(%p) key(%lu)\n", surface, key);
1328 _tbm_surface_mutex_unlock();
1333 old_data = user_data_lookup(&surface->user_data_list, key);
1335 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1336 _tbm_surface_mutex_unlock();
1340 *data = old_data->data;
1342 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1344 _tbm_surface_mutex_unlock();
1350 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1353 tbm_user_data *old_data = (void *)0;
1355 _tbm_surface_mutex_lock();
1357 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1359 old_data = user_data_lookup(&surface->user_data_list, key);
1361 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1362 _tbm_surface_mutex_unlock();
1366 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1368 user_data_delete(old_data);
1370 _tbm_surface_mutex_unlock();
1375 /* LCOV_EXCL_START */
1377 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1379 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1381 return surface->debug_pid;
1385 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1387 _tbm_surface_mutex_lock();
1389 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1391 surface->debug_pid = pid;
1393 _tbm_surface_mutex_unlock();
1396 static tbm_surface_debug_data *
1397 _tbm_surface_internal_debug_data_create(char *key, char *value)
1399 tbm_surface_debug_data *debug_data = NULL;
1401 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1405 if (key) debug_data->key = strdup(key);
1406 if (value) debug_data->value = strdup(value);
1412 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1414 tbm_surface_debug_data *debug_data = NULL;
1415 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1416 tbm_bufmgr bufmgr = NULL;
1418 _tbm_surface_mutex_lock();
1420 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1421 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1423 bufmgr = surface->bufmgr;
1425 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1427 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1428 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1430 if (!strcmp(old_data->key, key)) {
1431 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1432 TBM_TRACE("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1433 goto add_debug_key_list;
1436 if (old_data->value)
1437 free(old_data->value);
1440 old_data->value = strdup(value);
1442 old_data->value = NULL;
1444 goto add_debug_key_list;
1450 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1452 TBM_LOG_E("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1453 _tbm_surface_mutex_unlock();
1457 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1459 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1462 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1463 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1464 if (!strcmp(old_data->key, key)) {
1465 _tbm_surface_mutex_unlock();
1471 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1472 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1474 _tbm_surface_mutex_unlock();
1480 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1482 tbm_surface_debug_data *old_data = NULL;
1484 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1486 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1487 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1488 if (!strcmp(old_data->key, key))
1489 return old_data->value;
1496 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1497 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1499 struct _tbm_surface_dump_buf_info {
1509 tbm_surface_info_s info;
1511 struct list_head link;
1514 struct _tbm_surface_dump_info {
1515 char *path; // copy???
1518 struct list_head *link;
1519 struct list_head surface_list; /* link of surface */
1522 static tbm_surface_dump_info *g_dump_info = NULL;
1523 static const char *dump_postfix[2] = {"png", "yuv"};
1524 static double scale_factor;
1527 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1528 void *data2, int size2, void *data3, int size3)
1531 unsigned int *blocks;
1533 if (!_tbm_surface_check_file_is_valid(file, 1))
1534 TBM_LOG_E("%s is symbolic link\n", file);
1536 fp = fopen(file, "w+");
1537 TBM_RETURN_IF_FAIL(fp != NULL);
1539 blocks = (unsigned int *)data1;
1540 fwrite(blocks, 1, size1, fp);
1543 blocks = (unsigned int *)data2;
1544 fwrite(blocks, 1, size2, fp);
1548 blocks = (unsigned int *)data3;
1549 fwrite(blocks, 1, size3, fp);
1556 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1558 unsigned int *blocks = (unsigned int *)data;
1561 png_bytep *row_pointers;
1564 if (!_tbm_surface_check_file_is_valid(file, 1))
1565 TBM_LOG_E("%s is symbolic link\n", file);
1567 fp = fopen(file, "wb");
1568 TBM_RETURN_IF_FAIL(fp != NULL);
1570 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1573 TBM_LOG_E("fail to create a png write structure.\n");
1578 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1580 TBM_LOG_E("fail to create a png info structure.\n");
1581 png_destroy_write_struct(&pPngStruct, NULL);
1586 png_init_io(pPngStruct, fp);
1587 if (format == TBM_FORMAT_XRGB8888) {
1589 png_set_IHDR(pPngStruct,
1596 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1599 png_set_IHDR(pPngStruct,
1604 PNG_COLOR_TYPE_RGBA,
1606 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1609 png_set_bgr(pPngStruct);
1610 png_write_info(pPngStruct, pPngInfo);
1612 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1613 if (!row_pointers) {
1614 TBM_LOG_E("fail to allocate the png row_pointers.\n");
1615 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1620 for (y = 0; y < height; ++y) {
1624 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1626 TBM_LOG_E("fail to allocate the png row.\n");
1627 for (x = 0; x < y; x++)
1628 png_free(pPngStruct, row_pointers[x]);
1629 png_free(pPngStruct, row_pointers);
1630 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1634 row_pointers[y] = (png_bytep)row;
1636 for (x = 0; x < width; ++x) {
1637 unsigned int curBlock = blocks[y * width + x];
1639 if (pixel_size == 3) { // XRGB8888
1640 row[x * pixel_size] = (curBlock & 0xFF);
1641 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1642 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1643 } else { // ARGB8888
1644 row[x * pixel_size] = (curBlock & 0xFF);
1645 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1646 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1647 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1652 png_write_image(pPngStruct, row_pointers);
1653 png_write_end(pPngStruct, pPngInfo);
1655 for (y = 0; y < height; y++)
1656 png_free(pPngStruct, row_pointers[y]);
1657 png_free(pPngStruct, row_pointers);
1659 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1665 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1667 TBM_RETURN_IF_FAIL(path != NULL);
1668 TBM_RETURN_IF_FAIL(w > 0);
1669 TBM_RETURN_IF_FAIL(h > 0);
1670 TBM_RETURN_IF_FAIL(count > 0);
1672 tbm_surface_dump_buf_info *buf_info = NULL;
1673 tbm_surface_h tbm_surface;
1674 tbm_surface_info_s info;
1679 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1683 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1684 TBM_RETURN_IF_FAIL(g_dump_info);
1686 LIST_INITHEAD(&g_dump_info->surface_list);
1687 g_dump_info->count = 0;
1688 g_dump_info->dump_max = count;
1690 /* get buffer size */
1691 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1692 if (tbm_surface == NULL) {
1693 TBM_LOG_E("tbm_surface_create fail\n");
1699 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1700 TBM_LOG_E("tbm_surface_get_info fail\n");
1701 tbm_surface_destroy(tbm_surface);
1706 buffer_size = info.size;
1707 tbm_surface_destroy(tbm_surface);
1709 /* create dump lists */
1710 for (i = 0; i < count; i++) {
1713 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1714 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1716 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1718 TBM_LOG_E("fail to allocate the tbm_bo[%d]\n", i);
1723 buf_info->index = i;
1725 buf_info->size = buffer_size;
1727 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1730 g_dump_info->path = path;
1731 g_dump_info->link = &g_dump_info->surface_list;
1735 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1740 /* free resources */
1741 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1742 tbm_surface_dump_buf_info *tmp;
1744 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1745 tbm_bo_unref(buf_info->bo);
1746 LIST_DEL(&buf_info->link);
1751 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1760 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1767 tbm_surface_internal_dump_start(path, w, h, count);
1768 scale_factor = scale;
1772 tbm_surface_internal_dump_end(void)
1774 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1775 tbm_bo_handle bo_handle;
1780 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1787 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1790 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1791 if (bo_handle.ptr == NULL) {
1792 tbm_bo_unref(buf_info->bo);
1793 LIST_DEL(&buf_info->link);
1798 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1799 TBM_LOG_I("Dump File.. %s generated.\n", file);
1801 if (buf_info->dirty) {
1802 void *ptr1 = NULL, *ptr2 = NULL;
1804 switch (buf_info->info.format) {
1805 case TBM_FORMAT_ARGB8888:
1806 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1807 buf_info->info.planes[0].stride >> 2,
1808 buf_info->info.height, TBM_FORMAT_ARGB8888);
1810 case TBM_FORMAT_XRGB8888:
1811 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1812 buf_info->info.planes[0].stride >> 2,
1813 buf_info->info.height, TBM_FORMAT_XRGB8888);
1815 case TBM_FORMAT_YVU420:
1816 case TBM_FORMAT_YUV420:
1817 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1818 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1819 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1820 buf_info->info.planes[0].stride * buf_info->info.height,
1822 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1824 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1826 case TBM_FORMAT_NV12:
1827 case TBM_FORMAT_NV21:
1828 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1829 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1830 buf_info->info.planes[0].stride * buf_info->info.height,
1832 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1835 case TBM_FORMAT_YUYV:
1836 case TBM_FORMAT_UYVY:
1837 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1838 buf_info->info.planes[0].stride * buf_info->info.height,
1842 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1845 } else if (buf_info->dirty_shm)
1846 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1847 buf_info->shm_stride >> 2,
1848 buf_info->shm_h, 0);
1850 tbm_bo_unmap(buf_info->bo);
1851 tbm_bo_unref(buf_info->bo);
1852 LIST_DEL(&buf_info->link);
1859 TBM_LOG_I("Dump End..\n");
1862 static pixman_format_code_t
1863 _tbm_surface_internal_pixman_format_get(tbm_format format)
1866 case TBM_FORMAT_ARGB8888:
1867 return PIXMAN_a8r8g8b8;
1868 case TBM_FORMAT_XRGB8888:
1869 return PIXMAN_x8r8g8b8;
1878 * This function supports only if a buffer has below formats.
1879 * - TBM_FORMAT_ARGB8888
1880 * - TBM_FORMAT_XRGB8888
1882 static tbm_surface_error_e
1883 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1884 int format, int src_stride, int src_w, int src_h,
1885 int dst_stride, int dst_w, int dst_h)
1887 pixman_image_t *src_img = NULL, *dst_img = NULL;
1888 pixman_format_code_t pixman_format;
1889 pixman_transform_t t;
1890 struct pixman_f_transform ft;
1891 double scale_x, scale_y;
1893 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1894 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1896 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1897 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1900 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1901 (uint32_t*)src_ptr, src_stride);
1902 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1905 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1906 (uint32_t*)dst_ptr, dst_stride);
1907 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1909 pixman_f_transform_init_identity(&ft);
1911 scale_x = (double)src_w / dst_w;
1912 scale_y = (double)src_h / dst_h;
1914 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
1915 pixman_f_transform_translate(&ft, NULL, 0, 0);
1916 pixman_transform_from_pixman_f_transform(&t, &ft);
1917 pixman_image_set_transform(src_img, &t);
1919 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
1920 0, 0, 0, 0, 0, 0, dst_w, dst_h);
1922 pixman_image_unref(src_img);
1923 pixman_image_unref(dst_img);
1925 return TBM_SURFACE_ERROR_NONE;
1929 pixman_image_unref(src_img);
1931 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1934 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
1935 #define KEY_LEN 5 // "_XXXX"
1936 #define KEYS_LEN KEY_LEN * MAX_BOS
1938 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
1940 char *keys, temp_key[KEY_LEN + 1];
1941 struct _tbm_surface *surf;
1945 _tbm_surface_mutex_lock();
1947 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1949 surf = (struct _tbm_surface *)surface;
1951 num_bos = surf->num_bos;
1952 if (num_bos > MAX_BOS)
1955 keys = calloc(KEYS_LEN + 1, sizeof(char));
1957 TBM_LOG_E("Failed to alloc memory");
1958 _tbm_surface_mutex_unlock();
1962 for (i = 0; i < num_bos; i++) {
1963 memset(temp_key, 0x00, KEY_LEN + 1);
1965 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
1966 strncat(keys, temp_key, KEY_LEN);
1969 _tbm_surface_mutex_unlock();
1974 static void _tbm_surface_internal_put_keys(char *keys)
1981 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1983 TBM_RETURN_IF_FAIL(surface != NULL);
1984 TBM_RETURN_IF_FAIL(type != NULL);
1986 tbm_surface_dump_buf_info *buf_info;
1987 struct list_head *next_link;
1988 tbm_surface_info_s info;
1989 tbm_bo_handle bo_handle;
1990 const char *postfix;
1991 const char *format = NULL;
1998 next_link = g_dump_info->link->next;
1999 TBM_RETURN_IF_FAIL(next_link != NULL);
2001 if (next_link == &g_dump_info->surface_list) {
2002 next_link = next_link->next;
2003 TBM_RETURN_IF_FAIL(next_link != NULL);
2006 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2007 TBM_RETURN_IF_FAIL(buf_info != NULL);
2009 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2010 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2012 if (scale_factor > 0.0) {
2015 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2016 TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n",
2017 _tbm_surface_internal_format_to_str(info.format));
2018 tbm_surface_unmap(surface);
2022 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2024 buf_info->info.width = info.width * scale_factor;
2025 buf_info->info.height = info.height * scale_factor;
2026 buf_info->info.format = info.format;
2027 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2028 buf_info->info.num_planes = 1;
2029 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2030 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2032 if (buf_info->info.size > buf_info->size) {
2033 TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2034 buf_info->info.size, buf_info->size);
2035 tbm_surface_unmap(surface);
2039 if (info.size > buf_info->size) {
2040 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
2041 info.size, buf_info->size);
2042 tbm_surface_unmap(surface);
2046 /* make the file information */
2047 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2050 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2051 postfix = dump_postfix[0];
2052 format = _tbm_surface_internal_format_to_str(info.format);
2054 postfix = dump_postfix[1];
2056 keys = _tbm_surface_internal_get_keys(surface);
2058 TBM_LOG_E("fail to get keys");
2059 tbm_surface_unmap(surface);
2064 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2065 if (!bo_handle.ptr) {
2066 TBM_LOG_E("fail to map bo");
2067 _tbm_surface_internal_put_keys(keys);
2068 tbm_surface_unmap(surface);
2071 memset(bo_handle.ptr, 0x00, buf_info->size);
2073 switch (info.format) {
2074 case TBM_FORMAT_ARGB8888:
2075 case TBM_FORMAT_XRGB8888:
2076 snprintf(buf_info->name, sizeof(buf_info->name),
2077 "%10.3f_%03d%s_%p_%s-%s.%s",
2078 _tbm_surface_internal_get_time(),
2079 g_dump_info->count++, keys, surface, format, type, postfix);
2081 if (scale_factor > 0.0) {
2082 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2084 buf_info->info.format,
2085 info.planes[0].stride,
2086 info.width, info.height,
2087 buf_info->info.planes[0].stride,
2088 buf_info->info.width,
2089 buf_info->info.height);
2090 if (ret != TBM_SURFACE_ERROR_NONE) {
2091 TBM_LOG_E("fail to scale buffer");
2092 tbm_bo_unmap(buf_info->bo);
2093 _tbm_surface_internal_put_keys(keys);
2094 tbm_surface_unmap(surface);
2098 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2100 case TBM_FORMAT_YVU420:
2101 case TBM_FORMAT_YUV420:
2102 snprintf(buf_info->name, sizeof(buf_info->name),
2103 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2104 _tbm_surface_internal_get_time(),
2105 g_dump_info->count++, keys, type, info.planes[0].stride,
2106 info.height, FOURCC_STR(info.format), postfix);
2107 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2108 bo_handle.ptr += info.planes[0].stride * info.height;
2109 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2110 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2111 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2113 case TBM_FORMAT_NV12:
2114 case TBM_FORMAT_NV21:
2115 snprintf(buf_info->name, sizeof(buf_info->name),
2116 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2117 _tbm_surface_internal_get_time(),
2118 g_dump_info->count++, keys, type, info.planes[0].stride,
2119 info.height, FOURCC_STR(info.format), postfix);
2120 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2121 bo_handle.ptr += info.planes[0].stride * info.height;
2122 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2124 case TBM_FORMAT_YUYV:
2125 case TBM_FORMAT_UYVY:
2126 snprintf(buf_info->name, sizeof(buf_info->name),
2127 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2128 _tbm_surface_internal_get_time(),
2129 g_dump_info->count++, keys, type, info.planes[0].stride,
2130 info.height, FOURCC_STR(info.format), postfix);
2131 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2134 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2135 tbm_bo_unmap(buf_info->bo);
2136 _tbm_surface_internal_put_keys(keys);
2137 tbm_surface_unmap(surface);
2141 tbm_bo_unmap(buf_info->bo);
2143 _tbm_surface_internal_put_keys(keys);
2145 tbm_surface_unmap(surface);
2147 buf_info->dirty = 1;
2148 buf_info->dirty_shm = 0;
2150 if (g_dump_info->count == 1000)
2151 g_dump_info->count = 0;
2153 g_dump_info->link = next_link;
2155 TBM_LOG_I("Dump %s \n", buf_info->name);
2158 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2161 TBM_RETURN_IF_FAIL(ptr != NULL);
2162 TBM_RETURN_IF_FAIL(w > 0);
2163 TBM_RETURN_IF_FAIL(h > 0);
2164 TBM_RETURN_IF_FAIL(stride > 0);
2165 TBM_RETURN_IF_FAIL(type != NULL);
2167 tbm_surface_dump_buf_info *buf_info;
2168 struct list_head *next_link;
2169 tbm_bo_handle bo_handle;
2170 int ret, size, dw = 0, dh = 0, dstride = 0;
2175 next_link = g_dump_info->link->next;
2176 TBM_RETURN_IF_FAIL(next_link != NULL);
2178 if (next_link == &g_dump_info->surface_list) {
2179 next_link = next_link->next;
2180 TBM_RETURN_IF_FAIL(next_link != NULL);
2183 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2184 TBM_RETURN_IF_FAIL(buf_info != NULL);
2186 if (scale_factor > 0.0) {
2189 dw = w * scale_factor;
2190 dh = h * scale_factor;
2192 size = dstride * dh;
2196 if (size > buf_info->size) {
2197 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2198 size, buf_info->size);
2203 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2204 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2206 memset(bo_handle.ptr, 0x00, buf_info->size);
2207 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2209 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2210 _tbm_surface_internal_get_time(),
2211 g_dump_info->count++, type, dump_postfix[0]);
2212 if (scale_factor > 0.0) {
2213 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2214 TBM_FORMAT_ARGB8888, stride,
2215 w, h, dstride, dw, dh);
2216 if (ret != TBM_SURFACE_ERROR_NONE) {
2217 TBM_LOG_E("fail to scale buffer");
2218 tbm_bo_unmap(buf_info->bo);
2221 buf_info->shm_stride = dstride;
2222 buf_info->shm_h = dh;
2224 memcpy(bo_handle.ptr, ptr, size);
2225 buf_info->shm_stride = stride;
2226 buf_info->shm_h = h;
2229 tbm_bo_unmap(buf_info->bo);
2231 buf_info->dirty = 0;
2232 buf_info->dirty_shm = 1;
2234 if (g_dump_info->count == 1000)
2235 g_dump_info->count = 0;
2237 g_dump_info->link = next_link;
2239 TBM_LOG_I("Dump %s \n", buf_info->name);
2243 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2245 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2246 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2247 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2249 tbm_surface_info_s info;
2250 const char *postfix;
2254 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2255 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2257 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2258 postfix = dump_postfix[0];
2260 postfix = dump_postfix[1];
2262 if (strcmp(postfix, type)) {
2263 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2264 tbm_surface_unmap(surface);
2268 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2270 if (!access(file, 0)) {
2271 TBM_LOG_E("can't capture buffer, exist file %s", file);
2272 tbm_surface_unmap(surface);
2276 switch (info.format) {
2277 case TBM_FORMAT_ARGB8888:
2278 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2279 info.planes[0].stride >> 2,
2280 info.height, TBM_FORMAT_ARGB8888);
2282 case TBM_FORMAT_XRGB8888:
2283 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2284 info.planes[0].stride >> 2,
2285 info.height, TBM_FORMAT_XRGB8888);
2287 case TBM_FORMAT_YVU420:
2288 case TBM_FORMAT_YUV420:
2289 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2290 info.planes[0].stride * info.height,
2292 info.planes[1].stride * (info.height >> 1),
2294 info.planes[2].stride * (info.height >> 1));
2296 case TBM_FORMAT_NV12:
2297 case TBM_FORMAT_NV21:
2298 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2299 info.planes[0].stride * info.height,
2301 info.planes[1].stride * (info.height >> 1),
2304 case TBM_FORMAT_YUYV:
2305 case TBM_FORMAT_UYVY:
2306 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2307 info.planes[0].stride * info.height,
2311 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2312 tbm_surface_unmap(surface);
2316 tbm_surface_unmap(surface);
2318 TBM_TRACE("Capture %s \n", file);
2324 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2325 const char *path, const char *name, const char *type)
2327 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2328 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2329 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2330 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2331 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2332 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2336 if (strcmp(dump_postfix[0], type)) {
2337 TBM_LOG_E("Not supported type:%s'", type);
2341 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2343 if (!access(file, 0)) {
2344 TBM_LOG_E("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2348 _tbm_surface_internal_dump_file_png(file, ptr, stride, h, 0);
2350 TBM_TRACE("Capture %s \n", file);