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 **************************************************************************/
36 #include "tbm_bufmgr.h"
37 #include "tbm_bufmgr_int.h"
38 #include "tbm_surface_internal.h"
42 #define C(b, m) (((b) >> (m)) & 0xFF)
43 #define B(c, s) ((((unsigned int)(c)) & 0xff) << (s))
44 #define FOURCC(a, b, c, d) (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
45 #define FOURCC_STR(id) C(id, 0), C(id, 8), C(id, 16), C(id, 24)
46 #define FOURCC_ID(str) FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
48 static tbm_bufmgr g_surface_bufmgr;
49 static pthread_mutex_t tbm_surface_lock;
52 #define USE_REALTIME 1
55 _tbm_surface_internal_get_time(void)
61 clock_gettime(CLOCK_REALTIME, &tp);
62 #else /* USE_MONOTONIC */
63 clock_gettime(CLOCK_MONOTONIC, &tp);
65 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
71 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
73 LIST_DEL(&debug_data->item_link);
75 if (debug_data->key) free(debug_data->key);
76 if (debug_data->value) free(debug_data->value);
81 _tbm_surface_internal_format_to_str(tbm_format format)
85 return "TBM_FORMAT_C8";
86 case TBM_FORMAT_RGB332:
87 return "TBM_FORMAT_RGB332";
88 case TBM_FORMAT_BGR233:
89 return "TBM_FORMAT_BGR233";
90 case TBM_FORMAT_XRGB4444:
91 return "TBM_FORMAT_XRGB4444";
92 case TBM_FORMAT_XBGR4444:
93 return "TBM_FORMAT_XBGR4444";
94 case TBM_FORMAT_RGBX4444:
95 return "TBM_FORMAT_RGBX4444";
96 case TBM_FORMAT_BGRX4444:
97 return "TBM_FORMAT_BGRX4444";
98 case TBM_FORMAT_ARGB4444:
99 return "TBM_FORMAT_ARGB4444";
100 case TBM_FORMAT_ABGR4444:
101 return "TBM_FORMAT_ABGR4444";
102 case TBM_FORMAT_RGBA4444:
103 return "TBM_FORMAT_RGBA4444";
104 case TBM_FORMAT_BGRA4444:
105 return "TBM_FORMAT_BGRA4444";
106 case TBM_FORMAT_XRGB1555:
107 return "TBM_FORMAT_XRGB1555";
108 case TBM_FORMAT_XBGR1555:
109 return "TBM_FORMAT_XBGR1555";
110 case TBM_FORMAT_RGBX5551:
111 return "TBM_FORMAT_RGBX5551";
112 case TBM_FORMAT_BGRX5551:
113 return "TBM_FORMAT_BGRX5551";
114 case TBM_FORMAT_ARGB1555:
115 return "TBM_FORMAT_ARGB1555";
116 case TBM_FORMAT_ABGR1555:
117 return "TBM_FORMAT_ABGR1555";
118 case TBM_FORMAT_RGBA5551:
119 return "TBM_FORMAT_RGBA5551";
120 case TBM_FORMAT_BGRA5551:
121 return "TBM_FORMAT_BGRA5551";
122 case TBM_FORMAT_RGB565:
123 return "TBM_FORMAT_RGB565";
124 case TBM_FORMAT_BGR565:
125 return "TBM_FORMAT_BGR565";
126 case TBM_FORMAT_RGB888:
127 return "TBM_FORMAT_RGB888";
128 case TBM_FORMAT_BGR888:
129 return "TBM_FORMAT_BGR888";
130 case TBM_FORMAT_XRGB8888:
131 return "TBM_FORMAT_XRGB8888";
132 case TBM_FORMAT_XBGR8888:
133 return "TBM_FORMAT_XBGR8888";
134 case TBM_FORMAT_RGBX8888:
135 return "TBM_FORMAT_RGBX8888";
136 case TBM_FORMAT_BGRX8888:
137 return "TBM_FORMAT_BGRX8888";
138 case TBM_FORMAT_ARGB8888:
139 return "TBM_FORMAT_ARGB8888";
140 case TBM_FORMAT_ABGR8888:
141 return "TBM_FORMAT_ABGR8888";
142 case TBM_FORMAT_RGBA8888:
143 return "TBM_FORMAT_RGBA8888";
144 case TBM_FORMAT_BGRA8888:
145 return "TBM_FORMAT_BGRA8888";
146 case TBM_FORMAT_XRGB2101010:
147 return "TBM_FORMAT_XRGB2101010";
148 case TBM_FORMAT_XBGR2101010:
149 return "TBM_FORMAT_XBGR2101010";
150 case TBM_FORMAT_RGBX1010102:
151 return "TBM_FORMAT_RGBX1010102";
152 case TBM_FORMAT_BGRX1010102:
153 return "TBM_FORMAT_BGRX1010102";
154 case TBM_FORMAT_ARGB2101010:
155 return "TBM_FORMAT_ARGB2101010";
156 case TBM_FORMAT_ABGR2101010:
157 return "TBM_FORMAT_ABGR2101010";
158 case TBM_FORMAT_RGBA1010102:
159 return "TBM_FORMAT_RGBA1010102";
160 case TBM_FORMAT_BGRA1010102:
161 return "TBM_FORMAT_BGRA1010102";
162 case TBM_FORMAT_YUYV:
163 return "TBM_FORMAT_YUYV";
164 case TBM_FORMAT_YVYU:
165 return "TBM_FORMAT_YVYU";
166 case TBM_FORMAT_UYVY:
167 return "TBM_FORMAT_UYVY";
168 case TBM_FORMAT_VYUY:
169 return "TBM_FORMAT_VYUY";
170 case TBM_FORMAT_AYUV:
171 return "TBM_FORMAT_AYUV";
172 case TBM_FORMAT_NV12:
173 return "TBM_FORMAT_NV12";
174 case TBM_FORMAT_NV21:
175 return "TBM_FORMAT_NV21";
176 case TBM_FORMAT_NV16:
177 return "TBM_FORMAT_NV16";
178 case TBM_FORMAT_NV61:
179 return "TBM_FORMAT_NV61";
180 case TBM_FORMAT_YUV410:
181 return "TBM_FORMAT_YUV410";
182 case TBM_FORMAT_YVU410:
183 return "TBM_FORMAT_YVU410";
184 case TBM_FORMAT_YUV411:
185 return "TBM_FORMAT_YUV411";
186 case TBM_FORMAT_YVU411:
187 return "TBM_FORMAT_YVU411";
188 case TBM_FORMAT_YUV420:
189 return "TBM_FORMAT_YUV420";
190 case TBM_FORMAT_YVU420:
191 return "TBM_FORMAT_YVU420";
192 case TBM_FORMAT_YUV422:
193 return "TBM_FORMAT_YUV422";
194 case TBM_FORMAT_YVU422:
195 return "TBM_FORMAT_YVU422";
196 case TBM_FORMAT_YUV444:
197 return "TBM_FORMAT_YUV444";
198 case TBM_FORMAT_YVU444:
199 return "TBM_FORMAT_YVU444";
200 case TBM_FORMAT_NV12MT:
201 return "TBM_FORMAT_NV12MT";
209 _tbm_surface_mutex_init(void)
211 static bool tbm_surface_mutex_init = false;
213 if (tbm_surface_mutex_init)
216 if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
217 TBM_LOG_E("fail: tbm_surface mutex init\n");
221 tbm_surface_mutex_init = true;
227 _tbm_surface_mutex_lock(void)
229 if (!_tbm_surface_mutex_init())
232 pthread_mutex_lock(&tbm_surface_lock);
236 _tbm_surface_mutex_unlock(void)
238 pthread_mutex_unlock(&tbm_surface_lock);
242 _init_surface_bufmgr(void)
244 g_surface_bufmgr = tbm_bufmgr_init(-1);
248 _deinit_surface_bufmgr(void)
250 if (!g_surface_bufmgr)
253 tbm_bufmgr_deinit(g_surface_bufmgr);
254 g_surface_bufmgr = NULL;
258 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
259 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
261 TBM_RETURN_VAL_IF_FAIL(surface, 0);
262 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
264 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
265 struct _tbm_bufmgr *mgr = surf->bufmgr;
268 TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
269 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
270 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
271 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
273 if (!mgr->backend->surface_get_plane_data)
276 ret = mgr->backend->surface_get_plane_data(surf->info.width,
277 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
285 _tbm_surface_internal_destroy(tbm_surface_h surface)
288 tbm_bufmgr bufmgr = surface->bufmgr;
289 tbm_user_data *old_data = NULL, *tmp = NULL;
290 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
292 /* destory the user_data_list */
293 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
294 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
295 DBG("free user_data\n");
296 user_data_delete(old_data);
300 for (i = 0; i < surface->num_bos; i++) {
301 surface->bos[i]->surface = NULL;
303 tbm_bo_unref(surface->bos[i]);
304 surface->bos[i] = NULL;
307 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
308 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
309 _tbm_surface_internal_debug_data_delete(debug_old_data);
312 LIST_DEL(&surface->item_link);
317 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
318 LIST_DELINIT(&bufmgr->surf_list);
320 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
321 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
322 _tbm_surface_internal_debug_data_delete(debug_old_data);
326 _deinit_surface_bufmgr();
331 _tbm_surface_get_max_size(int * w, int * h)
334 tbm_surface_h surface = NULL, tmp = NULL;
335 tbm_surface_info_s info;
340 if (g_surface_bufmgr == NULL)
343 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
344 LIST_FOR_EACH_ENTRY_SAFE(surface, tmp, &g_surface_bufmgr->surf_list, item_link) {
345 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
347 if (*w < info.width) *w = info.width;
348 if (*h < info.height) *h = info.height;
357 tbm_surface_internal_is_valid(tbm_surface_h surface)
359 tbm_surface_h old_data = NULL, tmp = NULL;
361 if (surface == NULL || g_surface_bufmgr == NULL) {
362 TBM_TRACE("error: tbm_surface(%p)\n", surface);
366 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
367 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &g_surface_bufmgr->surf_list, item_link) {
368 if (old_data == surface) {
369 TBM_TRACE("tbm_surface(%p)\n", surface);
374 TBM_TRACE("error: tbm_surface(%p)\n", surface);
379 tbm_surface_internal_query_supported_formats(uint32_t **formats,
382 struct _tbm_bufmgr *mgr;
385 _tbm_surface_mutex_lock();
387 if (!g_surface_bufmgr) {
388 _init_surface_bufmgr();
389 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
392 mgr = g_surface_bufmgr;
394 if (!mgr->backend->surface_supported_format) {
395 TBM_TRACE("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
396 _tbm_surface_mutex_unlock();
400 ret = mgr->backend->surface_supported_format(formats, num);
402 TBM_TRACE("tbm_bufmgr(%p) format num(%d)\n", g_surface_bufmgr, *num);
404 _tbm_surface_mutex_unlock();
410 tbm_surface_internal_get_num_planes(tbm_format format)
416 case TBM_FORMAT_RGB332:
417 case TBM_FORMAT_BGR233:
418 case TBM_FORMAT_XRGB4444:
419 case TBM_FORMAT_XBGR4444:
420 case TBM_FORMAT_RGBX4444:
421 case TBM_FORMAT_BGRX4444:
422 case TBM_FORMAT_ARGB4444:
423 case TBM_FORMAT_ABGR4444:
424 case TBM_FORMAT_RGBA4444:
425 case TBM_FORMAT_BGRA4444:
426 case TBM_FORMAT_XRGB1555:
427 case TBM_FORMAT_XBGR1555:
428 case TBM_FORMAT_RGBX5551:
429 case TBM_FORMAT_BGRX5551:
430 case TBM_FORMAT_ARGB1555:
431 case TBM_FORMAT_ABGR1555:
432 case TBM_FORMAT_RGBA5551:
433 case TBM_FORMAT_BGRA5551:
434 case TBM_FORMAT_RGB565:
435 case TBM_FORMAT_BGR565:
436 case TBM_FORMAT_RGB888:
437 case TBM_FORMAT_BGR888:
438 case TBM_FORMAT_XRGB8888:
439 case TBM_FORMAT_XBGR8888:
440 case TBM_FORMAT_RGBX8888:
441 case TBM_FORMAT_BGRX8888:
442 case TBM_FORMAT_ARGB8888:
443 case TBM_FORMAT_ABGR8888:
444 case TBM_FORMAT_RGBA8888:
445 case TBM_FORMAT_BGRA8888:
446 case TBM_FORMAT_XRGB2101010:
447 case TBM_FORMAT_XBGR2101010:
448 case TBM_FORMAT_RGBX1010102:
449 case TBM_FORMAT_BGRX1010102:
450 case TBM_FORMAT_ARGB2101010:
451 case TBM_FORMAT_ABGR2101010:
452 case TBM_FORMAT_RGBA1010102:
453 case TBM_FORMAT_BGRA1010102:
454 case TBM_FORMAT_YUYV:
455 case TBM_FORMAT_YVYU:
456 case TBM_FORMAT_UYVY:
457 case TBM_FORMAT_VYUY:
458 case TBM_FORMAT_AYUV:
461 case TBM_FORMAT_NV12:
462 case TBM_FORMAT_NV12MT:
463 case TBM_FORMAT_NV21:
464 case TBM_FORMAT_NV16:
465 case TBM_FORMAT_NV61:
468 case TBM_FORMAT_YUV410:
469 case TBM_FORMAT_YVU410:
470 case TBM_FORMAT_YUV411:
471 case TBM_FORMAT_YVU411:
472 case TBM_FORMAT_YUV420:
473 case TBM_FORMAT_YVU420:
474 case TBM_FORMAT_YUV422:
475 case TBM_FORMAT_YVU422:
476 case TBM_FORMAT_YUV444:
477 case TBM_FORMAT_YVU444:
485 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
491 tbm_surface_internal_get_bpp(tbm_format format)
498 case TBM_FORMAT_RGB332:
499 case TBM_FORMAT_BGR233:
502 case TBM_FORMAT_XRGB4444:
503 case TBM_FORMAT_XBGR4444:
504 case TBM_FORMAT_RGBX4444:
505 case TBM_FORMAT_BGRX4444:
506 case TBM_FORMAT_ARGB4444:
507 case TBM_FORMAT_ABGR4444:
508 case TBM_FORMAT_RGBA4444:
509 case TBM_FORMAT_BGRA4444:
510 case TBM_FORMAT_XRGB1555:
511 case TBM_FORMAT_XBGR1555:
512 case TBM_FORMAT_RGBX5551:
513 case TBM_FORMAT_BGRX5551:
514 case TBM_FORMAT_ARGB1555:
515 case TBM_FORMAT_ABGR1555:
516 case TBM_FORMAT_RGBA5551:
517 case TBM_FORMAT_BGRA5551:
518 case TBM_FORMAT_RGB565:
519 case TBM_FORMAT_BGR565:
522 case TBM_FORMAT_RGB888:
523 case TBM_FORMAT_BGR888:
526 case TBM_FORMAT_XRGB8888:
527 case TBM_FORMAT_XBGR8888:
528 case TBM_FORMAT_RGBX8888:
529 case TBM_FORMAT_BGRX8888:
530 case TBM_FORMAT_ARGB8888:
531 case TBM_FORMAT_ABGR8888:
532 case TBM_FORMAT_RGBA8888:
533 case TBM_FORMAT_BGRA8888:
534 case TBM_FORMAT_XRGB2101010:
535 case TBM_FORMAT_XBGR2101010:
536 case TBM_FORMAT_RGBX1010102:
537 case TBM_FORMAT_BGRX1010102:
538 case TBM_FORMAT_ARGB2101010:
539 case TBM_FORMAT_ABGR2101010:
540 case TBM_FORMAT_RGBA1010102:
541 case TBM_FORMAT_BGRA1010102:
542 case TBM_FORMAT_YUYV:
543 case TBM_FORMAT_YVYU:
544 case TBM_FORMAT_UYVY:
545 case TBM_FORMAT_VYUY:
546 case TBM_FORMAT_AYUV:
549 case TBM_FORMAT_NV12:
550 case TBM_FORMAT_NV12MT:
551 case TBM_FORMAT_NV21:
554 case TBM_FORMAT_NV16:
555 case TBM_FORMAT_NV61:
558 case TBM_FORMAT_YUV410:
559 case TBM_FORMAT_YVU410:
562 case TBM_FORMAT_YUV411:
563 case TBM_FORMAT_YVU411:
564 case TBM_FORMAT_YUV420:
565 case TBM_FORMAT_YVU420:
568 case TBM_FORMAT_YUV422:
569 case TBM_FORMAT_YVU422:
572 case TBM_FORMAT_YUV444:
573 case TBM_FORMAT_YVU444:
580 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
586 tbm_surface_internal_create_with_flags(int width, int height,
587 int format, int flags)
589 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
590 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
592 struct _tbm_bufmgr *mgr;
593 struct _tbm_surface *surf = NULL;
597 uint32_t bo_size = 0;
601 _tbm_surface_mutex_lock();
603 if (!g_surface_bufmgr) {
604 _init_surface_bufmgr();
605 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
608 mgr = g_surface_bufmgr;
609 if (!TBM_BUFMGR_IS_VALID(mgr)) {
610 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
611 width, height, _tbm_surface_internal_format_to_str(format), flags);
612 _tbm_surface_mutex_unlock();
615 surf = calloc(1, sizeof(struct _tbm_surface));
617 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
618 width, height, _tbm_surface_internal_format_to_str(format), flags);
619 _tbm_surface_mutex_unlock();
624 surf->info.width = width;
625 surf->info.height = height;
626 surf->info.format = format;
627 surf->info.bpp = tbm_surface_internal_get_bpp(format);
628 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
631 /* get size, stride and offset bo_idx */
632 for (i = 0; i < surf->info.num_planes; i++) {
633 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride,
635 surf->info.planes[i].size = size;
636 surf->info.planes[i].offset = offset;
637 surf->info.planes[i].stride = stride;
638 surf->planes_bo_idx[i] = bo_idx;
643 for (i = 0; i < surf->info.num_planes; i++) {
644 surf->info.size += surf->info.planes[i].size;
646 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
647 surf->num_bos = surf->planes_bo_idx[i] + 1;
652 for (i = 0; i < surf->num_bos; i++) {
654 for (j = 0; j < surf->info.num_planes; j++) {
655 if (surf->planes_bo_idx[j] == i)
656 bo_size += surf->info.planes[j].size;
659 if (mgr->backend->surface_bo_alloc) {
660 /* LCOV_EXCL_START */
662 void *bo_priv = NULL;
664 bo = calloc(1, sizeof(struct _tbm_bo));
666 TBM_LOG_E("fail to alloc bo struct\n");
670 bo->bufmgr = surf->bufmgr;
672 pthread_mutex_lock(&surf->bufmgr->lock);
674 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
676 TBM_LOG_E("fail to alloc bo priv\n");
678 pthread_mutex_unlock(&surf->bufmgr->lock);
686 LIST_INITHEAD(&bo->user_data_list);
688 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
690 pthread_mutex_unlock(&surf->bufmgr->lock);
695 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
699 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
703 _tbm_bo_set_surface(surf->bos[i], surf);
707 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
708 _tbm_surface_internal_format_to_str(format), flags, surf);
710 LIST_INITHEAD(&surf->user_data_list);
711 LIST_INITHEAD(&surf->debug_data_list);
713 LIST_ADD(&surf->item_link, &mgr->surf_list);
715 _tbm_surface_mutex_unlock();
721 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
722 width, height, _tbm_surface_internal_format_to_str(format), flags);
724 for (j = 0; j < i; j++) {
726 tbm_bo_unref(surf->bos[j]);
732 if (LIST_IS_EMPTY(&mgr->surf_list)) {
733 LIST_DELINIT(&mgr->surf_list);
734 _deinit_surface_bufmgr();
737 _tbm_surface_mutex_unlock();
742 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
743 tbm_bo *bos, int num)
745 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
746 TBM_RETURN_VAL_IF_FAIL(info, NULL);
747 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
749 struct _tbm_bufmgr *mgr;
750 struct _tbm_surface *surf = NULL;
753 _tbm_surface_mutex_lock();
755 if (!g_surface_bufmgr) {
756 _init_surface_bufmgr();
757 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
760 mgr = g_surface_bufmgr;
761 if (!TBM_BUFMGR_IS_VALID(mgr)) {
762 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
763 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
764 _tbm_surface_mutex_unlock();
768 surf = calloc(1, sizeof(struct _tbm_surface));
770 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
771 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
772 _tbm_surface_mutex_unlock();
777 surf->info.width = info->width;
778 surf->info.height = info->height;
779 surf->info.format = info->format;
780 surf->info.bpp = info->bpp;
781 surf->info.num_planes = info->num_planes;
784 /* get size, stride and offset */
785 for (i = 0; i < info->num_planes; i++) {
786 surf->info.planes[i].offset = info->planes[i].offset;
787 surf->info.planes[i].stride = info->planes[i].stride;
789 if (info->planes[i].size > 0)
790 surf->info.planes[i].size = info->planes[i].size;
792 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
795 surf->planes_bo_idx[i] = 0;
797 surf->planes_bo_idx[i] = i;
800 if (info->size > 0) {
801 surf->info.size = info->size;
804 for (i = 0; i < info->num_planes; i++)
805 surf->info.size += surf->info.planes[i].size;
808 surf->flags = TBM_BO_DEFAULT;
810 /* create only one bo */
812 for (i = 0; i < num; i++) {
816 surf->bos[i] = tbm_bo_ref(bos[i]);
817 _tbm_bo_set_surface(bos[i], surf);
820 TBM_TRACE("tbm_surface(%p) width(%d) height(%d) format(%s) bo_num(%d)\n", surf,
821 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
823 LIST_INITHEAD(&surf->user_data_list);
824 LIST_INITHEAD(&surf->debug_data_list);
826 LIST_ADD(&surf->item_link, &mgr->surf_list);
828 _tbm_surface_mutex_unlock();
832 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
833 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
834 for (i = 0; i < num; i++) {
836 tbm_bo_unref(surf->bos[i]);
844 if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
845 LIST_DELINIT(&g_surface_bufmgr->surf_list);
846 _deinit_surface_bufmgr();
849 _tbm_surface_mutex_unlock();
855 tbm_surface_internal_destroy(tbm_surface_h surface)
857 if (!tbm_surface_internal_is_valid(surface))
860 _tbm_surface_mutex_lock();
864 if (surface->refcnt > 0) {
865 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
866 _tbm_surface_mutex_unlock();
870 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
872 if (surface->refcnt == 0)
873 _tbm_surface_internal_destroy(surface);
875 _tbm_surface_mutex_unlock();
879 tbm_surface_internal_ref(tbm_surface_h surface)
881 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
883 _tbm_surface_mutex_lock();
887 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
889 _tbm_surface_mutex_unlock();
893 tbm_surface_internal_unref(tbm_surface_h surface)
895 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
897 _tbm_surface_mutex_lock();
901 if (surface->refcnt > 0) {
902 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
903 _tbm_surface_mutex_unlock();
907 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
909 if (surface->refcnt == 0)
910 _tbm_surface_internal_destroy(surface);
912 _tbm_surface_mutex_unlock();
916 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
918 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
920 struct _tbm_surface *surf;
923 _tbm_surface_mutex_lock();
925 surf = (struct _tbm_surface *)surface;
928 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
930 _tbm_surface_mutex_unlock();
936 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
938 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
939 TBM_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
941 struct _tbm_surface *surf;
944 _tbm_surface_mutex_lock();
946 surf = (struct _tbm_surface *)surface;
947 bo = surf->bos[bo_idx];
949 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
951 _tbm_surface_mutex_unlock();
957 tbm_surface_internal_get_size(tbm_surface_h surface)
959 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
961 struct _tbm_surface *surf;
964 _tbm_surface_mutex_lock();
966 surf = (struct _tbm_surface *)surface;
967 size = surf->info.size;
969 TBM_TRACE("tbm_surface(%p) size(%d)\n", surface, size);
971 _tbm_surface_mutex_unlock();
977 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
978 uint32_t *size, uint32_t *offset, uint32_t *pitch)
980 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
981 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
983 struct _tbm_surface *surf;
985 _tbm_surface_mutex_lock();
987 surf = (struct _tbm_surface *)surface;
989 if (plane_idx >= surf->info.num_planes) {
990 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
991 _tbm_surface_mutex_unlock();
996 *size = surf->info.planes[plane_idx].size;
999 *offset = surf->info.planes[plane_idx].offset;
1002 *pitch = surf->info.planes[plane_idx].stride;
1004 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%d) offset(%d) pitch(%d)\n", surface, plane_idx,
1005 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1006 surf->info.planes[plane_idx].stride);
1008 _tbm_surface_mutex_unlock();
1014 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1015 tbm_surface_info_s *info, int map)
1017 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1019 struct _tbm_surface *surf;
1020 tbm_bo_handle bo_handles[4];
1023 _tbm_surface_mutex_lock();
1025 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1027 surf = (struct _tbm_surface *)surface;
1029 memset(info, 0x00, sizeof(tbm_surface_info_s));
1030 info->width = surf->info.width;
1031 info->height = surf->info.height;
1032 info->format = surf->info.format;
1033 info->bpp = surf->info.bpp;
1034 info->size = surf->info.size;
1035 info->num_planes = surf->info.num_planes;
1038 for (i = 0; i < surf->num_bos; i++) {
1039 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1040 if (bo_handles[i].ptr == NULL) {
1041 for (j = 0; j < i; j++)
1042 tbm_bo_unmap(surf->bos[j]);
1044 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1045 _tbm_surface_mutex_unlock();
1050 for (i = 0; i < surf->num_bos; i++)
1051 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1054 for (i = 0; i < surf->info.num_planes; i++) {
1055 info->planes[i].size = surf->info.planes[i].size;
1056 info->planes[i].offset = surf->info.planes[i].offset;
1057 info->planes[i].stride = surf->info.planes[i].stride;
1059 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1060 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1061 surf->info.planes[i].offset;
1064 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1066 _tbm_surface_mutex_unlock();
1072 tbm_surface_internal_unmap(tbm_surface_h surface)
1074 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1076 struct _tbm_surface *surf;
1079 _tbm_surface_mutex_lock();
1081 surf = (struct _tbm_surface *)surface;
1083 for (i = 0; i < surf->num_bos; i++)
1084 tbm_bo_unmap(surf->bos[i]);
1086 TBM_TRACE("tbm_surface(%p)\n", surface);
1088 _tbm_surface_mutex_unlock();
1092 tbm_surface_internal_get_width(tbm_surface_h surface)
1094 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1096 struct _tbm_surface *surf;
1099 _tbm_surface_mutex_lock();
1101 surf = (struct _tbm_surface *)surface;
1102 width = surf->info.width;
1104 TBM_TRACE("tbm_surface(%p) width(%d)\n", surface, width);
1106 _tbm_surface_mutex_unlock();
1112 tbm_surface_internal_get_height(tbm_surface_h surface)
1114 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1116 struct _tbm_surface *surf;
1117 unsigned int height;
1119 _tbm_surface_mutex_lock();
1121 surf = (struct _tbm_surface *)surface;
1122 height = surf->info.height;
1124 TBM_TRACE("tbm_surface(%p) height(%d)\n", surface, height);
1126 _tbm_surface_mutex_unlock();
1133 tbm_surface_internal_get_format(tbm_surface_h surface)
1135 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1137 struct _tbm_surface *surf;
1140 _tbm_surface_mutex_lock();
1142 surf = (struct _tbm_surface *)surface;
1143 format = surf->info.format;
1145 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1147 _tbm_surface_mutex_unlock();
1153 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1155 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1156 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1157 struct _tbm_surface *surf;
1160 _tbm_surface_mutex_lock();
1162 surf = (struct _tbm_surface *)surface;
1163 bo_idx = surf->planes_bo_idx[plane_idx];
1165 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1167 _tbm_surface_mutex_unlock();
1173 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1174 tbm_data_free data_free_func)
1176 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1178 tbm_user_data *data;
1180 /* check if the data according to the key exist if so, return false. */
1181 data = user_data_lookup(&surface->user_data_list, key);
1183 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1187 data = user_data_create(key, data_free_func);
1189 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1193 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1195 LIST_ADD(&data->item_link, &surface->user_data_list);
1201 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1204 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1206 tbm_user_data *old_data;
1208 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1209 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1213 old_data = user_data_lookup(&surface->user_data_list, key);
1215 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1219 if (old_data->data && old_data->free_func)
1220 old_data->free_func(old_data->data);
1222 old_data->data = data;
1224 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1230 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1233 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1235 tbm_user_data *old_data;
1237 if (!data || LIST_IS_EMPTY(&surface->user_data_list)) {
1238 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1242 old_data = user_data_lookup(&surface->user_data_list, key);
1244 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1249 *data = old_data->data;
1251 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1257 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1260 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1262 tbm_user_data *old_data = (void *)0;
1264 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1265 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1269 old_data = user_data_lookup(&surface->user_data_list, key);
1271 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1275 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1277 user_data_delete(old_data);
1282 /* LCOV_EXCL_START */
1284 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1286 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1288 return surface->debug_pid;
1292 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1294 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1296 surface->debug_pid = pid;
1299 static tbm_surface_debug_data *
1300 _tbm_surface_internal_debug_data_create(char *key, char *value)
1302 tbm_surface_debug_data *debug_data = NULL;
1304 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1308 if (key) debug_data->key = strdup(key);
1309 if (value) debug_data->value = strdup(value);
1315 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1317 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1318 TBM_RETURN_VAL_IF_FAIL(key, 0);
1320 tbm_surface_debug_data *debug_data = NULL;
1321 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1322 tbm_bufmgr bufmgr = surface->bufmgr;
1324 TBM_RETURN_VAL_IF_FAIL(bufmgr, 0);
1326 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1327 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1328 if (!strcmp(old_data->key, key)) {
1330 old_data->value = strdup(value);
1332 old_data->value = NULL;
1337 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1339 TBM_TRACE("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1343 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1345 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1347 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1348 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1349 if (!strcmp(old_data->key, key))
1354 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1355 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1361 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1363 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
1365 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1367 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1368 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1369 if (!strcmp(old_data->key, key))
1370 return old_data->value;
1377 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1378 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1380 struct _tbm_surface_dump_buf_info {
1390 tbm_surface_info_s info;
1392 struct list_head link;
1395 struct _tbm_surface_dump_info {
1396 char *path; // copy???
1399 struct list_head *link;
1400 struct list_head surface_list; /* link of surface */
1403 static tbm_surface_dump_info *g_dump_info = NULL;
1404 static const char *dump_postfix[2] = {"png", "yuv"};
1407 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1408 int size2, void *data3, int size3)
1410 unsigned int *blocks;
1411 FILE *fp = fopen(file, "w+");
1412 TBM_RETURN_IF_FAIL(fp != NULL);
1414 blocks = (unsigned int *)data1;
1415 fwrite(blocks, 1, size1, fp);
1418 blocks = (unsigned int *)data2;
1419 fwrite(blocks, 1, size2, fp);
1423 blocks = (unsigned int *)data3;
1424 fwrite(blocks, 1, size3, fp);
1431 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1434 FILE *fp = fopen(file, "wb");
1435 TBM_RETURN_IF_FAIL(fp != NULL);
1438 png_structp pPngStruct =
1439 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1445 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1447 png_destroy_write_struct(&pPngStruct, NULL);
1452 png_init_io(pPngStruct, fp);
1453 png_set_IHDR(pPngStruct,
1458 PNG_COLOR_TYPE_RGBA,
1460 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1462 png_set_bgr(pPngStruct);
1463 png_write_info(pPngStruct, pPngInfo);
1465 const int pixel_size = 4; // RGBA
1466 png_bytep *row_pointers =
1467 png_malloc(pPngStruct, height * sizeof(png_byte *));
1469 unsigned int *blocks = (unsigned int *)data;
1473 for (; y < height; ++y) {
1475 png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1476 row_pointers[y] = (png_bytep)row;
1477 for (x = 0; x < width; ++x) {
1478 unsigned int curBlock = blocks[y * width + x];
1479 row[x * pixel_size] = (curBlock & 0xFF);
1480 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1481 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1482 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1486 png_write_image(pPngStruct, row_pointers);
1487 png_write_end(pPngStruct, pPngInfo);
1489 for (y = 0; y < height; y++)
1490 png_free(pPngStruct, row_pointers[y]);
1491 png_free(pPngStruct, row_pointers);
1493 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1499 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1501 TBM_RETURN_IF_FAIL(path != NULL);
1502 TBM_RETURN_IF_FAIL(w > 0);
1503 TBM_RETURN_IF_FAIL(h > 0);
1504 TBM_RETURN_IF_FAIL(count > 0);
1506 tbm_surface_dump_buf_info *buf_info = NULL;
1507 tbm_surface_dump_buf_info *tmp;
1511 tbm_surface_h tbm_surface;
1512 tbm_surface_info_s info;
1513 tbm_surface_error_e err;
1517 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1521 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1522 TBM_RETURN_IF_FAIL(g_dump_info);
1524 LIST_INITHEAD(&g_dump_info->surface_list);
1525 g_dump_info->count = 0;
1526 g_dump_info->dump_max = count;
1528 /* get buffer size */
1529 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1530 if (tbm_surface == NULL) {
1531 TBM_LOG_E("tbm_surface_create fail\n");
1536 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
1537 if (err != TBM_SURFACE_ERROR_NONE) {
1538 TBM_LOG_E("tbm_surface_map fail\n");
1539 tbm_surface_destroy(tbm_surface);
1544 buffer_size = info.planes[0].stride * h;
1545 tbm_surface_unmap(tbm_surface);
1546 tbm_surface_destroy(tbm_surface);
1548 /* create dump lists */
1549 for (i = 0; i < count; i++) {
1550 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1551 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1552 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1558 buf_info->index = i;
1560 buf_info->size = buffer_size;
1562 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1565 g_dump_info->path = path;
1566 g_dump_info->link = &g_dump_info->surface_list;
1568 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1572 /* free resources */
1573 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1574 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1575 tbm_bo_unref(buf_info->bo);
1580 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1589 tbm_surface_internal_dump_end(void)
1591 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1592 tbm_bo_handle bo_handle;
1598 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1599 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1602 if (buf_info->dirty) {
1606 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1607 if (bo_handle.ptr == NULL)
1610 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1611 TBM_LOG_I("Dump File.. %s generated.\n", file);
1613 switch (buf_info->info.format) {
1614 case TBM_FORMAT_ARGB8888:
1615 case TBM_FORMAT_XRGB8888:
1616 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1617 buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1619 case TBM_FORMAT_YVU420:
1620 case TBM_FORMAT_YUV420:
1621 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1622 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1623 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1624 buf_info->info.planes[0].stride * buf_info->info.height,
1626 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1628 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1630 case TBM_FORMAT_NV12:
1631 case TBM_FORMAT_NV21:
1632 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1633 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1634 buf_info->info.planes[0].stride * buf_info->info.height,
1636 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1639 case TBM_FORMAT_YUYV:
1640 case TBM_FORMAT_UYVY:
1641 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1642 buf_info->info.planes[0].stride * buf_info->info.height,
1646 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1647 tbm_bo_unmap(buf_info->bo);
1651 tbm_bo_unmap(buf_info->bo);
1652 } else if (buf_info->dirty_shm) {
1653 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1654 if (bo_handle.ptr == NULL)
1657 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1658 TBM_LOG_I("Dump File.. %s generated.\n", file);
1660 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1661 buf_info->shm_stride >> 2, buf_info->shm_h);
1663 tbm_bo_unmap(buf_info->bo);
1668 /* free resources */
1669 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1670 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1671 tbm_bo_unref(buf_info->bo);
1679 TBM_LOG_I("Dump End..\n");
1683 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1685 TBM_RETURN_IF_FAIL(surface != NULL);
1686 TBM_RETURN_IF_FAIL(type != NULL);
1688 tbm_surface_dump_buf_info *buf_info;
1689 tbm_surface_info_s info;
1690 struct list_head *next_link;
1691 tbm_bo_handle bo_handle;
1693 const char *postfix;
1698 next_link = g_dump_info->link->next;
1699 TBM_RETURN_IF_FAIL(next_link != NULL);
1701 if (next_link == &g_dump_info->surface_list) {
1702 next_link = next_link->next;
1703 TBM_RETURN_IF_FAIL(next_link != NULL);
1706 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1707 TBM_RETURN_IF_FAIL(buf_info != NULL);
1709 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1710 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1712 if (info.size > buf_info->size) {
1713 TBM_LOG_W("Dump skip. surface over created buffer size(%d, %d)\n", info.size, buf_info->size);
1714 tbm_surface_unmap(surface);
1718 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1719 postfix = dump_postfix[0];
1721 postfix = dump_postfix[1];
1723 /* make the file information */
1724 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1727 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1728 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1729 memset(bo_handle.ptr, 0x00, buf_info->size);
1731 switch (info.format) {
1732 case TBM_FORMAT_ARGB8888:
1733 case TBM_FORMAT_XRGB8888:
1734 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d_%p-%s.%s",
1735 _tbm_surface_internal_get_time(),
1736 g_dump_info->count++, surface, type, postfix);
1737 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1739 case TBM_FORMAT_YVU420:
1740 case TBM_FORMAT_YUV420:
1741 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1742 _tbm_surface_internal_get_time(),
1743 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1744 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1745 bo_handle.ptr += info.planes[0].stride * info.height;
1746 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1747 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1748 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1750 case TBM_FORMAT_NV12:
1751 case TBM_FORMAT_NV21:
1752 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1753 _tbm_surface_internal_get_time(),
1754 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1755 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1756 bo_handle.ptr += info.planes[0].stride * info.height;
1757 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1759 case TBM_FORMAT_YUYV:
1760 case TBM_FORMAT_UYVY:
1761 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1762 _tbm_surface_internal_get_time(),
1763 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1764 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1767 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1768 tbm_bo_unmap(buf_info->bo);
1772 tbm_bo_unmap(buf_info->bo);
1774 tbm_surface_unmap(surface);
1776 buf_info->dirty = 1;
1777 buf_info->dirty_shm = 0;
1779 if (g_dump_info->count == 1000)
1780 g_dump_info->count = 0;
1782 g_dump_info->link = next_link;
1784 TBM_LOG_I("Dump %s \n", buf_info->name);
1787 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, const char *type)
1789 TBM_RETURN_IF_FAIL(ptr != NULL);
1790 TBM_RETURN_IF_FAIL(w > 0);
1791 TBM_RETURN_IF_FAIL(h > 0);
1792 TBM_RETURN_IF_FAIL(stride > 0);
1793 TBM_RETURN_IF_FAIL(type != NULL);
1795 tbm_surface_dump_buf_info *buf_info;
1796 struct list_head *next_link;
1797 tbm_bo_handle bo_handle;
1802 next_link = g_dump_info->link->next;
1803 TBM_RETURN_IF_FAIL(next_link != NULL);
1805 if (next_link == &g_dump_info->surface_list) {
1806 next_link = next_link->next;
1807 TBM_RETURN_IF_FAIL(next_link != NULL);
1810 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1811 TBM_RETURN_IF_FAIL(buf_info != NULL);
1813 if (stride * h > buf_info->size) {
1814 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", stride * h, buf_info->size);
1819 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1820 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1821 memset(bo_handle.ptr, 0x00, buf_info->size);
1822 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1824 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1825 _tbm_surface_internal_get_time(),
1826 g_dump_info->count++, type, dump_postfix[0]);
1827 memcpy(bo_handle.ptr, ptr, stride * h);
1829 tbm_bo_unmap(buf_info->bo);
1831 buf_info->dirty = 0;
1832 buf_info->dirty_shm = 1;
1833 buf_info->shm_stride = stride;
1834 buf_info->shm_h = h;
1836 if (g_dump_info->count == 1000)
1837 g_dump_info->count = 0;
1839 g_dump_info->link = next_link;
1841 TBM_LOG_I("Dump %s \n", buf_info->name);
1844 void tbm_surface_internal_dump_all(char *path)
1846 TBM_RETURN_IF_FAIL(path != NULL);
1847 int w = 0, h = 0, count = 0;
1848 tbm_surface_h surface = NULL, tmp = NULL;
1850 count = _tbm_surface_get_max_size(&w, &h);
1852 TBM_LOG_I("No tbm_surface.\n");
1856 tbm_surface_internal_dump_start(path, w, h, count);
1858 LIST_FOR_EACH_ENTRY_SAFE(surface, tmp, &g_surface_bufmgr->surf_list, item_link) {
1859 tbm_surface_internal_dump_buffer(surface, "dump_all");
1862 tbm_surface_internal_dump_end();