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;
54 _get_time_in_millis(void)
58 gettimeofday(&tv, NULL);
60 return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
64 _tbm_surface_internal_format_to_str(tbm_format format)
68 return "TBM_FORMAT_C8";
69 case TBM_FORMAT_RGB332:
70 return "TBM_FORMAT_RGB332";
71 case TBM_FORMAT_BGR233:
72 return "TBM_FORMAT_BGR233";
73 case TBM_FORMAT_XRGB4444:
74 return "TBM_FORMAT_XRGB4444";
75 case TBM_FORMAT_XBGR4444:
76 return "TBM_FORMAT_XBGR4444";
77 case TBM_FORMAT_RGBX4444:
78 return "TBM_FORMAT_RGBX4444";
79 case TBM_FORMAT_BGRX4444:
80 return "TBM_FORMAT_BGRX4444";
81 case TBM_FORMAT_ARGB4444:
82 return "TBM_FORMAT_ARGB4444";
83 case TBM_FORMAT_ABGR4444:
84 return "TBM_FORMAT_ABGR4444";
85 case TBM_FORMAT_RGBA4444:
86 return "TBM_FORMAT_RGBA4444";
87 case TBM_FORMAT_BGRA4444:
88 return "TBM_FORMAT_BGRA4444";
89 case TBM_FORMAT_XRGB1555:
90 return "TBM_FORMAT_XRGB1555";
91 case TBM_FORMAT_XBGR1555:
92 return "TBM_FORMAT_XBGR1555";
93 case TBM_FORMAT_RGBX5551:
94 return "TBM_FORMAT_RGBX5551";
95 case TBM_FORMAT_BGRX5551:
96 return "TBM_FORMAT_BGRX5551";
97 case TBM_FORMAT_ARGB1555:
98 return "TBM_FORMAT_ARGB1555";
99 case TBM_FORMAT_ABGR1555:
100 return "TBM_FORMAT_ABGR1555";
101 case TBM_FORMAT_RGBA5551:
102 return "TBM_FORMAT_RGBA5551";
103 case TBM_FORMAT_BGRA5551:
104 return "TBM_FORMAT_BGRA5551";
105 case TBM_FORMAT_RGB565:
106 return "TBM_FORMAT_RGB565";
107 case TBM_FORMAT_BGR565:
108 return "TBM_FORMAT_BGR565";
109 case TBM_FORMAT_RGB888:
110 return "TBM_FORMAT_RGB888";
111 case TBM_FORMAT_BGR888:
112 return "TBM_FORMAT_BGR888";
113 case TBM_FORMAT_XRGB8888:
114 return "TBM_FORMAT_XRGB8888";
115 case TBM_FORMAT_XBGR8888:
116 return "TBM_FORMAT_XBGR8888";
117 case TBM_FORMAT_RGBX8888:
118 return "TBM_FORMAT_RGBX8888";
119 case TBM_FORMAT_BGRX8888:
120 return "TBM_FORMAT_BGRX8888";
121 case TBM_FORMAT_ARGB8888:
122 return "TBM_FORMAT_ARGB8888";
123 case TBM_FORMAT_ABGR8888:
124 return "TBM_FORMAT_ABGR8888";
125 case TBM_FORMAT_RGBA8888:
126 return "TBM_FORMAT_RGBA8888";
127 case TBM_FORMAT_BGRA8888:
128 return "TBM_FORMAT_BGRA8888";
129 case TBM_FORMAT_XRGB2101010:
130 return "TBM_FORMAT_XRGB2101010";
131 case TBM_FORMAT_XBGR2101010:
132 return "TBM_FORMAT_XBGR2101010";
133 case TBM_FORMAT_RGBX1010102:
134 return "TBM_FORMAT_RGBX1010102";
135 case TBM_FORMAT_BGRX1010102:
136 return "TBM_FORMAT_BGRX1010102";
137 case TBM_FORMAT_ARGB2101010:
138 return "TBM_FORMAT_ARGB2101010";
139 case TBM_FORMAT_ABGR2101010:
140 return "TBM_FORMAT_ABGR2101010";
141 case TBM_FORMAT_RGBA1010102:
142 return "TBM_FORMAT_RGBA1010102";
143 case TBM_FORMAT_BGRA1010102:
144 return "TBM_FORMAT_BGRA1010102";
145 case TBM_FORMAT_YUYV:
146 return "TBM_FORMAT_YUYV";
147 case TBM_FORMAT_YVYU:
148 return "TBM_FORMAT_YVYU";
149 case TBM_FORMAT_UYVY:
150 return "TBM_FORMAT_UYVY";
151 case TBM_FORMAT_VYUY:
152 return "TBM_FORMAT_VYUY";
153 case TBM_FORMAT_AYUV:
154 return "TBM_FORMAT_AYUV";
155 case TBM_FORMAT_NV12:
156 return "TBM_FORMAT_NV12";
157 case TBM_FORMAT_NV21:
158 return "TBM_FORMAT_NV21";
159 case TBM_FORMAT_NV16:
160 return "TBM_FORMAT_NV16";
161 case TBM_FORMAT_NV61:
162 return "TBM_FORMAT_NV61";
163 case TBM_FORMAT_YUV410:
164 return "TBM_FORMAT_YUV410";
165 case TBM_FORMAT_YVU410:
166 return "TBM_FORMAT_YVU410";
167 case TBM_FORMAT_YUV411:
168 return "TBM_FORMAT_YUV411";
169 case TBM_FORMAT_YVU411:
170 return "TBM_FORMAT_YVU411";
171 case TBM_FORMAT_YUV420:
172 return "TBM_FORMAT_YUV420";
173 case TBM_FORMAT_YVU420:
174 return "TBM_FORMAT_YVU420";
175 case TBM_FORMAT_YUV422:
176 return "TBM_FORMAT_YUV422";
177 case TBM_FORMAT_YVU422:
178 return "TBM_FORMAT_YVU422";
179 case TBM_FORMAT_YUV444:
180 return "TBM_FORMAT_YUV444";
181 case TBM_FORMAT_YVU444:
182 return "TBM_FORMAT_YVU444";
183 case TBM_FORMAT_NV12MT:
184 return "TBM_FORMAT_NV12MT";
192 _tbm_surface_mutex_init(void)
194 static bool tbm_surface_mutex_init = false;
196 if (tbm_surface_mutex_init)
199 if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
200 TBM_LOG_E("fail: tbm_surface mutex init\n");
204 tbm_surface_mutex_init = true;
210 _tbm_surface_mutex_lock(void)
212 if (!_tbm_surface_mutex_init())
215 pthread_mutex_lock(&tbm_surface_lock);
219 _tbm_surface_mutex_unlock(void)
221 pthread_mutex_unlock(&tbm_surface_lock);
225 _init_surface_bufmgr(void)
227 g_surface_bufmgr = tbm_bufmgr_init(-1);
231 _deinit_surface_bufmgr(void)
233 if (!g_surface_bufmgr)
236 tbm_bufmgr_deinit(g_surface_bufmgr);
237 g_surface_bufmgr = NULL;
241 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
242 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
244 TBM_RETURN_VAL_IF_FAIL(surface, 0);
245 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
247 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
248 struct _tbm_bufmgr *mgr = surf->bufmgr;
251 TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
252 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
253 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
254 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
256 if (!mgr->backend->surface_get_plane_data)
259 ret = mgr->backend->surface_get_plane_data(surf->info.width,
260 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
268 _tbm_surface_internal_destroy(tbm_surface_h surface)
271 tbm_bufmgr bufmgr = surface->bufmgr;
272 tbm_user_data *old_data = NULL, *tmp = NULL;
274 for (i = 0; i < surface->num_bos; i++) {
275 surface->bos[i]->surface = NULL;
277 tbm_bo_unref(surface->bos[i]);
278 surface->bos[i] = 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 LIST_DEL(&surface->item_link);
294 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
295 LIST_DELINIT(&bufmgr->surf_list);
296 _deinit_surface_bufmgr();
301 _tbm_surface_get_max_size(int * w, int * h)
304 tbm_surface_h surface = NULL, tmp = NULL;
305 tbm_surface_info_s info;
310 if (g_surface_bufmgr == NULL)
313 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
314 LIST_FOR_EACH_ENTRY_SAFE(surface, tmp, &g_surface_bufmgr->surf_list, item_link) {
315 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
317 if (*w < info.width) *w = info.width;
318 if (*h < info.height) *h = info.height;
327 tbm_surface_internal_is_valid(tbm_surface_h surface)
329 tbm_surface_h old_data = NULL, tmp = NULL;
331 if (surface == NULL || g_surface_bufmgr == NULL) {
332 TBM_TRACE("error: tbm_surface(%p)\n", surface);
336 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
337 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &g_surface_bufmgr->surf_list, item_link) {
338 if (old_data == surface) {
339 TBM_TRACE("tbm_surface(%p)\n", surface);
344 TBM_TRACE("error: tbm_surface(%p)\n", surface);
349 tbm_surface_internal_query_supported_formats(uint32_t **formats,
352 struct _tbm_bufmgr *mgr;
355 _tbm_surface_mutex_lock();
357 if (!g_surface_bufmgr) {
358 _init_surface_bufmgr();
359 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
362 mgr = g_surface_bufmgr;
364 if (!mgr->backend->surface_supported_format) {
365 TBM_TRACE("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
366 _tbm_surface_mutex_unlock();
370 ret = mgr->backend->surface_supported_format(formats, num);
372 TBM_TRACE("tbm_bufmgr(%p) format num(%d)\n", g_surface_bufmgr, *num);
374 _tbm_surface_mutex_unlock();
380 tbm_surface_internal_get_num_planes(tbm_format format)
386 case TBM_FORMAT_RGB332:
387 case TBM_FORMAT_BGR233:
388 case TBM_FORMAT_XRGB4444:
389 case TBM_FORMAT_XBGR4444:
390 case TBM_FORMAT_RGBX4444:
391 case TBM_FORMAT_BGRX4444:
392 case TBM_FORMAT_ARGB4444:
393 case TBM_FORMAT_ABGR4444:
394 case TBM_FORMAT_RGBA4444:
395 case TBM_FORMAT_BGRA4444:
396 case TBM_FORMAT_XRGB1555:
397 case TBM_FORMAT_XBGR1555:
398 case TBM_FORMAT_RGBX5551:
399 case TBM_FORMAT_BGRX5551:
400 case TBM_FORMAT_ARGB1555:
401 case TBM_FORMAT_ABGR1555:
402 case TBM_FORMAT_RGBA5551:
403 case TBM_FORMAT_BGRA5551:
404 case TBM_FORMAT_RGB565:
405 case TBM_FORMAT_BGR565:
406 case TBM_FORMAT_RGB888:
407 case TBM_FORMAT_BGR888:
408 case TBM_FORMAT_XRGB8888:
409 case TBM_FORMAT_XBGR8888:
410 case TBM_FORMAT_RGBX8888:
411 case TBM_FORMAT_BGRX8888:
412 case TBM_FORMAT_ARGB8888:
413 case TBM_FORMAT_ABGR8888:
414 case TBM_FORMAT_RGBA8888:
415 case TBM_FORMAT_BGRA8888:
416 case TBM_FORMAT_XRGB2101010:
417 case TBM_FORMAT_XBGR2101010:
418 case TBM_FORMAT_RGBX1010102:
419 case TBM_FORMAT_BGRX1010102:
420 case TBM_FORMAT_ARGB2101010:
421 case TBM_FORMAT_ABGR2101010:
422 case TBM_FORMAT_RGBA1010102:
423 case TBM_FORMAT_BGRA1010102:
424 case TBM_FORMAT_YUYV:
425 case TBM_FORMAT_YVYU:
426 case TBM_FORMAT_UYVY:
427 case TBM_FORMAT_VYUY:
428 case TBM_FORMAT_AYUV:
431 case TBM_FORMAT_NV12:
432 case TBM_FORMAT_NV12MT:
433 case TBM_FORMAT_NV21:
434 case TBM_FORMAT_NV16:
435 case TBM_FORMAT_NV61:
438 case TBM_FORMAT_YUV410:
439 case TBM_FORMAT_YVU410:
440 case TBM_FORMAT_YUV411:
441 case TBM_FORMAT_YVU411:
442 case TBM_FORMAT_YUV420:
443 case TBM_FORMAT_YVU420:
444 case TBM_FORMAT_YUV422:
445 case TBM_FORMAT_YVU422:
446 case TBM_FORMAT_YUV444:
447 case TBM_FORMAT_YVU444:
455 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
461 tbm_surface_internal_get_bpp(tbm_format format)
468 case TBM_FORMAT_RGB332:
469 case TBM_FORMAT_BGR233:
472 case TBM_FORMAT_XRGB4444:
473 case TBM_FORMAT_XBGR4444:
474 case TBM_FORMAT_RGBX4444:
475 case TBM_FORMAT_BGRX4444:
476 case TBM_FORMAT_ARGB4444:
477 case TBM_FORMAT_ABGR4444:
478 case TBM_FORMAT_RGBA4444:
479 case TBM_FORMAT_BGRA4444:
480 case TBM_FORMAT_XRGB1555:
481 case TBM_FORMAT_XBGR1555:
482 case TBM_FORMAT_RGBX5551:
483 case TBM_FORMAT_BGRX5551:
484 case TBM_FORMAT_ARGB1555:
485 case TBM_FORMAT_ABGR1555:
486 case TBM_FORMAT_RGBA5551:
487 case TBM_FORMAT_BGRA5551:
488 case TBM_FORMAT_RGB565:
489 case TBM_FORMAT_BGR565:
492 case TBM_FORMAT_RGB888:
493 case TBM_FORMAT_BGR888:
496 case TBM_FORMAT_XRGB8888:
497 case TBM_FORMAT_XBGR8888:
498 case TBM_FORMAT_RGBX8888:
499 case TBM_FORMAT_BGRX8888:
500 case TBM_FORMAT_ARGB8888:
501 case TBM_FORMAT_ABGR8888:
502 case TBM_FORMAT_RGBA8888:
503 case TBM_FORMAT_BGRA8888:
504 case TBM_FORMAT_XRGB2101010:
505 case TBM_FORMAT_XBGR2101010:
506 case TBM_FORMAT_RGBX1010102:
507 case TBM_FORMAT_BGRX1010102:
508 case TBM_FORMAT_ARGB2101010:
509 case TBM_FORMAT_ABGR2101010:
510 case TBM_FORMAT_RGBA1010102:
511 case TBM_FORMAT_BGRA1010102:
512 case TBM_FORMAT_YUYV:
513 case TBM_FORMAT_YVYU:
514 case TBM_FORMAT_UYVY:
515 case TBM_FORMAT_VYUY:
516 case TBM_FORMAT_AYUV:
519 case TBM_FORMAT_NV12:
520 case TBM_FORMAT_NV12MT:
521 case TBM_FORMAT_NV21:
524 case TBM_FORMAT_NV16:
525 case TBM_FORMAT_NV61:
528 case TBM_FORMAT_YUV410:
529 case TBM_FORMAT_YVU410:
532 case TBM_FORMAT_YUV411:
533 case TBM_FORMAT_YVU411:
534 case TBM_FORMAT_YUV420:
535 case TBM_FORMAT_YVU420:
538 case TBM_FORMAT_YUV422:
539 case TBM_FORMAT_YVU422:
542 case TBM_FORMAT_YUV444:
543 case TBM_FORMAT_YVU444:
550 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
556 tbm_surface_internal_create_with_flags(int width, int height,
557 int format, int flags)
559 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
560 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
562 struct _tbm_bufmgr *mgr;
563 struct _tbm_surface *surf = NULL;
567 uint32_t bo_size = 0;
571 _tbm_surface_mutex_lock();
573 if (!g_surface_bufmgr) {
574 _init_surface_bufmgr();
575 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
578 mgr = g_surface_bufmgr;
579 if (!TBM_BUFMGR_IS_VALID(mgr)) {
580 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
581 width, height, _tbm_surface_internal_format_to_str(format), flags);
582 _tbm_surface_mutex_unlock();
585 surf = calloc(1, sizeof(struct _tbm_surface));
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();
594 surf->info.width = width;
595 surf->info.height = height;
596 surf->info.format = format;
597 surf->info.bpp = tbm_surface_internal_get_bpp(format);
598 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
601 /* get size, stride and offset bo_idx */
602 for (i = 0; i < surf->info.num_planes; i++) {
603 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride,
605 surf->info.planes[i].size = size;
606 surf->info.planes[i].offset = offset;
607 surf->info.planes[i].stride = stride;
608 surf->planes_bo_idx[i] = bo_idx;
613 for (i = 0; i < surf->info.num_planes; i++) {
614 surf->info.size += surf->info.planes[i].size;
616 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
617 surf->num_bos = surf->planes_bo_idx[i] + 1;
622 for (i = 0; i < surf->num_bos; i++) {
624 for (j = 0; j < surf->info.num_planes; j++) {
625 if (surf->planes_bo_idx[j] == i)
626 bo_size += surf->info.planes[j].size;
629 if (mgr->backend->surface_bo_alloc) {
630 /* LCOV_EXCL_START */
632 void *bo_priv = NULL;
634 bo = calloc(1, sizeof(struct _tbm_bo));
636 TBM_LOG_E("fail to alloc bo struct\n");
640 bo->bufmgr = surf->bufmgr;
642 pthread_mutex_lock(&surf->bufmgr->lock);
644 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
646 TBM_LOG_E("fail to alloc bo priv\n");
648 pthread_mutex_unlock(&surf->bufmgr->lock);
656 LIST_INITHEAD(&bo->user_data_list);
658 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
660 pthread_mutex_unlock(&surf->bufmgr->lock);
665 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
669 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
673 _tbm_bo_set_surface(surf->bos[i], surf);
677 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
678 _tbm_surface_internal_format_to_str(format), flags, surf);
680 LIST_INITHEAD(&surf->user_data_list);
682 LIST_ADD(&surf->item_link, &mgr->surf_list);
684 _tbm_surface_mutex_unlock();
690 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
691 width, height, _tbm_surface_internal_format_to_str(format), flags);
693 for (j = 0; j < i; j++) {
695 tbm_bo_unref(surf->bos[j]);
701 if (LIST_IS_EMPTY(&mgr->surf_list)) {
702 LIST_DELINIT(&mgr->surf_list);
703 _deinit_surface_bufmgr();
706 _tbm_surface_mutex_unlock();
711 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
712 tbm_bo *bos, int num)
714 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
715 TBM_RETURN_VAL_IF_FAIL(info, NULL);
716 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
718 struct _tbm_bufmgr *mgr;
719 struct _tbm_surface *surf = NULL;
722 _tbm_surface_mutex_lock();
724 if (!g_surface_bufmgr) {
725 _init_surface_bufmgr();
726 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
729 mgr = g_surface_bufmgr;
730 if (!TBM_BUFMGR_IS_VALID(mgr)) {
731 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
732 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
733 _tbm_surface_mutex_unlock();
737 surf = calloc(1, sizeof(struct _tbm_surface));
739 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
740 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
741 _tbm_surface_mutex_unlock();
746 surf->info.width = info->width;
747 surf->info.height = info->height;
748 surf->info.format = info->format;
749 surf->info.bpp = info->bpp;
750 surf->info.num_planes = info->num_planes;
753 /* get size, stride and offset */
754 for (i = 0; i < info->num_planes; i++) {
755 surf->info.planes[i].offset = info->planes[i].offset;
756 surf->info.planes[i].stride = info->planes[i].stride;
758 if (info->planes[i].size > 0)
759 surf->info.planes[i].size = info->planes[i].size;
761 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
764 surf->planes_bo_idx[i] = 0;
766 surf->planes_bo_idx[i] = i;
769 if (info->size > 0) {
770 surf->info.size = info->size;
773 for (i = 0; i < info->num_planes; i++)
774 surf->info.size += surf->info.planes[i].size;
777 surf->flags = TBM_BO_DEFAULT;
779 /* create only one bo */
781 for (i = 0; i < num; i++) {
785 surf->bos[i] = tbm_bo_ref(bos[i]);
786 _tbm_bo_set_surface(bos[i], surf);
789 TBM_TRACE("tbm_surface(%p) width(%d) height(%d) format(%s) bo_num(%d)\n", surf,
790 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
792 LIST_INITHEAD(&surf->user_data_list);
794 LIST_ADD(&surf->item_link, &mgr->surf_list);
796 _tbm_surface_mutex_unlock();
800 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
801 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
802 for (i = 0; i < num; i++) {
804 tbm_bo_unref(surf->bos[i]);
812 if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
813 LIST_DELINIT(&g_surface_bufmgr->surf_list);
814 _deinit_surface_bufmgr();
817 _tbm_surface_mutex_unlock();
823 tbm_surface_internal_destroy(tbm_surface_h surface)
825 if (!tbm_surface_internal_is_valid(surface))
828 _tbm_surface_mutex_lock();
832 if (surface->refcnt > 0) {
833 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
834 _tbm_surface_mutex_unlock();
838 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
840 if (surface->refcnt == 0)
841 _tbm_surface_internal_destroy(surface);
843 _tbm_surface_mutex_unlock();
847 tbm_surface_internal_ref(tbm_surface_h surface)
849 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
851 _tbm_surface_mutex_lock();
855 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
857 _tbm_surface_mutex_unlock();
861 tbm_surface_internal_unref(tbm_surface_h surface)
863 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
865 _tbm_surface_mutex_lock();
869 if (surface->refcnt > 0) {
870 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
871 _tbm_surface_mutex_unlock();
875 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
877 if (surface->refcnt == 0)
878 _tbm_surface_internal_destroy(surface);
880 _tbm_surface_mutex_unlock();
884 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
886 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
888 struct _tbm_surface *surf;
891 _tbm_surface_mutex_lock();
893 surf = (struct _tbm_surface *)surface;
896 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
898 _tbm_surface_mutex_unlock();
904 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
906 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
907 TBM_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
909 struct _tbm_surface *surf;
912 _tbm_surface_mutex_lock();
914 surf = (struct _tbm_surface *)surface;
915 bo = surf->bos[bo_idx];
917 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
919 _tbm_surface_mutex_unlock();
925 tbm_surface_internal_get_size(tbm_surface_h surface)
927 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
929 struct _tbm_surface *surf;
932 _tbm_surface_mutex_lock();
934 surf = (struct _tbm_surface *)surface;
935 size = surf->info.size;
937 TBM_TRACE("tbm_surface(%p) size(%d)\n", surface, size);
939 _tbm_surface_mutex_unlock();
945 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
946 uint32_t *size, uint32_t *offset, uint32_t *pitch)
948 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
949 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
951 struct _tbm_surface *surf;
953 _tbm_surface_mutex_lock();
955 surf = (struct _tbm_surface *)surface;
957 if (plane_idx >= surf->info.num_planes) {
958 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
959 _tbm_surface_mutex_unlock();
964 *size = surf->info.planes[plane_idx].size;
967 *offset = surf->info.planes[plane_idx].offset;
970 *pitch = surf->info.planes[plane_idx].stride;
972 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%d) offset(%d) pitch(%d)\n", surface, plane_idx,
973 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
974 surf->info.planes[plane_idx].stride);
976 _tbm_surface_mutex_unlock();
982 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
983 tbm_surface_info_s *info, int map)
985 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
987 struct _tbm_surface *surf;
988 tbm_bo_handle bo_handles[4];
991 _tbm_surface_mutex_lock();
993 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
995 surf = (struct _tbm_surface *)surface;
997 memset(info, 0x00, sizeof(tbm_surface_info_s));
998 info->width = surf->info.width;
999 info->height = surf->info.height;
1000 info->format = surf->info.format;
1001 info->bpp = surf->info.bpp;
1002 info->size = surf->info.size;
1003 info->num_planes = surf->info.num_planes;
1006 for (i = 0; i < surf->num_bos; i++) {
1007 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1008 if (bo_handles[i].ptr == NULL) {
1009 for (j = 0; j < i; j++)
1010 tbm_bo_unmap(surf->bos[j]);
1012 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1013 _tbm_surface_mutex_unlock();
1018 for (i = 0; i < surf->num_bos; i++)
1019 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1022 for (i = 0; i < surf->info.num_planes; i++) {
1023 info->planes[i].size = surf->info.planes[i].size;
1024 info->planes[i].offset = surf->info.planes[i].offset;
1025 info->planes[i].stride = surf->info.planes[i].stride;
1027 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1028 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1029 surf->info.planes[i].offset;
1032 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1034 _tbm_surface_mutex_unlock();
1040 tbm_surface_internal_unmap(tbm_surface_h surface)
1042 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1044 struct _tbm_surface *surf;
1047 _tbm_surface_mutex_lock();
1049 surf = (struct _tbm_surface *)surface;
1051 for (i = 0; i < surf->num_bos; i++)
1052 tbm_bo_unmap(surf->bos[i]);
1054 TBM_TRACE("tbm_surface(%p)\n", surface);
1056 _tbm_surface_mutex_unlock();
1060 tbm_surface_internal_get_width(tbm_surface_h surface)
1062 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1064 struct _tbm_surface *surf;
1067 _tbm_surface_mutex_lock();
1069 surf = (struct _tbm_surface *)surface;
1070 width = surf->info.width;
1072 TBM_TRACE("tbm_surface(%p) width(%d)\n", surface, width);
1074 _tbm_surface_mutex_unlock();
1080 tbm_surface_internal_get_height(tbm_surface_h surface)
1082 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1084 struct _tbm_surface *surf;
1085 unsigned int height;
1087 _tbm_surface_mutex_lock();
1089 surf = (struct _tbm_surface *)surface;
1090 height = surf->info.height;
1092 TBM_TRACE("tbm_surface(%p) height(%d)\n", surface, height);
1094 _tbm_surface_mutex_unlock();
1101 tbm_surface_internal_get_format(tbm_surface_h surface)
1103 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1105 struct _tbm_surface *surf;
1108 _tbm_surface_mutex_lock();
1110 surf = (struct _tbm_surface *)surface;
1111 format = surf->info.format;
1113 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1115 _tbm_surface_mutex_unlock();
1121 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1123 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1124 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1125 struct _tbm_surface *surf;
1128 _tbm_surface_mutex_lock();
1130 surf = (struct _tbm_surface *)surface;
1131 bo_idx = surf->planes_bo_idx[plane_idx];
1133 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1135 _tbm_surface_mutex_unlock();
1141 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1142 tbm_data_free data_free_func)
1144 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1146 tbm_user_data *data;
1148 /* check if the data according to the key exist if so, return false. */
1149 data = user_data_lookup(&surface->user_data_list, key);
1151 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1155 data = user_data_create(key, data_free_func);
1157 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1161 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1163 LIST_ADD(&data->item_link, &surface->user_data_list);
1169 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1172 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1174 tbm_user_data *old_data;
1176 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1177 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1181 old_data = user_data_lookup(&surface->user_data_list, key);
1183 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1187 if (old_data->data && old_data->free_func)
1188 old_data->free_func(old_data->data);
1190 old_data->data = data;
1192 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1198 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1201 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1203 tbm_user_data *old_data;
1205 if (!data || LIST_IS_EMPTY(&surface->user_data_list)) {
1206 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1210 old_data = user_data_lookup(&surface->user_data_list, key);
1212 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1217 *data = old_data->data;
1219 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1225 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1228 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1230 tbm_user_data *old_data = (void *)0;
1232 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1233 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1237 old_data = user_data_lookup(&surface->user_data_list, key);
1239 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1243 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1245 user_data_delete(old_data);
1250 /* LCOV_EXCL_START */
1252 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1254 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1256 return surface->debug_pid;
1260 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1262 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1264 surface->debug_pid = pid;
1267 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1268 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1270 struct _tbm_surface_dump_buf_info {
1280 tbm_surface_info_s info;
1282 struct list_head link;
1285 struct _tbm_surface_dump_info {
1286 char *path; // copy???
1289 struct list_head *link;
1290 struct list_head surface_list; /* link of surface */
1293 static tbm_surface_dump_info *g_dump_info = NULL;
1294 static const char *dump_postfix[2] = {"png", "yuv"};
1297 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1298 int size2, void *data3, int size3)
1300 unsigned int *blocks;
1301 FILE *fp = fopen(file, "w+");
1302 TBM_RETURN_IF_FAIL(fp != NULL);
1304 blocks = (unsigned int *)data1;
1305 fwrite(blocks, 1, size1, fp);
1308 blocks = (unsigned int *)data2;
1309 fwrite(blocks, 1, size2, fp);
1313 blocks = (unsigned int *)data3;
1314 fwrite(blocks, 1, size3, fp);
1321 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1324 FILE *fp = fopen(file, "wb");
1325 TBM_RETURN_IF_FAIL(fp != NULL);
1328 png_structp pPngStruct =
1329 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1335 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1337 png_destroy_write_struct(&pPngStruct, NULL);
1342 png_init_io(pPngStruct, fp);
1343 png_set_IHDR(pPngStruct,
1348 PNG_COLOR_TYPE_RGBA,
1350 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1352 png_set_bgr(pPngStruct);
1353 png_write_info(pPngStruct, pPngInfo);
1355 const int pixel_size = 4; // RGBA
1356 png_bytep *row_pointers =
1357 png_malloc(pPngStruct, height * sizeof(png_byte *));
1359 unsigned int *blocks = (unsigned int *)data;
1363 for (; y < height; ++y) {
1365 png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1366 row_pointers[y] = (png_bytep)row;
1367 for (x = 0; x < width; ++x) {
1368 unsigned int curBlock = blocks[y * width + x];
1369 row[x * pixel_size] = (curBlock & 0xFF);
1370 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1371 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1372 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1376 png_write_image(pPngStruct, row_pointers);
1377 png_write_end(pPngStruct, pPngInfo);
1379 for (y = 0; y < height; y++)
1380 png_free(pPngStruct, row_pointers[y]);
1381 png_free(pPngStruct, row_pointers);
1383 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1389 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1391 TBM_RETURN_IF_FAIL(path != NULL);
1392 TBM_RETURN_IF_FAIL(w > 0);
1393 TBM_RETURN_IF_FAIL(h > 0);
1394 TBM_RETURN_IF_FAIL(count > 0);
1396 tbm_surface_dump_buf_info *buf_info = NULL;
1397 tbm_surface_dump_buf_info *tmp;
1401 tbm_surface_h tbm_surface;
1402 tbm_surface_info_s info;
1403 tbm_surface_error_e err;
1407 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1411 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1412 TBM_RETURN_IF_FAIL(g_dump_info);
1414 LIST_INITHEAD(&g_dump_info->surface_list);
1415 g_dump_info->count = 0;
1416 g_dump_info->dump_max = count;
1418 /* get buffer size */
1419 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1420 if (tbm_surface == NULL) {
1421 TBM_LOG_E("tbm_surface_create fail\n");
1426 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
1427 if (err != TBM_SURFACE_ERROR_NONE) {
1428 TBM_LOG_E("tbm_surface_map fail\n");
1429 tbm_surface_destroy(tbm_surface);
1434 buffer_size = info.planes[0].stride * h;
1435 tbm_surface_unmap(tbm_surface);
1436 tbm_surface_destroy(tbm_surface);
1438 /* create dump lists */
1439 for (i = 0; i < count; i++) {
1440 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1441 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1442 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1448 buf_info->index = i;
1450 buf_info->size = buffer_size;
1452 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1455 g_dump_info->path = path;
1456 g_dump_info->link = &g_dump_info->surface_list;
1458 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1462 /* free resources */
1463 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1464 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1465 tbm_bo_unref(buf_info->bo);
1470 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1479 tbm_surface_internal_dump_end(void)
1481 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1482 tbm_bo_handle bo_handle;
1488 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1489 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1492 if (buf_info->dirty) {
1496 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1497 if (bo_handle.ptr == NULL)
1500 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1501 TBM_LOG_I("Dump File.. %s generated.\n", file);
1503 switch (buf_info->info.format) {
1504 case TBM_FORMAT_ARGB8888:
1505 case TBM_FORMAT_XRGB8888:
1506 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1507 buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1509 case TBM_FORMAT_YVU420:
1510 case TBM_FORMAT_YUV420:
1511 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1512 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1513 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1514 buf_info->info.planes[0].stride * buf_info->info.height,
1516 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1518 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1520 case TBM_FORMAT_NV12:
1521 case TBM_FORMAT_NV21:
1522 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1523 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1524 buf_info->info.planes[0].stride * buf_info->info.height,
1526 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1529 case TBM_FORMAT_YUYV:
1530 case TBM_FORMAT_UYVY:
1531 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1532 buf_info->info.planes[0].stride * buf_info->info.height,
1536 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1537 tbm_bo_unmap(buf_info->bo);
1541 tbm_bo_unmap(buf_info->bo);
1542 } else if (buf_info->dirty_shm) {
1543 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1544 if (bo_handle.ptr == NULL)
1547 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1548 TBM_LOG_I("Dump File.. %s generated.\n", file);
1550 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1551 buf_info->shm_stride >> 2, buf_info->shm_h);
1553 tbm_bo_unmap(buf_info->bo);
1559 /* free resources */
1560 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1561 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1562 tbm_bo_unref(buf_info->bo);
1570 TBM_LOG_I("Dump End..\n");
1574 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1576 TBM_RETURN_IF_FAIL(surface != NULL);
1577 TBM_RETURN_IF_FAIL(type != NULL);
1579 tbm_surface_dump_buf_info *buf_info;
1580 tbm_surface_info_s info;
1581 struct list_head *next_link;
1582 tbm_bo_handle bo_handle;
1584 const char *postfix;
1589 next_link = g_dump_info->link->next;
1590 TBM_RETURN_IF_FAIL(next_link != NULL);
1592 if (next_link == &g_dump_info->surface_list) {
1593 next_link = next_link->next;
1594 TBM_RETURN_IF_FAIL(next_link != NULL);
1597 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1598 TBM_RETURN_IF_FAIL(buf_info != NULL);
1600 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1601 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1603 if (info.size > buf_info->size) {
1604 TBM_LOG_W("Dump skip. surface over created buffer size(%d, %d)\n", info.size, buf_info->size);
1605 tbm_surface_unmap(surface);
1609 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1610 postfix = dump_postfix[0];
1612 postfix = dump_postfix[1];
1614 /* make the file information */
1615 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1618 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1619 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1620 memset(bo_handle.ptr, 0x00, buf_info->size);
1622 switch (info.format) {
1623 case TBM_FORMAT_ARGB8888:
1624 case TBM_FORMAT_XRGB8888:
1625 snprintf(buf_info->name, sizeof(buf_info->name), "%.3f_%03d_%p-%s.%s", _get_time_in_millis() / 1000.0, g_dump_info->count++, surface, type, postfix);
1626 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1628 case TBM_FORMAT_YVU420:
1629 case TBM_FORMAT_YUV420:
1630 snprintf(buf_info->name, sizeof(buf_info->name), "%03d-%s_%dx%d_%c%c%c%c.%s",
1631 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1632 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1633 bo_handle.ptr += info.planes[0].stride * info.height;
1634 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1635 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1636 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1638 case TBM_FORMAT_NV12:
1639 case TBM_FORMAT_NV21:
1640 snprintf(buf_info->name, sizeof(buf_info->name), "%03d-%s_%dx%d_%c%c%c%c.%s",
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));
1646 case TBM_FORMAT_YUYV:
1647 case TBM_FORMAT_UYVY:
1648 snprintf(buf_info->name, sizeof(buf_info->name), "%03d-%s_%dx%d_%c%c%c%c.%s",
1649 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1650 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1653 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1654 tbm_bo_unmap(buf_info->bo);
1658 tbm_bo_unmap(buf_info->bo);
1660 tbm_surface_unmap(surface);
1662 buf_info->dirty = 1;
1663 buf_info->dirty_shm = 0;
1665 if (g_dump_info->count == 1000)
1666 g_dump_info->count = 0;
1668 g_dump_info->link = next_link;
1670 TBM_LOG_I("Dump %s \n", buf_info->name);
1673 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, const char *type)
1675 TBM_RETURN_IF_FAIL(ptr != NULL);
1676 TBM_RETURN_IF_FAIL(w > 0);
1677 TBM_RETURN_IF_FAIL(h > 0);
1678 TBM_RETURN_IF_FAIL(stride > 0);
1679 TBM_RETURN_IF_FAIL(type != NULL);
1681 tbm_surface_dump_buf_info *buf_info;
1682 struct list_head *next_link;
1683 tbm_bo_handle bo_handle;
1688 next_link = g_dump_info->link->next;
1689 TBM_RETURN_IF_FAIL(next_link != NULL);
1691 if (next_link == &g_dump_info->surface_list) {
1692 next_link = next_link->next;
1693 TBM_RETURN_IF_FAIL(next_link != NULL);
1696 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1697 TBM_RETURN_IF_FAIL(buf_info != NULL);
1699 if (stride * h > buf_info->size) {
1700 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", stride * h, buf_info->size);
1705 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1706 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1707 memset(bo_handle.ptr, 0x00, buf_info->size);
1708 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1711 snprintf(buf_info->name, sizeof(buf_info->name), "%03d-%s.%s", g_dump_info->count++, type, dump_postfix[0]);
1712 memcpy(bo_handle.ptr, ptr, stride * h);
1714 tbm_bo_unmap(buf_info->bo);
1716 buf_info->dirty = 0;
1717 buf_info->dirty_shm = 1;
1718 buf_info->shm_stride = stride;
1719 buf_info->shm_h = h;
1721 if (g_dump_info->count == 1000)
1722 g_dump_info->count = 0;
1724 g_dump_info->link = next_link;
1726 TBM_LOG_I("Dump %s \n", buf_info->name);
1729 void tbm_surface_internal_dump_all(char *path)
1731 TBM_RETURN_IF_FAIL(path != NULL);
1732 int w = 0, h = 0, count = 0;
1733 tbm_surface_h surface = NULL, tmp = NULL;
1735 count = _tbm_surface_get_max_size(&w, &h);
1737 TBM_LOG_I("No tbm_surface.\n");
1741 tbm_surface_internal_dump_start(path, w, h, count);
1743 LIST_FOR_EACH_ENTRY_SAFE(surface, tmp, &g_surface_bufmgr->surf_list, item_link) {
1744 tbm_surface_internal_dump_buffer(surface, "dump_all");
1747 tbm_surface_internal_dump_end();