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_internal_is_valid(tbm_surface_h surface)
333 tbm_surface_h old_data = NULL, tmp = NULL;
335 if (surface == NULL || g_surface_bufmgr == NULL) {
336 TBM_TRACE("error: tbm_surface(%p)\n", surface);
340 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
341 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &g_surface_bufmgr->surf_list, item_link) {
342 if (old_data == surface) {
343 TBM_TRACE("tbm_surface(%p)\n", surface);
348 TBM_TRACE("error: tbm_surface(%p)\n", surface);
353 tbm_surface_internal_query_supported_formats(uint32_t **formats,
356 struct _tbm_bufmgr *mgr;
359 _tbm_surface_mutex_lock();
361 if (!g_surface_bufmgr) {
362 _init_surface_bufmgr();
363 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
366 mgr = g_surface_bufmgr;
368 if (!mgr->backend->surface_supported_format) {
369 TBM_TRACE("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
370 _tbm_surface_mutex_unlock();
374 ret = mgr->backend->surface_supported_format(formats, num);
376 TBM_TRACE("tbm_bufmgr(%p) format num(%d)\n", g_surface_bufmgr, *num);
378 _tbm_surface_mutex_unlock();
384 tbm_surface_internal_get_num_planes(tbm_format format)
390 case TBM_FORMAT_RGB332:
391 case TBM_FORMAT_BGR233:
392 case TBM_FORMAT_XRGB4444:
393 case TBM_FORMAT_XBGR4444:
394 case TBM_FORMAT_RGBX4444:
395 case TBM_FORMAT_BGRX4444:
396 case TBM_FORMAT_ARGB4444:
397 case TBM_FORMAT_ABGR4444:
398 case TBM_FORMAT_RGBA4444:
399 case TBM_FORMAT_BGRA4444:
400 case TBM_FORMAT_XRGB1555:
401 case TBM_FORMAT_XBGR1555:
402 case TBM_FORMAT_RGBX5551:
403 case TBM_FORMAT_BGRX5551:
404 case TBM_FORMAT_ARGB1555:
405 case TBM_FORMAT_ABGR1555:
406 case TBM_FORMAT_RGBA5551:
407 case TBM_FORMAT_BGRA5551:
408 case TBM_FORMAT_RGB565:
409 case TBM_FORMAT_BGR565:
410 case TBM_FORMAT_RGB888:
411 case TBM_FORMAT_BGR888:
412 case TBM_FORMAT_XRGB8888:
413 case TBM_FORMAT_XBGR8888:
414 case TBM_FORMAT_RGBX8888:
415 case TBM_FORMAT_BGRX8888:
416 case TBM_FORMAT_ARGB8888:
417 case TBM_FORMAT_ABGR8888:
418 case TBM_FORMAT_RGBA8888:
419 case TBM_FORMAT_BGRA8888:
420 case TBM_FORMAT_XRGB2101010:
421 case TBM_FORMAT_XBGR2101010:
422 case TBM_FORMAT_RGBX1010102:
423 case TBM_FORMAT_BGRX1010102:
424 case TBM_FORMAT_ARGB2101010:
425 case TBM_FORMAT_ABGR2101010:
426 case TBM_FORMAT_RGBA1010102:
427 case TBM_FORMAT_BGRA1010102:
428 case TBM_FORMAT_YUYV:
429 case TBM_FORMAT_YVYU:
430 case TBM_FORMAT_UYVY:
431 case TBM_FORMAT_VYUY:
432 case TBM_FORMAT_AYUV:
435 case TBM_FORMAT_NV12:
436 case TBM_FORMAT_NV12MT:
437 case TBM_FORMAT_NV21:
438 case TBM_FORMAT_NV16:
439 case TBM_FORMAT_NV61:
442 case TBM_FORMAT_YUV410:
443 case TBM_FORMAT_YVU410:
444 case TBM_FORMAT_YUV411:
445 case TBM_FORMAT_YVU411:
446 case TBM_FORMAT_YUV420:
447 case TBM_FORMAT_YVU420:
448 case TBM_FORMAT_YUV422:
449 case TBM_FORMAT_YVU422:
450 case TBM_FORMAT_YUV444:
451 case TBM_FORMAT_YVU444:
459 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
465 tbm_surface_internal_get_bpp(tbm_format format)
472 case TBM_FORMAT_RGB332:
473 case TBM_FORMAT_BGR233:
476 case TBM_FORMAT_XRGB4444:
477 case TBM_FORMAT_XBGR4444:
478 case TBM_FORMAT_RGBX4444:
479 case TBM_FORMAT_BGRX4444:
480 case TBM_FORMAT_ARGB4444:
481 case TBM_FORMAT_ABGR4444:
482 case TBM_FORMAT_RGBA4444:
483 case TBM_FORMAT_BGRA4444:
484 case TBM_FORMAT_XRGB1555:
485 case TBM_FORMAT_XBGR1555:
486 case TBM_FORMAT_RGBX5551:
487 case TBM_FORMAT_BGRX5551:
488 case TBM_FORMAT_ARGB1555:
489 case TBM_FORMAT_ABGR1555:
490 case TBM_FORMAT_RGBA5551:
491 case TBM_FORMAT_BGRA5551:
492 case TBM_FORMAT_RGB565:
493 case TBM_FORMAT_BGR565:
496 case TBM_FORMAT_RGB888:
497 case TBM_FORMAT_BGR888:
500 case TBM_FORMAT_XRGB8888:
501 case TBM_FORMAT_XBGR8888:
502 case TBM_FORMAT_RGBX8888:
503 case TBM_FORMAT_BGRX8888:
504 case TBM_FORMAT_ARGB8888:
505 case TBM_FORMAT_ABGR8888:
506 case TBM_FORMAT_RGBA8888:
507 case TBM_FORMAT_BGRA8888:
508 case TBM_FORMAT_XRGB2101010:
509 case TBM_FORMAT_XBGR2101010:
510 case TBM_FORMAT_RGBX1010102:
511 case TBM_FORMAT_BGRX1010102:
512 case TBM_FORMAT_ARGB2101010:
513 case TBM_FORMAT_ABGR2101010:
514 case TBM_FORMAT_RGBA1010102:
515 case TBM_FORMAT_BGRA1010102:
516 case TBM_FORMAT_YUYV:
517 case TBM_FORMAT_YVYU:
518 case TBM_FORMAT_UYVY:
519 case TBM_FORMAT_VYUY:
520 case TBM_FORMAT_AYUV:
523 case TBM_FORMAT_NV12:
524 case TBM_FORMAT_NV12MT:
525 case TBM_FORMAT_NV21:
528 case TBM_FORMAT_NV16:
529 case TBM_FORMAT_NV61:
532 case TBM_FORMAT_YUV410:
533 case TBM_FORMAT_YVU410:
536 case TBM_FORMAT_YUV411:
537 case TBM_FORMAT_YVU411:
538 case TBM_FORMAT_YUV420:
539 case TBM_FORMAT_YVU420:
542 case TBM_FORMAT_YUV422:
543 case TBM_FORMAT_YVU422:
546 case TBM_FORMAT_YUV444:
547 case TBM_FORMAT_YVU444:
554 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
560 tbm_surface_internal_create_with_flags(int width, int height,
561 int format, int flags)
563 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
564 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
566 struct _tbm_bufmgr *mgr;
567 struct _tbm_surface *surf = NULL;
571 uint32_t bo_size = 0;
575 _tbm_surface_mutex_lock();
577 if (!g_surface_bufmgr) {
578 _init_surface_bufmgr();
579 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
582 mgr = g_surface_bufmgr;
583 if (!TBM_BUFMGR_IS_VALID(mgr)) {
584 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
585 width, height, _tbm_surface_internal_format_to_str(format), flags);
586 _tbm_surface_mutex_unlock();
589 surf = calloc(1, sizeof(struct _tbm_surface));
591 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
592 width, height, _tbm_surface_internal_format_to_str(format), flags);
593 _tbm_surface_mutex_unlock();
598 surf->info.width = width;
599 surf->info.height = height;
600 surf->info.format = format;
601 surf->info.bpp = tbm_surface_internal_get_bpp(format);
602 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
605 /* get size, stride and offset bo_idx */
606 for (i = 0; i < surf->info.num_planes; i++) {
607 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride,
609 surf->info.planes[i].size = size;
610 surf->info.planes[i].offset = offset;
611 surf->info.planes[i].stride = stride;
612 surf->planes_bo_idx[i] = bo_idx;
617 for (i = 0; i < surf->info.num_planes; i++) {
618 surf->info.size += surf->info.planes[i].size;
620 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
621 surf->num_bos = surf->planes_bo_idx[i] + 1;
626 for (i = 0; i < surf->num_bos; i++) {
628 for (j = 0; j < surf->info.num_planes; j++) {
629 if (surf->planes_bo_idx[j] == i)
630 bo_size += surf->info.planes[j].size;
633 if (mgr->backend->surface_bo_alloc) {
634 /* LCOV_EXCL_START */
636 void *bo_priv = NULL;
638 bo = calloc(1, sizeof(struct _tbm_bo));
640 TBM_LOG_E("fail to alloc bo struct\n");
644 bo->bufmgr = surf->bufmgr;
646 pthread_mutex_lock(&surf->bufmgr->lock);
648 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
650 TBM_LOG_E("fail to alloc bo priv\n");
652 pthread_mutex_unlock(&surf->bufmgr->lock);
660 LIST_INITHEAD(&bo->user_data_list);
662 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
664 pthread_mutex_unlock(&surf->bufmgr->lock);
669 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
673 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
677 _tbm_bo_set_surface(surf->bos[i], surf);
681 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
682 _tbm_surface_internal_format_to_str(format), flags, surf);
684 LIST_INITHEAD(&surf->user_data_list);
685 LIST_INITHEAD(&surf->debug_data_list);
687 LIST_ADD(&surf->item_link, &mgr->surf_list);
689 _tbm_surface_mutex_unlock();
695 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
696 width, height, _tbm_surface_internal_format_to_str(format), flags);
698 for (j = 0; j < i; j++) {
700 tbm_bo_unref(surf->bos[j]);
706 if (LIST_IS_EMPTY(&mgr->surf_list)) {
707 LIST_DELINIT(&mgr->surf_list);
708 _deinit_surface_bufmgr();
711 _tbm_surface_mutex_unlock();
716 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
717 tbm_bo *bos, int num)
719 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
720 TBM_RETURN_VAL_IF_FAIL(info, NULL);
721 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
723 struct _tbm_bufmgr *mgr;
724 struct _tbm_surface *surf = NULL;
727 _tbm_surface_mutex_lock();
729 if (!g_surface_bufmgr) {
730 _init_surface_bufmgr();
731 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
734 mgr = g_surface_bufmgr;
735 if (!TBM_BUFMGR_IS_VALID(mgr)) {
736 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
737 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
738 _tbm_surface_mutex_unlock();
742 surf = calloc(1, sizeof(struct _tbm_surface));
744 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
745 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
746 _tbm_surface_mutex_unlock();
751 surf->info.width = info->width;
752 surf->info.height = info->height;
753 surf->info.format = info->format;
754 surf->info.bpp = info->bpp;
755 surf->info.num_planes = info->num_planes;
758 /* get size, stride and offset */
759 for (i = 0; i < info->num_planes; i++) {
760 surf->info.planes[i].offset = info->planes[i].offset;
761 surf->info.planes[i].stride = info->planes[i].stride;
763 if (info->planes[i].size > 0)
764 surf->info.planes[i].size = info->planes[i].size;
766 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
769 surf->planes_bo_idx[i] = 0;
771 surf->planes_bo_idx[i] = i;
774 if (info->size > 0) {
775 surf->info.size = info->size;
778 for (i = 0; i < info->num_planes; i++)
779 surf->info.size += surf->info.planes[i].size;
782 surf->flags = TBM_BO_DEFAULT;
784 /* create only one bo */
786 for (i = 0; i < num; i++) {
790 surf->bos[i] = tbm_bo_ref(bos[i]);
791 _tbm_bo_set_surface(bos[i], surf);
794 TBM_TRACE("tbm_surface(%p) width(%d) height(%d) format(%s) bo_num(%d)\n", surf,
795 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
797 LIST_INITHEAD(&surf->user_data_list);
798 LIST_INITHEAD(&surf->debug_data_list);
800 LIST_ADD(&surf->item_link, &mgr->surf_list);
802 _tbm_surface_mutex_unlock();
806 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
807 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
808 for (i = 0; i < num; i++) {
810 tbm_bo_unref(surf->bos[i]);
818 if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
819 LIST_DELINIT(&g_surface_bufmgr->surf_list);
820 _deinit_surface_bufmgr();
823 _tbm_surface_mutex_unlock();
829 tbm_surface_internal_destroy(tbm_surface_h surface)
831 if (!tbm_surface_internal_is_valid(surface))
834 _tbm_surface_mutex_lock();
838 if (surface->refcnt > 0) {
839 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
840 _tbm_surface_mutex_unlock();
844 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
846 if (surface->refcnt == 0)
847 _tbm_surface_internal_destroy(surface);
849 _tbm_surface_mutex_unlock();
853 tbm_surface_internal_ref(tbm_surface_h surface)
855 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
857 _tbm_surface_mutex_lock();
861 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
863 _tbm_surface_mutex_unlock();
867 tbm_surface_internal_unref(tbm_surface_h surface)
869 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
871 _tbm_surface_mutex_lock();
875 if (surface->refcnt > 0) {
876 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
877 _tbm_surface_mutex_unlock();
881 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
883 if (surface->refcnt == 0)
884 _tbm_surface_internal_destroy(surface);
886 _tbm_surface_mutex_unlock();
890 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
892 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
894 struct _tbm_surface *surf;
897 _tbm_surface_mutex_lock();
899 surf = (struct _tbm_surface *)surface;
902 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
904 _tbm_surface_mutex_unlock();
910 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
912 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
913 TBM_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
915 struct _tbm_surface *surf;
918 _tbm_surface_mutex_lock();
920 surf = (struct _tbm_surface *)surface;
921 bo = surf->bos[bo_idx];
923 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
925 _tbm_surface_mutex_unlock();
931 tbm_surface_internal_get_size(tbm_surface_h surface)
933 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
935 struct _tbm_surface *surf;
938 _tbm_surface_mutex_lock();
940 surf = (struct _tbm_surface *)surface;
941 size = surf->info.size;
943 TBM_TRACE("tbm_surface(%p) size(%d)\n", surface, size);
945 _tbm_surface_mutex_unlock();
951 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
952 uint32_t *size, uint32_t *offset, uint32_t *pitch)
954 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
955 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
957 struct _tbm_surface *surf;
959 _tbm_surface_mutex_lock();
961 surf = (struct _tbm_surface *)surface;
963 if (plane_idx >= surf->info.num_planes) {
964 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
965 _tbm_surface_mutex_unlock();
970 *size = surf->info.planes[plane_idx].size;
973 *offset = surf->info.planes[plane_idx].offset;
976 *pitch = surf->info.planes[plane_idx].stride;
978 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%d) offset(%d) pitch(%d)\n", surface, plane_idx,
979 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
980 surf->info.planes[plane_idx].stride);
982 _tbm_surface_mutex_unlock();
988 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
989 tbm_surface_info_s *info, int map)
991 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
993 struct _tbm_surface *surf;
994 tbm_bo_handle bo_handles[4];
997 _tbm_surface_mutex_lock();
999 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1001 surf = (struct _tbm_surface *)surface;
1003 memset(info, 0x00, sizeof(tbm_surface_info_s));
1004 info->width = surf->info.width;
1005 info->height = surf->info.height;
1006 info->format = surf->info.format;
1007 info->bpp = surf->info.bpp;
1008 info->size = surf->info.size;
1009 info->num_planes = surf->info.num_planes;
1012 for (i = 0; i < surf->num_bos; i++) {
1013 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1014 if (bo_handles[i].ptr == NULL) {
1015 for (j = 0; j < i; j++)
1016 tbm_bo_unmap(surf->bos[j]);
1018 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1019 _tbm_surface_mutex_unlock();
1024 for (i = 0; i < surf->num_bos; i++)
1025 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1028 for (i = 0; i < surf->info.num_planes; i++) {
1029 info->planes[i].size = surf->info.planes[i].size;
1030 info->planes[i].offset = surf->info.planes[i].offset;
1031 info->planes[i].stride = surf->info.planes[i].stride;
1033 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1034 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1035 surf->info.planes[i].offset;
1038 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1040 _tbm_surface_mutex_unlock();
1046 tbm_surface_internal_unmap(tbm_surface_h surface)
1048 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1050 struct _tbm_surface *surf;
1053 _tbm_surface_mutex_lock();
1055 surf = (struct _tbm_surface *)surface;
1057 for (i = 0; i < surf->num_bos; i++)
1058 tbm_bo_unmap(surf->bos[i]);
1060 TBM_TRACE("tbm_surface(%p)\n", surface);
1062 _tbm_surface_mutex_unlock();
1066 tbm_surface_internal_get_width(tbm_surface_h surface)
1068 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1070 struct _tbm_surface *surf;
1073 _tbm_surface_mutex_lock();
1075 surf = (struct _tbm_surface *)surface;
1076 width = surf->info.width;
1078 TBM_TRACE("tbm_surface(%p) width(%d)\n", surface, width);
1080 _tbm_surface_mutex_unlock();
1086 tbm_surface_internal_get_height(tbm_surface_h surface)
1088 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1090 struct _tbm_surface *surf;
1091 unsigned int height;
1093 _tbm_surface_mutex_lock();
1095 surf = (struct _tbm_surface *)surface;
1096 height = surf->info.height;
1098 TBM_TRACE("tbm_surface(%p) height(%d)\n", surface, height);
1100 _tbm_surface_mutex_unlock();
1107 tbm_surface_internal_get_format(tbm_surface_h surface)
1109 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1111 struct _tbm_surface *surf;
1114 _tbm_surface_mutex_lock();
1116 surf = (struct _tbm_surface *)surface;
1117 format = surf->info.format;
1119 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1121 _tbm_surface_mutex_unlock();
1127 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1129 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1130 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1131 struct _tbm_surface *surf;
1134 _tbm_surface_mutex_lock();
1136 surf = (struct _tbm_surface *)surface;
1137 bo_idx = surf->planes_bo_idx[plane_idx];
1139 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1141 _tbm_surface_mutex_unlock();
1147 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1148 tbm_data_free data_free_func)
1150 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1152 tbm_user_data *data;
1154 /* check if the data according to the key exist if so, return false. */
1155 data = user_data_lookup(&surface->user_data_list, key);
1157 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1161 data = user_data_create(key, data_free_func);
1163 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1167 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1169 LIST_ADD(&data->item_link, &surface->user_data_list);
1175 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1178 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1180 tbm_user_data *old_data;
1182 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1183 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1187 old_data = user_data_lookup(&surface->user_data_list, key);
1189 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1193 if (old_data->data && old_data->free_func)
1194 old_data->free_func(old_data->data);
1196 old_data->data = data;
1198 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1204 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1207 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1209 tbm_user_data *old_data;
1211 if (!data || LIST_IS_EMPTY(&surface->user_data_list)) {
1212 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1216 old_data = user_data_lookup(&surface->user_data_list, key);
1218 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1223 *data = old_data->data;
1225 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1231 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1234 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1236 tbm_user_data *old_data = (void *)0;
1238 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1239 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1243 old_data = user_data_lookup(&surface->user_data_list, key);
1245 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1249 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1251 user_data_delete(old_data);
1256 /* LCOV_EXCL_START */
1258 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1260 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1262 return surface->debug_pid;
1266 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1268 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1270 surface->debug_pid = pid;
1273 static tbm_surface_debug_data *
1274 _tbm_surface_internal_debug_data_create(char *key, char *value)
1276 tbm_surface_debug_data *debug_data = NULL;
1278 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1282 if (key) debug_data->key = strdup(key);
1283 if (value) debug_data->value = strdup(value);
1289 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1291 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1292 TBM_RETURN_VAL_IF_FAIL(key, 0);
1294 tbm_surface_debug_data *debug_data = NULL;
1295 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1296 tbm_bufmgr bufmgr = surface->bufmgr;
1298 TBM_RETURN_VAL_IF_FAIL(bufmgr, 0);
1300 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1301 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1302 if (!strcmp(old_data->key, key)) {
1304 old_data->value = strdup(value);
1306 old_data->value = NULL;
1311 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1313 TBM_TRACE("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1317 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1319 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1321 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1322 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1323 if (!strcmp(old_data->key, key))
1328 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1329 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1335 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1337 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
1339 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1341 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1342 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1343 if (!strcmp(old_data->key, key))
1344 return old_data->value;
1351 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1352 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1354 struct _tbm_surface_dump_buf_info {
1364 tbm_surface_info_s info;
1366 struct list_head link;
1369 struct _tbm_surface_dump_info {
1370 char *path; // copy???
1373 struct list_head *link;
1374 struct list_head surface_list; /* link of surface */
1377 static tbm_surface_dump_info *g_dump_info = NULL;
1378 static const char *dump_postfix[2] = {"png", "yuv"};
1381 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1382 int size2, void *data3, int size3)
1384 unsigned int *blocks;
1385 FILE *fp = fopen(file, "w+");
1386 TBM_RETURN_IF_FAIL(fp != NULL);
1388 blocks = (unsigned int *)data1;
1389 fwrite(blocks, 1, size1, fp);
1392 blocks = (unsigned int *)data2;
1393 fwrite(blocks, 1, size2, fp);
1397 blocks = (unsigned int *)data3;
1398 fwrite(blocks, 1, size3, fp);
1405 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1408 FILE *fp = fopen(file, "wb");
1409 TBM_RETURN_IF_FAIL(fp != NULL);
1412 png_structp pPngStruct =
1413 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1419 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1421 png_destroy_write_struct(&pPngStruct, NULL);
1426 png_init_io(pPngStruct, fp);
1427 png_set_IHDR(pPngStruct,
1432 PNG_COLOR_TYPE_RGBA,
1434 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1436 png_set_bgr(pPngStruct);
1437 png_write_info(pPngStruct, pPngInfo);
1439 const int pixel_size = 4; // RGBA
1440 png_bytep *row_pointers =
1441 png_malloc(pPngStruct, height * sizeof(png_byte *));
1443 unsigned int *blocks = (unsigned int *)data;
1447 for (; y < height; ++y) {
1449 png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1450 row_pointers[y] = (png_bytep)row;
1451 for (x = 0; x < width; ++x) {
1452 unsigned int curBlock = blocks[y * width + x];
1453 row[x * pixel_size] = (curBlock & 0xFF);
1454 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1455 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1456 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1460 png_write_image(pPngStruct, row_pointers);
1461 png_write_end(pPngStruct, pPngInfo);
1463 for (y = 0; y < height; y++)
1464 png_free(pPngStruct, row_pointers[y]);
1465 png_free(pPngStruct, row_pointers);
1467 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1473 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1475 TBM_RETURN_IF_FAIL(path != NULL);
1476 TBM_RETURN_IF_FAIL(w > 0);
1477 TBM_RETURN_IF_FAIL(h > 0);
1478 TBM_RETURN_IF_FAIL(count > 0);
1480 tbm_surface_dump_buf_info *buf_info = NULL;
1481 tbm_surface_dump_buf_info *tmp;
1485 tbm_surface_h tbm_surface;
1486 tbm_surface_info_s info;
1487 tbm_surface_error_e err;
1491 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1495 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1496 TBM_RETURN_IF_FAIL(g_dump_info);
1498 LIST_INITHEAD(&g_dump_info->surface_list);
1499 g_dump_info->count = 0;
1500 g_dump_info->dump_max = count;
1502 /* get buffer size */
1503 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1504 if (tbm_surface == NULL) {
1505 TBM_LOG_E("tbm_surface_create fail\n");
1510 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
1511 if (err != TBM_SURFACE_ERROR_NONE) {
1512 TBM_LOG_E("tbm_surface_map fail\n");
1513 tbm_surface_destroy(tbm_surface);
1518 buffer_size = info.planes[0].stride * h;
1519 tbm_surface_unmap(tbm_surface);
1520 tbm_surface_destroy(tbm_surface);
1522 /* create dump lists */
1523 for (i = 0; i < count; i++) {
1524 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1525 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1526 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1532 buf_info->index = i;
1534 buf_info->size = buffer_size;
1536 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1539 g_dump_info->path = path;
1540 g_dump_info->link = &g_dump_info->surface_list;
1542 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1546 /* free resources */
1547 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1548 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1549 tbm_bo_unref(buf_info->bo);
1554 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1563 tbm_surface_internal_dump_end(void)
1565 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1566 tbm_bo_handle bo_handle;
1572 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1573 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1576 if (buf_info->dirty) {
1580 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1581 if (bo_handle.ptr == NULL)
1584 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1585 TBM_LOG_I("Dump File.. %s generated.\n", file);
1587 switch (buf_info->info.format) {
1588 case TBM_FORMAT_ARGB8888:
1589 case TBM_FORMAT_XRGB8888:
1590 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1591 buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1593 case TBM_FORMAT_YVU420:
1594 case TBM_FORMAT_YUV420:
1595 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1596 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1597 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1598 buf_info->info.planes[0].stride * buf_info->info.height,
1600 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1602 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1604 case TBM_FORMAT_NV12:
1605 case TBM_FORMAT_NV21:
1606 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1607 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1608 buf_info->info.planes[0].stride * buf_info->info.height,
1610 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1613 case TBM_FORMAT_YUYV:
1614 case TBM_FORMAT_UYVY:
1615 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1616 buf_info->info.planes[0].stride * buf_info->info.height,
1620 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1621 tbm_bo_unmap(buf_info->bo);
1625 tbm_bo_unmap(buf_info->bo);
1626 } else if (buf_info->dirty_shm) {
1627 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1628 if (bo_handle.ptr == NULL)
1631 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1632 TBM_LOG_I("Dump File.. %s generated.\n", file);
1634 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1635 buf_info->shm_stride >> 2, buf_info->shm_h);
1637 tbm_bo_unmap(buf_info->bo);
1642 /* free resources */
1643 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1644 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1645 tbm_bo_unref(buf_info->bo);
1653 TBM_LOG_I("Dump End..\n");
1657 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1659 TBM_RETURN_IF_FAIL(surface != NULL);
1660 TBM_RETURN_IF_FAIL(type != NULL);
1662 tbm_surface_dump_buf_info *buf_info;
1663 tbm_surface_info_s info;
1664 struct list_head *next_link;
1665 tbm_bo_handle bo_handle;
1667 const char *postfix;
1672 next_link = g_dump_info->link->next;
1673 TBM_RETURN_IF_FAIL(next_link != NULL);
1675 if (next_link == &g_dump_info->surface_list) {
1676 next_link = next_link->next;
1677 TBM_RETURN_IF_FAIL(next_link != NULL);
1680 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1681 TBM_RETURN_IF_FAIL(buf_info != NULL);
1683 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1684 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1686 if (info.size > buf_info->size) {
1687 TBM_LOG_W("Dump skip. surface over created buffer size(%d, %d)\n", info.size, buf_info->size);
1688 tbm_surface_unmap(surface);
1692 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1693 postfix = dump_postfix[0];
1695 postfix = dump_postfix[1];
1697 /* make the file information */
1698 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1701 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1702 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1703 memset(bo_handle.ptr, 0x00, buf_info->size);
1705 switch (info.format) {
1706 case TBM_FORMAT_ARGB8888:
1707 case TBM_FORMAT_XRGB8888:
1708 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d_%p-%s.%s",
1709 _tbm_surface_internal_get_time(),
1710 g_dump_info->count++, surface, type, postfix);
1711 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1713 case TBM_FORMAT_YVU420:
1714 case TBM_FORMAT_YUV420:
1715 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1716 _tbm_surface_internal_get_time(),
1717 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1718 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1719 bo_handle.ptr += info.planes[0].stride * info.height;
1720 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1721 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1722 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1724 case TBM_FORMAT_NV12:
1725 case TBM_FORMAT_NV21:
1726 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1727 _tbm_surface_internal_get_time(),
1728 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1729 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1730 bo_handle.ptr += info.planes[0].stride * info.height;
1731 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1733 case TBM_FORMAT_YUYV:
1734 case TBM_FORMAT_UYVY:
1735 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1736 _tbm_surface_internal_get_time(),
1737 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1738 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1741 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1742 tbm_bo_unmap(buf_info->bo);
1746 tbm_bo_unmap(buf_info->bo);
1748 tbm_surface_unmap(surface);
1750 buf_info->dirty = 1;
1751 buf_info->dirty_shm = 0;
1753 if (g_dump_info->count == 1000)
1754 g_dump_info->count = 0;
1756 g_dump_info->link = next_link;
1758 TBM_LOG_I("Dump %s \n", buf_info->name);
1761 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, const char *type)
1763 TBM_RETURN_IF_FAIL(ptr != NULL);
1764 TBM_RETURN_IF_FAIL(w > 0);
1765 TBM_RETURN_IF_FAIL(h > 0);
1766 TBM_RETURN_IF_FAIL(stride > 0);
1767 TBM_RETURN_IF_FAIL(type != NULL);
1769 tbm_surface_dump_buf_info *buf_info;
1770 struct list_head *next_link;
1771 tbm_bo_handle bo_handle;
1776 next_link = g_dump_info->link->next;
1777 TBM_RETURN_IF_FAIL(next_link != NULL);
1779 if (next_link == &g_dump_info->surface_list) {
1780 next_link = next_link->next;
1781 TBM_RETURN_IF_FAIL(next_link != NULL);
1784 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1785 TBM_RETURN_IF_FAIL(buf_info != NULL);
1787 if (stride * h > buf_info->size) {
1788 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", stride * h, buf_info->size);
1793 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1794 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1795 memset(bo_handle.ptr, 0x00, buf_info->size);
1796 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1798 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1799 _tbm_surface_internal_get_time(),
1800 g_dump_info->count++, type, dump_postfix[0]);
1801 memcpy(bo_handle.ptr, ptr, stride * h);
1803 tbm_bo_unmap(buf_info->bo);
1805 buf_info->dirty = 0;
1806 buf_info->dirty_shm = 1;
1807 buf_info->shm_stride = stride;
1808 buf_info->shm_h = h;
1810 if (g_dump_info->count == 1000)
1811 g_dump_info->count = 0;
1813 g_dump_info->link = next_link;
1815 TBM_LOG_I("Dump %s \n", buf_info->name);