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_format_to_str(tbm_format format)
75 return "TBM_FORMAT_C8";
76 case TBM_FORMAT_RGB332:
77 return "TBM_FORMAT_RGB332";
78 case TBM_FORMAT_BGR233:
79 return "TBM_FORMAT_BGR233";
80 case TBM_FORMAT_XRGB4444:
81 return "TBM_FORMAT_XRGB4444";
82 case TBM_FORMAT_XBGR4444:
83 return "TBM_FORMAT_XBGR4444";
84 case TBM_FORMAT_RGBX4444:
85 return "TBM_FORMAT_RGBX4444";
86 case TBM_FORMAT_BGRX4444:
87 return "TBM_FORMAT_BGRX4444";
88 case TBM_FORMAT_ARGB4444:
89 return "TBM_FORMAT_ARGB4444";
90 case TBM_FORMAT_ABGR4444:
91 return "TBM_FORMAT_ABGR4444";
92 case TBM_FORMAT_RGBA4444:
93 return "TBM_FORMAT_RGBA4444";
94 case TBM_FORMAT_BGRA4444:
95 return "TBM_FORMAT_BGRA4444";
96 case TBM_FORMAT_XRGB1555:
97 return "TBM_FORMAT_XRGB1555";
98 case TBM_FORMAT_XBGR1555:
99 return "TBM_FORMAT_XBGR1555";
100 case TBM_FORMAT_RGBX5551:
101 return "TBM_FORMAT_RGBX5551";
102 case TBM_FORMAT_BGRX5551:
103 return "TBM_FORMAT_BGRX5551";
104 case TBM_FORMAT_ARGB1555:
105 return "TBM_FORMAT_ARGB1555";
106 case TBM_FORMAT_ABGR1555:
107 return "TBM_FORMAT_ABGR1555";
108 case TBM_FORMAT_RGBA5551:
109 return "TBM_FORMAT_RGBA5551";
110 case TBM_FORMAT_BGRA5551:
111 return "TBM_FORMAT_BGRA5551";
112 case TBM_FORMAT_RGB565:
113 return "TBM_FORMAT_RGB565";
114 case TBM_FORMAT_BGR565:
115 return "TBM_FORMAT_BGR565";
116 case TBM_FORMAT_RGB888:
117 return "TBM_FORMAT_RGB888";
118 case TBM_FORMAT_BGR888:
119 return "TBM_FORMAT_BGR888";
120 case TBM_FORMAT_XRGB8888:
121 return "TBM_FORMAT_XRGB8888";
122 case TBM_FORMAT_XBGR8888:
123 return "TBM_FORMAT_XBGR8888";
124 case TBM_FORMAT_RGBX8888:
125 return "TBM_FORMAT_RGBX8888";
126 case TBM_FORMAT_BGRX8888:
127 return "TBM_FORMAT_BGRX8888";
128 case TBM_FORMAT_ARGB8888:
129 return "TBM_FORMAT_ARGB8888";
130 case TBM_FORMAT_ABGR8888:
131 return "TBM_FORMAT_ABGR8888";
132 case TBM_FORMAT_RGBA8888:
133 return "TBM_FORMAT_RGBA8888";
134 case TBM_FORMAT_BGRA8888:
135 return "TBM_FORMAT_BGRA8888";
136 case TBM_FORMAT_XRGB2101010:
137 return "TBM_FORMAT_XRGB2101010";
138 case TBM_FORMAT_XBGR2101010:
139 return "TBM_FORMAT_XBGR2101010";
140 case TBM_FORMAT_RGBX1010102:
141 return "TBM_FORMAT_RGBX1010102";
142 case TBM_FORMAT_BGRX1010102:
143 return "TBM_FORMAT_BGRX1010102";
144 case TBM_FORMAT_ARGB2101010:
145 return "TBM_FORMAT_ARGB2101010";
146 case TBM_FORMAT_ABGR2101010:
147 return "TBM_FORMAT_ABGR2101010";
148 case TBM_FORMAT_RGBA1010102:
149 return "TBM_FORMAT_RGBA1010102";
150 case TBM_FORMAT_BGRA1010102:
151 return "TBM_FORMAT_BGRA1010102";
152 case TBM_FORMAT_YUYV:
153 return "TBM_FORMAT_YUYV";
154 case TBM_FORMAT_YVYU:
155 return "TBM_FORMAT_YVYU";
156 case TBM_FORMAT_UYVY:
157 return "TBM_FORMAT_UYVY";
158 case TBM_FORMAT_VYUY:
159 return "TBM_FORMAT_VYUY";
160 case TBM_FORMAT_AYUV:
161 return "TBM_FORMAT_AYUV";
162 case TBM_FORMAT_NV12:
163 return "TBM_FORMAT_NV12";
164 case TBM_FORMAT_NV21:
165 return "TBM_FORMAT_NV21";
166 case TBM_FORMAT_NV16:
167 return "TBM_FORMAT_NV16";
168 case TBM_FORMAT_NV61:
169 return "TBM_FORMAT_NV61";
170 case TBM_FORMAT_YUV410:
171 return "TBM_FORMAT_YUV410";
172 case TBM_FORMAT_YVU410:
173 return "TBM_FORMAT_YVU410";
174 case TBM_FORMAT_YUV411:
175 return "TBM_FORMAT_YUV411";
176 case TBM_FORMAT_YVU411:
177 return "TBM_FORMAT_YVU411";
178 case TBM_FORMAT_YUV420:
179 return "TBM_FORMAT_YUV420";
180 case TBM_FORMAT_YVU420:
181 return "TBM_FORMAT_YVU420";
182 case TBM_FORMAT_YUV422:
183 return "TBM_FORMAT_YUV422";
184 case TBM_FORMAT_YVU422:
185 return "TBM_FORMAT_YVU422";
186 case TBM_FORMAT_YUV444:
187 return "TBM_FORMAT_YUV444";
188 case TBM_FORMAT_YVU444:
189 return "TBM_FORMAT_YVU444";
190 case TBM_FORMAT_NV12MT:
191 return "TBM_FORMAT_NV12MT";
199 _tbm_surface_mutex_init(void)
201 static bool tbm_surface_mutex_init = false;
203 if (tbm_surface_mutex_init)
206 if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
207 TBM_LOG_E("fail: tbm_surface mutex init\n");
211 tbm_surface_mutex_init = true;
217 _tbm_surface_mutex_lock(void)
219 if (!_tbm_surface_mutex_init())
222 pthread_mutex_lock(&tbm_surface_lock);
226 _tbm_surface_mutex_unlock(void)
228 pthread_mutex_unlock(&tbm_surface_lock);
232 _init_surface_bufmgr(void)
234 g_surface_bufmgr = tbm_bufmgr_init(-1);
238 _deinit_surface_bufmgr(void)
240 if (!g_surface_bufmgr)
243 tbm_bufmgr_deinit(g_surface_bufmgr);
244 g_surface_bufmgr = NULL;
248 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
249 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
251 TBM_RETURN_VAL_IF_FAIL(surface, 0);
252 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
254 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
255 struct _tbm_bufmgr *mgr = surf->bufmgr;
258 TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
259 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
260 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
261 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
263 if (!mgr->backend->surface_get_plane_data)
266 ret = mgr->backend->surface_get_plane_data(surf->info.width,
267 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
275 _tbm_surface_internal_destroy(tbm_surface_h surface)
278 tbm_bufmgr bufmgr = surface->bufmgr;
279 tbm_user_data *old_data = NULL, *tmp = NULL;
281 /* destory the user_data_list */
282 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
283 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
284 DBG("free user_data\n");
285 user_data_delete(old_data);
289 for (i = 0; i < surface->num_bos; i++) {
290 surface->bos[i]->surface = NULL;
292 tbm_bo_unref(surface->bos[i]);
293 surface->bos[i] = NULL;
296 LIST_DEL(&surface->item_link);
301 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
302 LIST_DELINIT(&bufmgr->surf_list);
303 _deinit_surface_bufmgr();
308 _tbm_surface_get_max_size(int * w, int * h)
311 tbm_surface_h surface = NULL, tmp = NULL;
312 tbm_surface_info_s info;
317 if (g_surface_bufmgr == NULL)
320 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
321 LIST_FOR_EACH_ENTRY_SAFE(surface, tmp, &g_surface_bufmgr->surf_list, item_link) {
322 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
324 if (*w < info.width) *w = info.width;
325 if (*h < info.height) *h = info.height;
334 tbm_surface_internal_is_valid(tbm_surface_h surface)
336 tbm_surface_h old_data = NULL, tmp = NULL;
338 if (surface == NULL || g_surface_bufmgr == NULL) {
339 TBM_TRACE("error: tbm_surface(%p)\n", surface);
343 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
344 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &g_surface_bufmgr->surf_list, item_link) {
345 if (old_data == surface) {
346 TBM_TRACE("tbm_surface(%p)\n", surface);
351 TBM_TRACE("error: tbm_surface(%p)\n", surface);
356 tbm_surface_internal_query_supported_formats(uint32_t **formats,
359 struct _tbm_bufmgr *mgr;
362 _tbm_surface_mutex_lock();
364 if (!g_surface_bufmgr) {
365 _init_surface_bufmgr();
366 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
369 mgr = g_surface_bufmgr;
371 if (!mgr->backend->surface_supported_format) {
372 TBM_TRACE("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
373 _tbm_surface_mutex_unlock();
377 ret = mgr->backend->surface_supported_format(formats, num);
379 TBM_TRACE("tbm_bufmgr(%p) format num(%d)\n", g_surface_bufmgr, *num);
381 _tbm_surface_mutex_unlock();
387 tbm_surface_internal_get_num_planes(tbm_format format)
393 case TBM_FORMAT_RGB332:
394 case TBM_FORMAT_BGR233:
395 case TBM_FORMAT_XRGB4444:
396 case TBM_FORMAT_XBGR4444:
397 case TBM_FORMAT_RGBX4444:
398 case TBM_FORMAT_BGRX4444:
399 case TBM_FORMAT_ARGB4444:
400 case TBM_FORMAT_ABGR4444:
401 case TBM_FORMAT_RGBA4444:
402 case TBM_FORMAT_BGRA4444:
403 case TBM_FORMAT_XRGB1555:
404 case TBM_FORMAT_XBGR1555:
405 case TBM_FORMAT_RGBX5551:
406 case TBM_FORMAT_BGRX5551:
407 case TBM_FORMAT_ARGB1555:
408 case TBM_FORMAT_ABGR1555:
409 case TBM_FORMAT_RGBA5551:
410 case TBM_FORMAT_BGRA5551:
411 case TBM_FORMAT_RGB565:
412 case TBM_FORMAT_BGR565:
413 case TBM_FORMAT_RGB888:
414 case TBM_FORMAT_BGR888:
415 case TBM_FORMAT_XRGB8888:
416 case TBM_FORMAT_XBGR8888:
417 case TBM_FORMAT_RGBX8888:
418 case TBM_FORMAT_BGRX8888:
419 case TBM_FORMAT_ARGB8888:
420 case TBM_FORMAT_ABGR8888:
421 case TBM_FORMAT_RGBA8888:
422 case TBM_FORMAT_BGRA8888:
423 case TBM_FORMAT_XRGB2101010:
424 case TBM_FORMAT_XBGR2101010:
425 case TBM_FORMAT_RGBX1010102:
426 case TBM_FORMAT_BGRX1010102:
427 case TBM_FORMAT_ARGB2101010:
428 case TBM_FORMAT_ABGR2101010:
429 case TBM_FORMAT_RGBA1010102:
430 case TBM_FORMAT_BGRA1010102:
431 case TBM_FORMAT_YUYV:
432 case TBM_FORMAT_YVYU:
433 case TBM_FORMAT_UYVY:
434 case TBM_FORMAT_VYUY:
435 case TBM_FORMAT_AYUV:
438 case TBM_FORMAT_NV12:
439 case TBM_FORMAT_NV12MT:
440 case TBM_FORMAT_NV21:
441 case TBM_FORMAT_NV16:
442 case TBM_FORMAT_NV61:
445 case TBM_FORMAT_YUV410:
446 case TBM_FORMAT_YVU410:
447 case TBM_FORMAT_YUV411:
448 case TBM_FORMAT_YVU411:
449 case TBM_FORMAT_YUV420:
450 case TBM_FORMAT_YVU420:
451 case TBM_FORMAT_YUV422:
452 case TBM_FORMAT_YVU422:
453 case TBM_FORMAT_YUV444:
454 case TBM_FORMAT_YVU444:
462 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
468 tbm_surface_internal_get_bpp(tbm_format format)
475 case TBM_FORMAT_RGB332:
476 case TBM_FORMAT_BGR233:
479 case TBM_FORMAT_XRGB4444:
480 case TBM_FORMAT_XBGR4444:
481 case TBM_FORMAT_RGBX4444:
482 case TBM_FORMAT_BGRX4444:
483 case TBM_FORMAT_ARGB4444:
484 case TBM_FORMAT_ABGR4444:
485 case TBM_FORMAT_RGBA4444:
486 case TBM_FORMAT_BGRA4444:
487 case TBM_FORMAT_XRGB1555:
488 case TBM_FORMAT_XBGR1555:
489 case TBM_FORMAT_RGBX5551:
490 case TBM_FORMAT_BGRX5551:
491 case TBM_FORMAT_ARGB1555:
492 case TBM_FORMAT_ABGR1555:
493 case TBM_FORMAT_RGBA5551:
494 case TBM_FORMAT_BGRA5551:
495 case TBM_FORMAT_RGB565:
496 case TBM_FORMAT_BGR565:
499 case TBM_FORMAT_RGB888:
500 case TBM_FORMAT_BGR888:
503 case TBM_FORMAT_XRGB8888:
504 case TBM_FORMAT_XBGR8888:
505 case TBM_FORMAT_RGBX8888:
506 case TBM_FORMAT_BGRX8888:
507 case TBM_FORMAT_ARGB8888:
508 case TBM_FORMAT_ABGR8888:
509 case TBM_FORMAT_RGBA8888:
510 case TBM_FORMAT_BGRA8888:
511 case TBM_FORMAT_XRGB2101010:
512 case TBM_FORMAT_XBGR2101010:
513 case TBM_FORMAT_RGBX1010102:
514 case TBM_FORMAT_BGRX1010102:
515 case TBM_FORMAT_ARGB2101010:
516 case TBM_FORMAT_ABGR2101010:
517 case TBM_FORMAT_RGBA1010102:
518 case TBM_FORMAT_BGRA1010102:
519 case TBM_FORMAT_YUYV:
520 case TBM_FORMAT_YVYU:
521 case TBM_FORMAT_UYVY:
522 case TBM_FORMAT_VYUY:
523 case TBM_FORMAT_AYUV:
526 case TBM_FORMAT_NV12:
527 case TBM_FORMAT_NV12MT:
528 case TBM_FORMAT_NV21:
531 case TBM_FORMAT_NV16:
532 case TBM_FORMAT_NV61:
535 case TBM_FORMAT_YUV410:
536 case TBM_FORMAT_YVU410:
539 case TBM_FORMAT_YUV411:
540 case TBM_FORMAT_YVU411:
541 case TBM_FORMAT_YUV420:
542 case TBM_FORMAT_YVU420:
545 case TBM_FORMAT_YUV422:
546 case TBM_FORMAT_YVU422:
549 case TBM_FORMAT_YUV444:
550 case TBM_FORMAT_YVU444:
557 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
563 tbm_surface_internal_create_with_flags(int width, int height,
564 int format, int flags)
566 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
567 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
569 struct _tbm_bufmgr *mgr;
570 struct _tbm_surface *surf = NULL;
574 uint32_t bo_size = 0;
578 _tbm_surface_mutex_lock();
580 if (!g_surface_bufmgr) {
581 _init_surface_bufmgr();
582 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
585 mgr = g_surface_bufmgr;
586 if (!TBM_BUFMGR_IS_VALID(mgr)) {
587 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
588 width, height, _tbm_surface_internal_format_to_str(format), flags);
589 _tbm_surface_mutex_unlock();
592 surf = calloc(1, sizeof(struct _tbm_surface));
594 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
595 width, height, _tbm_surface_internal_format_to_str(format), flags);
596 _tbm_surface_mutex_unlock();
601 surf->info.width = width;
602 surf->info.height = height;
603 surf->info.format = format;
604 surf->info.bpp = tbm_surface_internal_get_bpp(format);
605 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
608 /* get size, stride and offset bo_idx */
609 for (i = 0; i < surf->info.num_planes; i++) {
610 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride,
612 surf->info.planes[i].size = size;
613 surf->info.planes[i].offset = offset;
614 surf->info.planes[i].stride = stride;
615 surf->planes_bo_idx[i] = bo_idx;
620 for (i = 0; i < surf->info.num_planes; i++) {
621 surf->info.size += surf->info.planes[i].size;
623 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
624 surf->num_bos = surf->planes_bo_idx[i] + 1;
629 for (i = 0; i < surf->num_bos; i++) {
631 for (j = 0; j < surf->info.num_planes; j++) {
632 if (surf->planes_bo_idx[j] == i)
633 bo_size += surf->info.planes[j].size;
636 if (mgr->backend->surface_bo_alloc) {
637 /* LCOV_EXCL_START */
639 void *bo_priv = NULL;
641 bo = calloc(1, sizeof(struct _tbm_bo));
643 TBM_LOG_E("fail to alloc bo struct\n");
647 bo->bufmgr = surf->bufmgr;
649 pthread_mutex_lock(&surf->bufmgr->lock);
651 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
653 TBM_LOG_E("fail to alloc bo priv\n");
655 pthread_mutex_unlock(&surf->bufmgr->lock);
663 LIST_INITHEAD(&bo->user_data_list);
665 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
667 pthread_mutex_unlock(&surf->bufmgr->lock);
672 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
676 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
680 _tbm_bo_set_surface(surf->bos[i], surf);
684 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
685 _tbm_surface_internal_format_to_str(format), flags, surf);
687 LIST_INITHEAD(&surf->user_data_list);
689 LIST_ADD(&surf->item_link, &mgr->surf_list);
691 _tbm_surface_mutex_unlock();
697 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
698 width, height, _tbm_surface_internal_format_to_str(format), flags);
700 for (j = 0; j < i; j++) {
702 tbm_bo_unref(surf->bos[j]);
708 if (LIST_IS_EMPTY(&mgr->surf_list)) {
709 LIST_DELINIT(&mgr->surf_list);
710 _deinit_surface_bufmgr();
713 _tbm_surface_mutex_unlock();
718 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
719 tbm_bo *bos, int num)
721 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
722 TBM_RETURN_VAL_IF_FAIL(info, NULL);
723 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
725 struct _tbm_bufmgr *mgr;
726 struct _tbm_surface *surf = NULL;
729 _tbm_surface_mutex_lock();
731 if (!g_surface_bufmgr) {
732 _init_surface_bufmgr();
733 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
736 mgr = g_surface_bufmgr;
737 if (!TBM_BUFMGR_IS_VALID(mgr)) {
738 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
739 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
740 _tbm_surface_mutex_unlock();
744 surf = calloc(1, sizeof(struct _tbm_surface));
746 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
747 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
748 _tbm_surface_mutex_unlock();
753 surf->info.width = info->width;
754 surf->info.height = info->height;
755 surf->info.format = info->format;
756 surf->info.bpp = info->bpp;
757 surf->info.num_planes = info->num_planes;
760 /* get size, stride and offset */
761 for (i = 0; i < info->num_planes; i++) {
762 surf->info.planes[i].offset = info->planes[i].offset;
763 surf->info.planes[i].stride = info->planes[i].stride;
765 if (info->planes[i].size > 0)
766 surf->info.planes[i].size = info->planes[i].size;
768 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
771 surf->planes_bo_idx[i] = 0;
773 surf->planes_bo_idx[i] = i;
776 if (info->size > 0) {
777 surf->info.size = info->size;
780 for (i = 0; i < info->num_planes; i++)
781 surf->info.size += surf->info.planes[i].size;
784 surf->flags = TBM_BO_DEFAULT;
786 /* create only one bo */
788 for (i = 0; i < num; i++) {
792 surf->bos[i] = tbm_bo_ref(bos[i]);
793 _tbm_bo_set_surface(bos[i], surf);
796 TBM_TRACE("tbm_surface(%p) width(%d) height(%d) format(%s) bo_num(%d)\n", surf,
797 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
799 LIST_INITHEAD(&surf->user_data_list);
801 LIST_ADD(&surf->item_link, &mgr->surf_list);
803 _tbm_surface_mutex_unlock();
807 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
808 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
809 for (i = 0; i < num; i++) {
811 tbm_bo_unref(surf->bos[i]);
819 if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
820 LIST_DELINIT(&g_surface_bufmgr->surf_list);
821 _deinit_surface_bufmgr();
824 _tbm_surface_mutex_unlock();
830 tbm_surface_internal_destroy(tbm_surface_h surface)
832 if (!tbm_surface_internal_is_valid(surface))
835 _tbm_surface_mutex_lock();
839 if (surface->refcnt > 0) {
840 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
841 _tbm_surface_mutex_unlock();
845 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
847 if (surface->refcnt == 0)
848 _tbm_surface_internal_destroy(surface);
850 _tbm_surface_mutex_unlock();
854 tbm_surface_internal_ref(tbm_surface_h surface)
856 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
858 _tbm_surface_mutex_lock();
862 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
864 _tbm_surface_mutex_unlock();
868 tbm_surface_internal_unref(tbm_surface_h surface)
870 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
872 _tbm_surface_mutex_lock();
876 if (surface->refcnt > 0) {
877 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
878 _tbm_surface_mutex_unlock();
882 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
884 if (surface->refcnt == 0)
885 _tbm_surface_internal_destroy(surface);
887 _tbm_surface_mutex_unlock();
891 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
893 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
895 struct _tbm_surface *surf;
898 _tbm_surface_mutex_lock();
900 surf = (struct _tbm_surface *)surface;
903 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
905 _tbm_surface_mutex_unlock();
911 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
913 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
914 TBM_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
916 struct _tbm_surface *surf;
919 _tbm_surface_mutex_lock();
921 surf = (struct _tbm_surface *)surface;
922 bo = surf->bos[bo_idx];
924 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
926 _tbm_surface_mutex_unlock();
932 tbm_surface_internal_get_size(tbm_surface_h surface)
934 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
936 struct _tbm_surface *surf;
939 _tbm_surface_mutex_lock();
941 surf = (struct _tbm_surface *)surface;
942 size = surf->info.size;
944 TBM_TRACE("tbm_surface(%p) size(%d)\n", surface, size);
946 _tbm_surface_mutex_unlock();
952 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
953 uint32_t *size, uint32_t *offset, uint32_t *pitch)
955 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
956 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
958 struct _tbm_surface *surf;
960 _tbm_surface_mutex_lock();
962 surf = (struct _tbm_surface *)surface;
964 if (plane_idx >= surf->info.num_planes) {
965 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
966 _tbm_surface_mutex_unlock();
971 *size = surf->info.planes[plane_idx].size;
974 *offset = surf->info.planes[plane_idx].offset;
977 *pitch = surf->info.planes[plane_idx].stride;
979 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%d) offset(%d) pitch(%d)\n", surface, plane_idx,
980 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
981 surf->info.planes[plane_idx].stride);
983 _tbm_surface_mutex_unlock();
989 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
990 tbm_surface_info_s *info, int map)
992 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
994 struct _tbm_surface *surf;
995 tbm_bo_handle bo_handles[4];
998 _tbm_surface_mutex_lock();
1000 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1002 surf = (struct _tbm_surface *)surface;
1004 memset(info, 0x00, sizeof(tbm_surface_info_s));
1005 info->width = surf->info.width;
1006 info->height = surf->info.height;
1007 info->format = surf->info.format;
1008 info->bpp = surf->info.bpp;
1009 info->size = surf->info.size;
1010 info->num_planes = surf->info.num_planes;
1013 for (i = 0; i < surf->num_bos; i++) {
1014 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1015 if (bo_handles[i].ptr == NULL) {
1016 for (j = 0; j < i; j++)
1017 tbm_bo_unmap(surf->bos[j]);
1019 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1020 _tbm_surface_mutex_unlock();
1025 for (i = 0; i < surf->num_bos; i++)
1026 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1029 for (i = 0; i < surf->info.num_planes; i++) {
1030 info->planes[i].size = surf->info.planes[i].size;
1031 info->planes[i].offset = surf->info.planes[i].offset;
1032 info->planes[i].stride = surf->info.planes[i].stride;
1034 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1035 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1036 surf->info.planes[i].offset;
1039 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1041 _tbm_surface_mutex_unlock();
1047 tbm_surface_internal_unmap(tbm_surface_h surface)
1049 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1051 struct _tbm_surface *surf;
1054 _tbm_surface_mutex_lock();
1056 surf = (struct _tbm_surface *)surface;
1058 for (i = 0; i < surf->num_bos; i++)
1059 tbm_bo_unmap(surf->bos[i]);
1061 TBM_TRACE("tbm_surface(%p)\n", surface);
1063 _tbm_surface_mutex_unlock();
1067 tbm_surface_internal_get_width(tbm_surface_h surface)
1069 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1071 struct _tbm_surface *surf;
1074 _tbm_surface_mutex_lock();
1076 surf = (struct _tbm_surface *)surface;
1077 width = surf->info.width;
1079 TBM_TRACE("tbm_surface(%p) width(%d)\n", surface, width);
1081 _tbm_surface_mutex_unlock();
1087 tbm_surface_internal_get_height(tbm_surface_h surface)
1089 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1091 struct _tbm_surface *surf;
1092 unsigned int height;
1094 _tbm_surface_mutex_lock();
1096 surf = (struct _tbm_surface *)surface;
1097 height = surf->info.height;
1099 TBM_TRACE("tbm_surface(%p) height(%d)\n", surface, height);
1101 _tbm_surface_mutex_unlock();
1108 tbm_surface_internal_get_format(tbm_surface_h surface)
1110 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1112 struct _tbm_surface *surf;
1115 _tbm_surface_mutex_lock();
1117 surf = (struct _tbm_surface *)surface;
1118 format = surf->info.format;
1120 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1122 _tbm_surface_mutex_unlock();
1128 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1130 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1131 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1132 struct _tbm_surface *surf;
1135 _tbm_surface_mutex_lock();
1137 surf = (struct _tbm_surface *)surface;
1138 bo_idx = surf->planes_bo_idx[plane_idx];
1140 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1142 _tbm_surface_mutex_unlock();
1148 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1149 tbm_data_free data_free_func)
1151 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1153 tbm_user_data *data;
1155 /* check if the data according to the key exist if so, return false. */
1156 data = user_data_lookup(&surface->user_data_list, key);
1158 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1162 data = user_data_create(key, data_free_func);
1164 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1168 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1170 LIST_ADD(&data->item_link, &surface->user_data_list);
1176 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1179 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1181 tbm_user_data *old_data;
1183 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1184 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1188 old_data = user_data_lookup(&surface->user_data_list, key);
1190 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1194 if (old_data->data && old_data->free_func)
1195 old_data->free_func(old_data->data);
1197 old_data->data = data;
1199 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1205 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1208 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1210 tbm_user_data *old_data;
1212 if (!data || LIST_IS_EMPTY(&surface->user_data_list)) {
1213 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1217 old_data = user_data_lookup(&surface->user_data_list, key);
1219 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1224 *data = old_data->data;
1226 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1232 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1235 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1237 tbm_user_data *old_data = (void *)0;
1239 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1240 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1244 old_data = user_data_lookup(&surface->user_data_list, key);
1246 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1250 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1252 user_data_delete(old_data);
1257 /* LCOV_EXCL_START */
1259 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1261 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1263 return surface->debug_pid;
1267 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1269 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1271 surface->debug_pid = pid;
1274 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1275 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1277 struct _tbm_surface_dump_buf_info {
1287 tbm_surface_info_s info;
1289 struct list_head link;
1292 struct _tbm_surface_dump_info {
1293 char *path; // copy???
1296 struct list_head *link;
1297 struct list_head surface_list; /* link of surface */
1300 static tbm_surface_dump_info *g_dump_info = NULL;
1301 static const char *dump_postfix[2] = {"png", "yuv"};
1304 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1305 int size2, void *data3, int size3)
1307 unsigned int *blocks;
1308 FILE *fp = fopen(file, "w+");
1309 TBM_RETURN_IF_FAIL(fp != NULL);
1311 blocks = (unsigned int *)data1;
1312 fwrite(blocks, 1, size1, fp);
1315 blocks = (unsigned int *)data2;
1316 fwrite(blocks, 1, size2, fp);
1320 blocks = (unsigned int *)data3;
1321 fwrite(blocks, 1, size3, fp);
1328 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1331 FILE *fp = fopen(file, "wb");
1332 TBM_RETURN_IF_FAIL(fp != NULL);
1335 png_structp pPngStruct =
1336 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1342 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1344 png_destroy_write_struct(&pPngStruct, NULL);
1349 png_init_io(pPngStruct, fp);
1350 png_set_IHDR(pPngStruct,
1355 PNG_COLOR_TYPE_RGBA,
1357 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1359 png_set_bgr(pPngStruct);
1360 png_write_info(pPngStruct, pPngInfo);
1362 const int pixel_size = 4; // RGBA
1363 png_bytep *row_pointers =
1364 png_malloc(pPngStruct, height * sizeof(png_byte *));
1366 unsigned int *blocks = (unsigned int *)data;
1370 for (; y < height; ++y) {
1372 png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1373 row_pointers[y] = (png_bytep)row;
1374 for (x = 0; x < width; ++x) {
1375 unsigned int curBlock = blocks[y * width + x];
1376 row[x * pixel_size] = (curBlock & 0xFF);
1377 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1378 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1379 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1383 png_write_image(pPngStruct, row_pointers);
1384 png_write_end(pPngStruct, pPngInfo);
1386 for (y = 0; y < height; y++)
1387 png_free(pPngStruct, row_pointers[y]);
1388 png_free(pPngStruct, row_pointers);
1390 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1396 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1398 TBM_RETURN_IF_FAIL(path != NULL);
1399 TBM_RETURN_IF_FAIL(w > 0);
1400 TBM_RETURN_IF_FAIL(h > 0);
1401 TBM_RETURN_IF_FAIL(count > 0);
1403 tbm_surface_dump_buf_info *buf_info = NULL;
1404 tbm_surface_dump_buf_info *tmp;
1408 tbm_surface_h tbm_surface;
1409 tbm_surface_info_s info;
1410 tbm_surface_error_e err;
1414 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1418 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1419 TBM_RETURN_IF_FAIL(g_dump_info);
1421 LIST_INITHEAD(&g_dump_info->surface_list);
1422 g_dump_info->count = 0;
1423 g_dump_info->dump_max = count;
1425 /* get buffer size */
1426 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1427 if (tbm_surface == NULL) {
1428 TBM_LOG_E("tbm_surface_create fail\n");
1433 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
1434 if (err != TBM_SURFACE_ERROR_NONE) {
1435 TBM_LOG_E("tbm_surface_map fail\n");
1436 tbm_surface_destroy(tbm_surface);
1441 buffer_size = info.planes[0].stride * h;
1442 tbm_surface_unmap(tbm_surface);
1443 tbm_surface_destroy(tbm_surface);
1445 /* create dump lists */
1446 for (i = 0; i < count; i++) {
1447 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1448 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1449 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1455 buf_info->index = i;
1457 buf_info->size = buffer_size;
1459 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1462 g_dump_info->path = path;
1463 g_dump_info->link = &g_dump_info->surface_list;
1465 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1469 /* free resources */
1470 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1471 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1472 tbm_bo_unref(buf_info->bo);
1477 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1486 tbm_surface_internal_dump_end(void)
1488 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1489 tbm_bo_handle bo_handle;
1495 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1496 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1499 if (buf_info->dirty) {
1503 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1504 if (bo_handle.ptr == NULL)
1507 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1508 TBM_LOG_I("Dump File.. %s generated.\n", file);
1510 switch (buf_info->info.format) {
1511 case TBM_FORMAT_ARGB8888:
1512 case TBM_FORMAT_XRGB8888:
1513 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1514 buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1516 case TBM_FORMAT_YVU420:
1517 case TBM_FORMAT_YUV420:
1518 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1519 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1520 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1521 buf_info->info.planes[0].stride * buf_info->info.height,
1523 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1525 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1527 case TBM_FORMAT_NV12:
1528 case TBM_FORMAT_NV21:
1529 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1530 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1531 buf_info->info.planes[0].stride * buf_info->info.height,
1533 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1536 case TBM_FORMAT_YUYV:
1537 case TBM_FORMAT_UYVY:
1538 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1539 buf_info->info.planes[0].stride * buf_info->info.height,
1543 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1544 tbm_bo_unmap(buf_info->bo);
1548 tbm_bo_unmap(buf_info->bo);
1549 } else if (buf_info->dirty_shm) {
1550 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1551 if (bo_handle.ptr == NULL)
1554 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1555 TBM_LOG_I("Dump File.. %s generated.\n", file);
1557 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1558 buf_info->shm_stride >> 2, buf_info->shm_h);
1560 tbm_bo_unmap(buf_info->bo);
1566 /* free resources */
1567 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1568 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1569 tbm_bo_unref(buf_info->bo);
1577 TBM_LOG_I("Dump End..\n");
1581 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1583 TBM_RETURN_IF_FAIL(surface != NULL);
1584 TBM_RETURN_IF_FAIL(type != NULL);
1586 tbm_surface_dump_buf_info *buf_info;
1587 tbm_surface_info_s info;
1588 struct list_head *next_link;
1589 tbm_bo_handle bo_handle;
1591 const char *postfix;
1596 next_link = g_dump_info->link->next;
1597 TBM_RETURN_IF_FAIL(next_link != NULL);
1599 if (next_link == &g_dump_info->surface_list) {
1600 next_link = next_link->next;
1601 TBM_RETURN_IF_FAIL(next_link != NULL);
1604 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1605 TBM_RETURN_IF_FAIL(buf_info != NULL);
1607 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1608 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1610 if (info.size > buf_info->size) {
1611 TBM_LOG_W("Dump skip. surface over created buffer size(%d, %d)\n", info.size, buf_info->size);
1612 tbm_surface_unmap(surface);
1616 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1617 postfix = dump_postfix[0];
1619 postfix = dump_postfix[1];
1621 /* make the file information */
1622 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1625 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1626 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1627 memset(bo_handle.ptr, 0x00, buf_info->size);
1629 switch (info.format) {
1630 case TBM_FORMAT_ARGB8888:
1631 case TBM_FORMAT_XRGB8888:
1632 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d_%p-%s.%s",
1633 _tbm_surface_internal_get_time(),
1634 g_dump_info->count++, surface, type, postfix);
1635 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1637 case TBM_FORMAT_YVU420:
1638 case TBM_FORMAT_YUV420:
1639 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1640 _tbm_surface_internal_get_time(),
1641 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1642 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1643 bo_handle.ptr += info.planes[0].stride * info.height;
1644 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1645 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1646 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1648 case TBM_FORMAT_NV12:
1649 case TBM_FORMAT_NV21:
1650 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1651 _tbm_surface_internal_get_time(),
1652 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1653 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1654 bo_handle.ptr += info.planes[0].stride * info.height;
1655 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1657 case TBM_FORMAT_YUYV:
1658 case TBM_FORMAT_UYVY:
1659 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1660 _tbm_surface_internal_get_time(),
1661 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1662 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1665 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1666 tbm_bo_unmap(buf_info->bo);
1670 tbm_bo_unmap(buf_info->bo);
1672 tbm_surface_unmap(surface);
1674 buf_info->dirty = 1;
1675 buf_info->dirty_shm = 0;
1677 if (g_dump_info->count == 1000)
1678 g_dump_info->count = 0;
1680 g_dump_info->link = next_link;
1682 TBM_LOG_I("Dump %s \n", buf_info->name);
1685 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, const char *type)
1687 TBM_RETURN_IF_FAIL(ptr != NULL);
1688 TBM_RETURN_IF_FAIL(w > 0);
1689 TBM_RETURN_IF_FAIL(h > 0);
1690 TBM_RETURN_IF_FAIL(stride > 0);
1691 TBM_RETURN_IF_FAIL(type != NULL);
1693 tbm_surface_dump_buf_info *buf_info;
1694 struct list_head *next_link;
1695 tbm_bo_handle bo_handle;
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 if (stride * h > buf_info->size) {
1712 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", stride * h, buf_info->size);
1717 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1718 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1719 memset(bo_handle.ptr, 0x00, buf_info->size);
1720 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1722 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1723 _tbm_surface_internal_get_time(),
1724 g_dump_info->count++, type, dump_postfix[0]);
1725 memcpy(bo_handle.ptr, ptr, stride * h);
1727 tbm_bo_unmap(buf_info->bo);
1729 buf_info->dirty = 0;
1730 buf_info->dirty_shm = 1;
1731 buf_info->shm_stride = stride;
1732 buf_info->shm_h = h;
1734 if (g_dump_info->count == 1000)
1735 g_dump_info->count = 0;
1737 g_dump_info->link = next_link;
1739 TBM_LOG_I("Dump %s \n", buf_info->name);
1742 void tbm_surface_internal_dump_all(char *path)
1744 TBM_RETURN_IF_FAIL(path != NULL);
1745 int w = 0, h = 0, count = 0;
1746 tbm_surface_h surface = NULL, tmp = NULL;
1748 count = _tbm_surface_get_max_size(&w, &h);
1750 TBM_LOG_I("No tbm_surface.\n");
1754 tbm_surface_internal_dump_start(path, w, h, count);
1756 LIST_FOR_EACH_ENTRY_SAFE(surface, tmp, &g_surface_bufmgr->surf_list, item_link) {
1757 tbm_surface_internal_dump_buffer(surface, "dump_all");
1760 tbm_surface_internal_dump_end();