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_query_plane_data(tbm_surface_h surface,
273 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
275 TBM_RETURN_VAL_IF_FAIL(surface, 0);
276 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
278 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
279 struct _tbm_bufmgr *mgr = surf->bufmgr;
282 TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
283 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
284 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
285 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
287 if (!mgr->backend->surface_get_plane_data)
290 ret = mgr->backend->surface_get_plane_data(surf->info.width,
291 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
299 _tbm_surface_internal_destroy(tbm_surface_h surface)
302 tbm_bufmgr bufmgr = surface->bufmgr;
303 tbm_user_data *old_data = NULL, *tmp = NULL;
304 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
306 /* destory the user_data_list */
307 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
308 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
309 TBM_DBG("free user_data\n");
310 user_data_delete(old_data);
314 for (i = 0; i < surface->num_bos; i++) {
315 surface->bos[i]->surface = NULL;
317 tbm_bo_unref(surface->bos[i]);
318 surface->bos[i] = NULL;
321 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
322 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
323 _tbm_surface_internal_debug_data_delete(debug_old_data);
326 LIST_DEL(&surface->item_link);
331 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
332 LIST_DELINIT(&bufmgr->surf_list);
334 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
335 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
336 _tbm_surface_internal_debug_data_delete(debug_old_data);
340 _deinit_surface_bufmgr();
345 tbm_surface_internal_is_valid(tbm_surface_h surface)
347 tbm_surface_h old_data = NULL;
349 if (surface == NULL || g_surface_bufmgr == NULL) {
350 TBM_TRACE("error: tbm_surface(%p)\n", surface);
354 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
355 LIST_FOR_EACH_ENTRY(old_data, &g_surface_bufmgr->surf_list, item_link) {
356 if (old_data == surface) {
357 TBM_TRACE("tbm_surface(%p)\n", surface);
362 TBM_TRACE("error: tbm_surface(%p)\n", surface);
367 tbm_surface_internal_query_supported_formats(uint32_t **formats,
370 struct _tbm_bufmgr *mgr;
373 _tbm_surface_mutex_lock();
375 if (!g_surface_bufmgr) {
376 _init_surface_bufmgr();
377 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
380 mgr = g_surface_bufmgr;
382 if (!mgr->backend->surface_supported_format) {
383 TBM_TRACE("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
384 _tbm_surface_mutex_unlock();
388 ret = mgr->backend->surface_supported_format(formats, num);
390 TBM_TRACE("tbm_bufmgr(%p) format num(%d)\n", g_surface_bufmgr, *num);
392 _tbm_surface_mutex_unlock();
398 tbm_surface_internal_get_num_planes(tbm_format format)
404 case TBM_FORMAT_RGB332:
405 case TBM_FORMAT_BGR233:
406 case TBM_FORMAT_XRGB4444:
407 case TBM_FORMAT_XBGR4444:
408 case TBM_FORMAT_RGBX4444:
409 case TBM_FORMAT_BGRX4444:
410 case TBM_FORMAT_ARGB4444:
411 case TBM_FORMAT_ABGR4444:
412 case TBM_FORMAT_RGBA4444:
413 case TBM_FORMAT_BGRA4444:
414 case TBM_FORMAT_XRGB1555:
415 case TBM_FORMAT_XBGR1555:
416 case TBM_FORMAT_RGBX5551:
417 case TBM_FORMAT_BGRX5551:
418 case TBM_FORMAT_ARGB1555:
419 case TBM_FORMAT_ABGR1555:
420 case TBM_FORMAT_RGBA5551:
421 case TBM_FORMAT_BGRA5551:
422 case TBM_FORMAT_RGB565:
423 case TBM_FORMAT_BGR565:
424 case TBM_FORMAT_RGB888:
425 case TBM_FORMAT_BGR888:
426 case TBM_FORMAT_XRGB8888:
427 case TBM_FORMAT_XBGR8888:
428 case TBM_FORMAT_RGBX8888:
429 case TBM_FORMAT_BGRX8888:
430 case TBM_FORMAT_ARGB8888:
431 case TBM_FORMAT_ABGR8888:
432 case TBM_FORMAT_RGBA8888:
433 case TBM_FORMAT_BGRA8888:
434 case TBM_FORMAT_XRGB2101010:
435 case TBM_FORMAT_XBGR2101010:
436 case TBM_FORMAT_RGBX1010102:
437 case TBM_FORMAT_BGRX1010102:
438 case TBM_FORMAT_ARGB2101010:
439 case TBM_FORMAT_ABGR2101010:
440 case TBM_FORMAT_RGBA1010102:
441 case TBM_FORMAT_BGRA1010102:
442 case TBM_FORMAT_YUYV:
443 case TBM_FORMAT_YVYU:
444 case TBM_FORMAT_UYVY:
445 case TBM_FORMAT_VYUY:
446 case TBM_FORMAT_AYUV:
449 case TBM_FORMAT_NV12:
450 case TBM_FORMAT_NV12MT:
451 case TBM_FORMAT_NV21:
452 case TBM_FORMAT_NV16:
453 case TBM_FORMAT_NV61:
456 case TBM_FORMAT_YUV410:
457 case TBM_FORMAT_YVU410:
458 case TBM_FORMAT_YUV411:
459 case TBM_FORMAT_YVU411:
460 case TBM_FORMAT_YUV420:
461 case TBM_FORMAT_YVU420:
462 case TBM_FORMAT_YUV422:
463 case TBM_FORMAT_YVU422:
464 case TBM_FORMAT_YUV444:
465 case TBM_FORMAT_YVU444:
473 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
479 tbm_surface_internal_get_bpp(tbm_format format)
486 case TBM_FORMAT_RGB332:
487 case TBM_FORMAT_BGR233:
490 case TBM_FORMAT_XRGB4444:
491 case TBM_FORMAT_XBGR4444:
492 case TBM_FORMAT_RGBX4444:
493 case TBM_FORMAT_BGRX4444:
494 case TBM_FORMAT_ARGB4444:
495 case TBM_FORMAT_ABGR4444:
496 case TBM_FORMAT_RGBA4444:
497 case TBM_FORMAT_BGRA4444:
498 case TBM_FORMAT_XRGB1555:
499 case TBM_FORMAT_XBGR1555:
500 case TBM_FORMAT_RGBX5551:
501 case TBM_FORMAT_BGRX5551:
502 case TBM_FORMAT_ARGB1555:
503 case TBM_FORMAT_ABGR1555:
504 case TBM_FORMAT_RGBA5551:
505 case TBM_FORMAT_BGRA5551:
506 case TBM_FORMAT_RGB565:
507 case TBM_FORMAT_BGR565:
510 case TBM_FORMAT_RGB888:
511 case TBM_FORMAT_BGR888:
514 case TBM_FORMAT_XRGB8888:
515 case TBM_FORMAT_XBGR8888:
516 case TBM_FORMAT_RGBX8888:
517 case TBM_FORMAT_BGRX8888:
518 case TBM_FORMAT_ARGB8888:
519 case TBM_FORMAT_ABGR8888:
520 case TBM_FORMAT_RGBA8888:
521 case TBM_FORMAT_BGRA8888:
522 case TBM_FORMAT_XRGB2101010:
523 case TBM_FORMAT_XBGR2101010:
524 case TBM_FORMAT_RGBX1010102:
525 case TBM_FORMAT_BGRX1010102:
526 case TBM_FORMAT_ARGB2101010:
527 case TBM_FORMAT_ABGR2101010:
528 case TBM_FORMAT_RGBA1010102:
529 case TBM_FORMAT_BGRA1010102:
530 case TBM_FORMAT_YUYV:
531 case TBM_FORMAT_YVYU:
532 case TBM_FORMAT_UYVY:
533 case TBM_FORMAT_VYUY:
534 case TBM_FORMAT_AYUV:
537 case TBM_FORMAT_NV12:
538 case TBM_FORMAT_NV12MT:
539 case TBM_FORMAT_NV21:
542 case TBM_FORMAT_NV16:
543 case TBM_FORMAT_NV61:
546 case TBM_FORMAT_YUV410:
547 case TBM_FORMAT_YVU410:
550 case TBM_FORMAT_YUV411:
551 case TBM_FORMAT_YVU411:
552 case TBM_FORMAT_YUV420:
553 case TBM_FORMAT_YVU420:
556 case TBM_FORMAT_YUV422:
557 case TBM_FORMAT_YVU422:
560 case TBM_FORMAT_YUV444:
561 case TBM_FORMAT_YVU444:
568 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
574 tbm_surface_internal_create_with_flags(int width, int height,
575 int format, int flags)
577 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
578 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
580 struct _tbm_bufmgr *mgr;
581 struct _tbm_surface *surf = NULL;
585 uint32_t bo_size = 0;
588 bool bufmgr_initialized = false;
590 _tbm_surface_mutex_lock();
592 if (!g_surface_bufmgr) {
593 _init_surface_bufmgr();
594 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
595 bufmgr_initialized = true;
598 mgr = g_surface_bufmgr;
599 if (!TBM_BUFMGR_IS_VALID(mgr)) {
600 TBM_LOG_E("The bufmgr is invalid\n");
601 goto check_valid_fail;
604 surf = calloc(1, sizeof(struct _tbm_surface));
606 TBM_LOG_E("fail to alloc surf\n");
607 goto alloc_surf_fail;
611 surf->info.width = width;
612 surf->info.height = height;
613 surf->info.format = format;
614 surf->info.bpp = tbm_surface_internal_get_bpp(format);
615 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
618 /* get size, stride and offset bo_idx */
619 for (i = 0; i < surf->info.num_planes; i++) {
620 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
621 &offset, &stride, &bo_idx)) {
622 TBM_LOG_E("fail to query plane data\n");
623 goto query_plane_data_fail;
626 surf->info.planes[i].size = size;
627 surf->info.planes[i].offset = offset;
628 surf->info.planes[i].stride = stride;
629 surf->planes_bo_idx[i] = bo_idx;
634 for (i = 0; i < surf->info.num_planes; i++) {
635 surf->info.size += surf->info.planes[i].size;
637 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
638 surf->num_bos = surf->planes_bo_idx[i] + 1;
643 for (i = 0; i < surf->num_bos; i++) {
645 for (j = 0; j < surf->info.num_planes; j++) {
646 if (surf->planes_bo_idx[j] == i)
647 bo_size += surf->info.planes[j].size;
650 if (mgr->backend->surface_bo_alloc) {
651 /* LCOV_EXCL_START */
653 void *bo_priv = NULL;
655 bo = calloc(1, sizeof(struct _tbm_bo));
657 TBM_LOG_E("fail to alloc bo struct\n");
661 bo->bufmgr = surf->bufmgr;
663 pthread_mutex_lock(&surf->bufmgr->lock);
665 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
667 TBM_LOG_E("fail to alloc bo priv\n");
669 pthread_mutex_unlock(&surf->bufmgr->lock);
677 LIST_INITHEAD(&bo->user_data_list);
679 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
681 pthread_mutex_unlock(&surf->bufmgr->lock);
686 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
688 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
693 _tbm_bo_set_surface(surf->bos[i], surf);
696 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
697 _tbm_surface_internal_format_to_str(format), flags, surf);
699 LIST_INITHEAD(&surf->user_data_list);
700 LIST_INITHEAD(&surf->debug_data_list);
702 LIST_ADD(&surf->item_link, &mgr->surf_list);
704 _tbm_surface_mutex_unlock();
709 for (j = 0; j < i; j++) {
711 tbm_bo_unref(surf->bos[j]);
713 query_plane_data_fail:
717 if (bufmgr_initialized) {
718 LIST_DELINIT(&mgr->surf_list);
719 _deinit_surface_bufmgr();
721 _tbm_surface_mutex_unlock();
722 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
724 _tbm_surface_internal_format_to_str(format), flags);
729 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
730 tbm_bo *bos, int num)
732 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
733 TBM_RETURN_VAL_IF_FAIL(info, NULL);
734 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
736 struct _tbm_bufmgr *mgr;
737 struct _tbm_surface *surf = NULL;
740 _tbm_surface_mutex_lock();
742 if (!g_surface_bufmgr) {
743 _init_surface_bufmgr();
744 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
747 mgr = g_surface_bufmgr;
748 if (!TBM_BUFMGR_IS_VALID(mgr)) {
749 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
750 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
751 _tbm_surface_mutex_unlock();
755 surf = calloc(1, sizeof(struct _tbm_surface));
757 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
758 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
759 _tbm_surface_mutex_unlock();
764 surf->info.width = info->width;
765 surf->info.height = info->height;
766 surf->info.format = info->format;
767 surf->info.bpp = info->bpp;
768 surf->info.num_planes = info->num_planes;
771 /* get size, stride and offset */
772 for (i = 0; i < info->num_planes; i++) {
773 surf->info.planes[i].offset = info->planes[i].offset;
774 surf->info.planes[i].stride = info->planes[i].stride;
776 if (info->planes[i].size > 0)
777 surf->info.planes[i].size = info->planes[i].size;
779 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
782 surf->planes_bo_idx[i] = 0;
784 surf->planes_bo_idx[i] = i;
787 if (info->size > 0) {
788 surf->info.size = info->size;
791 for (i = 0; i < info->num_planes; i++)
792 surf->info.size += surf->info.planes[i].size;
795 surf->flags = TBM_BO_DEFAULT;
797 /* create only one bo */
799 for (i = 0; i < num; i++) {
803 surf->bos[i] = tbm_bo_ref(bos[i]);
804 _tbm_bo_set_surface(bos[i], surf);
807 TBM_TRACE("tbm_surface(%p) width(%d) height(%d) format(%s) bo_num(%d)\n", surf,
808 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
810 LIST_INITHEAD(&surf->user_data_list);
811 LIST_INITHEAD(&surf->debug_data_list);
813 LIST_ADD(&surf->item_link, &mgr->surf_list);
815 _tbm_surface_mutex_unlock();
819 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
820 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
821 for (i = 0; i < num; i++) {
823 tbm_bo_unref(surf->bos[i]);
831 if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
832 LIST_DELINIT(&g_surface_bufmgr->surf_list);
833 _deinit_surface_bufmgr();
836 _tbm_surface_mutex_unlock();
842 tbm_surface_internal_destroy(tbm_surface_h surface)
844 _tbm_surface_mutex_lock();
846 TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
850 if (surface->refcnt > 0) {
851 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
852 _tbm_surface_mutex_unlock();
856 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
858 if (surface->refcnt == 0)
859 _tbm_surface_internal_destroy(surface);
861 _tbm_surface_mutex_unlock();
865 tbm_surface_internal_ref(tbm_surface_h surface)
867 _tbm_surface_mutex_lock();
869 TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
873 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
875 _tbm_surface_mutex_unlock();
879 tbm_surface_internal_unref(tbm_surface_h surface)
881 _tbm_surface_mutex_lock();
883 TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
887 if (surface->refcnt > 0) {
888 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
889 _tbm_surface_mutex_unlock();
893 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
895 if (surface->refcnt == 0)
896 _tbm_surface_internal_destroy(surface);
898 _tbm_surface_mutex_unlock();
902 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
904 struct _tbm_surface *surf;
907 _tbm_surface_mutex_lock();
909 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
911 surf = (struct _tbm_surface *)surface;
914 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
916 _tbm_surface_mutex_unlock();
922 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
924 struct _tbm_surface *surf;
927 _tbm_surface_mutex_lock();
929 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
930 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
932 surf = (struct _tbm_surface *)surface;
933 bo = surf->bos[bo_idx];
935 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
937 _tbm_surface_mutex_unlock();
943 tbm_surface_internal_get_size(tbm_surface_h surface)
945 struct _tbm_surface *surf;
948 _tbm_surface_mutex_lock();
950 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
952 surf = (struct _tbm_surface *)surface;
953 size = surf->info.size;
955 TBM_TRACE("tbm_surface(%p) size(%d)\n", surface, size);
957 _tbm_surface_mutex_unlock();
963 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
964 uint32_t *size, uint32_t *offset, uint32_t *pitch)
966 struct _tbm_surface *surf;
968 _tbm_surface_mutex_lock();
970 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
971 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
973 surf = (struct _tbm_surface *)surface;
975 if (plane_idx >= surf->info.num_planes) {
976 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
977 _tbm_surface_mutex_unlock();
982 *size = surf->info.planes[plane_idx].size;
985 *offset = surf->info.planes[plane_idx].offset;
988 *pitch = surf->info.planes[plane_idx].stride;
990 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%d) offset(%d) pitch(%d)\n", surface, plane_idx,
991 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
992 surf->info.planes[plane_idx].stride);
994 _tbm_surface_mutex_unlock();
1000 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1001 tbm_surface_info_s *info, int map)
1003 struct _tbm_surface *surf;
1004 tbm_bo_handle bo_handles[4];
1007 _tbm_surface_mutex_lock();
1009 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1011 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1013 surf = (struct _tbm_surface *)surface;
1015 memset(info, 0x00, sizeof(tbm_surface_info_s));
1016 info->width = surf->info.width;
1017 info->height = surf->info.height;
1018 info->format = surf->info.format;
1019 info->bpp = surf->info.bpp;
1020 info->size = surf->info.size;
1021 info->num_planes = surf->info.num_planes;
1024 for (i = 0; i < surf->num_bos; i++) {
1025 _tbm_surface_mutex_unlock();
1026 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1027 _tbm_surface_mutex_lock();
1028 if (bo_handles[i].ptr == NULL) {
1029 for (j = 0; j < i; j++)
1030 tbm_bo_unmap(surf->bos[j]);
1032 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1033 _tbm_surface_mutex_unlock();
1038 for (i = 0; i < surf->num_bos; i++)
1039 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1042 for (i = 0; i < surf->info.num_planes; i++) {
1043 info->planes[i].size = surf->info.planes[i].size;
1044 info->planes[i].offset = surf->info.planes[i].offset;
1045 info->planes[i].stride = surf->info.planes[i].stride;
1047 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1048 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1049 surf->info.planes[i].offset;
1052 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1054 _tbm_surface_mutex_unlock();
1060 tbm_surface_internal_unmap(tbm_surface_h surface)
1062 struct _tbm_surface *surf;
1065 _tbm_surface_mutex_lock();
1067 TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1069 surf = (struct _tbm_surface *)surface;
1071 for (i = 0; i < surf->num_bos; i++)
1072 tbm_bo_unmap(surf->bos[i]);
1074 TBM_TRACE("tbm_surface(%p)\n", surface);
1076 _tbm_surface_mutex_unlock();
1080 tbm_surface_internal_get_width(tbm_surface_h surface)
1082 struct _tbm_surface *surf;
1085 _tbm_surface_mutex_lock();
1087 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1089 surf = (struct _tbm_surface *)surface;
1090 width = surf->info.width;
1092 TBM_TRACE("tbm_surface(%p) width(%d)\n", surface, width);
1094 _tbm_surface_mutex_unlock();
1100 tbm_surface_internal_get_height(tbm_surface_h surface)
1102 struct _tbm_surface *surf;
1103 unsigned int height;
1105 _tbm_surface_mutex_lock();
1107 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1109 surf = (struct _tbm_surface *)surface;
1110 height = surf->info.height;
1112 TBM_TRACE("tbm_surface(%p) height(%d)\n", surface, height);
1114 _tbm_surface_mutex_unlock();
1121 tbm_surface_internal_get_format(tbm_surface_h surface)
1123 struct _tbm_surface *surf;
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 format = surf->info.format;
1133 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1135 _tbm_surface_mutex_unlock();
1141 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1143 struct _tbm_surface *surf;
1146 _tbm_surface_mutex_lock();
1148 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1149 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1151 surf = (struct _tbm_surface *)surface;
1152 bo_idx = surf->planes_bo_idx[plane_idx];
1154 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1156 _tbm_surface_mutex_unlock();
1162 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1163 tbm_data_free data_free_func)
1165 tbm_user_data *data;
1167 _tbm_surface_mutex_lock();
1169 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1171 /* check if the data according to the key exist if so, return false. */
1172 data = user_data_lookup(&surface->user_data_list, key);
1174 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1175 _tbm_surface_mutex_unlock();
1179 data = user_data_create(key, data_free_func);
1181 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1182 _tbm_surface_mutex_unlock();
1186 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1188 LIST_ADD(&data->item_link, &surface->user_data_list);
1190 _tbm_surface_mutex_unlock();
1196 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1199 tbm_user_data *old_data;
1201 _tbm_surface_mutex_lock();
1203 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1205 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1206 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1207 _tbm_surface_mutex_unlock();
1211 old_data = user_data_lookup(&surface->user_data_list, key);
1213 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1214 _tbm_surface_mutex_unlock();
1218 if (old_data->data && old_data->free_func)
1219 old_data->free_func(old_data->data);
1221 old_data->data = data;
1223 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1225 _tbm_surface_mutex_unlock();
1231 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1234 tbm_user_data *old_data;
1236 _tbm_surface_mutex_lock();
1238 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1240 if (!data || LIST_IS_EMPTY(&surface->user_data_list)) {
1241 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1242 _tbm_surface_mutex_unlock();
1246 old_data = user_data_lookup(&surface->user_data_list, key);
1248 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1250 _tbm_surface_mutex_unlock();
1254 *data = old_data->data;
1256 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1258 _tbm_surface_mutex_unlock();
1264 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1267 tbm_user_data *old_data = (void *)0;
1269 _tbm_surface_mutex_lock();
1271 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1273 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1274 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1275 _tbm_surface_mutex_unlock();
1279 old_data = user_data_lookup(&surface->user_data_list, key);
1281 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1282 _tbm_surface_mutex_unlock();
1286 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1288 user_data_delete(old_data);
1290 _tbm_surface_mutex_unlock();
1295 /* LCOV_EXCL_START */
1297 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1299 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1301 return surface->debug_pid;
1305 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1307 _tbm_surface_mutex_lock();
1309 TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1311 surface->debug_pid = pid;
1313 _tbm_surface_mutex_unlock();
1316 static tbm_surface_debug_data *
1317 _tbm_surface_internal_debug_data_create(char *key, char *value)
1319 tbm_surface_debug_data *debug_data = NULL;
1321 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1325 if (key) debug_data->key = strdup(key);
1326 if (value) debug_data->value = strdup(value);
1332 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1334 tbm_surface_debug_data *debug_data = NULL;
1335 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1336 tbm_bufmgr bufmgr = NULL;
1338 _tbm_surface_mutex_lock();
1340 TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1341 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1343 bufmgr = surface->bufmgr;
1345 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1347 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1348 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1349 if (!strcmp(old_data->key, key)) {
1351 old_data->value = strdup(value);
1353 old_data->value = NULL;
1358 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1360 TBM_TRACE("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1361 _tbm_surface_mutex_unlock();
1365 TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1367 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1369 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1370 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1371 if (!strcmp(old_data->key, key)) {
1372 _tbm_surface_mutex_unlock();
1378 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1379 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1381 _tbm_surface_mutex_unlock();
1387 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1389 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1391 _tbm_surface_mutex_lock();
1393 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1395 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1396 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1397 if (!strcmp(old_data->key, key)) {
1398 _tbm_surface_mutex_unlock();
1399 return old_data->value;
1404 _tbm_surface_mutex_unlock();
1409 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1410 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1412 struct _tbm_surface_dump_buf_info {
1422 tbm_surface_info_s info;
1424 struct list_head link;
1427 struct _tbm_surface_dump_info {
1428 char *path; // copy???
1431 struct list_head *link;
1432 struct list_head surface_list; /* link of surface */
1435 static tbm_surface_dump_info *g_dump_info = NULL;
1436 static const char *dump_postfix[2] = {"png", "yuv"};
1439 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1440 int size2, void *data3, int size3)
1442 unsigned int *blocks;
1443 FILE *fp = fopen(file, "w+");
1444 TBM_RETURN_IF_FAIL(fp != NULL);
1446 blocks = (unsigned int *)data1;
1447 fwrite(blocks, 1, size1, fp);
1450 blocks = (unsigned int *)data2;
1451 fwrite(blocks, 1, size2, fp);
1455 blocks = (unsigned int *)data3;
1456 fwrite(blocks, 1, size3, fp);
1463 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1466 FILE *fp = fopen(file, "wb");
1467 TBM_RETURN_IF_FAIL(fp != NULL);
1470 png_structp pPngStruct =
1471 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1477 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1479 png_destroy_write_struct(&pPngStruct, NULL);
1484 png_init_io(pPngStruct, fp);
1485 png_set_IHDR(pPngStruct,
1490 PNG_COLOR_TYPE_RGBA,
1492 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1494 png_set_bgr(pPngStruct);
1495 png_write_info(pPngStruct, pPngInfo);
1497 const int pixel_size = 4; // RGBA
1498 png_bytep *row_pointers =
1499 png_malloc(pPngStruct, height * sizeof(png_byte *));
1501 unsigned int *blocks = (unsigned int *)data;
1505 for (; y < height; ++y) {
1507 png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1508 row_pointers[y] = (png_bytep)row;
1509 for (x = 0; x < width; ++x) {
1510 unsigned int curBlock = blocks[y * width + x];
1511 row[x * pixel_size] = (curBlock & 0xFF);
1512 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1513 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1514 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1518 png_write_image(pPngStruct, row_pointers);
1519 png_write_end(pPngStruct, pPngInfo);
1521 for (y = 0; y < height; y++)
1522 png_free(pPngStruct, row_pointers[y]);
1523 png_free(pPngStruct, row_pointers);
1525 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1531 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1533 TBM_RETURN_IF_FAIL(path != NULL);
1534 TBM_RETURN_IF_FAIL(w > 0);
1535 TBM_RETURN_IF_FAIL(h > 0);
1536 TBM_RETURN_IF_FAIL(count > 0);
1538 tbm_surface_dump_buf_info *buf_info = NULL;
1539 tbm_surface_dump_buf_info *tmp;
1543 tbm_surface_h tbm_surface;
1544 tbm_surface_info_s info;
1545 tbm_surface_error_e err;
1549 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1553 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1554 TBM_RETURN_IF_FAIL(g_dump_info);
1556 LIST_INITHEAD(&g_dump_info->surface_list);
1557 g_dump_info->count = 0;
1558 g_dump_info->dump_max = count;
1560 /* get buffer size */
1561 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1562 if (tbm_surface == NULL) {
1563 TBM_LOG_E("tbm_surface_create fail\n");
1568 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
1569 if (err != TBM_SURFACE_ERROR_NONE) {
1570 TBM_LOG_E("tbm_surface_map fail\n");
1571 tbm_surface_destroy(tbm_surface);
1576 buffer_size = info.planes[0].stride * h;
1577 tbm_surface_unmap(tbm_surface);
1578 tbm_surface_destroy(tbm_surface);
1580 /* create dump lists */
1581 for (i = 0; i < count; i++) {
1582 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1583 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1584 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1590 buf_info->index = i;
1592 buf_info->size = buffer_size;
1594 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1597 g_dump_info->path = path;
1598 g_dump_info->link = &g_dump_info->surface_list;
1600 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1604 /* free resources */
1605 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1606 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1607 tbm_bo_unref(buf_info->bo);
1612 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1621 tbm_surface_internal_dump_end(void)
1623 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1624 tbm_bo_handle bo_handle;
1630 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1631 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1634 if (buf_info->dirty) {
1638 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1639 if (bo_handle.ptr == NULL)
1642 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1643 TBM_LOG_I("Dump File.. %s generated.\n", file);
1645 switch (buf_info->info.format) {
1646 case TBM_FORMAT_ARGB8888:
1647 case TBM_FORMAT_XRGB8888:
1648 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1649 buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1651 case TBM_FORMAT_YVU420:
1652 case TBM_FORMAT_YUV420:
1653 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1654 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1655 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1656 buf_info->info.planes[0].stride * buf_info->info.height,
1658 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1660 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1662 case TBM_FORMAT_NV12:
1663 case TBM_FORMAT_NV21:
1664 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1665 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1666 buf_info->info.planes[0].stride * buf_info->info.height,
1668 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1671 case TBM_FORMAT_YUYV:
1672 case TBM_FORMAT_UYVY:
1673 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1674 buf_info->info.planes[0].stride * buf_info->info.height,
1678 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1679 tbm_bo_unmap(buf_info->bo);
1683 tbm_bo_unmap(buf_info->bo);
1684 } else if (buf_info->dirty_shm) {
1685 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1686 if (bo_handle.ptr == NULL)
1689 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1690 TBM_LOG_I("Dump File.. %s generated.\n", file);
1692 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1693 buf_info->shm_stride >> 2, buf_info->shm_h);
1695 tbm_bo_unmap(buf_info->bo);
1700 /* free resources */
1701 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1702 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1703 tbm_bo_unref(buf_info->bo);
1711 TBM_LOG_I("Dump End..\n");
1715 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1717 TBM_RETURN_IF_FAIL(surface != NULL);
1718 TBM_RETURN_IF_FAIL(type != NULL);
1720 tbm_surface_dump_buf_info *buf_info;
1721 tbm_surface_info_s info;
1722 struct list_head *next_link;
1723 tbm_bo_handle bo_handle;
1725 const char *postfix;
1730 next_link = g_dump_info->link->next;
1731 TBM_RETURN_IF_FAIL(next_link != NULL);
1733 if (next_link == &g_dump_info->surface_list) {
1734 next_link = next_link->next;
1735 TBM_RETURN_IF_FAIL(next_link != NULL);
1738 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1739 TBM_RETURN_IF_FAIL(buf_info != NULL);
1741 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1742 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1744 if (info.size > buf_info->size) {
1745 TBM_LOG_W("Dump skip. surface over created buffer size(%d, %d)\n", info.size, buf_info->size);
1746 tbm_surface_unmap(surface);
1750 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1751 postfix = dump_postfix[0];
1753 postfix = dump_postfix[1];
1755 /* make the file information */
1756 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1759 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1760 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1761 memset(bo_handle.ptr, 0x00, buf_info->size);
1763 switch (info.format) {
1764 case TBM_FORMAT_ARGB8888:
1765 case TBM_FORMAT_XRGB8888:
1766 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d_%p-%s.%s",
1767 _tbm_surface_internal_get_time(),
1768 g_dump_info->count++, surface, type, postfix);
1769 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1771 case TBM_FORMAT_YVU420:
1772 case TBM_FORMAT_YUV420:
1773 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1774 _tbm_surface_internal_get_time(),
1775 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1776 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1777 bo_handle.ptr += info.planes[0].stride * info.height;
1778 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1779 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1780 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1782 case TBM_FORMAT_NV12:
1783 case TBM_FORMAT_NV21:
1784 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1785 _tbm_surface_internal_get_time(),
1786 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1787 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1788 bo_handle.ptr += info.planes[0].stride * info.height;
1789 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1791 case TBM_FORMAT_YUYV:
1792 case TBM_FORMAT_UYVY:
1793 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1794 _tbm_surface_internal_get_time(),
1795 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1796 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1799 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1800 tbm_bo_unmap(buf_info->bo);
1804 tbm_bo_unmap(buf_info->bo);
1806 tbm_surface_unmap(surface);
1808 buf_info->dirty = 1;
1809 buf_info->dirty_shm = 0;
1811 if (g_dump_info->count == 1000)
1812 g_dump_info->count = 0;
1814 g_dump_info->link = next_link;
1816 TBM_LOG_I("Dump %s \n", buf_info->name);
1819 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, const char *type)
1821 TBM_RETURN_IF_FAIL(ptr != NULL);
1822 TBM_RETURN_IF_FAIL(w > 0);
1823 TBM_RETURN_IF_FAIL(h > 0);
1824 TBM_RETURN_IF_FAIL(stride > 0);
1825 TBM_RETURN_IF_FAIL(type != NULL);
1827 tbm_surface_dump_buf_info *buf_info;
1828 struct list_head *next_link;
1829 tbm_bo_handle bo_handle;
1834 next_link = g_dump_info->link->next;
1835 TBM_RETURN_IF_FAIL(next_link != NULL);
1837 if (next_link == &g_dump_info->surface_list) {
1838 next_link = next_link->next;
1839 TBM_RETURN_IF_FAIL(next_link != NULL);
1842 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1843 TBM_RETURN_IF_FAIL(buf_info != NULL);
1845 if (stride * h > buf_info->size) {
1846 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", stride * h, buf_info->size);
1851 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1852 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1853 memset(bo_handle.ptr, 0x00, buf_info->size);
1854 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1856 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1857 _tbm_surface_internal_get_time(),
1858 g_dump_info->count++, type, dump_postfix[0]);
1859 memcpy(bo_handle.ptr, ptr, stride * h);
1861 tbm_bo_unmap(buf_info->bo);
1863 buf_info->dirty = 0;
1864 buf_info->dirty_shm = 1;
1865 buf_info->shm_stride = stride;
1866 buf_info->shm_h = h;
1868 if (g_dump_info->count == 1000)
1869 g_dump_info->count = 0;
1871 g_dump_info->link = next_link;
1873 TBM_LOG_I("Dump %s \n", buf_info->name);