1 /**************************************************************************
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
36 #include "tbm_bufmgr.h"
37 #include "tbm_bufmgr_int.h"
38 #include "tbm_surface_internal.h"
42 #define C(b, m) (((b) >> (m)) & 0xFF)
43 #define B(c, s) ((((unsigned int)(c)) & 0xff) << (s))
44 #define FOURCC(a, b, c, d) (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
45 #define FOURCC_STR(id) C(id, 0), C(id, 8), C(id, 16), C(id, 24)
46 #define FOURCC_ID(str) FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
48 static tbm_bufmgr g_surface_bufmgr;
49 static pthread_mutex_t tbm_surface_lock;
54 _get_time_in_millis(void)
58 gettimeofday(&tv, NULL);
60 return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
64 _tbm_surface_internal_format_to_str(tbm_format format)
68 return "TBM_FORMAT_C8";
69 case TBM_FORMAT_RGB332:
70 return "TBM_FORMAT_RGB332";
71 case TBM_FORMAT_BGR233:
72 return "TBM_FORMAT_BGR233";
73 case TBM_FORMAT_XRGB4444:
74 return "TBM_FORMAT_XRGB4444";
75 case TBM_FORMAT_XBGR4444:
76 return "TBM_FORMAT_XBGR4444";
77 case TBM_FORMAT_RGBX4444:
78 return "TBM_FORMAT_RGBX4444";
79 case TBM_FORMAT_BGRX4444:
80 return "TBM_FORMAT_BGRX4444";
81 case TBM_FORMAT_ARGB4444:
82 return "TBM_FORMAT_ARGB4444";
83 case TBM_FORMAT_ABGR4444:
84 return "TBM_FORMAT_ABGR4444";
85 case TBM_FORMAT_RGBA4444:
86 return "TBM_FORMAT_RGBA4444";
87 case TBM_FORMAT_BGRA4444:
88 return "TBM_FORMAT_BGRA4444";
89 case TBM_FORMAT_XRGB1555:
90 return "TBM_FORMAT_XRGB1555";
91 case TBM_FORMAT_XBGR1555:
92 return "TBM_FORMAT_XBGR1555";
93 case TBM_FORMAT_RGBX5551:
94 return "TBM_FORMAT_RGBX5551";
95 case TBM_FORMAT_BGRX5551:
96 return "TBM_FORMAT_BGRX5551";
97 case TBM_FORMAT_ARGB1555:
98 return "TBM_FORMAT_ARGB1555";
99 case TBM_FORMAT_ABGR1555:
100 return "TBM_FORMAT_ABGR1555";
101 case TBM_FORMAT_RGBA5551:
102 return "TBM_FORMAT_RGBA5551";
103 case TBM_FORMAT_BGRA5551:
104 return "TBM_FORMAT_BGRA5551";
105 case TBM_FORMAT_RGB565:
106 return "TBM_FORMAT_RGB565";
107 case TBM_FORMAT_BGR565:
108 return "TBM_FORMAT_BGR565";
109 case TBM_FORMAT_RGB888:
110 return "TBM_FORMAT_RGB888";
111 case TBM_FORMAT_BGR888:
112 return "TBM_FORMAT_BGR888";
113 case TBM_FORMAT_XRGB8888:
114 return "TBM_FORMAT_XRGB8888";
115 case TBM_FORMAT_XBGR8888:
116 return "TBM_FORMAT_XBGR8888";
117 case TBM_FORMAT_RGBX8888:
118 return "TBM_FORMAT_RGBX8888";
119 case TBM_FORMAT_BGRX8888:
120 return "TBM_FORMAT_BGRX8888";
121 case TBM_FORMAT_ARGB8888:
122 return "TBM_FORMAT_ARGB8888";
123 case TBM_FORMAT_ABGR8888:
124 return "TBM_FORMAT_ABGR8888";
125 case TBM_FORMAT_RGBA8888:
126 return "TBM_FORMAT_RGBA8888";
127 case TBM_FORMAT_BGRA8888:
128 return "TBM_FORMAT_BGRA8888";
129 case TBM_FORMAT_XRGB2101010:
130 return "TBM_FORMAT_XRGB2101010";
131 case TBM_FORMAT_XBGR2101010:
132 return "TBM_FORMAT_XBGR2101010";
133 case TBM_FORMAT_RGBX1010102:
134 return "TBM_FORMAT_RGBX1010102";
135 case TBM_FORMAT_BGRX1010102:
136 return "TBM_FORMAT_BGRX1010102";
137 case TBM_FORMAT_ARGB2101010:
138 return "TBM_FORMAT_ARGB2101010";
139 case TBM_FORMAT_ABGR2101010:
140 return "TBM_FORMAT_ABGR2101010";
141 case TBM_FORMAT_RGBA1010102:
142 return "TBM_FORMAT_RGBA1010102";
143 case TBM_FORMAT_BGRA1010102:
144 return "TBM_FORMAT_BGRA1010102";
145 case TBM_FORMAT_YUYV:
146 return "TBM_FORMAT_YUYV";
147 case TBM_FORMAT_YVYU:
148 return "TBM_FORMAT_YVYU";
149 case TBM_FORMAT_UYVY:
150 return "TBM_FORMAT_UYVY";
151 case TBM_FORMAT_VYUY:
152 return "TBM_FORMAT_VYUY";
153 case TBM_FORMAT_AYUV:
154 return "TBM_FORMAT_AYUV";
155 case TBM_FORMAT_NV12:
156 return "TBM_FORMAT_NV12";
157 case TBM_FORMAT_NV21:
158 return "TBM_FORMAT_NV21";
159 case TBM_FORMAT_NV16:
160 return "TBM_FORMAT_NV16";
161 case TBM_FORMAT_NV61:
162 return "TBM_FORMAT_NV61";
163 case TBM_FORMAT_YUV410:
164 return "TBM_FORMAT_YUV410";
165 case TBM_FORMAT_YVU410:
166 return "TBM_FORMAT_YVU410";
167 case TBM_FORMAT_YUV411:
168 return "TBM_FORMAT_YUV411";
169 case TBM_FORMAT_YVU411:
170 return "TBM_FORMAT_YVU411";
171 case TBM_FORMAT_YUV420:
172 return "TBM_FORMAT_YUV420";
173 case TBM_FORMAT_YVU420:
174 return "TBM_FORMAT_YVU420";
175 case TBM_FORMAT_YUV422:
176 return "TBM_FORMAT_YUV422";
177 case TBM_FORMAT_YVU422:
178 return "TBM_FORMAT_YVU422";
179 case TBM_FORMAT_YUV444:
180 return "TBM_FORMAT_YUV444";
181 case TBM_FORMAT_YVU444:
182 return "TBM_FORMAT_YVU444";
183 case TBM_FORMAT_NV12MT:
184 return "TBM_FORMAT_NV12MT";
192 _tbm_surface_mutex_init(void)
194 static bool tbm_surface_mutex_init = false;
196 if (tbm_surface_mutex_init)
199 if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
200 TBM_LOG_E("fail: tbm_surface mutex init\n");
204 tbm_surface_mutex_init = true;
210 _tbm_surface_mutex_lock(void)
212 if (!_tbm_surface_mutex_init())
215 pthread_mutex_lock(&tbm_surface_lock);
219 _tbm_surface_mutex_unlock(void)
221 pthread_mutex_unlock(&tbm_surface_lock);
225 _init_surface_bufmgr(void)
227 g_surface_bufmgr = tbm_bufmgr_init(-1);
231 _deinit_surface_bufmgr(void)
233 if (!g_surface_bufmgr)
236 tbm_bufmgr_deinit(g_surface_bufmgr);
237 g_surface_bufmgr = NULL;
241 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
242 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
244 TBM_RETURN_VAL_IF_FAIL(surface, 0);
245 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
247 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
248 struct _tbm_bufmgr *mgr = surf->bufmgr;
251 TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
252 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
253 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
254 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
256 if (!mgr->backend->surface_get_plane_data)
259 ret = mgr->backend->surface_get_plane_data(surf->info.width,
260 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
268 _tbm_surface_internal_destroy(tbm_surface_h surface)
271 tbm_bufmgr bufmgr = surface->bufmgr;
272 tbm_user_data *old_data = NULL, *tmp = NULL;
274 for (i = 0; i < surface->num_bos; i++) {
275 surface->bos[i]->surface = NULL;
277 tbm_bo_unref(surface->bos[i]);
278 surface->bos[i] = NULL;
281 /* destory the user_data_list */
282 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
283 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
284 DBG("free user_data\n");
285 user_data_delete(old_data);
289 LIST_DEL(&surface->item_link);
294 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
295 LIST_DELINIT(&bufmgr->surf_list);
296 _deinit_surface_bufmgr();
301 tbm_surface_internal_is_valid(tbm_surface_h surface)
303 tbm_surface_h old_data = NULL, tmp = NULL;
305 if (surface == NULL || g_surface_bufmgr == NULL) {
306 TBM_TRACE("error: tbm_surface(%p)\n", surface);
310 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
311 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &g_surface_bufmgr->surf_list, item_link) {
312 if (old_data == surface) {
313 TBM_TRACE("tbm_surface(%p)\n", surface);
318 TBM_TRACE("error: tbm_surface(%p)\n", surface);
323 tbm_surface_internal_query_supported_formats(uint32_t **formats,
326 struct _tbm_bufmgr *mgr;
329 _tbm_surface_mutex_lock();
331 if (!g_surface_bufmgr) {
332 _init_surface_bufmgr();
333 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
336 mgr = g_surface_bufmgr;
338 if (!mgr->backend->surface_supported_format) {
339 TBM_TRACE("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
340 _tbm_surface_mutex_unlock();
344 ret = mgr->backend->surface_supported_format(formats, num);
346 TBM_TRACE("tbm_bufmgr(%p) format num(%d)\n", g_surface_bufmgr, *num);
348 _tbm_surface_mutex_unlock();
354 tbm_surface_internal_get_num_planes(tbm_format format)
360 case TBM_FORMAT_RGB332:
361 case TBM_FORMAT_BGR233:
362 case TBM_FORMAT_XRGB4444:
363 case TBM_FORMAT_XBGR4444:
364 case TBM_FORMAT_RGBX4444:
365 case TBM_FORMAT_BGRX4444:
366 case TBM_FORMAT_ARGB4444:
367 case TBM_FORMAT_ABGR4444:
368 case TBM_FORMAT_RGBA4444:
369 case TBM_FORMAT_BGRA4444:
370 case TBM_FORMAT_XRGB1555:
371 case TBM_FORMAT_XBGR1555:
372 case TBM_FORMAT_RGBX5551:
373 case TBM_FORMAT_BGRX5551:
374 case TBM_FORMAT_ARGB1555:
375 case TBM_FORMAT_ABGR1555:
376 case TBM_FORMAT_RGBA5551:
377 case TBM_FORMAT_BGRA5551:
378 case TBM_FORMAT_RGB565:
379 case TBM_FORMAT_BGR565:
380 case TBM_FORMAT_RGB888:
381 case TBM_FORMAT_BGR888:
382 case TBM_FORMAT_XRGB8888:
383 case TBM_FORMAT_XBGR8888:
384 case TBM_FORMAT_RGBX8888:
385 case TBM_FORMAT_BGRX8888:
386 case TBM_FORMAT_ARGB8888:
387 case TBM_FORMAT_ABGR8888:
388 case TBM_FORMAT_RGBA8888:
389 case TBM_FORMAT_BGRA8888:
390 case TBM_FORMAT_XRGB2101010:
391 case TBM_FORMAT_XBGR2101010:
392 case TBM_FORMAT_RGBX1010102:
393 case TBM_FORMAT_BGRX1010102:
394 case TBM_FORMAT_ARGB2101010:
395 case TBM_FORMAT_ABGR2101010:
396 case TBM_FORMAT_RGBA1010102:
397 case TBM_FORMAT_BGRA1010102:
398 case TBM_FORMAT_YUYV:
399 case TBM_FORMAT_YVYU:
400 case TBM_FORMAT_UYVY:
401 case TBM_FORMAT_VYUY:
402 case TBM_FORMAT_AYUV:
405 case TBM_FORMAT_NV12:
406 case TBM_FORMAT_NV12MT:
407 case TBM_FORMAT_NV21:
408 case TBM_FORMAT_NV16:
409 case TBM_FORMAT_NV61:
412 case TBM_FORMAT_YUV410:
413 case TBM_FORMAT_YVU410:
414 case TBM_FORMAT_YUV411:
415 case TBM_FORMAT_YVU411:
416 case TBM_FORMAT_YUV420:
417 case TBM_FORMAT_YVU420:
418 case TBM_FORMAT_YUV422:
419 case TBM_FORMAT_YVU422:
420 case TBM_FORMAT_YUV444:
421 case TBM_FORMAT_YVU444:
429 TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
435 tbm_surface_internal_get_bpp(tbm_format format)
442 case TBM_FORMAT_RGB332:
443 case TBM_FORMAT_BGR233:
446 case TBM_FORMAT_XRGB4444:
447 case TBM_FORMAT_XBGR4444:
448 case TBM_FORMAT_RGBX4444:
449 case TBM_FORMAT_BGRX4444:
450 case TBM_FORMAT_ARGB4444:
451 case TBM_FORMAT_ABGR4444:
452 case TBM_FORMAT_RGBA4444:
453 case TBM_FORMAT_BGRA4444:
454 case TBM_FORMAT_XRGB1555:
455 case TBM_FORMAT_XBGR1555:
456 case TBM_FORMAT_RGBX5551:
457 case TBM_FORMAT_BGRX5551:
458 case TBM_FORMAT_ARGB1555:
459 case TBM_FORMAT_ABGR1555:
460 case TBM_FORMAT_RGBA5551:
461 case TBM_FORMAT_BGRA5551:
462 case TBM_FORMAT_RGB565:
463 case TBM_FORMAT_BGR565:
466 case TBM_FORMAT_RGB888:
467 case TBM_FORMAT_BGR888:
470 case TBM_FORMAT_XRGB8888:
471 case TBM_FORMAT_XBGR8888:
472 case TBM_FORMAT_RGBX8888:
473 case TBM_FORMAT_BGRX8888:
474 case TBM_FORMAT_ARGB8888:
475 case TBM_FORMAT_ABGR8888:
476 case TBM_FORMAT_RGBA8888:
477 case TBM_FORMAT_BGRA8888:
478 case TBM_FORMAT_XRGB2101010:
479 case TBM_FORMAT_XBGR2101010:
480 case TBM_FORMAT_RGBX1010102:
481 case TBM_FORMAT_BGRX1010102:
482 case TBM_FORMAT_ARGB2101010:
483 case TBM_FORMAT_ABGR2101010:
484 case TBM_FORMAT_RGBA1010102:
485 case TBM_FORMAT_BGRA1010102:
486 case TBM_FORMAT_YUYV:
487 case TBM_FORMAT_YVYU:
488 case TBM_FORMAT_UYVY:
489 case TBM_FORMAT_VYUY:
490 case TBM_FORMAT_AYUV:
493 case TBM_FORMAT_NV12:
494 case TBM_FORMAT_NV12MT:
495 case TBM_FORMAT_NV21:
498 case TBM_FORMAT_NV16:
499 case TBM_FORMAT_NV61:
502 case TBM_FORMAT_YUV410:
503 case TBM_FORMAT_YVU410:
506 case TBM_FORMAT_YUV411:
507 case TBM_FORMAT_YVU411:
508 case TBM_FORMAT_YUV420:
509 case TBM_FORMAT_YVU420:
512 case TBM_FORMAT_YUV422:
513 case TBM_FORMAT_YVU422:
516 case TBM_FORMAT_YUV444:
517 case TBM_FORMAT_YVU444:
524 TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
530 tbm_surface_internal_create_with_flags(int width, int height,
531 int format, int flags)
533 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
534 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
536 struct _tbm_bufmgr *mgr;
537 struct _tbm_surface *surf = NULL;
541 uint32_t bo_size = 0;
545 _tbm_surface_mutex_lock();
547 if (!g_surface_bufmgr) {
548 _init_surface_bufmgr();
549 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
552 mgr = g_surface_bufmgr;
553 if (!TBM_BUFMGR_IS_VALID(mgr)) {
554 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
555 width, height, _tbm_surface_internal_format_to_str(format), flags);
556 _tbm_surface_mutex_unlock();
559 surf = calloc(1, sizeof(struct _tbm_surface));
561 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
562 width, height, _tbm_surface_internal_format_to_str(format), flags);
563 _tbm_surface_mutex_unlock();
568 surf->info.width = width;
569 surf->info.height = height;
570 surf->info.format = format;
571 surf->info.bpp = tbm_surface_internal_get_bpp(format);
572 surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
575 /* get size, stride and offset bo_idx */
576 for (i = 0; i < surf->info.num_planes; i++) {
577 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride,
579 surf->info.planes[i].size = size;
580 surf->info.planes[i].offset = offset;
581 surf->info.planes[i].stride = stride;
582 surf->planes_bo_idx[i] = bo_idx;
587 for (i = 0; i < surf->info.num_planes; i++) {
588 surf->info.size += surf->info.planes[i].size;
590 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
591 surf->num_bos = surf->planes_bo_idx[i] + 1;
596 for (i = 0; i < surf->num_bos; i++) {
598 for (j = 0; j < surf->info.num_planes; j++) {
599 if (surf->planes_bo_idx[j] == i)
600 bo_size += surf->info.planes[j].size;
603 if (mgr->backend->surface_bo_alloc) {
604 /* LCOV_EXCL_START */
606 void *bo_priv = NULL;
608 bo = calloc(1, sizeof(struct _tbm_bo));
610 TBM_LOG_E("fail to alloc bo struct\n");
614 bo->bufmgr = surf->bufmgr;
616 pthread_mutex_lock(&surf->bufmgr->lock);
618 bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
620 TBM_LOG_E("fail to alloc bo priv\n");
622 pthread_mutex_unlock(&surf->bufmgr->lock);
630 LIST_INITHEAD(&bo->user_data_list);
632 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
634 pthread_mutex_unlock(&surf->bufmgr->lock);
639 surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
643 TBM_LOG_E("fail to alloc bo idx:%d\n", i);
647 _tbm_bo_set_surface(surf->bos[i], surf);
651 TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
652 _tbm_surface_internal_format_to_str(format), flags, surf);
654 LIST_INITHEAD(&surf->user_data_list);
656 LIST_ADD(&surf->item_link, &mgr->surf_list);
658 _tbm_surface_mutex_unlock();
664 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
665 width, height, _tbm_surface_internal_format_to_str(format), flags);
667 for (j = 0; j < i; j++) {
669 tbm_bo_unref(surf->bos[j]);
675 if (LIST_IS_EMPTY(&mgr->surf_list)) {
676 LIST_DELINIT(&mgr->surf_list);
677 _deinit_surface_bufmgr();
680 _tbm_surface_mutex_unlock();
685 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
686 tbm_bo *bos, int num)
688 TBM_RETURN_VAL_IF_FAIL(bos, NULL);
689 TBM_RETURN_VAL_IF_FAIL(info, NULL);
690 TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
692 struct _tbm_bufmgr *mgr;
693 struct _tbm_surface *surf = NULL;
696 _tbm_surface_mutex_lock();
698 if (!g_surface_bufmgr) {
699 _init_surface_bufmgr();
700 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
703 mgr = g_surface_bufmgr;
704 if (!TBM_BUFMGR_IS_VALID(mgr)) {
705 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
706 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
707 _tbm_surface_mutex_unlock();
711 surf = calloc(1, sizeof(struct _tbm_surface));
713 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
714 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
715 _tbm_surface_mutex_unlock();
720 surf->info.width = info->width;
721 surf->info.height = info->height;
722 surf->info.format = info->format;
723 surf->info.bpp = info->bpp;
724 surf->info.num_planes = info->num_planes;
727 /* get size, stride and offset */
728 for (i = 0; i < info->num_planes; i++) {
729 surf->info.planes[i].offset = info->planes[i].offset;
730 surf->info.planes[i].stride = info->planes[i].stride;
732 if (info->planes[i].size > 0)
733 surf->info.planes[i].size = info->planes[i].size;
735 surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
738 surf->planes_bo_idx[i] = 0;
740 surf->planes_bo_idx[i] = i;
743 if (info->size > 0) {
744 surf->info.size = info->size;
747 for (i = 0; i < info->num_planes; i++)
748 surf->info.size += surf->info.planes[i].size;
751 surf->flags = TBM_BO_DEFAULT;
753 /* create only one bo */
755 for (i = 0; i < num; i++) {
759 surf->bos[i] = tbm_bo_ref(bos[i]);
760 _tbm_bo_set_surface(bos[i], surf);
763 TBM_TRACE("tbm_surface(%p) width(%d) height(%d) format(%s) bo_num(%d)\n", surf,
764 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
766 LIST_INITHEAD(&surf->user_data_list);
768 LIST_ADD(&surf->item_link, &mgr->surf_list);
770 _tbm_surface_mutex_unlock();
774 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
775 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
776 for (i = 0; i < num; i++) {
778 tbm_bo_unref(surf->bos[i]);
786 if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
787 LIST_DELINIT(&g_surface_bufmgr->surf_list);
788 _deinit_surface_bufmgr();
791 _tbm_surface_mutex_unlock();
797 tbm_surface_internal_destroy(tbm_surface_h surface)
799 if (!tbm_surface_internal_is_valid(surface))
802 _tbm_surface_mutex_lock();
806 if (surface->refcnt > 0) {
807 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
808 _tbm_surface_mutex_unlock();
812 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
814 if (surface->refcnt == 0)
815 _tbm_surface_internal_destroy(surface);
817 _tbm_surface_mutex_unlock();
821 tbm_surface_internal_ref(tbm_surface_h surface)
823 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
825 _tbm_surface_mutex_lock();
829 TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
831 _tbm_surface_mutex_unlock();
835 tbm_surface_internal_unref(tbm_surface_h surface)
837 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
839 _tbm_surface_mutex_lock();
843 if (surface->refcnt > 0) {
844 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
845 _tbm_surface_mutex_unlock();
849 TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
851 if (surface->refcnt == 0)
852 _tbm_surface_internal_destroy(surface);
854 _tbm_surface_mutex_unlock();
858 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
860 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
862 struct _tbm_surface *surf;
865 _tbm_surface_mutex_lock();
867 surf = (struct _tbm_surface *)surface;
870 TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
872 _tbm_surface_mutex_unlock();
878 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
880 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
881 TBM_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
883 struct _tbm_surface *surf;
886 _tbm_surface_mutex_lock();
888 surf = (struct _tbm_surface *)surface;
889 bo = surf->bos[bo_idx];
891 TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
893 _tbm_surface_mutex_unlock();
899 tbm_surface_internal_get_size(tbm_surface_h surface)
901 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
903 struct _tbm_surface *surf;
906 _tbm_surface_mutex_lock();
908 surf = (struct _tbm_surface *)surface;
909 size = surf->info.size;
911 TBM_TRACE("tbm_surface(%p) size(%d)\n", surface, size);
913 _tbm_surface_mutex_unlock();
919 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
920 uint32_t *size, uint32_t *offset, uint32_t *pitch)
922 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
923 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
925 struct _tbm_surface *surf;
927 _tbm_surface_mutex_lock();
929 surf = (struct _tbm_surface *)surface;
931 if (plane_idx >= surf->info.num_planes) {
932 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
933 _tbm_surface_mutex_unlock();
938 *size = surf->info.planes[plane_idx].size;
941 *offset = surf->info.planes[plane_idx].offset;
944 *pitch = surf->info.planes[plane_idx].stride;
946 TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%d) offset(%d) pitch(%d)\n", surface, plane_idx,
947 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
948 surf->info.planes[plane_idx].stride);
950 _tbm_surface_mutex_unlock();
956 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
957 tbm_surface_info_s *info, int map)
959 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
961 struct _tbm_surface *surf;
962 tbm_bo_handle bo_handles[4];
965 _tbm_surface_mutex_lock();
967 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
969 surf = (struct _tbm_surface *)surface;
971 memset(info, 0x00, sizeof(tbm_surface_info_s));
972 info->width = surf->info.width;
973 info->height = surf->info.height;
974 info->format = surf->info.format;
975 info->bpp = surf->info.bpp;
976 info->size = surf->info.size;
977 info->num_planes = surf->info.num_planes;
980 for (i = 0; i < surf->num_bos; i++) {
981 bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
982 if (bo_handles[i].ptr == NULL) {
983 for (j = 0; j < i; j++)
984 tbm_bo_unmap(surf->bos[j]);
986 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
987 _tbm_surface_mutex_unlock();
992 for (i = 0; i < surf->num_bos; i++)
993 bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
996 for (i = 0; i < surf->info.num_planes; i++) {
997 info->planes[i].size = surf->info.planes[i].size;
998 info->planes[i].offset = surf->info.planes[i].offset;
999 info->planes[i].stride = surf->info.planes[i].stride;
1001 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1002 info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1003 surf->info.planes[i].offset;
1006 TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1008 _tbm_surface_mutex_unlock();
1014 tbm_surface_internal_unmap(tbm_surface_h surface)
1016 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1018 struct _tbm_surface *surf;
1021 _tbm_surface_mutex_lock();
1023 surf = (struct _tbm_surface *)surface;
1025 for (i = 0; i < surf->num_bos; i++)
1026 tbm_bo_unmap(surf->bos[i]);
1028 TBM_TRACE("tbm_surface(%p)\n", surface);
1030 _tbm_surface_mutex_unlock();
1034 tbm_surface_internal_get_width(tbm_surface_h surface)
1036 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1038 struct _tbm_surface *surf;
1041 _tbm_surface_mutex_lock();
1043 surf = (struct _tbm_surface *)surface;
1044 width = surf->info.width;
1046 TBM_TRACE("tbm_surface(%p) width(%d)\n", surface, width);
1048 _tbm_surface_mutex_unlock();
1054 tbm_surface_internal_get_height(tbm_surface_h surface)
1056 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1058 struct _tbm_surface *surf;
1059 unsigned int height;
1061 _tbm_surface_mutex_lock();
1063 surf = (struct _tbm_surface *)surface;
1064 height = surf->info.height;
1066 TBM_TRACE("tbm_surface(%p) height(%d)\n", surface, height);
1068 _tbm_surface_mutex_unlock();
1075 tbm_surface_internal_get_format(tbm_surface_h surface)
1077 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1079 struct _tbm_surface *surf;
1082 _tbm_surface_mutex_lock();
1084 surf = (struct _tbm_surface *)surface;
1085 format = surf->info.format;
1087 TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1089 _tbm_surface_mutex_unlock();
1095 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1097 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1098 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1099 struct _tbm_surface *surf;
1102 _tbm_surface_mutex_lock();
1104 surf = (struct _tbm_surface *)surface;
1105 bo_idx = surf->planes_bo_idx[plane_idx];
1107 TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1109 _tbm_surface_mutex_unlock();
1115 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1116 tbm_data_free data_free_func)
1118 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1120 tbm_user_data *data;
1122 /* check if the data according to the key exist if so, return false. */
1123 data = user_data_lookup(&surface->user_data_list, key);
1125 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1129 data = user_data_create(key, data_free_func);
1131 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1135 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1137 LIST_ADD(&data->item_link, &surface->user_data_list);
1143 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1146 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1148 tbm_user_data *old_data;
1150 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1151 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1155 old_data = user_data_lookup(&surface->user_data_list, key);
1157 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1161 if (old_data->data && old_data->free_func)
1162 old_data->free_func(old_data->data);
1164 old_data->data = data;
1166 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1172 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1175 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1177 tbm_user_data *old_data;
1179 if (!data || LIST_IS_EMPTY(&surface->user_data_list)) {
1180 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1184 old_data = user_data_lookup(&surface->user_data_list, key);
1186 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1191 *data = old_data->data;
1193 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1199 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1202 TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1204 tbm_user_data *old_data = (void *)0;
1206 if (LIST_IS_EMPTY(&surface->user_data_list)) {
1207 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1211 old_data = user_data_lookup(&surface->user_data_list, key);
1213 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1217 TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1219 user_data_delete(old_data);
1224 /* LCOV_EXCL_START */
1226 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1228 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1230 return surface->debug_pid;
1234 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1236 TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1238 surface->debug_pid = pid;
1241 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1242 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1244 struct _tbm_surface_dump_buf_info {
1254 tbm_surface_info_s info;
1256 struct list_head link;
1259 struct _tbm_surface_dump_info {
1260 char *path; // copy???
1263 struct list_head *link;
1264 struct list_head surface_list; /* link of surface */
1267 static tbm_surface_dump_info *g_dump_info = NULL;
1268 static const char *dump_postfix[2] = {"png", "yuv"};
1271 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1272 int size2, void *data3, int size3)
1274 unsigned int *blocks;
1275 FILE *fp = fopen(file, "w+");
1276 TBM_RETURN_IF_FAIL(fp != NULL);
1278 blocks = (unsigned int *)data1;
1279 fwrite(blocks, 1, size1, fp);
1282 blocks = (unsigned int *)data2;
1283 fwrite(blocks, 1, size2, fp);
1287 blocks = (unsigned int *)data3;
1288 fwrite(blocks, 1, size3, fp);
1295 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1298 FILE *fp = fopen(file, "wb");
1299 TBM_RETURN_IF_FAIL(fp != NULL);
1302 png_structp pPngStruct =
1303 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1309 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1311 png_destroy_write_struct(&pPngStruct, NULL);
1316 png_init_io(pPngStruct, fp);
1317 png_set_IHDR(pPngStruct,
1322 PNG_COLOR_TYPE_RGBA,
1324 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1326 png_set_bgr(pPngStruct);
1327 png_write_info(pPngStruct, pPngInfo);
1329 const int pixel_size = 4; // RGBA
1330 png_bytep *row_pointers =
1331 png_malloc(pPngStruct, height * sizeof(png_byte *));
1333 unsigned int *blocks = (unsigned int *)data;
1337 for (; y < height; ++y) {
1339 png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1340 row_pointers[y] = (png_bytep)row;
1341 for (x = 0; x < width; ++x) {
1342 unsigned int curBlock = blocks[y * width + x];
1343 row[x * pixel_size] = (curBlock & 0xFF);
1344 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1345 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1346 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1350 png_write_image(pPngStruct, row_pointers);
1351 png_write_end(pPngStruct, pPngInfo);
1353 for (y = 0; y < height; y++)
1354 png_free(pPngStruct, row_pointers[y]);
1355 png_free(pPngStruct, row_pointers);
1357 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1363 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1365 TBM_RETURN_IF_FAIL(path != NULL);
1366 TBM_RETURN_IF_FAIL(w > 0);
1367 TBM_RETURN_IF_FAIL(h > 0);
1368 TBM_RETURN_IF_FAIL(count > 0);
1370 tbm_surface_dump_buf_info *buf_info = NULL;
1371 tbm_surface_dump_buf_info *tmp;
1375 tbm_surface_h tbm_surface;
1376 tbm_surface_info_s info;
1377 tbm_surface_error_e err;
1381 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1385 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1386 TBM_RETURN_IF_FAIL(g_dump_info);
1388 LIST_INITHEAD(&g_dump_info->surface_list);
1389 g_dump_info->count = 0;
1390 g_dump_info->dump_max = count;
1392 /* get buffer size */
1393 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1394 if (tbm_surface == NULL) {
1395 TBM_LOG_E("tbm_surface_create fail\n");
1400 err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
1401 if (err != TBM_SURFACE_ERROR_NONE) {
1402 TBM_LOG_E("tbm_surface_map fail\n");
1403 tbm_surface_destroy(tbm_surface);
1408 buffer_size = info.planes[0].stride * h;
1409 tbm_surface_unmap(tbm_surface);
1410 tbm_surface_destroy(tbm_surface);
1412 /* create dump lists */
1413 for (i = 0; i < count; i++) {
1414 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1415 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1416 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1422 buf_info->index = i;
1424 buf_info->size = buffer_size;
1426 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1429 g_dump_info->path = path;
1430 g_dump_info->link = &g_dump_info->surface_list;
1432 TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1436 /* free resources */
1437 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1438 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1439 tbm_bo_unref(buf_info->bo);
1444 TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1453 tbm_surface_internal_dump_end(void)
1455 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1456 tbm_bo_handle bo_handle;
1462 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1463 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1466 if (buf_info->dirty) {
1470 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1471 if (bo_handle.ptr == NULL)
1474 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1475 TBM_LOG_I("Dump File.. %s generated.\n", file);
1477 switch (buf_info->info.format) {
1478 case TBM_FORMAT_ARGB8888:
1479 case TBM_FORMAT_XRGB8888:
1480 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1481 buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1483 case TBM_FORMAT_YVU420:
1484 case TBM_FORMAT_YUV420:
1485 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1486 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1487 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1488 buf_info->info.planes[0].stride * buf_info->info.height,
1490 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1492 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1494 case TBM_FORMAT_NV12:
1495 case TBM_FORMAT_NV21:
1496 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1497 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1498 buf_info->info.planes[0].stride * buf_info->info.height,
1500 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1503 case TBM_FORMAT_YUYV:
1504 case TBM_FORMAT_UYVY:
1505 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1506 buf_info->info.planes[0].stride * buf_info->info.height,
1510 TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1511 tbm_bo_unmap(buf_info->bo);
1515 tbm_bo_unmap(buf_info->bo);
1516 } else if (buf_info->dirty_shm) {
1517 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1518 if (bo_handle.ptr == NULL)
1521 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1522 TBM_LOG_I("Dump File.. %s generated.\n", file);
1524 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1525 buf_info->shm_stride >> 2, buf_info->shm_h);
1527 tbm_bo_unmap(buf_info->bo);
1533 /* free resources */
1534 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1535 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1536 tbm_bo_unref(buf_info->bo);
1544 TBM_LOG_I("Dump End..\n");
1548 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1550 TBM_RETURN_IF_FAIL(surface != NULL);
1551 TBM_RETURN_IF_FAIL(type != NULL);
1553 tbm_surface_dump_buf_info *buf_info;
1554 tbm_surface_info_s info;
1555 struct list_head *next_link;
1556 tbm_bo_handle bo_handle;
1558 const char *postfix;
1563 next_link = g_dump_info->link->next;
1564 TBM_RETURN_IF_FAIL(next_link != NULL);
1566 if (next_link == &g_dump_info->surface_list) {
1567 next_link = next_link->next;
1568 TBM_RETURN_IF_FAIL(next_link != NULL);
1571 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1572 TBM_RETURN_IF_FAIL(buf_info != NULL);
1574 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1575 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1577 if (info.size > buf_info->size) {
1578 TBM_LOG_W("Dump skip. surface over created buffer size(%d, %d)\n", info.size, buf_info->size);
1579 tbm_surface_unmap(surface);
1583 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1584 postfix = dump_postfix[0];
1586 postfix = dump_postfix[1];
1588 /* make the file information */
1589 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1592 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1593 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1594 memset(bo_handle.ptr, 0x00, buf_info->size);
1596 switch (info.format) {
1597 case TBM_FORMAT_ARGB8888:
1598 case TBM_FORMAT_XRGB8888:
1599 snprintf(buf_info->name, sizeof(buf_info->name), "%.3f_%03d_%p-%s.%s", _get_time_in_millis() / 1000.0, g_dump_info->count++, surface, type, postfix);
1600 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1602 case TBM_FORMAT_YVU420:
1603 case TBM_FORMAT_YUV420:
1604 snprintf(buf_info->name, sizeof(buf_info->name), "%03d-%s_%dx%d_%c%c%c%c.%s",
1605 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1606 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1607 bo_handle.ptr += info.planes[0].stride * info.height;
1608 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1609 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1610 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1612 case TBM_FORMAT_NV12:
1613 case TBM_FORMAT_NV21:
1614 snprintf(buf_info->name, sizeof(buf_info->name), "%03d-%s_%dx%d_%c%c%c%c.%s",
1615 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1616 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1617 bo_handle.ptr += info.planes[0].stride * info.height;
1618 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1620 case TBM_FORMAT_YUYV:
1621 case TBM_FORMAT_UYVY:
1622 snprintf(buf_info->name, sizeof(buf_info->name), "%03d-%s_%dx%d_%c%c%c%c.%s",
1623 g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1624 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1627 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1628 tbm_bo_unmap(buf_info->bo);
1632 tbm_bo_unmap(buf_info->bo);
1634 tbm_surface_unmap(surface);
1636 buf_info->dirty = 1;
1637 buf_info->dirty_shm = 0;
1639 if (g_dump_info->count == 1000)
1640 g_dump_info->count = 0;
1642 g_dump_info->link = next_link;
1644 TBM_LOG_I("Dump %s \n", buf_info->name);
1647 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, const char *type)
1649 TBM_RETURN_IF_FAIL(ptr != NULL);
1650 TBM_RETURN_IF_FAIL(w > 0);
1651 TBM_RETURN_IF_FAIL(h > 0);
1652 TBM_RETURN_IF_FAIL(stride > 0);
1653 TBM_RETURN_IF_FAIL(type != NULL);
1655 tbm_surface_dump_buf_info *buf_info;
1656 struct list_head *next_link;
1657 tbm_bo_handle bo_handle;
1662 next_link = g_dump_info->link->next;
1663 TBM_RETURN_IF_FAIL(next_link != NULL);
1665 if (next_link == &g_dump_info->surface_list) {
1666 next_link = next_link->next;
1667 TBM_RETURN_IF_FAIL(next_link != NULL);
1670 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1671 TBM_RETURN_IF_FAIL(buf_info != NULL);
1673 if (stride * h > buf_info->size) {
1674 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", stride * h, buf_info->size);
1679 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1680 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1681 memset(bo_handle.ptr, 0x00, buf_info->size);
1682 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1685 snprintf(buf_info->name, sizeof(buf_info->name), "%03d-%s.%s", g_dump_info->count++, type, dump_postfix[0]);
1686 memcpy(bo_handle.ptr, ptr, stride * h);
1688 tbm_bo_unmap(buf_info->bo);
1690 buf_info->dirty = 0;
1691 buf_info->dirty_shm = 1;
1692 buf_info->shm_stride = stride;
1693 buf_info->shm_h = h;
1695 if (g_dump_info->count == 1000)
1696 g_dump_info->count = 0;
1698 g_dump_info->link = next_link;
1700 TBM_LOG_I("Dump %s \n", buf_info->name);