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(info->num_planes > 0, NULL);
813 TBM_RETURN_VAL_IF_FAIL(num > 0, NULL);
814 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
816 struct _tbm_bufmgr *mgr;
817 struct _tbm_surface *surf = NULL;
819 bool bufmgr_initialized = false;
821 _tbm_surface_mutex_lock();
823 if (!g_surface_bufmgr) {
824 _init_surface_bufmgr();
825 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
826 bufmgr_initialized = true;
829 mgr = g_surface_bufmgr;
830 if (!TBM_BUFMGR_IS_VALID(mgr)) {
831 TBM_LOG_E("fail to validate the Bufmgr.\n");
832 goto check_valid_fail;
835 surf = calloc(1, sizeof(struct _tbm_surface));
837 /* LCOV_EXCL_START */
838 TBM_LOG_E("fail to allocate struct _tbm_surface.\n");
839 goto alloc_surf_fail;
844 surf->info.width = info->width;
845 surf->info.height = info->height;
846 surf->info.format = info->format;
848 surf->info.bpp = info->bpp;
850 surf->info.bpp = tbm_surface_internal_get_bpp(info->format);
851 surf->info.num_planes = info->num_planes;
854 /* get size, stride and offset */
855 for (i = 0; i < info->num_planes; i++) {
856 surf->info.planes[i].offset = info->planes[i].offset;
857 surf->info.planes[i].stride = info->planes[i].stride;
859 if (info->planes[i].size > 0)
860 surf->info.planes[i].size = info->planes[i].size;
862 uint32_t size = 0, offset = 0, stride = 0;
865 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
866 surf->info.planes[i].size = size;
870 surf->planes_bo_idx[i] = 0;
872 surf->planes_bo_idx[i] = i;
875 if (info->size > 0) {
876 surf->info.size = info->size;
879 for (i = 0; i < info->num_planes; i++)
880 surf->info.size += surf->info.planes[i].size;
883 surf->flags = TBM_BO_DEFAULT;
885 /* create only one bo */
887 for (i = 0; i < num; i++) {
888 if (bos[i] == NULL) {
889 TBM_LOG_E("bos[%d] is null.\n", i);
893 surf->bos[i] = tbm_bo_ref(bos[i]);
894 _tbm_bo_set_surface(bos[i], surf);
897 TBM_TRACE("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
898 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
900 LIST_INITHEAD(&surf->user_data_list);
901 LIST_INITHEAD(&surf->debug_data_list);
903 LIST_ADD(&surf->item_link, &mgr->surf_list);
905 _tbm_surface_mutex_unlock();
909 /* LCOV_EXCL_START */
911 for (i = 0; i < num; i++) {
913 tbm_bo_unref(surf->bos[i]);
918 if (bufmgr_initialized && mgr) {
919 LIST_DELINIT(&mgr->surf_list);
920 _deinit_surface_bufmgr();
922 _tbm_surface_mutex_unlock();
924 TBM_LOG_E("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
925 info->width, info->height,
926 _tbm_surface_internal_format_to_str(info->format), num);
933 tbm_surface_internal_destroy(tbm_surface_h surface)
935 _tbm_surface_mutex_lock();
937 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
941 if (surface->refcnt > 0) {
942 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
943 _tbm_surface_mutex_unlock();
947 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
949 if (surface->refcnt == 0)
950 _tbm_surface_internal_destroy(surface);
952 _tbm_surface_mutex_unlock();
956 tbm_surface_internal_ref(tbm_surface_h surface)
958 _tbm_surface_mutex_lock();
960 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
964 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
966 _tbm_surface_mutex_unlock();
970 tbm_surface_internal_unref(tbm_surface_h surface)
972 _tbm_surface_mutex_lock();
974 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
978 if (surface->refcnt > 0) {
979 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
980 _tbm_surface_mutex_unlock();
984 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
986 if (surface->refcnt == 0)
987 _tbm_surface_internal_destroy(surface);
989 _tbm_surface_mutex_unlock();
993 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
995 struct _tbm_surface *surf;
998 _tbm_surface_mutex_lock();
1000 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1002 surf = (struct _tbm_surface *)surface;
1003 num = surf->num_bos;
1005 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
1007 _tbm_surface_mutex_unlock();
1013 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1015 struct _tbm_surface *surf;
1018 _tbm_surface_mutex_lock();
1020 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1021 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1023 surf = (struct _tbm_surface *)surface;
1024 bo = surf->bos[bo_idx];
1026 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1028 _tbm_surface_mutex_unlock();
1034 tbm_surface_internal_get_size(tbm_surface_h surface)
1036 struct _tbm_surface *surf;
1039 _tbm_surface_mutex_lock();
1041 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1043 surf = (struct _tbm_surface *)surface;
1044 size = surf->info.size;
1046 TBM_TRACE("tbm_surface(%p) size(%u)\n", surface, size);
1048 _tbm_surface_mutex_unlock();
1054 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1055 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1057 struct _tbm_surface *surf;
1059 _tbm_surface_mutex_lock();
1061 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1062 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1064 surf = (struct _tbm_surface *)surface;
1066 if (plane_idx >= surf->info.num_planes) {
1067 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1068 _tbm_surface_mutex_unlock();
1073 *size = surf->info.planes[plane_idx].size;
1076 *offset = surf->info.planes[plane_idx].offset;
1079 *pitch = surf->info.planes[plane_idx].stride;
1081 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1082 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1083 surf->info.planes[plane_idx].stride);
1085 _tbm_surface_mutex_unlock();
1091 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1092 tbm_surface_info_s *info, int map)
1094 struct _tbm_surface *surf;
1095 tbm_bo_handle bo_handles[4];
1098 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1101 _tbm_surface_mutex_lock();
1103 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1105 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1107 surf = (struct _tbm_surface *)surface;
1109 memset(info, 0x00, sizeof(tbm_surface_info_s));
1110 info->width = surf->info.width;
1111 info->height = surf->info.height;
1112 info->format = surf->info.format;
1113 info->bpp = surf->info.bpp;
1114 info->size = surf->info.size;
1115 info->num_planes = surf->info.num_planes;
1117 for (i = 0; i < surf->info.num_planes; i++) {
1118 info->planes[i].size = surf->info.planes[i].size;
1119 info->planes[i].offset = surf->info.planes[i].offset;
1120 info->planes[i].stride = surf->info.planes[i].stride;
1121 planes_bo_idx[i] = surf->planes_bo_idx[i];
1124 for (i = 0; i < surf->num_bos; i++)
1125 bos[i] = surf->bos[i];
1127 num_bos = surf->num_bos;
1130 _tbm_surface_mutex_unlock();
1131 for (i = 0; i < num_bos; i++) {
1132 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1133 if (bo_handles[i].ptr == NULL) {
1134 for (j = 0; j < i; j++)
1135 tbm_bo_unmap(bos[j]);
1137 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1141 _tbm_surface_mutex_lock();
1143 for (i = 0; i < num_bos; i++) {
1144 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1145 if (bo_handles[i].ptr == NULL) {
1146 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1147 _tbm_surface_mutex_unlock();
1153 for (i = 0; i < info->num_planes; i++) {
1154 if (bo_handles[planes_bo_idx[i]].ptr)
1155 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1158 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1160 _tbm_surface_mutex_unlock();
1166 tbm_surface_internal_unmap(tbm_surface_h surface)
1168 struct _tbm_surface *surf;
1171 _tbm_surface_mutex_lock();
1173 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1175 surf = (struct _tbm_surface *)surface;
1177 for (i = 0; i < surf->num_bos; i++)
1178 tbm_bo_unmap(surf->bos[i]);
1180 TBM_TRACE("tbm_surface(%p)\n", surface);
1182 _tbm_surface_mutex_unlock();
1186 tbm_surface_internal_get_width(tbm_surface_h surface)
1188 struct _tbm_surface *surf;
1191 _tbm_surface_mutex_lock();
1193 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1195 surf = (struct _tbm_surface *)surface;
1196 width = surf->info.width;
1198 TBM_TRACE("tbm_surface(%p) width(%u)\n", surface, width);
1200 _tbm_surface_mutex_unlock();
1206 tbm_surface_internal_get_height(tbm_surface_h surface)
1208 struct _tbm_surface *surf;
1209 unsigned int height;
1211 _tbm_surface_mutex_lock();
1213 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1215 surf = (struct _tbm_surface *)surface;
1216 height = surf->info.height;
1218 TBM_TRACE("tbm_surface(%p) height(%u)\n", surface, height);
1220 _tbm_surface_mutex_unlock();
1227 tbm_surface_internal_get_format(tbm_surface_h surface)
1229 struct _tbm_surface *surf;
1232 _tbm_surface_mutex_lock();
1234 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1236 surf = (struct _tbm_surface *)surface;
1237 format = surf->info.format;
1239 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1241 _tbm_surface_mutex_unlock();
1247 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1249 struct _tbm_surface *surf;
1252 _tbm_surface_mutex_lock();
1254 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1255 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1257 surf = (struct _tbm_surface *)surface;
1258 bo_idx = surf->planes_bo_idx[plane_idx];
1260 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1262 _tbm_surface_mutex_unlock();
1268 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1269 tbm_data_free data_free_func)
1271 tbm_user_data *data;
1273 _tbm_surface_mutex_lock();
1275 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1277 /* check if the data according to the key exist if so, return false. */
1278 data = user_data_lookup(&surface->user_data_list, key);
1280 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1281 _tbm_surface_mutex_unlock();
1285 data = user_data_create(key, data_free_func);
1287 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1288 _tbm_surface_mutex_unlock();
1292 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1294 LIST_ADD(&data->item_link, &surface->user_data_list);
1296 _tbm_surface_mutex_unlock();
1302 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1305 tbm_user_data *old_data;
1307 _tbm_surface_mutex_lock();
1309 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1311 old_data = user_data_lookup(&surface->user_data_list, key);
1313 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1314 _tbm_surface_mutex_unlock();
1318 if (old_data->data && old_data->free_func)
1319 old_data->free_func(old_data->data);
1321 old_data->data = data;
1323 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1325 _tbm_surface_mutex_unlock();
1331 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1334 tbm_user_data *old_data;
1336 _tbm_surface_mutex_lock();
1338 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1341 TBM_LOG_E("error: tbm_surface(%p) key(%lu)\n", surface, key);
1342 _tbm_surface_mutex_unlock();
1347 old_data = user_data_lookup(&surface->user_data_list, key);
1349 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1350 _tbm_surface_mutex_unlock();
1354 *data = old_data->data;
1356 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1358 _tbm_surface_mutex_unlock();
1364 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1367 tbm_user_data *old_data = (void *)0;
1369 _tbm_surface_mutex_lock();
1371 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1373 old_data = user_data_lookup(&surface->user_data_list, key);
1375 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1376 _tbm_surface_mutex_unlock();
1380 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1382 user_data_delete(old_data);
1384 _tbm_surface_mutex_unlock();
1389 /* LCOV_EXCL_START */
1391 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1393 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1395 return surface->debug_pid;
1399 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1401 _tbm_surface_mutex_lock();
1403 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1405 surface->debug_pid = pid;
1407 _tbm_surface_mutex_unlock();
1410 static tbm_surface_debug_data *
1411 _tbm_surface_internal_debug_data_create(char *key, char *value)
1413 tbm_surface_debug_data *debug_data = NULL;
1415 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1419 if (key) debug_data->key = strdup(key);
1420 if (value) debug_data->value = strdup(value);
1426 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1428 tbm_surface_debug_data *debug_data = NULL;
1429 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1430 tbm_bufmgr bufmgr = NULL;
1432 _tbm_surface_mutex_lock();
1434 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1435 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1437 bufmgr = surface->bufmgr;
1439 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1441 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1442 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1444 if (!strcmp(old_data->key, key)) {
1445 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1446 TBM_TRACE("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1447 goto add_debug_key_list;
1450 if (old_data->value)
1451 free(old_data->value);
1454 old_data->value = strdup(value);
1456 old_data->value = NULL;
1458 goto add_debug_key_list;
1464 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1466 TBM_LOG_E("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1467 _tbm_surface_mutex_unlock();
1471 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1473 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1476 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1477 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1478 if (!strcmp(old_data->key, key)) {
1479 _tbm_surface_mutex_unlock();
1485 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1486 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1488 _tbm_surface_mutex_unlock();
1494 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1496 tbm_surface_debug_data *old_data = NULL;
1498 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1500 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1501 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1502 if (!strcmp(old_data->key, key))
1503 return old_data->value;
1510 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1511 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1513 struct _tbm_surface_dump_buf_info {
1523 tbm_surface_info_s info;
1525 struct list_head link;
1528 struct _tbm_surface_dump_info {
1529 char *path; // copy???
1532 struct list_head *link;
1533 struct list_head surface_list; /* link of surface */
1536 static tbm_surface_dump_info *g_dump_info = NULL;
1537 static const char *dump_postfix[2] = {"png", "yuv"};
1538 static double scale_factor;
1541 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1542 void *data2, int size2, void *data3, int size3)
1545 unsigned int *blocks;
1547 if (!_tbm_surface_check_file_is_valid(file, 1))
1548 TBM_LOG_E("%s is symbolic link\n", file);
1550 fp = fopen(file, "w+");
1551 TBM_RETURN_IF_FAIL(fp != NULL);
1553 blocks = (unsigned int *)data1;
1554 fwrite(blocks, 1, size1, fp);
1557 blocks = (unsigned int *)data2;
1558 fwrite(blocks, 1, size2, fp);
1562 blocks = (unsigned int *)data3;
1563 fwrite(blocks, 1, size3, fp);
1570 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1572 unsigned int *blocks = (unsigned int *)data;
1575 png_bytep *row_pointers;
1578 if (!_tbm_surface_check_file_is_valid(file, 1))
1579 TBM_LOG_E("%s is symbolic link\n", file);
1581 fp = fopen(file, "wb");
1582 TBM_RETURN_IF_FAIL(fp != NULL);
1584 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1587 TBM_LOG_E("fail to create a png write structure.\n");
1592 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1594 TBM_LOG_E("fail to create a png info structure.\n");
1595 png_destroy_write_struct(&pPngStruct, NULL);
1600 png_init_io(pPngStruct, fp);
1601 if (format == TBM_FORMAT_XRGB8888) {
1603 png_set_IHDR(pPngStruct,
1610 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1613 png_set_IHDR(pPngStruct,
1618 PNG_COLOR_TYPE_RGBA,
1620 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1623 png_set_bgr(pPngStruct);
1624 png_write_info(pPngStruct, pPngInfo);
1626 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1627 if (!row_pointers) {
1628 TBM_LOG_E("fail to allocate the png row_pointers.\n");
1629 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1634 for (y = 0; y < height; ++y) {
1638 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1640 TBM_LOG_E("fail to allocate the png row.\n");
1641 for (x = 0; x < y; x++)
1642 png_free(pPngStruct, row_pointers[x]);
1643 png_free(pPngStruct, row_pointers);
1644 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1648 row_pointers[y] = (png_bytep)row;
1650 for (x = 0; x < width; ++x) {
1651 unsigned int curBlock = blocks[y * width + x];
1653 if (pixel_size == 3) { // XRGB8888
1654 row[x * pixel_size] = (curBlock & 0xFF);
1655 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1656 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1657 } else { // ARGB8888
1658 row[x * pixel_size] = (curBlock & 0xFF);
1659 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1660 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1661 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1666 png_write_image(pPngStruct, row_pointers);
1667 png_write_end(pPngStruct, pPngInfo);
1669 for (y = 0; y < height; y++)
1670 png_free(pPngStruct, row_pointers[y]);
1671 png_free(pPngStruct, row_pointers);
1673 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1679 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1681 TBM_RETURN_IF_FAIL(path != NULL);
1682 TBM_RETURN_IF_FAIL(w > 0);
1683 TBM_RETURN_IF_FAIL(h > 0);
1684 TBM_RETURN_IF_FAIL(count > 0);
1686 tbm_surface_dump_buf_info *buf_info = NULL;
1687 tbm_surface_h tbm_surface;
1688 tbm_surface_info_s info;
1693 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1697 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1698 TBM_RETURN_IF_FAIL(g_dump_info);
1700 LIST_INITHEAD(&g_dump_info->surface_list);
1701 g_dump_info->count = 0;
1702 g_dump_info->dump_max = count;
1704 /* get buffer size */
1705 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1706 if (tbm_surface == NULL) {
1707 TBM_LOG_E("tbm_surface_create fail\n");
1713 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1714 TBM_LOG_E("tbm_surface_get_info fail\n");
1715 tbm_surface_destroy(tbm_surface);
1720 buffer_size = info.size;
1721 tbm_surface_destroy(tbm_surface);
1723 /* create dump lists */
1724 for (i = 0; i < count; i++) {
1727 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1728 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1730 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1732 TBM_LOG_E("fail to allocate the tbm_bo[%d]\n", i);
1737 buf_info->index = i;
1739 buf_info->size = buffer_size;
1741 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1744 g_dump_info->path = path;
1745 g_dump_info->link = &g_dump_info->surface_list;
1749 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1754 /* free resources */
1755 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1756 tbm_surface_dump_buf_info *tmp;
1758 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1759 tbm_bo_unref(buf_info->bo);
1760 LIST_DEL(&buf_info->link);
1765 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1774 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1781 tbm_surface_internal_dump_start(path, w, h, count);
1782 scale_factor = scale;
1786 tbm_surface_internal_dump_end(void)
1788 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1789 tbm_bo_handle bo_handle;
1794 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1801 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1804 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1805 if (bo_handle.ptr == NULL) {
1806 tbm_bo_unref(buf_info->bo);
1807 LIST_DEL(&buf_info->link);
1812 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1813 TBM_LOG_I("Dump File.. %s generated.\n", file);
1815 if (buf_info->dirty) {
1816 void *ptr1 = NULL, *ptr2 = NULL;
1818 switch (buf_info->info.format) {
1819 case TBM_FORMAT_ARGB8888:
1820 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1821 buf_info->info.planes[0].stride >> 2,
1822 buf_info->info.height, TBM_FORMAT_ARGB8888);
1824 case TBM_FORMAT_XRGB8888:
1825 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1826 buf_info->info.planes[0].stride >> 2,
1827 buf_info->info.height, TBM_FORMAT_XRGB8888);
1829 case TBM_FORMAT_YVU420:
1830 case TBM_FORMAT_YUV420:
1831 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1832 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1833 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1834 buf_info->info.planes[0].stride * buf_info->info.height,
1836 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1838 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1840 case TBM_FORMAT_NV12:
1841 case TBM_FORMAT_NV21:
1842 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1843 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1844 buf_info->info.planes[0].stride * buf_info->info.height,
1846 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1849 case TBM_FORMAT_YUYV:
1850 case TBM_FORMAT_UYVY:
1851 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1852 buf_info->info.planes[0].stride * buf_info->info.height,
1856 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1859 } else if (buf_info->dirty_shm)
1860 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1861 buf_info->shm_stride >> 2,
1862 buf_info->shm_h, 0);
1864 tbm_bo_unmap(buf_info->bo);
1865 tbm_bo_unref(buf_info->bo);
1866 LIST_DEL(&buf_info->link);
1873 TBM_LOG_I("Dump End..\n");
1876 static pixman_format_code_t
1877 _tbm_surface_internal_pixman_format_get(tbm_format format)
1880 case TBM_FORMAT_ARGB8888:
1881 return PIXMAN_a8r8g8b8;
1882 case TBM_FORMAT_XRGB8888:
1883 return PIXMAN_x8r8g8b8;
1892 * This function supports only if a buffer has below formats.
1893 * - TBM_FORMAT_ARGB8888
1894 * - TBM_FORMAT_XRGB8888
1896 static tbm_surface_error_e
1897 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1898 int format, int src_stride, int src_w, int src_h,
1899 int dst_stride, int dst_w, int dst_h)
1901 pixman_image_t *src_img = NULL, *dst_img = NULL;
1902 pixman_format_code_t pixman_format;
1903 pixman_transform_t t;
1904 struct pixman_f_transform ft;
1905 double scale_x, scale_y;
1907 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1908 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1910 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1911 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1914 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1915 (uint32_t*)src_ptr, src_stride);
1916 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1919 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1920 (uint32_t*)dst_ptr, dst_stride);
1921 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1923 pixman_f_transform_init_identity(&ft);
1925 scale_x = (double)src_w / dst_w;
1926 scale_y = (double)src_h / dst_h;
1928 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
1929 pixman_f_transform_translate(&ft, NULL, 0, 0);
1930 pixman_transform_from_pixman_f_transform(&t, &ft);
1931 pixman_image_set_transform(src_img, &t);
1933 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
1934 0, 0, 0, 0, 0, 0, dst_w, dst_h);
1936 pixman_image_unref(src_img);
1937 pixman_image_unref(dst_img);
1939 return TBM_SURFACE_ERROR_NONE;
1943 pixman_image_unref(src_img);
1945 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1948 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
1949 #define KEY_LEN 5 // "_XXXX"
1950 #define KEYS_LEN KEY_LEN * MAX_BOS
1952 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
1954 char *keys, temp_key[KEY_LEN + 1];
1955 struct _tbm_surface *surf;
1959 _tbm_surface_mutex_lock();
1961 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1963 surf = (struct _tbm_surface *)surface;
1965 num_bos = surf->num_bos;
1966 if (num_bos > MAX_BOS)
1969 keys = calloc(KEYS_LEN + 1, sizeof(char));
1971 TBM_LOG_E("Failed to alloc memory");
1972 _tbm_surface_mutex_unlock();
1976 for (i = 0; i < num_bos; i++) {
1977 memset(temp_key, 0x00, KEY_LEN + 1);
1979 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
1980 strncat(keys, temp_key, KEY_LEN);
1983 _tbm_surface_mutex_unlock();
1988 static void _tbm_surface_internal_put_keys(char *keys)
1995 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1997 TBM_RETURN_IF_FAIL(surface != NULL);
1998 TBM_RETURN_IF_FAIL(type != NULL);
2000 tbm_surface_dump_buf_info *buf_info;
2001 struct list_head *next_link;
2002 tbm_surface_info_s info;
2003 tbm_bo_handle bo_handle;
2004 const char *postfix;
2005 const char *format = NULL;
2012 next_link = g_dump_info->link->next;
2013 TBM_RETURN_IF_FAIL(next_link != NULL);
2015 if (next_link == &g_dump_info->surface_list) {
2016 next_link = next_link->next;
2017 TBM_RETURN_IF_FAIL(next_link != NULL);
2020 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2021 TBM_RETURN_IF_FAIL(buf_info != NULL);
2023 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2024 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2026 if (scale_factor > 0.0) {
2029 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2030 TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n",
2031 _tbm_surface_internal_format_to_str(info.format));
2032 tbm_surface_unmap(surface);
2036 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2038 buf_info->info.width = info.width * scale_factor;
2039 buf_info->info.height = info.height * scale_factor;
2040 buf_info->info.format = info.format;
2041 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2042 buf_info->info.num_planes = 1;
2043 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2044 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2046 if (buf_info->info.size > buf_info->size) {
2047 TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2048 buf_info->info.size, buf_info->size);
2049 tbm_surface_unmap(surface);
2053 if (info.size > buf_info->size) {
2054 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
2055 info.size, buf_info->size);
2056 tbm_surface_unmap(surface);
2060 /* make the file information */
2061 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2064 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2065 postfix = dump_postfix[0];
2066 format = _tbm_surface_internal_format_to_str(info.format);
2068 postfix = dump_postfix[1];
2070 keys = _tbm_surface_internal_get_keys(surface);
2072 TBM_LOG_E("fail to get keys");
2073 tbm_surface_unmap(surface);
2078 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2079 if (!bo_handle.ptr) {
2080 TBM_LOG_E("fail to map bo");
2081 _tbm_surface_internal_put_keys(keys);
2082 tbm_surface_unmap(surface);
2085 memset(bo_handle.ptr, 0x00, buf_info->size);
2087 switch (info.format) {
2088 case TBM_FORMAT_ARGB8888:
2089 case TBM_FORMAT_XRGB8888:
2090 snprintf(buf_info->name, sizeof(buf_info->name),
2091 "%10.3f_%03d%s_%p_%s-%s.%s",
2092 _tbm_surface_internal_get_time(),
2093 g_dump_info->count++, keys, surface, format, type, postfix);
2095 if (scale_factor > 0.0) {
2096 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2098 buf_info->info.format,
2099 info.planes[0].stride,
2100 info.width, info.height,
2101 buf_info->info.planes[0].stride,
2102 buf_info->info.width,
2103 buf_info->info.height);
2104 if (ret != TBM_SURFACE_ERROR_NONE) {
2105 TBM_LOG_E("fail to scale buffer");
2106 tbm_bo_unmap(buf_info->bo);
2107 _tbm_surface_internal_put_keys(keys);
2108 tbm_surface_unmap(surface);
2112 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2114 case TBM_FORMAT_YVU420:
2115 case TBM_FORMAT_YUV420:
2116 snprintf(buf_info->name, sizeof(buf_info->name),
2117 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2118 _tbm_surface_internal_get_time(),
2119 g_dump_info->count++, keys, type, info.planes[0].stride,
2120 info.height, FOURCC_STR(info.format), postfix);
2121 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2122 bo_handle.ptr += info.planes[0].stride * info.height;
2123 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2124 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2125 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2127 case TBM_FORMAT_NV12:
2128 case TBM_FORMAT_NV21:
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);
2135 bo_handle.ptr += info.planes[0].stride * info.height;
2136 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2138 case TBM_FORMAT_YUYV:
2139 case TBM_FORMAT_UYVY:
2140 snprintf(buf_info->name, sizeof(buf_info->name),
2141 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2142 _tbm_surface_internal_get_time(),
2143 g_dump_info->count++, keys, type, info.planes[0].stride,
2144 info.height, FOURCC_STR(info.format), postfix);
2145 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2148 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2149 tbm_bo_unmap(buf_info->bo);
2150 _tbm_surface_internal_put_keys(keys);
2151 tbm_surface_unmap(surface);
2155 tbm_bo_unmap(buf_info->bo);
2157 _tbm_surface_internal_put_keys(keys);
2159 tbm_surface_unmap(surface);
2161 buf_info->dirty = 1;
2162 buf_info->dirty_shm = 0;
2164 if (g_dump_info->count == 1000)
2165 g_dump_info->count = 0;
2167 g_dump_info->link = next_link;
2169 TBM_LOG_I("Dump %s \n", buf_info->name);
2172 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2175 TBM_RETURN_IF_FAIL(ptr != NULL);
2176 TBM_RETURN_IF_FAIL(w > 0);
2177 TBM_RETURN_IF_FAIL(h > 0);
2178 TBM_RETURN_IF_FAIL(stride > 0);
2179 TBM_RETURN_IF_FAIL(type != NULL);
2181 tbm_surface_dump_buf_info *buf_info;
2182 struct list_head *next_link;
2183 tbm_bo_handle bo_handle;
2184 int ret, size, dw = 0, dh = 0, dstride = 0;
2189 next_link = g_dump_info->link->next;
2190 TBM_RETURN_IF_FAIL(next_link != NULL);
2192 if (next_link == &g_dump_info->surface_list) {
2193 next_link = next_link->next;
2194 TBM_RETURN_IF_FAIL(next_link != NULL);
2197 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2198 TBM_RETURN_IF_FAIL(buf_info != NULL);
2200 if (scale_factor > 0.0) {
2203 dw = w * scale_factor;
2204 dh = h * scale_factor;
2206 size = dstride * dh;
2210 if (size > buf_info->size) {
2211 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2212 size, buf_info->size);
2217 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2218 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2220 memset(bo_handle.ptr, 0x00, buf_info->size);
2221 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2223 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2224 _tbm_surface_internal_get_time(),
2225 g_dump_info->count++, type, dump_postfix[0]);
2226 if (scale_factor > 0.0) {
2227 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2228 TBM_FORMAT_ARGB8888, stride,
2229 w, h, dstride, dw, dh);
2230 if (ret != TBM_SURFACE_ERROR_NONE) {
2231 TBM_LOG_E("fail to scale buffer");
2232 tbm_bo_unmap(buf_info->bo);
2235 buf_info->shm_stride = dstride;
2236 buf_info->shm_h = dh;
2238 memcpy(bo_handle.ptr, ptr, size);
2239 buf_info->shm_stride = stride;
2240 buf_info->shm_h = h;
2243 tbm_bo_unmap(buf_info->bo);
2245 buf_info->dirty = 0;
2246 buf_info->dirty_shm = 1;
2248 if (g_dump_info->count == 1000)
2249 g_dump_info->count = 0;
2251 g_dump_info->link = next_link;
2253 TBM_LOG_I("Dump %s \n", buf_info->name);
2257 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2259 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2260 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2261 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2263 tbm_surface_info_s info;
2264 const char *postfix;
2268 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2269 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2271 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2272 postfix = dump_postfix[0];
2274 postfix = dump_postfix[1];
2276 if (strcmp(postfix, type)) {
2277 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2278 tbm_surface_unmap(surface);
2282 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2284 if (!access(file, 0)) {
2285 TBM_LOG_E("can't capture buffer, exist file %s", file);
2286 tbm_surface_unmap(surface);
2290 switch (info.format) {
2291 case TBM_FORMAT_ARGB8888:
2292 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2293 info.planes[0].stride >> 2,
2294 info.height, TBM_FORMAT_ARGB8888);
2296 case TBM_FORMAT_XRGB8888:
2297 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2298 info.planes[0].stride >> 2,
2299 info.height, TBM_FORMAT_XRGB8888);
2301 case TBM_FORMAT_YVU420:
2302 case TBM_FORMAT_YUV420:
2303 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2304 info.planes[0].stride * info.height,
2306 info.planes[1].stride * (info.height >> 1),
2308 info.planes[2].stride * (info.height >> 1));
2310 case TBM_FORMAT_NV12:
2311 case TBM_FORMAT_NV21:
2312 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2313 info.planes[0].stride * info.height,
2315 info.planes[1].stride * (info.height >> 1),
2318 case TBM_FORMAT_YUYV:
2319 case TBM_FORMAT_UYVY:
2320 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2321 info.planes[0].stride * info.height,
2325 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2326 tbm_surface_unmap(surface);
2330 tbm_surface_unmap(surface);
2332 TBM_TRACE("Capture %s \n", file);
2338 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2339 const char *path, const char *name, const char *type)
2341 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2342 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2343 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2344 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2345 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2346 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2350 if (strcmp(dump_postfix[0], type)) {
2351 TBM_LOG_E("Not supported type:%s'", type);
2355 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2357 if (!access(file, 0)) {
2358 TBM_LOG_E("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2362 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2364 TBM_TRACE("Capture %s \n", file);