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)) {
1355 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1356 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1362 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1364 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
1366 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1368 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1369 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1370 if (!strcmp(old_data->key, key)) {
1371 return old_data->value;
1379 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1380 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1382 struct _tbm_surface_dump_buf_info {
1392 tbm_surface_info_s info;
1394 struct list_head link;
1397 struct _tbm_surface_dump_info {
1398 char *path; // copy???
1401 struct list_head *link;
1402 struct list_head surface_list; /* link of surface */
1405 static tbm_surface_dump_info *g_dump_info = NULL;
1406 static const char *dump_postfix[2] = {"png", "yuv"};
1409 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1410 int size2, void *data3, int size3)
1412 unsigned int *blocks;
1413 FILE *fp = fopen(file, "w+");
1414 TBM_RETURN_IF_FAIL(fp != NULL);
1416 blocks = (unsigned int *)data1;
1417 fwrite(blocks, 1, size1, fp);
1420 blocks = (unsigned int *)data2;
1421 fwrite(blocks, 1, size2, fp);
1425 blocks = (unsigned int *)data3;
1426 fwrite(blocks, 1, size3, fp);
1433 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1436 FILE *fp = fopen(file, "wb");
1437 TBM_RETURN_IF_FAIL(fp != NULL);
1440 png_structp pPngStruct =
1441 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1447 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1449 png_destroy_write_struct(&pPngStruct, NULL);
1454 png_init_io(pPngStruct, fp);
1455 png_set_IHDR(pPngStruct,
1460 PNG_COLOR_TYPE_RGBA,
1462 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1464 png_set_bgr(pPngStruct);
1465 png_write_info(pPngStruct, pPngInfo);
1467 const int pixel_size = 4; // RGBA
1468 png_bytep *row_pointers =
1469 png_malloc(pPngStruct, height * sizeof(png_byte *));
1471 unsigned int *blocks = (unsigned int *)data;
1475 for (; y < height; ++y) {
1477 png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1478 row_pointers[y] = (png_bytep)row;
1479 for (x = 0; x < width; ++x) {
1480 unsigned int curBlock = blocks[y * width + x];
1481 row[x * pixel_size] = (curBlock & 0xFF);
1482 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1483 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1484 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1488 png_write_image(pPngStruct, row_pointers);
1489 png_write_end(pPngStruct, pPngInfo);
1491 for (y = 0; y < height; y++)
1492 png_free(pPngStruct, row_pointers[y]);
1493 png_free(pPngStruct, row_pointers);
1495 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1501 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1503 TBM_RETURN_IF_FAIL(path != NULL);
1504 TBM_RETURN_IF_FAIL(w > 0);
1505 TBM_RETURN_IF_FAIL(h > 0);
1506 TBM_RETURN_IF_FAIL(count > 0);
1508 tbm_surface_dump_buf_info *buf_info = NULL;
1509 tbm_surface_dump_buf_info *tmp;
1513 tbm_surface_h tbm_surface;
1514 tbm_surface_info_s info;
1515 tbm_surface_error_e err;
1519 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1523 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1524 TBM_RETURN_IF_FAIL(g_dump_info);
1526 LIST_INITHEAD(&g_dump_info->surface_list);
1527 g_dump_info->count = 0;
1528 g_dump_info->dump_max = count;
1530 /* get buffer size */
1531 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1532 if (tbm_surface == NULL) {
1533 TBM_LOG_E("tbm_surface_create fail\n");
1538 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
1539 if (err != TBM_SURFACE_ERROR_NONE) {
1540 TBM_LOG_E("tbm_surface_map fail\n");
1541 tbm_surface_destroy(tbm_surface);
1546 buffer_size = info.planes[0].stride * h;
1547 tbm_surface_unmap(tbm_surface);
1548 tbm_surface_destroy(tbm_surface);
1550 /* create dump lists */
1551 for (i = 0; i < count; i++) {
1552 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1553 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1554 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1560 buf_info->index = i;
1562 buf_info->size = buffer_size;
1564 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1567 g_dump_info->path = path;
1568 g_dump_info->link = &g_dump_info->surface_list;
1570 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1574 /* free resources */
1575 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1576 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1577 tbm_bo_unref(buf_info->bo);
1582 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1591 tbm_surface_internal_dump_end(void)
1593 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1594 tbm_bo_handle bo_handle;
1600 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1601 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1604 if (buf_info->dirty) {
1608 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1609 if (bo_handle.ptr == NULL)
1612 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1613 TBM_LOG_I("Dump File.. %s generated.\n", file);
1615 switch (buf_info->info.format) {
1616 case TBM_FORMAT_ARGB8888:
1617 case TBM_FORMAT_XRGB8888:
1618 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1619 buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1621 case TBM_FORMAT_YVU420:
1622 case TBM_FORMAT_YUV420:
1623 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1624 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1625 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1626 buf_info->info.planes[0].stride * buf_info->info.height,
1628 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1630 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1632 case TBM_FORMAT_NV12:
1633 case TBM_FORMAT_NV21:
1634 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1635 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1636 buf_info->info.planes[0].stride * buf_info->info.height,
1638 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1641 case TBM_FORMAT_YUYV:
1642 case TBM_FORMAT_UYVY:
1643 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1644 buf_info->info.planes[0].stride * buf_info->info.height,
1648 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1649 tbm_bo_unmap(buf_info->bo);
1653 tbm_bo_unmap(buf_info->bo);
1654 } else if (buf_info->dirty_shm) {
1655 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1656 if (bo_handle.ptr == NULL)
1659 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1660 TBM_LOG_I("Dump File.. %s generated.\n", file);
1662 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1663 buf_info->shm_stride >> 2, buf_info->shm_h);
1665 tbm_bo_unmap(buf_info->bo);
1670 /* free resources */
1671 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1672 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1673 tbm_bo_unref(buf_info->bo);
1681 TBM_LOG_I("Dump End..\n");
1685 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1687 TBM_RETURN_IF_FAIL(surface != NULL);
1688 TBM_RETURN_IF_FAIL(type != NULL);
1690 tbm_surface_dump_buf_info *buf_info;
1691 tbm_surface_info_s info;
1692 struct list_head *next_link;
1693 tbm_bo_handle bo_handle;
1695 const char *postfix;
1700 next_link = g_dump_info->link->next;
1701 TBM_RETURN_IF_FAIL(next_link != NULL);
1703 if (next_link == &g_dump_info->surface_list) {
1704 next_link = next_link->next;
1705 TBM_RETURN_IF_FAIL(next_link != NULL);
1708 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1709 TBM_RETURN_IF_FAIL(buf_info != NULL);
1711 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1712 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1714 if (info.size > buf_info->size) {
1715 TBM_LOG_W("Dump skip. surface over created buffer size(%d, %d)\n", info.size, buf_info->size);
1716 tbm_surface_unmap(surface);
1720 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1721 postfix = dump_postfix[0];
1723 postfix = dump_postfix[1];
1725 /* make the file information */
1726 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1729 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1730 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1731 memset(bo_handle.ptr, 0x00, buf_info->size);
1733 switch (info.format) {
1734 case TBM_FORMAT_ARGB8888:
1735 case TBM_FORMAT_XRGB8888:
1736 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d_%p-%s.%s",
1737 _tbm_surface_internal_get_time(),
1738 g_dump_info->count++, surface, type, postfix);
1739 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1741 case TBM_FORMAT_YVU420:
1742 case TBM_FORMAT_YUV420:
1743 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1744 _tbm_surface_internal_get_time(),
1745 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1746 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1747 bo_handle.ptr += info.planes[0].stride * info.height;
1748 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1749 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1750 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1752 case TBM_FORMAT_NV12:
1753 case TBM_FORMAT_NV21:
1754 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1755 _tbm_surface_internal_get_time(),
1756 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1757 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1758 bo_handle.ptr += info.planes[0].stride * info.height;
1759 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1761 case TBM_FORMAT_YUYV:
1762 case TBM_FORMAT_UYVY:
1763 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1764 _tbm_surface_internal_get_time(),
1765 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1766 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1769 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1770 tbm_bo_unmap(buf_info->bo);
1774 tbm_bo_unmap(buf_info->bo);
1776 tbm_surface_unmap(surface);
1778 buf_info->dirty = 1;
1779 buf_info->dirty_shm = 0;
1781 if (g_dump_info->count == 1000)
1782 g_dump_info->count = 0;
1784 g_dump_info->link = next_link;
1786 TBM_LOG_I("Dump %s \n", buf_info->name);
1789 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, const char *type)
1791 TBM_RETURN_IF_FAIL(ptr != NULL);
1792 TBM_RETURN_IF_FAIL(w > 0);
1793 TBM_RETURN_IF_FAIL(h > 0);
1794 TBM_RETURN_IF_FAIL(stride > 0);
1795 TBM_RETURN_IF_FAIL(type != NULL);
1797 tbm_surface_dump_buf_info *buf_info;
1798 struct list_head *next_link;
1799 tbm_bo_handle bo_handle;
1804 next_link = g_dump_info->link->next;
1805 TBM_RETURN_IF_FAIL(next_link != NULL);
1807 if (next_link == &g_dump_info->surface_list) {
1808 next_link = next_link->next;
1809 TBM_RETURN_IF_FAIL(next_link != NULL);
1812 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1813 TBM_RETURN_IF_FAIL(buf_info != NULL);
1815 if (stride * h > buf_info->size) {
1816 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", stride * h, buf_info->size);
1821 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1822 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1823 memset(bo_handle.ptr, 0x00, buf_info->size);
1824 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1826 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1827 _tbm_surface_internal_get_time(),
1828 g_dump_info->count++, type, dump_postfix[0]);
1829 memcpy(bo_handle.ptr, ptr, stride * h);
1831 tbm_bo_unmap(buf_info->bo);
1833 buf_info->dirty = 0;
1834 buf_info->dirty_shm = 1;
1835 buf_info->shm_stride = stride;
1836 buf_info->shm_h = h;
1838 if (g_dump_info->count == 1000)
1839 g_dump_info->count = 0;
1841 g_dump_info->link = next_link;
1843 TBM_LOG_I("Dump %s \n", buf_info->name);
1846 void tbm_surface_internal_dump_all(char *path)
1848 TBM_RETURN_IF_FAIL(path != NULL);
1849 int w = 0, h = 0, count = 0;
1850 tbm_surface_h surface = NULL, tmp = NULL;
1852 count = _tbm_surface_get_max_size(&w, &h);
1854 TBM_LOG_I("No tbm_surface.\n");
1858 tbm_surface_internal_dump_start(path, w, h, count);
1860 LIST_FOR_EACH_ENTRY_SAFE(surface, tmp, &g_surface_bufmgr->surf_list, item_link) {
1861 tbm_surface_internal_dump_buffer(surface, "dump_all");
1864 tbm_surface_internal_dump_end();