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_ERR("'%s' failed.\n", #cond);\
58 _tbm_surface_mutex_unlock();\
63 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
65 TBM_ERR("'%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_ERR("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_ERR("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_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
290 TBM_ERR("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 *bufmgr = surf->bufmgr;
307 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
308 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
309 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
310 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
312 if (bufmgr->backend_module_data) {
313 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data)
316 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
317 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
318 if (error != TBM_ERROR_NONE) {
319 /* LCOV_EXCL_START */
320 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
326 if (!bufmgr->backend->surface_get_plane_data)
329 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
330 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
332 /* LCOV_EXCL_START */
333 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
343 _tbm_surface_internal_destroy(tbm_surface_h surface)
346 tbm_bufmgr bufmgr = surface->bufmgr;
347 tbm_user_data *old_data = NULL, *tmp = NULL;
348 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
350 /* destory the user_data_list */
351 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
352 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
353 TBM_DBG("free user_data\n");
354 user_data_delete(old_data);
358 for (i = 0; i < surface->num_bos; i++) {
359 surface->bos[i]->surface = NULL;
361 tbm_bo_unref(surface->bos[i]);
362 surface->bos[i] = NULL;
365 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
366 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
367 _tbm_surface_internal_debug_data_delete(debug_old_data);
370 LIST_DEL(&surface->item_link);
375 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
376 LIST_DELINIT(&bufmgr->surf_list);
378 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
379 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
380 _tbm_surface_internal_debug_data_delete(debug_old_data);
384 _deinit_surface_bufmgr();
388 /* LCOV_EXCL_START */
390 _tbm_surface_check_file_is_symbolic_link(const char* path)
397 if (stat(path, &sb) != 0)
400 if (S_ISLNK(sb.st_mode))
408 _tbm_surface_internal_get_num_planes(tbm_format format)
414 case TBM_FORMAT_RGB332:
415 case TBM_FORMAT_BGR233:
416 case TBM_FORMAT_XRGB4444:
417 case TBM_FORMAT_XBGR4444:
418 case TBM_FORMAT_RGBX4444:
419 case TBM_FORMAT_BGRX4444:
420 case TBM_FORMAT_ARGB4444:
421 case TBM_FORMAT_ABGR4444:
422 case TBM_FORMAT_RGBA4444:
423 case TBM_FORMAT_BGRA4444:
424 case TBM_FORMAT_XRGB1555:
425 case TBM_FORMAT_XBGR1555:
426 case TBM_FORMAT_RGBX5551:
427 case TBM_FORMAT_BGRX5551:
428 case TBM_FORMAT_ARGB1555:
429 case TBM_FORMAT_ABGR1555:
430 case TBM_FORMAT_RGBA5551:
431 case TBM_FORMAT_BGRA5551:
432 case TBM_FORMAT_RGB565:
433 case TBM_FORMAT_BGR565:
434 case TBM_FORMAT_RGB888:
435 case TBM_FORMAT_BGR888:
436 case TBM_FORMAT_XRGB8888:
437 case TBM_FORMAT_XBGR8888:
438 case TBM_FORMAT_RGBX8888:
439 case TBM_FORMAT_BGRX8888:
440 case TBM_FORMAT_ARGB8888:
441 case TBM_FORMAT_ABGR8888:
442 case TBM_FORMAT_RGBA8888:
443 case TBM_FORMAT_BGRA8888:
444 case TBM_FORMAT_XRGB2101010:
445 case TBM_FORMAT_XBGR2101010:
446 case TBM_FORMAT_RGBX1010102:
447 case TBM_FORMAT_BGRX1010102:
448 case TBM_FORMAT_ARGB2101010:
449 case TBM_FORMAT_ABGR2101010:
450 case TBM_FORMAT_RGBA1010102:
451 case TBM_FORMAT_BGRA1010102:
452 case TBM_FORMAT_YUYV:
453 case TBM_FORMAT_YVYU:
454 case TBM_FORMAT_UYVY:
455 case TBM_FORMAT_VYUY:
456 case TBM_FORMAT_AYUV:
459 case TBM_FORMAT_NV12:
460 case TBM_FORMAT_NV12MT:
461 case TBM_FORMAT_NV21:
462 case TBM_FORMAT_NV16:
463 case TBM_FORMAT_NV61:
466 case TBM_FORMAT_YUV410:
467 case TBM_FORMAT_YVU410:
468 case TBM_FORMAT_YUV411:
469 case TBM_FORMAT_YVU411:
470 case TBM_FORMAT_YUV420:
471 case TBM_FORMAT_YVU420:
472 case TBM_FORMAT_YUV422:
473 case TBM_FORMAT_YVU422:
474 case TBM_FORMAT_YUV444:
475 case TBM_FORMAT_YVU444:
480 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
488 tbm_surface_internal_is_valid(tbm_surface_h surface)
492 _tbm_surface_mutex_lock();
494 /* Return silently if surface is null. */
496 _tbm_surface_mutex_unlock();
500 ret = _tbm_surface_internal_is_valid(surface);
502 _tbm_surface_mutex_unlock();
508 tbm_surface_internal_query_supported_formats(uint32_t **formats,
511 TBM_RETURN_VAL_IF_FAIL(formats, 0);
512 TBM_RETURN_VAL_IF_FAIL(num, 0);
514 struct _tbm_bufmgr *bufmgr;
516 bool bufmgr_initialized = false;
519 _tbm_surface_mutex_lock();
521 if (!g_surface_bufmgr) {
522 _init_surface_bufmgr();
523 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
524 bufmgr_initialized = true;
527 bufmgr = g_surface_bufmgr;
529 if (bufmgr->backend_module_data) {
530 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats)
533 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
534 if (error != TBM_ERROR_NONE) {
535 /* LCOV_EXCL_START */
536 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
538 /* LCOV_EXCL_START */
542 if (!bufmgr->backend->surface_supported_format)
545 ret = bufmgr->backend->surface_supported_format(formats, num);
547 /* LCOV_EXCL_START */
548 TBM_ERR("Fail to surface_supported_format.\n");
550 /* LCOV_EXCL_START */
554 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
556 if (bufmgr_initialized) {
557 LIST_DELINIT(&g_surface_bufmgr->surf_list);
558 _deinit_surface_bufmgr();
561 _tbm_surface_mutex_unlock();
565 /* LCOV_EXCL_START */
567 if (bufmgr_initialized) {
568 LIST_DELINIT(&g_surface_bufmgr->surf_list);
569 _deinit_surface_bufmgr();
571 _tbm_surface_mutex_unlock();
573 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
580 tbm_surface_internal_get_num_planes(tbm_format format)
584 _tbm_surface_mutex_lock();
585 _tbm_set_last_result(TBM_ERROR_NONE);
587 num_planes = _tbm_surface_internal_get_num_planes(format);
589 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
590 _tbm_surface_mutex_unlock();
594 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
596 _tbm_surface_mutex_unlock();
602 tbm_surface_internal_get_bpp(tbm_format format)
609 case TBM_FORMAT_RGB332:
610 case TBM_FORMAT_BGR233:
613 case TBM_FORMAT_XRGB4444:
614 case TBM_FORMAT_XBGR4444:
615 case TBM_FORMAT_RGBX4444:
616 case TBM_FORMAT_BGRX4444:
617 case TBM_FORMAT_ARGB4444:
618 case TBM_FORMAT_ABGR4444:
619 case TBM_FORMAT_RGBA4444:
620 case TBM_FORMAT_BGRA4444:
621 case TBM_FORMAT_XRGB1555:
622 case TBM_FORMAT_XBGR1555:
623 case TBM_FORMAT_RGBX5551:
624 case TBM_FORMAT_BGRX5551:
625 case TBM_FORMAT_ARGB1555:
626 case TBM_FORMAT_ABGR1555:
627 case TBM_FORMAT_RGBA5551:
628 case TBM_FORMAT_BGRA5551:
629 case TBM_FORMAT_RGB565:
630 case TBM_FORMAT_BGR565:
633 case TBM_FORMAT_RGB888:
634 case TBM_FORMAT_BGR888:
637 case TBM_FORMAT_XRGB8888:
638 case TBM_FORMAT_XBGR8888:
639 case TBM_FORMAT_RGBX8888:
640 case TBM_FORMAT_BGRX8888:
641 case TBM_FORMAT_ARGB8888:
642 case TBM_FORMAT_ABGR8888:
643 case TBM_FORMAT_RGBA8888:
644 case TBM_FORMAT_BGRA8888:
645 case TBM_FORMAT_XRGB2101010:
646 case TBM_FORMAT_XBGR2101010:
647 case TBM_FORMAT_RGBX1010102:
648 case TBM_FORMAT_BGRX1010102:
649 case TBM_FORMAT_ARGB2101010:
650 case TBM_FORMAT_ABGR2101010:
651 case TBM_FORMAT_RGBA1010102:
652 case TBM_FORMAT_BGRA1010102:
653 case TBM_FORMAT_YUYV:
654 case TBM_FORMAT_YVYU:
655 case TBM_FORMAT_UYVY:
656 case TBM_FORMAT_VYUY:
657 case TBM_FORMAT_AYUV:
660 case TBM_FORMAT_NV12:
661 case TBM_FORMAT_NV12MT:
662 case TBM_FORMAT_NV21:
665 case TBM_FORMAT_NV16:
666 case TBM_FORMAT_NV61:
669 case TBM_FORMAT_YUV410:
670 case TBM_FORMAT_YVU410:
673 case TBM_FORMAT_YUV411:
674 case TBM_FORMAT_YVU411:
675 case TBM_FORMAT_YUV420:
676 case TBM_FORMAT_YVU420:
679 case TBM_FORMAT_YUV422:
680 case TBM_FORMAT_YVU422:
683 case TBM_FORMAT_YUV444:
684 case TBM_FORMAT_YVU444:
691 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
697 tbm_surface_internal_create_with_flags(int width, int height,
698 int format, int flags)
700 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
701 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
703 struct _tbm_bufmgr *bufmgr;
704 struct _tbm_surface *surf = NULL;
708 uint32_t bo_size = 0;
711 bool bufmgr_initialized = false;
713 void *bo_priv = NULL;
714 tbm_backend_bo_data *bo_data = NULL;
717 _tbm_surface_mutex_lock();
719 if (!g_surface_bufmgr) {
720 _init_surface_bufmgr();
721 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
722 bufmgr_initialized = true;
725 bufmgr = g_surface_bufmgr;
726 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
727 TBM_ERR("The bufmgr is invalid\n");
728 goto check_valid_fail;
731 surf = calloc(1, sizeof(struct _tbm_surface));
733 /* LCOV_EXCL_START */
734 TBM_ERR("fail to alloc surf\n");
735 goto alloc_surf_fail;
739 surf->bufmgr = bufmgr;
740 surf->info.width = width;
741 surf->info.height = height;
742 surf->info.format = format;
743 surf->info.bpp = tbm_surface_internal_get_bpp(format);
744 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
745 if (!surf->info.num_planes) {
746 TBM_ERR("fail to get num_planes. error(%s)\n", tbm_error_str(tbm_get_last_error()));
747 goto num_planes_fail;
751 /* get size, stride and offset bo_idx */
752 for (i = 0; i < surf->info.num_planes; i++) {
753 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
754 &offset, &stride, &bo_idx)) {
755 TBM_ERR("fail to query plane data\n");
756 goto query_plane_data_fail;
759 surf->info.planes[i].size = size;
760 surf->info.planes[i].offset = offset;
761 surf->info.planes[i].stride = stride;
762 surf->planes_bo_idx[i] = bo_idx;
767 for (i = 0; i < surf->info.num_planes; i++) {
768 surf->info.size += surf->info.planes[i].size;
770 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
771 surf->num_bos = surf->planes_bo_idx[i] + 1;
776 for (i = 0; i < surf->num_bos; i++) {
778 for (j = 0; j < surf->info.num_planes; j++) {
779 if (surf->planes_bo_idx[j] == i)
780 bo_size += surf->info.planes[j].size;
783 if (bufmgr->backend_module_data) {
784 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
785 /* LCOV_EXCL_START */
786 bo = calloc(1, sizeof(struct _tbm_bo));
788 TBM_ERR("fail to alloc bo struct\n");
792 bo->bufmgr = surf->bufmgr;
794 pthread_mutex_lock(&surf->bufmgr->lock);
796 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format(bufmgr->bufmgr_data, format, i,
797 width, height, flags, &error);
799 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
801 pthread_mutex_unlock(&surf->bufmgr->lock);
804 bo->bo_data = bo_data;
808 LIST_INITHEAD(&bo->user_data_list);
810 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
812 pthread_mutex_unlock(&surf->bufmgr->lock);
817 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
819 TBM_ERR("fail to alloc bo idx:%d\n", i);
824 if (bufmgr->backend->surface_bo_alloc) {
825 /* LCOV_EXCL_START */
826 bo = calloc(1, sizeof(struct _tbm_bo));
828 TBM_ERR("fail to alloc bo struct\n");
832 bo->bufmgr = surf->bufmgr;
834 pthread_mutex_lock(&surf->bufmgr->lock);
836 bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
838 TBM_ERR("fail to alloc bo priv\n");
840 pthread_mutex_unlock(&surf->bufmgr->lock);
847 LIST_INITHEAD(&bo->user_data_list);
849 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
851 pthread_mutex_unlock(&surf->bufmgr->lock);
856 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
858 TBM_ERR("fail to alloc bo idx:%d\n", i);
864 _tbm_bo_set_surface(surf->bos[i], surf);
867 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
868 _tbm_surface_internal_format_to_str(format), flags, surf);
870 LIST_INITHEAD(&surf->user_data_list);
871 LIST_INITHEAD(&surf->debug_data_list);
873 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
875 _tbm_surface_mutex_unlock();
879 /* LCOV_EXCL_START */
881 for (j = 0; j < i; j++) {
883 tbm_bo_unref(surf->bos[j]);
885 query_plane_data_fail:
890 if (bufmgr_initialized && bufmgr) {
891 LIST_DELINIT(&bufmgr->surf_list);
892 _deinit_surface_bufmgr();
894 _tbm_surface_mutex_unlock();
896 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
898 _tbm_surface_internal_format_to_str(format), flags);
905 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
906 tbm_bo *bos, int num)
908 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
909 TBM_RETURN_VAL_IF_FAIL(info, NULL);
910 TBM_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
911 TBM_RETURN_VAL_IF_FAIL(num > 0, NULL);
912 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
914 struct _tbm_bufmgr *bufmgr;
915 struct _tbm_surface *surf = NULL;
917 bool bufmgr_initialized = false;
919 _tbm_surface_mutex_lock();
921 if (!g_surface_bufmgr) {
922 _init_surface_bufmgr();
923 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
924 bufmgr_initialized = true;
927 bufmgr = g_surface_bufmgr;
928 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
929 TBM_ERR("fail to validate the Bufmgr.\n");
930 goto check_valid_fail;
933 surf = calloc(1, sizeof(struct _tbm_surface));
935 /* LCOV_EXCL_START */
936 TBM_ERR("fail to allocate struct _tbm_surface.\n");
937 goto alloc_surf_fail;
941 surf->bufmgr = bufmgr;
942 surf->info.width = info->width;
943 surf->info.height = info->height;
944 surf->info.format = info->format;
946 surf->info.bpp = info->bpp;
948 surf->info.bpp = tbm_surface_internal_get_bpp(info->format);
949 surf->info.num_planes = info->num_planes;
952 /* get size, stride and offset */
953 for (i = 0; i < info->num_planes; i++) {
954 surf->info.planes[i].offset = info->planes[i].offset;
955 surf->info.planes[i].stride = info->planes[i].stride;
957 if (info->planes[i].size > 0)
958 surf->info.planes[i].size = info->planes[i].size;
960 uint32_t size = 0, offset = 0, stride = 0;
963 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
964 surf->info.planes[i].size = size;
968 surf->planes_bo_idx[i] = 0;
970 surf->planes_bo_idx[i] = i;
973 if (info->size > 0) {
974 surf->info.size = info->size;
977 for (i = 0; i < info->num_planes; i++)
978 surf->info.size += surf->info.planes[i].size;
981 surf->flags = TBM_BO_DEFAULT;
983 /* create only one bo */
985 for (i = 0; i < num; i++) {
986 if (bos[i] == NULL) {
987 TBM_ERR("bos[%d] is null.\n", i);
991 surf->bos[i] = tbm_bo_ref(bos[i]);
992 _tbm_bo_set_surface(bos[i], surf);
995 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
996 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
998 LIST_INITHEAD(&surf->user_data_list);
999 LIST_INITHEAD(&surf->debug_data_list);
1001 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1003 _tbm_surface_mutex_unlock();
1007 /* LCOV_EXCL_START */
1009 for (i = 0; i < num; i++) {
1011 tbm_bo_unref(surf->bos[i]);
1016 if (bufmgr_initialized && bufmgr) {
1017 LIST_DELINIT(&bufmgr->surf_list);
1018 _deinit_surface_bufmgr();
1020 _tbm_surface_mutex_unlock();
1022 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1023 info->width, info->height,
1024 _tbm_surface_internal_format_to_str(info->format), num);
1025 /* LCOV_EXCL_STOP */
1031 tbm_surface_internal_destroy(tbm_surface_h surface)
1033 _tbm_surface_mutex_lock();
1035 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1039 if (surface->refcnt > 0) {
1040 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1041 _tbm_surface_mutex_unlock();
1045 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1047 if (surface->refcnt == 0)
1048 _tbm_surface_internal_destroy(surface);
1050 _tbm_surface_mutex_unlock();
1054 tbm_surface_internal_ref(tbm_surface_h surface)
1056 _tbm_surface_mutex_lock();
1058 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1062 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1064 _tbm_surface_mutex_unlock();
1068 tbm_surface_internal_unref(tbm_surface_h surface)
1070 _tbm_surface_mutex_lock();
1072 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1076 if (surface->refcnt > 0) {
1077 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1078 _tbm_surface_mutex_unlock();
1082 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1084 if (surface->refcnt == 0)
1085 _tbm_surface_internal_destroy(surface);
1087 _tbm_surface_mutex_unlock();
1091 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1093 struct _tbm_surface *surf;
1096 _tbm_surface_mutex_lock();
1098 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1100 surf = (struct _tbm_surface *)surface;
1101 num = surf->num_bos;
1103 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1105 _tbm_surface_mutex_unlock();
1111 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1113 struct _tbm_surface *surf;
1116 _tbm_surface_mutex_lock();
1118 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1119 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1121 surf = (struct _tbm_surface *)surface;
1122 bo = surf->bos[bo_idx];
1124 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1126 _tbm_surface_mutex_unlock();
1132 tbm_surface_internal_get_size(tbm_surface_h surface)
1134 struct _tbm_surface *surf;
1137 _tbm_surface_mutex_lock();
1139 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1141 surf = (struct _tbm_surface *)surface;
1142 size = surf->info.size;
1144 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1146 _tbm_surface_mutex_unlock();
1152 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1153 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1155 struct _tbm_surface *surf;
1157 _tbm_surface_mutex_lock();
1159 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1160 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1162 surf = (struct _tbm_surface *)surface;
1164 if (plane_idx >= surf->info.num_planes) {
1165 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1166 _tbm_surface_mutex_unlock();
1171 *size = surf->info.planes[plane_idx].size;
1174 *offset = surf->info.planes[plane_idx].offset;
1177 *pitch = surf->info.planes[plane_idx].stride;
1179 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1180 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1181 surf->info.planes[plane_idx].stride);
1183 _tbm_surface_mutex_unlock();
1189 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1190 tbm_surface_info_s *info, int map)
1192 struct _tbm_surface *surf;
1193 tbm_bo_handle bo_handles[4];
1196 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1199 _tbm_surface_mutex_lock();
1201 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1203 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1205 surf = (struct _tbm_surface *)surface;
1207 memset(info, 0x00, sizeof(tbm_surface_info_s));
1208 info->width = surf->info.width;
1209 info->height = surf->info.height;
1210 info->format = surf->info.format;
1211 info->bpp = surf->info.bpp;
1212 info->size = surf->info.size;
1213 info->num_planes = surf->info.num_planes;
1215 for (i = 0; i < surf->info.num_planes; i++) {
1216 info->planes[i].size = surf->info.planes[i].size;
1217 info->planes[i].offset = surf->info.planes[i].offset;
1218 info->planes[i].stride = surf->info.planes[i].stride;
1219 planes_bo_idx[i] = surf->planes_bo_idx[i];
1222 for (i = 0; i < surf->num_bos; i++)
1223 bos[i] = surf->bos[i];
1225 num_bos = surf->num_bos;
1228 _tbm_surface_mutex_unlock();
1229 for (i = 0; i < num_bos; i++) {
1230 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1231 if (bo_handles[i].ptr == NULL) {
1232 for (j = 0; j < i; j++)
1233 tbm_bo_unmap(bos[j]);
1235 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1239 _tbm_surface_mutex_lock();
1241 for (i = 0; i < num_bos; i++) {
1242 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1243 if (bo_handles[i].ptr == NULL) {
1244 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1245 _tbm_surface_mutex_unlock();
1251 for (i = 0; i < info->num_planes; i++) {
1252 if (bo_handles[planes_bo_idx[i]].ptr)
1253 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1256 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1258 _tbm_surface_mutex_unlock();
1264 tbm_surface_internal_unmap(tbm_surface_h surface)
1266 struct _tbm_surface *surf;
1269 _tbm_surface_mutex_lock();
1271 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1273 surf = (struct _tbm_surface *)surface;
1275 for (i = 0; i < surf->num_bos; i++)
1276 tbm_bo_unmap(surf->bos[i]);
1278 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1280 _tbm_surface_mutex_unlock();
1284 tbm_surface_internal_get_width(tbm_surface_h surface)
1286 struct _tbm_surface *surf;
1289 _tbm_surface_mutex_lock();
1291 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1293 surf = (struct _tbm_surface *)surface;
1294 width = surf->info.width;
1296 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1298 _tbm_surface_mutex_unlock();
1304 tbm_surface_internal_get_height(tbm_surface_h surface)
1306 struct _tbm_surface *surf;
1307 unsigned int height;
1309 _tbm_surface_mutex_lock();
1311 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1313 surf = (struct _tbm_surface *)surface;
1314 height = surf->info.height;
1316 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1318 _tbm_surface_mutex_unlock();
1325 tbm_surface_internal_get_format(tbm_surface_h surface)
1327 struct _tbm_surface *surf;
1330 _tbm_surface_mutex_lock();
1332 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1334 surf = (struct _tbm_surface *)surface;
1335 format = surf->info.format;
1337 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1339 _tbm_surface_mutex_unlock();
1345 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1347 struct _tbm_surface *surf;
1350 _tbm_surface_mutex_lock();
1352 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1353 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1355 surf = (struct _tbm_surface *)surface;
1356 bo_idx = surf->planes_bo_idx[plane_idx];
1358 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1360 _tbm_surface_mutex_unlock();
1366 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1367 tbm_data_free data_free_func)
1369 tbm_user_data *data;
1371 _tbm_surface_mutex_lock();
1373 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1375 /* check if the data according to the key exist if so, return false. */
1376 data = user_data_lookup(&surface->user_data_list, key);
1378 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1379 _tbm_surface_mutex_unlock();
1383 data = user_data_create(key, data_free_func);
1385 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1386 _tbm_surface_mutex_unlock();
1390 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1392 LIST_ADD(&data->item_link, &surface->user_data_list);
1394 _tbm_surface_mutex_unlock();
1400 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1403 tbm_user_data *old_data;
1405 _tbm_surface_mutex_lock();
1407 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1409 old_data = user_data_lookup(&surface->user_data_list, key);
1411 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1412 _tbm_surface_mutex_unlock();
1416 if (old_data->data && old_data->free_func)
1417 old_data->free_func(old_data->data);
1419 old_data->data = data;
1421 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1423 _tbm_surface_mutex_unlock();
1429 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1432 tbm_user_data *old_data;
1434 _tbm_surface_mutex_lock();
1436 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1439 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1440 _tbm_surface_mutex_unlock();
1445 old_data = user_data_lookup(&surface->user_data_list, key);
1447 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1448 _tbm_surface_mutex_unlock();
1452 *data = old_data->data;
1454 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1456 _tbm_surface_mutex_unlock();
1462 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1465 tbm_user_data *old_data = (void *)0;
1467 _tbm_surface_mutex_lock();
1469 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1471 old_data = user_data_lookup(&surface->user_data_list, key);
1473 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1474 _tbm_surface_mutex_unlock();
1478 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1480 user_data_delete(old_data);
1482 _tbm_surface_mutex_unlock();
1487 /* LCOV_EXCL_START */
1489 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1491 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1493 return surface->debug_pid;
1497 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1499 _tbm_surface_mutex_lock();
1501 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1503 surface->debug_pid = pid;
1505 _tbm_surface_mutex_unlock();
1508 static tbm_surface_debug_data *
1509 _tbm_surface_internal_debug_data_create(char *key, char *value)
1511 tbm_surface_debug_data *debug_data = NULL;
1513 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1517 if (key) debug_data->key = strdup(key);
1518 if (value) debug_data->value = strdup(value);
1524 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1526 tbm_surface_debug_data *debug_data = NULL;
1527 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1528 tbm_bufmgr bufmgr = NULL;
1530 _tbm_surface_mutex_lock();
1532 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1533 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1535 bufmgr = surface->bufmgr;
1537 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1539 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1540 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1542 if (!strcmp(old_data->key, key)) {
1543 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1544 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1545 goto add_debug_key_list;
1548 if (old_data->value)
1549 free(old_data->value);
1552 old_data->value = strdup(value);
1554 old_data->value = NULL;
1556 goto add_debug_key_list;
1562 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1564 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1565 _tbm_surface_mutex_unlock();
1569 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1571 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1574 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1575 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1576 if (!strcmp(old_data->key, key)) {
1577 _tbm_surface_mutex_unlock();
1583 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1584 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1586 _tbm_surface_mutex_unlock();
1592 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1594 tbm_surface_debug_data *old_data = NULL;
1596 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1598 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1599 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1600 if (!strcmp(old_data->key, key))
1601 return old_data->value;
1608 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1609 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1611 struct _tbm_surface_dump_buf_info {
1621 tbm_surface_info_s info;
1623 struct list_head link;
1626 struct _tbm_surface_dump_info {
1627 char *path; // copy???
1630 struct list_head *link;
1631 struct list_head surface_list; /* link of surface */
1634 static tbm_surface_dump_info *g_dump_info = NULL;
1635 static const char *dump_postfix[2] = {"png", "yuv"};
1636 static double scale_factor;
1639 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1640 void *data2, int size2, void *data3, int size3)
1643 unsigned int *blocks;
1645 if (_tbm_surface_check_file_is_symbolic_link(file))
1646 TBM_ERR("%s is symbolic link\n", file);
1648 fp = fopen(file, "w+");
1649 TBM_RETURN_IF_FAIL(fp != NULL);
1651 blocks = (unsigned int *)data1;
1652 fwrite(blocks, 1, size1, fp);
1655 blocks = (unsigned int *)data2;
1656 fwrite(blocks, 1, size2, fp);
1660 blocks = (unsigned int *)data3;
1661 fwrite(blocks, 1, size3, fp);
1668 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1670 unsigned int *blocks = (unsigned int *)data;
1673 png_bytep *row_pointers;
1676 if (_tbm_surface_check_file_is_symbolic_link(file))
1677 TBM_ERR("%s is symbolic link\n", file);
1679 fp = fopen(file, "wb");
1680 TBM_RETURN_IF_FAIL(fp != NULL);
1682 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1685 TBM_ERR("fail to create a png write structure.\n");
1690 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1692 TBM_ERR("fail to create a png info structure.\n");
1693 png_destroy_write_struct(&pPngStruct, NULL);
1698 png_init_io(pPngStruct, fp);
1699 if (format == TBM_FORMAT_XRGB8888) {
1701 png_set_IHDR(pPngStruct,
1708 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1711 png_set_IHDR(pPngStruct,
1716 PNG_COLOR_TYPE_RGBA,
1718 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1721 png_set_bgr(pPngStruct);
1722 png_write_info(pPngStruct, pPngInfo);
1724 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1725 if (!row_pointers) {
1726 TBM_ERR("fail to allocate the png row_pointers.\n");
1727 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1732 for (y = 0; y < height; ++y) {
1736 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1738 TBM_ERR("fail to allocate the png row.\n");
1739 for (x = 0; x < y; x++)
1740 png_free(pPngStruct, row_pointers[x]);
1741 png_free(pPngStruct, row_pointers);
1742 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1746 row_pointers[y] = (png_bytep)row;
1748 for (x = 0; x < width; ++x) {
1749 unsigned int curBlock = blocks[y * width + x];
1751 if (pixel_size == 3) { // XRGB8888
1752 row[x * pixel_size] = (curBlock & 0xFF);
1753 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1754 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1755 } else { // ARGB8888
1756 row[x * pixel_size] = (curBlock & 0xFF);
1757 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1758 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1759 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1764 png_write_image(pPngStruct, row_pointers);
1765 png_write_end(pPngStruct, pPngInfo);
1767 for (y = 0; y < height; y++)
1768 png_free(pPngStruct, row_pointers[y]);
1769 png_free(pPngStruct, row_pointers);
1771 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1777 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1779 TBM_RETURN_IF_FAIL(path != NULL);
1780 TBM_RETURN_IF_FAIL(w > 0);
1781 TBM_RETURN_IF_FAIL(h > 0);
1782 TBM_RETURN_IF_FAIL(count > 0);
1784 tbm_surface_dump_buf_info *buf_info = NULL;
1785 tbm_surface_h tbm_surface;
1786 tbm_surface_info_s info;
1791 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1795 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1796 TBM_RETURN_IF_FAIL(g_dump_info);
1798 LIST_INITHEAD(&g_dump_info->surface_list);
1799 g_dump_info->count = 0;
1800 g_dump_info->dump_max = count;
1802 /* get buffer size */
1803 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1804 if (tbm_surface == NULL) {
1805 TBM_ERR("tbm_surface_create fail\n");
1811 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1812 TBM_ERR("tbm_surface_get_info fail\n");
1813 tbm_surface_destroy(tbm_surface);
1818 buffer_size = info.size;
1819 tbm_surface_destroy(tbm_surface);
1821 /* create dump lists */
1822 for (i = 0; i < count; i++) {
1825 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1826 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1828 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1830 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1835 buf_info->index = i;
1837 buf_info->size = buffer_size;
1839 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1842 g_dump_info->path = path;
1843 g_dump_info->link = &g_dump_info->surface_list;
1847 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1852 /* free resources */
1853 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1854 tbm_surface_dump_buf_info *tmp;
1856 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1857 tbm_bo_unref(buf_info->bo);
1858 LIST_DEL(&buf_info->link);
1863 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1872 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1879 tbm_surface_internal_dump_start(path, w, h, count);
1880 scale_factor = scale;
1884 tbm_surface_internal_dump_end(void)
1886 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1887 tbm_bo_handle bo_handle;
1892 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1899 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1902 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1903 if (bo_handle.ptr == NULL) {
1904 tbm_bo_unref(buf_info->bo);
1905 LIST_DEL(&buf_info->link);
1910 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1911 TBM_INFO("Dump File.. %s generated.\n", file);
1913 if (buf_info->dirty) {
1914 void *ptr1 = NULL, *ptr2 = NULL;
1916 switch (buf_info->info.format) {
1917 case TBM_FORMAT_ARGB8888:
1918 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1919 buf_info->info.planes[0].stride >> 2,
1920 buf_info->info.height, TBM_FORMAT_ARGB8888);
1922 case TBM_FORMAT_XRGB8888:
1923 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1924 buf_info->info.planes[0].stride >> 2,
1925 buf_info->info.height, TBM_FORMAT_XRGB8888);
1927 case TBM_FORMAT_YVU420:
1928 case TBM_FORMAT_YUV420:
1929 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1930 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1931 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1932 buf_info->info.planes[0].stride * buf_info->info.height,
1934 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1936 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1938 case TBM_FORMAT_NV12:
1939 case TBM_FORMAT_NV21:
1940 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1941 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1942 buf_info->info.planes[0].stride * buf_info->info.height,
1944 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1947 case TBM_FORMAT_YUYV:
1948 case TBM_FORMAT_UYVY:
1949 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1950 buf_info->info.planes[0].stride * buf_info->info.height,
1954 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1957 } else if (buf_info->dirty_shm)
1958 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1959 buf_info->shm_stride >> 2,
1960 buf_info->shm_h, 0);
1962 tbm_bo_unmap(buf_info->bo);
1963 tbm_bo_unref(buf_info->bo);
1964 LIST_DEL(&buf_info->link);
1971 TBM_INFO("Dump End..\n");
1974 static pixman_format_code_t
1975 _tbm_surface_internal_pixman_format_get(tbm_format format)
1978 case TBM_FORMAT_ARGB8888:
1979 return PIXMAN_a8r8g8b8;
1980 case TBM_FORMAT_XRGB8888:
1981 return PIXMAN_x8r8g8b8;
1990 * This function supports only if a buffer has below formats.
1991 * - TBM_FORMAT_ARGB8888
1992 * - TBM_FORMAT_XRGB8888
1994 static tbm_surface_error_e
1995 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1996 int format, int src_stride, int src_w, int src_h,
1997 int dst_stride, int dst_w, int dst_h)
1999 pixman_image_t *src_img = NULL, *dst_img = NULL;
2000 pixman_format_code_t pixman_format;
2001 pixman_transform_t t;
2002 struct pixman_f_transform ft;
2003 double scale_x, scale_y;
2005 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2006 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2008 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2009 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2012 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2013 (uint32_t*)src_ptr, src_stride);
2014 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2017 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2018 (uint32_t*)dst_ptr, dst_stride);
2019 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2021 pixman_f_transform_init_identity(&ft);
2023 scale_x = (double)src_w / dst_w;
2024 scale_y = (double)src_h / dst_h;
2026 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2027 pixman_f_transform_translate(&ft, NULL, 0, 0);
2028 pixman_transform_from_pixman_f_transform(&t, &ft);
2029 pixman_image_set_transform(src_img, &t);
2031 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2032 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2034 pixman_image_unref(src_img);
2035 pixman_image_unref(dst_img);
2037 return TBM_SURFACE_ERROR_NONE;
2041 pixman_image_unref(src_img);
2043 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2046 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2047 #define KEY_LEN 5 // "_XXXX"
2048 #define KEYS_LEN KEY_LEN * MAX_BOS
2050 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2052 char *keys, temp_key[KEY_LEN + 1];
2053 struct _tbm_surface *surf;
2057 _tbm_surface_mutex_lock();
2059 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2061 surf = (struct _tbm_surface *)surface;
2063 num_bos = surf->num_bos;
2064 if (num_bos > MAX_BOS)
2067 keys = calloc(KEYS_LEN + 1, sizeof(char));
2069 TBM_ERR("Failed to alloc memory");
2070 _tbm_surface_mutex_unlock();
2074 for (i = 0; i < num_bos; i++) {
2075 memset(temp_key, 0x00, KEY_LEN + 1);
2077 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2078 strncat(keys, temp_key, KEY_LEN);
2081 _tbm_surface_mutex_unlock();
2086 static void _tbm_surface_internal_put_keys(char *keys)
2093 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2095 TBM_RETURN_IF_FAIL(surface != NULL);
2096 TBM_RETURN_IF_FAIL(type != NULL);
2098 tbm_surface_dump_buf_info *buf_info;
2099 struct list_head *next_link;
2100 tbm_surface_info_s info;
2101 tbm_bo_handle bo_handle;
2102 const char *postfix;
2103 const char *format = NULL;
2110 next_link = g_dump_info->link->next;
2111 TBM_RETURN_IF_FAIL(next_link != NULL);
2113 if (next_link == &g_dump_info->surface_list) {
2114 next_link = next_link->next;
2115 TBM_RETURN_IF_FAIL(next_link != NULL);
2118 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2119 TBM_RETURN_IF_FAIL(buf_info != NULL);
2121 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2122 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2124 if (scale_factor > 0.0) {
2127 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2128 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2129 _tbm_surface_internal_format_to_str(info.format));
2130 tbm_surface_unmap(surface);
2134 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2136 buf_info->info.width = info.width * scale_factor;
2137 buf_info->info.height = info.height * scale_factor;
2138 buf_info->info.format = info.format;
2139 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2140 buf_info->info.num_planes = 1;
2141 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2142 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2144 if (buf_info->info.size > buf_info->size) {
2145 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2146 buf_info->info.size, buf_info->size);
2147 tbm_surface_unmap(surface);
2151 if (info.size > buf_info->size) {
2152 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2153 info.size, buf_info->size);
2154 tbm_surface_unmap(surface);
2158 /* make the file information */
2159 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2162 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2163 postfix = dump_postfix[0];
2164 format = _tbm_surface_internal_format_to_str(info.format);
2166 postfix = dump_postfix[1];
2168 keys = _tbm_surface_internal_get_keys(surface);
2170 TBM_ERR("fail to get keys");
2171 tbm_surface_unmap(surface);
2176 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2177 if (!bo_handle.ptr) {
2178 TBM_ERR("fail to map bo");
2179 _tbm_surface_internal_put_keys(keys);
2180 tbm_surface_unmap(surface);
2183 memset(bo_handle.ptr, 0x00, buf_info->size);
2185 switch (info.format) {
2186 case TBM_FORMAT_ARGB8888:
2187 case TBM_FORMAT_XRGB8888:
2188 snprintf(buf_info->name, sizeof(buf_info->name),
2189 "%10.3f_%03d%s_%p_%s-%s.%s",
2190 _tbm_surface_internal_get_time(),
2191 g_dump_info->count++, keys, surface, format, type, postfix);
2193 if (scale_factor > 0.0) {
2194 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2196 buf_info->info.format,
2197 info.planes[0].stride,
2198 info.width, info.height,
2199 buf_info->info.planes[0].stride,
2200 buf_info->info.width,
2201 buf_info->info.height);
2202 if (ret != TBM_SURFACE_ERROR_NONE) {
2203 TBM_ERR("fail to scale buffer");
2204 tbm_bo_unmap(buf_info->bo);
2205 _tbm_surface_internal_put_keys(keys);
2206 tbm_surface_unmap(surface);
2210 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2212 case TBM_FORMAT_YVU420:
2213 case TBM_FORMAT_YUV420:
2214 snprintf(buf_info->name, sizeof(buf_info->name),
2215 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2216 _tbm_surface_internal_get_time(),
2217 g_dump_info->count++, keys, type, info.planes[0].stride,
2218 info.height, FOURCC_STR(info.format), postfix);
2219 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2220 bo_handle.ptr += info.planes[0].stride * info.height;
2221 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2222 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2223 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2225 case TBM_FORMAT_NV12:
2226 case TBM_FORMAT_NV21:
2227 snprintf(buf_info->name, sizeof(buf_info->name),
2228 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2229 _tbm_surface_internal_get_time(),
2230 g_dump_info->count++, keys, type, info.planes[0].stride,
2231 info.height, FOURCC_STR(info.format), postfix);
2232 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2233 bo_handle.ptr += info.planes[0].stride * info.height;
2234 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2236 case TBM_FORMAT_YUYV:
2237 case TBM_FORMAT_UYVY:
2238 snprintf(buf_info->name, sizeof(buf_info->name),
2239 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2240 _tbm_surface_internal_get_time(),
2241 g_dump_info->count++, keys, type, info.planes[0].stride,
2242 info.height, FOURCC_STR(info.format), postfix);
2243 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2246 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2247 tbm_bo_unmap(buf_info->bo);
2248 _tbm_surface_internal_put_keys(keys);
2249 tbm_surface_unmap(surface);
2253 tbm_bo_unmap(buf_info->bo);
2255 _tbm_surface_internal_put_keys(keys);
2257 tbm_surface_unmap(surface);
2259 buf_info->dirty = 1;
2260 buf_info->dirty_shm = 0;
2262 if (g_dump_info->count == 1000)
2263 g_dump_info->count = 0;
2265 g_dump_info->link = next_link;
2267 TBM_INFO("Dump %s \n", buf_info->name);
2270 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2273 TBM_RETURN_IF_FAIL(ptr != NULL);
2274 TBM_RETURN_IF_FAIL(w > 0);
2275 TBM_RETURN_IF_FAIL(h > 0);
2276 TBM_RETURN_IF_FAIL(stride > 0);
2277 TBM_RETURN_IF_FAIL(type != NULL);
2279 tbm_surface_dump_buf_info *buf_info;
2280 struct list_head *next_link;
2281 tbm_bo_handle bo_handle;
2282 int ret, size, dw = 0, dh = 0, dstride = 0;
2287 next_link = g_dump_info->link->next;
2288 TBM_RETURN_IF_FAIL(next_link != NULL);
2290 if (next_link == &g_dump_info->surface_list) {
2291 next_link = next_link->next;
2292 TBM_RETURN_IF_FAIL(next_link != NULL);
2295 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2296 TBM_RETURN_IF_FAIL(buf_info != NULL);
2298 if (scale_factor > 0.0) {
2301 dw = w * scale_factor;
2302 dh = h * scale_factor;
2304 size = dstride * dh;
2308 if (size > buf_info->size) {
2309 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2310 size, buf_info->size);
2315 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2316 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2318 memset(bo_handle.ptr, 0x00, buf_info->size);
2319 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2321 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2322 _tbm_surface_internal_get_time(),
2323 g_dump_info->count++, type, dump_postfix[0]);
2324 if (scale_factor > 0.0) {
2325 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2326 TBM_FORMAT_ARGB8888, stride,
2327 w, h, dstride, dw, dh);
2328 if (ret != TBM_SURFACE_ERROR_NONE) {
2329 TBM_ERR("fail to scale buffer");
2330 tbm_bo_unmap(buf_info->bo);
2333 buf_info->shm_stride = dstride;
2334 buf_info->shm_h = dh;
2336 memcpy(bo_handle.ptr, ptr, size);
2337 buf_info->shm_stride = stride;
2338 buf_info->shm_h = h;
2341 tbm_bo_unmap(buf_info->bo);
2343 buf_info->dirty = 0;
2344 buf_info->dirty_shm = 1;
2346 if (g_dump_info->count == 1000)
2347 g_dump_info->count = 0;
2349 g_dump_info->link = next_link;
2351 TBM_INFO("Dump %s \n", buf_info->name);
2355 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2357 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2358 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2359 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2361 tbm_surface_info_s info;
2362 const char *postfix;
2366 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2367 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2369 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2370 postfix = dump_postfix[0];
2372 postfix = dump_postfix[1];
2374 if (strcmp(postfix, type)) {
2375 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2376 tbm_surface_unmap(surface);
2380 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2382 if (!access(file, 0)) {
2383 TBM_ERR("can't capture buffer, exist file %s", file);
2384 tbm_surface_unmap(surface);
2388 switch (info.format) {
2389 case TBM_FORMAT_ARGB8888:
2390 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2391 info.planes[0].stride >> 2,
2392 info.height, TBM_FORMAT_ARGB8888);
2394 case TBM_FORMAT_XRGB8888:
2395 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2396 info.planes[0].stride >> 2,
2397 info.height, TBM_FORMAT_XRGB8888);
2399 case TBM_FORMAT_YVU420:
2400 case TBM_FORMAT_YUV420:
2401 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2402 info.planes[0].stride * info.height,
2404 info.planes[1].stride * (info.height >> 1),
2406 info.planes[2].stride * (info.height >> 1));
2408 case TBM_FORMAT_NV12:
2409 case TBM_FORMAT_NV21:
2410 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2411 info.planes[0].stride * info.height,
2413 info.planes[1].stride * (info.height >> 1),
2416 case TBM_FORMAT_YUYV:
2417 case TBM_FORMAT_UYVY:
2418 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2419 info.planes[0].stride * info.height,
2423 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2424 tbm_surface_unmap(surface);
2428 tbm_surface_unmap(surface);
2430 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2436 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2437 const char *path, const char *name, const char *type)
2439 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2440 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2441 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2442 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2443 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2444 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2448 if (strcmp(dump_postfix[0], type)) {
2449 TBM_ERR("Not supported type:%s'", type);
2453 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2455 if (!access(file, 0)) {
2456 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2460 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2462 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);