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 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
857 TBM_ERR("fail to alloc bo idx:%d\n", i);
861 } else if (bufmgr->backend_module_data) {
862 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
863 /* LCOV_EXCL_START */
864 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, &error);
866 TBM_ERR("fail to tbm_bo_alloc_with_format idx:%d\n", i);
870 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
871 /* LCOV_EXCL_START */
872 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, &error);
874 TBM_ERR("fail to tbm_bo_alloc_with_tiled_format idx:%d\n", i);
879 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
881 TBM_ERR("fail to alloc bo idx:%d\n", i);
886 if (bufmgr->backend->surface_bo_alloc) {
887 /* LCOV_EXCL_START */
888 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
890 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
895 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
897 TBM_ERR("fail to alloc bo idx:%d\n", i);
903 _tbm_bo_set_surface(surf->bos[i], surf);
906 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
907 _tbm_surface_internal_format_to_str(format), flags, surf);
909 LIST_INITHEAD(&surf->user_data_list);
910 LIST_INITHEAD(&surf->debug_data_list);
911 LIST_INITHEAD(&surf->destroy_funcs);
913 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
915 _tbm_surface_mutex_unlock();
919 /* LCOV_EXCL_START */
921 for (j = 0; j < i; j++) {
923 tbm_bo_unref(surf->bos[j]);
925 query_plane_data_fail:
931 if (bufmgr_initialized && bufmgr) {
932 LIST_DELINIT(&bufmgr->surf_list);
933 _deinit_surface_bufmgr();
935 _tbm_surface_mutex_unlock();
937 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
939 _tbm_surface_internal_format_to_str(format), flags);
946 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
947 tbm_bo *bos, int num)
949 struct _tbm_bufmgr *bufmgr;
950 struct _tbm_surface *surf = NULL;
952 bool bufmgr_initialized = false;
954 _tbm_surface_mutex_lock();
955 _tbm_set_last_result(TBM_ERROR_NONE);
957 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
958 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
959 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
960 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
961 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
963 if (!g_surface_bufmgr) {
964 _init_surface_bufmgr();
965 if (!g_surface_bufmgr) {
966 TBM_ERR("fail bufmgr initialization\n");
967 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
968 goto check_valid_fail;
970 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
971 bufmgr_initialized = true;
974 bufmgr = g_surface_bufmgr;
975 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
976 TBM_ERR("fail to validate the Bufmgr.\n");
977 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
978 goto check_valid_fail;
981 surf = calloc(1, sizeof(struct _tbm_surface));
983 /* LCOV_EXCL_START */
984 TBM_ERR("fail to allocate struct _tbm_surface.\n");
985 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
986 goto alloc_surf_fail;
990 surf->magic = TBM_SURFACE_MAGIC;
991 surf->bufmgr = bufmgr;
992 surf->info.width = info->width;
993 surf->info.height = info->height;
994 surf->info.format = info->format;
996 surf->info.bpp = info->bpp;
998 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
999 if (!surf->info.bpp) {
1000 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1004 surf->info.num_planes = info->num_planes;
1007 /* get size, stride and offset */
1008 for (i = 0; i < info->num_planes; i++) {
1009 surf->info.planes[i].offset = info->planes[i].offset;
1010 surf->info.planes[i].stride = info->planes[i].stride;
1012 if (info->planes[i].size > 0)
1013 surf->info.planes[i].size = info->planes[i].size;
1015 uint32_t size = 0, offset = 0, stride = 0;
1018 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1019 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1020 goto plane_data_fail;
1022 surf->info.planes[i].size = size;
1026 surf->planes_bo_idx[i] = 0;
1028 surf->planes_bo_idx[i] = i;
1031 if (info->size > 0) {
1032 surf->info.size = info->size;
1034 surf->info.size = 0;
1035 for (i = 0; i < info->num_planes; i++)
1036 surf->info.size += surf->info.planes[i].size;
1039 surf->flags = TBM_BO_DEFAULT;
1041 /* create only one bo */
1042 surf->num_bos = num;
1043 for (i = 0; i < num; i++) {
1044 if (bos[i] == NULL) {
1045 TBM_ERR("bos[%d] is null.\n", i);
1046 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1050 surf->bos[i] = tbm_bo_ref(bos[i]);
1051 _tbm_bo_set_surface(bos[i], surf);
1054 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1055 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1057 LIST_INITHEAD(&surf->user_data_list);
1058 LIST_INITHEAD(&surf->debug_data_list);
1059 LIST_INITHEAD(&surf->destroy_funcs);
1061 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1063 _tbm_surface_mutex_unlock();
1067 /* LCOV_EXCL_START */
1071 for (i = 0; i < num; i++) {
1073 tbm_bo_unref(surf->bos[i]);
1078 if (bufmgr_initialized && bufmgr) {
1079 LIST_DELINIT(&bufmgr->surf_list);
1080 _deinit_surface_bufmgr();
1082 _tbm_surface_mutex_unlock();
1084 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1085 info->width, info->height,
1086 _tbm_surface_internal_format_to_str(info->format), num);
1087 /* LCOV_EXCL_STOP */
1093 tbm_surface_internal_destroy(tbm_surface_h surface)
1095 _tbm_surface_mutex_lock();
1096 _tbm_set_last_result(TBM_ERROR_NONE);
1098 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1102 if (surface->refcnt > 0) {
1103 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1104 _tbm_surface_mutex_unlock();
1108 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1110 if (surface->refcnt == 0)
1111 _tbm_surface_internal_destroy(surface);
1113 _tbm_surface_mutex_unlock();
1117 tbm_surface_internal_ref(tbm_surface_h surface)
1119 _tbm_surface_mutex_lock();
1120 _tbm_set_last_result(TBM_ERROR_NONE);
1122 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1126 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1128 _tbm_surface_mutex_unlock();
1132 tbm_surface_internal_unref(tbm_surface_h surface)
1134 _tbm_surface_mutex_lock();
1135 _tbm_set_last_result(TBM_ERROR_NONE);
1137 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1141 if (surface->refcnt > 0) {
1142 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1143 _tbm_surface_mutex_unlock();
1147 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1149 if (surface->refcnt == 0)
1150 _tbm_surface_internal_destroy(surface);
1152 _tbm_surface_mutex_unlock();
1156 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1158 struct _tbm_surface *surf;
1161 _tbm_surface_mutex_lock();
1162 _tbm_set_last_result(TBM_ERROR_NONE);
1164 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1166 surf = (struct _tbm_surface *)surface;
1167 num = surf->num_bos;
1170 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1172 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1174 _tbm_surface_mutex_unlock();
1180 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1182 struct _tbm_surface *surf;
1185 _tbm_surface_mutex_lock();
1186 _tbm_set_last_result(TBM_ERROR_NONE);
1188 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1189 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1191 surf = (struct _tbm_surface *)surface;
1192 bo = surf->bos[bo_idx];
1194 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1196 _tbm_surface_mutex_unlock();
1202 tbm_surface_internal_get_size(tbm_surface_h surface)
1204 struct _tbm_surface *surf;
1207 _tbm_surface_mutex_lock();
1208 _tbm_set_last_result(TBM_ERROR_NONE);
1210 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1212 surf = (struct _tbm_surface *)surface;
1213 size = surf->info.size;
1215 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1217 _tbm_surface_mutex_unlock();
1223 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1224 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1226 struct _tbm_surface *surf;
1228 _tbm_surface_mutex_lock();
1229 _tbm_set_last_result(TBM_ERROR_NONE);
1231 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1232 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1234 surf = (struct _tbm_surface *)surface;
1236 if (plane_idx >= surf->info.num_planes) {
1237 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1238 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1239 _tbm_surface_mutex_unlock();
1244 *size = surf->info.planes[plane_idx].size;
1247 *offset = surf->info.planes[plane_idx].offset;
1250 *pitch = surf->info.planes[plane_idx].stride;
1252 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1253 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1254 surf->info.planes[plane_idx].stride);
1256 _tbm_surface_mutex_unlock();
1262 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1263 tbm_surface_info_s *info, int map)
1265 struct _tbm_surface *surf;
1266 tbm_bo_handle bo_handles[4];
1269 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1272 _tbm_surface_mutex_lock();
1273 _tbm_set_last_result(TBM_ERROR_NONE);
1275 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1277 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1279 surf = (struct _tbm_surface *)surface;
1281 memset(info, 0x00, sizeof(tbm_surface_info_s));
1282 info->width = surf->info.width;
1283 info->height = surf->info.height;
1284 info->format = surf->info.format;
1285 info->bpp = surf->info.bpp;
1286 info->size = surf->info.size;
1287 info->num_planes = surf->info.num_planes;
1289 for (i = 0; i < surf->info.num_planes; i++) {
1290 info->planes[i].size = surf->info.planes[i].size;
1291 info->planes[i].offset = surf->info.planes[i].offset;
1292 info->planes[i].stride = surf->info.planes[i].stride;
1293 planes_bo_idx[i] = surf->planes_bo_idx[i];
1296 for (i = 0; i < surf->num_bos; i++)
1297 bos[i] = surf->bos[i];
1299 num_bos = surf->num_bos;
1302 _tbm_surface_mutex_unlock();
1303 for (i = 0; i < num_bos; i++) {
1304 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1305 if (bo_handles[i].ptr == NULL) {
1306 for (j = 0; j < i; j++)
1307 tbm_bo_unmap(bos[j]);
1309 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1313 _tbm_surface_mutex_lock();
1315 for (i = 0; i < num_bos; i++) {
1316 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1317 if (bo_handles[i].ptr == NULL) {
1318 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1319 _tbm_surface_mutex_unlock();
1325 for (i = 0; i < info->num_planes; i++) {
1326 if (bo_handles[planes_bo_idx[i]].ptr)
1327 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1330 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1332 _tbm_surface_mutex_unlock();
1338 tbm_surface_internal_unmap(tbm_surface_h surface)
1340 struct _tbm_surface *surf;
1343 _tbm_surface_mutex_lock();
1344 _tbm_set_last_result(TBM_ERROR_NONE);
1346 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1348 surf = (struct _tbm_surface *)surface;
1350 for (i = 0; i < surf->num_bos; i++)
1351 tbm_bo_unmap(surf->bos[i]);
1353 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1355 _tbm_surface_mutex_unlock();
1359 tbm_surface_internal_get_width(tbm_surface_h surface)
1361 struct _tbm_surface *surf;
1364 _tbm_surface_mutex_lock();
1365 _tbm_set_last_result(TBM_ERROR_NONE);
1367 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1369 surf = (struct _tbm_surface *)surface;
1370 width = surf->info.width;
1372 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1374 _tbm_surface_mutex_unlock();
1380 tbm_surface_internal_get_height(tbm_surface_h surface)
1382 struct _tbm_surface *surf;
1383 unsigned int height;
1385 _tbm_surface_mutex_lock();
1386 _tbm_set_last_result(TBM_ERROR_NONE);
1388 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1390 surf = (struct _tbm_surface *)surface;
1391 height = surf->info.height;
1393 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1395 _tbm_surface_mutex_unlock();
1402 tbm_surface_internal_get_format(tbm_surface_h surface)
1404 struct _tbm_surface *surf;
1407 _tbm_surface_mutex_lock();
1408 _tbm_set_last_result(TBM_ERROR_NONE);
1410 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1412 surf = (struct _tbm_surface *)surface;
1413 format = surf->info.format;
1415 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1417 _tbm_surface_mutex_unlock();
1423 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1425 struct _tbm_surface *surf;
1428 _tbm_surface_mutex_lock();
1429 _tbm_set_last_result(TBM_ERROR_NONE);
1431 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1432 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1434 surf = (struct _tbm_surface *)surface;
1435 bo_idx = surf->planes_bo_idx[plane_idx];
1437 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1439 _tbm_surface_mutex_unlock();
1445 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1446 tbm_data_free data_free_func)
1448 tbm_user_data *data;
1450 _tbm_surface_mutex_lock();
1451 _tbm_set_last_result(TBM_ERROR_NONE);
1453 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1455 /* check if the data according to the key exist if so, return false. */
1456 data = user_data_lookup(&surface->user_data_list, key);
1458 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1459 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1460 _tbm_surface_mutex_unlock();
1464 data = user_data_create(key, data_free_func);
1466 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1467 _tbm_surface_mutex_unlock();
1471 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1473 LIST_ADD(&data->item_link, &surface->user_data_list);
1475 _tbm_surface_mutex_unlock();
1481 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1484 tbm_user_data *old_data;
1486 _tbm_surface_mutex_lock();
1487 _tbm_set_last_result(TBM_ERROR_NONE);
1489 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1491 old_data = user_data_lookup(&surface->user_data_list, key);
1493 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1494 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1495 _tbm_surface_mutex_unlock();
1499 if (old_data->data && old_data->free_func)
1500 old_data->free_func(old_data->data);
1502 old_data->data = data;
1504 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1506 _tbm_surface_mutex_unlock();
1512 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1515 tbm_user_data *old_data;
1517 _tbm_surface_mutex_lock();
1518 _tbm_set_last_result(TBM_ERROR_NONE);
1520 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1523 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1524 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1525 _tbm_surface_mutex_unlock();
1530 old_data = user_data_lookup(&surface->user_data_list, key);
1532 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1533 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1534 _tbm_surface_mutex_unlock();
1538 *data = old_data->data;
1540 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1542 _tbm_surface_mutex_unlock();
1548 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1551 tbm_user_data *old_data = (void *)0;
1553 _tbm_surface_mutex_lock();
1554 _tbm_set_last_result(TBM_ERROR_NONE);
1556 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1558 old_data = user_data_lookup(&surface->user_data_list, key);
1560 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1561 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1562 _tbm_surface_mutex_unlock();
1566 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1568 user_data_delete(old_data);
1570 _tbm_surface_mutex_unlock();
1575 /* LCOV_EXCL_START */
1577 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1579 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1581 return surface->debug_pid;
1585 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1587 _tbm_surface_mutex_lock();
1588 _tbm_set_last_result(TBM_ERROR_NONE);
1590 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1592 surface->debug_pid = pid;
1594 _tbm_surface_mutex_unlock();
1597 static tbm_surface_debug_data *
1598 _tbm_surface_internal_debug_data_create(char *key, char *value)
1600 tbm_surface_debug_data *debug_data = NULL;
1602 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1604 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1605 TBM_ERR("fail to allocate the debug_data.");
1609 if (key) debug_data->key = strdup(key);
1610 if (value) debug_data->value = strdup(value);
1616 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1618 if (!debug_data->value && !value)
1621 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1624 if (debug_data->value)
1625 free(debug_data->value);
1628 debug_data->value = strdup(value);
1630 debug_data->value = NULL;
1633 static tbm_surface_debug_data *
1634 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1636 tbm_surface_debug_data *debug_data = NULL;
1638 if (LIST_IS_EMPTY(list))
1641 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1642 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1650 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1652 tbm_surface_debug_data *debug_data = NULL;
1653 tbm_bufmgr bufmgr = NULL;
1655 _tbm_surface_mutex_lock();
1656 _tbm_set_last_result(TBM_ERROR_NONE);
1658 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1659 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1661 bufmgr = surface->bufmgr;
1663 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1665 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1667 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1669 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1671 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1672 _tbm_surface_mutex_unlock();
1676 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1679 /* add new debug key to list */
1680 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1682 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1684 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1687 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1689 _tbm_surface_mutex_unlock();
1695 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1697 tbm_surface_debug_data *old_data = NULL;
1699 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1701 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1702 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1703 if (!strcmp(old_data->key, key))
1704 return old_data->value;
1711 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1712 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1714 struct _tbm_surface_dump_buf_info {
1724 tbm_surface_info_s info;
1726 struct list_head link;
1729 struct _tbm_surface_dump_info {
1730 char *path; // copy???
1733 struct list_head *link;
1734 struct list_head surface_list; /* link of surface */
1737 static tbm_surface_dump_info *g_dump_info = NULL;
1738 static const char *dump_postfix[2] = {"png", "yuv"};
1739 static double scale_factor;
1742 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1743 void *data2, int size2, void *data3, int size3)
1746 unsigned int *blocks;
1748 if (_tbm_surface_check_file_is_symbolic_link(file))
1749 TBM_ERR("%s is symbolic link\n", file);
1751 fp = fopen(file, "w+");
1752 TBM_RETURN_IF_FAIL(fp != NULL);
1754 blocks = (unsigned int *)data1;
1755 fwrite(blocks, 1, size1, fp);
1758 blocks = (unsigned int *)data2;
1759 fwrite(blocks, 1, size2, fp);
1763 blocks = (unsigned int *)data3;
1764 fwrite(blocks, 1, size3, fp);
1771 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1773 unsigned int *blocks = (unsigned int *)data;
1776 png_bytep *row_pointers;
1779 if (_tbm_surface_check_file_is_symbolic_link(file))
1780 TBM_ERR("%s is symbolic link\n", file);
1782 fp = fopen(file, "wb");
1783 TBM_RETURN_IF_FAIL(fp != NULL);
1785 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1788 TBM_ERR("fail to create a png write structure.\n");
1793 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1795 TBM_ERR("fail to create a png info structure.\n");
1796 png_destroy_write_struct(&pPngStruct, NULL);
1801 if (setjmp(png_jmpbuf(pPngStruct))) {
1802 /* if png has problem of writing the file, we get here */
1803 TBM_ERR("fail to write png file.\n");
1804 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1809 png_init_io(pPngStruct, fp);
1810 if (format == TBM_FORMAT_XRGB8888) {
1812 png_set_IHDR(pPngStruct,
1819 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1822 png_set_IHDR(pPngStruct,
1827 PNG_COLOR_TYPE_RGBA,
1829 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1832 png_set_bgr(pPngStruct);
1833 png_write_info(pPngStruct, pPngInfo);
1835 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1836 if (!row_pointers) {
1837 TBM_ERR("fail to allocate the png row_pointers.\n");
1838 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1843 for (y = 0; y < height; ++y) {
1847 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1849 TBM_ERR("fail to allocate the png row.\n");
1850 for (x = 0; x < y; x++)
1851 png_free(pPngStruct, row_pointers[x]);
1852 png_free(pPngStruct, row_pointers);
1853 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1857 row_pointers[y] = (png_bytep)row;
1859 for (x = 0; x < width; ++x) {
1860 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1862 if (pixel_size == 3) { // XRGB8888
1863 row[x * pixel_size] = (curBlock & 0xFF);
1864 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1865 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1866 } else { // ARGB8888
1867 row[x * pixel_size] = (curBlock & 0xFF);
1868 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1869 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1870 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1875 png_write_image(pPngStruct, row_pointers);
1876 png_write_end(pPngStruct, pPngInfo);
1878 for (y = 0; y < height; y++)
1879 png_free(pPngStruct, row_pointers[y]);
1880 png_free(pPngStruct, row_pointers);
1882 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1888 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1890 TBM_RETURN_IF_FAIL(path != NULL);
1891 TBM_RETURN_IF_FAIL(w > 0);
1892 TBM_RETURN_IF_FAIL(h > 0);
1893 TBM_RETURN_IF_FAIL(count > 0);
1895 tbm_surface_dump_buf_info *buf_info = NULL;
1896 tbm_surface_h tbm_surface;
1897 tbm_surface_info_s info;
1902 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1906 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1907 TBM_RETURN_IF_FAIL(g_dump_info);
1909 LIST_INITHEAD(&g_dump_info->surface_list);
1910 g_dump_info->count = 0;
1911 g_dump_info->dump_max = count;
1913 /* get buffer size */
1914 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1915 if (tbm_surface == NULL) {
1916 TBM_ERR("tbm_surface_create fail\n");
1922 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1923 TBM_ERR("tbm_surface_get_info fail\n");
1924 tbm_surface_destroy(tbm_surface);
1929 buffer_size = info.size;
1930 tbm_surface_destroy(tbm_surface);
1932 /* create dump lists */
1933 for (i = 0; i < count; i++) {
1936 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1937 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1939 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1941 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1946 buf_info->index = i;
1948 buf_info->size = buffer_size;
1950 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1953 g_dump_info->path = path;
1954 g_dump_info->link = &g_dump_info->surface_list;
1958 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1963 /* free resources */
1964 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1965 tbm_surface_dump_buf_info *tmp;
1967 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1968 tbm_bo_unref(buf_info->bo);
1969 LIST_DEL(&buf_info->link);
1974 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1983 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1990 tbm_surface_internal_dump_start(path, w, h, count);
1991 scale_factor = scale;
1995 tbm_surface_internal_dump_end(void)
1997 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1998 tbm_bo_handle bo_handle;
2003 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2010 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2013 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2014 if (bo_handle.ptr == NULL) {
2015 tbm_bo_unref(buf_info->bo);
2016 LIST_DEL(&buf_info->link);
2021 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2022 TBM_INFO("Dump File.. %s generated.\n", file);
2024 if (buf_info->dirty) {
2025 void *ptr1 = NULL, *ptr2 = NULL;
2027 switch (buf_info->info.format) {
2028 case TBM_FORMAT_ARGB8888:
2029 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2030 buf_info->info.planes[0].stride >> 2,
2031 buf_info->info.height,
2032 buf_info->info.planes[0].stride,
2033 TBM_FORMAT_ARGB8888);
2035 case TBM_FORMAT_XRGB8888:
2036 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2037 buf_info->info.planes[0].stride >> 2,
2038 buf_info->info.height,
2039 buf_info->info.planes[0].stride,
2040 TBM_FORMAT_XRGB8888);
2042 case TBM_FORMAT_YVU420:
2043 case TBM_FORMAT_YUV420:
2044 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2045 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2046 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2047 buf_info->info.planes[0].stride * buf_info->info.height,
2049 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2051 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2053 case TBM_FORMAT_NV12:
2054 case TBM_FORMAT_NV21:
2055 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
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),
2062 case TBM_FORMAT_YUYV:
2063 case TBM_FORMAT_UYVY:
2064 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2065 buf_info->info.planes[0].stride * buf_info->info.height,
2069 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2072 } else if (buf_info->dirty_shm)
2073 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2074 buf_info->shm_stride >> 2,
2076 buf_info->shm_stride, 0);
2078 tbm_bo_unmap(buf_info->bo);
2079 tbm_bo_unref(buf_info->bo);
2080 LIST_DEL(&buf_info->link);
2087 TBM_INFO("Dump End..\n");
2090 static pixman_format_code_t
2091 _tbm_surface_internal_pixman_format_get(tbm_format format)
2094 case TBM_FORMAT_ARGB8888:
2095 return PIXMAN_a8r8g8b8;
2096 case TBM_FORMAT_XRGB8888:
2097 return PIXMAN_x8r8g8b8;
2106 * This function supports only if a buffer has below formats.
2107 * - TBM_FORMAT_ARGB8888
2108 * - TBM_FORMAT_XRGB8888
2110 static tbm_surface_error_e
2111 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2112 int format, int src_stride, int src_w, int src_h,
2113 int dst_stride, int dst_w, int dst_h)
2115 pixman_image_t *src_img = NULL, *dst_img = NULL;
2116 pixman_format_code_t pixman_format;
2117 pixman_transform_t t;
2118 struct pixman_f_transform ft;
2119 double scale_x, scale_y;
2121 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2122 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2124 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2125 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2128 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2129 (uint32_t*)src_ptr, src_stride);
2130 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2133 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2134 (uint32_t*)dst_ptr, dst_stride);
2135 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2137 pixman_f_transform_init_identity(&ft);
2139 scale_x = (double)src_w / dst_w;
2140 scale_y = (double)src_h / dst_h;
2142 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2143 pixman_f_transform_translate(&ft, NULL, 0, 0);
2144 pixman_transform_from_pixman_f_transform(&t, &ft);
2145 pixman_image_set_transform(src_img, &t);
2147 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2148 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2150 pixman_image_unref(src_img);
2151 pixman_image_unref(dst_img);
2153 return TBM_SURFACE_ERROR_NONE;
2157 pixman_image_unref(src_img);
2159 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2162 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2163 #define KEY_LEN 5 // "_XXXX"
2164 #define KEYS_LEN KEY_LEN * MAX_BOS
2166 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2168 char *keys, temp_key[KEY_LEN + 1];
2169 struct _tbm_surface *surf;
2173 _tbm_surface_mutex_lock();
2175 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2177 surf = (struct _tbm_surface *)surface;
2179 num_bos = surf->num_bos;
2180 if (num_bos > MAX_BOS)
2183 keys = calloc(KEYS_LEN + 1, sizeof(char));
2185 TBM_ERR("Failed to alloc memory");
2186 _tbm_surface_mutex_unlock();
2190 for (i = 0; i < num_bos; i++) {
2191 memset(temp_key, 0x00, KEY_LEN + 1);
2193 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2194 strncat(keys, temp_key, KEY_LEN + 1);
2197 _tbm_surface_mutex_unlock();
2202 static void _tbm_surface_internal_put_keys(char *keys)
2209 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2211 TBM_RETURN_IF_FAIL(surface != NULL);
2212 TBM_RETURN_IF_FAIL(type != NULL);
2214 tbm_surface_dump_buf_info *buf_info;
2215 struct list_head *next_link;
2216 tbm_surface_info_s info;
2217 tbm_bo_handle bo_handle;
2218 const char *postfix;
2219 const char *format = NULL;
2226 next_link = g_dump_info->link->next;
2227 TBM_RETURN_IF_FAIL(next_link != NULL);
2229 if (next_link == &g_dump_info->surface_list) {
2230 next_link = next_link->next;
2231 TBM_RETURN_IF_FAIL(next_link != NULL);
2234 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2235 TBM_RETURN_IF_FAIL(buf_info != NULL);
2237 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2238 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2240 if (scale_factor > 0.0) {
2243 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2244 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2245 _tbm_surface_internal_format_to_str(info.format));
2246 tbm_surface_unmap(surface);
2250 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2252 buf_info->info.width = info.width * scale_factor;
2253 buf_info->info.height = info.height * scale_factor;
2254 buf_info->info.format = info.format;
2255 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2256 if (!buf_info->info.bpp) {
2257 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2258 tbm_surface_unmap(surface);
2261 buf_info->info.num_planes = 1;
2262 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2263 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2265 if (buf_info->info.size > buf_info->size) {
2266 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2267 buf_info->info.size, buf_info->size);
2268 tbm_surface_unmap(surface);
2272 if (info.size > buf_info->size) {
2273 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2274 info.size, buf_info->size);
2275 tbm_surface_unmap(surface);
2279 /* make the file information */
2280 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2283 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2284 postfix = dump_postfix[0];
2285 format = _tbm_surface_internal_format_to_str(info.format);
2287 postfix = dump_postfix[1];
2289 keys = _tbm_surface_internal_get_keys(surface);
2291 TBM_ERR("fail to get keys");
2292 tbm_surface_unmap(surface);
2297 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2298 if (!bo_handle.ptr) {
2299 TBM_ERR("fail to map bo");
2300 _tbm_surface_internal_put_keys(keys);
2301 tbm_surface_unmap(surface);
2304 memset(bo_handle.ptr, 0x00, buf_info->size);
2306 switch (info.format) {
2307 case TBM_FORMAT_ARGB8888:
2308 case TBM_FORMAT_XRGB8888:
2309 snprintf(buf_info->name, sizeof(buf_info->name),
2310 "%10.3f_%03d%s_%p_%s-%s.%s",
2311 _tbm_surface_internal_get_time(),
2312 g_dump_info->count++, keys, surface, format, type, postfix);
2314 if (scale_factor > 0.0) {
2315 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2317 buf_info->info.format,
2318 info.planes[0].stride,
2319 info.width, info.height,
2320 buf_info->info.planes[0].stride,
2321 buf_info->info.width,
2322 buf_info->info.height);
2323 if (ret != TBM_SURFACE_ERROR_NONE) {
2324 TBM_ERR("fail to scale buffer");
2325 tbm_bo_unmap(buf_info->bo);
2326 _tbm_surface_internal_put_keys(keys);
2327 tbm_surface_unmap(surface);
2331 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2333 case TBM_FORMAT_YVU420:
2334 case TBM_FORMAT_YUV420:
2335 snprintf(buf_info->name, sizeof(buf_info->name),
2336 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2337 _tbm_surface_internal_get_time(),
2338 g_dump_info->count++, keys, type, info.planes[0].stride,
2339 info.height, FOURCC_STR(info.format), postfix);
2340 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2341 bo_handle.ptr += info.planes[0].stride * info.height;
2342 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2343 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2344 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2346 case TBM_FORMAT_NV12:
2347 case TBM_FORMAT_NV21:
2348 snprintf(buf_info->name, sizeof(buf_info->name),
2349 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2350 _tbm_surface_internal_get_time(),
2351 g_dump_info->count++, keys, type, info.planes[0].stride,
2352 info.height, FOURCC_STR(info.format), postfix);
2353 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2354 bo_handle.ptr += info.planes[0].stride * info.height;
2355 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2357 case TBM_FORMAT_YUYV:
2358 case TBM_FORMAT_UYVY:
2359 snprintf(buf_info->name, sizeof(buf_info->name),
2360 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2361 _tbm_surface_internal_get_time(),
2362 g_dump_info->count++, keys, type, info.planes[0].stride,
2363 info.height, FOURCC_STR(info.format), postfix);
2364 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2367 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2368 tbm_bo_unmap(buf_info->bo);
2369 _tbm_surface_internal_put_keys(keys);
2370 tbm_surface_unmap(surface);
2374 tbm_bo_unmap(buf_info->bo);
2376 _tbm_surface_internal_put_keys(keys);
2378 tbm_surface_unmap(surface);
2380 buf_info->dirty = 1;
2381 buf_info->dirty_shm = 0;
2383 if (g_dump_info->count == 1000)
2384 g_dump_info->count = 0;
2386 g_dump_info->link = next_link;
2388 TBM_INFO("Dump %s \n", buf_info->name);
2391 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2394 TBM_RETURN_IF_FAIL(ptr != NULL);
2395 TBM_RETURN_IF_FAIL(w > 0);
2396 TBM_RETURN_IF_FAIL(h > 0);
2397 TBM_RETURN_IF_FAIL(stride > 0);
2398 TBM_RETURN_IF_FAIL(type != NULL);
2400 tbm_surface_dump_buf_info *buf_info;
2401 struct list_head *next_link;
2402 tbm_bo_handle bo_handle;
2403 int ret, size, dw = 0, dh = 0, dstride = 0;
2408 next_link = g_dump_info->link->next;
2409 TBM_RETURN_IF_FAIL(next_link != NULL);
2411 if (next_link == &g_dump_info->surface_list) {
2412 next_link = next_link->next;
2413 TBM_RETURN_IF_FAIL(next_link != NULL);
2416 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2417 TBM_RETURN_IF_FAIL(buf_info != NULL);
2419 if (scale_factor > 0.0) {
2422 dw = w * scale_factor;
2423 dh = h * scale_factor;
2425 size = dstride * dh;
2429 if (size > buf_info->size) {
2430 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2431 size, buf_info->size);
2436 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2437 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2439 memset(bo_handle.ptr, 0x00, buf_info->size);
2440 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2442 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2443 _tbm_surface_internal_get_time(),
2444 g_dump_info->count++, type, dump_postfix[0]);
2445 if (scale_factor > 0.0) {
2446 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2447 TBM_FORMAT_ARGB8888, stride,
2448 w, h, dstride, dw, dh);
2449 if (ret != TBM_SURFACE_ERROR_NONE) {
2450 TBM_ERR("fail to scale buffer");
2451 tbm_bo_unmap(buf_info->bo);
2454 buf_info->shm_stride = dstride;
2455 buf_info->shm_h = dh;
2457 memcpy(bo_handle.ptr, ptr, size);
2458 buf_info->shm_stride = stride;
2459 buf_info->shm_h = h;
2462 tbm_bo_unmap(buf_info->bo);
2464 buf_info->dirty = 0;
2465 buf_info->dirty_shm = 1;
2467 if (g_dump_info->count == 1000)
2468 g_dump_info->count = 0;
2470 g_dump_info->link = next_link;
2472 TBM_INFO("Dump %s \n", buf_info->name);
2476 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2478 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2479 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2480 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2482 tbm_surface_info_s info;
2483 const char *postfix;
2487 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2488 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2490 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2491 postfix = dump_postfix[0];
2493 postfix = dump_postfix[1];
2495 if (strcmp(postfix, type)) {
2496 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2497 tbm_surface_unmap(surface);
2501 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2503 if (!access(file, 0)) {
2504 TBM_ERR("can't capture buffer, exist file %s", file);
2505 tbm_surface_unmap(surface);
2509 switch (info.format) {
2510 case TBM_FORMAT_ARGB8888:
2511 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2514 info.planes[0].stride,
2515 TBM_FORMAT_ARGB8888);
2517 case TBM_FORMAT_XRGB8888:
2518 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2521 info.planes[0].stride,
2522 TBM_FORMAT_XRGB8888);
2524 case TBM_FORMAT_YVU420:
2525 case TBM_FORMAT_YUV420:
2526 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2527 info.planes[0].stride * info.height,
2529 info.planes[1].stride * (info.height >> 1),
2531 info.planes[2].stride * (info.height >> 1));
2533 case TBM_FORMAT_NV12:
2534 case TBM_FORMAT_NV21:
2535 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2536 info.planes[0].stride * info.height,
2538 info.planes[1].stride * (info.height >> 1),
2541 case TBM_FORMAT_YUYV:
2542 case TBM_FORMAT_UYVY:
2543 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2544 info.planes[0].stride * info.height,
2548 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2549 tbm_surface_unmap(surface);
2553 tbm_surface_unmap(surface);
2555 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2561 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2562 const char *path, const char *name, const char *type)
2564 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2565 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2566 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2567 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2568 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2569 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2573 if (strcmp(dump_postfix[0], type)) {
2574 TBM_ERR("Not supported type:%s'", type);
2578 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2580 if (!access(file, 0)) {
2581 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2585 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2587 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2593 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2595 struct _tbm_surface *surf;
2597 _tbm_surface_mutex_lock();
2598 _tbm_set_last_result(TBM_ERROR_NONE);
2600 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2601 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2602 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2604 surf = (struct _tbm_surface *)surface;
2608 surf->damage.width = width;
2609 surf->damage.height = height;
2611 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2612 surface, x, y, width, height);
2614 _tbm_surface_mutex_unlock();
2620 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2622 struct _tbm_surface *surf;
2624 _tbm_surface_mutex_lock();
2625 _tbm_set_last_result(TBM_ERROR_NONE);
2627 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2629 surf = (struct _tbm_surface *)surface;
2631 if (x) *x = surf->damage.x;
2632 if (y) *y = surf->damage.y;
2633 if (width) *width = surf->damage.width;
2634 if (height) *height = surf->damage.height;
2636 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2637 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2639 _tbm_surface_mutex_unlock();
2645 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2647 struct _tbm_surface *surf;
2648 tbm_surface_destroy_func_info *func_info = NULL;
2650 _tbm_surface_mutex_lock();
2651 _tbm_set_last_result(TBM_ERROR_NONE);
2653 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2654 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2656 surf = (struct _tbm_surface *)surface;
2657 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2658 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2659 TBM_ERR("can't add twice");
2660 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2661 _tbm_surface_mutex_unlock();
2666 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2667 if (func_info == NULL) {
2668 TBM_ERR("alloc failed");
2669 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2670 _tbm_surface_mutex_unlock();
2674 func_info->destroy_func = func;
2675 func_info->user_data = user_data;
2677 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2679 _tbm_surface_mutex_unlock();
2685 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2687 struct _tbm_surface *surf;
2688 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2690 _tbm_surface_mutex_lock();
2691 _tbm_set_last_result(TBM_ERROR_NONE);
2693 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2694 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2696 surf = (struct _tbm_surface *)surface;
2697 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2698 if (func_info->destroy_func != func || func_info->user_data != user_data)
2701 LIST_DEL(&func_info->item_link);
2704 _tbm_surface_mutex_unlock();
2709 _tbm_surface_mutex_unlock();