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) {
1359 if (!strcmp(old_data->key, key)) {
1360 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1361 TBM_TRACE("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1362 goto add_debug_key_list;
1365 if (old_data->value)
1366 free(old_data->value);
1369 old_data->value = strdup(value);
1371 old_data->value = NULL;
1377 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1379 TBM_TRACE("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1380 _tbm_surface_mutex_unlock();
1384 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1386 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1389 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1390 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1391 if (!strcmp(old_data->key, key)) {
1392 _tbm_surface_mutex_unlock();
1398 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1399 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1401 _tbm_surface_mutex_unlock();
1407 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1409 tbm_surface_debug_data *old_data = NULL;
1411 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1413 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1414 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1415 if (!strcmp(old_data->key, key))
1416 return old_data->value;
1423 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1424 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1426 struct _tbm_surface_dump_buf_info {
1436 tbm_surface_info_s info;
1438 struct list_head link;
1441 struct _tbm_surface_dump_info {
1442 char *path; // copy???
1445 struct list_head *link;
1446 struct list_head surface_list; /* link of surface */
1449 static tbm_surface_dump_info *g_dump_info = NULL;
1450 static const char *dump_postfix[2] = {"png", "yuv"};
1453 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1454 void *data2, int size2, void *data3, int size3)
1456 FILE *fp = fopen(file, "w+");
1457 TBM_RETURN_IF_FAIL(fp != NULL);
1458 unsigned int *blocks;
1460 blocks = (unsigned int *)data1;
1461 fwrite(blocks, 1, size1, fp);
1464 blocks = (unsigned int *)data2;
1465 fwrite(blocks, 1, size2, fp);
1469 blocks = (unsigned int *)data3;
1470 fwrite(blocks, 1, size3, fp);
1477 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height)
1479 unsigned int *blocks = (unsigned int *)data;
1480 FILE *fp = fopen(file, "wb");
1481 TBM_RETURN_IF_FAIL(fp != NULL);
1482 const int pixel_size = 4; // RGBA
1483 png_bytep *row_pointers;
1486 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1493 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1495 png_destroy_write_struct(&pPngStruct, NULL);
1500 png_init_io(pPngStruct, fp);
1501 png_set_IHDR(pPngStruct,
1506 PNG_COLOR_TYPE_RGBA,
1508 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1510 png_set_bgr(pPngStruct);
1511 png_write_info(pPngStruct, pPngInfo);
1513 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1514 if (!row_pointers) {
1515 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1520 for (y = 0; y < height; ++y) {
1524 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1526 for (x = 0; x < y; x++)
1527 png_free(pPngStruct, row_pointers[x]);
1528 png_free(pPngStruct, row_pointers);
1529 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1533 row_pointers[y] = (png_bytep)row;
1535 for (x = 0; x < width; ++x) {
1536 unsigned int curBlock = blocks[y * width + x];
1538 row[x * pixel_size] = (curBlock & 0xFF);
1539 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1540 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1541 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1545 png_write_image(pPngStruct, row_pointers);
1546 png_write_end(pPngStruct, pPngInfo);
1548 for (y = 0; y < height; y++)
1549 png_free(pPngStruct, row_pointers[y]);
1550 png_free(pPngStruct, row_pointers);
1552 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1558 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1560 TBM_RETURN_IF_FAIL(path != NULL);
1561 TBM_RETURN_IF_FAIL(w > 0);
1562 TBM_RETURN_IF_FAIL(h > 0);
1563 TBM_RETURN_IF_FAIL(count > 0);
1565 tbm_surface_dump_buf_info *buf_info = NULL;
1566 tbm_surface_h tbm_surface;
1567 tbm_surface_info_s info;
1572 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1576 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1577 TBM_RETURN_IF_FAIL(g_dump_info);
1579 LIST_INITHEAD(&g_dump_info->surface_list);
1580 g_dump_info->count = 0;
1581 g_dump_info->dump_max = count;
1583 /* get buffer size */
1584 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1585 if (tbm_surface == NULL) {
1586 TBM_LOG_E("tbm_surface_create fail\n");
1592 if (TBM_SURFACE_ERROR_NONE != tbm_surface_map(tbm_surface,
1593 TBM_SURF_OPTION_READ, &info)) {
1594 TBM_LOG_E("tbm_surface_map fail\n");
1595 tbm_surface_destroy(tbm_surface);
1600 buffer_size = info.planes[0].stride * h;
1602 tbm_surface_unmap(tbm_surface);
1603 tbm_surface_destroy(tbm_surface);
1605 /* create dump lists */
1606 for (i = 0; i < count; i++) {
1609 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1610 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1612 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1618 buf_info->index = i;
1620 buf_info->size = buffer_size;
1622 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1625 g_dump_info->path = path;
1626 g_dump_info->link = &g_dump_info->surface_list;
1628 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1633 /* free resources */
1634 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1635 tbm_surface_dump_buf_info *tmp;
1637 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1638 tbm_bo_unref(buf_info->bo);
1639 LIST_DEL(&buf_info->link);
1644 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1653 tbm_surface_internal_dump_end(void)
1655 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1656 tbm_bo_handle bo_handle;
1661 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1668 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1671 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1672 if (bo_handle.ptr == NULL) {
1673 tbm_bo_unref(buf_info->bo);
1674 LIST_DEL(&buf_info->link);
1679 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1680 TBM_LOG_I("Dump File.. %s generated.\n", file);
1682 if (buf_info->dirty) {
1683 void *ptr1 = NULL, *ptr2 = NULL;
1685 switch (buf_info->info.format) {
1686 case TBM_FORMAT_ARGB8888:
1687 case TBM_FORMAT_XRGB8888:
1688 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1689 buf_info->info.planes[0].stride >> 2,
1690 buf_info->info.height);
1692 case TBM_FORMAT_YVU420:
1693 case TBM_FORMAT_YUV420:
1694 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1695 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1696 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1697 buf_info->info.planes[0].stride * buf_info->info.height,
1699 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1701 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1703 case TBM_FORMAT_NV12:
1704 case TBM_FORMAT_NV21:
1705 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1706 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1707 buf_info->info.planes[0].stride * buf_info->info.height,
1709 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1712 case TBM_FORMAT_YUYV:
1713 case TBM_FORMAT_UYVY:
1714 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1715 buf_info->info.planes[0].stride * buf_info->info.height,
1719 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1722 } else if (buf_info->dirty_shm)
1723 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1724 buf_info->shm_stride >> 2,
1727 tbm_bo_unmap(buf_info->bo);
1728 tbm_bo_unref(buf_info->bo);
1729 LIST_DEL(&buf_info->link);
1736 TBM_LOG_I("Dump End..\n");
1740 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1742 TBM_RETURN_IF_FAIL(surface != NULL);
1743 TBM_RETURN_IF_FAIL(type != NULL);
1745 tbm_surface_dump_buf_info *buf_info;
1746 struct list_head *next_link;
1747 tbm_surface_info_s info;
1748 tbm_bo_handle bo_handle;
1749 const char *postfix;
1755 next_link = g_dump_info->link->next;
1756 TBM_RETURN_IF_FAIL(next_link != NULL);
1758 if (next_link == &g_dump_info->surface_list) {
1759 next_link = next_link->next;
1760 TBM_RETURN_IF_FAIL(next_link != NULL);
1763 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1764 TBM_RETURN_IF_FAIL(buf_info != NULL);
1766 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1767 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1769 if (info.size > buf_info->size) {
1770 TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n",
1771 info.size, buf_info->size);
1772 tbm_surface_unmap(surface);
1776 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1777 postfix = dump_postfix[0];
1779 postfix = dump_postfix[1];
1781 /* make the file information */
1782 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1785 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1786 if (!bo_handle.ptr) {
1787 TBM_LOG_E("fail to map bo");
1788 tbm_surface_unmap(surface);
1791 memset(bo_handle.ptr, 0x00, buf_info->size);
1793 switch (info.format) {
1794 case TBM_FORMAT_ARGB8888:
1795 case TBM_FORMAT_XRGB8888:
1796 snprintf(buf_info->name, sizeof(buf_info->name),
1797 "%10.3f_%03d_%p-%s.%s",
1798 _tbm_surface_internal_get_time(),
1799 g_dump_info->count++, surface, type, postfix);
1800 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1802 case TBM_FORMAT_YVU420:
1803 case TBM_FORMAT_YUV420:
1804 snprintf(buf_info->name, sizeof(buf_info->name),
1805 "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1806 _tbm_surface_internal_get_time(),
1807 g_dump_info->count++, type, info.planes[0].stride,
1808 info.height, FOURCC_STR(info.format), postfix);
1809 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1810 bo_handle.ptr += info.planes[0].stride * info.height;
1811 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1812 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1813 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1815 case TBM_FORMAT_NV12:
1816 case TBM_FORMAT_NV21:
1817 snprintf(buf_info->name, sizeof(buf_info->name),
1818 "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1819 _tbm_surface_internal_get_time(),
1820 g_dump_info->count++, type, info.planes[0].stride,
1821 info.height, FOURCC_STR(info.format), postfix);
1822 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1823 bo_handle.ptr += info.planes[0].stride * info.height;
1824 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1826 case TBM_FORMAT_YUYV:
1827 case TBM_FORMAT_UYVY:
1828 snprintf(buf_info->name, sizeof(buf_info->name),
1829 "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1830 _tbm_surface_internal_get_time(),
1831 g_dump_info->count++, type, info.planes[0].stride,
1832 info.height, FOURCC_STR(info.format), postfix);
1833 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1836 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1837 tbm_bo_unmap(buf_info->bo);
1838 tbm_surface_unmap(surface);
1842 tbm_bo_unmap(buf_info->bo);
1844 tbm_surface_unmap(surface);
1846 buf_info->dirty = 1;
1847 buf_info->dirty_shm = 0;
1849 if (g_dump_info->count == 1000)
1850 g_dump_info->count = 0;
1852 g_dump_info->link = next_link;
1854 TBM_LOG_I("Dump %s \n", buf_info->name);
1857 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
1860 TBM_RETURN_IF_FAIL(ptr != NULL);
1861 TBM_RETURN_IF_FAIL(w > 0);
1862 TBM_RETURN_IF_FAIL(h > 0);
1863 TBM_RETURN_IF_FAIL(stride > 0);
1864 TBM_RETURN_IF_FAIL(type != NULL);
1866 tbm_surface_dump_buf_info *buf_info;
1867 struct list_head *next_link;
1868 tbm_bo_handle bo_handle;
1874 next_link = g_dump_info->link->next;
1875 TBM_RETURN_IF_FAIL(next_link != NULL);
1877 if (next_link == &g_dump_info->surface_list) {
1878 next_link = next_link->next;
1879 TBM_RETURN_IF_FAIL(next_link != NULL);
1882 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1883 TBM_RETURN_IF_FAIL(buf_info != NULL);
1886 if (size > buf_info->size) {
1887 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n",
1888 size, buf_info->size);
1893 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1894 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1896 memset(bo_handle.ptr, 0x00, buf_info->size);
1897 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1899 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1900 _tbm_surface_internal_get_time(),
1901 g_dump_info->count++, type, dump_postfix[0]);
1902 memcpy(bo_handle.ptr, ptr, size);
1904 tbm_bo_unmap(buf_info->bo);
1906 buf_info->dirty = 0;
1907 buf_info->dirty_shm = 1;
1908 buf_info->shm_stride = stride;
1909 buf_info->shm_h = h;
1911 if (g_dump_info->count == 1000)
1912 g_dump_info->count = 0;
1914 g_dump_info->link = next_link;
1916 TBM_LOG_I("Dump %s \n", buf_info->name);
1920 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
1922 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
1923 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
1924 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
1926 tbm_surface_info_s info;
1927 const char *postfix;
1931 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1932 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
1934 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1935 postfix = dump_postfix[0];
1937 postfix = dump_postfix[1];
1939 if (strcmp(postfix, type)) {
1940 TBM_LOG_E("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
1941 tbm_surface_unmap(surface);
1945 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
1947 if (!access(file, 0)) {
1948 TBM_LOG_E("can't capture buffer, exist file %s", file);
1949 tbm_surface_unmap(surface);
1953 switch (info.format) {
1954 case TBM_FORMAT_ARGB8888:
1955 case TBM_FORMAT_XRGB8888:
1956 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
1957 info.planes[0].stride >> 2,
1960 case TBM_FORMAT_YVU420:
1961 case TBM_FORMAT_YUV420:
1962 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
1963 info.planes[0].stride * info.height,
1965 info.planes[1].stride * (info.height >> 1),
1967 info.planes[2].stride * (info.height >> 1));
1969 case TBM_FORMAT_NV12:
1970 case TBM_FORMAT_NV21:
1971 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
1972 info.planes[0].stride * info.height,
1974 info.planes[1].stride * (info.height >> 1),
1977 case TBM_FORMAT_YUYV:
1978 case TBM_FORMAT_UYVY:
1979 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
1980 info.planes[0].stride * info.height,
1984 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
1985 tbm_surface_unmap(surface);
1989 tbm_surface_unmap(surface);
1991 TBM_LOG_I("Capture %s \n", file);
1997 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
1998 const char *path, const char *name, const char *type)
2000 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2001 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2002 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2003 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2004 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2005 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2009 if (strcmp(dump_postfix[0], type)) {
2010 TBM_LOG_E("Not supported type:%s'", type);
2014 if (!access(file, 0)) {
2015 TBM_LOG_E("can't capture buffer, exist file %s", file);
2019 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2021 _tbm_surface_internal_dump_file_png(file, ptr, stride, h);
2023 TBM_LOG_I("Capture %s \n", file);