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 #define TBM_SURFACE_MAGIC 0xBF021234
46 static tbm_bufmgr g_surface_bufmgr;
47 static pthread_mutex_t tbm_surface_lock = PTHREAD_MUTEX_INITIALIZER;
48 void _tbm_surface_mutex_unlock(void);
51 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
53 TBM_ERR("'%s' failed.\n", #cond);\
54 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
55 _tbm_surface_mutex_unlock();\
60 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
62 TBM_ERR("'%s' failed.\n", #cond);\
63 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
64 _tbm_surface_mutex_unlock();\
71 _tbm_surface_internal_get_time(void)
76 clock_gettime(CLOCK_MONOTONIC, &tp);
77 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
83 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
85 LIST_DEL(&debug_data->item_link);
87 if (debug_data->key) free(debug_data->key);
88 if (debug_data->value) free(debug_data->value);
93 _tbm_surface_internal_format_to_str(tbm_format format)
97 return "TBM_FORMAT_C8";
98 case TBM_FORMAT_RGB332:
99 return "TBM_FORMAT_RGB332";
100 case TBM_FORMAT_BGR233:
101 return "TBM_FORMAT_BGR233";
102 case TBM_FORMAT_XRGB4444:
103 return "TBM_FORMAT_XRGB4444";
104 case TBM_FORMAT_XBGR4444:
105 return "TBM_FORMAT_XBGR4444";
106 case TBM_FORMAT_RGBX4444:
107 return "TBM_FORMAT_RGBX4444";
108 case TBM_FORMAT_BGRX4444:
109 return "TBM_FORMAT_BGRX4444";
110 case TBM_FORMAT_ARGB4444:
111 return "TBM_FORMAT_ARGB4444";
112 case TBM_FORMAT_ABGR4444:
113 return "TBM_FORMAT_ABGR4444";
114 case TBM_FORMAT_RGBA4444:
115 return "TBM_FORMAT_RGBA4444";
116 case TBM_FORMAT_BGRA4444:
117 return "TBM_FORMAT_BGRA4444";
118 case TBM_FORMAT_XRGB1555:
119 return "TBM_FORMAT_XRGB1555";
120 case TBM_FORMAT_XBGR1555:
121 return "TBM_FORMAT_XBGR1555";
122 case TBM_FORMAT_RGBX5551:
123 return "TBM_FORMAT_RGBX5551";
124 case TBM_FORMAT_BGRX5551:
125 return "TBM_FORMAT_BGRX5551";
126 case TBM_FORMAT_ARGB1555:
127 return "TBM_FORMAT_ARGB1555";
128 case TBM_FORMAT_ABGR1555:
129 return "TBM_FORMAT_ABGR1555";
130 case TBM_FORMAT_RGBA5551:
131 return "TBM_FORMAT_RGBA5551";
132 case TBM_FORMAT_BGRA5551:
133 return "TBM_FORMAT_BGRA5551";
134 case TBM_FORMAT_RGB565:
135 return "TBM_FORMAT_RGB565";
136 case TBM_FORMAT_BGR565:
137 return "TBM_FORMAT_BGR565";
138 case TBM_FORMAT_RGB888:
139 return "TBM_FORMAT_RGB888";
140 case TBM_FORMAT_BGR888:
141 return "TBM_FORMAT_BGR888";
142 case TBM_FORMAT_XRGB8888:
143 return "TBM_FORMAT_XRGB8888";
144 case TBM_FORMAT_XBGR8888:
145 return "TBM_FORMAT_XBGR8888";
146 case TBM_FORMAT_RGBX8888:
147 return "TBM_FORMAT_RGBX8888";
148 case TBM_FORMAT_BGRX8888:
149 return "TBM_FORMAT_BGRX8888";
150 case TBM_FORMAT_ARGB8888:
151 return "TBM_FORMAT_ARGB8888";
152 case TBM_FORMAT_ABGR8888:
153 return "TBM_FORMAT_ABGR8888";
154 case TBM_FORMAT_RGBA8888:
155 return "TBM_FORMAT_RGBA8888";
156 case TBM_FORMAT_BGRA8888:
157 return "TBM_FORMAT_BGRA8888";
158 case TBM_FORMAT_XRGB2101010:
159 return "TBM_FORMAT_XRGB2101010";
160 case TBM_FORMAT_XBGR2101010:
161 return "TBM_FORMAT_XBGR2101010";
162 case TBM_FORMAT_RGBX1010102:
163 return "TBM_FORMAT_RGBX1010102";
164 case TBM_FORMAT_BGRX1010102:
165 return "TBM_FORMAT_BGRX1010102";
166 case TBM_FORMAT_ARGB2101010:
167 return "TBM_FORMAT_ARGB2101010";
168 case TBM_FORMAT_ABGR2101010:
169 return "TBM_FORMAT_ABGR2101010";
170 case TBM_FORMAT_RGBA1010102:
171 return "TBM_FORMAT_RGBA1010102";
172 case TBM_FORMAT_BGRA1010102:
173 return "TBM_FORMAT_BGRA1010102";
174 case TBM_FORMAT_YUYV:
175 return "TBM_FORMAT_YUYV";
176 case TBM_FORMAT_YVYU:
177 return "TBM_FORMAT_YVYU";
178 case TBM_FORMAT_UYVY:
179 return "TBM_FORMAT_UYVY";
180 case TBM_FORMAT_VYUY:
181 return "TBM_FORMAT_VYUY";
182 case TBM_FORMAT_AYUV:
183 return "TBM_FORMAT_AYUV";
184 case TBM_FORMAT_NV12:
185 return "TBM_FORMAT_NV12";
186 case TBM_FORMAT_NV21:
187 return "TBM_FORMAT_NV21";
188 case TBM_FORMAT_NV16:
189 return "TBM_FORMAT_NV16";
190 case TBM_FORMAT_NV61:
191 return "TBM_FORMAT_NV61";
192 case TBM_FORMAT_YUV410:
193 return "TBM_FORMAT_YUV410";
194 case TBM_FORMAT_YVU410:
195 return "TBM_FORMAT_YVU410";
196 case TBM_FORMAT_YUV411:
197 return "TBM_FORMAT_YUV411";
198 case TBM_FORMAT_YVU411:
199 return "TBM_FORMAT_YVU411";
200 case TBM_FORMAT_YUV420:
201 return "TBM_FORMAT_YUV420";
202 case TBM_FORMAT_YVU420:
203 return "TBM_FORMAT_YVU420";
204 case TBM_FORMAT_YUV422:
205 return "TBM_FORMAT_YUV422";
206 case TBM_FORMAT_YVU422:
207 return "TBM_FORMAT_YVU422";
208 case TBM_FORMAT_YUV444:
209 return "TBM_FORMAT_YUV444";
210 case TBM_FORMAT_YVU444:
211 return "TBM_FORMAT_YVU444";
212 case TBM_FORMAT_NV12MT:
213 return "TBM_FORMAT_NV12MT";
220 _tbm_surface_mutex_lock(void)
222 pthread_mutex_lock(&tbm_surface_lock);
226 _tbm_surface_mutex_unlock(void)
228 pthread_mutex_unlock(&tbm_surface_lock);
232 _init_surface_bufmgr(void)
234 g_surface_bufmgr = tbm_bufmgr_init(-1);
238 _deinit_surface_bufmgr(void)
240 if (!g_surface_bufmgr)
243 tbm_bufmgr_deinit(g_surface_bufmgr);
244 g_surface_bufmgr = NULL;
249 _tbm_surface_internal_magic_check(tbm_surface_h surface)
251 if (surface->magic != TBM_SURFACE_MAGIC)
258 _tbm_surface_internal_is_valid(tbm_surface_h surface)
261 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
262 TBM_ERR("error: No valid tbm_surface is NULL\n");
266 if (!_tbm_surface_internal_magic_check(surface)) {
267 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
268 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
276 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
277 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
279 TBM_RETURN_VAL_IF_FAIL(surface, 0);
280 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
282 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
283 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
287 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
288 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
289 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
290 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
292 if (bufmgr->use_hal_tbm) {
293 error = (tbm_error_e)hal_tbm_bufmgr_get_plane_data(bufmgr->hal_bufmgr, (hal_tbm_format)surf->info.format,
294 plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
295 /* LCOV_EXCL_START */
296 if (error == TBM_ERROR_NOT_SUPPORTED) {
297 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
299 } else if (error != TBM_ERROR_NONE) {
300 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
301 _tbm_set_last_result(error);
306 } else if (bufmgr->backend_module_data) {
307 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
308 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
312 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
313 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
314 if (error != TBM_ERROR_NONE) {
315 /* LCOV_EXCL_START */
316 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
317 _tbm_set_last_result(error);
323 if (!bufmgr->backend->surface_get_plane_data) {
324 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
328 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
329 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
331 /* LCOV_EXCL_START */
332 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
333 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
343 _tbm_surface_internal_destroy(tbm_surface_h surface)
346 tbm_bufmgr bufmgr = surface->bufmgr;
347 tbm_user_data *old_data = NULL, *tmp = NULL;
348 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
349 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
351 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
352 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
353 func_info->destroy_func(surface, func_info->user_data);
355 TBM_DBG("free destroy_funcs %p\n", surface);
356 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
357 LIST_DEL(&func_info->item_link);
362 /* destory the user_data_list */
363 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
364 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
365 TBM_DBG("free user_data\n");
366 user_data_delete(old_data);
370 for (i = 0; i < surface->num_bos; i++) {
371 surface->bos[i]->surface = NULL;
373 tbm_bo_unref(surface->bos[i]);
374 surface->bos[i] = NULL;
377 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
378 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
379 _tbm_surface_internal_debug_data_delete(debug_old_data);
382 LIST_DEL(&surface->item_link);
388 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
389 LIST_DELINIT(&bufmgr->surf_list);
391 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
392 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
393 _tbm_surface_internal_debug_data_delete(debug_old_data);
397 _deinit_surface_bufmgr();
401 /* LCOV_EXCL_START */
403 _tbm_surface_check_file_is_symbolic_link(const char* path)
410 if (stat(path, &sb) != 0)
413 if (S_ISLNK(sb.st_mode))
421 _tbm_surface_internal_get_num_planes(tbm_format format)
427 case TBM_FORMAT_RGB332:
428 case TBM_FORMAT_BGR233:
429 case TBM_FORMAT_XRGB4444:
430 case TBM_FORMAT_XBGR4444:
431 case TBM_FORMAT_RGBX4444:
432 case TBM_FORMAT_BGRX4444:
433 case TBM_FORMAT_ARGB4444:
434 case TBM_FORMAT_ABGR4444:
435 case TBM_FORMAT_RGBA4444:
436 case TBM_FORMAT_BGRA4444:
437 case TBM_FORMAT_XRGB1555:
438 case TBM_FORMAT_XBGR1555:
439 case TBM_FORMAT_RGBX5551:
440 case TBM_FORMAT_BGRX5551:
441 case TBM_FORMAT_ARGB1555:
442 case TBM_FORMAT_ABGR1555:
443 case TBM_FORMAT_RGBA5551:
444 case TBM_FORMAT_BGRA5551:
445 case TBM_FORMAT_RGB565:
446 case TBM_FORMAT_BGR565:
447 case TBM_FORMAT_RGB888:
448 case TBM_FORMAT_BGR888:
449 case TBM_FORMAT_XRGB8888:
450 case TBM_FORMAT_XBGR8888:
451 case TBM_FORMAT_RGBX8888:
452 case TBM_FORMAT_BGRX8888:
453 case TBM_FORMAT_ARGB8888:
454 case TBM_FORMAT_ABGR8888:
455 case TBM_FORMAT_RGBA8888:
456 case TBM_FORMAT_BGRA8888:
457 case TBM_FORMAT_XRGB2101010:
458 case TBM_FORMAT_XBGR2101010:
459 case TBM_FORMAT_RGBX1010102:
460 case TBM_FORMAT_BGRX1010102:
461 case TBM_FORMAT_ARGB2101010:
462 case TBM_FORMAT_ABGR2101010:
463 case TBM_FORMAT_RGBA1010102:
464 case TBM_FORMAT_BGRA1010102:
465 case TBM_FORMAT_YUYV:
466 case TBM_FORMAT_YVYU:
467 case TBM_FORMAT_UYVY:
468 case TBM_FORMAT_VYUY:
469 case TBM_FORMAT_AYUV:
472 case TBM_FORMAT_NV12:
473 case TBM_FORMAT_NV12MT:
474 case TBM_FORMAT_NV21:
475 case TBM_FORMAT_NV16:
476 case TBM_FORMAT_NV61:
479 case TBM_FORMAT_YUV410:
480 case TBM_FORMAT_YVU410:
481 case TBM_FORMAT_YUV411:
482 case TBM_FORMAT_YVU411:
483 case TBM_FORMAT_YUV420:
484 case TBM_FORMAT_YVU420:
485 case TBM_FORMAT_YUV422:
486 case TBM_FORMAT_YVU422:
487 case TBM_FORMAT_YUV444:
488 case TBM_FORMAT_YVU444:
493 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
501 _tbm_surface_internal_get_bpp(tbm_format format)
508 case TBM_FORMAT_RGB332:
509 case TBM_FORMAT_BGR233:
512 case TBM_FORMAT_XRGB4444:
513 case TBM_FORMAT_XBGR4444:
514 case TBM_FORMAT_RGBX4444:
515 case TBM_FORMAT_BGRX4444:
516 case TBM_FORMAT_ARGB4444:
517 case TBM_FORMAT_ABGR4444:
518 case TBM_FORMAT_RGBA4444:
519 case TBM_FORMAT_BGRA4444:
520 case TBM_FORMAT_XRGB1555:
521 case TBM_FORMAT_XBGR1555:
522 case TBM_FORMAT_RGBX5551:
523 case TBM_FORMAT_BGRX5551:
524 case TBM_FORMAT_ARGB1555:
525 case TBM_FORMAT_ABGR1555:
526 case TBM_FORMAT_RGBA5551:
527 case TBM_FORMAT_BGRA5551:
528 case TBM_FORMAT_RGB565:
529 case TBM_FORMAT_BGR565:
532 case TBM_FORMAT_RGB888:
533 case TBM_FORMAT_BGR888:
536 case TBM_FORMAT_XRGB8888:
537 case TBM_FORMAT_XBGR8888:
538 case TBM_FORMAT_RGBX8888:
539 case TBM_FORMAT_BGRX8888:
540 case TBM_FORMAT_ARGB8888:
541 case TBM_FORMAT_ABGR8888:
542 case TBM_FORMAT_RGBA8888:
543 case TBM_FORMAT_BGRA8888:
544 case TBM_FORMAT_XRGB2101010:
545 case TBM_FORMAT_XBGR2101010:
546 case TBM_FORMAT_RGBX1010102:
547 case TBM_FORMAT_BGRX1010102:
548 case TBM_FORMAT_ARGB2101010:
549 case TBM_FORMAT_ABGR2101010:
550 case TBM_FORMAT_RGBA1010102:
551 case TBM_FORMAT_BGRA1010102:
552 case TBM_FORMAT_YUYV:
553 case TBM_FORMAT_YVYU:
554 case TBM_FORMAT_UYVY:
555 case TBM_FORMAT_VYUY:
556 case TBM_FORMAT_AYUV:
559 case TBM_FORMAT_NV12:
560 case TBM_FORMAT_NV12MT:
561 case TBM_FORMAT_NV21:
564 case TBM_FORMAT_NV16:
565 case TBM_FORMAT_NV61:
568 case TBM_FORMAT_YUV410:
569 case TBM_FORMAT_YVU410:
572 case TBM_FORMAT_YUV411:
573 case TBM_FORMAT_YVU411:
574 case TBM_FORMAT_YUV420:
575 case TBM_FORMAT_YVU420:
578 case TBM_FORMAT_YUV422:
579 case TBM_FORMAT_YVU422:
582 case TBM_FORMAT_YUV444:
583 case TBM_FORMAT_YVU444:
587 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
595 tbm_surface_internal_is_valid(tbm_surface_h surface)
599 _tbm_surface_mutex_lock();
600 _tbm_set_last_result(TBM_ERROR_NONE);
602 /* Return silently if surface is null. */
604 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
605 _tbm_surface_mutex_unlock();
609 ret = _tbm_surface_internal_is_valid(surface);
611 _tbm_surface_mutex_unlock();
617 tbm_surface_internal_query_supported_formats(uint32_t **formats,
620 struct _tbm_bufmgr *bufmgr;
622 bool bufmgr_initialized = false;
625 _tbm_surface_mutex_lock();
626 _tbm_set_last_result(TBM_ERROR_NONE);
628 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
629 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
631 if (!g_surface_bufmgr) {
632 _init_surface_bufmgr();
633 if (!g_surface_bufmgr) {
634 TBM_ERR("fail bufmgr initialization\n");
635 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
638 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
639 bufmgr_initialized = true;
642 bufmgr = g_surface_bufmgr;
644 if (bufmgr->use_hal_tbm) {
645 error = (tbm_error_e)hal_tbm_bufmgr_get_supported_formats(bufmgr->hal_bufmgr, formats, num);
646 /* LCOV_EXCL_START */
647 if (error == TBM_ERROR_NOT_SUPPORTED) {
648 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
650 } else if (error != TBM_ERROR_NONE) {
651 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
656 } else if (bufmgr->backend_module_data) {
657 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
658 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
662 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
663 if (error != TBM_ERROR_NONE) {
664 /* LCOV_EXCL_START */
665 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
667 /* LCOV_EXCL_START */
671 if (!bufmgr->backend->surface_supported_format) {
672 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
676 ret = bufmgr->backend->surface_supported_format(formats, num);
678 /* LCOV_EXCL_START */
679 TBM_ERR("Fail to surface_supported_format.\n");
680 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
682 /* LCOV_EXCL_START */
686 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
688 if (bufmgr_initialized) {
689 LIST_DELINIT(&g_surface_bufmgr->surf_list);
690 _deinit_surface_bufmgr();
693 _tbm_surface_mutex_unlock();
697 /* LCOV_EXCL_START */
699 if (bufmgr_initialized) {
700 LIST_DELINIT(&g_surface_bufmgr->surf_list);
701 _deinit_surface_bufmgr();
703 _tbm_surface_mutex_unlock();
705 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
712 tbm_surface_internal_get_num_planes(tbm_format format)
716 _tbm_surface_mutex_lock();
717 _tbm_set_last_result(TBM_ERROR_NONE);
719 num_planes = _tbm_surface_internal_get_num_planes(format);
721 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
722 _tbm_surface_mutex_unlock();
726 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
728 _tbm_surface_mutex_unlock();
734 tbm_surface_internal_get_bpp(tbm_format format)
738 _tbm_surface_mutex_lock();
739 _tbm_set_last_result(TBM_ERROR_NONE);
741 bpp = _tbm_surface_internal_get_bpp(format);
743 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
744 _tbm_surface_mutex_unlock();
748 _tbm_surface_mutex_unlock();
750 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
756 tbm_surface_internal_create_with_flags(int width, int height,
757 int format, int flags)
759 struct _tbm_bufmgr *bufmgr;
760 struct _tbm_surface *surf = NULL;
764 uint32_t bo_size = 0;
767 bool bufmgr_initialized = false;
770 _tbm_surface_mutex_lock();
771 _tbm_set_last_result(TBM_ERROR_NONE);
773 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
774 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
776 if (!g_surface_bufmgr) {
777 _init_surface_bufmgr();
778 if (!g_surface_bufmgr) {
779 TBM_ERR("fail bufmgr initialization\n");
780 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
781 goto check_valid_fail;
783 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
784 bufmgr_initialized = true;
787 bufmgr = g_surface_bufmgr;
788 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
789 TBM_ERR("The bufmgr is invalid\n");
790 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
791 goto check_valid_fail;
794 surf = calloc(1, sizeof(struct _tbm_surface));
796 /* LCOV_EXCL_START */
797 TBM_ERR("fail to alloc surf\n");
798 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
799 goto alloc_surf_fail;
803 surf->magic = TBM_SURFACE_MAGIC;
804 surf->bufmgr = bufmgr;
805 surf->info.width = width;
806 surf->info.height = height;
807 surf->info.format = format;
808 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
809 if (!surf->info.bpp) {
810 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
813 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
814 if (!surf->info.num_planes) {
815 TBM_ERR("fail to get num_planes. error(%s)\n", tbm_error_str(tbm_get_last_error()));
816 goto num_planes_fail;
820 /* get size, stride and offset bo_idx */
821 for (i = 0; i < surf->info.num_planes; i++) {
822 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
823 &offset, &stride, &bo_idx)) {
824 TBM_ERR("fail to query plane data\n");
825 goto query_plane_data_fail;
828 surf->info.planes[i].size = size;
829 surf->info.planes[i].offset = offset;
830 surf->info.planes[i].stride = stride;
831 surf->planes_bo_idx[i] = bo_idx;
836 for (i = 0; i < surf->info.num_planes; i++) {
837 surf->info.size += surf->info.planes[i].size;
839 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
840 surf->num_bos = surf->planes_bo_idx[i] + 1;
845 for (i = 0; i < surf->num_bos; i++) {
847 for (j = 0; j < surf->info.num_planes; j++) {
848 if (surf->planes_bo_idx[j] == i)
849 bo_size += surf->info.planes[j].size;
852 if (bufmgr->use_hal_tbm) {
853 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, &error);
854 if (error == TBM_ERROR_NOT_SUPPORTED) {
855 if (error != TBM_ERROR_NONE) {
856 TBM_ERR("fail to alloc bo idx:%d\n", i);
859 } else if (error != TBM_ERROR_NONE) {
860 TBM_ERR("fail to alloc bo idx:%d\n", i);
863 } else if (bufmgr->backend_module_data) {
864 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
865 /* LCOV_EXCL_START */
866 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, &error);
868 TBM_ERR("fail to tbm_bo_alloc_with_format idx:%d\n", i);
872 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
873 /* LCOV_EXCL_START */
874 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, &error);
876 TBM_ERR("fail to tbm_bo_alloc_with_tiled_format idx:%d\n", i);
881 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
883 TBM_ERR("fail to alloc bo idx:%d\n", i);
888 if (bufmgr->backend->surface_bo_alloc) {
889 /* LCOV_EXCL_START */
890 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
892 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
897 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
899 TBM_ERR("fail to alloc bo idx:%d\n", i);
905 _tbm_bo_set_surface(surf->bos[i], surf);
908 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
909 _tbm_surface_internal_format_to_str(format), flags, surf);
911 LIST_INITHEAD(&surf->user_data_list);
912 LIST_INITHEAD(&surf->debug_data_list);
913 LIST_INITHEAD(&surf->destroy_funcs);
915 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
917 _tbm_surface_mutex_unlock();
921 /* LCOV_EXCL_START */
923 for (j = 0; j < i; j++) {
925 tbm_bo_unref(surf->bos[j]);
927 query_plane_data_fail:
933 if (bufmgr_initialized && bufmgr) {
934 LIST_DELINIT(&bufmgr->surf_list);
935 _deinit_surface_bufmgr();
937 _tbm_surface_mutex_unlock();
939 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
941 _tbm_surface_internal_format_to_str(format), flags);
948 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
949 tbm_bo *bos, int num)
951 struct _tbm_bufmgr *bufmgr;
952 struct _tbm_surface *surf = NULL;
954 bool bufmgr_initialized = false;
956 _tbm_surface_mutex_lock();
957 _tbm_set_last_result(TBM_ERROR_NONE);
959 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
960 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
961 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
962 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
963 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
965 if (!g_surface_bufmgr) {
966 _init_surface_bufmgr();
967 if (!g_surface_bufmgr) {
968 TBM_ERR("fail bufmgr initialization\n");
969 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
970 goto check_valid_fail;
972 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
973 bufmgr_initialized = true;
976 bufmgr = g_surface_bufmgr;
977 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
978 TBM_ERR("fail to validate the Bufmgr.\n");
979 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
980 goto check_valid_fail;
983 surf = calloc(1, sizeof(struct _tbm_surface));
985 /* LCOV_EXCL_START */
986 TBM_ERR("fail to allocate struct _tbm_surface.\n");
987 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
988 goto alloc_surf_fail;
992 surf->magic = TBM_SURFACE_MAGIC;
993 surf->bufmgr = bufmgr;
994 surf->info.width = info->width;
995 surf->info.height = info->height;
996 surf->info.format = info->format;
998 surf->info.bpp = info->bpp;
1000 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1001 if (!surf->info.bpp) {
1002 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1006 surf->info.num_planes = info->num_planes;
1009 /* get size, stride and offset */
1010 for (i = 0; i < info->num_planes; i++) {
1011 surf->info.planes[i].offset = info->planes[i].offset;
1012 surf->info.planes[i].stride = info->planes[i].stride;
1014 if (info->planes[i].size > 0)
1015 surf->info.planes[i].size = info->planes[i].size;
1017 uint32_t size = 0, offset = 0, stride = 0;
1020 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1021 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1022 goto plane_data_fail;
1024 surf->info.planes[i].size = size;
1028 surf->planes_bo_idx[i] = 0;
1030 surf->planes_bo_idx[i] = i;
1033 if (info->size > 0) {
1034 surf->info.size = info->size;
1036 surf->info.size = 0;
1037 for (i = 0; i < info->num_planes; i++)
1038 surf->info.size += surf->info.planes[i].size;
1041 surf->flags = TBM_BO_DEFAULT;
1043 /* create only one bo */
1044 surf->num_bos = num;
1045 for (i = 0; i < num; i++) {
1046 if (bos[i] == NULL) {
1047 TBM_ERR("bos[%d] is null.\n", i);
1048 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1052 surf->bos[i] = tbm_bo_ref(bos[i]);
1053 _tbm_bo_set_surface(bos[i], surf);
1056 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1057 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1059 LIST_INITHEAD(&surf->user_data_list);
1060 LIST_INITHEAD(&surf->debug_data_list);
1061 LIST_INITHEAD(&surf->destroy_funcs);
1063 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1065 _tbm_surface_mutex_unlock();
1069 /* LCOV_EXCL_START */
1073 for (i = 0; i < num; i++) {
1075 tbm_bo_unref(surf->bos[i]);
1080 if (bufmgr_initialized && bufmgr) {
1081 LIST_DELINIT(&bufmgr->surf_list);
1082 _deinit_surface_bufmgr();
1084 _tbm_surface_mutex_unlock();
1086 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1087 info->width, info->height,
1088 _tbm_surface_internal_format_to_str(info->format), num);
1089 /* LCOV_EXCL_STOP */
1095 tbm_surface_internal_destroy(tbm_surface_h surface)
1097 _tbm_surface_mutex_lock();
1098 _tbm_set_last_result(TBM_ERROR_NONE);
1100 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1104 if (surface->refcnt > 0) {
1105 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1106 _tbm_surface_mutex_unlock();
1110 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1112 if (surface->refcnt == 0)
1113 _tbm_surface_internal_destroy(surface);
1115 _tbm_surface_mutex_unlock();
1119 tbm_surface_internal_ref(tbm_surface_h surface)
1121 _tbm_surface_mutex_lock();
1122 _tbm_set_last_result(TBM_ERROR_NONE);
1124 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1128 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1130 _tbm_surface_mutex_unlock();
1134 tbm_surface_internal_unref(tbm_surface_h surface)
1136 _tbm_surface_mutex_lock();
1137 _tbm_set_last_result(TBM_ERROR_NONE);
1139 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1143 if (surface->refcnt > 0) {
1144 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1145 _tbm_surface_mutex_unlock();
1149 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1151 if (surface->refcnt == 0)
1152 _tbm_surface_internal_destroy(surface);
1154 _tbm_surface_mutex_unlock();
1158 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1160 struct _tbm_surface *surf;
1163 _tbm_surface_mutex_lock();
1164 _tbm_set_last_result(TBM_ERROR_NONE);
1166 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1168 surf = (struct _tbm_surface *)surface;
1169 num = surf->num_bos;
1172 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1174 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1176 _tbm_surface_mutex_unlock();
1182 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1184 struct _tbm_surface *surf;
1187 _tbm_surface_mutex_lock();
1188 _tbm_set_last_result(TBM_ERROR_NONE);
1190 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1191 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1193 surf = (struct _tbm_surface *)surface;
1194 bo = surf->bos[bo_idx];
1196 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1198 _tbm_surface_mutex_unlock();
1204 tbm_surface_internal_get_size(tbm_surface_h surface)
1206 struct _tbm_surface *surf;
1209 _tbm_surface_mutex_lock();
1210 _tbm_set_last_result(TBM_ERROR_NONE);
1212 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1214 surf = (struct _tbm_surface *)surface;
1215 size = surf->info.size;
1217 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1219 _tbm_surface_mutex_unlock();
1225 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1226 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1228 struct _tbm_surface *surf;
1230 _tbm_surface_mutex_lock();
1231 _tbm_set_last_result(TBM_ERROR_NONE);
1233 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1234 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1236 surf = (struct _tbm_surface *)surface;
1238 if (plane_idx >= surf->info.num_planes) {
1239 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1240 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1241 _tbm_surface_mutex_unlock();
1246 *size = surf->info.planes[plane_idx].size;
1249 *offset = surf->info.planes[plane_idx].offset;
1252 *pitch = surf->info.planes[plane_idx].stride;
1254 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1255 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1256 surf->info.planes[plane_idx].stride);
1258 _tbm_surface_mutex_unlock();
1264 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1265 tbm_surface_info_s *info, int map)
1267 struct _tbm_surface *surf;
1268 tbm_bo_handle bo_handles[4];
1271 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1274 _tbm_surface_mutex_lock();
1275 _tbm_set_last_result(TBM_ERROR_NONE);
1277 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1279 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1281 surf = (struct _tbm_surface *)surface;
1283 memset(info, 0x00, sizeof(tbm_surface_info_s));
1284 info->width = surf->info.width;
1285 info->height = surf->info.height;
1286 info->format = surf->info.format;
1287 info->bpp = surf->info.bpp;
1288 info->size = surf->info.size;
1289 info->num_planes = surf->info.num_planes;
1291 for (i = 0; i < surf->info.num_planes; i++) {
1292 info->planes[i].size = surf->info.planes[i].size;
1293 info->planes[i].offset = surf->info.planes[i].offset;
1294 info->planes[i].stride = surf->info.planes[i].stride;
1295 planes_bo_idx[i] = surf->planes_bo_idx[i];
1298 for (i = 0; i < surf->num_bos; i++)
1299 bos[i] = surf->bos[i];
1301 num_bos = surf->num_bos;
1304 _tbm_surface_mutex_unlock();
1305 for (i = 0; i < num_bos; i++) {
1306 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1307 if (bo_handles[i].ptr == NULL) {
1308 for (j = 0; j < i; j++)
1309 tbm_bo_unmap(bos[j]);
1311 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1315 _tbm_surface_mutex_lock();
1317 for (i = 0; i < num_bos; i++) {
1318 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1319 if (bo_handles[i].ptr == NULL) {
1320 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1321 _tbm_surface_mutex_unlock();
1327 for (i = 0; i < info->num_planes; i++) {
1328 if (bo_handles[planes_bo_idx[i]].ptr)
1329 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1332 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1334 _tbm_surface_mutex_unlock();
1340 tbm_surface_internal_unmap(tbm_surface_h surface)
1342 struct _tbm_surface *surf;
1345 _tbm_surface_mutex_lock();
1346 _tbm_set_last_result(TBM_ERROR_NONE);
1348 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1350 surf = (struct _tbm_surface *)surface;
1352 for (i = 0; i < surf->num_bos; i++)
1353 tbm_bo_unmap(surf->bos[i]);
1355 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1357 _tbm_surface_mutex_unlock();
1361 tbm_surface_internal_get_width(tbm_surface_h surface)
1363 struct _tbm_surface *surf;
1366 _tbm_surface_mutex_lock();
1367 _tbm_set_last_result(TBM_ERROR_NONE);
1369 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1371 surf = (struct _tbm_surface *)surface;
1372 width = surf->info.width;
1374 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1376 _tbm_surface_mutex_unlock();
1382 tbm_surface_internal_get_height(tbm_surface_h surface)
1384 struct _tbm_surface *surf;
1385 unsigned int height;
1387 _tbm_surface_mutex_lock();
1388 _tbm_set_last_result(TBM_ERROR_NONE);
1390 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1392 surf = (struct _tbm_surface *)surface;
1393 height = surf->info.height;
1395 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1397 _tbm_surface_mutex_unlock();
1404 tbm_surface_internal_get_format(tbm_surface_h surface)
1406 struct _tbm_surface *surf;
1409 _tbm_surface_mutex_lock();
1410 _tbm_set_last_result(TBM_ERROR_NONE);
1412 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1414 surf = (struct _tbm_surface *)surface;
1415 format = surf->info.format;
1417 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1419 _tbm_surface_mutex_unlock();
1425 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1427 struct _tbm_surface *surf;
1430 _tbm_surface_mutex_lock();
1431 _tbm_set_last_result(TBM_ERROR_NONE);
1433 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1434 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1436 surf = (struct _tbm_surface *)surface;
1437 bo_idx = surf->planes_bo_idx[plane_idx];
1439 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1441 _tbm_surface_mutex_unlock();
1447 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1448 tbm_data_free data_free_func)
1450 tbm_user_data *data;
1452 _tbm_surface_mutex_lock();
1453 _tbm_set_last_result(TBM_ERROR_NONE);
1455 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1457 /* check if the data according to the key exist if so, return false. */
1458 data = user_data_lookup(&surface->user_data_list, key);
1460 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1461 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1462 _tbm_surface_mutex_unlock();
1466 data = user_data_create(key, data_free_func);
1468 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1469 _tbm_surface_mutex_unlock();
1473 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1475 LIST_ADD(&data->item_link, &surface->user_data_list);
1477 _tbm_surface_mutex_unlock();
1483 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1486 tbm_user_data *old_data;
1488 _tbm_surface_mutex_lock();
1489 _tbm_set_last_result(TBM_ERROR_NONE);
1491 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1493 old_data = user_data_lookup(&surface->user_data_list, key);
1495 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1496 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1497 _tbm_surface_mutex_unlock();
1501 if (old_data->data && old_data->free_func)
1502 old_data->free_func(old_data->data);
1504 old_data->data = data;
1506 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1508 _tbm_surface_mutex_unlock();
1514 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1517 tbm_user_data *old_data;
1519 _tbm_surface_mutex_lock();
1520 _tbm_set_last_result(TBM_ERROR_NONE);
1522 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1525 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1526 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1527 _tbm_surface_mutex_unlock();
1532 old_data = user_data_lookup(&surface->user_data_list, key);
1534 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1535 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1536 _tbm_surface_mutex_unlock();
1540 *data = old_data->data;
1542 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1544 _tbm_surface_mutex_unlock();
1550 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1553 tbm_user_data *old_data = (void *)0;
1555 _tbm_surface_mutex_lock();
1556 _tbm_set_last_result(TBM_ERROR_NONE);
1558 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1560 old_data = user_data_lookup(&surface->user_data_list, key);
1562 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1563 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1564 _tbm_surface_mutex_unlock();
1568 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1570 user_data_delete(old_data);
1572 _tbm_surface_mutex_unlock();
1577 /* LCOV_EXCL_START */
1579 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1581 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1583 return surface->debug_pid;
1587 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1589 _tbm_surface_mutex_lock();
1590 _tbm_set_last_result(TBM_ERROR_NONE);
1592 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1594 surface->debug_pid = pid;
1596 _tbm_surface_mutex_unlock();
1599 static tbm_surface_debug_data *
1600 _tbm_surface_internal_debug_data_create(char *key, char *value)
1602 tbm_surface_debug_data *debug_data = NULL;
1604 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1606 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1607 TBM_ERR("fail to allocate the debug_data.");
1611 if (key) debug_data->key = strdup(key);
1612 if (value) debug_data->value = strdup(value);
1618 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1620 if (!debug_data->value && !value)
1623 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1626 if (debug_data->value)
1627 free(debug_data->value);
1630 debug_data->value = strdup(value);
1632 debug_data->value = NULL;
1635 static tbm_surface_debug_data *
1636 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1638 tbm_surface_debug_data *debug_data = NULL;
1640 if (LIST_IS_EMPTY(list))
1643 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1644 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1652 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1654 tbm_surface_debug_data *debug_data = NULL;
1655 tbm_bufmgr bufmgr = NULL;
1657 _tbm_surface_mutex_lock();
1658 _tbm_set_last_result(TBM_ERROR_NONE);
1660 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1661 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1663 bufmgr = surface->bufmgr;
1665 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1667 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1669 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1671 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1673 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1674 _tbm_surface_mutex_unlock();
1678 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1681 /* add new debug key to list */
1682 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1684 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1686 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1689 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1691 _tbm_surface_mutex_unlock();
1697 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1699 tbm_surface_debug_data *old_data = NULL;
1701 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1703 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1704 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1705 if (!strcmp(old_data->key, key))
1706 return old_data->value;
1713 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1714 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1716 struct _tbm_surface_dump_buf_info {
1726 tbm_surface_info_s info;
1728 struct list_head link;
1731 struct _tbm_surface_dump_info {
1732 char *path; // copy???
1735 struct list_head *link;
1736 struct list_head surface_list; /* link of surface */
1739 static tbm_surface_dump_info *g_dump_info = NULL;
1740 static const char *dump_postfix[2] = {"png", "yuv"};
1741 static double scale_factor;
1744 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1745 void *data2, int size2, void *data3, int size3)
1748 unsigned int *blocks;
1750 if (_tbm_surface_check_file_is_symbolic_link(file))
1751 TBM_ERR("%s is symbolic link\n", file);
1753 fp = fopen(file, "w+");
1754 TBM_RETURN_IF_FAIL(fp != NULL);
1756 blocks = (unsigned int *)data1;
1757 fwrite(blocks, 1, size1, fp);
1760 blocks = (unsigned int *)data2;
1761 fwrite(blocks, 1, size2, fp);
1765 blocks = (unsigned int *)data3;
1766 fwrite(blocks, 1, size3, fp);
1773 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1775 unsigned int *blocks = (unsigned int *)data;
1778 png_bytep *row_pointers;
1781 if (_tbm_surface_check_file_is_symbolic_link(file))
1782 TBM_ERR("%s is symbolic link\n", file);
1784 fp = fopen(file, "wb");
1785 TBM_RETURN_IF_FAIL(fp != NULL);
1787 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1790 TBM_ERR("fail to create a png write structure.\n");
1795 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1797 TBM_ERR("fail to create a png info structure.\n");
1798 png_destroy_write_struct(&pPngStruct, NULL);
1803 if (setjmp(png_jmpbuf(pPngStruct))) {
1804 /* if png has problem of writing the file, we get here */
1805 TBM_ERR("fail to write png file.\n");
1806 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1811 png_init_io(pPngStruct, fp);
1812 if (format == TBM_FORMAT_XRGB8888) {
1814 png_set_IHDR(pPngStruct,
1821 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1824 png_set_IHDR(pPngStruct,
1829 PNG_COLOR_TYPE_RGBA,
1831 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1834 png_set_bgr(pPngStruct);
1835 png_write_info(pPngStruct, pPngInfo);
1837 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1838 if (!row_pointers) {
1839 TBM_ERR("fail to allocate the png row_pointers.\n");
1840 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1845 for (y = 0; y < height; ++y) {
1849 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1851 TBM_ERR("fail to allocate the png row.\n");
1852 for (x = 0; x < y; x++)
1853 png_free(pPngStruct, row_pointers[x]);
1854 png_free(pPngStruct, row_pointers);
1855 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1859 row_pointers[y] = (png_bytep)row;
1861 for (x = 0; x < width; ++x) {
1862 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1864 if (pixel_size == 3) { // XRGB8888
1865 row[x * pixel_size] = (curBlock & 0xFF);
1866 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1867 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1868 } else { // ARGB8888
1869 row[x * pixel_size] = (curBlock & 0xFF);
1870 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1871 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1872 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1877 png_write_image(pPngStruct, row_pointers);
1878 png_write_end(pPngStruct, pPngInfo);
1880 for (y = 0; y < height; y++)
1881 png_free(pPngStruct, row_pointers[y]);
1882 png_free(pPngStruct, row_pointers);
1884 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1890 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1892 TBM_RETURN_IF_FAIL(path != NULL);
1893 TBM_RETURN_IF_FAIL(w > 0);
1894 TBM_RETURN_IF_FAIL(h > 0);
1895 TBM_RETURN_IF_FAIL(count > 0);
1897 tbm_surface_dump_buf_info *buf_info = NULL;
1898 tbm_surface_h tbm_surface;
1899 tbm_surface_info_s info;
1904 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1908 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1909 TBM_RETURN_IF_FAIL(g_dump_info);
1911 LIST_INITHEAD(&g_dump_info->surface_list);
1912 g_dump_info->count = 0;
1913 g_dump_info->dump_max = count;
1915 /* get buffer size */
1916 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1917 if (tbm_surface == NULL) {
1918 TBM_ERR("tbm_surface_create fail\n");
1924 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1925 TBM_ERR("tbm_surface_get_info fail\n");
1926 tbm_surface_destroy(tbm_surface);
1931 buffer_size = info.size;
1932 tbm_surface_destroy(tbm_surface);
1934 /* create dump lists */
1935 for (i = 0; i < count; i++) {
1938 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1939 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1941 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1943 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1948 buf_info->index = i;
1950 buf_info->size = buffer_size;
1952 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1955 g_dump_info->path = path;
1956 g_dump_info->link = &g_dump_info->surface_list;
1960 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1965 /* free resources */
1966 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1967 tbm_surface_dump_buf_info *tmp;
1969 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1970 tbm_bo_unref(buf_info->bo);
1971 LIST_DEL(&buf_info->link);
1976 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1985 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1992 tbm_surface_internal_dump_start(path, w, h, count);
1993 scale_factor = scale;
1997 tbm_surface_internal_dump_end(void)
1999 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2000 tbm_bo_handle bo_handle;
2005 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2012 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2015 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2016 if (bo_handle.ptr == NULL) {
2017 tbm_bo_unref(buf_info->bo);
2018 LIST_DEL(&buf_info->link);
2023 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2024 TBM_INFO("Dump File.. %s generated.\n", file);
2026 if (buf_info->dirty) {
2027 void *ptr1 = NULL, *ptr2 = NULL;
2029 switch (buf_info->info.format) {
2030 case TBM_FORMAT_ARGB8888:
2031 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2032 buf_info->info.planes[0].stride >> 2,
2033 buf_info->info.height,
2034 buf_info->info.planes[0].stride,
2035 TBM_FORMAT_ARGB8888);
2037 case TBM_FORMAT_XRGB8888:
2038 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2039 buf_info->info.planes[0].stride >> 2,
2040 buf_info->info.height,
2041 buf_info->info.planes[0].stride,
2042 TBM_FORMAT_XRGB8888);
2044 case TBM_FORMAT_YVU420:
2045 case TBM_FORMAT_YUV420:
2046 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2047 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2048 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2049 buf_info->info.planes[0].stride * buf_info->info.height,
2051 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2053 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2055 case TBM_FORMAT_NV12:
2056 case TBM_FORMAT_NV21:
2057 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2058 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2059 buf_info->info.planes[0].stride * buf_info->info.height,
2061 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2064 case TBM_FORMAT_YUYV:
2065 case TBM_FORMAT_UYVY:
2066 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2067 buf_info->info.planes[0].stride * buf_info->info.height,
2071 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2074 } else if (buf_info->dirty_shm)
2075 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2076 buf_info->shm_stride >> 2,
2078 buf_info->shm_stride, 0);
2080 tbm_bo_unmap(buf_info->bo);
2081 tbm_bo_unref(buf_info->bo);
2082 LIST_DEL(&buf_info->link);
2089 TBM_INFO("Dump End..\n");
2092 static pixman_format_code_t
2093 _tbm_surface_internal_pixman_format_get(tbm_format format)
2096 case TBM_FORMAT_ARGB8888:
2097 return PIXMAN_a8r8g8b8;
2098 case TBM_FORMAT_XRGB8888:
2099 return PIXMAN_x8r8g8b8;
2108 * This function supports only if a buffer has below formats.
2109 * - TBM_FORMAT_ARGB8888
2110 * - TBM_FORMAT_XRGB8888
2112 static tbm_surface_error_e
2113 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2114 int format, int src_stride, int src_w, int src_h,
2115 int dst_stride, int dst_w, int dst_h)
2117 pixman_image_t *src_img = NULL, *dst_img = NULL;
2118 pixman_format_code_t pixman_format;
2119 pixman_transform_t t;
2120 struct pixman_f_transform ft;
2121 double scale_x, scale_y;
2123 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2124 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2126 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2127 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2130 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2131 (uint32_t*)src_ptr, src_stride);
2132 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2135 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2136 (uint32_t*)dst_ptr, dst_stride);
2137 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2139 pixman_f_transform_init_identity(&ft);
2141 scale_x = (double)src_w / dst_w;
2142 scale_y = (double)src_h / dst_h;
2144 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2145 pixman_f_transform_translate(&ft, NULL, 0, 0);
2146 pixman_transform_from_pixman_f_transform(&t, &ft);
2147 pixman_image_set_transform(src_img, &t);
2149 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2150 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2152 pixman_image_unref(src_img);
2153 pixman_image_unref(dst_img);
2155 return TBM_SURFACE_ERROR_NONE;
2159 pixman_image_unref(src_img);
2161 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2164 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2165 #define KEY_LEN 5 // "_XXXX"
2166 #define KEYS_LEN KEY_LEN * MAX_BOS
2168 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2170 char *keys, temp_key[KEY_LEN + 1];
2171 struct _tbm_surface *surf;
2175 _tbm_surface_mutex_lock();
2177 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2179 surf = (struct _tbm_surface *)surface;
2181 num_bos = surf->num_bos;
2182 if (num_bos > MAX_BOS)
2185 keys = calloc(KEYS_LEN + 1, sizeof(char));
2187 TBM_ERR("Failed to alloc memory");
2188 _tbm_surface_mutex_unlock();
2192 for (i = 0; i < num_bos; i++) {
2193 memset(temp_key, 0x00, KEY_LEN + 1);
2195 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2196 strncat(keys, temp_key, KEY_LEN + 1);
2199 _tbm_surface_mutex_unlock();
2204 static void _tbm_surface_internal_put_keys(char *keys)
2211 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2213 TBM_RETURN_IF_FAIL(surface != NULL);
2214 TBM_RETURN_IF_FAIL(type != NULL);
2216 tbm_surface_dump_buf_info *buf_info;
2217 struct list_head *next_link;
2218 tbm_surface_info_s info;
2219 tbm_bo_handle bo_handle;
2220 const char *postfix;
2221 const char *format = NULL;
2228 next_link = g_dump_info->link->next;
2229 TBM_RETURN_IF_FAIL(next_link != NULL);
2231 if (next_link == &g_dump_info->surface_list) {
2232 next_link = next_link->next;
2233 TBM_RETURN_IF_FAIL(next_link != NULL);
2236 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2237 TBM_RETURN_IF_FAIL(buf_info != NULL);
2239 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2240 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2242 if (scale_factor > 0.0) {
2245 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2246 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2247 _tbm_surface_internal_format_to_str(info.format));
2248 tbm_surface_unmap(surface);
2252 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2254 buf_info->info.width = info.width * scale_factor;
2255 buf_info->info.height = info.height * scale_factor;
2256 buf_info->info.format = info.format;
2257 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2258 if (!buf_info->info.bpp) {
2259 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2260 tbm_surface_unmap(surface);
2263 buf_info->info.num_planes = 1;
2264 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2265 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2267 if (buf_info->info.size > buf_info->size) {
2268 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2269 buf_info->info.size, buf_info->size);
2270 tbm_surface_unmap(surface);
2274 if (info.size > buf_info->size) {
2275 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2276 info.size, buf_info->size);
2277 tbm_surface_unmap(surface);
2281 /* make the file information */
2282 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2285 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2286 postfix = dump_postfix[0];
2287 format = _tbm_surface_internal_format_to_str(info.format);
2289 postfix = dump_postfix[1];
2291 keys = _tbm_surface_internal_get_keys(surface);
2293 TBM_ERR("fail to get keys");
2294 tbm_surface_unmap(surface);
2299 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2300 if (!bo_handle.ptr) {
2301 TBM_ERR("fail to map bo");
2302 _tbm_surface_internal_put_keys(keys);
2303 tbm_surface_unmap(surface);
2306 memset(bo_handle.ptr, 0x00, buf_info->size);
2308 switch (info.format) {
2309 case TBM_FORMAT_ARGB8888:
2310 case TBM_FORMAT_XRGB8888:
2311 snprintf(buf_info->name, sizeof(buf_info->name),
2312 "%10.3f_%03d%s_%p_%s-%s.%s",
2313 _tbm_surface_internal_get_time(),
2314 g_dump_info->count++, keys, surface, format, type, postfix);
2316 if (scale_factor > 0.0) {
2317 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2319 buf_info->info.format,
2320 info.planes[0].stride,
2321 info.width, info.height,
2322 buf_info->info.planes[0].stride,
2323 buf_info->info.width,
2324 buf_info->info.height);
2325 if (ret != TBM_SURFACE_ERROR_NONE) {
2326 TBM_ERR("fail to scale buffer");
2327 tbm_bo_unmap(buf_info->bo);
2328 _tbm_surface_internal_put_keys(keys);
2329 tbm_surface_unmap(surface);
2333 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2335 case TBM_FORMAT_YVU420:
2336 case TBM_FORMAT_YUV420:
2337 snprintf(buf_info->name, sizeof(buf_info->name),
2338 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2339 _tbm_surface_internal_get_time(),
2340 g_dump_info->count++, keys, type, info.planes[0].stride,
2341 info.height, FOURCC_STR(info.format), postfix);
2342 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2343 bo_handle.ptr += info.planes[0].stride * info.height;
2344 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2345 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2346 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2348 case TBM_FORMAT_NV12:
2349 case TBM_FORMAT_NV21:
2350 snprintf(buf_info->name, sizeof(buf_info->name),
2351 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2352 _tbm_surface_internal_get_time(),
2353 g_dump_info->count++, keys, type, info.planes[0].stride,
2354 info.height, FOURCC_STR(info.format), postfix);
2355 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2356 bo_handle.ptr += info.planes[0].stride * info.height;
2357 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2359 case TBM_FORMAT_YUYV:
2360 case TBM_FORMAT_UYVY:
2361 snprintf(buf_info->name, sizeof(buf_info->name),
2362 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2363 _tbm_surface_internal_get_time(),
2364 g_dump_info->count++, keys, type, info.planes[0].stride,
2365 info.height, FOURCC_STR(info.format), postfix);
2366 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2369 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2370 tbm_bo_unmap(buf_info->bo);
2371 _tbm_surface_internal_put_keys(keys);
2372 tbm_surface_unmap(surface);
2376 tbm_bo_unmap(buf_info->bo);
2378 _tbm_surface_internal_put_keys(keys);
2380 tbm_surface_unmap(surface);
2382 buf_info->dirty = 1;
2383 buf_info->dirty_shm = 0;
2385 if (g_dump_info->count == 1000)
2386 g_dump_info->count = 0;
2388 g_dump_info->link = next_link;
2390 TBM_INFO("Dump %s \n", buf_info->name);
2393 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2396 TBM_RETURN_IF_FAIL(ptr != NULL);
2397 TBM_RETURN_IF_FAIL(w > 0);
2398 TBM_RETURN_IF_FAIL(h > 0);
2399 TBM_RETURN_IF_FAIL(stride > 0);
2400 TBM_RETURN_IF_FAIL(type != NULL);
2402 tbm_surface_dump_buf_info *buf_info;
2403 struct list_head *next_link;
2404 tbm_bo_handle bo_handle;
2405 int ret, size, dw = 0, dh = 0, dstride = 0;
2410 next_link = g_dump_info->link->next;
2411 TBM_RETURN_IF_FAIL(next_link != NULL);
2413 if (next_link == &g_dump_info->surface_list) {
2414 next_link = next_link->next;
2415 TBM_RETURN_IF_FAIL(next_link != NULL);
2418 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2419 TBM_RETURN_IF_FAIL(buf_info != NULL);
2421 if (scale_factor > 0.0) {
2424 dw = w * scale_factor;
2425 dh = h * scale_factor;
2427 size = dstride * dh;
2431 if (size > buf_info->size) {
2432 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2433 size, buf_info->size);
2438 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2439 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2441 memset(bo_handle.ptr, 0x00, buf_info->size);
2442 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2444 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2445 _tbm_surface_internal_get_time(),
2446 g_dump_info->count++, type, dump_postfix[0]);
2447 if (scale_factor > 0.0) {
2448 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2449 TBM_FORMAT_ARGB8888, stride,
2450 w, h, dstride, dw, dh);
2451 if (ret != TBM_SURFACE_ERROR_NONE) {
2452 TBM_ERR("fail to scale buffer");
2453 tbm_bo_unmap(buf_info->bo);
2456 buf_info->shm_stride = dstride;
2457 buf_info->shm_h = dh;
2459 memcpy(bo_handle.ptr, ptr, size);
2460 buf_info->shm_stride = stride;
2461 buf_info->shm_h = h;
2464 tbm_bo_unmap(buf_info->bo);
2466 buf_info->dirty = 0;
2467 buf_info->dirty_shm = 1;
2469 if (g_dump_info->count == 1000)
2470 g_dump_info->count = 0;
2472 g_dump_info->link = next_link;
2474 TBM_INFO("Dump %s \n", buf_info->name);
2478 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2480 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2481 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2482 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2484 tbm_surface_info_s info;
2485 const char *postfix;
2489 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2490 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2492 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2493 postfix = dump_postfix[0];
2495 postfix = dump_postfix[1];
2497 if (strcmp(postfix, type)) {
2498 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2499 tbm_surface_unmap(surface);
2503 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2505 if (!access(file, 0)) {
2506 TBM_ERR("can't capture buffer, exist file %s", file);
2507 tbm_surface_unmap(surface);
2511 switch (info.format) {
2512 case TBM_FORMAT_ARGB8888:
2513 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2516 info.planes[0].stride,
2517 TBM_FORMAT_ARGB8888);
2519 case TBM_FORMAT_XRGB8888:
2520 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2523 info.planes[0].stride,
2524 TBM_FORMAT_XRGB8888);
2526 case TBM_FORMAT_YVU420:
2527 case TBM_FORMAT_YUV420:
2528 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2529 info.planes[0].stride * info.height,
2531 info.planes[1].stride * (info.height >> 1),
2533 info.planes[2].stride * (info.height >> 1));
2535 case TBM_FORMAT_NV12:
2536 case TBM_FORMAT_NV21:
2537 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2538 info.planes[0].stride * info.height,
2540 info.planes[1].stride * (info.height >> 1),
2543 case TBM_FORMAT_YUYV:
2544 case TBM_FORMAT_UYVY:
2545 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2546 info.planes[0].stride * info.height,
2550 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2551 tbm_surface_unmap(surface);
2555 tbm_surface_unmap(surface);
2557 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2563 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2564 const char *path, const char *name, const char *type)
2566 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2567 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2568 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2569 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2570 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2571 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2575 if (strcmp(dump_postfix[0], type)) {
2576 TBM_ERR("Not supported type:%s'", type);
2580 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2582 if (!access(file, 0)) {
2583 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2587 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2589 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2595 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2597 struct _tbm_surface *surf;
2599 _tbm_surface_mutex_lock();
2600 _tbm_set_last_result(TBM_ERROR_NONE);
2602 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2603 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2604 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2606 surf = (struct _tbm_surface *)surface;
2610 surf->damage.width = width;
2611 surf->damage.height = height;
2613 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2614 surface, x, y, width, height);
2616 _tbm_surface_mutex_unlock();
2622 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2624 struct _tbm_surface *surf;
2626 _tbm_surface_mutex_lock();
2627 _tbm_set_last_result(TBM_ERROR_NONE);
2629 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2631 surf = (struct _tbm_surface *)surface;
2633 if (x) *x = surf->damage.x;
2634 if (y) *y = surf->damage.y;
2635 if (width) *width = surf->damage.width;
2636 if (height) *height = surf->damage.height;
2638 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2639 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2641 _tbm_surface_mutex_unlock();
2647 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2649 struct _tbm_surface *surf;
2650 tbm_surface_destroy_func_info *func_info = NULL;
2652 _tbm_surface_mutex_lock();
2653 _tbm_set_last_result(TBM_ERROR_NONE);
2655 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2656 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2658 surf = (struct _tbm_surface *)surface;
2659 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2660 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2661 TBM_ERR("can't add twice");
2662 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2663 _tbm_surface_mutex_unlock();
2668 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2669 if (func_info == NULL) {
2670 TBM_ERR("alloc failed");
2671 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2672 _tbm_surface_mutex_unlock();
2676 func_info->destroy_func = func;
2677 func_info->user_data = user_data;
2679 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2681 _tbm_surface_mutex_unlock();
2687 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2689 struct _tbm_surface *surf;
2690 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2692 _tbm_surface_mutex_lock();
2693 _tbm_set_last_result(TBM_ERROR_NONE);
2695 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2696 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2698 surf = (struct _tbm_surface *)surface;
2699 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2700 if (func_info->destroy_func != func || func_info->user_data != user_data)
2703 LIST_DEL(&func_info->item_link);
2706 _tbm_surface_mutex_unlock();
2711 _tbm_surface_mutex_unlock();