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 TBM_RETURN_VAL_IF_FAIL(formats, 0);
422 TBM_RETURN_VAL_IF_FAIL(num, 0);
424 struct _tbm_bufmgr *mgr;
426 bool bufmgr_initialized = false;
428 _tbm_surface_mutex_lock();
430 if (!g_surface_bufmgr) {
431 _init_surface_bufmgr();
432 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
433 bufmgr_initialized = true;
436 mgr = g_surface_bufmgr;
438 if (!mgr->backend->surface_supported_format)
441 ret = mgr->backend->surface_supported_format(formats, num);
443 /* LCOV_EXCL_START */
444 TBM_LOG_E("Fail to surface_supported_format.\n");
446 /* LCOV_EXCL_START */
449 TBM_TRACE("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
451 _tbm_surface_mutex_unlock();
455 /* LCOV_EXCL_START */
457 if (bufmgr_initialized) {
458 LIST_DELINIT(&g_surface_bufmgr->surf_list);
459 _deinit_surface_bufmgr();
461 _tbm_surface_mutex_unlock();
463 TBM_LOG_E("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
470 tbm_surface_internal_get_num_planes(tbm_format format)
476 case TBM_FORMAT_RGB332:
477 case TBM_FORMAT_BGR233:
478 case TBM_FORMAT_XRGB4444:
479 case TBM_FORMAT_XBGR4444:
480 case TBM_FORMAT_RGBX4444:
481 case TBM_FORMAT_BGRX4444:
482 case TBM_FORMAT_ARGB4444:
483 case TBM_FORMAT_ABGR4444:
484 case TBM_FORMAT_RGBA4444:
485 case TBM_FORMAT_BGRA4444:
486 case TBM_FORMAT_XRGB1555:
487 case TBM_FORMAT_XBGR1555:
488 case TBM_FORMAT_RGBX5551:
489 case TBM_FORMAT_BGRX5551:
490 case TBM_FORMAT_ARGB1555:
491 case TBM_FORMAT_ABGR1555:
492 case TBM_FORMAT_RGBA5551:
493 case TBM_FORMAT_BGRA5551:
494 case TBM_FORMAT_RGB565:
495 case TBM_FORMAT_BGR565:
496 case TBM_FORMAT_RGB888:
497 case TBM_FORMAT_BGR888:
498 case TBM_FORMAT_XRGB8888:
499 case TBM_FORMAT_XBGR8888:
500 case TBM_FORMAT_RGBX8888:
501 case TBM_FORMAT_BGRX8888:
502 case TBM_FORMAT_ARGB8888:
503 case TBM_FORMAT_ABGR8888:
504 case TBM_FORMAT_RGBA8888:
505 case TBM_FORMAT_BGRA8888:
506 case TBM_FORMAT_XRGB2101010:
507 case TBM_FORMAT_XBGR2101010:
508 case TBM_FORMAT_RGBX1010102:
509 case TBM_FORMAT_BGRX1010102:
510 case TBM_FORMAT_ARGB2101010:
511 case TBM_FORMAT_ABGR2101010:
512 case TBM_FORMAT_RGBA1010102:
513 case TBM_FORMAT_BGRA1010102:
514 case TBM_FORMAT_YUYV:
515 case TBM_FORMAT_YVYU:
516 case TBM_FORMAT_UYVY:
517 case TBM_FORMAT_VYUY:
518 case TBM_FORMAT_AYUV:
521 case TBM_FORMAT_NV12:
522 case TBM_FORMAT_NV12MT:
523 case TBM_FORMAT_NV21:
524 case TBM_FORMAT_NV16:
525 case TBM_FORMAT_NV61:
528 case TBM_FORMAT_YUV410:
529 case TBM_FORMAT_YVU410:
530 case TBM_FORMAT_YUV411:
531 case TBM_FORMAT_YVU411:
532 case TBM_FORMAT_YUV420:
533 case TBM_FORMAT_YVU420:
534 case TBM_FORMAT_YUV422:
535 case TBM_FORMAT_YVU422:
536 case TBM_FORMAT_YUV444:
537 case TBM_FORMAT_YVU444:
545 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
551 tbm_surface_internal_get_bpp(tbm_format format)
558 case TBM_FORMAT_RGB332:
559 case TBM_FORMAT_BGR233:
562 case TBM_FORMAT_XRGB4444:
563 case TBM_FORMAT_XBGR4444:
564 case TBM_FORMAT_RGBX4444:
565 case TBM_FORMAT_BGRX4444:
566 case TBM_FORMAT_ARGB4444:
567 case TBM_FORMAT_ABGR4444:
568 case TBM_FORMAT_RGBA4444:
569 case TBM_FORMAT_BGRA4444:
570 case TBM_FORMAT_XRGB1555:
571 case TBM_FORMAT_XBGR1555:
572 case TBM_FORMAT_RGBX5551:
573 case TBM_FORMAT_BGRX5551:
574 case TBM_FORMAT_ARGB1555:
575 case TBM_FORMAT_ABGR1555:
576 case TBM_FORMAT_RGBA5551:
577 case TBM_FORMAT_BGRA5551:
578 case TBM_FORMAT_RGB565:
579 case TBM_FORMAT_BGR565:
582 case TBM_FORMAT_RGB888:
583 case TBM_FORMAT_BGR888:
586 case TBM_FORMAT_XRGB8888:
587 case TBM_FORMAT_XBGR8888:
588 case TBM_FORMAT_RGBX8888:
589 case TBM_FORMAT_BGRX8888:
590 case TBM_FORMAT_ARGB8888:
591 case TBM_FORMAT_ABGR8888:
592 case TBM_FORMAT_RGBA8888:
593 case TBM_FORMAT_BGRA8888:
594 case TBM_FORMAT_XRGB2101010:
595 case TBM_FORMAT_XBGR2101010:
596 case TBM_FORMAT_RGBX1010102:
597 case TBM_FORMAT_BGRX1010102:
598 case TBM_FORMAT_ARGB2101010:
599 case TBM_FORMAT_ABGR2101010:
600 case TBM_FORMAT_RGBA1010102:
601 case TBM_FORMAT_BGRA1010102:
602 case TBM_FORMAT_YUYV:
603 case TBM_FORMAT_YVYU:
604 case TBM_FORMAT_UYVY:
605 case TBM_FORMAT_VYUY:
606 case TBM_FORMAT_AYUV:
609 case TBM_FORMAT_NV12:
610 case TBM_FORMAT_NV12MT:
611 case TBM_FORMAT_NV21:
614 case TBM_FORMAT_NV16:
615 case TBM_FORMAT_NV61:
618 case TBM_FORMAT_YUV410:
619 case TBM_FORMAT_YVU410:
622 case TBM_FORMAT_YUV411:
623 case TBM_FORMAT_YVU411:
624 case TBM_FORMAT_YUV420:
625 case TBM_FORMAT_YVU420:
628 case TBM_FORMAT_YUV422:
629 case TBM_FORMAT_YVU422:
632 case TBM_FORMAT_YUV444:
633 case TBM_FORMAT_YVU444:
640 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
646 tbm_surface_internal_create_with_flags(int width, int height,
647 int format, int flags)
649 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
650 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
652 struct _tbm_bufmgr *mgr;
653 struct _tbm_surface *surf = NULL;
657 uint32_t bo_size = 0;
660 bool bufmgr_initialized = false;
662 _tbm_surface_mutex_lock();
664 if (!g_surface_bufmgr) {
665 _init_surface_bufmgr();
666 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
667 bufmgr_initialized = true;
670 mgr = g_surface_bufmgr;
671 if (!TBM_BUFMGR_IS_VALID(mgr)) {
672 TBM_LOG_E("The bufmgr is invalid\n");
673 goto check_valid_fail;
676 surf = calloc(1, sizeof(struct _tbm_surface));
678 /* LCOV_EXCL_START */
679 TBM_LOG_E("fail to alloc surf\n");
680 goto alloc_surf_fail;
685 surf->info.width = width;
686 surf->info.height = height;
687 surf->info.format = format;
688 surf->info.bpp = tbm_surface_internal_get_bpp(format);
689 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
692 /* get size, stride and offset bo_idx */
693 for (i = 0; i < surf->info.num_planes; i++) {
694 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
695 &offset, &stride, &bo_idx)) {
696 TBM_LOG_E("fail to query plane data\n");
697 goto query_plane_data_fail;
700 surf->info.planes[i].size = size;
701 surf->info.planes[i].offset = offset;
702 surf->info.planes[i].stride = stride;
703 surf->planes_bo_idx[i] = bo_idx;
708 for (i = 0; i < surf->info.num_planes; i++) {
709 surf->info.size += surf->info.planes[i].size;
711 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
712 surf->num_bos = surf->planes_bo_idx[i] + 1;
717 for (i = 0; i < surf->num_bos; i++) {
719 for (j = 0; j < surf->info.num_planes; j++) {
720 if (surf->planes_bo_idx[j] == i)
721 bo_size += surf->info.planes[j].size;
724 if (mgr->backend->surface_bo_alloc) {
725 /* LCOV_EXCL_START */
727 void *bo_priv = NULL;
729 bo = calloc(1, sizeof(struct _tbm_bo));
731 TBM_LOG_E("fail to alloc bo struct\n");
735 bo->bufmgr = surf->bufmgr;
737 pthread_mutex_lock(&surf->bufmgr->lock);
739 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
741 TBM_LOG_E("fail to alloc bo priv\n");
743 pthread_mutex_unlock(&surf->bufmgr->lock);
751 LIST_INITHEAD(&bo->user_data_list);
753 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
755 pthread_mutex_unlock(&surf->bufmgr->lock);
760 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
762 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
767 _tbm_bo_set_surface(surf->bos[i], surf);
770 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
771 _tbm_surface_internal_format_to_str(format), flags, surf);
773 LIST_INITHEAD(&surf->user_data_list);
774 LIST_INITHEAD(&surf->debug_data_list);
776 LIST_ADD(&surf->item_link, &mgr->surf_list);
778 _tbm_surface_mutex_unlock();
782 /* LCOV_EXCL_START */
784 for (j = 0; j < i; j++) {
786 tbm_bo_unref(surf->bos[j]);
788 query_plane_data_fail:
792 if (bufmgr_initialized && mgr) {
793 LIST_DELINIT(&mgr->surf_list);
794 _deinit_surface_bufmgr();
796 _tbm_surface_mutex_unlock();
798 TBM_LOG_E("error: width(%d) height(%d) format(%s) flags(%d)\n",
800 _tbm_surface_internal_format_to_str(format), flags);
807 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
808 tbm_bo *bos, int num)
810 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
811 TBM_RETURN_VAL_IF_FAIL(info, NULL);
812 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
814 struct _tbm_bufmgr *mgr;
815 struct _tbm_surface *surf = NULL;
817 bool bufmgr_initialized = false;
819 _tbm_surface_mutex_lock();
821 if (!g_surface_bufmgr) {
822 _init_surface_bufmgr();
823 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
824 bufmgr_initialized = true;
827 mgr = g_surface_bufmgr;
828 if (!TBM_BUFMGR_IS_VALID(mgr)) {
829 TBM_LOG_E("fail to validate the Bufmgr.\n");
830 goto check_valid_fail;
833 surf = calloc(1, sizeof(struct _tbm_surface));
835 /* LCOV_EXCL_START */
836 TBM_LOG_E("fail to allocate struct _tbm_surface.\n");
837 goto alloc_surf_fail;
842 surf->info.width = info->width;
843 surf->info.height = info->height;
844 surf->info.format = info->format;
846 surf->info.bpp = info->bpp;
848 surf->info.bpp = tbm_surface_internal_get_bpp(info->format);
849 surf->info.num_planes = info->num_planes;
852 /* get size, stride and offset */
853 for (i = 0; i < info->num_planes; i++) {
854 surf->info.planes[i].offset = info->planes[i].offset;
855 surf->info.planes[i].stride = info->planes[i].stride;
857 if (info->planes[i].size > 0)
858 surf->info.planes[i].size = info->planes[i].size;
860 uint32_t size = 0, offset = 0, stride = 0;
863 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
864 surf->info.planes[i].size = size;
868 surf->planes_bo_idx[i] = 0;
870 surf->planes_bo_idx[i] = i;
873 if (info->size > 0) {
874 surf->info.size = info->size;
877 for (i = 0; i < info->num_planes; i++)
878 surf->info.size += surf->info.planes[i].size;
881 surf->flags = TBM_BO_DEFAULT;
883 /* create only one bo */
885 for (i = 0; i < num; i++) {
886 if (bos[i] == NULL) {
887 TBM_LOG_E("bos[%d] is null.\n", i);
891 surf->bos[i] = tbm_bo_ref(bos[i]);
892 _tbm_bo_set_surface(bos[i], surf);
895 TBM_TRACE("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
896 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
898 LIST_INITHEAD(&surf->user_data_list);
899 LIST_INITHEAD(&surf->debug_data_list);
901 LIST_ADD(&surf->item_link, &mgr->surf_list);
903 _tbm_surface_mutex_unlock();
907 /* LCOV_EXCL_START */
909 for (i = 0; i < num; i++) {
911 tbm_bo_unref(surf->bos[i]);
916 if (bufmgr_initialized && mgr) {
917 LIST_DELINIT(&mgr->surf_list);
918 _deinit_surface_bufmgr();
920 _tbm_surface_mutex_unlock();
922 TBM_LOG_E("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
923 info->width, info->height,
924 _tbm_surface_internal_format_to_str(info->format), num);
931 tbm_surface_internal_destroy(tbm_surface_h surface)
933 _tbm_surface_mutex_lock();
935 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
939 if (surface->refcnt > 0) {
940 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
941 _tbm_surface_mutex_unlock();
945 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
947 if (surface->refcnt == 0)
948 _tbm_surface_internal_destroy(surface);
950 _tbm_surface_mutex_unlock();
954 tbm_surface_internal_ref(tbm_surface_h surface)
956 _tbm_surface_mutex_lock();
958 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
962 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
964 _tbm_surface_mutex_unlock();
968 tbm_surface_internal_unref(tbm_surface_h surface)
970 _tbm_surface_mutex_lock();
972 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
976 if (surface->refcnt > 0) {
977 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
978 _tbm_surface_mutex_unlock();
982 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
984 if (surface->refcnt == 0)
985 _tbm_surface_internal_destroy(surface);
987 _tbm_surface_mutex_unlock();
991 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
993 struct _tbm_surface *surf;
996 _tbm_surface_mutex_lock();
998 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1000 surf = (struct _tbm_surface *)surface;
1001 num = surf->num_bos;
1003 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
1005 _tbm_surface_mutex_unlock();
1011 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1013 struct _tbm_surface *surf;
1016 _tbm_surface_mutex_lock();
1018 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1019 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1021 surf = (struct _tbm_surface *)surface;
1022 bo = surf->bos[bo_idx];
1024 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1026 _tbm_surface_mutex_unlock();
1032 tbm_surface_internal_get_size(tbm_surface_h surface)
1034 struct _tbm_surface *surf;
1037 _tbm_surface_mutex_lock();
1039 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1041 surf = (struct _tbm_surface *)surface;
1042 size = surf->info.size;
1044 TBM_TRACE("tbm_surface(%p) size(%u)\n", surface, size);
1046 _tbm_surface_mutex_unlock();
1052 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1053 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1055 struct _tbm_surface *surf;
1057 _tbm_surface_mutex_lock();
1059 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1060 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1062 surf = (struct _tbm_surface *)surface;
1064 if (plane_idx >= surf->info.num_planes) {
1065 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1066 _tbm_surface_mutex_unlock();
1071 *size = surf->info.planes[plane_idx].size;
1074 *offset = surf->info.planes[plane_idx].offset;
1077 *pitch = surf->info.planes[plane_idx].stride;
1079 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1080 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1081 surf->info.planes[plane_idx].stride);
1083 _tbm_surface_mutex_unlock();
1089 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1090 tbm_surface_info_s *info, int map)
1092 struct _tbm_surface *surf;
1093 tbm_bo_handle bo_handles[4];
1096 _tbm_surface_mutex_lock();
1098 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1100 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1102 surf = (struct _tbm_surface *)surface;
1104 memset(info, 0x00, sizeof(tbm_surface_info_s));
1105 info->width = surf->info.width;
1106 info->height = surf->info.height;
1107 info->format = surf->info.format;
1108 info->bpp = surf->info.bpp;
1109 info->size = surf->info.size;
1110 info->num_planes = surf->info.num_planes;
1113 for (i = 0; i < surf->num_bos; i++) {
1114 _tbm_surface_mutex_unlock();
1115 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1116 _tbm_surface_mutex_lock();
1117 if (bo_handles[i].ptr == NULL) {
1118 for (j = 0; j < i; j++)
1119 tbm_bo_unmap(surf->bos[j]);
1121 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1122 _tbm_surface_mutex_unlock();
1127 for (i = 0; i < surf->num_bos; i++) {
1128 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1129 if (bo_handles[i].ptr == NULL) {
1130 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1131 _tbm_surface_mutex_unlock();
1137 for (i = 0; i < surf->info.num_planes; i++) {
1138 info->planes[i].size = surf->info.planes[i].size;
1139 info->planes[i].offset = surf->info.planes[i].offset;
1140 info->planes[i].stride = surf->info.planes[i].stride;
1142 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1143 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1144 surf->info.planes[i].offset;
1147 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1149 _tbm_surface_mutex_unlock();
1155 tbm_surface_internal_unmap(tbm_surface_h surface)
1157 struct _tbm_surface *surf;
1160 _tbm_surface_mutex_lock();
1162 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1164 surf = (struct _tbm_surface *)surface;
1166 for (i = 0; i < surf->num_bos; i++)
1167 tbm_bo_unmap(surf->bos[i]);
1169 TBM_TRACE("tbm_surface(%p)\n", surface);
1171 _tbm_surface_mutex_unlock();
1175 tbm_surface_internal_get_width(tbm_surface_h surface)
1177 struct _tbm_surface *surf;
1180 _tbm_surface_mutex_lock();
1182 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1184 surf = (struct _tbm_surface *)surface;
1185 width = surf->info.width;
1187 TBM_TRACE("tbm_surface(%p) width(%u)\n", surface, width);
1189 _tbm_surface_mutex_unlock();
1195 tbm_surface_internal_get_height(tbm_surface_h surface)
1197 struct _tbm_surface *surf;
1198 unsigned int height;
1200 _tbm_surface_mutex_lock();
1202 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1204 surf = (struct _tbm_surface *)surface;
1205 height = surf->info.height;
1207 TBM_TRACE("tbm_surface(%p) height(%u)\n", surface, height);
1209 _tbm_surface_mutex_unlock();
1216 tbm_surface_internal_get_format(tbm_surface_h surface)
1218 struct _tbm_surface *surf;
1221 _tbm_surface_mutex_lock();
1223 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1225 surf = (struct _tbm_surface *)surface;
1226 format = surf->info.format;
1228 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1230 _tbm_surface_mutex_unlock();
1236 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1238 struct _tbm_surface *surf;
1241 _tbm_surface_mutex_lock();
1243 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1244 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1246 surf = (struct _tbm_surface *)surface;
1247 bo_idx = surf->planes_bo_idx[plane_idx];
1249 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1251 _tbm_surface_mutex_unlock();
1257 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1258 tbm_data_free data_free_func)
1260 tbm_user_data *data;
1262 _tbm_surface_mutex_lock();
1264 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1266 /* check if the data according to the key exist if so, return false. */
1267 data = user_data_lookup(&surface->user_data_list, key);
1269 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1270 _tbm_surface_mutex_unlock();
1274 data = user_data_create(key, data_free_func);
1276 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1277 _tbm_surface_mutex_unlock();
1281 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1283 LIST_ADD(&data->item_link, &surface->user_data_list);
1285 _tbm_surface_mutex_unlock();
1291 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1294 tbm_user_data *old_data;
1296 _tbm_surface_mutex_lock();
1298 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1300 old_data = user_data_lookup(&surface->user_data_list, key);
1302 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1303 _tbm_surface_mutex_unlock();
1307 if (old_data->data && old_data->free_func)
1308 old_data->free_func(old_data->data);
1310 old_data->data = data;
1312 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1314 _tbm_surface_mutex_unlock();
1320 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1323 tbm_user_data *old_data;
1325 _tbm_surface_mutex_lock();
1327 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1330 TBM_LOG_E("error: tbm_surface(%p) key(%lu)\n", surface, key);
1331 _tbm_surface_mutex_unlock();
1336 old_data = user_data_lookup(&surface->user_data_list, key);
1338 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1339 _tbm_surface_mutex_unlock();
1343 *data = old_data->data;
1345 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1347 _tbm_surface_mutex_unlock();
1353 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1356 tbm_user_data *old_data = (void *)0;
1358 _tbm_surface_mutex_lock();
1360 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1362 old_data = user_data_lookup(&surface->user_data_list, key);
1364 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1365 _tbm_surface_mutex_unlock();
1369 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1371 user_data_delete(old_data);
1373 _tbm_surface_mutex_unlock();
1378 /* LCOV_EXCL_START */
1380 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1382 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1384 return surface->debug_pid;
1388 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1390 _tbm_surface_mutex_lock();
1392 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1394 surface->debug_pid = pid;
1396 _tbm_surface_mutex_unlock();
1399 static tbm_surface_debug_data *
1400 _tbm_surface_internal_debug_data_create(char *key, char *value)
1402 tbm_surface_debug_data *debug_data = NULL;
1404 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1408 if (key) debug_data->key = strdup(key);
1409 if (value) debug_data->value = strdup(value);
1415 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1417 tbm_surface_debug_data *debug_data = NULL;
1418 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1419 tbm_bufmgr bufmgr = NULL;
1421 _tbm_surface_mutex_lock();
1423 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1424 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1426 bufmgr = surface->bufmgr;
1428 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1430 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1431 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1433 if (!strcmp(old_data->key, key)) {
1434 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1435 TBM_TRACE("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1436 goto add_debug_key_list;
1439 if (old_data->value)
1440 free(old_data->value);
1443 old_data->value = strdup(value);
1445 old_data->value = NULL;
1447 goto add_debug_key_list;
1453 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1455 TBM_LOG_E("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1456 _tbm_surface_mutex_unlock();
1460 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1462 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1465 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1466 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1467 if (!strcmp(old_data->key, key)) {
1468 _tbm_surface_mutex_unlock();
1474 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1475 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1477 _tbm_surface_mutex_unlock();
1483 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1485 tbm_surface_debug_data *old_data = NULL;
1487 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1489 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1490 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1491 if (!strcmp(old_data->key, key))
1492 return old_data->value;
1499 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1500 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1502 struct _tbm_surface_dump_buf_info {
1512 tbm_surface_info_s info;
1514 struct list_head link;
1517 struct _tbm_surface_dump_info {
1518 char *path; // copy???
1521 struct list_head *link;
1522 struct list_head surface_list; /* link of surface */
1525 static tbm_surface_dump_info *g_dump_info = NULL;
1526 static const char *dump_postfix[2] = {"png", "yuv"};
1527 static double scale_factor;
1530 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1531 void *data2, int size2, void *data3, int size3)
1534 unsigned int *blocks;
1536 if (!_tbm_surface_check_file_is_valid(file, 1))
1537 TBM_LOG_E("%s is symbolic link\n", file);
1539 fp = fopen(file, "w+");
1540 TBM_RETURN_IF_FAIL(fp != NULL);
1542 blocks = (unsigned int *)data1;
1543 fwrite(blocks, 1, size1, fp);
1546 blocks = (unsigned int *)data2;
1547 fwrite(blocks, 1, size2, fp);
1551 blocks = (unsigned int *)data3;
1552 fwrite(blocks, 1, size3, fp);
1559 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1561 unsigned int *blocks = (unsigned int *)data;
1564 png_bytep *row_pointers;
1567 if (!_tbm_surface_check_file_is_valid(file, 1))
1568 TBM_LOG_E("%s is symbolic link\n", file);
1570 fp = fopen(file, "wb");
1571 TBM_RETURN_IF_FAIL(fp != NULL);
1573 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1576 TBM_LOG_E("fail to create a png write structure.\n");
1581 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1583 TBM_LOG_E("fail to create a png info structure.\n");
1584 png_destroy_write_struct(&pPngStruct, NULL);
1589 png_init_io(pPngStruct, fp);
1590 if (format == TBM_FORMAT_XRGB8888) {
1592 png_set_IHDR(pPngStruct,
1599 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1602 png_set_IHDR(pPngStruct,
1607 PNG_COLOR_TYPE_RGBA,
1609 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1612 png_set_bgr(pPngStruct);
1613 png_write_info(pPngStruct, pPngInfo);
1615 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1616 if (!row_pointers) {
1617 TBM_LOG_E("fail to allocate the png row_pointers.\n");
1618 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1623 for (y = 0; y < height; ++y) {
1627 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1629 TBM_LOG_E("fail to allocate the png row.\n");
1630 for (x = 0; x < y; x++)
1631 png_free(pPngStruct, row_pointers[x]);
1632 png_free(pPngStruct, row_pointers);
1633 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1637 row_pointers[y] = (png_bytep)row;
1639 for (x = 0; x < width; ++x) {
1640 unsigned int curBlock = blocks[y * width + x];
1642 if (pixel_size == 3) { // XRGB8888
1643 row[x * pixel_size] = (curBlock & 0xFF);
1644 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1645 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1646 } else { // ARGB8888
1647 row[x * pixel_size] = (curBlock & 0xFF);
1648 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1649 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1650 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1655 png_write_image(pPngStruct, row_pointers);
1656 png_write_end(pPngStruct, pPngInfo);
1658 for (y = 0; y < height; y++)
1659 png_free(pPngStruct, row_pointers[y]);
1660 png_free(pPngStruct, row_pointers);
1662 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1668 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1670 TBM_RETURN_IF_FAIL(path != NULL);
1671 TBM_RETURN_IF_FAIL(w > 0);
1672 TBM_RETURN_IF_FAIL(h > 0);
1673 TBM_RETURN_IF_FAIL(count > 0);
1675 tbm_surface_dump_buf_info *buf_info = NULL;
1676 tbm_surface_h tbm_surface;
1677 tbm_surface_info_s info;
1682 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1686 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1687 TBM_RETURN_IF_FAIL(g_dump_info);
1689 LIST_INITHEAD(&g_dump_info->surface_list);
1690 g_dump_info->count = 0;
1691 g_dump_info->dump_max = count;
1693 /* get buffer size */
1694 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1695 if (tbm_surface == NULL) {
1696 TBM_LOG_E("tbm_surface_create fail\n");
1702 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1703 TBM_LOG_E("tbm_surface_get_info fail\n");
1704 tbm_surface_destroy(tbm_surface);
1709 buffer_size = info.size;
1710 tbm_surface_destroy(tbm_surface);
1712 /* create dump lists */
1713 for (i = 0; i < count; i++) {
1716 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1717 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1719 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1721 TBM_LOG_E("fail to allocate the tbm_bo[%d]\n", i);
1726 buf_info->index = i;
1728 buf_info->size = buffer_size;
1730 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1733 g_dump_info->path = path;
1734 g_dump_info->link = &g_dump_info->surface_list;
1738 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1743 /* free resources */
1744 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1745 tbm_surface_dump_buf_info *tmp;
1747 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1748 tbm_bo_unref(buf_info->bo);
1749 LIST_DEL(&buf_info->link);
1754 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1763 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1770 tbm_surface_internal_dump_start(path, w, h, count);
1771 scale_factor = scale;
1775 tbm_surface_internal_dump_end(void)
1777 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1778 tbm_bo_handle bo_handle;
1783 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1790 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1793 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1794 if (bo_handle.ptr == NULL) {
1795 tbm_bo_unref(buf_info->bo);
1796 LIST_DEL(&buf_info->link);
1801 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1802 TBM_LOG_I("Dump File.. %s generated.\n", file);
1804 if (buf_info->dirty) {
1805 void *ptr1 = NULL, *ptr2 = NULL;
1807 switch (buf_info->info.format) {
1808 case TBM_FORMAT_ARGB8888:
1809 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1810 buf_info->info.planes[0].stride >> 2,
1811 buf_info->info.height, TBM_FORMAT_ARGB8888);
1813 case TBM_FORMAT_XRGB8888:
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_XRGB8888);
1818 case TBM_FORMAT_YVU420:
1819 case TBM_FORMAT_YUV420:
1820 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1821 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1822 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1823 buf_info->info.planes[0].stride * buf_info->info.height,
1825 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1827 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1829 case TBM_FORMAT_NV12:
1830 case TBM_FORMAT_NV21:
1831 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1832 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1833 buf_info->info.planes[0].stride * buf_info->info.height,
1835 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1838 case TBM_FORMAT_YUYV:
1839 case TBM_FORMAT_UYVY:
1840 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1841 buf_info->info.planes[0].stride * buf_info->info.height,
1845 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1848 } else if (buf_info->dirty_shm)
1849 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1850 buf_info->shm_stride >> 2,
1851 buf_info->shm_h, 0);
1853 tbm_bo_unmap(buf_info->bo);
1854 tbm_bo_unref(buf_info->bo);
1855 LIST_DEL(&buf_info->link);
1862 TBM_LOG_I("Dump End..\n");
1865 static pixman_format_code_t
1866 _tbm_surface_internal_pixman_format_get(tbm_format format)
1869 case TBM_FORMAT_ARGB8888:
1870 return PIXMAN_a8r8g8b8;
1871 case TBM_FORMAT_XRGB8888:
1872 return PIXMAN_x8r8g8b8;
1881 * This function supports only if a buffer has below formats.
1882 * - TBM_FORMAT_ARGB8888
1883 * - TBM_FORMAT_XRGB8888
1885 static tbm_surface_error_e
1886 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1887 int format, int src_stride, int src_w, int src_h,
1888 int dst_stride, int dst_w, int dst_h)
1890 pixman_image_t *src_img = NULL, *dst_img = NULL;
1891 pixman_format_code_t pixman_format;
1892 pixman_transform_t t;
1893 struct pixman_f_transform ft;
1894 double scale_x, scale_y;
1896 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1897 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1899 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1900 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1903 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1904 (uint32_t*)src_ptr, src_stride);
1905 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1908 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1909 (uint32_t*)dst_ptr, dst_stride);
1910 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1912 pixman_f_transform_init_identity(&ft);
1914 scale_x = (double)src_w / dst_w;
1915 scale_y = (double)src_h / dst_h;
1917 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
1918 pixman_f_transform_translate(&ft, NULL, 0, 0);
1919 pixman_transform_from_pixman_f_transform(&t, &ft);
1920 pixman_image_set_transform(src_img, &t);
1922 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
1923 0, 0, 0, 0, 0, 0, dst_w, dst_h);
1925 pixman_image_unref(src_img);
1926 pixman_image_unref(dst_img);
1928 return TBM_SURFACE_ERROR_NONE;
1932 pixman_image_unref(src_img);
1934 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1937 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
1938 #define KEY_LEN 5 // "_XXXX"
1939 #define KEYS_LEN KEY_LEN * MAX_BOS
1941 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
1943 char *keys, temp_key[KEY_LEN + 1];
1944 struct _tbm_surface *surf;
1948 _tbm_surface_mutex_lock();
1950 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1952 surf = (struct _tbm_surface *)surface;
1954 num_bos = surf->num_bos;
1955 if (num_bos > MAX_BOS)
1958 keys = calloc(KEYS_LEN + 1, sizeof(char));
1960 TBM_LOG_E("Failed to alloc memory");
1961 _tbm_surface_mutex_unlock();
1965 for (i = 0; i < num_bos; i++) {
1966 memset(temp_key, 0x00, KEY_LEN + 1);
1968 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
1969 strncat(keys, temp_key, KEY_LEN);
1972 _tbm_surface_mutex_unlock();
1977 static void _tbm_surface_internal_put_keys(char *keys)
1984 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1986 TBM_RETURN_IF_FAIL(surface != NULL);
1987 TBM_RETURN_IF_FAIL(type != NULL);
1989 tbm_surface_dump_buf_info *buf_info;
1990 struct list_head *next_link;
1991 tbm_surface_info_s info;
1992 tbm_bo_handle bo_handle;
1993 const char *postfix;
1994 const char *format = NULL;
2001 next_link = g_dump_info->link->next;
2002 TBM_RETURN_IF_FAIL(next_link != NULL);
2004 if (next_link == &g_dump_info->surface_list) {
2005 next_link = next_link->next;
2006 TBM_RETURN_IF_FAIL(next_link != NULL);
2009 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2010 TBM_RETURN_IF_FAIL(buf_info != NULL);
2012 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2013 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2015 if (scale_factor > 0.0) {
2018 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2019 TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n",
2020 _tbm_surface_internal_format_to_str(info.format));
2021 tbm_surface_unmap(surface);
2025 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2027 buf_info->info.width = info.width * scale_factor;
2028 buf_info->info.height = info.height * scale_factor;
2029 buf_info->info.format = info.format;
2030 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2031 buf_info->info.num_planes = 1;
2032 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2033 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2035 if (buf_info->info.size > buf_info->size) {
2036 TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2037 buf_info->info.size, buf_info->size);
2038 tbm_surface_unmap(surface);
2042 if (info.size > buf_info->size) {
2043 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
2044 info.size, buf_info->size);
2045 tbm_surface_unmap(surface);
2049 /* make the file information */
2050 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2053 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2054 postfix = dump_postfix[0];
2055 format = _tbm_surface_internal_format_to_str(info.format);
2057 postfix = dump_postfix[1];
2059 keys = _tbm_surface_internal_get_keys(surface);
2061 TBM_LOG_E("fail to get keys");
2062 tbm_surface_unmap(surface);
2067 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2068 if (!bo_handle.ptr) {
2069 TBM_LOG_E("fail to map bo");
2070 _tbm_surface_internal_put_keys(keys);
2071 tbm_surface_unmap(surface);
2074 memset(bo_handle.ptr, 0x00, buf_info->size);
2076 switch (info.format) {
2077 case TBM_FORMAT_ARGB8888:
2078 case TBM_FORMAT_XRGB8888:
2079 snprintf(buf_info->name, sizeof(buf_info->name),
2080 "%10.3f_%03d%s_%p_%s-%s.%s",
2081 _tbm_surface_internal_get_time(),
2082 g_dump_info->count++, keys, surface, format, type, postfix);
2084 if (scale_factor > 0.0) {
2085 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2087 buf_info->info.format,
2088 info.planes[0].stride,
2089 info.width, info.height,
2090 buf_info->info.planes[0].stride,
2091 buf_info->info.width,
2092 buf_info->info.height);
2093 if (ret != TBM_SURFACE_ERROR_NONE) {
2094 TBM_LOG_E("fail to scale buffer");
2095 tbm_bo_unmap(buf_info->bo);
2096 _tbm_surface_internal_put_keys(keys);
2097 tbm_surface_unmap(surface);
2101 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2103 case TBM_FORMAT_YVU420:
2104 case TBM_FORMAT_YUV420:
2105 snprintf(buf_info->name, sizeof(buf_info->name),
2106 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2107 _tbm_surface_internal_get_time(),
2108 g_dump_info->count++, keys, type, info.planes[0].stride,
2109 info.height, FOURCC_STR(info.format), postfix);
2110 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2111 bo_handle.ptr += info.planes[0].stride * info.height;
2112 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2113 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2114 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2116 case TBM_FORMAT_NV12:
2117 case TBM_FORMAT_NV21:
2118 snprintf(buf_info->name, sizeof(buf_info->name),
2119 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2120 _tbm_surface_internal_get_time(),
2121 g_dump_info->count++, keys, type, info.planes[0].stride,
2122 info.height, FOURCC_STR(info.format), postfix);
2123 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2124 bo_handle.ptr += info.planes[0].stride * info.height;
2125 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2127 case TBM_FORMAT_YUYV:
2128 case TBM_FORMAT_UYVY:
2129 snprintf(buf_info->name, sizeof(buf_info->name),
2130 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2131 _tbm_surface_internal_get_time(),
2132 g_dump_info->count++, keys, type, info.planes[0].stride,
2133 info.height, FOURCC_STR(info.format), postfix);
2134 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2137 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2138 tbm_bo_unmap(buf_info->bo);
2139 _tbm_surface_internal_put_keys(keys);
2140 tbm_surface_unmap(surface);
2144 tbm_bo_unmap(buf_info->bo);
2146 _tbm_surface_internal_put_keys(keys);
2148 tbm_surface_unmap(surface);
2150 buf_info->dirty = 1;
2151 buf_info->dirty_shm = 0;
2153 if (g_dump_info->count == 1000)
2154 g_dump_info->count = 0;
2156 g_dump_info->link = next_link;
2158 TBM_LOG_I("Dump %s \n", buf_info->name);
2161 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2164 TBM_RETURN_IF_FAIL(ptr != NULL);
2165 TBM_RETURN_IF_FAIL(w > 0);
2166 TBM_RETURN_IF_FAIL(h > 0);
2167 TBM_RETURN_IF_FAIL(stride > 0);
2168 TBM_RETURN_IF_FAIL(type != NULL);
2170 tbm_surface_dump_buf_info *buf_info;
2171 struct list_head *next_link;
2172 tbm_bo_handle bo_handle;
2173 int ret, size, dw = 0, dh = 0, dstride = 0;
2178 next_link = g_dump_info->link->next;
2179 TBM_RETURN_IF_FAIL(next_link != NULL);
2181 if (next_link == &g_dump_info->surface_list) {
2182 next_link = next_link->next;
2183 TBM_RETURN_IF_FAIL(next_link != NULL);
2186 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2187 TBM_RETURN_IF_FAIL(buf_info != NULL);
2189 if (scale_factor > 0.0) {
2192 dw = w * scale_factor;
2193 dh = h * scale_factor;
2195 size = dstride * dh;
2199 if (size > buf_info->size) {
2200 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2201 size, buf_info->size);
2206 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2207 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2209 memset(bo_handle.ptr, 0x00, buf_info->size);
2210 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2212 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2213 _tbm_surface_internal_get_time(),
2214 g_dump_info->count++, type, dump_postfix[0]);
2215 if (scale_factor > 0.0) {
2216 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2217 TBM_FORMAT_ARGB8888, stride,
2218 w, h, dstride, dw, dh);
2219 if (ret != TBM_SURFACE_ERROR_NONE) {
2220 TBM_LOG_E("fail to scale buffer");
2221 tbm_bo_unmap(buf_info->bo);
2224 buf_info->shm_stride = dstride;
2225 buf_info->shm_h = dh;
2227 memcpy(bo_handle.ptr, ptr, size);
2228 buf_info->shm_stride = stride;
2229 buf_info->shm_h = h;
2232 tbm_bo_unmap(buf_info->bo);
2234 buf_info->dirty = 0;
2235 buf_info->dirty_shm = 1;
2237 if (g_dump_info->count == 1000)
2238 g_dump_info->count = 0;
2240 g_dump_info->link = next_link;
2242 TBM_LOG_I("Dump %s \n", buf_info->name);
2246 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2248 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2249 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2250 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2252 tbm_surface_info_s info;
2253 const char *postfix;
2257 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2258 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2260 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2261 postfix = dump_postfix[0];
2263 postfix = dump_postfix[1];
2265 if (strcmp(postfix, type)) {
2266 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2267 tbm_surface_unmap(surface);
2271 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2273 if (!access(file, 0)) {
2274 TBM_LOG_E("can't capture buffer, exist file %s", file);
2275 tbm_surface_unmap(surface);
2279 switch (info.format) {
2280 case TBM_FORMAT_ARGB8888:
2281 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2282 info.planes[0].stride >> 2,
2283 info.height, TBM_FORMAT_ARGB8888);
2285 case TBM_FORMAT_XRGB8888:
2286 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2287 info.planes[0].stride >> 2,
2288 info.height, TBM_FORMAT_XRGB8888);
2290 case TBM_FORMAT_YVU420:
2291 case TBM_FORMAT_YUV420:
2292 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2293 info.planes[0].stride * info.height,
2295 info.planes[1].stride * (info.height >> 1),
2297 info.planes[2].stride * (info.height >> 1));
2299 case TBM_FORMAT_NV12:
2300 case TBM_FORMAT_NV21:
2301 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2302 info.planes[0].stride * info.height,
2304 info.planes[1].stride * (info.height >> 1),
2307 case TBM_FORMAT_YUYV:
2308 case TBM_FORMAT_UYVY:
2309 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2310 info.planes[0].stride * info.height,
2314 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2315 tbm_surface_unmap(surface);
2319 tbm_surface_unmap(surface);
2321 TBM_TRACE("Capture %s \n", file);
2327 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2328 const char *path, const char *name, const char *type)
2330 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2331 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2332 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2333 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2334 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2335 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2339 if (strcmp(dump_postfix[0], type)) {
2340 TBM_LOG_E("Not supported type:%s'", type);
2344 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2346 if (!access(file, 0)) {
2347 TBM_LOG_E("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2351 _tbm_surface_internal_dump_file_png(file, ptr, stride, h, 0);
2353 TBM_TRACE("Capture %s \n", file);