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 **************************************************************************/
37 #include "tbm_bufmgr.h"
38 #include "tbm_bufmgr_int.h"
39 #include "tbm_surface_internal.h"
43 static tbm_bufmgr g_surface_bufmgr;
44 static pthread_mutex_t tbm_surface_lock;
45 void _tbm_surface_mutex_unlock(void);
47 #define C(b, m) (((b) >> (m)) & 0xFF)
48 #define B(c, s) ((((unsigned int)(c)) & 0xff) << (s))
49 #define FOURCC(a, b, c, d) (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
50 #define FOURCC_STR(id) C(id, 0), C(id, 8), C(id, 16), C(id, 24)
51 #define FOURCC_ID(str) FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
54 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
56 TBM_LOG_E("'%s' failed.\n", #cond);\
57 _tbm_surface_mutex_unlock();\
62 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
64 TBM_LOG_E("'%s' failed.\n", #cond);\
65 _tbm_surface_mutex_unlock();\
73 _tbm_surface_internal_get_time(void)
78 clock_gettime(CLOCK_MONOTONIC, &tp);
79 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
85 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
87 LIST_DEL(&debug_data->item_link);
89 if (debug_data->key) free(debug_data->key);
90 if (debug_data->value) free(debug_data->value);
95 _tbm_surface_internal_format_to_str(tbm_format format)
99 return "TBM_FORMAT_C8";
100 case TBM_FORMAT_RGB332:
101 return "TBM_FORMAT_RGB332";
102 case TBM_FORMAT_BGR233:
103 return "TBM_FORMAT_BGR233";
104 case TBM_FORMAT_XRGB4444:
105 return "TBM_FORMAT_XRGB4444";
106 case TBM_FORMAT_XBGR4444:
107 return "TBM_FORMAT_XBGR4444";
108 case TBM_FORMAT_RGBX4444:
109 return "TBM_FORMAT_RGBX4444";
110 case TBM_FORMAT_BGRX4444:
111 return "TBM_FORMAT_BGRX4444";
112 case TBM_FORMAT_ARGB4444:
113 return "TBM_FORMAT_ARGB4444";
114 case TBM_FORMAT_ABGR4444:
115 return "TBM_FORMAT_ABGR4444";
116 case TBM_FORMAT_RGBA4444:
117 return "TBM_FORMAT_RGBA4444";
118 case TBM_FORMAT_BGRA4444:
119 return "TBM_FORMAT_BGRA4444";
120 case TBM_FORMAT_XRGB1555:
121 return "TBM_FORMAT_XRGB1555";
122 case TBM_FORMAT_XBGR1555:
123 return "TBM_FORMAT_XBGR1555";
124 case TBM_FORMAT_RGBX5551:
125 return "TBM_FORMAT_RGBX5551";
126 case TBM_FORMAT_BGRX5551:
127 return "TBM_FORMAT_BGRX5551";
128 case TBM_FORMAT_ARGB1555:
129 return "TBM_FORMAT_ARGB1555";
130 case TBM_FORMAT_ABGR1555:
131 return "TBM_FORMAT_ABGR1555";
132 case TBM_FORMAT_RGBA5551:
133 return "TBM_FORMAT_RGBA5551";
134 case TBM_FORMAT_BGRA5551:
135 return "TBM_FORMAT_BGRA5551";
136 case TBM_FORMAT_RGB565:
137 return "TBM_FORMAT_RGB565";
138 case TBM_FORMAT_BGR565:
139 return "TBM_FORMAT_BGR565";
140 case TBM_FORMAT_RGB888:
141 return "TBM_FORMAT_RGB888";
142 case TBM_FORMAT_BGR888:
143 return "TBM_FORMAT_BGR888";
144 case TBM_FORMAT_XRGB8888:
145 return "TBM_FORMAT_XRGB8888";
146 case TBM_FORMAT_XBGR8888:
147 return "TBM_FORMAT_XBGR8888";
148 case TBM_FORMAT_RGBX8888:
149 return "TBM_FORMAT_RGBX8888";
150 case TBM_FORMAT_BGRX8888:
151 return "TBM_FORMAT_BGRX8888";
152 case TBM_FORMAT_ARGB8888:
153 return "TBM_FORMAT_ARGB8888";
154 case TBM_FORMAT_ABGR8888:
155 return "TBM_FORMAT_ABGR8888";
156 case TBM_FORMAT_RGBA8888:
157 return "TBM_FORMAT_RGBA8888";
158 case TBM_FORMAT_BGRA8888:
159 return "TBM_FORMAT_BGRA8888";
160 case TBM_FORMAT_XRGB2101010:
161 return "TBM_FORMAT_XRGB2101010";
162 case TBM_FORMAT_XBGR2101010:
163 return "TBM_FORMAT_XBGR2101010";
164 case TBM_FORMAT_RGBX1010102:
165 return "TBM_FORMAT_RGBX1010102";
166 case TBM_FORMAT_BGRX1010102:
167 return "TBM_FORMAT_BGRX1010102";
168 case TBM_FORMAT_ARGB2101010:
169 return "TBM_FORMAT_ARGB2101010";
170 case TBM_FORMAT_ABGR2101010:
171 return "TBM_FORMAT_ABGR2101010";
172 case TBM_FORMAT_RGBA1010102:
173 return "TBM_FORMAT_RGBA1010102";
174 case TBM_FORMAT_BGRA1010102:
175 return "TBM_FORMAT_BGRA1010102";
176 case TBM_FORMAT_YUYV:
177 return "TBM_FORMAT_YUYV";
178 case TBM_FORMAT_YVYU:
179 return "TBM_FORMAT_YVYU";
180 case TBM_FORMAT_UYVY:
181 return "TBM_FORMAT_UYVY";
182 case TBM_FORMAT_VYUY:
183 return "TBM_FORMAT_VYUY";
184 case TBM_FORMAT_AYUV:
185 return "TBM_FORMAT_AYUV";
186 case TBM_FORMAT_NV12:
187 return "TBM_FORMAT_NV12";
188 case TBM_FORMAT_NV21:
189 return "TBM_FORMAT_NV21";
190 case TBM_FORMAT_NV16:
191 return "TBM_FORMAT_NV16";
192 case TBM_FORMAT_NV61:
193 return "TBM_FORMAT_NV61";
194 case TBM_FORMAT_YUV410:
195 return "TBM_FORMAT_YUV410";
196 case TBM_FORMAT_YVU410:
197 return "TBM_FORMAT_YVU410";
198 case TBM_FORMAT_YUV411:
199 return "TBM_FORMAT_YUV411";
200 case TBM_FORMAT_YVU411:
201 return "TBM_FORMAT_YVU411";
202 case TBM_FORMAT_YUV420:
203 return "TBM_FORMAT_YUV420";
204 case TBM_FORMAT_YVU420:
205 return "TBM_FORMAT_YVU420";
206 case TBM_FORMAT_YUV422:
207 return "TBM_FORMAT_YUV422";
208 case TBM_FORMAT_YVU422:
209 return "TBM_FORMAT_YVU422";
210 case TBM_FORMAT_YUV444:
211 return "TBM_FORMAT_YUV444";
212 case TBM_FORMAT_YVU444:
213 return "TBM_FORMAT_YVU444";
214 case TBM_FORMAT_NV12MT:
215 return "TBM_FORMAT_NV12MT";
223 _tbm_surface_mutex_init(void)
225 static bool tbm_surface_mutex_init = false;
227 if (tbm_surface_mutex_init)
230 if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
231 TBM_LOG_E("fail: pthread_mutex_init for tbm_surface_lock.\n");
235 tbm_surface_mutex_init = true;
241 _tbm_surface_mutex_lock(void)
243 if (!_tbm_surface_mutex_init()) {
244 TBM_LOG_E("fail: _tbm_surface_mutex_init.\n");
248 pthread_mutex_lock(&tbm_surface_lock);
252 _tbm_surface_mutex_unlock(void)
254 pthread_mutex_unlock(&tbm_surface_lock);
258 _init_surface_bufmgr(void)
260 g_surface_bufmgr = tbm_bufmgr_init(-1);
264 _deinit_surface_bufmgr(void)
266 if (!g_surface_bufmgr)
269 tbm_bufmgr_deinit(g_surface_bufmgr);
270 g_surface_bufmgr = NULL;
274 _tbm_surface_internal_is_valid(tbm_surface_h surface)
276 tbm_surface_h old_data = NULL;
278 TBM_RETURN_VAL_IF_FAIL(g_surface_bufmgr, 0);
279 TBM_RETURN_VAL_IF_FAIL(surface, 0);
281 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
282 LIST_FOR_EACH_ENTRY(old_data, &g_surface_bufmgr->surf_list, item_link) {
283 if (old_data == surface) {
284 TBM_TRACE("tbm_surface(%p)\n", surface);
290 TBM_LOG_E("error: No valid tbm_surface(%p)\n", surface);
296 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
297 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
299 TBM_RETURN_VAL_IF_FAIL(surface, 0);
300 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
302 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
303 struct _tbm_bufmgr *mgr = surf->bufmgr;
306 TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
307 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
308 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
309 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
311 if (!mgr->backend->surface_get_plane_data)
314 ret = mgr->backend->surface_get_plane_data(surf->info.width,
315 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
317 TBM_LOG_E("Fail to surface_get_plane_data. surface(%p)\n", surface);
325 _tbm_surface_internal_destroy(tbm_surface_h surface)
328 tbm_bufmgr bufmgr = surface->bufmgr;
329 tbm_user_data *old_data = NULL, *tmp = NULL;
330 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
332 /* destory the user_data_list */
333 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
334 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
335 TBM_DBG("free user_data\n");
336 user_data_delete(old_data);
340 for (i = 0; i < surface->num_bos; i++) {
341 surface->bos[i]->surface = NULL;
343 tbm_bo_unref(surface->bos[i]);
344 surface->bos[i] = NULL;
347 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
348 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
349 _tbm_surface_internal_debug_data_delete(debug_old_data);
352 LIST_DEL(&surface->item_link);
357 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
358 LIST_DELINIT(&bufmgr->surf_list);
360 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
361 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
362 _tbm_surface_internal_debug_data_delete(debug_old_data);
366 _deinit_surface_bufmgr();
371 tbm_surface_internal_is_valid(tbm_surface_h surface)
375 _tbm_surface_mutex_lock();
377 /* Return silently if surface is null. */
379 _tbm_surface_mutex_unlock();
383 ret = _tbm_surface_internal_is_valid(surface);
385 _tbm_surface_mutex_unlock();
391 tbm_surface_internal_query_supported_formats(uint32_t **formats,
394 struct _tbm_bufmgr *mgr;
396 bool bufmgr_initialized = false;
398 _tbm_surface_mutex_lock();
400 if (!g_surface_bufmgr) {
401 _init_surface_bufmgr();
402 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
403 bufmgr_initialized = true;
406 mgr = g_surface_bufmgr;
408 if (!mgr->backend->surface_supported_format)
411 ret = mgr->backend->surface_supported_format(formats, num);
413 TBM_LOG_E("Fail to surface_supported_format.\n");
417 TBM_TRACE("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
419 _tbm_surface_mutex_unlock();
424 if (bufmgr_initialized) {
425 LIST_DELINIT(&g_surface_bufmgr->surf_list);
426 _deinit_surface_bufmgr();
428 _tbm_surface_mutex_unlock();
430 TBM_LOG_E("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
436 tbm_surface_internal_get_num_planes(tbm_format format)
442 case TBM_FORMAT_RGB332:
443 case TBM_FORMAT_BGR233:
444 case TBM_FORMAT_XRGB4444:
445 case TBM_FORMAT_XBGR4444:
446 case TBM_FORMAT_RGBX4444:
447 case TBM_FORMAT_BGRX4444:
448 case TBM_FORMAT_ARGB4444:
449 case TBM_FORMAT_ABGR4444:
450 case TBM_FORMAT_RGBA4444:
451 case TBM_FORMAT_BGRA4444:
452 case TBM_FORMAT_XRGB1555:
453 case TBM_FORMAT_XBGR1555:
454 case TBM_FORMAT_RGBX5551:
455 case TBM_FORMAT_BGRX5551:
456 case TBM_FORMAT_ARGB1555:
457 case TBM_FORMAT_ABGR1555:
458 case TBM_FORMAT_RGBA5551:
459 case TBM_FORMAT_BGRA5551:
460 case TBM_FORMAT_RGB565:
461 case TBM_FORMAT_BGR565:
462 case TBM_FORMAT_RGB888:
463 case TBM_FORMAT_BGR888:
464 case TBM_FORMAT_XRGB8888:
465 case TBM_FORMAT_XBGR8888:
466 case TBM_FORMAT_RGBX8888:
467 case TBM_FORMAT_BGRX8888:
468 case TBM_FORMAT_ARGB8888:
469 case TBM_FORMAT_ABGR8888:
470 case TBM_FORMAT_RGBA8888:
471 case TBM_FORMAT_BGRA8888:
472 case TBM_FORMAT_XRGB2101010:
473 case TBM_FORMAT_XBGR2101010:
474 case TBM_FORMAT_RGBX1010102:
475 case TBM_FORMAT_BGRX1010102:
476 case TBM_FORMAT_ARGB2101010:
477 case TBM_FORMAT_ABGR2101010:
478 case TBM_FORMAT_RGBA1010102:
479 case TBM_FORMAT_BGRA1010102:
480 case TBM_FORMAT_YUYV:
481 case TBM_FORMAT_YVYU:
482 case TBM_FORMAT_UYVY:
483 case TBM_FORMAT_VYUY:
484 case TBM_FORMAT_AYUV:
487 case TBM_FORMAT_NV12:
488 case TBM_FORMAT_NV12MT:
489 case TBM_FORMAT_NV21:
490 case TBM_FORMAT_NV16:
491 case TBM_FORMAT_NV61:
494 case TBM_FORMAT_YUV410:
495 case TBM_FORMAT_YVU410:
496 case TBM_FORMAT_YUV411:
497 case TBM_FORMAT_YVU411:
498 case TBM_FORMAT_YUV420:
499 case TBM_FORMAT_YVU420:
500 case TBM_FORMAT_YUV422:
501 case TBM_FORMAT_YVU422:
502 case TBM_FORMAT_YUV444:
503 case TBM_FORMAT_YVU444:
511 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
517 tbm_surface_internal_get_bpp(tbm_format format)
524 case TBM_FORMAT_RGB332:
525 case TBM_FORMAT_BGR233:
528 case TBM_FORMAT_XRGB4444:
529 case TBM_FORMAT_XBGR4444:
530 case TBM_FORMAT_RGBX4444:
531 case TBM_FORMAT_BGRX4444:
532 case TBM_FORMAT_ARGB4444:
533 case TBM_FORMAT_ABGR4444:
534 case TBM_FORMAT_RGBA4444:
535 case TBM_FORMAT_BGRA4444:
536 case TBM_FORMAT_XRGB1555:
537 case TBM_FORMAT_XBGR1555:
538 case TBM_FORMAT_RGBX5551:
539 case TBM_FORMAT_BGRX5551:
540 case TBM_FORMAT_ARGB1555:
541 case TBM_FORMAT_ABGR1555:
542 case TBM_FORMAT_RGBA5551:
543 case TBM_FORMAT_BGRA5551:
544 case TBM_FORMAT_RGB565:
545 case TBM_FORMAT_BGR565:
548 case TBM_FORMAT_RGB888:
549 case TBM_FORMAT_BGR888:
552 case TBM_FORMAT_XRGB8888:
553 case TBM_FORMAT_XBGR8888:
554 case TBM_FORMAT_RGBX8888:
555 case TBM_FORMAT_BGRX8888:
556 case TBM_FORMAT_ARGB8888:
557 case TBM_FORMAT_ABGR8888:
558 case TBM_FORMAT_RGBA8888:
559 case TBM_FORMAT_BGRA8888:
560 case TBM_FORMAT_XRGB2101010:
561 case TBM_FORMAT_XBGR2101010:
562 case TBM_FORMAT_RGBX1010102:
563 case TBM_FORMAT_BGRX1010102:
564 case TBM_FORMAT_ARGB2101010:
565 case TBM_FORMAT_ABGR2101010:
566 case TBM_FORMAT_RGBA1010102:
567 case TBM_FORMAT_BGRA1010102:
568 case TBM_FORMAT_YUYV:
569 case TBM_FORMAT_YVYU:
570 case TBM_FORMAT_UYVY:
571 case TBM_FORMAT_VYUY:
572 case TBM_FORMAT_AYUV:
575 case TBM_FORMAT_NV12:
576 case TBM_FORMAT_NV12MT:
577 case TBM_FORMAT_NV21:
580 case TBM_FORMAT_NV16:
581 case TBM_FORMAT_NV61:
584 case TBM_FORMAT_YUV410:
585 case TBM_FORMAT_YVU410:
588 case TBM_FORMAT_YUV411:
589 case TBM_FORMAT_YVU411:
590 case TBM_FORMAT_YUV420:
591 case TBM_FORMAT_YVU420:
594 case TBM_FORMAT_YUV422:
595 case TBM_FORMAT_YVU422:
598 case TBM_FORMAT_YUV444:
599 case TBM_FORMAT_YVU444:
606 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
612 tbm_surface_internal_create_with_flags(int width, int height,
613 int format, int flags)
615 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
616 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
618 struct _tbm_bufmgr *mgr;
619 struct _tbm_surface *surf = NULL;
623 uint32_t bo_size = 0;
626 bool bufmgr_initialized = false;
628 _tbm_surface_mutex_lock();
630 if (!g_surface_bufmgr) {
631 _init_surface_bufmgr();
632 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
633 bufmgr_initialized = true;
636 mgr = g_surface_bufmgr;
637 if (!TBM_BUFMGR_IS_VALID(mgr)) {
638 TBM_LOG_E("The bufmgr is invalid\n");
639 goto check_valid_fail;
642 surf = calloc(1, sizeof(struct _tbm_surface));
644 TBM_LOG_E("fail to alloc surf\n");
645 goto alloc_surf_fail;
649 surf->info.width = width;
650 surf->info.height = height;
651 surf->info.format = format;
652 surf->info.bpp = tbm_surface_internal_get_bpp(format);
653 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
656 /* get size, stride and offset bo_idx */
657 for (i = 0; i < surf->info.num_planes; i++) {
658 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
659 &offset, &stride, &bo_idx)) {
660 TBM_LOG_E("fail to query plane data\n");
661 goto query_plane_data_fail;
664 surf->info.planes[i].size = size;
665 surf->info.planes[i].offset = offset;
666 surf->info.planes[i].stride = stride;
667 surf->planes_bo_idx[i] = bo_idx;
672 for (i = 0; i < surf->info.num_planes; i++) {
673 surf->info.size += surf->info.planes[i].size;
675 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
676 surf->num_bos = surf->planes_bo_idx[i] + 1;
681 for (i = 0; i < surf->num_bos; i++) {
683 for (j = 0; j < surf->info.num_planes; j++) {
684 if (surf->planes_bo_idx[j] == i)
685 bo_size += surf->info.planes[j].size;
688 if (mgr->backend->surface_bo_alloc) {
689 /* LCOV_EXCL_START */
691 void *bo_priv = NULL;
693 bo = calloc(1, sizeof(struct _tbm_bo));
695 TBM_LOG_E("fail to alloc bo struct\n");
699 bo->bufmgr = surf->bufmgr;
701 pthread_mutex_lock(&surf->bufmgr->lock);
703 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
705 TBM_LOG_E("fail to alloc bo priv\n");
707 pthread_mutex_unlock(&surf->bufmgr->lock);
715 LIST_INITHEAD(&bo->user_data_list);
717 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
719 pthread_mutex_unlock(&surf->bufmgr->lock);
724 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
726 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
731 _tbm_bo_set_surface(surf->bos[i], surf);
734 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
735 _tbm_surface_internal_format_to_str(format), flags, surf);
737 LIST_INITHEAD(&surf->user_data_list);
738 LIST_INITHEAD(&surf->debug_data_list);
740 LIST_ADD(&surf->item_link, &mgr->surf_list);
742 _tbm_surface_mutex_unlock();
747 for (j = 0; j < i; j++) {
749 tbm_bo_unref(surf->bos[j]);
751 query_plane_data_fail:
755 if (bufmgr_initialized && mgr) {
756 LIST_DELINIT(&mgr->surf_list);
757 _deinit_surface_bufmgr();
759 _tbm_surface_mutex_unlock();
761 TBM_LOG_E("error: width(%d) height(%d) format(%s) flags(%d)\n",
763 _tbm_surface_internal_format_to_str(format), flags);
769 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
770 tbm_bo *bos, int num)
772 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
773 TBM_RETURN_VAL_IF_FAIL(info, NULL);
774 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
776 struct _tbm_bufmgr *mgr;
777 struct _tbm_surface *surf = NULL;
779 bool bufmgr_initialized = false;
781 _tbm_surface_mutex_lock();
783 if (!g_surface_bufmgr) {
784 _init_surface_bufmgr();
785 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
786 bufmgr_initialized = true;
789 mgr = g_surface_bufmgr;
790 if (!TBM_BUFMGR_IS_VALID(mgr)) {
791 TBM_LOG_E("fail to validate the Bufmgr.\n");
792 goto check_valid_fail;
795 surf = calloc(1, sizeof(struct _tbm_surface));
797 TBM_LOG_E("fail to allocate struct _tbm_surface.\n");
798 goto alloc_surf_fail;
802 surf->info.width = info->width;
803 surf->info.height = info->height;
804 surf->info.format = info->format;
805 surf->info.bpp = info->bpp;
806 surf->info.num_planes = info->num_planes;
809 /* get size, stride and offset */
810 for (i = 0; i < info->num_planes; i++) {
811 surf->info.planes[i].offset = info->planes[i].offset;
812 surf->info.planes[i].stride = info->planes[i].stride;
814 if (info->planes[i].size > 0)
815 surf->info.planes[i].size = info->planes[i].size;
817 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
820 surf->planes_bo_idx[i] = 0;
822 surf->planes_bo_idx[i] = i;
825 if (info->size > 0) {
826 surf->info.size = info->size;
829 for (i = 0; i < info->num_planes; i++)
830 surf->info.size += surf->info.planes[i].size;
833 surf->flags = TBM_BO_DEFAULT;
835 /* create only one bo */
837 for (i = 0; i < num; i++) {
838 if (bos[i] == NULL) {
839 TBM_LOG_E("bos[%d] is null.\n", i);
843 surf->bos[i] = tbm_bo_ref(bos[i]);
844 _tbm_bo_set_surface(bos[i], surf);
847 TBM_TRACE("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
848 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
850 LIST_INITHEAD(&surf->user_data_list);
851 LIST_INITHEAD(&surf->debug_data_list);
853 LIST_ADD(&surf->item_link, &mgr->surf_list);
855 _tbm_surface_mutex_unlock();
860 for (i = 0; i < num; i++) {
862 tbm_bo_unref(surf->bos[i]);
867 if (bufmgr_initialized && mgr) {
868 LIST_DELINIT(&mgr->surf_list);
869 _deinit_surface_bufmgr();
871 _tbm_surface_mutex_unlock();
873 TBM_LOG_E("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
874 info->width, info->height,
875 _tbm_surface_internal_format_to_str(info->format), num);
881 tbm_surface_internal_destroy(tbm_surface_h surface)
883 _tbm_surface_mutex_lock();
885 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
889 if (surface->refcnt > 0) {
890 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
891 _tbm_surface_mutex_unlock();
895 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
897 if (surface->refcnt == 0)
898 _tbm_surface_internal_destroy(surface);
900 _tbm_surface_mutex_unlock();
904 tbm_surface_internal_ref(tbm_surface_h surface)
906 _tbm_surface_mutex_lock();
908 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
912 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
914 _tbm_surface_mutex_unlock();
918 tbm_surface_internal_unref(tbm_surface_h surface)
920 _tbm_surface_mutex_lock();
922 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
926 if (surface->refcnt > 0) {
927 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
928 _tbm_surface_mutex_unlock();
932 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
934 if (surface->refcnt == 0)
935 _tbm_surface_internal_destroy(surface);
937 _tbm_surface_mutex_unlock();
941 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
943 struct _tbm_surface *surf;
946 _tbm_surface_mutex_lock();
948 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
950 surf = (struct _tbm_surface *)surface;
953 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
955 _tbm_surface_mutex_unlock();
961 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
963 struct _tbm_surface *surf;
966 _tbm_surface_mutex_lock();
968 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
969 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
971 surf = (struct _tbm_surface *)surface;
972 bo = surf->bos[bo_idx];
974 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
976 _tbm_surface_mutex_unlock();
982 tbm_surface_internal_get_size(tbm_surface_h surface)
984 struct _tbm_surface *surf;
987 _tbm_surface_mutex_lock();
989 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
991 surf = (struct _tbm_surface *)surface;
992 size = surf->info.size;
994 TBM_TRACE("tbm_surface(%p) size(%u)\n", surface, size);
996 _tbm_surface_mutex_unlock();
1002 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1003 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1005 struct _tbm_surface *surf;
1007 _tbm_surface_mutex_lock();
1009 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1010 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1012 surf = (struct _tbm_surface *)surface;
1014 if (plane_idx >= surf->info.num_planes) {
1015 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1016 _tbm_surface_mutex_unlock();
1021 *size = surf->info.planes[plane_idx].size;
1024 *offset = surf->info.planes[plane_idx].offset;
1027 *pitch = surf->info.planes[plane_idx].stride;
1029 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1030 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1031 surf->info.planes[plane_idx].stride);
1033 _tbm_surface_mutex_unlock();
1039 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1040 tbm_surface_info_s *info, int map)
1042 struct _tbm_surface *surf;
1043 tbm_bo_handle bo_handles[4];
1046 _tbm_surface_mutex_lock();
1048 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1050 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1052 surf = (struct _tbm_surface *)surface;
1054 memset(info, 0x00, sizeof(tbm_surface_info_s));
1055 info->width = surf->info.width;
1056 info->height = surf->info.height;
1057 info->format = surf->info.format;
1058 info->bpp = surf->info.bpp;
1059 info->size = surf->info.size;
1060 info->num_planes = surf->info.num_planes;
1063 for (i = 0; i < surf->num_bos; i++) {
1064 _tbm_surface_mutex_unlock();
1065 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1066 _tbm_surface_mutex_lock();
1067 if (bo_handles[i].ptr == NULL) {
1068 for (j = 0; j < i; j++)
1069 tbm_bo_unmap(surf->bos[j]);
1071 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1072 _tbm_surface_mutex_unlock();
1077 for (i = 0; i < surf->num_bos; i++) {
1078 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1079 if (bo_handles[i].ptr == NULL) {
1080 TBM_LOG_E("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1081 _tbm_surface_mutex_unlock();
1087 for (i = 0; i < surf->info.num_planes; i++) {
1088 info->planes[i].size = surf->info.planes[i].size;
1089 info->planes[i].offset = surf->info.planes[i].offset;
1090 info->planes[i].stride = surf->info.planes[i].stride;
1092 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1093 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1094 surf->info.planes[i].offset;
1097 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1099 _tbm_surface_mutex_unlock();
1105 tbm_surface_internal_unmap(tbm_surface_h surface)
1107 struct _tbm_surface *surf;
1110 _tbm_surface_mutex_lock();
1112 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1114 surf = (struct _tbm_surface *)surface;
1116 for (i = 0; i < surf->num_bos; i++)
1117 tbm_bo_unmap(surf->bos[i]);
1119 TBM_TRACE("tbm_surface(%p)\n", surface);
1121 _tbm_surface_mutex_unlock();
1125 tbm_surface_internal_get_width(tbm_surface_h surface)
1127 struct _tbm_surface *surf;
1130 _tbm_surface_mutex_lock();
1132 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1134 surf = (struct _tbm_surface *)surface;
1135 width = surf->info.width;
1137 TBM_TRACE("tbm_surface(%p) width(%u)\n", surface, width);
1139 _tbm_surface_mutex_unlock();
1145 tbm_surface_internal_get_height(tbm_surface_h surface)
1147 struct _tbm_surface *surf;
1148 unsigned int height;
1150 _tbm_surface_mutex_lock();
1152 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1154 surf = (struct _tbm_surface *)surface;
1155 height = surf->info.height;
1157 TBM_TRACE("tbm_surface(%p) height(%u)\n", surface, height);
1159 _tbm_surface_mutex_unlock();
1166 tbm_surface_internal_get_format(tbm_surface_h surface)
1168 struct _tbm_surface *surf;
1171 _tbm_surface_mutex_lock();
1173 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1175 surf = (struct _tbm_surface *)surface;
1176 format = surf->info.format;
1178 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1180 _tbm_surface_mutex_unlock();
1186 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1188 struct _tbm_surface *surf;
1191 _tbm_surface_mutex_lock();
1193 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1194 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1196 surf = (struct _tbm_surface *)surface;
1197 bo_idx = surf->planes_bo_idx[plane_idx];
1199 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1201 _tbm_surface_mutex_unlock();
1207 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1208 tbm_data_free data_free_func)
1210 tbm_user_data *data;
1212 _tbm_surface_mutex_lock();
1214 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1216 /* check if the data according to the key exist if so, return false. */
1217 data = user_data_lookup(&surface->user_data_list, key);
1219 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1220 _tbm_surface_mutex_unlock();
1224 data = user_data_create(key, data_free_func);
1226 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1227 _tbm_surface_mutex_unlock();
1231 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1233 LIST_ADD(&data->item_link, &surface->user_data_list);
1235 _tbm_surface_mutex_unlock();
1241 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1244 tbm_user_data *old_data;
1246 _tbm_surface_mutex_lock();
1248 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1250 old_data = user_data_lookup(&surface->user_data_list, key);
1252 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1253 _tbm_surface_mutex_unlock();
1257 if (old_data->data && old_data->free_func)
1258 old_data->free_func(old_data->data);
1260 old_data->data = data;
1262 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1264 _tbm_surface_mutex_unlock();
1270 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1273 tbm_user_data *old_data;
1275 _tbm_surface_mutex_lock();
1277 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1280 TBM_LOG_E("error: tbm_surface(%p) key(%lu)\n", surface, key);
1281 _tbm_surface_mutex_unlock();
1286 old_data = user_data_lookup(&surface->user_data_list, key);
1288 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1289 _tbm_surface_mutex_unlock();
1293 *data = old_data->data;
1295 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1297 _tbm_surface_mutex_unlock();
1303 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1306 tbm_user_data *old_data = (void *)0;
1308 _tbm_surface_mutex_lock();
1310 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1312 old_data = user_data_lookup(&surface->user_data_list, key);
1314 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1315 _tbm_surface_mutex_unlock();
1319 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1321 user_data_delete(old_data);
1323 _tbm_surface_mutex_unlock();
1328 /* LCOV_EXCL_START */
1330 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1332 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1334 return surface->debug_pid;
1338 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1340 _tbm_surface_mutex_lock();
1342 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1344 surface->debug_pid = pid;
1346 _tbm_surface_mutex_unlock();
1349 static tbm_surface_debug_data *
1350 _tbm_surface_internal_debug_data_create(char *key, char *value)
1352 tbm_surface_debug_data *debug_data = NULL;
1354 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1358 if (key) debug_data->key = strdup(key);
1359 if (value) debug_data->value = strdup(value);
1365 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1367 tbm_surface_debug_data *debug_data = NULL;
1368 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1369 tbm_bufmgr bufmgr = NULL;
1371 _tbm_surface_mutex_lock();
1373 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1374 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1376 bufmgr = surface->bufmgr;
1378 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1380 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1381 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1383 if (!strcmp(old_data->key, key)) {
1384 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1385 TBM_TRACE("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1386 goto add_debug_key_list;
1389 if (old_data->value)
1390 free(old_data->value);
1393 old_data->value = strdup(value);
1395 old_data->value = NULL;
1397 goto add_debug_key_list;
1403 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1405 TBM_LOG_E("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1406 _tbm_surface_mutex_unlock();
1410 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1412 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1415 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1416 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1417 if (!strcmp(old_data->key, key)) {
1418 _tbm_surface_mutex_unlock();
1424 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1425 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1427 _tbm_surface_mutex_unlock();
1433 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1435 tbm_surface_debug_data *old_data = NULL;
1437 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1439 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1440 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1441 if (!strcmp(old_data->key, key))
1442 return old_data->value;
1449 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1450 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1452 struct _tbm_surface_dump_buf_info {
1462 tbm_surface_info_s info;
1464 struct list_head link;
1467 struct _tbm_surface_dump_info {
1468 char *path; // copy???
1471 struct list_head *link;
1472 struct list_head surface_list; /* link of surface */
1475 static tbm_surface_dump_info *g_dump_info = NULL;
1476 static const char *dump_postfix[2] = {"png", "yuv"};
1479 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1480 void *data2, int size2, void *data3, int size3)
1482 FILE *fp = fopen(file, "w+");
1483 TBM_RETURN_IF_FAIL(fp != NULL);
1484 unsigned int *blocks;
1486 blocks = (unsigned int *)data1;
1487 fwrite(blocks, 1, size1, fp);
1490 blocks = (unsigned int *)data2;
1491 fwrite(blocks, 1, size2, fp);
1495 blocks = (unsigned int *)data3;
1496 fwrite(blocks, 1, size3, fp);
1503 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height)
1505 unsigned int *blocks = (unsigned int *)data;
1506 FILE *fp = fopen(file, "wb");
1507 TBM_RETURN_IF_FAIL(fp != NULL);
1508 const int pixel_size = 4; // RGBA
1509 png_bytep *row_pointers;
1512 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1515 TBM_LOG_E("fail to create a png write structure.\n");
1520 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1522 TBM_LOG_E("fail to create a png info structure.\n");
1523 png_destroy_write_struct(&pPngStruct, NULL);
1528 png_init_io(pPngStruct, fp);
1529 png_set_IHDR(pPngStruct,
1534 PNG_COLOR_TYPE_RGBA,
1536 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1538 png_set_bgr(pPngStruct);
1539 png_write_info(pPngStruct, pPngInfo);
1541 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1542 if (!row_pointers) {
1543 TBM_LOG_E("fail to allocate the png row_pointers.\n");
1544 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1549 for (y = 0; y < height; ++y) {
1553 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1555 TBM_LOG_E("fail to allocate the png row.\n");
1556 for (x = 0; x < y; x++)
1557 png_free(pPngStruct, row_pointers[x]);
1558 png_free(pPngStruct, row_pointers);
1559 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1563 row_pointers[y] = (png_bytep)row;
1565 for (x = 0; x < width; ++x) {
1566 unsigned int curBlock = blocks[y * width + x];
1568 row[x * pixel_size] = (curBlock & 0xFF);
1569 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1570 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1571 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1575 png_write_image(pPngStruct, row_pointers);
1576 png_write_end(pPngStruct, pPngInfo);
1578 for (y = 0; y < height; y++)
1579 png_free(pPngStruct, row_pointers[y]);
1580 png_free(pPngStruct, row_pointers);
1582 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1588 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1590 TBM_RETURN_IF_FAIL(path != NULL);
1591 TBM_RETURN_IF_FAIL(w > 0);
1592 TBM_RETURN_IF_FAIL(h > 0);
1593 TBM_RETURN_IF_FAIL(count > 0);
1595 tbm_surface_dump_buf_info *buf_info = NULL;
1596 tbm_surface_h tbm_surface;
1597 tbm_surface_info_s info;
1602 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1606 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1607 TBM_RETURN_IF_FAIL(g_dump_info);
1609 LIST_INITHEAD(&g_dump_info->surface_list);
1610 g_dump_info->count = 0;
1611 g_dump_info->dump_max = count;
1613 /* get buffer size */
1614 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1615 if (tbm_surface == NULL) {
1616 TBM_LOG_E("tbm_surface_create fail\n");
1622 if (TBM_SURFACE_ERROR_NONE != tbm_surface_map(tbm_surface,
1623 TBM_SURF_OPTION_READ, &info)) {
1624 TBM_LOG_E("tbm_surface_map fail\n");
1625 tbm_surface_destroy(tbm_surface);
1630 buffer_size = info.planes[0].stride * h;
1632 tbm_surface_unmap(tbm_surface);
1633 tbm_surface_destroy(tbm_surface);
1635 /* create dump lists */
1636 for (i = 0; i < count; i++) {
1639 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1640 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1642 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1644 TBM_LOG_E("fail to allocate the tbm_bo[%d]\n", i);
1649 buf_info->index = i;
1651 buf_info->size = buffer_size;
1653 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1656 g_dump_info->path = path;
1657 g_dump_info->link = &g_dump_info->surface_list;
1659 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1664 /* free resources */
1665 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1666 tbm_surface_dump_buf_info *tmp;
1668 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1669 tbm_bo_unref(buf_info->bo);
1670 LIST_DEL(&buf_info->link);
1675 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1684 tbm_surface_internal_dump_end(void)
1686 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1687 tbm_bo_handle bo_handle;
1692 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1699 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1702 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1703 if (bo_handle.ptr == NULL) {
1704 tbm_bo_unref(buf_info->bo);
1705 LIST_DEL(&buf_info->link);
1710 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1711 TBM_LOG_I("Dump File.. %s generated.\n", file);
1713 if (buf_info->dirty) {
1714 void *ptr1 = NULL, *ptr2 = NULL;
1716 switch (buf_info->info.format) {
1717 case TBM_FORMAT_ARGB8888:
1718 case TBM_FORMAT_XRGB8888:
1719 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1720 buf_info->info.planes[0].stride >> 2,
1721 buf_info->info.height);
1723 case TBM_FORMAT_YVU420:
1724 case TBM_FORMAT_YUV420:
1725 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1726 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1727 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1728 buf_info->info.planes[0].stride * buf_info->info.height,
1730 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1732 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1734 case TBM_FORMAT_NV12:
1735 case TBM_FORMAT_NV21:
1736 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1737 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1738 buf_info->info.planes[0].stride * buf_info->info.height,
1740 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1743 case TBM_FORMAT_YUYV:
1744 case TBM_FORMAT_UYVY:
1745 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1746 buf_info->info.planes[0].stride * buf_info->info.height,
1750 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1753 } else if (buf_info->dirty_shm)
1754 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1755 buf_info->shm_stride >> 2,
1758 tbm_bo_unmap(buf_info->bo);
1759 tbm_bo_unref(buf_info->bo);
1760 LIST_DEL(&buf_info->link);
1767 TBM_LOG_I("Dump End..\n");
1771 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1773 TBM_RETURN_IF_FAIL(surface != NULL);
1774 TBM_RETURN_IF_FAIL(type != NULL);
1776 tbm_surface_dump_buf_info *buf_info;
1777 struct list_head *next_link;
1778 tbm_surface_info_s info;
1779 tbm_bo_handle bo_handle;
1780 const char *postfix;
1786 next_link = g_dump_info->link->next;
1787 TBM_RETURN_IF_FAIL(next_link != NULL);
1789 if (next_link == &g_dump_info->surface_list) {
1790 next_link = next_link->next;
1791 TBM_RETURN_IF_FAIL(next_link != NULL);
1794 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1795 TBM_RETURN_IF_FAIL(buf_info != NULL);
1797 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1798 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1800 if (info.size > buf_info->size) {
1801 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
1802 info.size, buf_info->size);
1803 tbm_surface_unmap(surface);
1807 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1808 postfix = dump_postfix[0];
1810 postfix = dump_postfix[1];
1812 /* make the file information */
1813 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1816 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1817 if (!bo_handle.ptr) {
1818 TBM_LOG_E("fail to map bo");
1819 tbm_surface_unmap(surface);
1822 memset(bo_handle.ptr, 0x00, buf_info->size);
1824 switch (info.format) {
1825 case TBM_FORMAT_ARGB8888:
1826 case TBM_FORMAT_XRGB8888:
1827 snprintf(buf_info->name, sizeof(buf_info->name),
1828 "%10.3f_%03d_%p-%s.%s",
1829 _tbm_surface_internal_get_time(),
1830 g_dump_info->count++, surface, type, postfix);
1831 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1833 case TBM_FORMAT_YVU420:
1834 case TBM_FORMAT_YUV420:
1835 snprintf(buf_info->name, sizeof(buf_info->name),
1836 "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1837 _tbm_surface_internal_get_time(),
1838 g_dump_info->count++, type, info.planes[0].stride,
1839 info.height, FOURCC_STR(info.format), postfix);
1840 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1841 bo_handle.ptr += info.planes[0].stride * info.height;
1842 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1843 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1844 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1846 case TBM_FORMAT_NV12:
1847 case TBM_FORMAT_NV21:
1848 snprintf(buf_info->name, sizeof(buf_info->name),
1849 "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1850 _tbm_surface_internal_get_time(),
1851 g_dump_info->count++, type, info.planes[0].stride,
1852 info.height, FOURCC_STR(info.format), postfix);
1853 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1854 bo_handle.ptr += info.planes[0].stride * info.height;
1855 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1857 case TBM_FORMAT_YUYV:
1858 case TBM_FORMAT_UYVY:
1859 snprintf(buf_info->name, sizeof(buf_info->name),
1860 "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1861 _tbm_surface_internal_get_time(),
1862 g_dump_info->count++, type, info.planes[0].stride,
1863 info.height, FOURCC_STR(info.format), postfix);
1864 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1867 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1868 tbm_bo_unmap(buf_info->bo);
1869 tbm_surface_unmap(surface);
1873 tbm_bo_unmap(buf_info->bo);
1875 tbm_surface_unmap(surface);
1877 buf_info->dirty = 1;
1878 buf_info->dirty_shm = 0;
1880 if (g_dump_info->count == 1000)
1881 g_dump_info->count = 0;
1883 g_dump_info->link = next_link;
1885 TBM_LOG_I("Dump %s \n", buf_info->name);
1888 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
1891 TBM_RETURN_IF_FAIL(ptr != NULL);
1892 TBM_RETURN_IF_FAIL(w > 0);
1893 TBM_RETURN_IF_FAIL(h > 0);
1894 TBM_RETURN_IF_FAIL(stride > 0);
1895 TBM_RETURN_IF_FAIL(type != NULL);
1897 tbm_surface_dump_buf_info *buf_info;
1898 struct list_head *next_link;
1899 tbm_bo_handle bo_handle;
1905 next_link = g_dump_info->link->next;
1906 TBM_RETURN_IF_FAIL(next_link != NULL);
1908 if (next_link == &g_dump_info->surface_list) {
1909 next_link = next_link->next;
1910 TBM_RETURN_IF_FAIL(next_link != NULL);
1913 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1914 TBM_RETURN_IF_FAIL(buf_info != NULL);
1917 if (size > buf_info->size) {
1918 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
1919 size, buf_info->size);
1924 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1925 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1927 memset(bo_handle.ptr, 0x00, buf_info->size);
1928 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1930 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1931 _tbm_surface_internal_get_time(),
1932 g_dump_info->count++, type, dump_postfix[0]);
1933 memcpy(bo_handle.ptr, ptr, size);
1935 tbm_bo_unmap(buf_info->bo);
1937 buf_info->dirty = 0;
1938 buf_info->dirty_shm = 1;
1939 buf_info->shm_stride = stride;
1940 buf_info->shm_h = h;
1942 if (g_dump_info->count == 1000)
1943 g_dump_info->count = 0;
1945 g_dump_info->link = next_link;
1947 TBM_LOG_I("Dump %s \n", buf_info->name);
1951 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
1953 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
1954 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
1955 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
1957 tbm_surface_info_s info;
1958 const char *postfix;
1962 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1963 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
1965 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1966 postfix = dump_postfix[0];
1968 postfix = dump_postfix[1];
1970 if (strcmp(postfix, type)) {
1971 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
1972 tbm_surface_unmap(surface);
1976 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
1978 if (!access(file, 0)) {
1979 TBM_LOG_E("can't capture buffer, exist file %s", file);
1980 tbm_surface_unmap(surface);
1984 switch (info.format) {
1985 case TBM_FORMAT_ARGB8888:
1986 case TBM_FORMAT_XRGB8888:
1987 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
1988 info.planes[0].stride >> 2,
1991 case TBM_FORMAT_YVU420:
1992 case TBM_FORMAT_YUV420:
1993 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
1994 info.planes[0].stride * info.height,
1996 info.planes[1].stride * (info.height >> 1),
1998 info.planes[2].stride * (info.height >> 1));
2000 case TBM_FORMAT_NV12:
2001 case TBM_FORMAT_NV21:
2002 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2003 info.planes[0].stride * info.height,
2005 info.planes[1].stride * (info.height >> 1),
2008 case TBM_FORMAT_YUYV:
2009 case TBM_FORMAT_UYVY:
2010 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2011 info.planes[0].stride * info.height,
2015 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2016 tbm_surface_unmap(surface);
2020 tbm_surface_unmap(surface);
2022 TBM_LOG_I("Capture %s \n", file);
2028 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2029 const char *path, const char *name, const char *type)
2031 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2032 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2033 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2034 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2035 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2036 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2040 if (strcmp(dump_postfix[0], type)) {
2041 TBM_LOG_E("Not supported type:%s'", type);
2045 if (!access(file, 0)) {
2046 TBM_LOG_E("can't capture buffer, exist file %s", file);
2050 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2052 _tbm_surface_internal_dump_file_png(file, ptr, stride, h);
2054 TBM_LOG_I("Capture %s \n", file);