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_is_valid(tbm_surface_h surface)
412 _tbm_surface_mutex_lock();
414 /* Return silently if surface is null. */
416 _tbm_surface_mutex_unlock();
420 ret = _tbm_surface_internal_is_valid(surface);
422 _tbm_surface_mutex_unlock();
428 tbm_surface_internal_query_supported_formats(uint32_t **formats,
431 TBM_RETURN_VAL_IF_FAIL(formats, 0);
432 TBM_RETURN_VAL_IF_FAIL(num, 0);
434 struct _tbm_bufmgr *bufmgr;
436 bool bufmgr_initialized = false;
439 _tbm_surface_mutex_lock();
441 if (!g_surface_bufmgr) {
442 _init_surface_bufmgr();
443 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
444 bufmgr_initialized = true;
447 bufmgr = g_surface_bufmgr;
449 if (bufmgr->backend_module_data) {
450 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats)
453 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
454 if (error != TBM_ERROR_NONE) {
455 /* LCOV_EXCL_START */
456 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
458 /* LCOV_EXCL_START */
462 if (!bufmgr->backend->surface_supported_format)
465 ret = bufmgr->backend->surface_supported_format(formats, num);
467 /* LCOV_EXCL_START */
468 TBM_ERR("Fail to surface_supported_format.\n");
470 /* LCOV_EXCL_START */
474 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
476 if (bufmgr_initialized) {
477 LIST_DELINIT(&g_surface_bufmgr->surf_list);
478 _deinit_surface_bufmgr();
481 _tbm_surface_mutex_unlock();
485 /* LCOV_EXCL_START */
487 if (bufmgr_initialized) {
488 LIST_DELINIT(&g_surface_bufmgr->surf_list);
489 _deinit_surface_bufmgr();
491 _tbm_surface_mutex_unlock();
493 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
500 tbm_surface_internal_get_num_planes(tbm_format format)
506 case TBM_FORMAT_RGB332:
507 case TBM_FORMAT_BGR233:
508 case TBM_FORMAT_XRGB4444:
509 case TBM_FORMAT_XBGR4444:
510 case TBM_FORMAT_RGBX4444:
511 case TBM_FORMAT_BGRX4444:
512 case TBM_FORMAT_ARGB4444:
513 case TBM_FORMAT_ABGR4444:
514 case TBM_FORMAT_RGBA4444:
515 case TBM_FORMAT_BGRA4444:
516 case TBM_FORMAT_XRGB1555:
517 case TBM_FORMAT_XBGR1555:
518 case TBM_FORMAT_RGBX5551:
519 case TBM_FORMAT_BGRX5551:
520 case TBM_FORMAT_ARGB1555:
521 case TBM_FORMAT_ABGR1555:
522 case TBM_FORMAT_RGBA5551:
523 case TBM_FORMAT_BGRA5551:
524 case TBM_FORMAT_RGB565:
525 case TBM_FORMAT_BGR565:
526 case TBM_FORMAT_RGB888:
527 case TBM_FORMAT_BGR888:
528 case TBM_FORMAT_XRGB8888:
529 case TBM_FORMAT_XBGR8888:
530 case TBM_FORMAT_RGBX8888:
531 case TBM_FORMAT_BGRX8888:
532 case TBM_FORMAT_ARGB8888:
533 case TBM_FORMAT_ABGR8888:
534 case TBM_FORMAT_RGBA8888:
535 case TBM_FORMAT_BGRA8888:
536 case TBM_FORMAT_XRGB2101010:
537 case TBM_FORMAT_XBGR2101010:
538 case TBM_FORMAT_RGBX1010102:
539 case TBM_FORMAT_BGRX1010102:
540 case TBM_FORMAT_ARGB2101010:
541 case TBM_FORMAT_ABGR2101010:
542 case TBM_FORMAT_RGBA1010102:
543 case TBM_FORMAT_BGRA1010102:
544 case TBM_FORMAT_YUYV:
545 case TBM_FORMAT_YVYU:
546 case TBM_FORMAT_UYVY:
547 case TBM_FORMAT_VYUY:
548 case TBM_FORMAT_AYUV:
551 case TBM_FORMAT_NV12:
552 case TBM_FORMAT_NV12MT:
553 case TBM_FORMAT_NV21:
554 case TBM_FORMAT_NV16:
555 case TBM_FORMAT_NV61:
558 case TBM_FORMAT_YUV410:
559 case TBM_FORMAT_YVU410:
560 case TBM_FORMAT_YUV411:
561 case TBM_FORMAT_YVU411:
562 case TBM_FORMAT_YUV420:
563 case TBM_FORMAT_YVU420:
564 case TBM_FORMAT_YUV422:
565 case TBM_FORMAT_YVU422:
566 case TBM_FORMAT_YUV444:
567 case TBM_FORMAT_YVU444:
575 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
581 tbm_surface_internal_get_bpp(tbm_format format)
588 case TBM_FORMAT_RGB332:
589 case TBM_FORMAT_BGR233:
592 case TBM_FORMAT_XRGB4444:
593 case TBM_FORMAT_XBGR4444:
594 case TBM_FORMAT_RGBX4444:
595 case TBM_FORMAT_BGRX4444:
596 case TBM_FORMAT_ARGB4444:
597 case TBM_FORMAT_ABGR4444:
598 case TBM_FORMAT_RGBA4444:
599 case TBM_FORMAT_BGRA4444:
600 case TBM_FORMAT_XRGB1555:
601 case TBM_FORMAT_XBGR1555:
602 case TBM_FORMAT_RGBX5551:
603 case TBM_FORMAT_BGRX5551:
604 case TBM_FORMAT_ARGB1555:
605 case TBM_FORMAT_ABGR1555:
606 case TBM_FORMAT_RGBA5551:
607 case TBM_FORMAT_BGRA5551:
608 case TBM_FORMAT_RGB565:
609 case TBM_FORMAT_BGR565:
612 case TBM_FORMAT_RGB888:
613 case TBM_FORMAT_BGR888:
616 case TBM_FORMAT_XRGB8888:
617 case TBM_FORMAT_XBGR8888:
618 case TBM_FORMAT_RGBX8888:
619 case TBM_FORMAT_BGRX8888:
620 case TBM_FORMAT_ARGB8888:
621 case TBM_FORMAT_ABGR8888:
622 case TBM_FORMAT_RGBA8888:
623 case TBM_FORMAT_BGRA8888:
624 case TBM_FORMAT_XRGB2101010:
625 case TBM_FORMAT_XBGR2101010:
626 case TBM_FORMAT_RGBX1010102:
627 case TBM_FORMAT_BGRX1010102:
628 case TBM_FORMAT_ARGB2101010:
629 case TBM_FORMAT_ABGR2101010:
630 case TBM_FORMAT_RGBA1010102:
631 case TBM_FORMAT_BGRA1010102:
632 case TBM_FORMAT_YUYV:
633 case TBM_FORMAT_YVYU:
634 case TBM_FORMAT_UYVY:
635 case TBM_FORMAT_VYUY:
636 case TBM_FORMAT_AYUV:
639 case TBM_FORMAT_NV12:
640 case TBM_FORMAT_NV12MT:
641 case TBM_FORMAT_NV21:
644 case TBM_FORMAT_NV16:
645 case TBM_FORMAT_NV61:
648 case TBM_FORMAT_YUV410:
649 case TBM_FORMAT_YVU410:
652 case TBM_FORMAT_YUV411:
653 case TBM_FORMAT_YVU411:
654 case TBM_FORMAT_YUV420:
655 case TBM_FORMAT_YVU420:
658 case TBM_FORMAT_YUV422:
659 case TBM_FORMAT_YVU422:
662 case TBM_FORMAT_YUV444:
663 case TBM_FORMAT_YVU444:
670 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
676 tbm_surface_internal_create_with_flags(int width, int height,
677 int format, int flags)
679 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
680 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
682 struct _tbm_bufmgr *bufmgr;
683 struct _tbm_surface *surf = NULL;
687 uint32_t bo_size = 0;
690 bool bufmgr_initialized = false;
692 void *bo_priv = NULL;
693 tbm_backend_bo_data *bo_data = NULL;
696 _tbm_surface_mutex_lock();
698 if (!g_surface_bufmgr) {
699 _init_surface_bufmgr();
700 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
701 bufmgr_initialized = true;
704 bufmgr = g_surface_bufmgr;
705 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
706 TBM_ERR("The bufmgr is invalid\n");
707 goto check_valid_fail;
710 surf = calloc(1, sizeof(struct _tbm_surface));
712 /* LCOV_EXCL_START */
713 TBM_ERR("fail to alloc surf\n");
714 goto alloc_surf_fail;
718 surf->bufmgr = bufmgr;
719 surf->info.width = width;
720 surf->info.height = height;
721 surf->info.format = format;
722 surf->info.bpp = tbm_surface_internal_get_bpp(format);
723 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
726 /* get size, stride and offset bo_idx */
727 for (i = 0; i < surf->info.num_planes; i++) {
728 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
729 &offset, &stride, &bo_idx)) {
730 TBM_ERR("fail to query plane data\n");
731 goto query_plane_data_fail;
734 surf->info.planes[i].size = size;
735 surf->info.planes[i].offset = offset;
736 surf->info.planes[i].stride = stride;
737 surf->planes_bo_idx[i] = bo_idx;
742 for (i = 0; i < surf->info.num_planes; i++) {
743 surf->info.size += surf->info.planes[i].size;
745 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
746 surf->num_bos = surf->planes_bo_idx[i] + 1;
751 for (i = 0; i < surf->num_bos; i++) {
753 for (j = 0; j < surf->info.num_planes; j++) {
754 if (surf->planes_bo_idx[j] == i)
755 bo_size += surf->info.planes[j].size;
758 if (bufmgr->backend_module_data) {
759 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
760 /* LCOV_EXCL_START */
761 bo = calloc(1, sizeof(struct _tbm_bo));
763 TBM_ERR("fail to alloc bo struct\n");
767 bo->bufmgr = surf->bufmgr;
769 pthread_mutex_lock(&surf->bufmgr->lock);
771 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format(bufmgr->bufmgr_data, format, i,
772 width, height, flags, &error);
774 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
776 pthread_mutex_unlock(&surf->bufmgr->lock);
779 bo->bo_data = bo_data;
783 LIST_INITHEAD(&bo->user_data_list);
785 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
787 pthread_mutex_unlock(&surf->bufmgr->lock);
792 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
794 TBM_ERR("fail to alloc bo idx:%d\n", i);
799 if (bufmgr->backend->surface_bo_alloc) {
800 /* LCOV_EXCL_START */
801 bo = calloc(1, sizeof(struct _tbm_bo));
803 TBM_ERR("fail to alloc bo struct\n");
807 bo->bufmgr = surf->bufmgr;
809 pthread_mutex_lock(&surf->bufmgr->lock);
811 bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
813 TBM_ERR("fail to alloc bo priv\n");
815 pthread_mutex_unlock(&surf->bufmgr->lock);
822 LIST_INITHEAD(&bo->user_data_list);
824 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
826 pthread_mutex_unlock(&surf->bufmgr->lock);
831 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
833 TBM_ERR("fail to alloc bo idx:%d\n", i);
839 _tbm_bo_set_surface(surf->bos[i], surf);
842 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
843 _tbm_surface_internal_format_to_str(format), flags, surf);
845 LIST_INITHEAD(&surf->user_data_list);
846 LIST_INITHEAD(&surf->debug_data_list);
848 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
850 _tbm_surface_mutex_unlock();
854 /* LCOV_EXCL_START */
856 for (j = 0; j < i; j++) {
858 tbm_bo_unref(surf->bos[j]);
860 query_plane_data_fail:
864 if (bufmgr_initialized && bufmgr) {
865 LIST_DELINIT(&bufmgr->surf_list);
866 _deinit_surface_bufmgr();
868 _tbm_surface_mutex_unlock();
870 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
872 _tbm_surface_internal_format_to_str(format), flags);
879 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
880 tbm_bo *bos, int num)
882 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
883 TBM_RETURN_VAL_IF_FAIL(info, NULL);
884 TBM_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
885 TBM_RETURN_VAL_IF_FAIL(num > 0, NULL);
886 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
888 struct _tbm_bufmgr *bufmgr;
889 struct _tbm_surface *surf = NULL;
891 bool bufmgr_initialized = false;
893 _tbm_surface_mutex_lock();
895 if (!g_surface_bufmgr) {
896 _init_surface_bufmgr();
897 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
898 bufmgr_initialized = true;
901 bufmgr = g_surface_bufmgr;
902 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
903 TBM_ERR("fail to validate the Bufmgr.\n");
904 goto check_valid_fail;
907 surf = calloc(1, sizeof(struct _tbm_surface));
909 /* LCOV_EXCL_START */
910 TBM_ERR("fail to allocate struct _tbm_surface.\n");
911 goto alloc_surf_fail;
915 surf->bufmgr = bufmgr;
916 surf->info.width = info->width;
917 surf->info.height = info->height;
918 surf->info.format = info->format;
920 surf->info.bpp = info->bpp;
922 surf->info.bpp = tbm_surface_internal_get_bpp(info->format);
923 surf->info.num_planes = info->num_planes;
926 /* get size, stride and offset */
927 for (i = 0; i < info->num_planes; i++) {
928 surf->info.planes[i].offset = info->planes[i].offset;
929 surf->info.planes[i].stride = info->planes[i].stride;
931 if (info->planes[i].size > 0)
932 surf->info.planes[i].size = info->planes[i].size;
934 uint32_t size = 0, offset = 0, stride = 0;
937 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
938 surf->info.planes[i].size = size;
942 surf->planes_bo_idx[i] = 0;
944 surf->planes_bo_idx[i] = i;
947 if (info->size > 0) {
948 surf->info.size = info->size;
951 for (i = 0; i < info->num_planes; i++)
952 surf->info.size += surf->info.planes[i].size;
955 surf->flags = TBM_BO_DEFAULT;
957 /* create only one bo */
959 for (i = 0; i < num; i++) {
960 if (bos[i] == NULL) {
961 TBM_ERR("bos[%d] is null.\n", i);
965 surf->bos[i] = tbm_bo_ref(bos[i]);
966 _tbm_bo_set_surface(bos[i], surf);
969 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
970 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
972 LIST_INITHEAD(&surf->user_data_list);
973 LIST_INITHEAD(&surf->debug_data_list);
975 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
977 _tbm_surface_mutex_unlock();
981 /* LCOV_EXCL_START */
983 for (i = 0; i < num; i++) {
985 tbm_bo_unref(surf->bos[i]);
990 if (bufmgr_initialized && bufmgr) {
991 LIST_DELINIT(&bufmgr->surf_list);
992 _deinit_surface_bufmgr();
994 _tbm_surface_mutex_unlock();
996 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
997 info->width, info->height,
998 _tbm_surface_internal_format_to_str(info->format), num);
1005 tbm_surface_internal_destroy(tbm_surface_h surface)
1007 _tbm_surface_mutex_lock();
1009 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1013 if (surface->refcnt > 0) {
1014 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1015 _tbm_surface_mutex_unlock();
1019 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1021 if (surface->refcnt == 0)
1022 _tbm_surface_internal_destroy(surface);
1024 _tbm_surface_mutex_unlock();
1028 tbm_surface_internal_ref(tbm_surface_h surface)
1030 _tbm_surface_mutex_lock();
1032 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1036 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1038 _tbm_surface_mutex_unlock();
1042 tbm_surface_internal_unref(tbm_surface_h surface)
1044 _tbm_surface_mutex_lock();
1046 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1050 if (surface->refcnt > 0) {
1051 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1052 _tbm_surface_mutex_unlock();
1056 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1058 if (surface->refcnt == 0)
1059 _tbm_surface_internal_destroy(surface);
1061 _tbm_surface_mutex_unlock();
1065 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1067 struct _tbm_surface *surf;
1070 _tbm_surface_mutex_lock();
1072 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1074 surf = (struct _tbm_surface *)surface;
1075 num = surf->num_bos;
1077 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1079 _tbm_surface_mutex_unlock();
1085 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1087 struct _tbm_surface *surf;
1090 _tbm_surface_mutex_lock();
1092 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1093 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1095 surf = (struct _tbm_surface *)surface;
1096 bo = surf->bos[bo_idx];
1098 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1100 _tbm_surface_mutex_unlock();
1106 tbm_surface_internal_get_size(tbm_surface_h surface)
1108 struct _tbm_surface *surf;
1111 _tbm_surface_mutex_lock();
1113 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1115 surf = (struct _tbm_surface *)surface;
1116 size = surf->info.size;
1118 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1120 _tbm_surface_mutex_unlock();
1126 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1127 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1129 struct _tbm_surface *surf;
1131 _tbm_surface_mutex_lock();
1133 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1134 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1136 surf = (struct _tbm_surface *)surface;
1138 if (plane_idx >= surf->info.num_planes) {
1139 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1140 _tbm_surface_mutex_unlock();
1145 *size = surf->info.planes[plane_idx].size;
1148 *offset = surf->info.planes[plane_idx].offset;
1151 *pitch = surf->info.planes[plane_idx].stride;
1153 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1154 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1155 surf->info.planes[plane_idx].stride);
1157 _tbm_surface_mutex_unlock();
1163 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1164 tbm_surface_info_s *info, int map)
1166 struct _tbm_surface *surf;
1167 tbm_bo_handle bo_handles[4];
1170 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1173 _tbm_surface_mutex_lock();
1175 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1177 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1179 surf = (struct _tbm_surface *)surface;
1181 memset(info, 0x00, sizeof(tbm_surface_info_s));
1182 info->width = surf->info.width;
1183 info->height = surf->info.height;
1184 info->format = surf->info.format;
1185 info->bpp = surf->info.bpp;
1186 info->size = surf->info.size;
1187 info->num_planes = surf->info.num_planes;
1189 for (i = 0; i < surf->info.num_planes; i++) {
1190 info->planes[i].size = surf->info.planes[i].size;
1191 info->planes[i].offset = surf->info.planes[i].offset;
1192 info->planes[i].stride = surf->info.planes[i].stride;
1193 planes_bo_idx[i] = surf->planes_bo_idx[i];
1196 for (i = 0; i < surf->num_bos; i++)
1197 bos[i] = surf->bos[i];
1199 num_bos = surf->num_bos;
1202 _tbm_surface_mutex_unlock();
1203 for (i = 0; i < num_bos; i++) {
1204 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1205 if (bo_handles[i].ptr == NULL) {
1206 for (j = 0; j < i; j++)
1207 tbm_bo_unmap(bos[j]);
1209 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1213 _tbm_surface_mutex_lock();
1215 for (i = 0; i < num_bos; i++) {
1216 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1217 if (bo_handles[i].ptr == NULL) {
1218 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1219 _tbm_surface_mutex_unlock();
1225 for (i = 0; i < info->num_planes; i++) {
1226 if (bo_handles[planes_bo_idx[i]].ptr)
1227 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1230 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1232 _tbm_surface_mutex_unlock();
1238 tbm_surface_internal_unmap(tbm_surface_h surface)
1240 struct _tbm_surface *surf;
1243 _tbm_surface_mutex_lock();
1245 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1247 surf = (struct _tbm_surface *)surface;
1249 for (i = 0; i < surf->num_bos; i++)
1250 tbm_bo_unmap(surf->bos[i]);
1252 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1254 _tbm_surface_mutex_unlock();
1258 tbm_surface_internal_get_width(tbm_surface_h surface)
1260 struct _tbm_surface *surf;
1263 _tbm_surface_mutex_lock();
1265 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1267 surf = (struct _tbm_surface *)surface;
1268 width = surf->info.width;
1270 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1272 _tbm_surface_mutex_unlock();
1278 tbm_surface_internal_get_height(tbm_surface_h surface)
1280 struct _tbm_surface *surf;
1281 unsigned int height;
1283 _tbm_surface_mutex_lock();
1285 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1287 surf = (struct _tbm_surface *)surface;
1288 height = surf->info.height;
1290 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1292 _tbm_surface_mutex_unlock();
1299 tbm_surface_internal_get_format(tbm_surface_h surface)
1301 struct _tbm_surface *surf;
1304 _tbm_surface_mutex_lock();
1306 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1308 surf = (struct _tbm_surface *)surface;
1309 format = surf->info.format;
1311 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1313 _tbm_surface_mutex_unlock();
1319 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1321 struct _tbm_surface *surf;
1324 _tbm_surface_mutex_lock();
1326 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1327 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1329 surf = (struct _tbm_surface *)surface;
1330 bo_idx = surf->planes_bo_idx[plane_idx];
1332 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1334 _tbm_surface_mutex_unlock();
1340 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1341 tbm_data_free data_free_func)
1343 tbm_user_data *data;
1345 _tbm_surface_mutex_lock();
1347 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1349 /* check if the data according to the key exist if so, return false. */
1350 data = user_data_lookup(&surface->user_data_list, key);
1352 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1353 _tbm_surface_mutex_unlock();
1357 data = user_data_create(key, data_free_func);
1359 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1360 _tbm_surface_mutex_unlock();
1364 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1366 LIST_ADD(&data->item_link, &surface->user_data_list);
1368 _tbm_surface_mutex_unlock();
1374 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1377 tbm_user_data *old_data;
1379 _tbm_surface_mutex_lock();
1381 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1383 old_data = user_data_lookup(&surface->user_data_list, key);
1385 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1386 _tbm_surface_mutex_unlock();
1390 if (old_data->data && old_data->free_func)
1391 old_data->free_func(old_data->data);
1393 old_data->data = data;
1395 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1397 _tbm_surface_mutex_unlock();
1403 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1406 tbm_user_data *old_data;
1408 _tbm_surface_mutex_lock();
1410 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1413 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1414 _tbm_surface_mutex_unlock();
1419 old_data = user_data_lookup(&surface->user_data_list, key);
1421 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1422 _tbm_surface_mutex_unlock();
1426 *data = old_data->data;
1428 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1430 _tbm_surface_mutex_unlock();
1436 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1439 tbm_user_data *old_data = (void *)0;
1441 _tbm_surface_mutex_lock();
1443 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
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 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1454 user_data_delete(old_data);
1456 _tbm_surface_mutex_unlock();
1461 /* LCOV_EXCL_START */
1463 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1465 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1467 return surface->debug_pid;
1471 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1473 _tbm_surface_mutex_lock();
1475 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1477 surface->debug_pid = pid;
1479 _tbm_surface_mutex_unlock();
1482 static tbm_surface_debug_data *
1483 _tbm_surface_internal_debug_data_create(char *key, char *value)
1485 tbm_surface_debug_data *debug_data = NULL;
1487 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1491 if (key) debug_data->key = strdup(key);
1492 if (value) debug_data->value = strdup(value);
1498 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1500 tbm_surface_debug_data *debug_data = NULL;
1501 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1502 tbm_bufmgr bufmgr = NULL;
1504 _tbm_surface_mutex_lock();
1506 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1507 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1509 bufmgr = surface->bufmgr;
1511 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1513 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1514 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1516 if (!strcmp(old_data->key, key)) {
1517 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1518 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1519 goto add_debug_key_list;
1522 if (old_data->value)
1523 free(old_data->value);
1526 old_data->value = strdup(value);
1528 old_data->value = NULL;
1530 goto add_debug_key_list;
1536 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1538 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1539 _tbm_surface_mutex_unlock();
1543 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1545 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1548 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1549 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1550 if (!strcmp(old_data->key, key)) {
1551 _tbm_surface_mutex_unlock();
1557 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1558 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1560 _tbm_surface_mutex_unlock();
1566 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1568 tbm_surface_debug_data *old_data = NULL;
1570 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1572 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1573 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1574 if (!strcmp(old_data->key, key))
1575 return old_data->value;
1582 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1583 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1585 struct _tbm_surface_dump_buf_info {
1595 tbm_surface_info_s info;
1597 struct list_head link;
1600 struct _tbm_surface_dump_info {
1601 char *path; // copy???
1604 struct list_head *link;
1605 struct list_head surface_list; /* link of surface */
1608 static tbm_surface_dump_info *g_dump_info = NULL;
1609 static const char *dump_postfix[2] = {"png", "yuv"};
1610 static double scale_factor;
1613 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1614 void *data2, int size2, void *data3, int size3)
1617 unsigned int *blocks;
1619 if (_tbm_surface_check_file_is_symbolic_link(file))
1620 TBM_ERR("%s is symbolic link\n", file);
1622 fp = fopen(file, "w+");
1623 TBM_RETURN_IF_FAIL(fp != NULL);
1625 blocks = (unsigned int *)data1;
1626 fwrite(blocks, 1, size1, fp);
1629 blocks = (unsigned int *)data2;
1630 fwrite(blocks, 1, size2, fp);
1634 blocks = (unsigned int *)data3;
1635 fwrite(blocks, 1, size3, fp);
1642 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1644 unsigned int *blocks = (unsigned int *)data;
1647 png_bytep *row_pointers;
1650 if (_tbm_surface_check_file_is_symbolic_link(file))
1651 TBM_ERR("%s is symbolic link\n", file);
1653 fp = fopen(file, "wb");
1654 TBM_RETURN_IF_FAIL(fp != NULL);
1656 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1659 TBM_ERR("fail to create a png write structure.\n");
1664 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1666 TBM_ERR("fail to create a png info structure.\n");
1667 png_destroy_write_struct(&pPngStruct, NULL);
1672 png_init_io(pPngStruct, fp);
1673 if (format == TBM_FORMAT_XRGB8888) {
1675 png_set_IHDR(pPngStruct,
1682 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1685 png_set_IHDR(pPngStruct,
1690 PNG_COLOR_TYPE_RGBA,
1692 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1695 png_set_bgr(pPngStruct);
1696 png_write_info(pPngStruct, pPngInfo);
1698 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1699 if (!row_pointers) {
1700 TBM_ERR("fail to allocate the png row_pointers.\n");
1701 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1706 for (y = 0; y < height; ++y) {
1710 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1712 TBM_ERR("fail to allocate the png row.\n");
1713 for (x = 0; x < y; x++)
1714 png_free(pPngStruct, row_pointers[x]);
1715 png_free(pPngStruct, row_pointers);
1716 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1720 row_pointers[y] = (png_bytep)row;
1722 for (x = 0; x < width; ++x) {
1723 unsigned int curBlock = blocks[y * width + x];
1725 if (pixel_size == 3) { // XRGB8888
1726 row[x * pixel_size] = (curBlock & 0xFF);
1727 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1728 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1729 } else { // ARGB8888
1730 row[x * pixel_size] = (curBlock & 0xFF);
1731 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1732 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1733 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1738 png_write_image(pPngStruct, row_pointers);
1739 png_write_end(pPngStruct, pPngInfo);
1741 for (y = 0; y < height; y++)
1742 png_free(pPngStruct, row_pointers[y]);
1743 png_free(pPngStruct, row_pointers);
1745 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1751 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1753 TBM_RETURN_IF_FAIL(path != NULL);
1754 TBM_RETURN_IF_FAIL(w > 0);
1755 TBM_RETURN_IF_FAIL(h > 0);
1756 TBM_RETURN_IF_FAIL(count > 0);
1758 tbm_surface_dump_buf_info *buf_info = NULL;
1759 tbm_surface_h tbm_surface;
1760 tbm_surface_info_s info;
1765 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1769 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1770 TBM_RETURN_IF_FAIL(g_dump_info);
1772 LIST_INITHEAD(&g_dump_info->surface_list);
1773 g_dump_info->count = 0;
1774 g_dump_info->dump_max = count;
1776 /* get buffer size */
1777 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1778 if (tbm_surface == NULL) {
1779 TBM_ERR("tbm_surface_create fail\n");
1785 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1786 TBM_ERR("tbm_surface_get_info fail\n");
1787 tbm_surface_destroy(tbm_surface);
1792 buffer_size = info.size;
1793 tbm_surface_destroy(tbm_surface);
1795 /* create dump lists */
1796 for (i = 0; i < count; i++) {
1799 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1800 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1802 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1804 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1809 buf_info->index = i;
1811 buf_info->size = buffer_size;
1813 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1816 g_dump_info->path = path;
1817 g_dump_info->link = &g_dump_info->surface_list;
1821 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1826 /* free resources */
1827 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1828 tbm_surface_dump_buf_info *tmp;
1830 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1831 tbm_bo_unref(buf_info->bo);
1832 LIST_DEL(&buf_info->link);
1837 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1846 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1853 tbm_surface_internal_dump_start(path, w, h, count);
1854 scale_factor = scale;
1858 tbm_surface_internal_dump_end(void)
1860 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1861 tbm_bo_handle bo_handle;
1866 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1873 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1876 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1877 if (bo_handle.ptr == NULL) {
1878 tbm_bo_unref(buf_info->bo);
1879 LIST_DEL(&buf_info->link);
1884 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1885 TBM_INFO("Dump File.. %s generated.\n", file);
1887 if (buf_info->dirty) {
1888 void *ptr1 = NULL, *ptr2 = NULL;
1890 switch (buf_info->info.format) {
1891 case TBM_FORMAT_ARGB8888:
1892 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1893 buf_info->info.planes[0].stride >> 2,
1894 buf_info->info.height, TBM_FORMAT_ARGB8888);
1896 case TBM_FORMAT_XRGB8888:
1897 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1898 buf_info->info.planes[0].stride >> 2,
1899 buf_info->info.height, TBM_FORMAT_XRGB8888);
1901 case TBM_FORMAT_YVU420:
1902 case TBM_FORMAT_YUV420:
1903 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1904 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1905 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1906 buf_info->info.planes[0].stride * buf_info->info.height,
1908 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1910 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1912 case TBM_FORMAT_NV12:
1913 case TBM_FORMAT_NV21:
1914 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1915 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1916 buf_info->info.planes[0].stride * buf_info->info.height,
1918 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1921 case TBM_FORMAT_YUYV:
1922 case TBM_FORMAT_UYVY:
1923 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1924 buf_info->info.planes[0].stride * buf_info->info.height,
1928 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1931 } else if (buf_info->dirty_shm)
1932 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1933 buf_info->shm_stride >> 2,
1934 buf_info->shm_h, 0);
1936 tbm_bo_unmap(buf_info->bo);
1937 tbm_bo_unref(buf_info->bo);
1938 LIST_DEL(&buf_info->link);
1945 TBM_INFO("Dump End..\n");
1948 static pixman_format_code_t
1949 _tbm_surface_internal_pixman_format_get(tbm_format format)
1952 case TBM_FORMAT_ARGB8888:
1953 return PIXMAN_a8r8g8b8;
1954 case TBM_FORMAT_XRGB8888:
1955 return PIXMAN_x8r8g8b8;
1964 * This function supports only if a buffer has below formats.
1965 * - TBM_FORMAT_ARGB8888
1966 * - TBM_FORMAT_XRGB8888
1968 static tbm_surface_error_e
1969 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
1970 int format, int src_stride, int src_w, int src_h,
1971 int dst_stride, int dst_w, int dst_h)
1973 pixman_image_t *src_img = NULL, *dst_img = NULL;
1974 pixman_format_code_t pixman_format;
1975 pixman_transform_t t;
1976 struct pixman_f_transform ft;
1977 double scale_x, scale_y;
1979 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1980 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
1982 pixman_format = _tbm_surface_internal_pixman_format_get(format);
1983 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
1986 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
1987 (uint32_t*)src_ptr, src_stride);
1988 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
1991 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
1992 (uint32_t*)dst_ptr, dst_stride);
1993 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
1995 pixman_f_transform_init_identity(&ft);
1997 scale_x = (double)src_w / dst_w;
1998 scale_y = (double)src_h / dst_h;
2000 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2001 pixman_f_transform_translate(&ft, NULL, 0, 0);
2002 pixman_transform_from_pixman_f_transform(&t, &ft);
2003 pixman_image_set_transform(src_img, &t);
2005 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2006 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2008 pixman_image_unref(src_img);
2009 pixman_image_unref(dst_img);
2011 return TBM_SURFACE_ERROR_NONE;
2015 pixman_image_unref(src_img);
2017 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2020 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2021 #define KEY_LEN 5 // "_XXXX"
2022 #define KEYS_LEN KEY_LEN * MAX_BOS
2024 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2026 char *keys, temp_key[KEY_LEN + 1];
2027 struct _tbm_surface *surf;
2031 _tbm_surface_mutex_lock();
2033 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2035 surf = (struct _tbm_surface *)surface;
2037 num_bos = surf->num_bos;
2038 if (num_bos > MAX_BOS)
2041 keys = calloc(KEYS_LEN + 1, sizeof(char));
2043 TBM_ERR("Failed to alloc memory");
2044 _tbm_surface_mutex_unlock();
2048 for (i = 0; i < num_bos; i++) {
2049 memset(temp_key, 0x00, KEY_LEN + 1);
2051 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2052 strncat(keys, temp_key, KEY_LEN);
2055 _tbm_surface_mutex_unlock();
2060 static void _tbm_surface_internal_put_keys(char *keys)
2067 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2069 TBM_RETURN_IF_FAIL(surface != NULL);
2070 TBM_RETURN_IF_FAIL(type != NULL);
2072 tbm_surface_dump_buf_info *buf_info;
2073 struct list_head *next_link;
2074 tbm_surface_info_s info;
2075 tbm_bo_handle bo_handle;
2076 const char *postfix;
2077 const char *format = NULL;
2084 next_link = g_dump_info->link->next;
2085 TBM_RETURN_IF_FAIL(next_link != NULL);
2087 if (next_link == &g_dump_info->surface_list) {
2088 next_link = next_link->next;
2089 TBM_RETURN_IF_FAIL(next_link != NULL);
2092 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2093 TBM_RETURN_IF_FAIL(buf_info != NULL);
2095 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2096 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2098 if (scale_factor > 0.0) {
2101 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2102 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2103 _tbm_surface_internal_format_to_str(info.format));
2104 tbm_surface_unmap(surface);
2108 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2110 buf_info->info.width = info.width * scale_factor;
2111 buf_info->info.height = info.height * scale_factor;
2112 buf_info->info.format = info.format;
2113 buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
2114 buf_info->info.num_planes = 1;
2115 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2116 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2118 if (buf_info->info.size > buf_info->size) {
2119 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2120 buf_info->info.size, buf_info->size);
2121 tbm_surface_unmap(surface);
2125 if (info.size > buf_info->size) {
2126 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2127 info.size, buf_info->size);
2128 tbm_surface_unmap(surface);
2132 /* make the file information */
2133 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2136 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2137 postfix = dump_postfix[0];
2138 format = _tbm_surface_internal_format_to_str(info.format);
2140 postfix = dump_postfix[1];
2142 keys = _tbm_surface_internal_get_keys(surface);
2144 TBM_ERR("fail to get keys");
2145 tbm_surface_unmap(surface);
2150 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2151 if (!bo_handle.ptr) {
2152 TBM_ERR("fail to map bo");
2153 _tbm_surface_internal_put_keys(keys);
2154 tbm_surface_unmap(surface);
2157 memset(bo_handle.ptr, 0x00, buf_info->size);
2159 switch (info.format) {
2160 case TBM_FORMAT_ARGB8888:
2161 case TBM_FORMAT_XRGB8888:
2162 snprintf(buf_info->name, sizeof(buf_info->name),
2163 "%10.3f_%03d%s_%p_%s-%s.%s",
2164 _tbm_surface_internal_get_time(),
2165 g_dump_info->count++, keys, surface, format, type, postfix);
2167 if (scale_factor > 0.0) {
2168 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2170 buf_info->info.format,
2171 info.planes[0].stride,
2172 info.width, info.height,
2173 buf_info->info.planes[0].stride,
2174 buf_info->info.width,
2175 buf_info->info.height);
2176 if (ret != TBM_SURFACE_ERROR_NONE) {
2177 TBM_ERR("fail to scale buffer");
2178 tbm_bo_unmap(buf_info->bo);
2179 _tbm_surface_internal_put_keys(keys);
2180 tbm_surface_unmap(surface);
2184 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2186 case TBM_FORMAT_YVU420:
2187 case TBM_FORMAT_YUV420:
2188 snprintf(buf_info->name, sizeof(buf_info->name),
2189 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2190 _tbm_surface_internal_get_time(),
2191 g_dump_info->count++, keys, type, info.planes[0].stride,
2192 info.height, FOURCC_STR(info.format), postfix);
2193 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2194 bo_handle.ptr += info.planes[0].stride * info.height;
2195 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2196 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2197 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2199 case TBM_FORMAT_NV12:
2200 case TBM_FORMAT_NV21:
2201 snprintf(buf_info->name, sizeof(buf_info->name),
2202 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2203 _tbm_surface_internal_get_time(),
2204 g_dump_info->count++, keys, type, info.planes[0].stride,
2205 info.height, FOURCC_STR(info.format), postfix);
2206 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2207 bo_handle.ptr += info.planes[0].stride * info.height;
2208 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2210 case TBM_FORMAT_YUYV:
2211 case TBM_FORMAT_UYVY:
2212 snprintf(buf_info->name, sizeof(buf_info->name),
2213 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2214 _tbm_surface_internal_get_time(),
2215 g_dump_info->count++, keys, type, info.planes[0].stride,
2216 info.height, FOURCC_STR(info.format), postfix);
2217 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2220 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2221 tbm_bo_unmap(buf_info->bo);
2222 _tbm_surface_internal_put_keys(keys);
2223 tbm_surface_unmap(surface);
2227 tbm_bo_unmap(buf_info->bo);
2229 _tbm_surface_internal_put_keys(keys);
2231 tbm_surface_unmap(surface);
2233 buf_info->dirty = 1;
2234 buf_info->dirty_shm = 0;
2236 if (g_dump_info->count == 1000)
2237 g_dump_info->count = 0;
2239 g_dump_info->link = next_link;
2241 TBM_INFO("Dump %s \n", buf_info->name);
2244 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2247 TBM_RETURN_IF_FAIL(ptr != NULL);
2248 TBM_RETURN_IF_FAIL(w > 0);
2249 TBM_RETURN_IF_FAIL(h > 0);
2250 TBM_RETURN_IF_FAIL(stride > 0);
2251 TBM_RETURN_IF_FAIL(type != NULL);
2253 tbm_surface_dump_buf_info *buf_info;
2254 struct list_head *next_link;
2255 tbm_bo_handle bo_handle;
2256 int ret, size, dw = 0, dh = 0, dstride = 0;
2261 next_link = g_dump_info->link->next;
2262 TBM_RETURN_IF_FAIL(next_link != NULL);
2264 if (next_link == &g_dump_info->surface_list) {
2265 next_link = next_link->next;
2266 TBM_RETURN_IF_FAIL(next_link != NULL);
2269 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2270 TBM_RETURN_IF_FAIL(buf_info != NULL);
2272 if (scale_factor > 0.0) {
2275 dw = w * scale_factor;
2276 dh = h * scale_factor;
2278 size = dstride * dh;
2282 if (size > buf_info->size) {
2283 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2284 size, buf_info->size);
2289 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2290 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2292 memset(bo_handle.ptr, 0x00, buf_info->size);
2293 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2295 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2296 _tbm_surface_internal_get_time(),
2297 g_dump_info->count++, type, dump_postfix[0]);
2298 if (scale_factor > 0.0) {
2299 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2300 TBM_FORMAT_ARGB8888, stride,
2301 w, h, dstride, dw, dh);
2302 if (ret != TBM_SURFACE_ERROR_NONE) {
2303 TBM_ERR("fail to scale buffer");
2304 tbm_bo_unmap(buf_info->bo);
2307 buf_info->shm_stride = dstride;
2308 buf_info->shm_h = dh;
2310 memcpy(bo_handle.ptr, ptr, size);
2311 buf_info->shm_stride = stride;
2312 buf_info->shm_h = h;
2315 tbm_bo_unmap(buf_info->bo);
2317 buf_info->dirty = 0;
2318 buf_info->dirty_shm = 1;
2320 if (g_dump_info->count == 1000)
2321 g_dump_info->count = 0;
2323 g_dump_info->link = next_link;
2325 TBM_INFO("Dump %s \n", buf_info->name);
2329 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2331 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2332 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2333 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2335 tbm_surface_info_s info;
2336 const char *postfix;
2340 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2341 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2343 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2344 postfix = dump_postfix[0];
2346 postfix = dump_postfix[1];
2348 if (strcmp(postfix, type)) {
2349 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2350 tbm_surface_unmap(surface);
2354 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2356 if (!access(file, 0)) {
2357 TBM_ERR("can't capture buffer, exist file %s", file);
2358 tbm_surface_unmap(surface);
2362 switch (info.format) {
2363 case TBM_FORMAT_ARGB8888:
2364 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2365 info.planes[0].stride >> 2,
2366 info.height, TBM_FORMAT_ARGB8888);
2368 case TBM_FORMAT_XRGB8888:
2369 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2370 info.planes[0].stride >> 2,
2371 info.height, TBM_FORMAT_XRGB8888);
2373 case TBM_FORMAT_YVU420:
2374 case TBM_FORMAT_YUV420:
2375 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2376 info.planes[0].stride * info.height,
2378 info.planes[1].stride * (info.height >> 1),
2380 info.planes[2].stride * (info.height >> 1));
2382 case TBM_FORMAT_NV12:
2383 case TBM_FORMAT_NV21:
2384 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2385 info.planes[0].stride * info.height,
2387 info.planes[1].stride * (info.height >> 1),
2390 case TBM_FORMAT_YUYV:
2391 case TBM_FORMAT_UYVY:
2392 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2393 info.planes[0].stride * info.height,
2397 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2398 tbm_surface_unmap(surface);
2402 tbm_surface_unmap(surface);
2404 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2410 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2411 const char *path, const char *name, const char *type)
2413 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2414 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2415 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2416 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2417 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2418 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2422 if (strcmp(dump_postfix[0], type)) {
2423 TBM_ERR("Not supported type:%s'", type);
2427 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2429 if (!access(file, 0)) {
2430 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2434 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2436 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);