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_get_bpp(tbm_format format)
495 case TBM_FORMAT_RGB332:
496 case TBM_FORMAT_BGR233:
499 case TBM_FORMAT_XRGB4444:
500 case TBM_FORMAT_XBGR4444:
501 case TBM_FORMAT_RGBX4444:
502 case TBM_FORMAT_BGRX4444:
503 case TBM_FORMAT_ARGB4444:
504 case TBM_FORMAT_ABGR4444:
505 case TBM_FORMAT_RGBA4444:
506 case TBM_FORMAT_BGRA4444:
507 case TBM_FORMAT_XRGB1555:
508 case TBM_FORMAT_XBGR1555:
509 case TBM_FORMAT_RGBX5551:
510 case TBM_FORMAT_BGRX5551:
511 case TBM_FORMAT_ARGB1555:
512 case TBM_FORMAT_ABGR1555:
513 case TBM_FORMAT_RGBA5551:
514 case TBM_FORMAT_BGRA5551:
515 case TBM_FORMAT_RGB565:
516 case TBM_FORMAT_BGR565:
519 case TBM_FORMAT_RGB888:
520 case TBM_FORMAT_BGR888:
523 case TBM_FORMAT_XRGB8888:
524 case TBM_FORMAT_XBGR8888:
525 case TBM_FORMAT_RGBX8888:
526 case TBM_FORMAT_BGRX8888:
527 case TBM_FORMAT_ARGB8888:
528 case TBM_FORMAT_ABGR8888:
529 case TBM_FORMAT_RGBA8888:
530 case TBM_FORMAT_BGRA8888:
531 case TBM_FORMAT_XRGB2101010:
532 case TBM_FORMAT_XBGR2101010:
533 case TBM_FORMAT_RGBX1010102:
534 case TBM_FORMAT_BGRX1010102:
535 case TBM_FORMAT_ARGB2101010:
536 case TBM_FORMAT_ABGR2101010:
537 case TBM_FORMAT_RGBA1010102:
538 case TBM_FORMAT_BGRA1010102:
539 case TBM_FORMAT_YUYV:
540 case TBM_FORMAT_YVYU:
541 case TBM_FORMAT_UYVY:
542 case TBM_FORMAT_VYUY:
543 case TBM_FORMAT_AYUV:
546 case TBM_FORMAT_NV12:
547 case TBM_FORMAT_NV12MT:
548 case TBM_FORMAT_NV21:
551 case TBM_FORMAT_NV16:
552 case TBM_FORMAT_NV61:
555 case TBM_FORMAT_YUV410:
556 case TBM_FORMAT_YVU410:
559 case TBM_FORMAT_YUV411:
560 case TBM_FORMAT_YVU411:
561 case TBM_FORMAT_YUV420:
562 case TBM_FORMAT_YVU420:
565 case TBM_FORMAT_YUV422:
566 case TBM_FORMAT_YVU422:
569 case TBM_FORMAT_YUV444:
570 case TBM_FORMAT_YVU444:
574 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
582 tbm_surface_internal_is_valid(tbm_surface_h surface)
586 _tbm_surface_mutex_lock();
588 /* Return silently if surface is null. */
590 _tbm_surface_mutex_unlock();
594 ret = _tbm_surface_internal_is_valid(surface);
596 _tbm_surface_mutex_unlock();
602 tbm_surface_internal_query_supported_formats(uint32_t **formats,
605 TBM_RETURN_VAL_IF_FAIL(formats, 0);
606 TBM_RETURN_VAL_IF_FAIL(num, 0);
608 struct _tbm_bufmgr *bufmgr;
610 bool bufmgr_initialized = false;
613 _tbm_surface_mutex_lock();
615 if (!g_surface_bufmgr) {
616 _init_surface_bufmgr();
617 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
618 bufmgr_initialized = true;
621 bufmgr = g_surface_bufmgr;
623 if (bufmgr->backend_module_data) {
624 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats)
627 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
628 if (error != TBM_ERROR_NONE) {
629 /* LCOV_EXCL_START */
630 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
632 /* LCOV_EXCL_START */
636 if (!bufmgr->backend->surface_supported_format)
639 ret = bufmgr->backend->surface_supported_format(formats, num);
641 /* LCOV_EXCL_START */
642 TBM_ERR("Fail to surface_supported_format.\n");
644 /* LCOV_EXCL_START */
648 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
650 if (bufmgr_initialized) {
651 LIST_DELINIT(&g_surface_bufmgr->surf_list);
652 _deinit_surface_bufmgr();
655 _tbm_surface_mutex_unlock();
659 /* LCOV_EXCL_START */
661 if (bufmgr_initialized) {
662 LIST_DELINIT(&g_surface_bufmgr->surf_list);
663 _deinit_surface_bufmgr();
665 _tbm_surface_mutex_unlock();
667 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
674 tbm_surface_internal_get_num_planes(tbm_format format)
678 _tbm_surface_mutex_lock();
679 _tbm_set_last_result(TBM_ERROR_NONE);
681 num_planes = _tbm_surface_internal_get_num_planes(format);
683 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
684 _tbm_surface_mutex_unlock();
688 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
690 _tbm_surface_mutex_unlock();
696 tbm_surface_internal_get_bpp(tbm_format format)
700 _tbm_surface_mutex_lock();
701 _tbm_set_last_result(TBM_ERROR_NONE);
703 bpp = _tbm_surface_internal_get_bpp(format);
705 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
706 _tbm_surface_mutex_unlock();
710 _tbm_surface_mutex_unlock();
712 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
718 tbm_surface_internal_create_with_flags(int width, int height,
719 int format, int flags)
721 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
722 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
724 struct _tbm_bufmgr *bufmgr;
725 struct _tbm_surface *surf = NULL;
729 uint32_t bo_size = 0;
732 bool bufmgr_initialized = false;
734 void *bo_priv = NULL;
735 tbm_backend_bo_data *bo_data = NULL;
738 _tbm_surface_mutex_lock();
740 if (!g_surface_bufmgr) {
741 _init_surface_bufmgr();
742 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
743 bufmgr_initialized = true;
746 bufmgr = g_surface_bufmgr;
747 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
748 TBM_ERR("The bufmgr is invalid\n");
749 goto check_valid_fail;
752 surf = calloc(1, sizeof(struct _tbm_surface));
754 /* LCOV_EXCL_START */
755 TBM_ERR("fail to alloc surf\n");
756 goto alloc_surf_fail;
760 surf->bufmgr = bufmgr;
761 surf->info.width = width;
762 surf->info.height = height;
763 surf->info.format = format;
764 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
765 if (!surf->info.bpp) {
766 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
769 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
770 if (!surf->info.num_planes) {
771 TBM_ERR("fail to get num_planes. error(%s)\n", tbm_error_str(tbm_get_last_error()));
772 goto num_planes_fail;
776 /* get size, stride and offset bo_idx */
777 for (i = 0; i < surf->info.num_planes; i++) {
778 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
779 &offset, &stride, &bo_idx)) {
780 TBM_ERR("fail to query plane data\n");
781 goto query_plane_data_fail;
784 surf->info.planes[i].size = size;
785 surf->info.planes[i].offset = offset;
786 surf->info.planes[i].stride = stride;
787 surf->planes_bo_idx[i] = bo_idx;
792 for (i = 0; i < surf->info.num_planes; i++) {
793 surf->info.size += surf->info.planes[i].size;
795 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
796 surf->num_bos = surf->planes_bo_idx[i] + 1;
801 for (i = 0; i < surf->num_bos; i++) {
803 for (j = 0; j < surf->info.num_planes; j++) {
804 if (surf->planes_bo_idx[j] == i)
805 bo_size += surf->info.planes[j].size;
808 if (bufmgr->backend_module_data) {
809 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
810 /* LCOV_EXCL_START */
811 bo = calloc(1, sizeof(struct _tbm_bo));
813 TBM_ERR("fail to alloc bo struct\n");
817 bo->bufmgr = surf->bufmgr;
819 pthread_mutex_lock(&surf->bufmgr->lock);
821 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format(bufmgr->bufmgr_data, format, i,
822 width, height, flags, &error);
824 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
826 pthread_mutex_unlock(&surf->bufmgr->lock);
829 bo->bo_data = bo_data;
833 LIST_INITHEAD(&bo->user_data_list);
835 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
837 pthread_mutex_unlock(&surf->bufmgr->lock);
842 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
844 TBM_ERR("fail to alloc bo idx:%d\n", i);
849 if (bufmgr->backend->surface_bo_alloc) {
850 /* LCOV_EXCL_START */
851 bo = calloc(1, sizeof(struct _tbm_bo));
853 TBM_ERR("fail to alloc bo struct\n");
857 bo->bufmgr = surf->bufmgr;
859 pthread_mutex_lock(&surf->bufmgr->lock);
861 bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
863 TBM_ERR("fail to alloc bo priv\n");
865 pthread_mutex_unlock(&surf->bufmgr->lock);
872 LIST_INITHEAD(&bo->user_data_list);
874 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
876 pthread_mutex_unlock(&surf->bufmgr->lock);
881 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
883 TBM_ERR("fail to alloc bo idx:%d\n", i);
889 _tbm_bo_set_surface(surf->bos[i], surf);
892 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
893 _tbm_surface_internal_format_to_str(format), flags, surf);
895 LIST_INITHEAD(&surf->user_data_list);
896 LIST_INITHEAD(&surf->debug_data_list);
898 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
900 _tbm_surface_mutex_unlock();
904 /* LCOV_EXCL_START */
906 for (j = 0; j < i; j++) {
908 tbm_bo_unref(surf->bos[j]);
910 query_plane_data_fail:
916 if (bufmgr_initialized && bufmgr) {
917 LIST_DELINIT(&bufmgr->surf_list);
918 _deinit_surface_bufmgr();
920 _tbm_surface_mutex_unlock();
922 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
924 _tbm_surface_internal_format_to_str(format), flags);
931 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
932 tbm_bo *bos, int num)
934 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
935 TBM_RETURN_VAL_IF_FAIL(info, NULL);
936 TBM_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
937 TBM_RETURN_VAL_IF_FAIL(num > 0, NULL);
938 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
940 struct _tbm_bufmgr *bufmgr;
941 struct _tbm_surface *surf = NULL;
943 bool bufmgr_initialized = false;
945 _tbm_surface_mutex_lock();
947 if (!g_surface_bufmgr) {
948 _init_surface_bufmgr();
949 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
950 bufmgr_initialized = true;
953 bufmgr = g_surface_bufmgr;
954 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
955 TBM_ERR("fail to validate the Bufmgr.\n");
956 goto check_valid_fail;
959 surf = calloc(1, sizeof(struct _tbm_surface));
961 /* LCOV_EXCL_START */
962 TBM_ERR("fail to allocate struct _tbm_surface.\n");
963 goto alloc_surf_fail;
967 surf->bufmgr = bufmgr;
968 surf->info.width = info->width;
969 surf->info.height = info->height;
970 surf->info.format = info->format;
972 surf->info.bpp = info->bpp;
974 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
975 if (!surf->info.bpp) {
976 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
980 surf->info.num_planes = info->num_planes;
983 /* get size, stride and offset */
984 for (i = 0; i < info->num_planes; i++) {
985 surf->info.planes[i].offset = info->planes[i].offset;
986 surf->info.planes[i].stride = info->planes[i].stride;
988 if (info->planes[i].size > 0)
989 surf->info.planes[i].size = info->planes[i].size;
991 uint32_t size = 0, offset = 0, stride = 0;
994 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
995 surf->info.planes[i].size = size;
999 surf->planes_bo_idx[i] = 0;
1001 surf->planes_bo_idx[i] = i;
1004 if (info->size > 0) {
1005 surf->info.size = info->size;
1007 surf->info.size = 0;
1008 for (i = 0; i < info->num_planes; i++)
1009 surf->info.size += surf->info.planes[i].size;
1012 surf->flags = TBM_BO_DEFAULT;
1014 /* create only one bo */
1015 surf->num_bos = num;
1016 for (i = 0; i < num; i++) {
1017 if (bos[i] == NULL) {
1018 TBM_ERR("bos[%d] is null.\n", i);
1022 surf->bos[i] = tbm_bo_ref(bos[i]);
1023 _tbm_bo_set_surface(bos[i], surf);
1026 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1027 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1029 LIST_INITHEAD(&surf->user_data_list);
1030 LIST_INITHEAD(&surf->debug_data_list);
1032 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1034 _tbm_surface_mutex_unlock();
1038 /* LCOV_EXCL_START */
1041 for (i = 0; i < num; i++) {
1043 tbm_bo_unref(surf->bos[i]);
1048 if (bufmgr_initialized && bufmgr) {
1049 LIST_DELINIT(&bufmgr->surf_list);
1050 _deinit_surface_bufmgr();
1052 _tbm_surface_mutex_unlock();
1054 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1055 info->width, info->height,
1056 _tbm_surface_internal_format_to_str(info->format), num);
1057 /* LCOV_EXCL_STOP */
1063 tbm_surface_internal_destroy(tbm_surface_h surface)
1065 _tbm_surface_mutex_lock();
1067 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1071 if (surface->refcnt > 0) {
1072 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1073 _tbm_surface_mutex_unlock();
1077 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1079 if (surface->refcnt == 0)
1080 _tbm_surface_internal_destroy(surface);
1082 _tbm_surface_mutex_unlock();
1086 tbm_surface_internal_ref(tbm_surface_h surface)
1088 _tbm_surface_mutex_lock();
1090 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1094 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1096 _tbm_surface_mutex_unlock();
1100 tbm_surface_internal_unref(tbm_surface_h surface)
1102 _tbm_surface_mutex_lock();
1104 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1108 if (surface->refcnt > 0) {
1109 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1110 _tbm_surface_mutex_unlock();
1114 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1116 if (surface->refcnt == 0)
1117 _tbm_surface_internal_destroy(surface);
1119 _tbm_surface_mutex_unlock();
1123 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1125 struct _tbm_surface *surf;
1128 _tbm_surface_mutex_lock();
1130 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1132 surf = (struct _tbm_surface *)surface;
1133 num = surf->num_bos;
1135 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1137 _tbm_surface_mutex_unlock();
1143 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1145 struct _tbm_surface *surf;
1148 _tbm_surface_mutex_lock();
1150 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1151 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1153 surf = (struct _tbm_surface *)surface;
1154 bo = surf->bos[bo_idx];
1156 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1158 _tbm_surface_mutex_unlock();
1164 tbm_surface_internal_get_size(tbm_surface_h surface)
1166 struct _tbm_surface *surf;
1169 _tbm_surface_mutex_lock();
1171 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1173 surf = (struct _tbm_surface *)surface;
1174 size = surf->info.size;
1176 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1178 _tbm_surface_mutex_unlock();
1184 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1185 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1187 struct _tbm_surface *surf;
1189 _tbm_surface_mutex_lock();
1191 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1192 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1194 surf = (struct _tbm_surface *)surface;
1196 if (plane_idx >= surf->info.num_planes) {
1197 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1198 _tbm_surface_mutex_unlock();
1203 *size = surf->info.planes[plane_idx].size;
1206 *offset = surf->info.planes[plane_idx].offset;
1209 *pitch = surf->info.planes[plane_idx].stride;
1211 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1212 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1213 surf->info.planes[plane_idx].stride);
1215 _tbm_surface_mutex_unlock();
1221 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1222 tbm_surface_info_s *info, int map)
1224 struct _tbm_surface *surf;
1225 tbm_bo_handle bo_handles[4];
1228 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1231 _tbm_surface_mutex_lock();
1233 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1235 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1237 surf = (struct _tbm_surface *)surface;
1239 memset(info, 0x00, sizeof(tbm_surface_info_s));
1240 info->width = surf->info.width;
1241 info->height = surf->info.height;
1242 info->format = surf->info.format;
1243 info->bpp = surf->info.bpp;
1244 info->size = surf->info.size;
1245 info->num_planes = surf->info.num_planes;
1247 for (i = 0; i < surf->info.num_planes; i++) {
1248 info->planes[i].size = surf->info.planes[i].size;
1249 info->planes[i].offset = surf->info.planes[i].offset;
1250 info->planes[i].stride = surf->info.planes[i].stride;
1251 planes_bo_idx[i] = surf->planes_bo_idx[i];
1254 for (i = 0; i < surf->num_bos; i++)
1255 bos[i] = surf->bos[i];
1257 num_bos = surf->num_bos;
1260 _tbm_surface_mutex_unlock();
1261 for (i = 0; i < num_bos; i++) {
1262 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1263 if (bo_handles[i].ptr == NULL) {
1264 for (j = 0; j < i; j++)
1265 tbm_bo_unmap(bos[j]);
1267 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1271 _tbm_surface_mutex_lock();
1273 for (i = 0; i < num_bos; i++) {
1274 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1275 if (bo_handles[i].ptr == NULL) {
1276 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1277 _tbm_surface_mutex_unlock();
1283 for (i = 0; i < info->num_planes; i++) {
1284 if (bo_handles[planes_bo_idx[i]].ptr)
1285 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1288 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1290 _tbm_surface_mutex_unlock();
1296 tbm_surface_internal_unmap(tbm_surface_h surface)
1298 struct _tbm_surface *surf;
1301 _tbm_surface_mutex_lock();
1303 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1305 surf = (struct _tbm_surface *)surface;
1307 for (i = 0; i < surf->num_bos; i++)
1308 tbm_bo_unmap(surf->bos[i]);
1310 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1312 _tbm_surface_mutex_unlock();
1316 tbm_surface_internal_get_width(tbm_surface_h surface)
1318 struct _tbm_surface *surf;
1321 _tbm_surface_mutex_lock();
1323 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1325 surf = (struct _tbm_surface *)surface;
1326 width = surf->info.width;
1328 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1330 _tbm_surface_mutex_unlock();
1336 tbm_surface_internal_get_height(tbm_surface_h surface)
1338 struct _tbm_surface *surf;
1339 unsigned int height;
1341 _tbm_surface_mutex_lock();
1343 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1345 surf = (struct _tbm_surface *)surface;
1346 height = surf->info.height;
1348 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1350 _tbm_surface_mutex_unlock();
1357 tbm_surface_internal_get_format(tbm_surface_h surface)
1359 struct _tbm_surface *surf;
1362 _tbm_surface_mutex_lock();
1364 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1366 surf = (struct _tbm_surface *)surface;
1367 format = surf->info.format;
1369 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1371 _tbm_surface_mutex_unlock();
1377 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1379 struct _tbm_surface *surf;
1382 _tbm_surface_mutex_lock();
1384 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1385 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1387 surf = (struct _tbm_surface *)surface;
1388 bo_idx = surf->planes_bo_idx[plane_idx];
1390 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1392 _tbm_surface_mutex_unlock();
1398 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1399 tbm_data_free data_free_func)
1401 tbm_user_data *data;
1403 _tbm_surface_mutex_lock();
1405 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1407 /* check if the data according to the key exist if so, return false. */
1408 data = user_data_lookup(&surface->user_data_list, key);
1410 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1411 _tbm_surface_mutex_unlock();
1415 data = user_data_create(key, data_free_func);
1417 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1418 _tbm_surface_mutex_unlock();
1422 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1424 LIST_ADD(&data->item_link, &surface->user_data_list);
1426 _tbm_surface_mutex_unlock();
1432 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1435 tbm_user_data *old_data;
1437 _tbm_surface_mutex_lock();
1439 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1441 old_data = user_data_lookup(&surface->user_data_list, key);
1443 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1444 _tbm_surface_mutex_unlock();
1448 if (old_data->data && old_data->free_func)
1449 old_data->free_func(old_data->data);
1451 old_data->data = data;
1453 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1455 _tbm_surface_mutex_unlock();
1461 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1464 tbm_user_data *old_data;
1466 _tbm_surface_mutex_lock();
1468 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1471 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1472 _tbm_surface_mutex_unlock();
1477 old_data = user_data_lookup(&surface->user_data_list, key);
1479 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1480 _tbm_surface_mutex_unlock();
1484 *data = old_data->data;
1486 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1488 _tbm_surface_mutex_unlock();
1494 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1497 tbm_user_data *old_data = (void *)0;
1499 _tbm_surface_mutex_lock();
1501 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1503 old_data = user_data_lookup(&surface->user_data_list, key);
1505 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1506 _tbm_surface_mutex_unlock();
1510 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1512 user_data_delete(old_data);
1514 _tbm_surface_mutex_unlock();
1519 /* LCOV_EXCL_START */
1521 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1523 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1525 return surface->debug_pid;
1529 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1531 _tbm_surface_mutex_lock();
1533 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1535 surface->debug_pid = pid;
1537 _tbm_surface_mutex_unlock();
1540 static tbm_surface_debug_data *
1541 _tbm_surface_internal_debug_data_create(char *key, char *value)
1543 tbm_surface_debug_data *debug_data = NULL;
1545 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1549 if (key) debug_data->key = strdup(key);
1550 if (value) debug_data->value = strdup(value);
1556 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1558 tbm_surface_debug_data *debug_data = NULL;
1559 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1560 tbm_bufmgr bufmgr = NULL;
1562 _tbm_surface_mutex_lock();
1564 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1565 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1567 bufmgr = surface->bufmgr;
1569 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1571 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1572 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1574 if (!strcmp(old_data->key, key)) {
1575 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1576 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1577 goto add_debug_key_list;
1580 if (old_data->value)
1581 free(old_data->value);
1584 old_data->value = strdup(value);
1586 old_data->value = NULL;
1588 goto add_debug_key_list;
1594 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1596 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1597 _tbm_surface_mutex_unlock();
1601 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1603 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1606 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1607 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1608 if (!strcmp(old_data->key, key)) {
1609 _tbm_surface_mutex_unlock();
1615 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1616 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1618 _tbm_surface_mutex_unlock();
1624 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1626 tbm_surface_debug_data *old_data = NULL;
1628 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1630 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1631 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1632 if (!strcmp(old_data->key, key))
1633 return old_data->value;
1640 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1641 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1643 struct _tbm_surface_dump_buf_info {
1653 tbm_surface_info_s info;
1655 struct list_head link;
1658 struct _tbm_surface_dump_info {
1659 char *path; // copy???
1662 struct list_head *link;
1663 struct list_head surface_list; /* link of surface */
1666 static tbm_surface_dump_info *g_dump_info = NULL;
1667 static const char *dump_postfix[2] = {"png", "yuv"};
1668 static double scale_factor;
1671 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1672 void *data2, int size2, void *data3, int size3)
1675 unsigned int *blocks;
1677 if (_tbm_surface_check_file_is_symbolic_link(file))
1678 TBM_ERR("%s is symbolic link\n", file);
1680 fp = fopen(file, "w+");
1681 TBM_RETURN_IF_FAIL(fp != NULL);
1683 blocks = (unsigned int *)data1;
1684 fwrite(blocks, 1, size1, fp);
1687 blocks = (unsigned int *)data2;
1688 fwrite(blocks, 1, size2, fp);
1692 blocks = (unsigned int *)data3;
1693 fwrite(blocks, 1, size3, fp);
1700 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1702 unsigned int *blocks = (unsigned int *)data;
1705 png_bytep *row_pointers;
1708 if (_tbm_surface_check_file_is_symbolic_link(file))
1709 TBM_ERR("%s is symbolic link\n", file);
1711 fp = fopen(file, "wb");
1712 TBM_RETURN_IF_FAIL(fp != NULL);
1714 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1717 TBM_ERR("fail to create a png write structure.\n");
1722 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1724 TBM_ERR("fail to create a png info structure.\n");
1725 png_destroy_write_struct(&pPngStruct, NULL);
1730 png_init_io(pPngStruct, fp);
1731 if (format == TBM_FORMAT_XRGB8888) {
1733 png_set_IHDR(pPngStruct,
1740 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1743 png_set_IHDR(pPngStruct,
1748 PNG_COLOR_TYPE_RGBA,
1750 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1753 png_set_bgr(pPngStruct);
1754 png_write_info(pPngStruct, pPngInfo);
1756 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1757 if (!row_pointers) {
1758 TBM_ERR("fail to allocate the png row_pointers.\n");
1759 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1764 for (y = 0; y < height; ++y) {
1768 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1770 TBM_ERR("fail to allocate the png row.\n");
1771 for (x = 0; x < y; x++)
1772 png_free(pPngStruct, row_pointers[x]);
1773 png_free(pPngStruct, row_pointers);
1774 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1778 row_pointers[y] = (png_bytep)row;
1780 for (x = 0; x < width; ++x) {
1781 unsigned int curBlock = blocks[y * width + x];
1783 if (pixel_size == 3) { // XRGB8888
1784 row[x * pixel_size] = (curBlock & 0xFF);
1785 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1786 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1787 } else { // ARGB8888
1788 row[x * pixel_size] = (curBlock & 0xFF);
1789 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1790 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1791 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1796 png_write_image(pPngStruct, row_pointers);
1797 png_write_end(pPngStruct, pPngInfo);
1799 for (y = 0; y < height; y++)
1800 png_free(pPngStruct, row_pointers[y]);
1801 png_free(pPngStruct, row_pointers);
1803 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1809 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1811 TBM_RETURN_IF_FAIL(path != NULL);
1812 TBM_RETURN_IF_FAIL(w > 0);
1813 TBM_RETURN_IF_FAIL(h > 0);
1814 TBM_RETURN_IF_FAIL(count > 0);
1816 tbm_surface_dump_buf_info *buf_info = NULL;
1817 tbm_surface_h tbm_surface;
1818 tbm_surface_info_s info;
1823 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1827 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1828 TBM_RETURN_IF_FAIL(g_dump_info);
1830 LIST_INITHEAD(&g_dump_info->surface_list);
1831 g_dump_info->count = 0;
1832 g_dump_info->dump_max = count;
1834 /* get buffer size */
1835 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1836 if (tbm_surface == NULL) {
1837 TBM_ERR("tbm_surface_create fail\n");
1843 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1844 TBM_ERR("tbm_surface_get_info fail\n");
1845 tbm_surface_destroy(tbm_surface);
1850 buffer_size = info.size;
1851 tbm_surface_destroy(tbm_surface);
1853 /* create dump lists */
1854 for (i = 0; i < count; i++) {
1857 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1858 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1860 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1862 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1867 buf_info->index = i;
1869 buf_info->size = buffer_size;
1871 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1874 g_dump_info->path = path;
1875 g_dump_info->link = &g_dump_info->surface_list;
1879 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1884 /* free resources */
1885 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1886 tbm_surface_dump_buf_info *tmp;
1888 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1889 tbm_bo_unref(buf_info->bo);
1890 LIST_DEL(&buf_info->link);
1895 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1904 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1911 tbm_surface_internal_dump_start(path, w, h, count);
1912 scale_factor = scale;
1916 tbm_surface_internal_dump_end(void)
1918 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1919 tbm_bo_handle bo_handle;
1924 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1931 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1934 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1935 if (bo_handle.ptr == NULL) {
1936 tbm_bo_unref(buf_info->bo);
1937 LIST_DEL(&buf_info->link);
1942 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1943 TBM_INFO("Dump File.. %s generated.\n", file);
1945 if (buf_info->dirty) {
1946 void *ptr1 = NULL, *ptr2 = NULL;
1948 switch (buf_info->info.format) {
1949 case TBM_FORMAT_ARGB8888:
1950 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1951 buf_info->info.planes[0].stride >> 2,
1952 buf_info->info.height, TBM_FORMAT_ARGB8888);
1954 case TBM_FORMAT_XRGB8888:
1955 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1956 buf_info->info.planes[0].stride >> 2,
1957 buf_info->info.height, TBM_FORMAT_XRGB8888);
1959 case TBM_FORMAT_YVU420:
1960 case TBM_FORMAT_YUV420:
1961 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1962 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1963 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1964 buf_info->info.planes[0].stride * buf_info->info.height,
1966 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1968 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1970 case TBM_FORMAT_NV12:
1971 case TBM_FORMAT_NV21:
1972 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1973 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1974 buf_info->info.planes[0].stride * buf_info->info.height,
1976 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1979 case TBM_FORMAT_YUYV:
1980 case TBM_FORMAT_UYVY:
1981 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1982 buf_info->info.planes[0].stride * buf_info->info.height,
1986 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1989 } else if (buf_info->dirty_shm)
1990 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1991 buf_info->shm_stride >> 2,
1992 buf_info->shm_h, 0);
1994 tbm_bo_unmap(buf_info->bo);
1995 tbm_bo_unref(buf_info->bo);
1996 LIST_DEL(&buf_info->link);
2003 TBM_INFO("Dump End..\n");
2006 static pixman_format_code_t
2007 _tbm_surface_internal_pixman_format_get(tbm_format format)
2010 case TBM_FORMAT_ARGB8888:
2011 return PIXMAN_a8r8g8b8;
2012 case TBM_FORMAT_XRGB8888:
2013 return PIXMAN_x8r8g8b8;
2022 * This function supports only if a buffer has below formats.
2023 * - TBM_FORMAT_ARGB8888
2024 * - TBM_FORMAT_XRGB8888
2026 static tbm_surface_error_e
2027 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2028 int format, int src_stride, int src_w, int src_h,
2029 int dst_stride, int dst_w, int dst_h)
2031 pixman_image_t *src_img = NULL, *dst_img = NULL;
2032 pixman_format_code_t pixman_format;
2033 pixman_transform_t t;
2034 struct pixman_f_transform ft;
2035 double scale_x, scale_y;
2037 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2038 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2040 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2041 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2044 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2045 (uint32_t*)src_ptr, src_stride);
2046 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2049 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2050 (uint32_t*)dst_ptr, dst_stride);
2051 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2053 pixman_f_transform_init_identity(&ft);
2055 scale_x = (double)src_w / dst_w;
2056 scale_y = (double)src_h / dst_h;
2058 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2059 pixman_f_transform_translate(&ft, NULL, 0, 0);
2060 pixman_transform_from_pixman_f_transform(&t, &ft);
2061 pixman_image_set_transform(src_img, &t);
2063 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2064 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2066 pixman_image_unref(src_img);
2067 pixman_image_unref(dst_img);
2069 return TBM_SURFACE_ERROR_NONE;
2073 pixman_image_unref(src_img);
2075 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2078 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2079 #define KEY_LEN 5 // "_XXXX"
2080 #define KEYS_LEN KEY_LEN * MAX_BOS
2082 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2084 char *keys, temp_key[KEY_LEN + 1];
2085 struct _tbm_surface *surf;
2089 _tbm_surface_mutex_lock();
2091 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2093 surf = (struct _tbm_surface *)surface;
2095 num_bos = surf->num_bos;
2096 if (num_bos > MAX_BOS)
2099 keys = calloc(KEYS_LEN + 1, sizeof(char));
2101 TBM_ERR("Failed to alloc memory");
2102 _tbm_surface_mutex_unlock();
2106 for (i = 0; i < num_bos; i++) {
2107 memset(temp_key, 0x00, KEY_LEN + 1);
2109 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2110 strncat(keys, temp_key, KEY_LEN);
2113 _tbm_surface_mutex_unlock();
2118 static void _tbm_surface_internal_put_keys(char *keys)
2125 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2127 TBM_RETURN_IF_FAIL(surface != NULL);
2128 TBM_RETURN_IF_FAIL(type != NULL);
2130 tbm_surface_dump_buf_info *buf_info;
2131 struct list_head *next_link;
2132 tbm_surface_info_s info;
2133 tbm_bo_handle bo_handle;
2134 const char *postfix;
2135 const char *format = NULL;
2142 next_link = g_dump_info->link->next;
2143 TBM_RETURN_IF_FAIL(next_link != NULL);
2145 if (next_link == &g_dump_info->surface_list) {
2146 next_link = next_link->next;
2147 TBM_RETURN_IF_FAIL(next_link != NULL);
2150 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2151 TBM_RETURN_IF_FAIL(buf_info != NULL);
2153 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2154 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2156 if (scale_factor > 0.0) {
2159 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2160 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2161 _tbm_surface_internal_format_to_str(info.format));
2162 tbm_surface_unmap(surface);
2166 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2168 buf_info->info.width = info.width * scale_factor;
2169 buf_info->info.height = info.height * scale_factor;
2170 buf_info->info.format = info.format;
2171 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2172 if (!buf_info->info.bpp) {
2173 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2174 tbm_surface_unmap(surface);
2177 buf_info->info.num_planes = 1;
2178 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2179 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2181 if (buf_info->info.size > buf_info->size) {
2182 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2183 buf_info->info.size, buf_info->size);
2184 tbm_surface_unmap(surface);
2188 if (info.size > buf_info->size) {
2189 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2190 info.size, buf_info->size);
2191 tbm_surface_unmap(surface);
2195 /* make the file information */
2196 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2199 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2200 postfix = dump_postfix[0];
2201 format = _tbm_surface_internal_format_to_str(info.format);
2203 postfix = dump_postfix[1];
2205 keys = _tbm_surface_internal_get_keys(surface);
2207 TBM_ERR("fail to get keys");
2208 tbm_surface_unmap(surface);
2213 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2214 if (!bo_handle.ptr) {
2215 TBM_ERR("fail to map bo");
2216 _tbm_surface_internal_put_keys(keys);
2217 tbm_surface_unmap(surface);
2220 memset(bo_handle.ptr, 0x00, buf_info->size);
2222 switch (info.format) {
2223 case TBM_FORMAT_ARGB8888:
2224 case TBM_FORMAT_XRGB8888:
2225 snprintf(buf_info->name, sizeof(buf_info->name),
2226 "%10.3f_%03d%s_%p_%s-%s.%s",
2227 _tbm_surface_internal_get_time(),
2228 g_dump_info->count++, keys, surface, format, type, postfix);
2230 if (scale_factor > 0.0) {
2231 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2233 buf_info->info.format,
2234 info.planes[0].stride,
2235 info.width, info.height,
2236 buf_info->info.planes[0].stride,
2237 buf_info->info.width,
2238 buf_info->info.height);
2239 if (ret != TBM_SURFACE_ERROR_NONE) {
2240 TBM_ERR("fail to scale buffer");
2241 tbm_bo_unmap(buf_info->bo);
2242 _tbm_surface_internal_put_keys(keys);
2243 tbm_surface_unmap(surface);
2247 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2249 case TBM_FORMAT_YVU420:
2250 case TBM_FORMAT_YUV420:
2251 snprintf(buf_info->name, sizeof(buf_info->name),
2252 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2253 _tbm_surface_internal_get_time(),
2254 g_dump_info->count++, keys, type, info.planes[0].stride,
2255 info.height, FOURCC_STR(info.format), postfix);
2256 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2257 bo_handle.ptr += info.planes[0].stride * info.height;
2258 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2259 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2260 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2262 case TBM_FORMAT_NV12:
2263 case TBM_FORMAT_NV21:
2264 snprintf(buf_info->name, sizeof(buf_info->name),
2265 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2266 _tbm_surface_internal_get_time(),
2267 g_dump_info->count++, keys, type, info.planes[0].stride,
2268 info.height, FOURCC_STR(info.format), postfix);
2269 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2270 bo_handle.ptr += info.planes[0].stride * info.height;
2271 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2273 case TBM_FORMAT_YUYV:
2274 case TBM_FORMAT_UYVY:
2275 snprintf(buf_info->name, sizeof(buf_info->name),
2276 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2277 _tbm_surface_internal_get_time(),
2278 g_dump_info->count++, keys, type, info.planes[0].stride,
2279 info.height, FOURCC_STR(info.format), postfix);
2280 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2283 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2284 tbm_bo_unmap(buf_info->bo);
2285 _tbm_surface_internal_put_keys(keys);
2286 tbm_surface_unmap(surface);
2290 tbm_bo_unmap(buf_info->bo);
2292 _tbm_surface_internal_put_keys(keys);
2294 tbm_surface_unmap(surface);
2296 buf_info->dirty = 1;
2297 buf_info->dirty_shm = 0;
2299 if (g_dump_info->count == 1000)
2300 g_dump_info->count = 0;
2302 g_dump_info->link = next_link;
2304 TBM_INFO("Dump %s \n", buf_info->name);
2307 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2310 TBM_RETURN_IF_FAIL(ptr != NULL);
2311 TBM_RETURN_IF_FAIL(w > 0);
2312 TBM_RETURN_IF_FAIL(h > 0);
2313 TBM_RETURN_IF_FAIL(stride > 0);
2314 TBM_RETURN_IF_FAIL(type != NULL);
2316 tbm_surface_dump_buf_info *buf_info;
2317 struct list_head *next_link;
2318 tbm_bo_handle bo_handle;
2319 int ret, size, dw = 0, dh = 0, dstride = 0;
2324 next_link = g_dump_info->link->next;
2325 TBM_RETURN_IF_FAIL(next_link != NULL);
2327 if (next_link == &g_dump_info->surface_list) {
2328 next_link = next_link->next;
2329 TBM_RETURN_IF_FAIL(next_link != NULL);
2332 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2333 TBM_RETURN_IF_FAIL(buf_info != NULL);
2335 if (scale_factor > 0.0) {
2338 dw = w * scale_factor;
2339 dh = h * scale_factor;
2341 size = dstride * dh;
2345 if (size > buf_info->size) {
2346 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2347 size, buf_info->size);
2352 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2353 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2355 memset(bo_handle.ptr, 0x00, buf_info->size);
2356 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2358 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2359 _tbm_surface_internal_get_time(),
2360 g_dump_info->count++, type, dump_postfix[0]);
2361 if (scale_factor > 0.0) {
2362 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2363 TBM_FORMAT_ARGB8888, stride,
2364 w, h, dstride, dw, dh);
2365 if (ret != TBM_SURFACE_ERROR_NONE) {
2366 TBM_ERR("fail to scale buffer");
2367 tbm_bo_unmap(buf_info->bo);
2370 buf_info->shm_stride = dstride;
2371 buf_info->shm_h = dh;
2373 memcpy(bo_handle.ptr, ptr, size);
2374 buf_info->shm_stride = stride;
2375 buf_info->shm_h = h;
2378 tbm_bo_unmap(buf_info->bo);
2380 buf_info->dirty = 0;
2381 buf_info->dirty_shm = 1;
2383 if (g_dump_info->count == 1000)
2384 g_dump_info->count = 0;
2386 g_dump_info->link = next_link;
2388 TBM_INFO("Dump %s \n", buf_info->name);
2392 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2394 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2395 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2396 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2398 tbm_surface_info_s info;
2399 const char *postfix;
2403 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2404 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2406 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2407 postfix = dump_postfix[0];
2409 postfix = dump_postfix[1];
2411 if (strcmp(postfix, type)) {
2412 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2413 tbm_surface_unmap(surface);
2417 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2419 if (!access(file, 0)) {
2420 TBM_ERR("can't capture buffer, exist file %s", file);
2421 tbm_surface_unmap(surface);
2425 switch (info.format) {
2426 case TBM_FORMAT_ARGB8888:
2427 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2428 info.planes[0].stride >> 2,
2429 info.height, TBM_FORMAT_ARGB8888);
2431 case TBM_FORMAT_XRGB8888:
2432 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2433 info.planes[0].stride >> 2,
2434 info.height, TBM_FORMAT_XRGB8888);
2436 case TBM_FORMAT_YVU420:
2437 case TBM_FORMAT_YUV420:
2438 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2439 info.planes[0].stride * info.height,
2441 info.planes[1].stride * (info.height >> 1),
2443 info.planes[2].stride * (info.height >> 1));
2445 case TBM_FORMAT_NV12:
2446 case TBM_FORMAT_NV21:
2447 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2448 info.planes[0].stride * info.height,
2450 info.planes[1].stride * (info.height >> 1),
2453 case TBM_FORMAT_YUYV:
2454 case TBM_FORMAT_UYVY:
2455 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2456 info.planes[0].stride * info.height,
2460 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2461 tbm_surface_unmap(surface);
2465 tbm_surface_unmap(surface);
2467 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2473 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2474 const char *path, const char *name, const char *type)
2476 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2477 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2478 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2479 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2480 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2481 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2485 if (strcmp(dump_postfix[0], type)) {
2486 TBM_ERR("Not supported type:%s'", type);
2490 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2492 if (!access(file, 0)) {
2493 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2497 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2499 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);