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 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1099 _tbm_surface_mutex_lock();
1101 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1103 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1105 surf = (struct _tbm_surface *)surface;
1107 memset(info, 0x00, sizeof(tbm_surface_info_s));
1108 info->width = surf->info.width;
1109 info->height = surf->info.height;
1110 info->format = surf->info.format;
1111 info->bpp = surf->info.bpp;
1112 info->size = surf->info.size;
1113 info->num_planes = surf->info.num_planes;
1115 for (i = 0; i < surf->info.num_planes; i++) {
1116 info->planes[i].size = surf->info.planes[i].size;
1117 info->planes[i].offset = surf->info.planes[i].offset;
1118 info->planes[i].stride = surf->info.planes[i].stride;
1119 planes_bo_idx[i] = surf->planes_bo_idx[i];
1122 for (i = 0; i < surf->num_bos; i++)
1123 bos[i] = surf->bos[i];
1125 num_bos = surf->num_bos;
1128 _tbm_surface_mutex_unlock();
1129 for (i = 0; i < num_bos; i++) {
1130 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1131 if (bo_handles[i].ptr == NULL) {
1132 for (j = 0; j < i; j++)
1133 tbm_bo_unmap(bos[j]);
1135 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1139 _tbm_surface_mutex_lock();
1141 for (i = 0; i < num_bos; i++) {
1142 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1143 if (bo_handles[i].ptr == NULL) {
1144 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1145 _tbm_surface_mutex_unlock();
1151 for (i = 0; i < info->num_planes; i++) {
1152 if (bo_handles[planes_bo_idx[i]].ptr)
1153 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1156 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1158 _tbm_surface_mutex_unlock();
1164 tbm_surface_internal_unmap(tbm_surface_h surface)
1166 struct _tbm_surface *surf;
1169 _tbm_surface_mutex_lock();
1171 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1173 surf = (struct _tbm_surface *)surface;
1175 for (i = 0; i < surf->num_bos; i++)
1176 tbm_bo_unmap(surf->bos[i]);
1178 TBM_TRACE("tbm_surface(%p)\n", surface);
1180 _tbm_surface_mutex_unlock();
1184 tbm_surface_internal_get_width(tbm_surface_h surface)
1186 struct _tbm_surface *surf;
1189 _tbm_surface_mutex_lock();
1191 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1193 surf = (struct _tbm_surface *)surface;
1194 width = surf->info.width;
1196 TBM_TRACE("tbm_surface(%p) width(%u)\n", surface, width);
1198 _tbm_surface_mutex_unlock();
1204 tbm_surface_internal_get_height(tbm_surface_h surface)
1206 struct _tbm_surface *surf;
1207 unsigned int height;
1209 _tbm_surface_mutex_lock();
1211 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1213 surf = (struct _tbm_surface *)surface;
1214 height = surf->info.height;
1216 TBM_TRACE("tbm_surface(%p) height(%u)\n", surface, height);
1218 _tbm_surface_mutex_unlock();
1225 tbm_surface_internal_get_format(tbm_surface_h surface)
1227 struct _tbm_surface *surf;
1230 _tbm_surface_mutex_lock();
1232 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1234 surf = (struct _tbm_surface *)surface;
1235 format = surf->info.format;
1237 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1239 _tbm_surface_mutex_unlock();
1245 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1247 struct _tbm_surface *surf;
1250 _tbm_surface_mutex_lock();
1252 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1253 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1255 surf = (struct _tbm_surface *)surface;
1256 bo_idx = surf->planes_bo_idx[plane_idx];
1258 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1260 _tbm_surface_mutex_unlock();
1266 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1267 tbm_data_free data_free_func)
1269 tbm_user_data *data;
1271 _tbm_surface_mutex_lock();
1273 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1275 /* check if the data according to the key exist if so, return false. */
1276 data = user_data_lookup(&surface->user_data_list, key);
1278 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1279 _tbm_surface_mutex_unlock();
1283 data = user_data_create(key, data_free_func);
1285 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1286 _tbm_surface_mutex_unlock();
1290 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1292 LIST_ADD(&data->item_link, &surface->user_data_list);
1294 _tbm_surface_mutex_unlock();
1300 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1303 tbm_user_data *old_data;
1305 _tbm_surface_mutex_lock();
1307 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1309 old_data = user_data_lookup(&surface->user_data_list, key);
1311 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1312 _tbm_surface_mutex_unlock();
1316 if (old_data->data && old_data->free_func)
1317 old_data->free_func(old_data->data);
1319 old_data->data = data;
1321 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1323 _tbm_surface_mutex_unlock();
1329 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1332 tbm_user_data *old_data;
1334 _tbm_surface_mutex_lock();
1336 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1339 TBM_LOG_E("error: tbm_surface(%p) key(%lu)\n", surface, key);
1340 _tbm_surface_mutex_unlock();
1345 old_data = user_data_lookup(&surface->user_data_list, key);
1347 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1348 _tbm_surface_mutex_unlock();
1352 *data = old_data->data;
1354 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1356 _tbm_surface_mutex_unlock();
1362 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1365 tbm_user_data *old_data = (void *)0;
1367 _tbm_surface_mutex_lock();
1369 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1371 old_data = user_data_lookup(&surface->user_data_list, key);
1373 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1374 _tbm_surface_mutex_unlock();
1378 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1380 user_data_delete(old_data);
1382 _tbm_surface_mutex_unlock();
1387 /* LCOV_EXCL_START */
1389 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1391 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1393 return surface->debug_pid;
1397 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1399 _tbm_surface_mutex_lock();
1401 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1403 surface->debug_pid = pid;
1405 _tbm_surface_mutex_unlock();
1408 static tbm_surface_debug_data *
1409 _tbm_surface_internal_debug_data_create(char *key, char *value)
1411 tbm_surface_debug_data *debug_data = NULL;
1413 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1417 if (key) debug_data->key = strdup(key);
1418 if (value) debug_data->value = strdup(value);
1424 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1426 tbm_surface_debug_data *debug_data = NULL;
1427 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1428 tbm_bufmgr bufmgr = NULL;
1430 _tbm_surface_mutex_lock();
1432 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1433 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1435 bufmgr = surface->bufmgr;
1437 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1439 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1440 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1442 if (!strcmp(old_data->key, key)) {
1443 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1444 TBM_TRACE("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1445 goto add_debug_key_list;
1448 if (old_data->value)
1449 free(old_data->value);
1452 old_data->value = strdup(value);
1454 old_data->value = NULL;
1456 goto add_debug_key_list;
1462 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1464 TBM_LOG_E("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1465 _tbm_surface_mutex_unlock();
1469 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1471 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1474 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1475 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1476 if (!strcmp(old_data->key, key)) {
1477 _tbm_surface_mutex_unlock();
1483 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1484 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1486 _tbm_surface_mutex_unlock();
1492 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1494 tbm_surface_debug_data *old_data = NULL;
1496 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1498 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1499 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1500 if (!strcmp(old_data->key, key))
1501 return old_data->value;
1508 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1509 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1511 struct _tbm_surface_dump_buf_info {
1521 tbm_surface_info_s info;
1523 struct list_head link;
1526 struct _tbm_surface_dump_info {
1527 char *path; // copy???
1530 struct list_head *link;
1531 struct list_head surface_list; /* link of surface */
1534 static tbm_surface_dump_info *g_dump_info = NULL;
1535 static const char *dump_postfix[2] = {"png", "yuv"};
1536 static double scale_factor;
1539 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1540 void *data2, int size2, void *data3, int size3)
1543 unsigned int *blocks;
1545 if (!_tbm_surface_check_file_is_valid(file, 1))
1546 TBM_LOG_E("%s is symbolic link\n", file);
1548 fp = fopen(file, "w+");
1549 TBM_RETURN_IF_FAIL(fp != NULL);
1551 blocks = (unsigned int *)data1;
1552 fwrite(blocks, 1, size1, fp);
1555 blocks = (unsigned int *)data2;
1556 fwrite(blocks, 1, size2, fp);
1560 blocks = (unsigned int *)data3;
1561 fwrite(blocks, 1, size3, fp);
1568 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1570 unsigned int *blocks = (unsigned int *)data;
1573 png_bytep *row_pointers;
1576 if (!_tbm_surface_check_file_is_valid(file, 1))
1577 TBM_LOG_E("%s is symbolic link\n", file);
1579 fp = fopen(file, "wb");
1580 TBM_RETURN_IF_FAIL(fp != NULL);
1582 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1585 TBM_LOG_E("fail to create a png write structure.\n");
1590 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1592 TBM_LOG_E("fail to create a png info structure.\n");
1593 png_destroy_write_struct(&pPngStruct, NULL);
1598 png_init_io(pPngStruct, fp);
1599 if (format == TBM_FORMAT_XRGB8888) {
1601 png_set_IHDR(pPngStruct,
1608 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1611 png_set_IHDR(pPngStruct,
1616 PNG_COLOR_TYPE_RGBA,
1618 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1621 png_set_bgr(pPngStruct);
1622 png_write_info(pPngStruct, pPngInfo);
1624 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1625 if (!row_pointers) {
1626 TBM_LOG_E("fail to allocate the png row_pointers.\n");
1627 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1632 for (y = 0; y < height; ++y) {
1636 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1638 TBM_LOG_E("fail to allocate the png row.\n");
1639 for (x = 0; x < y; x++)
1640 png_free(pPngStruct, row_pointers[x]);
1641 png_free(pPngStruct, row_pointers);
1642 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1646 row_pointers[y] = (png_bytep)row;
1648 for (x = 0; x < width; ++x) {
1649 unsigned int curBlock = blocks[y * width + x];
1651 if (pixel_size == 3) { // XRGB8888
1652 row[x * pixel_size] = (curBlock & 0xFF);
1653 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1654 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1655 } else { // ARGB8888
1656 row[x * pixel_size] = (curBlock & 0xFF);
1657 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1658 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1659 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1664 png_write_image(pPngStruct, row_pointers);
1665 png_write_end(pPngStruct, pPngInfo);
1667 for (y = 0; y < height; y++)
1668 png_free(pPngStruct, row_pointers[y]);
1669 png_free(pPngStruct, row_pointers);
1671 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1677 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1679 TBM_RETURN_IF_FAIL(path != NULL);
1680 TBM_RETURN_IF_FAIL(w > 0);
1681 TBM_RETURN_IF_FAIL(h > 0);
1682 TBM_RETURN_IF_FAIL(count > 0);
1684 tbm_surface_dump_buf_info *buf_info = NULL;
1685 tbm_surface_h tbm_surface;
1686 tbm_surface_info_s info;
1691 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1695 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1696 TBM_RETURN_IF_FAIL(g_dump_info);
1698 LIST_INITHEAD(&g_dump_info->surface_list);
1699 g_dump_info->count = 0;
1700 g_dump_info->dump_max = count;
1702 /* get buffer size */
1703 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1704 if (tbm_surface == NULL) {
1705 TBM_LOG_E("tbm_surface_create fail\n");
1711 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1712 TBM_LOG_E("tbm_surface_get_info fail\n");
1713 tbm_surface_destroy(tbm_surface);
1718 buffer_size = info.size;
1719 tbm_surface_destroy(tbm_surface);
1721 /* create dump lists */
1722 for (i = 0; i < count; i++) {
1725 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1726 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1728 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1730 TBM_LOG_E("fail to allocate the tbm_bo[%d]\n", i);
1735 buf_info->index = i;
1737 buf_info->size = buffer_size;
1739 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1742 g_dump_info->path = path;
1743 g_dump_info->link = &g_dump_info->surface_list;
1747 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1752 /* free resources */
1753 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1754 tbm_surface_dump_buf_info *tmp;
1756 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1757 tbm_bo_unref(buf_info->bo);
1758 LIST_DEL(&buf_info->link);
1763 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1772 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1779 tbm_surface_internal_dump_start(path, w, h, count);
1780 scale_factor = scale;
1784 tbm_surface_internal_dump_end(void)
1786 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1787 tbm_bo_handle bo_handle;
1792 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1799 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1802 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1803 if (bo_handle.ptr == NULL) {
1804 tbm_bo_unref(buf_info->bo);
1805 LIST_DEL(&buf_info->link);
1810 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1811 TBM_LOG_I("Dump File.. %s generated.\n", file);
1813 if (buf_info->dirty) {
1814 void *ptr1 = NULL, *ptr2 = NULL;
1816 switch (buf_info->info.format) {
1817 case TBM_FORMAT_ARGB8888:
1818 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1819 buf_info->info.planes[0].stride >> 2,
1820 buf_info->info.height, TBM_FORMAT_ARGB8888);
1822 case TBM_FORMAT_XRGB8888:
1823 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1824 buf_info->info.planes[0].stride >> 2,
1825 buf_info->info.height, TBM_FORMAT_XRGB8888);
1827 case TBM_FORMAT_YVU420:
1828 case TBM_FORMAT_YUV420:
1829 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1830 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1831 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1832 buf_info->info.planes[0].stride * buf_info->info.height,
1834 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1836 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1838 case TBM_FORMAT_NV12:
1839 case TBM_FORMAT_NV21:
1840 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1841 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1842 buf_info->info.planes[0].stride * buf_info->info.height,
1844 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1847 case TBM_FORMAT_YUYV:
1848 case TBM_FORMAT_UYVY:
1849 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1850 buf_info->info.planes[0].stride * buf_info->info.height,
1854 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1857 } else if (buf_info->dirty_shm)
1858 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1859 buf_info->shm_stride >> 2,
1860 buf_info->shm_h, 0);
1862 tbm_bo_unmap(buf_info->bo);
1863 tbm_bo_unref(buf_info->bo);
1864 LIST_DEL(&buf_info->link);
1871 TBM_LOG_I("Dump End..\n");
1874 static pixman_format_code_t
1875 _tbm_surface_internal_pixman_format_get(tbm_format format)
1878 case TBM_FORMAT_ARGB8888:
1879 return PIXMAN_a8r8g8b8;
1880 case TBM_FORMAT_XRGB8888:
1881 return PIXMAN_x8r8g8b8;
1890 * This function supports only if a buffer has below formats.
1891 * - TBM_FORMAT_ARGB8888
1892 * - TBM_FORMAT_XRGB8888
1894 static tbm_surface_error_e
1895 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1896 int format, int src_stride, int src_w, int src_h,
1897 int dst_stride, int dst_w, int dst_h)
1899 pixman_image_t *src_img = NULL, *dst_img = NULL;
1900 pixman_format_code_t pixman_format;
1901 pixman_transform_t t;
1902 struct pixman_f_transform ft;
1903 double scale_x, scale_y;
1905 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1906 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1908 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1909 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1912 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1913 (uint32_t*)src_ptr, src_stride);
1914 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1917 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1918 (uint32_t*)dst_ptr, dst_stride);
1919 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1921 pixman_f_transform_init_identity(&ft);
1923 scale_x = (double)src_w / dst_w;
1924 scale_y = (double)src_h / dst_h;
1926 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
1927 pixman_f_transform_translate(&ft, NULL, 0, 0);
1928 pixman_transform_from_pixman_f_transform(&t, &ft);
1929 pixman_image_set_transform(src_img, &t);
1931 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
1932 0, 0, 0, 0, 0, 0, dst_w, dst_h);
1934 pixman_image_unref(src_img);
1935 pixman_image_unref(dst_img);
1937 return TBM_SURFACE_ERROR_NONE;
1941 pixman_image_unref(src_img);
1943 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1946 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
1947 #define KEY_LEN 5 // "_XXXX"
1948 #define KEYS_LEN KEY_LEN * MAX_BOS
1950 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
1952 char *keys, temp_key[KEY_LEN + 1];
1953 struct _tbm_surface *surf;
1957 _tbm_surface_mutex_lock();
1959 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1961 surf = (struct _tbm_surface *)surface;
1963 num_bos = surf->num_bos;
1964 if (num_bos > MAX_BOS)
1967 keys = calloc(KEYS_LEN + 1, sizeof(char));
1969 TBM_LOG_E("Failed to alloc memory");
1970 _tbm_surface_mutex_unlock();
1974 for (i = 0; i < num_bos; i++) {
1975 memset(temp_key, 0x00, KEY_LEN + 1);
1977 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
1978 strncat(keys, temp_key, KEY_LEN);
1981 _tbm_surface_mutex_unlock();
1986 static void _tbm_surface_internal_put_keys(char *keys)
1993 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1995 TBM_RETURN_IF_FAIL(surface != NULL);
1996 TBM_RETURN_IF_FAIL(type != NULL);
1998 tbm_surface_dump_buf_info *buf_info;
1999 struct list_head *next_link;
2000 tbm_surface_info_s info;
2001 tbm_bo_handle bo_handle;
2002 const char *postfix;
2003 const char *format = NULL;
2010 next_link = g_dump_info->link->next;
2011 TBM_RETURN_IF_FAIL(next_link != NULL);
2013 if (next_link == &g_dump_info->surface_list) {
2014 next_link = next_link->next;
2015 TBM_RETURN_IF_FAIL(next_link != NULL);
2018 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2019 TBM_RETURN_IF_FAIL(buf_info != NULL);
2021 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2022 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2024 if (scale_factor > 0.0) {
2027 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2028 TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n",
2029 _tbm_surface_internal_format_to_str(info.format));
2030 tbm_surface_unmap(surface);
2034 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2036 buf_info->info.width = info.width * scale_factor;
2037 buf_info->info.height = info.height * scale_factor;
2038 buf_info->info.format = info.format;
2039 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2040 buf_info->info.num_planes = 1;
2041 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2042 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2044 if (buf_info->info.size > buf_info->size) {
2045 TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2046 buf_info->info.size, buf_info->size);
2047 tbm_surface_unmap(surface);
2051 if (info.size > buf_info->size) {
2052 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
2053 info.size, buf_info->size);
2054 tbm_surface_unmap(surface);
2058 /* make the file information */
2059 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2062 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2063 postfix = dump_postfix[0];
2064 format = _tbm_surface_internal_format_to_str(info.format);
2066 postfix = dump_postfix[1];
2068 keys = _tbm_surface_internal_get_keys(surface);
2070 TBM_LOG_E("fail to get keys");
2071 tbm_surface_unmap(surface);
2076 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2077 if (!bo_handle.ptr) {
2078 TBM_LOG_E("fail to map bo");
2079 _tbm_surface_internal_put_keys(keys);
2080 tbm_surface_unmap(surface);
2083 memset(bo_handle.ptr, 0x00, buf_info->size);
2085 switch (info.format) {
2086 case TBM_FORMAT_ARGB8888:
2087 case TBM_FORMAT_XRGB8888:
2088 snprintf(buf_info->name, sizeof(buf_info->name),
2089 "%10.3f_%03d%s_%p_%s-%s.%s",
2090 _tbm_surface_internal_get_time(),
2091 g_dump_info->count++, keys, surface, format, type, postfix);
2093 if (scale_factor > 0.0) {
2094 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2096 buf_info->info.format,
2097 info.planes[0].stride,
2098 info.width, info.height,
2099 buf_info->info.planes[0].stride,
2100 buf_info->info.width,
2101 buf_info->info.height);
2102 if (ret != TBM_SURFACE_ERROR_NONE) {
2103 TBM_LOG_E("fail to scale buffer");
2104 tbm_bo_unmap(buf_info->bo);
2105 _tbm_surface_internal_put_keys(keys);
2106 tbm_surface_unmap(surface);
2110 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2112 case TBM_FORMAT_YVU420:
2113 case TBM_FORMAT_YUV420:
2114 snprintf(buf_info->name, sizeof(buf_info->name),
2115 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2116 _tbm_surface_internal_get_time(),
2117 g_dump_info->count++, keys, type, info.planes[0].stride,
2118 info.height, FOURCC_STR(info.format), postfix);
2119 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2120 bo_handle.ptr += info.planes[0].stride * info.height;
2121 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2122 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2123 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2125 case TBM_FORMAT_NV12:
2126 case TBM_FORMAT_NV21:
2127 snprintf(buf_info->name, sizeof(buf_info->name),
2128 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2129 _tbm_surface_internal_get_time(),
2130 g_dump_info->count++, keys, type, info.planes[0].stride,
2131 info.height, FOURCC_STR(info.format), postfix);
2132 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2133 bo_handle.ptr += info.planes[0].stride * info.height;
2134 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2136 case TBM_FORMAT_YUYV:
2137 case TBM_FORMAT_UYVY:
2138 snprintf(buf_info->name, sizeof(buf_info->name),
2139 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2140 _tbm_surface_internal_get_time(),
2141 g_dump_info->count++, keys, type, info.planes[0].stride,
2142 info.height, FOURCC_STR(info.format), postfix);
2143 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2146 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2147 tbm_bo_unmap(buf_info->bo);
2148 _tbm_surface_internal_put_keys(keys);
2149 tbm_surface_unmap(surface);
2153 tbm_bo_unmap(buf_info->bo);
2155 _tbm_surface_internal_put_keys(keys);
2157 tbm_surface_unmap(surface);
2159 buf_info->dirty = 1;
2160 buf_info->dirty_shm = 0;
2162 if (g_dump_info->count == 1000)
2163 g_dump_info->count = 0;
2165 g_dump_info->link = next_link;
2167 TBM_LOG_I("Dump %s \n", buf_info->name);
2170 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2173 TBM_RETURN_IF_FAIL(ptr != NULL);
2174 TBM_RETURN_IF_FAIL(w > 0);
2175 TBM_RETURN_IF_FAIL(h > 0);
2176 TBM_RETURN_IF_FAIL(stride > 0);
2177 TBM_RETURN_IF_FAIL(type != NULL);
2179 tbm_surface_dump_buf_info *buf_info;
2180 struct list_head *next_link;
2181 tbm_bo_handle bo_handle;
2182 int ret, size, dw = 0, dh = 0, dstride = 0;
2187 next_link = g_dump_info->link->next;
2188 TBM_RETURN_IF_FAIL(next_link != NULL);
2190 if (next_link == &g_dump_info->surface_list) {
2191 next_link = next_link->next;
2192 TBM_RETURN_IF_FAIL(next_link != NULL);
2195 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2196 TBM_RETURN_IF_FAIL(buf_info != NULL);
2198 if (scale_factor > 0.0) {
2201 dw = w * scale_factor;
2202 dh = h * scale_factor;
2204 size = dstride * dh;
2208 if (size > buf_info->size) {
2209 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2210 size, buf_info->size);
2215 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2216 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2218 memset(bo_handle.ptr, 0x00, buf_info->size);
2219 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2221 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2222 _tbm_surface_internal_get_time(),
2223 g_dump_info->count++, type, dump_postfix[0]);
2224 if (scale_factor > 0.0) {
2225 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2226 TBM_FORMAT_ARGB8888, stride,
2227 w, h, dstride, dw, dh);
2228 if (ret != TBM_SURFACE_ERROR_NONE) {
2229 TBM_LOG_E("fail to scale buffer");
2230 tbm_bo_unmap(buf_info->bo);
2233 buf_info->shm_stride = dstride;
2234 buf_info->shm_h = dh;
2236 memcpy(bo_handle.ptr, ptr, size);
2237 buf_info->shm_stride = stride;
2238 buf_info->shm_h = h;
2241 tbm_bo_unmap(buf_info->bo);
2243 buf_info->dirty = 0;
2244 buf_info->dirty_shm = 1;
2246 if (g_dump_info->count == 1000)
2247 g_dump_info->count = 0;
2249 g_dump_info->link = next_link;
2251 TBM_LOG_I("Dump %s \n", buf_info->name);
2255 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2257 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2258 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2259 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2261 tbm_surface_info_s info;
2262 const char *postfix;
2266 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2267 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2269 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2270 postfix = dump_postfix[0];
2272 postfix = dump_postfix[1];
2274 if (strcmp(postfix, type)) {
2275 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2276 tbm_surface_unmap(surface);
2280 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2282 if (!access(file, 0)) {
2283 TBM_LOG_E("can't capture buffer, exist file %s", file);
2284 tbm_surface_unmap(surface);
2288 switch (info.format) {
2289 case TBM_FORMAT_ARGB8888:
2290 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2291 info.planes[0].stride >> 2,
2292 info.height, TBM_FORMAT_ARGB8888);
2294 case TBM_FORMAT_XRGB8888:
2295 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2296 info.planes[0].stride >> 2,
2297 info.height, TBM_FORMAT_XRGB8888);
2299 case TBM_FORMAT_YVU420:
2300 case TBM_FORMAT_YUV420:
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),
2306 info.planes[2].stride * (info.height >> 1));
2308 case TBM_FORMAT_NV12:
2309 case TBM_FORMAT_NV21:
2310 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2311 info.planes[0].stride * info.height,
2313 info.planes[1].stride * (info.height >> 1),
2316 case TBM_FORMAT_YUYV:
2317 case TBM_FORMAT_UYVY:
2318 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2319 info.planes[0].stride * info.height,
2323 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2324 tbm_surface_unmap(surface);
2328 tbm_surface_unmap(surface);
2330 TBM_TRACE("Capture %s \n", file);
2336 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2337 const char *path, const char *name, const char *type)
2339 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2340 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2341 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2342 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2343 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2344 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2348 if (strcmp(dump_postfix[0], type)) {
2349 TBM_LOG_E("Not supported type:%s'", type);
2353 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2355 if (!access(file, 0)) {
2356 TBM_LOG_E("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2360 _tbm_surface_internal_dump_file_png(file, ptr, stride, h, 0);
2362 TBM_TRACE("Capture %s \n", file);