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: tbm_surface mutex init\n");
235 tbm_surface_mutex_init = true;
241 _tbm_surface_mutex_lock(void)
243 if (!_tbm_surface_mutex_init())
246 pthread_mutex_lock(&tbm_surface_lock);
250 _tbm_surface_mutex_unlock(void)
252 pthread_mutex_unlock(&tbm_surface_lock);
256 _init_surface_bufmgr(void)
258 g_surface_bufmgr = tbm_bufmgr_init(-1);
262 _deinit_surface_bufmgr(void)
264 if (!g_surface_bufmgr)
267 tbm_bufmgr_deinit(g_surface_bufmgr);
268 g_surface_bufmgr = NULL;
272 _tbm_surface_internal_is_valid(tbm_surface_h surface)
274 tbm_surface_h old_data = NULL;
276 if (surface == NULL || g_surface_bufmgr == NULL) {
277 TBM_TRACE("error: tbm_surface(%p)\n", surface);
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);
289 TBM_TRACE("error: tbm_surface(%p)\n", surface);
294 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
295 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
297 TBM_RETURN_VAL_IF_FAIL(surface, 0);
298 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
300 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
301 struct _tbm_bufmgr *mgr = surf->bufmgr;
304 TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
305 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
306 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
307 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
309 if (!mgr->backend->surface_get_plane_data)
312 ret = mgr->backend->surface_get_plane_data(surf->info.width,
313 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
321 _tbm_surface_internal_destroy(tbm_surface_h surface)
324 tbm_bufmgr bufmgr = surface->bufmgr;
325 tbm_user_data *old_data = NULL, *tmp = NULL;
326 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
328 /* destory the user_data_list */
329 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
330 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
331 TBM_DBG("free user_data\n");
332 user_data_delete(old_data);
336 for (i = 0; i < surface->num_bos; i++) {
337 surface->bos[i]->surface = NULL;
339 tbm_bo_unref(surface->bos[i]);
340 surface->bos[i] = NULL;
343 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
344 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
345 _tbm_surface_internal_debug_data_delete(debug_old_data);
348 LIST_DEL(&surface->item_link);
353 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
354 LIST_DELINIT(&bufmgr->surf_list);
356 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
357 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
358 _tbm_surface_internal_debug_data_delete(debug_old_data);
362 _deinit_surface_bufmgr();
367 tbm_surface_internal_is_valid(tbm_surface_h surface)
371 _tbm_surface_mutex_lock();
373 ret = _tbm_surface_internal_is_valid(surface);
375 _tbm_surface_mutex_unlock();
381 tbm_surface_internal_query_supported_formats(uint32_t **formats,
384 struct _tbm_bufmgr *mgr;
386 bool bufmgr_initialized = false;
388 _tbm_surface_mutex_lock();
390 if (!g_surface_bufmgr) {
391 _init_surface_bufmgr();
392 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
393 bufmgr_initialized = true;
396 mgr = g_surface_bufmgr;
398 if (!mgr->backend->surface_supported_format)
401 ret = mgr->backend->surface_supported_format(formats, num);
405 TBM_TRACE("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
407 _tbm_surface_mutex_unlock();
412 if (bufmgr_initialized) {
413 LIST_DELINIT(&g_surface_bufmgr->surf_list);
414 _deinit_surface_bufmgr();
416 _tbm_surface_mutex_unlock();
417 TBM_TRACE("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
422 tbm_surface_internal_get_num_planes(tbm_format format)
428 case TBM_FORMAT_RGB332:
429 case TBM_FORMAT_BGR233:
430 case TBM_FORMAT_XRGB4444:
431 case TBM_FORMAT_XBGR4444:
432 case TBM_FORMAT_RGBX4444:
433 case TBM_FORMAT_BGRX4444:
434 case TBM_FORMAT_ARGB4444:
435 case TBM_FORMAT_ABGR4444:
436 case TBM_FORMAT_RGBA4444:
437 case TBM_FORMAT_BGRA4444:
438 case TBM_FORMAT_XRGB1555:
439 case TBM_FORMAT_XBGR1555:
440 case TBM_FORMAT_RGBX5551:
441 case TBM_FORMAT_BGRX5551:
442 case TBM_FORMAT_ARGB1555:
443 case TBM_FORMAT_ABGR1555:
444 case TBM_FORMAT_RGBA5551:
445 case TBM_FORMAT_BGRA5551:
446 case TBM_FORMAT_RGB565:
447 case TBM_FORMAT_BGR565:
448 case TBM_FORMAT_RGB888:
449 case TBM_FORMAT_BGR888:
450 case TBM_FORMAT_XRGB8888:
451 case TBM_FORMAT_XBGR8888:
452 case TBM_FORMAT_RGBX8888:
453 case TBM_FORMAT_BGRX8888:
454 case TBM_FORMAT_ARGB8888:
455 case TBM_FORMAT_ABGR8888:
456 case TBM_FORMAT_RGBA8888:
457 case TBM_FORMAT_BGRA8888:
458 case TBM_FORMAT_XRGB2101010:
459 case TBM_FORMAT_XBGR2101010:
460 case TBM_FORMAT_RGBX1010102:
461 case TBM_FORMAT_BGRX1010102:
462 case TBM_FORMAT_ARGB2101010:
463 case TBM_FORMAT_ABGR2101010:
464 case TBM_FORMAT_RGBA1010102:
465 case TBM_FORMAT_BGRA1010102:
466 case TBM_FORMAT_YUYV:
467 case TBM_FORMAT_YVYU:
468 case TBM_FORMAT_UYVY:
469 case TBM_FORMAT_VYUY:
470 case TBM_FORMAT_AYUV:
473 case TBM_FORMAT_NV12:
474 case TBM_FORMAT_NV12MT:
475 case TBM_FORMAT_NV21:
476 case TBM_FORMAT_NV16:
477 case TBM_FORMAT_NV61:
480 case TBM_FORMAT_YUV410:
481 case TBM_FORMAT_YVU410:
482 case TBM_FORMAT_YUV411:
483 case TBM_FORMAT_YVU411:
484 case TBM_FORMAT_YUV420:
485 case TBM_FORMAT_YVU420:
486 case TBM_FORMAT_YUV422:
487 case TBM_FORMAT_YVU422:
488 case TBM_FORMAT_YUV444:
489 case TBM_FORMAT_YVU444:
497 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
503 tbm_surface_internal_get_bpp(tbm_format format)
510 case TBM_FORMAT_RGB332:
511 case TBM_FORMAT_BGR233:
514 case TBM_FORMAT_XRGB4444:
515 case TBM_FORMAT_XBGR4444:
516 case TBM_FORMAT_RGBX4444:
517 case TBM_FORMAT_BGRX4444:
518 case TBM_FORMAT_ARGB4444:
519 case TBM_FORMAT_ABGR4444:
520 case TBM_FORMAT_RGBA4444:
521 case TBM_FORMAT_BGRA4444:
522 case TBM_FORMAT_XRGB1555:
523 case TBM_FORMAT_XBGR1555:
524 case TBM_FORMAT_RGBX5551:
525 case TBM_FORMAT_BGRX5551:
526 case TBM_FORMAT_ARGB1555:
527 case TBM_FORMAT_ABGR1555:
528 case TBM_FORMAT_RGBA5551:
529 case TBM_FORMAT_BGRA5551:
530 case TBM_FORMAT_RGB565:
531 case TBM_FORMAT_BGR565:
534 case TBM_FORMAT_RGB888:
535 case TBM_FORMAT_BGR888:
538 case TBM_FORMAT_XRGB8888:
539 case TBM_FORMAT_XBGR8888:
540 case TBM_FORMAT_RGBX8888:
541 case TBM_FORMAT_BGRX8888:
542 case TBM_FORMAT_ARGB8888:
543 case TBM_FORMAT_ABGR8888:
544 case TBM_FORMAT_RGBA8888:
545 case TBM_FORMAT_BGRA8888:
546 case TBM_FORMAT_XRGB2101010:
547 case TBM_FORMAT_XBGR2101010:
548 case TBM_FORMAT_RGBX1010102:
549 case TBM_FORMAT_BGRX1010102:
550 case TBM_FORMAT_ARGB2101010:
551 case TBM_FORMAT_ABGR2101010:
552 case TBM_FORMAT_RGBA1010102:
553 case TBM_FORMAT_BGRA1010102:
554 case TBM_FORMAT_YUYV:
555 case TBM_FORMAT_YVYU:
556 case TBM_FORMAT_UYVY:
557 case TBM_FORMAT_VYUY:
558 case TBM_FORMAT_AYUV:
561 case TBM_FORMAT_NV12:
562 case TBM_FORMAT_NV12MT:
563 case TBM_FORMAT_NV21:
566 case TBM_FORMAT_NV16:
567 case TBM_FORMAT_NV61:
570 case TBM_FORMAT_YUV410:
571 case TBM_FORMAT_YVU410:
574 case TBM_FORMAT_YUV411:
575 case TBM_FORMAT_YVU411:
576 case TBM_FORMAT_YUV420:
577 case TBM_FORMAT_YVU420:
580 case TBM_FORMAT_YUV422:
581 case TBM_FORMAT_YVU422:
584 case TBM_FORMAT_YUV444:
585 case TBM_FORMAT_YVU444:
592 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
598 tbm_surface_internal_create_with_flags(int width, int height,
599 int format, int flags)
601 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
602 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
604 struct _tbm_bufmgr *mgr;
605 struct _tbm_surface *surf = NULL;
609 uint32_t bo_size = 0;
612 bool bufmgr_initialized = false;
614 _tbm_surface_mutex_lock();
616 if (!g_surface_bufmgr) {
617 _init_surface_bufmgr();
618 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
619 bufmgr_initialized = true;
622 mgr = g_surface_bufmgr;
623 if (!TBM_BUFMGR_IS_VALID(mgr)) {
624 TBM_LOG_E("The bufmgr is invalid\n");
625 goto check_valid_fail;
628 surf = calloc(1, sizeof(struct _tbm_surface));
630 TBM_LOG_E("fail to alloc surf\n");
631 goto alloc_surf_fail;
635 surf->info.width = width;
636 surf->info.height = height;
637 surf->info.format = format;
638 surf->info.bpp = tbm_surface_internal_get_bpp(format);
639 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
642 /* get size, stride and offset bo_idx */
643 for (i = 0; i < surf->info.num_planes; i++) {
644 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
645 &offset, &stride, &bo_idx)) {
646 TBM_LOG_E("fail to query plane data\n");
647 goto query_plane_data_fail;
650 surf->info.planes[i].size = size;
651 surf->info.planes[i].offset = offset;
652 surf->info.planes[i].stride = stride;
653 surf->planes_bo_idx[i] = bo_idx;
658 for (i = 0; i < surf->info.num_planes; i++) {
659 surf->info.size += surf->info.planes[i].size;
661 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
662 surf->num_bos = surf->planes_bo_idx[i] + 1;
667 for (i = 0; i < surf->num_bos; i++) {
669 for (j = 0; j < surf->info.num_planes; j++) {
670 if (surf->planes_bo_idx[j] == i)
671 bo_size += surf->info.planes[j].size;
674 if (mgr->backend->surface_bo_alloc) {
675 /* LCOV_EXCL_START */
677 void *bo_priv = NULL;
679 bo = calloc(1, sizeof(struct _tbm_bo));
681 TBM_LOG_E("fail to alloc bo struct\n");
685 bo->bufmgr = surf->bufmgr;
687 pthread_mutex_lock(&surf->bufmgr->lock);
689 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
691 TBM_LOG_E("fail to alloc bo priv\n");
693 pthread_mutex_unlock(&surf->bufmgr->lock);
701 LIST_INITHEAD(&bo->user_data_list);
703 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
705 pthread_mutex_unlock(&surf->bufmgr->lock);
710 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
712 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
717 _tbm_bo_set_surface(surf->bos[i], surf);
720 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
721 _tbm_surface_internal_format_to_str(format), flags, surf);
723 LIST_INITHEAD(&surf->user_data_list);
724 LIST_INITHEAD(&surf->debug_data_list);
726 LIST_ADD(&surf->item_link, &mgr->surf_list);
728 _tbm_surface_mutex_unlock();
733 for (j = 0; j < i; j++) {
735 tbm_bo_unref(surf->bos[j]);
737 query_plane_data_fail:
741 if (bufmgr_initialized && mgr) {
742 LIST_DELINIT(&mgr->surf_list);
743 _deinit_surface_bufmgr();
745 _tbm_surface_mutex_unlock();
746 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
748 _tbm_surface_internal_format_to_str(format), flags);
753 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
754 tbm_bo *bos, int num)
756 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
757 TBM_RETURN_VAL_IF_FAIL(info, NULL);
758 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
760 struct _tbm_bufmgr *mgr;
761 struct _tbm_surface *surf = NULL;
763 bool bufmgr_initialized = false;
765 _tbm_surface_mutex_lock();
767 if (!g_surface_bufmgr) {
768 _init_surface_bufmgr();
769 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
770 bufmgr_initialized = true;
773 mgr = g_surface_bufmgr;
774 if (!TBM_BUFMGR_IS_VALID(mgr))
775 goto check_valid_fail;
777 surf = calloc(1, sizeof(struct _tbm_surface));
779 goto alloc_surf_fail;
782 surf->info.width = info->width;
783 surf->info.height = info->height;
784 surf->info.format = info->format;
785 surf->info.bpp = info->bpp;
786 surf->info.num_planes = info->num_planes;
789 /* get size, stride and offset */
790 for (i = 0; i < info->num_planes; i++) {
791 surf->info.planes[i].offset = info->planes[i].offset;
792 surf->info.planes[i].stride = info->planes[i].stride;
794 if (info->planes[i].size > 0)
795 surf->info.planes[i].size = info->planes[i].size;
797 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
800 surf->planes_bo_idx[i] = 0;
802 surf->planes_bo_idx[i] = i;
805 if (info->size > 0) {
806 surf->info.size = info->size;
809 for (i = 0; i < info->num_planes; i++)
810 surf->info.size += surf->info.planes[i].size;
813 surf->flags = TBM_BO_DEFAULT;
815 /* create only one bo */
817 for (i = 0; i < num; i++) {
821 surf->bos[i] = tbm_bo_ref(bos[i]);
822 _tbm_bo_set_surface(bos[i], surf);
825 TBM_TRACE("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
826 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
828 LIST_INITHEAD(&surf->user_data_list);
829 LIST_INITHEAD(&surf->debug_data_list);
831 LIST_ADD(&surf->item_link, &mgr->surf_list);
833 _tbm_surface_mutex_unlock();
838 for (i = 0; i < num; i++) {
840 tbm_bo_unref(surf->bos[i]);
845 if (bufmgr_initialized && mgr) {
846 LIST_DELINIT(&mgr->surf_list);
847 _deinit_surface_bufmgr();
849 _tbm_surface_mutex_unlock();
850 TBM_TRACE("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
851 info->width, info->height,
852 _tbm_surface_internal_format_to_str(info->format), num);
857 tbm_surface_internal_destroy(tbm_surface_h surface)
859 _tbm_surface_mutex_lock();
861 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
865 if (surface->refcnt > 0) {
866 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
867 _tbm_surface_mutex_unlock();
871 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
873 if (surface->refcnt == 0)
874 _tbm_surface_internal_destroy(surface);
876 _tbm_surface_mutex_unlock();
880 tbm_surface_internal_ref(tbm_surface_h surface)
882 _tbm_surface_mutex_lock();
884 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
888 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
890 _tbm_surface_mutex_unlock();
894 tbm_surface_internal_unref(tbm_surface_h surface)
896 _tbm_surface_mutex_lock();
898 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
902 if (surface->refcnt > 0) {
903 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
904 _tbm_surface_mutex_unlock();
908 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
910 if (surface->refcnt == 0)
911 _tbm_surface_internal_destroy(surface);
913 _tbm_surface_mutex_unlock();
917 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
919 struct _tbm_surface *surf;
922 _tbm_surface_mutex_lock();
924 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
926 surf = (struct _tbm_surface *)surface;
929 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
931 _tbm_surface_mutex_unlock();
937 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
939 struct _tbm_surface *surf;
942 _tbm_surface_mutex_lock();
944 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
945 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
947 surf = (struct _tbm_surface *)surface;
948 bo = surf->bos[bo_idx];
950 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
952 _tbm_surface_mutex_unlock();
958 tbm_surface_internal_get_size(tbm_surface_h surface)
960 struct _tbm_surface *surf;
963 _tbm_surface_mutex_lock();
965 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
967 surf = (struct _tbm_surface *)surface;
968 size = surf->info.size;
970 TBM_TRACE("tbm_surface(%p) size(%u)\n", surface, size);
972 _tbm_surface_mutex_unlock();
978 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
979 uint32_t *size, uint32_t *offset, uint32_t *pitch)
981 struct _tbm_surface *surf;
983 _tbm_surface_mutex_lock();
985 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
986 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
988 surf = (struct _tbm_surface *)surface;
990 if (plane_idx >= surf->info.num_planes) {
991 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
992 _tbm_surface_mutex_unlock();
997 *size = surf->info.planes[plane_idx].size;
1000 *offset = surf->info.planes[plane_idx].offset;
1003 *pitch = surf->info.planes[plane_idx].stride;
1005 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1006 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1007 surf->info.planes[plane_idx].stride);
1009 _tbm_surface_mutex_unlock();
1015 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1016 tbm_surface_info_s *info, int map)
1018 struct _tbm_surface *surf;
1019 tbm_bo_handle bo_handles[4];
1022 _tbm_surface_mutex_lock();
1024 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1026 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1028 surf = (struct _tbm_surface *)surface;
1030 memset(info, 0x00, sizeof(tbm_surface_info_s));
1031 info->width = surf->info.width;
1032 info->height = surf->info.height;
1033 info->format = surf->info.format;
1034 info->bpp = surf->info.bpp;
1035 info->size = surf->info.size;
1036 info->num_planes = surf->info.num_planes;
1039 for (i = 0; i < surf->num_bos; i++) {
1040 _tbm_surface_mutex_unlock();
1041 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1042 _tbm_surface_mutex_lock();
1043 if (bo_handles[i].ptr == NULL) {
1044 for (j = 0; j < i; j++)
1045 tbm_bo_unmap(surf->bos[j]);
1047 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1048 _tbm_surface_mutex_unlock();
1053 for (i = 0; i < surf->num_bos; i++) {
1054 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1055 if (bo_handles[i].ptr == NULL) {
1056 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1057 _tbm_surface_mutex_unlock();
1063 for (i = 0; i < surf->info.num_planes; i++) {
1064 info->planes[i].size = surf->info.planes[i].size;
1065 info->planes[i].offset = surf->info.planes[i].offset;
1066 info->planes[i].stride = surf->info.planes[i].stride;
1068 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1069 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1070 surf->info.planes[i].offset;
1073 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1075 _tbm_surface_mutex_unlock();
1081 tbm_surface_internal_unmap(tbm_surface_h surface)
1083 struct _tbm_surface *surf;
1086 _tbm_surface_mutex_lock();
1088 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1090 surf = (struct _tbm_surface *)surface;
1092 for (i = 0; i < surf->num_bos; i++)
1093 tbm_bo_unmap(surf->bos[i]);
1095 TBM_TRACE("tbm_surface(%p)\n", surface);
1097 _tbm_surface_mutex_unlock();
1101 tbm_surface_internal_get_width(tbm_surface_h surface)
1103 struct _tbm_surface *surf;
1106 _tbm_surface_mutex_lock();
1108 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1110 surf = (struct _tbm_surface *)surface;
1111 width = surf->info.width;
1113 TBM_TRACE("tbm_surface(%p) width(%u)\n", surface, width);
1115 _tbm_surface_mutex_unlock();
1121 tbm_surface_internal_get_height(tbm_surface_h surface)
1123 struct _tbm_surface *surf;
1124 unsigned int height;
1126 _tbm_surface_mutex_lock();
1128 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1130 surf = (struct _tbm_surface *)surface;
1131 height = surf->info.height;
1133 TBM_TRACE("tbm_surface(%p) height(%u)\n", surface, height);
1135 _tbm_surface_mutex_unlock();
1142 tbm_surface_internal_get_format(tbm_surface_h surface)
1144 struct _tbm_surface *surf;
1147 _tbm_surface_mutex_lock();
1149 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1151 surf = (struct _tbm_surface *)surface;
1152 format = surf->info.format;
1154 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1156 _tbm_surface_mutex_unlock();
1162 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1164 struct _tbm_surface *surf;
1167 _tbm_surface_mutex_lock();
1169 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1170 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1172 surf = (struct _tbm_surface *)surface;
1173 bo_idx = surf->planes_bo_idx[plane_idx];
1175 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1177 _tbm_surface_mutex_unlock();
1183 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1184 tbm_data_free data_free_func)
1186 tbm_user_data *data;
1188 _tbm_surface_mutex_lock();
1190 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1192 /* check if the data according to the key exist if so, return false. */
1193 data = user_data_lookup(&surface->user_data_list, key);
1195 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1196 _tbm_surface_mutex_unlock();
1200 data = user_data_create(key, data_free_func);
1202 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1203 _tbm_surface_mutex_unlock();
1207 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1209 LIST_ADD(&data->item_link, &surface->user_data_list);
1211 _tbm_surface_mutex_unlock();
1217 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1220 tbm_user_data *old_data;
1222 _tbm_surface_mutex_lock();
1224 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1226 old_data = user_data_lookup(&surface->user_data_list, key);
1228 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1229 _tbm_surface_mutex_unlock();
1233 if (old_data->data && old_data->free_func)
1234 old_data->free_func(old_data->data);
1236 old_data->data = data;
1238 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1240 _tbm_surface_mutex_unlock();
1246 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1249 tbm_user_data *old_data;
1251 _tbm_surface_mutex_lock();
1253 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1256 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1257 _tbm_surface_mutex_unlock();
1262 old_data = user_data_lookup(&surface->user_data_list, key);
1264 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1265 _tbm_surface_mutex_unlock();
1269 *data = old_data->data;
1271 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1273 _tbm_surface_mutex_unlock();
1279 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1282 tbm_user_data *old_data = (void *)0;
1284 _tbm_surface_mutex_lock();
1286 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1288 old_data = user_data_lookup(&surface->user_data_list, key);
1290 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1291 _tbm_surface_mutex_unlock();
1295 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1297 user_data_delete(old_data);
1299 _tbm_surface_mutex_unlock();
1304 /* LCOV_EXCL_START */
1306 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1308 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1310 return surface->debug_pid;
1314 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1316 _tbm_surface_mutex_lock();
1318 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1320 surface->debug_pid = pid;
1322 _tbm_surface_mutex_unlock();
1325 static tbm_surface_debug_data *
1326 _tbm_surface_internal_debug_data_create(char *key, char *value)
1328 tbm_surface_debug_data *debug_data = NULL;
1330 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1334 if (key) debug_data->key = strdup(key);
1335 if (value) debug_data->value = strdup(value);
1341 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1343 tbm_surface_debug_data *debug_data = NULL;
1344 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1345 tbm_bufmgr bufmgr = NULL;
1347 _tbm_surface_mutex_lock();
1349 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1350 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1352 bufmgr = surface->bufmgr;
1354 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1356 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1357 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1358 if (!strcmp(old_data->key, key)) {
1359 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1360 TBM_TRACE("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1361 goto add_debug_key_list;
1364 if (old_data->value)
1365 free(old_data->value);
1368 old_data->value = strdup(value);
1370 old_data->value = NULL;
1375 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1377 TBM_TRACE("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1378 _tbm_surface_mutex_unlock();
1382 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1384 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1387 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1388 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1389 if (!strcmp(old_data->key, key)) {
1390 _tbm_surface_mutex_unlock();
1396 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1397 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1399 _tbm_surface_mutex_unlock();
1405 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1407 tbm_surface_debug_data *old_data = NULL;
1409 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1411 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1412 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1413 if (!strcmp(old_data->key, key))
1414 return old_data->value;
1421 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1422 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1424 struct _tbm_surface_dump_buf_info {
1434 tbm_surface_info_s info;
1436 struct list_head link;
1439 struct _tbm_surface_dump_info {
1440 char *path; // copy???
1443 struct list_head *link;
1444 struct list_head surface_list; /* link of surface */
1447 static tbm_surface_dump_info *g_dump_info = NULL;
1448 static const char *dump_postfix[2] = {"png", "yuv"};
1451 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1452 void *data2, int size2, void *data3, int size3)
1454 FILE *fp = fopen(file, "w+");
1455 TBM_RETURN_IF_FAIL(fp != NULL);
1456 unsigned int *blocks;
1458 blocks = (unsigned int *)data1;
1459 fwrite(blocks, 1, size1, fp);
1462 blocks = (unsigned int *)data2;
1463 fwrite(blocks, 1, size2, fp);
1467 blocks = (unsigned int *)data3;
1468 fwrite(blocks, 1, size3, fp);
1475 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height)
1477 unsigned int *blocks = (unsigned int *)data;
1478 FILE *fp = fopen(file, "wb");
1479 TBM_RETURN_IF_FAIL(fp != NULL);
1480 const int pixel_size = 4; // RGBA
1481 png_bytep *row_pointers;
1484 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1491 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1493 png_destroy_write_struct(&pPngStruct, NULL);
1498 png_init_io(pPngStruct, fp);
1499 png_set_IHDR(pPngStruct,
1504 PNG_COLOR_TYPE_RGBA,
1506 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1508 png_set_bgr(pPngStruct);
1509 png_write_info(pPngStruct, pPngInfo);
1511 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1512 if (!row_pointers) {
1513 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1518 for (y = 0; y < height; ++y) {
1522 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1524 for (x = 0; x < y; x++)
1525 png_free(pPngStruct, row_pointers[x]);
1526 png_free(pPngStruct, row_pointers);
1527 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1531 row_pointers[y] = (png_bytep)row;
1533 for (x = 0; x < width; ++x) {
1534 unsigned int curBlock = blocks[y * width + x];
1536 row[x * pixel_size] = (curBlock & 0xFF);
1537 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1538 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1539 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1543 png_write_image(pPngStruct, row_pointers);
1544 png_write_end(pPngStruct, pPngInfo);
1546 for (y = 0; y < height; y++)
1547 png_free(pPngStruct, row_pointers[y]);
1548 png_free(pPngStruct, row_pointers);
1550 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1556 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1558 TBM_RETURN_IF_FAIL(path != NULL);
1559 TBM_RETURN_IF_FAIL(w > 0);
1560 TBM_RETURN_IF_FAIL(h > 0);
1561 TBM_RETURN_IF_FAIL(count > 0);
1563 tbm_surface_dump_buf_info *buf_info = NULL;
1564 tbm_surface_h tbm_surface;
1565 tbm_surface_info_s info;
1570 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1574 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1575 TBM_RETURN_IF_FAIL(g_dump_info);
1577 LIST_INITHEAD(&g_dump_info->surface_list);
1578 g_dump_info->count = 0;
1579 g_dump_info->dump_max = count;
1581 /* get buffer size */
1582 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1583 if (tbm_surface == NULL) {
1584 TBM_LOG_E("tbm_surface_create fail\n");
1590 if (TBM_SURFACE_ERROR_NONE != tbm_surface_map(tbm_surface,
1591 TBM_SURF_OPTION_READ, &info)) {
1592 TBM_LOG_E("tbm_surface_map fail\n");
1593 tbm_surface_destroy(tbm_surface);
1598 buffer_size = info.planes[0].stride * h;
1600 tbm_surface_unmap(tbm_surface);
1601 tbm_surface_destroy(tbm_surface);
1603 /* create dump lists */
1604 for (i = 0; i < count; i++) {
1607 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1608 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1610 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1616 buf_info->index = i;
1618 buf_info->size = buffer_size;
1620 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1623 g_dump_info->path = path;
1624 g_dump_info->link = &g_dump_info->surface_list;
1626 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1631 /* free resources */
1632 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1633 tbm_surface_dump_buf_info *tmp;
1635 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1636 tbm_bo_unref(buf_info->bo);
1637 LIST_DEL(&buf_info->link);
1642 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1651 tbm_surface_internal_dump_end(void)
1653 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1654 tbm_bo_handle bo_handle;
1659 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1666 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1669 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1670 if (bo_handle.ptr == NULL) {
1671 tbm_bo_unref(buf_info->bo);
1672 LIST_DEL(&buf_info->link);
1677 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1678 TBM_LOG_I("Dump File.. %s generated.\n", file);
1680 if (buf_info->dirty) {
1681 void *ptr1 = NULL, *ptr2 = NULL;
1683 switch (buf_info->info.format) {
1684 case TBM_FORMAT_ARGB8888:
1685 case TBM_FORMAT_XRGB8888:
1686 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1687 buf_info->info.planes[0].stride >> 2,
1688 buf_info->info.height);
1690 case TBM_FORMAT_YVU420:
1691 case TBM_FORMAT_YUV420:
1692 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1693 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1694 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1695 buf_info->info.planes[0].stride * buf_info->info.height,
1697 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1699 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1701 case TBM_FORMAT_NV12:
1702 case TBM_FORMAT_NV21:
1703 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1704 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1705 buf_info->info.planes[0].stride * buf_info->info.height,
1707 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1710 case TBM_FORMAT_YUYV:
1711 case TBM_FORMAT_UYVY:
1712 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1713 buf_info->info.planes[0].stride * buf_info->info.height,
1717 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1720 } else if (buf_info->dirty_shm)
1721 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1722 buf_info->shm_stride >> 2,
1725 tbm_bo_unmap(buf_info->bo);
1726 tbm_bo_unref(buf_info->bo);
1727 LIST_DEL(&buf_info->link);
1734 TBM_LOG_I("Dump End..\n");
1738 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1740 TBM_RETURN_IF_FAIL(surface != NULL);
1741 TBM_RETURN_IF_FAIL(type != NULL);
1743 tbm_surface_dump_buf_info *buf_info;
1744 struct list_head *next_link;
1745 tbm_surface_info_s info;
1746 tbm_bo_handle bo_handle;
1747 const char *postfix;
1753 next_link = g_dump_info->link->next;
1754 TBM_RETURN_IF_FAIL(next_link != NULL);
1756 if (next_link == &g_dump_info->surface_list) {
1757 next_link = next_link->next;
1758 TBM_RETURN_IF_FAIL(next_link != NULL);
1761 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1762 TBM_RETURN_IF_FAIL(buf_info != NULL);
1764 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1765 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1767 if (info.size > buf_info->size) {
1768 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
1769 info.size, buf_info->size);
1770 tbm_surface_unmap(surface);
1774 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1775 postfix = dump_postfix[0];
1777 postfix = dump_postfix[1];
1779 /* make the file information */
1780 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1783 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1784 if (!bo_handle.ptr) {
1785 TBM_LOG_E("fail to map bo");
1786 tbm_surface_unmap(surface);
1789 memset(bo_handle.ptr, 0x00, buf_info->size);
1791 switch (info.format) {
1792 case TBM_FORMAT_ARGB8888:
1793 case TBM_FORMAT_XRGB8888:
1794 snprintf(buf_info->name, sizeof(buf_info->name),
1795 "%10.3f_%03d_%p-%s.%s",
1796 _tbm_surface_internal_get_time(),
1797 g_dump_info->count++, surface, type, postfix);
1798 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1800 case TBM_FORMAT_YVU420:
1801 case TBM_FORMAT_YUV420:
1802 snprintf(buf_info->name, sizeof(buf_info->name),
1803 "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1804 _tbm_surface_internal_get_time(),
1805 g_dump_info->count++, type, info.planes[0].stride,
1806 info.height, FOURCC_STR(info.format), postfix);
1807 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1808 bo_handle.ptr += info.planes[0].stride * info.height;
1809 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1810 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1811 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1813 case TBM_FORMAT_NV12:
1814 case TBM_FORMAT_NV21:
1815 snprintf(buf_info->name, sizeof(buf_info->name),
1816 "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1817 _tbm_surface_internal_get_time(),
1818 g_dump_info->count++, type, info.planes[0].stride,
1819 info.height, FOURCC_STR(info.format), postfix);
1820 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1821 bo_handle.ptr += info.planes[0].stride * info.height;
1822 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1824 case TBM_FORMAT_YUYV:
1825 case TBM_FORMAT_UYVY:
1826 snprintf(buf_info->name, sizeof(buf_info->name),
1827 "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1828 _tbm_surface_internal_get_time(),
1829 g_dump_info->count++, type, info.planes[0].stride,
1830 info.height, FOURCC_STR(info.format), postfix);
1831 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1834 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1835 tbm_bo_unmap(buf_info->bo);
1836 tbm_surface_unmap(surface);
1840 tbm_bo_unmap(buf_info->bo);
1842 tbm_surface_unmap(surface);
1844 buf_info->dirty = 1;
1845 buf_info->dirty_shm = 0;
1847 if (g_dump_info->count == 1000)
1848 g_dump_info->count = 0;
1850 g_dump_info->link = next_link;
1852 TBM_LOG_I("Dump %s \n", buf_info->name);
1855 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
1858 TBM_RETURN_IF_FAIL(ptr != NULL);
1859 TBM_RETURN_IF_FAIL(w > 0);
1860 TBM_RETURN_IF_FAIL(h > 0);
1861 TBM_RETURN_IF_FAIL(stride > 0);
1862 TBM_RETURN_IF_FAIL(type != NULL);
1864 tbm_surface_dump_buf_info *buf_info;
1865 struct list_head *next_link;
1866 tbm_bo_handle bo_handle;
1872 next_link = g_dump_info->link->next;
1873 TBM_RETURN_IF_FAIL(next_link != NULL);
1875 if (next_link == &g_dump_info->surface_list) {
1876 next_link = next_link->next;
1877 TBM_RETURN_IF_FAIL(next_link != NULL);
1880 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1881 TBM_RETURN_IF_FAIL(buf_info != NULL);
1884 if (size > buf_info->size) {
1885 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
1886 size, buf_info->size);
1891 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1892 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1894 memset(bo_handle.ptr, 0x00, buf_info->size);
1895 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1897 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1898 _tbm_surface_internal_get_time(),
1899 g_dump_info->count++, type, dump_postfix[0]);
1900 memcpy(bo_handle.ptr, ptr, size);
1902 tbm_bo_unmap(buf_info->bo);
1904 buf_info->dirty = 0;
1905 buf_info->dirty_shm = 1;
1906 buf_info->shm_stride = stride;
1907 buf_info->shm_h = h;
1909 if (g_dump_info->count == 1000)
1910 g_dump_info->count = 0;
1912 g_dump_info->link = next_link;
1914 TBM_LOG_I("Dump %s \n", buf_info->name);
1918 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
1920 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
1921 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
1922 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
1924 tbm_surface_info_s info;
1925 const char *postfix;
1929 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1930 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
1932 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1933 postfix = dump_postfix[0];
1935 postfix = dump_postfix[1];
1937 if (strcmp(postfix, type)) {
1938 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
1939 tbm_surface_unmap(surface);
1943 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
1945 if (!access(file, 0)) {
1946 TBM_LOG_E("can't capture buffer, exist file %s", file);
1947 tbm_surface_unmap(surface);
1951 switch (info.format) {
1952 case TBM_FORMAT_ARGB8888:
1953 case TBM_FORMAT_XRGB8888:
1954 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
1955 info.planes[0].stride >> 2,
1958 case TBM_FORMAT_YVU420:
1959 case TBM_FORMAT_YUV420:
1960 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
1961 info.planes[0].stride * info.height,
1963 info.planes[1].stride * (info.height >> 1),
1965 info.planes[2].stride * (info.height >> 1));
1967 case TBM_FORMAT_NV12:
1968 case TBM_FORMAT_NV21:
1969 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
1970 info.planes[0].stride * info.height,
1972 info.planes[1].stride * (info.height >> 1),
1975 case TBM_FORMAT_YUYV:
1976 case TBM_FORMAT_UYVY:
1977 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
1978 info.planes[0].stride * info.height,
1982 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
1983 tbm_surface_unmap(surface);
1987 tbm_surface_unmap(surface);
1989 TBM_LOG_I("Capture %s \n", file);
1995 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
1996 const char *path, const char *name, const char *type)
1998 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
1999 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2000 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2001 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2002 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2003 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2007 if (strcmp(dump_postfix[0], type)) {
2008 TBM_LOG_E("Not supported type:%s'", type);
2012 if (!access(file, 0)) {
2013 TBM_LOG_E("can't capture buffer, exist file %s", file);
2017 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2019 _tbm_surface_internal_dump_file_png(file, ptr, stride, h);
2021 TBM_LOG_I("Capture %s \n", file);