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"
44 static tbm_bufmgr g_surface_bufmgr;
45 static pthread_mutex_t tbm_surface_lock;
46 void _tbm_surface_mutex_unlock(void);
48 #define C(b, m) (((b) >> (m)) & 0xFF)
49 #define B(c, s) ((((unsigned int)(c)) & 0xff) << (s))
50 #define FOURCC(a, b, c, d) (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
51 #define FOURCC_STR(id) C(id, 0), C(id, 8), C(id, 16), C(id, 24)
52 #define FOURCC_ID(str) FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
55 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
57 TBM_ERR("'%s' failed.\n", #cond);\
58 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
59 _tbm_surface_mutex_unlock();\
64 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
66 TBM_ERR("'%s' failed.\n", #cond);\
67 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
68 _tbm_surface_mutex_unlock();\
75 _tbm_surface_internal_get_time(void)
80 clock_gettime(CLOCK_MONOTONIC, &tp);
81 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
87 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
89 LIST_DEL(&debug_data->item_link);
91 if (debug_data->key) free(debug_data->key);
92 if (debug_data->value) free(debug_data->value);
97 _tbm_surface_internal_format_to_str(tbm_format format)
101 return "TBM_FORMAT_C8";
102 case TBM_FORMAT_RGB332:
103 return "TBM_FORMAT_RGB332";
104 case TBM_FORMAT_BGR233:
105 return "TBM_FORMAT_BGR233";
106 case TBM_FORMAT_XRGB4444:
107 return "TBM_FORMAT_XRGB4444";
108 case TBM_FORMAT_XBGR4444:
109 return "TBM_FORMAT_XBGR4444";
110 case TBM_FORMAT_RGBX4444:
111 return "TBM_FORMAT_RGBX4444";
112 case TBM_FORMAT_BGRX4444:
113 return "TBM_FORMAT_BGRX4444";
114 case TBM_FORMAT_ARGB4444:
115 return "TBM_FORMAT_ARGB4444";
116 case TBM_FORMAT_ABGR4444:
117 return "TBM_FORMAT_ABGR4444";
118 case TBM_FORMAT_RGBA4444:
119 return "TBM_FORMAT_RGBA4444";
120 case TBM_FORMAT_BGRA4444:
121 return "TBM_FORMAT_BGRA4444";
122 case TBM_FORMAT_XRGB1555:
123 return "TBM_FORMAT_XRGB1555";
124 case TBM_FORMAT_XBGR1555:
125 return "TBM_FORMAT_XBGR1555";
126 case TBM_FORMAT_RGBX5551:
127 return "TBM_FORMAT_RGBX5551";
128 case TBM_FORMAT_BGRX5551:
129 return "TBM_FORMAT_BGRX5551";
130 case TBM_FORMAT_ARGB1555:
131 return "TBM_FORMAT_ARGB1555";
132 case TBM_FORMAT_ABGR1555:
133 return "TBM_FORMAT_ABGR1555";
134 case TBM_FORMAT_RGBA5551:
135 return "TBM_FORMAT_RGBA5551";
136 case TBM_FORMAT_BGRA5551:
137 return "TBM_FORMAT_BGRA5551";
138 case TBM_FORMAT_RGB565:
139 return "TBM_FORMAT_RGB565";
140 case TBM_FORMAT_BGR565:
141 return "TBM_FORMAT_BGR565";
142 case TBM_FORMAT_RGB888:
143 return "TBM_FORMAT_RGB888";
144 case TBM_FORMAT_BGR888:
145 return "TBM_FORMAT_BGR888";
146 case TBM_FORMAT_XRGB8888:
147 return "TBM_FORMAT_XRGB8888";
148 case TBM_FORMAT_XBGR8888:
149 return "TBM_FORMAT_XBGR8888";
150 case TBM_FORMAT_RGBX8888:
151 return "TBM_FORMAT_RGBX8888";
152 case TBM_FORMAT_BGRX8888:
153 return "TBM_FORMAT_BGRX8888";
154 case TBM_FORMAT_ARGB8888:
155 return "TBM_FORMAT_ARGB8888";
156 case TBM_FORMAT_ABGR8888:
157 return "TBM_FORMAT_ABGR8888";
158 case TBM_FORMAT_RGBA8888:
159 return "TBM_FORMAT_RGBA8888";
160 case TBM_FORMAT_BGRA8888:
161 return "TBM_FORMAT_BGRA8888";
162 case TBM_FORMAT_XRGB2101010:
163 return "TBM_FORMAT_XRGB2101010";
164 case TBM_FORMAT_XBGR2101010:
165 return "TBM_FORMAT_XBGR2101010";
166 case TBM_FORMAT_RGBX1010102:
167 return "TBM_FORMAT_RGBX1010102";
168 case TBM_FORMAT_BGRX1010102:
169 return "TBM_FORMAT_BGRX1010102";
170 case TBM_FORMAT_ARGB2101010:
171 return "TBM_FORMAT_ARGB2101010";
172 case TBM_FORMAT_ABGR2101010:
173 return "TBM_FORMAT_ABGR2101010";
174 case TBM_FORMAT_RGBA1010102:
175 return "TBM_FORMAT_RGBA1010102";
176 case TBM_FORMAT_BGRA1010102:
177 return "TBM_FORMAT_BGRA1010102";
178 case TBM_FORMAT_YUYV:
179 return "TBM_FORMAT_YUYV";
180 case TBM_FORMAT_YVYU:
181 return "TBM_FORMAT_YVYU";
182 case TBM_FORMAT_UYVY:
183 return "TBM_FORMAT_UYVY";
184 case TBM_FORMAT_VYUY:
185 return "TBM_FORMAT_VYUY";
186 case TBM_FORMAT_AYUV:
187 return "TBM_FORMAT_AYUV";
188 case TBM_FORMAT_NV12:
189 return "TBM_FORMAT_NV12";
190 case TBM_FORMAT_NV21:
191 return "TBM_FORMAT_NV21";
192 case TBM_FORMAT_NV16:
193 return "TBM_FORMAT_NV16";
194 case TBM_FORMAT_NV61:
195 return "TBM_FORMAT_NV61";
196 case TBM_FORMAT_YUV410:
197 return "TBM_FORMAT_YUV410";
198 case TBM_FORMAT_YVU410:
199 return "TBM_FORMAT_YVU410";
200 case TBM_FORMAT_YUV411:
201 return "TBM_FORMAT_YUV411";
202 case TBM_FORMAT_YVU411:
203 return "TBM_FORMAT_YVU411";
204 case TBM_FORMAT_YUV420:
205 return "TBM_FORMAT_YUV420";
206 case TBM_FORMAT_YVU420:
207 return "TBM_FORMAT_YVU420";
208 case TBM_FORMAT_YUV422:
209 return "TBM_FORMAT_YUV422";
210 case TBM_FORMAT_YVU422:
211 return "TBM_FORMAT_YVU422";
212 case TBM_FORMAT_YUV444:
213 return "TBM_FORMAT_YUV444";
214 case TBM_FORMAT_YVU444:
215 return "TBM_FORMAT_YVU444";
216 case TBM_FORMAT_NV12MT:
217 return "TBM_FORMAT_NV12MT";
224 _tbm_surface_mutex_init(void)
226 static bool tbm_surface_mutex_init = false;
228 if (tbm_surface_mutex_init)
231 if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
232 TBM_ERR("fail: pthread_mutex_init for tbm_surface_lock.\n");
236 tbm_surface_mutex_init = true;
242 _tbm_surface_mutex_lock(void)
244 if (!_tbm_surface_mutex_init()) {
245 TBM_ERR("fail: _tbm_surface_mutex_init.\n");
249 pthread_mutex_lock(&tbm_surface_lock);
253 _tbm_surface_mutex_unlock(void)
255 pthread_mutex_unlock(&tbm_surface_lock);
259 _init_surface_bufmgr(void)
261 g_surface_bufmgr = tbm_bufmgr_init(-1);
265 _deinit_surface_bufmgr(void)
267 if (!g_surface_bufmgr)
270 tbm_bufmgr_deinit(g_surface_bufmgr);
271 g_surface_bufmgr = NULL;
276 _tbm_surface_internal_is_valid(tbm_surface_h surface)
278 tbm_surface_h old_data = NULL;
280 TBM_RETURN_VAL_IF_FAIL(g_surface_bufmgr, 0);
281 TBM_RETURN_VAL_IF_FAIL(surface, 0);
283 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
284 LIST_FOR_EACH_ENTRY(old_data, &g_surface_bufmgr->surf_list, item_link) {
285 if (old_data == surface)
290 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
292 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
298 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
299 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
301 TBM_RETURN_VAL_IF_FAIL(surface, 0);
302 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
304 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
305 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
309 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
310 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
311 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
312 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
314 if (bufmgr->backend_module_data) {
315 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
316 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
320 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
321 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
322 if (error != TBM_ERROR_NONE) {
323 /* LCOV_EXCL_START */
324 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
325 _tbm_set_last_result(error);
331 if (!bufmgr->backend->surface_get_plane_data) {
332 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
336 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
337 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
339 /* LCOV_EXCL_START */
340 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
341 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
351 _tbm_surface_internal_destroy(tbm_surface_h surface)
354 tbm_bufmgr bufmgr = surface->bufmgr;
355 tbm_user_data *old_data = NULL, *tmp = NULL;
356 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
358 /* destory the user_data_list */
359 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
360 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
361 TBM_DBG("free user_data\n");
362 user_data_delete(old_data);
366 for (i = 0; i < surface->num_bos; i++) {
367 surface->bos[i]->surface = NULL;
369 tbm_bo_unref(surface->bos[i]);
370 surface->bos[i] = NULL;
373 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
374 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
375 _tbm_surface_internal_debug_data_delete(debug_old_data);
378 LIST_DEL(&surface->item_link);
383 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
384 LIST_DELINIT(&bufmgr->surf_list);
386 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
387 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
388 _tbm_surface_internal_debug_data_delete(debug_old_data);
392 _deinit_surface_bufmgr();
396 /* LCOV_EXCL_START */
398 _tbm_surface_check_file_is_symbolic_link(const char* path)
405 if (stat(path, &sb) != 0)
408 if (S_ISLNK(sb.st_mode))
416 _tbm_surface_internal_get_num_planes(tbm_format format)
422 case TBM_FORMAT_RGB332:
423 case TBM_FORMAT_BGR233:
424 case TBM_FORMAT_XRGB4444:
425 case TBM_FORMAT_XBGR4444:
426 case TBM_FORMAT_RGBX4444:
427 case TBM_FORMAT_BGRX4444:
428 case TBM_FORMAT_ARGB4444:
429 case TBM_FORMAT_ABGR4444:
430 case TBM_FORMAT_RGBA4444:
431 case TBM_FORMAT_BGRA4444:
432 case TBM_FORMAT_XRGB1555:
433 case TBM_FORMAT_XBGR1555:
434 case TBM_FORMAT_RGBX5551:
435 case TBM_FORMAT_BGRX5551:
436 case TBM_FORMAT_ARGB1555:
437 case TBM_FORMAT_ABGR1555:
438 case TBM_FORMAT_RGBA5551:
439 case TBM_FORMAT_BGRA5551:
440 case TBM_FORMAT_RGB565:
441 case TBM_FORMAT_BGR565:
442 case TBM_FORMAT_RGB888:
443 case TBM_FORMAT_BGR888:
444 case TBM_FORMAT_XRGB8888:
445 case TBM_FORMAT_XBGR8888:
446 case TBM_FORMAT_RGBX8888:
447 case TBM_FORMAT_BGRX8888:
448 case TBM_FORMAT_ARGB8888:
449 case TBM_FORMAT_ABGR8888:
450 case TBM_FORMAT_RGBA8888:
451 case TBM_FORMAT_BGRA8888:
452 case TBM_FORMAT_XRGB2101010:
453 case TBM_FORMAT_XBGR2101010:
454 case TBM_FORMAT_RGBX1010102:
455 case TBM_FORMAT_BGRX1010102:
456 case TBM_FORMAT_ARGB2101010:
457 case TBM_FORMAT_ABGR2101010:
458 case TBM_FORMAT_RGBA1010102:
459 case TBM_FORMAT_BGRA1010102:
460 case TBM_FORMAT_YUYV:
461 case TBM_FORMAT_YVYU:
462 case TBM_FORMAT_UYVY:
463 case TBM_FORMAT_VYUY:
464 case TBM_FORMAT_AYUV:
467 case TBM_FORMAT_NV12:
468 case TBM_FORMAT_NV12MT:
469 case TBM_FORMAT_NV21:
470 case TBM_FORMAT_NV16:
471 case TBM_FORMAT_NV61:
474 case TBM_FORMAT_YUV410:
475 case TBM_FORMAT_YVU410:
476 case TBM_FORMAT_YUV411:
477 case TBM_FORMAT_YVU411:
478 case TBM_FORMAT_YUV420:
479 case TBM_FORMAT_YVU420:
480 case TBM_FORMAT_YUV422:
481 case TBM_FORMAT_YVU422:
482 case TBM_FORMAT_YUV444:
483 case TBM_FORMAT_YVU444:
488 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
496 _tbm_surface_internal_get_bpp(tbm_format format)
503 case TBM_FORMAT_RGB332:
504 case TBM_FORMAT_BGR233:
507 case TBM_FORMAT_XRGB4444:
508 case TBM_FORMAT_XBGR4444:
509 case TBM_FORMAT_RGBX4444:
510 case TBM_FORMAT_BGRX4444:
511 case TBM_FORMAT_ARGB4444:
512 case TBM_FORMAT_ABGR4444:
513 case TBM_FORMAT_RGBA4444:
514 case TBM_FORMAT_BGRA4444:
515 case TBM_FORMAT_XRGB1555:
516 case TBM_FORMAT_XBGR1555:
517 case TBM_FORMAT_RGBX5551:
518 case TBM_FORMAT_BGRX5551:
519 case TBM_FORMAT_ARGB1555:
520 case TBM_FORMAT_ABGR1555:
521 case TBM_FORMAT_RGBA5551:
522 case TBM_FORMAT_BGRA5551:
523 case TBM_FORMAT_RGB565:
524 case TBM_FORMAT_BGR565:
527 case TBM_FORMAT_RGB888:
528 case TBM_FORMAT_BGR888:
531 case TBM_FORMAT_XRGB8888:
532 case TBM_FORMAT_XBGR8888:
533 case TBM_FORMAT_RGBX8888:
534 case TBM_FORMAT_BGRX8888:
535 case TBM_FORMAT_ARGB8888:
536 case TBM_FORMAT_ABGR8888:
537 case TBM_FORMAT_RGBA8888:
538 case TBM_FORMAT_BGRA8888:
539 case TBM_FORMAT_XRGB2101010:
540 case TBM_FORMAT_XBGR2101010:
541 case TBM_FORMAT_RGBX1010102:
542 case TBM_FORMAT_BGRX1010102:
543 case TBM_FORMAT_ARGB2101010:
544 case TBM_FORMAT_ABGR2101010:
545 case TBM_FORMAT_RGBA1010102:
546 case TBM_FORMAT_BGRA1010102:
547 case TBM_FORMAT_YUYV:
548 case TBM_FORMAT_YVYU:
549 case TBM_FORMAT_UYVY:
550 case TBM_FORMAT_VYUY:
551 case TBM_FORMAT_AYUV:
554 case TBM_FORMAT_NV12:
555 case TBM_FORMAT_NV12MT:
556 case TBM_FORMAT_NV21:
559 case TBM_FORMAT_NV16:
560 case TBM_FORMAT_NV61:
563 case TBM_FORMAT_YUV410:
564 case TBM_FORMAT_YVU410:
567 case TBM_FORMAT_YUV411:
568 case TBM_FORMAT_YVU411:
569 case TBM_FORMAT_YUV420:
570 case TBM_FORMAT_YVU420:
573 case TBM_FORMAT_YUV422:
574 case TBM_FORMAT_YVU422:
577 case TBM_FORMAT_YUV444:
578 case TBM_FORMAT_YVU444:
582 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
590 tbm_surface_internal_is_valid(tbm_surface_h surface)
594 _tbm_surface_mutex_lock();
595 _tbm_set_last_result(TBM_ERROR_NONE);
597 /* Return silently if surface is null. */
599 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
600 _tbm_surface_mutex_unlock();
604 ret = _tbm_surface_internal_is_valid(surface);
606 _tbm_surface_mutex_unlock();
612 tbm_surface_internal_query_supported_formats(uint32_t **formats,
615 struct _tbm_bufmgr *bufmgr;
617 bool bufmgr_initialized = false;
620 _tbm_surface_mutex_lock();
621 _tbm_set_last_result(TBM_ERROR_NONE);
623 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
624 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
626 if (!g_surface_bufmgr) {
627 _init_surface_bufmgr();
628 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
629 bufmgr_initialized = true;
632 bufmgr = g_surface_bufmgr;
634 if (bufmgr->backend_module_data) {
635 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
636 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
640 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
641 if (error != TBM_ERROR_NONE) {
642 /* LCOV_EXCL_START */
643 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
645 /* LCOV_EXCL_START */
649 if (!bufmgr->backend->surface_supported_format) {
650 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
654 ret = bufmgr->backend->surface_supported_format(formats, num);
656 /* LCOV_EXCL_START */
657 TBM_ERR("Fail to surface_supported_format.\n");
658 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
660 /* LCOV_EXCL_START */
664 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
666 if (bufmgr_initialized) {
667 LIST_DELINIT(&g_surface_bufmgr->surf_list);
668 _deinit_surface_bufmgr();
671 _tbm_surface_mutex_unlock();
675 /* LCOV_EXCL_START */
677 if (bufmgr_initialized) {
678 LIST_DELINIT(&g_surface_bufmgr->surf_list);
679 _deinit_surface_bufmgr();
681 _tbm_surface_mutex_unlock();
683 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
690 tbm_surface_internal_get_num_planes(tbm_format format)
694 _tbm_surface_mutex_lock();
695 _tbm_set_last_result(TBM_ERROR_NONE);
697 num_planes = _tbm_surface_internal_get_num_planes(format);
699 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
700 _tbm_surface_mutex_unlock();
704 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
706 _tbm_surface_mutex_unlock();
712 tbm_surface_internal_get_bpp(tbm_format format)
716 _tbm_surface_mutex_lock();
717 _tbm_set_last_result(TBM_ERROR_NONE);
719 bpp = _tbm_surface_internal_get_bpp(format);
721 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
722 _tbm_surface_mutex_unlock();
726 _tbm_surface_mutex_unlock();
728 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
734 tbm_surface_internal_create_with_flags(int width, int height,
735 int format, int flags)
737 struct _tbm_bufmgr *bufmgr;
738 struct _tbm_surface *surf = NULL;
742 uint32_t bo_size = 0;
745 bool bufmgr_initialized = false;
747 void *bo_priv = NULL;
748 tbm_backend_bo_data *bo_data = NULL;
751 _tbm_surface_mutex_lock();
752 _tbm_set_last_result(TBM_ERROR_NONE);
754 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
755 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
757 if (!g_surface_bufmgr) {
758 _init_surface_bufmgr();
759 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
760 bufmgr_initialized = true;
763 bufmgr = g_surface_bufmgr;
764 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
765 TBM_ERR("The bufmgr is invalid\n");
766 goto check_valid_fail;
769 surf = calloc(1, sizeof(struct _tbm_surface));
771 /* LCOV_EXCL_START */
772 TBM_ERR("fail to alloc surf\n");
773 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
774 goto alloc_surf_fail;
778 surf->bufmgr = bufmgr;
779 surf->info.width = width;
780 surf->info.height = height;
781 surf->info.format = format;
782 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
783 if (!surf->info.bpp) {
784 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
787 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
788 if (!surf->info.num_planes) {
789 TBM_ERR("fail to get num_planes. error(%s)\n", tbm_error_str(tbm_get_last_error()));
790 goto num_planes_fail;
794 /* get size, stride and offset bo_idx */
795 for (i = 0; i < surf->info.num_planes; i++) {
796 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
797 &offset, &stride, &bo_idx)) {
798 TBM_ERR("fail to query plane data\n");
799 goto query_plane_data_fail;
802 surf->info.planes[i].size = size;
803 surf->info.planes[i].offset = offset;
804 surf->info.planes[i].stride = stride;
805 surf->planes_bo_idx[i] = bo_idx;
810 for (i = 0; i < surf->info.num_planes; i++) {
811 surf->info.size += surf->info.planes[i].size;
813 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
814 surf->num_bos = surf->planes_bo_idx[i] + 1;
819 for (i = 0; i < surf->num_bos; i++) {
821 for (j = 0; j < surf->info.num_planes; j++) {
822 if (surf->planes_bo_idx[j] == i)
823 bo_size += surf->info.planes[j].size;
826 if (bufmgr->backend_module_data) {
827 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
828 /* LCOV_EXCL_START */
829 bo = calloc(1, sizeof(struct _tbm_bo));
831 TBM_ERR("fail to alloc bo struct\n");
832 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
836 bo->bufmgr = surf->bufmgr;
838 _tbm_bufmgr_mutex_lock();
840 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format(bufmgr->bufmgr_data, format, i,
841 width, height, flags, &error);
843 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
844 _tbm_set_last_result(error);
846 _tbm_bufmgr_mutex_unlock();
849 bo->bo_data = bo_data;
853 LIST_INITHEAD(&bo->user_data_list);
855 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
857 _tbm_bufmgr_mutex_unlock();
861 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
862 bo = calloc(1, sizeof(struct _tbm_bo));
864 TBM_ERR("fail to alloc bo struct\n");
865 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
869 bo->bufmgr = surf->bufmgr;
871 _tbm_bufmgr_mutex_lock();
873 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format(bufmgr->bufmgr_data, width, height, surf->info.bpp/8, format, flags, i, &error);
875 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
876 _tbm_set_last_result(error);
878 _tbm_bufmgr_mutex_unlock();
881 bo->bo_data = bo_data;
885 LIST_INITHEAD(&bo->user_data_list);
887 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
889 _tbm_bufmgr_mutex_unlock();
894 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
896 TBM_ERR("fail to alloc bo idx:%d\n", i);
901 if (bufmgr->backend->surface_bo_alloc) {
902 /* LCOV_EXCL_START */
903 bo = calloc(1, sizeof(struct _tbm_bo));
905 TBM_ERR("fail to alloc bo struct\n");
906 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
910 bo->bufmgr = surf->bufmgr;
912 _tbm_bufmgr_mutex_lock();
914 bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
916 TBM_ERR("fail to alloc bo priv\n");
917 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
919 _tbm_bufmgr_mutex_unlock();
926 LIST_INITHEAD(&bo->user_data_list);
928 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
930 _tbm_bufmgr_mutex_unlock();
935 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
937 TBM_ERR("fail to alloc bo idx:%d\n", i);
943 _tbm_bo_set_surface(surf->bos[i], surf);
946 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
947 _tbm_surface_internal_format_to_str(format), flags, surf);
949 LIST_INITHEAD(&surf->user_data_list);
950 LIST_INITHEAD(&surf->debug_data_list);
952 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
954 _tbm_surface_mutex_unlock();
958 /* LCOV_EXCL_START */
960 for (j = 0; j < i; j++) {
962 tbm_bo_unref(surf->bos[j]);
964 query_plane_data_fail:
970 if (bufmgr_initialized && bufmgr) {
971 LIST_DELINIT(&bufmgr->surf_list);
972 _deinit_surface_bufmgr();
974 _tbm_surface_mutex_unlock();
976 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
978 _tbm_surface_internal_format_to_str(format), flags);
985 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
986 tbm_bo *bos, int num)
988 struct _tbm_bufmgr *bufmgr;
989 struct _tbm_surface *surf = NULL;
991 bool bufmgr_initialized = false;
993 _tbm_surface_mutex_lock();
994 _tbm_set_last_result(TBM_ERROR_NONE);
996 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
997 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
998 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
999 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1000 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1002 if (!g_surface_bufmgr) {
1003 _init_surface_bufmgr();
1004 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1005 bufmgr_initialized = true;
1008 bufmgr = g_surface_bufmgr;
1009 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1010 TBM_ERR("fail to validate the Bufmgr.\n");
1011 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1012 goto check_valid_fail;
1015 surf = calloc(1, sizeof(struct _tbm_surface));
1017 /* LCOV_EXCL_START */
1018 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1019 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1020 goto alloc_surf_fail;
1021 /* LCOV_EXCL_STOP */
1024 surf->bufmgr = bufmgr;
1025 surf->info.width = info->width;
1026 surf->info.height = info->height;
1027 surf->info.format = info->format;
1029 surf->info.bpp = info->bpp;
1031 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1032 if (!surf->info.bpp) {
1033 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1037 surf->info.num_planes = info->num_planes;
1040 /* get size, stride and offset */
1041 for (i = 0; i < info->num_planes; i++) {
1042 surf->info.planes[i].offset = info->planes[i].offset;
1043 surf->info.planes[i].stride = info->planes[i].stride;
1045 if (info->planes[i].size > 0)
1046 surf->info.planes[i].size = info->planes[i].size;
1048 uint32_t size = 0, offset = 0, stride = 0;
1051 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1052 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1053 goto plane_data_fail;
1055 surf->info.planes[i].size = size;
1059 surf->planes_bo_idx[i] = 0;
1061 surf->planes_bo_idx[i] = i;
1064 if (info->size > 0) {
1065 surf->info.size = info->size;
1067 surf->info.size = 0;
1068 for (i = 0; i < info->num_planes; i++)
1069 surf->info.size += surf->info.planes[i].size;
1072 surf->flags = TBM_BO_DEFAULT;
1074 /* create only one bo */
1075 surf->num_bos = num;
1076 for (i = 0; i < num; i++) {
1077 if (bos[i] == NULL) {
1078 TBM_ERR("bos[%d] is null.\n", i);
1079 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1083 surf->bos[i] = tbm_bo_ref(bos[i]);
1084 _tbm_bo_set_surface(bos[i], surf);
1087 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1088 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1090 LIST_INITHEAD(&surf->user_data_list);
1091 LIST_INITHEAD(&surf->debug_data_list);
1093 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1095 _tbm_surface_mutex_unlock();
1099 /* LCOV_EXCL_START */
1103 for (i = 0; i < num; i++) {
1105 tbm_bo_unref(surf->bos[i]);
1110 if (bufmgr_initialized && bufmgr) {
1111 LIST_DELINIT(&bufmgr->surf_list);
1112 _deinit_surface_bufmgr();
1114 _tbm_surface_mutex_unlock();
1116 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1117 info->width, info->height,
1118 _tbm_surface_internal_format_to_str(info->format), num);
1119 /* LCOV_EXCL_STOP */
1125 tbm_surface_internal_destroy(tbm_surface_h surface)
1127 _tbm_surface_mutex_lock();
1128 _tbm_set_last_result(TBM_ERROR_NONE);
1130 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1134 if (surface->refcnt > 0) {
1135 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1136 _tbm_surface_mutex_unlock();
1140 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1142 if (surface->refcnt == 0)
1143 _tbm_surface_internal_destroy(surface);
1145 _tbm_surface_mutex_unlock();
1149 tbm_surface_internal_ref(tbm_surface_h surface)
1151 _tbm_surface_mutex_lock();
1152 _tbm_set_last_result(TBM_ERROR_NONE);
1154 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1158 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1160 _tbm_surface_mutex_unlock();
1164 tbm_surface_internal_unref(tbm_surface_h surface)
1166 _tbm_surface_mutex_lock();
1167 _tbm_set_last_result(TBM_ERROR_NONE);
1169 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1173 if (surface->refcnt > 0) {
1174 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1175 _tbm_surface_mutex_unlock();
1179 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1181 if (surface->refcnt == 0)
1182 _tbm_surface_internal_destroy(surface);
1184 _tbm_surface_mutex_unlock();
1188 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1190 struct _tbm_surface *surf;
1193 _tbm_surface_mutex_lock();
1194 _tbm_set_last_result(TBM_ERROR_NONE);
1196 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1198 surf = (struct _tbm_surface *)surface;
1199 num = surf->num_bos;
1202 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1204 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1206 _tbm_surface_mutex_unlock();
1212 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1214 struct _tbm_surface *surf;
1217 _tbm_surface_mutex_lock();
1218 _tbm_set_last_result(TBM_ERROR_NONE);
1220 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1221 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1223 surf = (struct _tbm_surface *)surface;
1224 bo = surf->bos[bo_idx];
1226 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1228 _tbm_surface_mutex_unlock();
1234 tbm_surface_internal_get_size(tbm_surface_h surface)
1236 struct _tbm_surface *surf;
1239 _tbm_surface_mutex_lock();
1240 _tbm_set_last_result(TBM_ERROR_NONE);
1242 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1244 surf = (struct _tbm_surface *)surface;
1245 size = surf->info.size;
1247 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1249 _tbm_surface_mutex_unlock();
1255 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1256 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1258 struct _tbm_surface *surf;
1260 _tbm_surface_mutex_lock();
1261 _tbm_set_last_result(TBM_ERROR_NONE);
1263 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1264 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1266 surf = (struct _tbm_surface *)surface;
1268 if (plane_idx >= surf->info.num_planes) {
1269 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1270 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1271 _tbm_surface_mutex_unlock();
1276 *size = surf->info.planes[plane_idx].size;
1279 *offset = surf->info.planes[plane_idx].offset;
1282 *pitch = surf->info.planes[plane_idx].stride;
1284 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1285 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1286 surf->info.planes[plane_idx].stride);
1288 _tbm_surface_mutex_unlock();
1294 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1295 tbm_surface_info_s *info, int map)
1297 struct _tbm_surface *surf;
1298 tbm_bo_handle bo_handles[4];
1301 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1304 _tbm_surface_mutex_lock();
1305 _tbm_set_last_result(TBM_ERROR_NONE);
1307 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1309 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1311 surf = (struct _tbm_surface *)surface;
1313 memset(info, 0x00, sizeof(tbm_surface_info_s));
1314 info->width = surf->info.width;
1315 info->height = surf->info.height;
1316 info->format = surf->info.format;
1317 info->bpp = surf->info.bpp;
1318 info->size = surf->info.size;
1319 info->num_planes = surf->info.num_planes;
1321 for (i = 0; i < surf->info.num_planes; i++) {
1322 info->planes[i].size = surf->info.planes[i].size;
1323 info->planes[i].offset = surf->info.planes[i].offset;
1324 info->planes[i].stride = surf->info.planes[i].stride;
1325 planes_bo_idx[i] = surf->planes_bo_idx[i];
1328 for (i = 0; i < surf->num_bos; i++)
1329 bos[i] = surf->bos[i];
1331 num_bos = surf->num_bos;
1334 _tbm_surface_mutex_unlock();
1335 for (i = 0; i < num_bos; i++) {
1336 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1337 if (bo_handles[i].ptr == NULL) {
1338 for (j = 0; j < i; j++)
1339 tbm_bo_unmap(bos[j]);
1341 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1345 _tbm_surface_mutex_lock();
1347 for (i = 0; i < num_bos; i++) {
1348 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1349 if (bo_handles[i].ptr == NULL) {
1350 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1351 _tbm_surface_mutex_unlock();
1357 for (i = 0; i < info->num_planes; i++) {
1358 if (bo_handles[planes_bo_idx[i]].ptr)
1359 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1362 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1364 _tbm_surface_mutex_unlock();
1370 tbm_surface_internal_unmap(tbm_surface_h surface)
1372 struct _tbm_surface *surf;
1375 _tbm_surface_mutex_lock();
1376 _tbm_set_last_result(TBM_ERROR_NONE);
1378 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1380 surf = (struct _tbm_surface *)surface;
1382 for (i = 0; i < surf->num_bos; i++)
1383 tbm_bo_unmap(surf->bos[i]);
1385 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1387 _tbm_surface_mutex_unlock();
1391 tbm_surface_internal_get_width(tbm_surface_h surface)
1393 struct _tbm_surface *surf;
1396 _tbm_surface_mutex_lock();
1397 _tbm_set_last_result(TBM_ERROR_NONE);
1399 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1401 surf = (struct _tbm_surface *)surface;
1402 width = surf->info.width;
1404 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1406 _tbm_surface_mutex_unlock();
1412 tbm_surface_internal_get_height(tbm_surface_h surface)
1414 struct _tbm_surface *surf;
1415 unsigned int height;
1417 _tbm_surface_mutex_lock();
1418 _tbm_set_last_result(TBM_ERROR_NONE);
1420 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1422 surf = (struct _tbm_surface *)surface;
1423 height = surf->info.height;
1425 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1427 _tbm_surface_mutex_unlock();
1434 tbm_surface_internal_get_format(tbm_surface_h surface)
1436 struct _tbm_surface *surf;
1439 _tbm_surface_mutex_lock();
1440 _tbm_set_last_result(TBM_ERROR_NONE);
1442 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1444 surf = (struct _tbm_surface *)surface;
1445 format = surf->info.format;
1447 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1449 _tbm_surface_mutex_unlock();
1455 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1457 struct _tbm_surface *surf;
1460 _tbm_surface_mutex_lock();
1461 _tbm_set_last_result(TBM_ERROR_NONE);
1463 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1464 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1466 surf = (struct _tbm_surface *)surface;
1467 bo_idx = surf->planes_bo_idx[plane_idx];
1469 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1471 _tbm_surface_mutex_unlock();
1477 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1478 tbm_data_free data_free_func)
1480 tbm_user_data *data;
1482 _tbm_surface_mutex_lock();
1483 _tbm_set_last_result(TBM_ERROR_NONE);
1485 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1487 /* check if the data according to the key exist if so, return false. */
1488 data = user_data_lookup(&surface->user_data_list, key);
1490 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1491 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1492 _tbm_surface_mutex_unlock();
1496 data = user_data_create(key, data_free_func);
1498 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1499 _tbm_surface_mutex_unlock();
1503 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1505 LIST_ADD(&data->item_link, &surface->user_data_list);
1507 _tbm_surface_mutex_unlock();
1513 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1516 tbm_user_data *old_data;
1518 _tbm_surface_mutex_lock();
1519 _tbm_set_last_result(TBM_ERROR_NONE);
1521 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1523 old_data = user_data_lookup(&surface->user_data_list, key);
1525 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1526 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1527 _tbm_surface_mutex_unlock();
1531 if (old_data->data && old_data->free_func)
1532 old_data->free_func(old_data->data);
1534 old_data->data = data;
1536 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1538 _tbm_surface_mutex_unlock();
1544 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1547 tbm_user_data *old_data;
1549 _tbm_surface_mutex_lock();
1550 _tbm_set_last_result(TBM_ERROR_NONE);
1552 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1555 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1556 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1557 _tbm_surface_mutex_unlock();
1562 old_data = user_data_lookup(&surface->user_data_list, key);
1564 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1565 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1566 _tbm_surface_mutex_unlock();
1570 *data = old_data->data;
1572 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1574 _tbm_surface_mutex_unlock();
1580 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1583 tbm_user_data *old_data = (void *)0;
1585 _tbm_surface_mutex_lock();
1586 _tbm_set_last_result(TBM_ERROR_NONE);
1588 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1590 old_data = user_data_lookup(&surface->user_data_list, key);
1592 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1593 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1594 _tbm_surface_mutex_unlock();
1598 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1600 user_data_delete(old_data);
1602 _tbm_surface_mutex_unlock();
1607 /* LCOV_EXCL_START */
1609 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1611 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1613 return surface->debug_pid;
1617 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1619 _tbm_surface_mutex_lock();
1620 _tbm_set_last_result(TBM_ERROR_NONE);
1622 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1624 surface->debug_pid = pid;
1626 _tbm_surface_mutex_unlock();
1629 static tbm_surface_debug_data *
1630 _tbm_surface_internal_debug_data_create(char *key, char *value)
1632 tbm_surface_debug_data *debug_data = NULL;
1634 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1636 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1637 TBM_ERR("fail to allocate the debug_data.");
1641 if (key) debug_data->key = strdup(key);
1642 if (value) debug_data->value = strdup(value);
1648 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1650 tbm_surface_debug_data *debug_data = NULL;
1651 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1652 tbm_bufmgr bufmgr = NULL;
1654 _tbm_surface_mutex_lock();
1655 _tbm_set_last_result(TBM_ERROR_NONE);
1657 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1658 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1660 bufmgr = surface->bufmgr;
1662 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1664 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1665 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1667 if (!strcmp(old_data->key, key)) {
1668 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1669 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1670 goto add_debug_key_list;
1673 if (old_data->value)
1674 free(old_data->value);
1677 old_data->value = strdup(value);
1679 old_data->value = NULL;
1681 goto add_debug_key_list;
1687 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1689 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1690 _tbm_surface_mutex_unlock();
1694 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1696 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1699 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1700 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1701 if (!strcmp(old_data->key, key)) {
1702 _tbm_surface_mutex_unlock();
1708 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1709 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1711 _tbm_surface_mutex_unlock();
1717 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1719 tbm_surface_debug_data *old_data = NULL;
1721 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1723 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1724 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1725 if (!strcmp(old_data->key, key))
1726 return old_data->value;
1733 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1734 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1736 struct _tbm_surface_dump_buf_info {
1746 tbm_surface_info_s info;
1748 struct list_head link;
1751 struct _tbm_surface_dump_info {
1752 char *path; // copy???
1755 struct list_head *link;
1756 struct list_head surface_list; /* link of surface */
1759 static tbm_surface_dump_info *g_dump_info = NULL;
1760 static const char *dump_postfix[2] = {"png", "yuv"};
1761 static double scale_factor;
1764 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1765 void *data2, int size2, void *data3, int size3)
1768 unsigned int *blocks;
1770 if (_tbm_surface_check_file_is_symbolic_link(file))
1771 TBM_ERR("%s is symbolic link\n", file);
1773 fp = fopen(file, "w+");
1774 TBM_RETURN_IF_FAIL(fp != NULL);
1776 blocks = (unsigned int *)data1;
1777 fwrite(blocks, 1, size1, fp);
1780 blocks = (unsigned int *)data2;
1781 fwrite(blocks, 1, size2, fp);
1785 blocks = (unsigned int *)data3;
1786 fwrite(blocks, 1, size3, fp);
1793 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1795 unsigned int *blocks = (unsigned int *)data;
1798 png_bytep *row_pointers;
1801 if (_tbm_surface_check_file_is_symbolic_link(file))
1802 TBM_ERR("%s is symbolic link\n", file);
1804 fp = fopen(file, "wb");
1805 TBM_RETURN_IF_FAIL(fp != NULL);
1807 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1810 TBM_ERR("fail to create a png write structure.\n");
1815 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1817 TBM_ERR("fail to create a png info structure.\n");
1818 png_destroy_write_struct(&pPngStruct, NULL);
1823 png_init_io(pPngStruct, fp);
1824 if (format == TBM_FORMAT_XRGB8888) {
1826 png_set_IHDR(pPngStruct,
1833 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1836 png_set_IHDR(pPngStruct,
1841 PNG_COLOR_TYPE_RGBA,
1843 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1846 png_set_bgr(pPngStruct);
1847 png_write_info(pPngStruct, pPngInfo);
1849 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1850 if (!row_pointers) {
1851 TBM_ERR("fail to allocate the png row_pointers.\n");
1852 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1857 for (y = 0; y < height; ++y) {
1861 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1863 TBM_ERR("fail to allocate the png row.\n");
1864 for (x = 0; x < y; x++)
1865 png_free(pPngStruct, row_pointers[x]);
1866 png_free(pPngStruct, row_pointers);
1867 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1871 row_pointers[y] = (png_bytep)row;
1873 for (x = 0; x < width; ++x) {
1874 unsigned int curBlock = blocks[y * width + x];
1876 if (pixel_size == 3) { // XRGB8888
1877 row[x * pixel_size] = (curBlock & 0xFF);
1878 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1879 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1880 } else { // ARGB8888
1881 row[x * pixel_size] = (curBlock & 0xFF);
1882 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1883 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1884 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1889 png_write_image(pPngStruct, row_pointers);
1890 png_write_end(pPngStruct, pPngInfo);
1892 for (y = 0; y < height; y++)
1893 png_free(pPngStruct, row_pointers[y]);
1894 png_free(pPngStruct, row_pointers);
1896 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1902 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1904 TBM_RETURN_IF_FAIL(path != NULL);
1905 TBM_RETURN_IF_FAIL(w > 0);
1906 TBM_RETURN_IF_FAIL(h > 0);
1907 TBM_RETURN_IF_FAIL(count > 0);
1909 tbm_surface_dump_buf_info *buf_info = NULL;
1910 tbm_surface_h tbm_surface;
1911 tbm_surface_info_s info;
1916 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1920 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1921 TBM_RETURN_IF_FAIL(g_dump_info);
1923 LIST_INITHEAD(&g_dump_info->surface_list);
1924 g_dump_info->count = 0;
1925 g_dump_info->dump_max = count;
1927 /* get buffer size */
1928 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1929 if (tbm_surface == NULL) {
1930 TBM_ERR("tbm_surface_create fail\n");
1936 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1937 TBM_ERR("tbm_surface_get_info fail\n");
1938 tbm_surface_destroy(tbm_surface);
1943 buffer_size = info.size;
1944 tbm_surface_destroy(tbm_surface);
1946 /* create dump lists */
1947 for (i = 0; i < count; i++) {
1950 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1951 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1953 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1955 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1960 buf_info->index = i;
1962 buf_info->size = buffer_size;
1964 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1967 g_dump_info->path = path;
1968 g_dump_info->link = &g_dump_info->surface_list;
1972 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1977 /* free resources */
1978 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1979 tbm_surface_dump_buf_info *tmp;
1981 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1982 tbm_bo_unref(buf_info->bo);
1983 LIST_DEL(&buf_info->link);
1988 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1997 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2004 tbm_surface_internal_dump_start(path, w, h, count);
2005 scale_factor = scale;
2009 tbm_surface_internal_dump_end(void)
2011 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2012 tbm_bo_handle bo_handle;
2017 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2024 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2027 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2028 if (bo_handle.ptr == NULL) {
2029 tbm_bo_unref(buf_info->bo);
2030 LIST_DEL(&buf_info->link);
2035 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2036 TBM_INFO("Dump File.. %s generated.\n", file);
2038 if (buf_info->dirty) {
2039 void *ptr1 = NULL, *ptr2 = NULL;
2041 switch (buf_info->info.format) {
2042 case TBM_FORMAT_ARGB8888:
2043 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2044 buf_info->info.planes[0].stride >> 2,
2045 buf_info->info.height, TBM_FORMAT_ARGB8888);
2047 case TBM_FORMAT_XRGB8888:
2048 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2049 buf_info->info.planes[0].stride >> 2,
2050 buf_info->info.height, TBM_FORMAT_XRGB8888);
2052 case TBM_FORMAT_YVU420:
2053 case TBM_FORMAT_YUV420:
2054 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2055 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2056 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2057 buf_info->info.planes[0].stride * buf_info->info.height,
2059 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2061 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2063 case TBM_FORMAT_NV12:
2064 case TBM_FORMAT_NV21:
2065 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2066 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2067 buf_info->info.planes[0].stride * buf_info->info.height,
2069 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2072 case TBM_FORMAT_YUYV:
2073 case TBM_FORMAT_UYVY:
2074 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2075 buf_info->info.planes[0].stride * buf_info->info.height,
2079 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2082 } else if (buf_info->dirty_shm)
2083 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2084 buf_info->shm_stride >> 2,
2085 buf_info->shm_h, 0);
2087 tbm_bo_unmap(buf_info->bo);
2088 tbm_bo_unref(buf_info->bo);
2089 LIST_DEL(&buf_info->link);
2096 TBM_INFO("Dump End..\n");
2099 static pixman_format_code_t
2100 _tbm_surface_internal_pixman_format_get(tbm_format format)
2103 case TBM_FORMAT_ARGB8888:
2104 return PIXMAN_a8r8g8b8;
2105 case TBM_FORMAT_XRGB8888:
2106 return PIXMAN_x8r8g8b8;
2115 * This function supports only if a buffer has below formats.
2116 * - TBM_FORMAT_ARGB8888
2117 * - TBM_FORMAT_XRGB8888
2119 static tbm_surface_error_e
2120 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2121 int format, int src_stride, int src_w, int src_h,
2122 int dst_stride, int dst_w, int dst_h)
2124 pixman_image_t *src_img = NULL, *dst_img = NULL;
2125 pixman_format_code_t pixman_format;
2126 pixman_transform_t t;
2127 struct pixman_f_transform ft;
2128 double scale_x, scale_y;
2130 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2131 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2133 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2134 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2137 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2138 (uint32_t*)src_ptr, src_stride);
2139 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2142 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2143 (uint32_t*)dst_ptr, dst_stride);
2144 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2146 pixman_f_transform_init_identity(&ft);
2148 scale_x = (double)src_w / dst_w;
2149 scale_y = (double)src_h / dst_h;
2151 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2152 pixman_f_transform_translate(&ft, NULL, 0, 0);
2153 pixman_transform_from_pixman_f_transform(&t, &ft);
2154 pixman_image_set_transform(src_img, &t);
2156 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2157 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2159 pixman_image_unref(src_img);
2160 pixman_image_unref(dst_img);
2162 return TBM_SURFACE_ERROR_NONE;
2166 pixman_image_unref(src_img);
2168 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2171 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2172 #define KEY_LEN 5 // "_XXXX"
2173 #define KEYS_LEN KEY_LEN * MAX_BOS
2175 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2177 char *keys, temp_key[KEY_LEN + 1];
2178 struct _tbm_surface *surf;
2182 _tbm_surface_mutex_lock();
2184 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2186 surf = (struct _tbm_surface *)surface;
2188 num_bos = surf->num_bos;
2189 if (num_bos > MAX_BOS)
2192 keys = calloc(KEYS_LEN + 1, sizeof(char));
2194 TBM_ERR("Failed to alloc memory");
2195 _tbm_surface_mutex_unlock();
2199 for (i = 0; i < num_bos; i++) {
2200 memset(temp_key, 0x00, KEY_LEN + 1);
2202 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2203 strncat(keys, temp_key, KEY_LEN);
2206 _tbm_surface_mutex_unlock();
2211 static void _tbm_surface_internal_put_keys(char *keys)
2218 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2220 TBM_RETURN_IF_FAIL(surface != NULL);
2221 TBM_RETURN_IF_FAIL(type != NULL);
2223 tbm_surface_dump_buf_info *buf_info;
2224 struct list_head *next_link;
2225 tbm_surface_info_s info;
2226 tbm_bo_handle bo_handle;
2227 const char *postfix;
2228 const char *format = NULL;
2235 next_link = g_dump_info->link->next;
2236 TBM_RETURN_IF_FAIL(next_link != NULL);
2238 if (next_link == &g_dump_info->surface_list) {
2239 next_link = next_link->next;
2240 TBM_RETURN_IF_FAIL(next_link != NULL);
2243 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2244 TBM_RETURN_IF_FAIL(buf_info != NULL);
2246 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2247 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2249 if (scale_factor > 0.0) {
2252 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2253 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2254 _tbm_surface_internal_format_to_str(info.format));
2255 tbm_surface_unmap(surface);
2259 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2261 buf_info->info.width = info.width * scale_factor;
2262 buf_info->info.height = info.height * scale_factor;
2263 buf_info->info.format = info.format;
2264 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2265 if (!buf_info->info.bpp) {
2266 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2267 tbm_surface_unmap(surface);
2270 buf_info->info.num_planes = 1;
2271 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2272 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2274 if (buf_info->info.size > buf_info->size) {
2275 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2276 buf_info->info.size, buf_info->size);
2277 tbm_surface_unmap(surface);
2281 if (info.size > buf_info->size) {
2282 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2283 info.size, buf_info->size);
2284 tbm_surface_unmap(surface);
2288 /* make the file information */
2289 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2292 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2293 postfix = dump_postfix[0];
2294 format = _tbm_surface_internal_format_to_str(info.format);
2296 postfix = dump_postfix[1];
2298 keys = _tbm_surface_internal_get_keys(surface);
2300 TBM_ERR("fail to get keys");
2301 tbm_surface_unmap(surface);
2306 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2307 if (!bo_handle.ptr) {
2308 TBM_ERR("fail to map bo");
2309 _tbm_surface_internal_put_keys(keys);
2310 tbm_surface_unmap(surface);
2313 memset(bo_handle.ptr, 0x00, buf_info->size);
2315 switch (info.format) {
2316 case TBM_FORMAT_ARGB8888:
2317 case TBM_FORMAT_XRGB8888:
2318 snprintf(buf_info->name, sizeof(buf_info->name),
2319 "%10.3f_%03d%s_%p_%s-%s.%s",
2320 _tbm_surface_internal_get_time(),
2321 g_dump_info->count++, keys, surface, format, type, postfix);
2323 if (scale_factor > 0.0) {
2324 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2326 buf_info->info.format,
2327 info.planes[0].stride,
2328 info.width, info.height,
2329 buf_info->info.planes[0].stride,
2330 buf_info->info.width,
2331 buf_info->info.height);
2332 if (ret != TBM_SURFACE_ERROR_NONE) {
2333 TBM_ERR("fail to scale buffer");
2334 tbm_bo_unmap(buf_info->bo);
2335 _tbm_surface_internal_put_keys(keys);
2336 tbm_surface_unmap(surface);
2340 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2342 case TBM_FORMAT_YVU420:
2343 case TBM_FORMAT_YUV420:
2344 snprintf(buf_info->name, sizeof(buf_info->name),
2345 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2346 _tbm_surface_internal_get_time(),
2347 g_dump_info->count++, keys, type, info.planes[0].stride,
2348 info.height, FOURCC_STR(info.format), postfix);
2349 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2350 bo_handle.ptr += info.planes[0].stride * info.height;
2351 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2352 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2353 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2355 case TBM_FORMAT_NV12:
2356 case TBM_FORMAT_NV21:
2357 snprintf(buf_info->name, sizeof(buf_info->name),
2358 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2359 _tbm_surface_internal_get_time(),
2360 g_dump_info->count++, keys, type, info.planes[0].stride,
2361 info.height, FOURCC_STR(info.format), postfix);
2362 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2363 bo_handle.ptr += info.planes[0].stride * info.height;
2364 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2366 case TBM_FORMAT_YUYV:
2367 case TBM_FORMAT_UYVY:
2368 snprintf(buf_info->name, sizeof(buf_info->name),
2369 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2370 _tbm_surface_internal_get_time(),
2371 g_dump_info->count++, keys, type, info.planes[0].stride,
2372 info.height, FOURCC_STR(info.format), postfix);
2373 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2376 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2377 tbm_bo_unmap(buf_info->bo);
2378 _tbm_surface_internal_put_keys(keys);
2379 tbm_surface_unmap(surface);
2383 tbm_bo_unmap(buf_info->bo);
2385 _tbm_surface_internal_put_keys(keys);
2387 tbm_surface_unmap(surface);
2389 buf_info->dirty = 1;
2390 buf_info->dirty_shm = 0;
2392 if (g_dump_info->count == 1000)
2393 g_dump_info->count = 0;
2395 g_dump_info->link = next_link;
2397 TBM_INFO("Dump %s \n", buf_info->name);
2400 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2403 TBM_RETURN_IF_FAIL(ptr != NULL);
2404 TBM_RETURN_IF_FAIL(w > 0);
2405 TBM_RETURN_IF_FAIL(h > 0);
2406 TBM_RETURN_IF_FAIL(stride > 0);
2407 TBM_RETURN_IF_FAIL(type != NULL);
2409 tbm_surface_dump_buf_info *buf_info;
2410 struct list_head *next_link;
2411 tbm_bo_handle bo_handle;
2412 int ret, size, dw = 0, dh = 0, dstride = 0;
2417 next_link = g_dump_info->link->next;
2418 TBM_RETURN_IF_FAIL(next_link != NULL);
2420 if (next_link == &g_dump_info->surface_list) {
2421 next_link = next_link->next;
2422 TBM_RETURN_IF_FAIL(next_link != NULL);
2425 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2426 TBM_RETURN_IF_FAIL(buf_info != NULL);
2428 if (scale_factor > 0.0) {
2431 dw = w * scale_factor;
2432 dh = h * scale_factor;
2434 size = dstride * dh;
2438 if (size > buf_info->size) {
2439 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2440 size, buf_info->size);
2445 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2446 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2448 memset(bo_handle.ptr, 0x00, buf_info->size);
2449 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2451 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2452 _tbm_surface_internal_get_time(),
2453 g_dump_info->count++, type, dump_postfix[0]);
2454 if (scale_factor > 0.0) {
2455 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2456 TBM_FORMAT_ARGB8888, stride,
2457 w, h, dstride, dw, dh);
2458 if (ret != TBM_SURFACE_ERROR_NONE) {
2459 TBM_ERR("fail to scale buffer");
2460 tbm_bo_unmap(buf_info->bo);
2463 buf_info->shm_stride = dstride;
2464 buf_info->shm_h = dh;
2466 memcpy(bo_handle.ptr, ptr, size);
2467 buf_info->shm_stride = stride;
2468 buf_info->shm_h = h;
2471 tbm_bo_unmap(buf_info->bo);
2473 buf_info->dirty = 0;
2474 buf_info->dirty_shm = 1;
2476 if (g_dump_info->count == 1000)
2477 g_dump_info->count = 0;
2479 g_dump_info->link = next_link;
2481 TBM_INFO("Dump %s \n", buf_info->name);
2485 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2487 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2488 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2489 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2491 tbm_surface_info_s info;
2492 const char *postfix;
2496 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2497 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2499 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2500 postfix = dump_postfix[0];
2502 postfix = dump_postfix[1];
2504 if (strcmp(postfix, type)) {
2505 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2506 tbm_surface_unmap(surface);
2510 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2512 if (!access(file, 0)) {
2513 TBM_ERR("can't capture buffer, exist file %s", file);
2514 tbm_surface_unmap(surface);
2518 switch (info.format) {
2519 case TBM_FORMAT_ARGB8888:
2520 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2521 info.planes[0].stride >> 2,
2522 info.height, TBM_FORMAT_ARGB8888);
2524 case TBM_FORMAT_XRGB8888:
2525 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2526 info.planes[0].stride >> 2,
2527 info.height, TBM_FORMAT_XRGB8888);
2529 case TBM_FORMAT_YVU420:
2530 case TBM_FORMAT_YUV420:
2531 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2532 info.planes[0].stride * info.height,
2534 info.planes[1].stride * (info.height >> 1),
2536 info.planes[2].stride * (info.height >> 1));
2538 case TBM_FORMAT_NV12:
2539 case TBM_FORMAT_NV21:
2540 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2541 info.planes[0].stride * info.height,
2543 info.planes[1].stride * (info.height >> 1),
2546 case TBM_FORMAT_YUYV:
2547 case TBM_FORMAT_UYVY:
2548 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2549 info.planes[0].stride * info.height,
2553 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2554 tbm_surface_unmap(surface);
2558 tbm_surface_unmap(surface);
2560 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2566 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2567 const char *path, const char *name, const char *type)
2569 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2570 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2571 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2572 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2573 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2574 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2578 if (strcmp(dump_postfix[0], type)) {
2579 TBM_ERR("Not supported type:%s'", type);
2583 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2585 if (!access(file, 0)) {
2586 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2590 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2592 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2598 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2600 struct _tbm_surface *surf;
2602 _tbm_surface_mutex_lock();
2603 _tbm_set_last_result(TBM_ERROR_NONE);
2605 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2606 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2607 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2609 surf = (struct _tbm_surface *)surface;
2613 surf->damage.width = width;
2614 surf->damage.height = height;
2616 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2617 surface, x, y, width, height);
2619 _tbm_surface_mutex_unlock();
2625 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2627 struct _tbm_surface *surf;
2629 _tbm_surface_mutex_lock();
2630 _tbm_set_last_result(TBM_ERROR_NONE);
2632 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2634 surf = (struct _tbm_surface *)surface;
2636 if (x) *x = surf->damage.x;
2637 if (y) *y = surf->damage.y;
2638 if (width) *width = surf->damage.width;
2639 if (height) *height = surf->damage.height;
2641 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2642 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2644 _tbm_surface_mutex_unlock();