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, flags, &error);
854 if (error == TBM_ERROR_NOT_SUPPORTED) {
855 if (flags & TBM_BO_TILED) {
856 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, &error);
857 if (error == TBM_ERROR_NOT_SUPPORTED) {
858 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
859 } else if (error != TBM_ERROR_NONE) {
860 TBM_ERR("fail to alloc bo idx:%d\n", i);
864 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
868 TBM_ERR("fail to alloc bo idx:%d\n", i);
871 } else if (error != TBM_ERROR_NONE) {
872 TBM_ERR("fail to alloc bo idx:%d\n", i);
875 } else if (bufmgr->backend_module_data) {
876 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
877 /* LCOV_EXCL_START */
878 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, flags, &error);
880 TBM_ERR("fail to tbm_bo_alloc_with_format idx:%d\n", i);
884 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
885 /* LCOV_EXCL_START */
886 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, &error);
888 TBM_ERR("fail to tbm_bo_alloc_with_tiled_format idx:%d\n", i);
893 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
895 TBM_ERR("fail to alloc bo idx:%d\n", i);
900 if (bufmgr->backend->surface_bo_alloc) {
901 /* LCOV_EXCL_START */
902 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
904 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
909 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
911 TBM_ERR("fail to alloc bo idx:%d\n", i);
917 _tbm_bo_set_surface(surf->bos[i], surf);
920 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
921 _tbm_surface_internal_format_to_str(format), flags, surf);
923 LIST_INITHEAD(&surf->user_data_list);
924 LIST_INITHEAD(&surf->debug_data_list);
925 LIST_INITHEAD(&surf->destroy_funcs);
927 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
929 _tbm_surface_mutex_unlock();
933 /* LCOV_EXCL_START */
935 for (j = 0; j < i; j++) {
937 tbm_bo_unref(surf->bos[j]);
939 query_plane_data_fail:
945 if (bufmgr_initialized && bufmgr) {
946 LIST_DELINIT(&bufmgr->surf_list);
947 _deinit_surface_bufmgr();
949 _tbm_surface_mutex_unlock();
951 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
953 _tbm_surface_internal_format_to_str(format), flags);
960 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
961 tbm_bo *bos, int num)
963 struct _tbm_bufmgr *bufmgr;
964 struct _tbm_surface *surf = NULL;
966 bool bufmgr_initialized = false;
968 _tbm_surface_mutex_lock();
969 _tbm_set_last_result(TBM_ERROR_NONE);
971 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
972 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
973 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
974 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
975 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
977 if (!g_surface_bufmgr) {
978 _init_surface_bufmgr();
979 if (!g_surface_bufmgr) {
980 TBM_ERR("fail bufmgr initialization\n");
981 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
982 goto check_valid_fail;
984 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
985 bufmgr_initialized = true;
988 bufmgr = g_surface_bufmgr;
989 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
990 TBM_ERR("fail to validate the Bufmgr.\n");
991 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
992 goto check_valid_fail;
995 surf = calloc(1, sizeof(struct _tbm_surface));
997 /* LCOV_EXCL_START */
998 TBM_ERR("fail to allocate struct _tbm_surface.\n");
999 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1000 goto alloc_surf_fail;
1001 /* LCOV_EXCL_STOP */
1004 surf->magic = TBM_SURFACE_MAGIC;
1005 surf->bufmgr = bufmgr;
1006 surf->info.width = info->width;
1007 surf->info.height = info->height;
1008 surf->info.format = info->format;
1010 surf->info.bpp = info->bpp;
1012 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1013 if (!surf->info.bpp) {
1014 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1018 surf->info.num_planes = info->num_planes;
1021 /* get size, stride and offset */
1022 for (i = 0; i < info->num_planes; i++) {
1023 surf->info.planes[i].offset = info->planes[i].offset;
1024 surf->info.planes[i].stride = info->planes[i].stride;
1026 if (info->planes[i].size > 0)
1027 surf->info.planes[i].size = info->planes[i].size;
1029 uint32_t size = 0, offset = 0, stride = 0;
1032 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1033 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1034 goto plane_data_fail;
1036 surf->info.planes[i].size = size;
1040 surf->planes_bo_idx[i] = 0;
1042 surf->planes_bo_idx[i] = i;
1045 if (info->size > 0) {
1046 surf->info.size = info->size;
1048 surf->info.size = 0;
1049 for (i = 0; i < info->num_planes; i++)
1050 surf->info.size += surf->info.planes[i].size;
1053 surf->flags = TBM_BO_DEFAULT;
1055 /* create only one bo */
1056 surf->num_bos = num;
1057 for (i = 0; i < num; i++) {
1058 if (bos[i] == NULL) {
1059 TBM_ERR("bos[%d] is null.\n", i);
1060 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1064 surf->bos[i] = tbm_bo_ref(bos[i]);
1065 _tbm_bo_set_surface(bos[i], surf);
1068 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1069 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1071 LIST_INITHEAD(&surf->user_data_list);
1072 LIST_INITHEAD(&surf->debug_data_list);
1073 LIST_INITHEAD(&surf->destroy_funcs);
1075 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1077 _tbm_surface_mutex_unlock();
1081 /* LCOV_EXCL_START */
1085 for (i = 0; i < num; i++) {
1087 tbm_bo_unref(surf->bos[i]);
1092 if (bufmgr_initialized && bufmgr) {
1093 LIST_DELINIT(&bufmgr->surf_list);
1094 _deinit_surface_bufmgr();
1096 _tbm_surface_mutex_unlock();
1098 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1099 info->width, info->height,
1100 _tbm_surface_internal_format_to_str(info->format), num);
1101 /* LCOV_EXCL_STOP */
1107 tbm_surface_internal_destroy(tbm_surface_h surface)
1109 _tbm_surface_mutex_lock();
1110 _tbm_set_last_result(TBM_ERROR_NONE);
1112 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1116 if (surface->refcnt > 0) {
1117 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1118 _tbm_surface_mutex_unlock();
1122 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1124 if (surface->refcnt == 0)
1125 _tbm_surface_internal_destroy(surface);
1127 _tbm_surface_mutex_unlock();
1131 tbm_surface_internal_ref(tbm_surface_h surface)
1133 _tbm_surface_mutex_lock();
1134 _tbm_set_last_result(TBM_ERROR_NONE);
1136 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1140 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1142 _tbm_surface_mutex_unlock();
1146 tbm_surface_internal_unref(tbm_surface_h surface)
1148 _tbm_surface_mutex_lock();
1149 _tbm_set_last_result(TBM_ERROR_NONE);
1151 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1155 if (surface->refcnt > 0) {
1156 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1157 _tbm_surface_mutex_unlock();
1161 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1163 if (surface->refcnt == 0)
1164 _tbm_surface_internal_destroy(surface);
1166 _tbm_surface_mutex_unlock();
1170 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1172 struct _tbm_surface *surf;
1175 _tbm_surface_mutex_lock();
1176 _tbm_set_last_result(TBM_ERROR_NONE);
1178 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1180 surf = (struct _tbm_surface *)surface;
1181 num = surf->num_bos;
1184 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1186 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1188 _tbm_surface_mutex_unlock();
1194 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1196 struct _tbm_surface *surf;
1199 _tbm_surface_mutex_lock();
1200 _tbm_set_last_result(TBM_ERROR_NONE);
1202 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1203 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1205 surf = (struct _tbm_surface *)surface;
1206 bo = surf->bos[bo_idx];
1208 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1210 _tbm_surface_mutex_unlock();
1216 tbm_surface_internal_get_size(tbm_surface_h surface)
1218 struct _tbm_surface *surf;
1221 _tbm_surface_mutex_lock();
1222 _tbm_set_last_result(TBM_ERROR_NONE);
1224 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1226 surf = (struct _tbm_surface *)surface;
1227 size = surf->info.size;
1229 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1231 _tbm_surface_mutex_unlock();
1237 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1238 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1240 struct _tbm_surface *surf;
1242 _tbm_surface_mutex_lock();
1243 _tbm_set_last_result(TBM_ERROR_NONE);
1245 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1246 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1248 surf = (struct _tbm_surface *)surface;
1250 if (plane_idx >= surf->info.num_planes) {
1251 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1252 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1253 _tbm_surface_mutex_unlock();
1258 *size = surf->info.planes[plane_idx].size;
1261 *offset = surf->info.planes[plane_idx].offset;
1264 *pitch = surf->info.planes[plane_idx].stride;
1266 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1267 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1268 surf->info.planes[plane_idx].stride);
1270 _tbm_surface_mutex_unlock();
1276 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1277 tbm_surface_info_s *info, int map)
1279 struct _tbm_surface *surf;
1280 tbm_bo_handle bo_handles[4];
1283 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1286 _tbm_surface_mutex_lock();
1287 _tbm_set_last_result(TBM_ERROR_NONE);
1289 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1291 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1293 surf = (struct _tbm_surface *)surface;
1295 memset(info, 0x00, sizeof(tbm_surface_info_s));
1296 info->width = surf->info.width;
1297 info->height = surf->info.height;
1298 info->format = surf->info.format;
1299 info->bpp = surf->info.bpp;
1300 info->size = surf->info.size;
1301 info->num_planes = surf->info.num_planes;
1303 for (i = 0; i < surf->info.num_planes; i++) {
1304 info->planes[i].size = surf->info.planes[i].size;
1305 info->planes[i].offset = surf->info.planes[i].offset;
1306 info->planes[i].stride = surf->info.planes[i].stride;
1307 planes_bo_idx[i] = surf->planes_bo_idx[i];
1310 for (i = 0; i < surf->num_bos; i++)
1311 bos[i] = surf->bos[i];
1313 num_bos = surf->num_bos;
1316 _tbm_surface_mutex_unlock();
1317 for (i = 0; i < num_bos; i++) {
1318 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1319 if (bo_handles[i].ptr == NULL) {
1320 for (j = 0; j < i; j++)
1321 tbm_bo_unmap(bos[j]);
1323 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1327 _tbm_surface_mutex_lock();
1329 for (i = 0; i < num_bos; i++) {
1330 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1331 if (bo_handles[i].ptr == NULL) {
1332 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1333 _tbm_surface_mutex_unlock();
1339 for (i = 0; i < info->num_planes; i++) {
1340 if (bo_handles[planes_bo_idx[i]].ptr)
1341 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1344 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1346 _tbm_surface_mutex_unlock();
1352 tbm_surface_internal_unmap(tbm_surface_h surface)
1354 struct _tbm_surface *surf;
1357 _tbm_surface_mutex_lock();
1358 _tbm_set_last_result(TBM_ERROR_NONE);
1360 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1362 surf = (struct _tbm_surface *)surface;
1364 for (i = 0; i < surf->num_bos; i++)
1365 tbm_bo_unmap(surf->bos[i]);
1367 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1369 _tbm_surface_mutex_unlock();
1373 tbm_surface_internal_get_width(tbm_surface_h surface)
1375 struct _tbm_surface *surf;
1378 _tbm_surface_mutex_lock();
1379 _tbm_set_last_result(TBM_ERROR_NONE);
1381 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1383 surf = (struct _tbm_surface *)surface;
1384 width = surf->info.width;
1386 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1388 _tbm_surface_mutex_unlock();
1394 tbm_surface_internal_get_height(tbm_surface_h surface)
1396 struct _tbm_surface *surf;
1397 unsigned int height;
1399 _tbm_surface_mutex_lock();
1400 _tbm_set_last_result(TBM_ERROR_NONE);
1402 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1404 surf = (struct _tbm_surface *)surface;
1405 height = surf->info.height;
1407 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1409 _tbm_surface_mutex_unlock();
1416 tbm_surface_internal_get_format(tbm_surface_h surface)
1418 struct _tbm_surface *surf;
1421 _tbm_surface_mutex_lock();
1422 _tbm_set_last_result(TBM_ERROR_NONE);
1424 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1426 surf = (struct _tbm_surface *)surface;
1427 format = surf->info.format;
1429 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1431 _tbm_surface_mutex_unlock();
1437 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1439 struct _tbm_surface *surf;
1442 _tbm_surface_mutex_lock();
1443 _tbm_set_last_result(TBM_ERROR_NONE);
1445 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1446 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1448 surf = (struct _tbm_surface *)surface;
1449 bo_idx = surf->planes_bo_idx[plane_idx];
1451 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1453 _tbm_surface_mutex_unlock();
1459 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1460 tbm_data_free data_free_func)
1462 tbm_user_data *data;
1464 _tbm_surface_mutex_lock();
1465 _tbm_set_last_result(TBM_ERROR_NONE);
1467 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1469 /* check if the data according to the key exist if so, return false. */
1470 data = user_data_lookup(&surface->user_data_list, key);
1472 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1473 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1474 _tbm_surface_mutex_unlock();
1478 data = user_data_create(key, data_free_func);
1480 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1481 _tbm_surface_mutex_unlock();
1485 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1487 LIST_ADD(&data->item_link, &surface->user_data_list);
1489 _tbm_surface_mutex_unlock();
1495 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1498 tbm_user_data *old_data;
1500 _tbm_surface_mutex_lock();
1501 _tbm_set_last_result(TBM_ERROR_NONE);
1503 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1505 old_data = user_data_lookup(&surface->user_data_list, key);
1507 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1508 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1509 _tbm_surface_mutex_unlock();
1513 if (old_data->data && old_data->free_func)
1514 old_data->free_func(old_data->data);
1516 old_data->data = data;
1518 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1520 _tbm_surface_mutex_unlock();
1526 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1529 tbm_user_data *old_data;
1531 _tbm_surface_mutex_lock();
1532 _tbm_set_last_result(TBM_ERROR_NONE);
1534 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1537 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1538 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1539 _tbm_surface_mutex_unlock();
1544 old_data = user_data_lookup(&surface->user_data_list, key);
1546 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1547 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1548 _tbm_surface_mutex_unlock();
1552 *data = old_data->data;
1554 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1556 _tbm_surface_mutex_unlock();
1562 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1565 tbm_user_data *old_data = (void *)0;
1567 _tbm_surface_mutex_lock();
1568 _tbm_set_last_result(TBM_ERROR_NONE);
1570 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1572 old_data = user_data_lookup(&surface->user_data_list, key);
1574 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1575 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1576 _tbm_surface_mutex_unlock();
1580 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1582 user_data_delete(old_data);
1584 _tbm_surface_mutex_unlock();
1589 /* LCOV_EXCL_START */
1591 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1593 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1595 return surface->debug_pid;
1599 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1601 _tbm_surface_mutex_lock();
1602 _tbm_set_last_result(TBM_ERROR_NONE);
1604 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1606 surface->debug_pid = pid;
1608 _tbm_surface_mutex_unlock();
1611 static tbm_surface_debug_data *
1612 _tbm_surface_internal_debug_data_create(char *key, char *value)
1614 tbm_surface_debug_data *debug_data = NULL;
1616 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1618 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1619 TBM_ERR("fail to allocate the debug_data.");
1623 if (key) debug_data->key = strdup(key);
1624 if (value) debug_data->value = strdup(value);
1630 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1632 if (!debug_data->value && !value)
1635 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1638 if (debug_data->value)
1639 free(debug_data->value);
1642 debug_data->value = strdup(value);
1644 debug_data->value = NULL;
1647 static tbm_surface_debug_data *
1648 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1650 tbm_surface_debug_data *debug_data = NULL;
1652 if (LIST_IS_EMPTY(list))
1655 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1656 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1664 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1666 tbm_surface_debug_data *debug_data = NULL;
1667 tbm_bufmgr bufmgr = NULL;
1669 _tbm_surface_mutex_lock();
1670 _tbm_set_last_result(TBM_ERROR_NONE);
1672 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1673 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1675 bufmgr = surface->bufmgr;
1677 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1679 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1681 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1683 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1685 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1686 _tbm_surface_mutex_unlock();
1690 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1693 /* add new debug key to list */
1694 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1696 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1698 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1701 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1703 _tbm_surface_mutex_unlock();
1709 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1711 tbm_surface_debug_data *old_data = NULL;
1713 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1715 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1716 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1717 if (!strcmp(old_data->key, key))
1718 return old_data->value;
1725 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1726 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1728 struct _tbm_surface_dump_buf_info {
1738 tbm_surface_info_s info;
1740 struct list_head link;
1743 struct _tbm_surface_dump_info {
1744 char *path; // copy???
1747 struct list_head *link;
1748 struct list_head surface_list; /* link of surface */
1751 static tbm_surface_dump_info *g_dump_info = NULL;
1752 static const char *dump_postfix[2] = {"png", "yuv"};
1753 static double scale_factor;
1756 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1757 void *data2, int size2, void *data3, int size3)
1760 unsigned int *blocks;
1762 if (_tbm_surface_check_file_is_symbolic_link(file))
1763 TBM_ERR("%s is symbolic link\n", file);
1765 fp = fopen(file, "w+");
1766 TBM_RETURN_IF_FAIL(fp != NULL);
1768 blocks = (unsigned int *)data1;
1769 fwrite(blocks, 1, size1, fp);
1772 blocks = (unsigned int *)data2;
1773 fwrite(blocks, 1, size2, fp);
1777 blocks = (unsigned int *)data3;
1778 fwrite(blocks, 1, size3, fp);
1785 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1787 unsigned int *blocks = (unsigned int *)data;
1790 png_bytep *row_pointers;
1793 if (_tbm_surface_check_file_is_symbolic_link(file))
1794 TBM_ERR("%s is symbolic link\n", file);
1796 fp = fopen(file, "wb");
1797 TBM_RETURN_IF_FAIL(fp != NULL);
1799 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1802 TBM_ERR("fail to create a png write structure.\n");
1807 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1809 TBM_ERR("fail to create a png info structure.\n");
1810 png_destroy_write_struct(&pPngStruct, NULL);
1815 if (setjmp(png_jmpbuf(pPngStruct))) {
1816 /* if png has problem of writing the file, we get here */
1817 TBM_ERR("fail to write png file.\n");
1818 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1823 png_init_io(pPngStruct, fp);
1824 if (format == TBM_FORMAT_XRGB8888) {
1826 png_set_IHDR(pPngStruct,
1833 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1836 png_set_IHDR(pPngStruct,
1841 PNG_COLOR_TYPE_RGBA,
1843 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1846 png_set_bgr(pPngStruct);
1847 png_write_info(pPngStruct, pPngInfo);
1849 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1850 if (!row_pointers) {
1851 TBM_ERR("fail to allocate the png row_pointers.\n");
1852 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1857 for (y = 0; y < height; ++y) {
1861 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1863 TBM_ERR("fail to allocate the png row.\n");
1864 for (x = 0; x < y; x++)
1865 png_free(pPngStruct, row_pointers[x]);
1866 png_free(pPngStruct, row_pointers);
1867 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1871 row_pointers[y] = (png_bytep)row;
1873 for (x = 0; x < width; ++x) {
1874 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1876 if (pixel_size == 3) { // XRGB8888
1877 row[x * pixel_size] = (curBlock & 0xFF);
1878 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1879 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1880 } else { // ARGB8888
1881 row[x * pixel_size] = (curBlock & 0xFF);
1882 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1883 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1884 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1889 png_write_image(pPngStruct, row_pointers);
1890 png_write_end(pPngStruct, pPngInfo);
1892 for (y = 0; y < height; y++)
1893 png_free(pPngStruct, row_pointers[y]);
1894 png_free(pPngStruct, row_pointers);
1896 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1902 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1904 TBM_RETURN_IF_FAIL(path != NULL);
1905 TBM_RETURN_IF_FAIL(w > 0);
1906 TBM_RETURN_IF_FAIL(h > 0);
1907 TBM_RETURN_IF_FAIL(count > 0);
1909 tbm_surface_dump_buf_info *buf_info = NULL;
1910 tbm_surface_h tbm_surface;
1911 tbm_surface_info_s info;
1916 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1920 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1921 TBM_RETURN_IF_FAIL(g_dump_info);
1923 LIST_INITHEAD(&g_dump_info->surface_list);
1924 g_dump_info->count = 0;
1925 g_dump_info->dump_max = count;
1927 /* get buffer size */
1928 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1929 if (tbm_surface == NULL) {
1930 TBM_ERR("tbm_surface_create fail\n");
1936 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1937 TBM_ERR("tbm_surface_get_info fail\n");
1938 tbm_surface_destroy(tbm_surface);
1943 buffer_size = info.size;
1944 tbm_surface_destroy(tbm_surface);
1946 /* create dump lists */
1947 for (i = 0; i < count; i++) {
1950 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1951 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1953 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1955 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1960 buf_info->index = i;
1962 buf_info->size = buffer_size;
1964 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1967 g_dump_info->path = path;
1968 g_dump_info->link = &g_dump_info->surface_list;
1972 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1977 /* free resources */
1978 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1979 tbm_surface_dump_buf_info *tmp;
1981 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1982 tbm_bo_unref(buf_info->bo);
1983 LIST_DEL(&buf_info->link);
1988 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1997 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2004 tbm_surface_internal_dump_start(path, w, h, count);
2005 scale_factor = scale;
2009 tbm_surface_internal_dump_end(void)
2011 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2012 tbm_bo_handle bo_handle;
2017 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2024 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2027 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2028 if (bo_handle.ptr == NULL) {
2029 tbm_bo_unref(buf_info->bo);
2030 LIST_DEL(&buf_info->link);
2035 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2036 TBM_INFO("Dump File.. %s generated.\n", file);
2038 if (buf_info->dirty) {
2039 void *ptr1 = NULL, *ptr2 = NULL;
2041 switch (buf_info->info.format) {
2042 case TBM_FORMAT_ARGB8888:
2043 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2044 buf_info->info.planes[0].stride >> 2,
2045 buf_info->info.height,
2046 buf_info->info.planes[0].stride,
2047 TBM_FORMAT_ARGB8888);
2049 case TBM_FORMAT_XRGB8888:
2050 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2051 buf_info->info.planes[0].stride >> 2,
2052 buf_info->info.height,
2053 buf_info->info.planes[0].stride,
2054 TBM_FORMAT_XRGB8888);
2056 case TBM_FORMAT_YVU420:
2057 case TBM_FORMAT_YUV420:
2058 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2059 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2060 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2061 buf_info->info.planes[0].stride * buf_info->info.height,
2063 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2065 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2067 case TBM_FORMAT_NV12:
2068 case TBM_FORMAT_NV21:
2069 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2070 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2071 buf_info->info.planes[0].stride * buf_info->info.height,
2073 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2076 case TBM_FORMAT_YUYV:
2077 case TBM_FORMAT_UYVY:
2078 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2079 buf_info->info.planes[0].stride * buf_info->info.height,
2083 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2086 } else if (buf_info->dirty_shm)
2087 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2088 buf_info->shm_stride >> 2,
2090 buf_info->shm_stride, 0);
2092 tbm_bo_unmap(buf_info->bo);
2093 tbm_bo_unref(buf_info->bo);
2094 LIST_DEL(&buf_info->link);
2101 TBM_INFO("Dump End..\n");
2104 static pixman_format_code_t
2105 _tbm_surface_internal_pixman_format_get(tbm_format format)
2108 case TBM_FORMAT_ARGB8888:
2109 return PIXMAN_a8r8g8b8;
2110 case TBM_FORMAT_XRGB8888:
2111 return PIXMAN_x8r8g8b8;
2120 * This function supports only if a buffer has below formats.
2121 * - TBM_FORMAT_ARGB8888
2122 * - TBM_FORMAT_XRGB8888
2124 static tbm_surface_error_e
2125 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2126 int format, int src_stride, int src_w, int src_h,
2127 int dst_stride, int dst_w, int dst_h)
2129 pixman_image_t *src_img = NULL, *dst_img = NULL;
2130 pixman_format_code_t pixman_format;
2131 pixman_transform_t t;
2132 struct pixman_f_transform ft;
2133 double scale_x, scale_y;
2135 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2136 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2138 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2139 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2142 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2143 (uint32_t*)src_ptr, src_stride);
2144 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2147 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2148 (uint32_t*)dst_ptr, dst_stride);
2149 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2151 pixman_f_transform_init_identity(&ft);
2153 scale_x = (double)src_w / dst_w;
2154 scale_y = (double)src_h / dst_h;
2156 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2157 pixman_f_transform_translate(&ft, NULL, 0, 0);
2158 pixman_transform_from_pixman_f_transform(&t, &ft);
2159 pixman_image_set_transform(src_img, &t);
2161 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2162 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2164 pixman_image_unref(src_img);
2165 pixman_image_unref(dst_img);
2167 return TBM_SURFACE_ERROR_NONE;
2171 pixman_image_unref(src_img);
2173 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2176 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2177 #define KEY_LEN 5 // "_XXXX"
2178 #define KEYS_LEN KEY_LEN * MAX_BOS
2180 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2182 char *keys, temp_key[KEY_LEN + 1];
2183 struct _tbm_surface *surf;
2187 _tbm_surface_mutex_lock();
2189 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2191 surf = (struct _tbm_surface *)surface;
2193 num_bos = surf->num_bos;
2194 if (num_bos > MAX_BOS)
2197 keys = calloc(KEYS_LEN + 1, sizeof(char));
2199 TBM_ERR("Failed to alloc memory");
2200 _tbm_surface_mutex_unlock();
2204 for (i = 0; i < num_bos; i++) {
2205 memset(temp_key, 0x00, KEY_LEN + 1);
2207 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2208 strncat(keys, temp_key, KEY_LEN + 1);
2211 _tbm_surface_mutex_unlock();
2216 static void _tbm_surface_internal_put_keys(char *keys)
2223 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2225 TBM_RETURN_IF_FAIL(surface != NULL);
2226 TBM_RETURN_IF_FAIL(type != NULL);
2228 tbm_surface_dump_buf_info *buf_info;
2229 struct list_head *next_link;
2230 tbm_surface_info_s info;
2231 tbm_bo_handle bo_handle;
2232 const char *postfix;
2233 const char *format = NULL;
2240 next_link = g_dump_info->link->next;
2241 TBM_RETURN_IF_FAIL(next_link != NULL);
2243 if (next_link == &g_dump_info->surface_list) {
2244 next_link = next_link->next;
2245 TBM_RETURN_IF_FAIL(next_link != NULL);
2248 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2249 TBM_RETURN_IF_FAIL(buf_info != NULL);
2251 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2252 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2254 if (scale_factor > 0.0) {
2257 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2258 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2259 _tbm_surface_internal_format_to_str(info.format));
2260 tbm_surface_unmap(surface);
2264 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2266 buf_info->info.width = info.width * scale_factor;
2267 buf_info->info.height = info.height * scale_factor;
2268 buf_info->info.format = info.format;
2269 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2270 if (!buf_info->info.bpp) {
2271 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2272 tbm_surface_unmap(surface);
2275 buf_info->info.num_planes = 1;
2276 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2277 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2279 if (buf_info->info.size > buf_info->size) {
2280 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2281 buf_info->info.size, buf_info->size);
2282 tbm_surface_unmap(surface);
2286 if (info.size > buf_info->size) {
2287 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2288 info.size, buf_info->size);
2289 tbm_surface_unmap(surface);
2293 /* make the file information */
2294 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2297 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2298 postfix = dump_postfix[0];
2299 format = _tbm_surface_internal_format_to_str(info.format);
2301 postfix = dump_postfix[1];
2303 keys = _tbm_surface_internal_get_keys(surface);
2305 TBM_ERR("fail to get keys");
2306 tbm_surface_unmap(surface);
2311 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2312 if (!bo_handle.ptr) {
2313 TBM_ERR("fail to map bo");
2314 _tbm_surface_internal_put_keys(keys);
2315 tbm_surface_unmap(surface);
2318 memset(bo_handle.ptr, 0x00, buf_info->size);
2320 switch (info.format) {
2321 case TBM_FORMAT_ARGB8888:
2322 case TBM_FORMAT_XRGB8888:
2323 snprintf(buf_info->name, sizeof(buf_info->name),
2324 "%10.3f_%03d%s_%p_%s-%s.%s",
2325 _tbm_surface_internal_get_time(),
2326 g_dump_info->count++, keys, surface, format, type, postfix);
2328 if (scale_factor > 0.0) {
2329 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2331 buf_info->info.format,
2332 info.planes[0].stride,
2333 info.width, info.height,
2334 buf_info->info.planes[0].stride,
2335 buf_info->info.width,
2336 buf_info->info.height);
2337 if (ret != TBM_SURFACE_ERROR_NONE) {
2338 TBM_ERR("fail to scale buffer");
2339 tbm_bo_unmap(buf_info->bo);
2340 _tbm_surface_internal_put_keys(keys);
2341 tbm_surface_unmap(surface);
2345 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2347 case TBM_FORMAT_YVU420:
2348 case TBM_FORMAT_YUV420:
2349 snprintf(buf_info->name, sizeof(buf_info->name),
2350 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2351 _tbm_surface_internal_get_time(),
2352 g_dump_info->count++, keys, type, info.planes[0].stride,
2353 info.height, FOURCC_STR(info.format), postfix);
2354 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2355 bo_handle.ptr += info.planes[0].stride * info.height;
2356 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2357 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2358 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2360 case TBM_FORMAT_NV12:
2361 case TBM_FORMAT_NV21:
2362 snprintf(buf_info->name, sizeof(buf_info->name),
2363 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2364 _tbm_surface_internal_get_time(),
2365 g_dump_info->count++, keys, type, info.planes[0].stride,
2366 info.height, FOURCC_STR(info.format), postfix);
2367 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2368 bo_handle.ptr += info.planes[0].stride * info.height;
2369 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2371 case TBM_FORMAT_YUYV:
2372 case TBM_FORMAT_UYVY:
2373 snprintf(buf_info->name, sizeof(buf_info->name),
2374 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2375 _tbm_surface_internal_get_time(),
2376 g_dump_info->count++, keys, type, info.planes[0].stride,
2377 info.height, FOURCC_STR(info.format), postfix);
2378 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2381 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2382 tbm_bo_unmap(buf_info->bo);
2383 _tbm_surface_internal_put_keys(keys);
2384 tbm_surface_unmap(surface);
2388 tbm_bo_unmap(buf_info->bo);
2390 _tbm_surface_internal_put_keys(keys);
2392 tbm_surface_unmap(surface);
2394 buf_info->dirty = 1;
2395 buf_info->dirty_shm = 0;
2397 if (g_dump_info->count == 1000)
2398 g_dump_info->count = 0;
2400 g_dump_info->link = next_link;
2402 TBM_INFO("Dump %s \n", buf_info->name);
2405 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2408 TBM_RETURN_IF_FAIL(ptr != NULL);
2409 TBM_RETURN_IF_FAIL(w > 0);
2410 TBM_RETURN_IF_FAIL(h > 0);
2411 TBM_RETURN_IF_FAIL(stride > 0);
2412 TBM_RETURN_IF_FAIL(type != NULL);
2414 tbm_surface_dump_buf_info *buf_info;
2415 struct list_head *next_link;
2416 tbm_bo_handle bo_handle;
2417 int ret, size, dw = 0, dh = 0, dstride = 0;
2422 next_link = g_dump_info->link->next;
2423 TBM_RETURN_IF_FAIL(next_link != NULL);
2425 if (next_link == &g_dump_info->surface_list) {
2426 next_link = next_link->next;
2427 TBM_RETURN_IF_FAIL(next_link != NULL);
2430 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2431 TBM_RETURN_IF_FAIL(buf_info != NULL);
2433 if (scale_factor > 0.0) {
2436 dw = w * scale_factor;
2437 dh = h * scale_factor;
2439 size = dstride * dh;
2443 if (size > buf_info->size) {
2444 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2445 size, buf_info->size);
2450 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2451 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2453 memset(bo_handle.ptr, 0x00, buf_info->size);
2454 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2456 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2457 _tbm_surface_internal_get_time(),
2458 g_dump_info->count++, type, dump_postfix[0]);
2459 if (scale_factor > 0.0) {
2460 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2461 TBM_FORMAT_ARGB8888, stride,
2462 w, h, dstride, dw, dh);
2463 if (ret != TBM_SURFACE_ERROR_NONE) {
2464 TBM_ERR("fail to scale buffer");
2465 tbm_bo_unmap(buf_info->bo);
2468 buf_info->shm_stride = dstride;
2469 buf_info->shm_h = dh;
2471 memcpy(bo_handle.ptr, ptr, size);
2472 buf_info->shm_stride = stride;
2473 buf_info->shm_h = h;
2476 tbm_bo_unmap(buf_info->bo);
2478 buf_info->dirty = 0;
2479 buf_info->dirty_shm = 1;
2481 if (g_dump_info->count == 1000)
2482 g_dump_info->count = 0;
2484 g_dump_info->link = next_link;
2486 TBM_INFO("Dump %s \n", buf_info->name);
2490 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2492 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2493 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2494 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2496 tbm_surface_info_s info;
2497 const char *postfix;
2501 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2502 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2504 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2505 postfix = dump_postfix[0];
2507 postfix = dump_postfix[1];
2509 if (strcmp(postfix, type)) {
2510 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2511 tbm_surface_unmap(surface);
2515 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2517 if (!access(file, 0)) {
2518 TBM_ERR("can't capture buffer, exist file %s", file);
2519 tbm_surface_unmap(surface);
2523 switch (info.format) {
2524 case TBM_FORMAT_ARGB8888:
2525 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2528 info.planes[0].stride,
2529 TBM_FORMAT_ARGB8888);
2531 case TBM_FORMAT_XRGB8888:
2532 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2535 info.planes[0].stride,
2536 TBM_FORMAT_XRGB8888);
2538 case TBM_FORMAT_YVU420:
2539 case TBM_FORMAT_YUV420:
2540 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2541 info.planes[0].stride * info.height,
2543 info.planes[1].stride * (info.height >> 1),
2545 info.planes[2].stride * (info.height >> 1));
2547 case TBM_FORMAT_NV12:
2548 case TBM_FORMAT_NV21:
2549 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2550 info.planes[0].stride * info.height,
2552 info.planes[1].stride * (info.height >> 1),
2555 case TBM_FORMAT_YUYV:
2556 case TBM_FORMAT_UYVY:
2557 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2558 info.planes[0].stride * info.height,
2562 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2563 tbm_surface_unmap(surface);
2567 tbm_surface_unmap(surface);
2569 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2575 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2576 const char *path, const char *name, const char *type)
2578 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2579 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2580 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2581 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2582 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2583 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2587 if (strcmp(dump_postfix[0], type)) {
2588 TBM_ERR("Not supported type:%s'", type);
2592 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2594 if (!access(file, 0)) {
2595 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2599 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2601 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2607 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2609 struct _tbm_surface *surf;
2611 _tbm_surface_mutex_lock();
2612 _tbm_set_last_result(TBM_ERROR_NONE);
2614 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2615 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2616 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2618 surf = (struct _tbm_surface *)surface;
2622 surf->damage.width = width;
2623 surf->damage.height = height;
2625 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2626 surface, x, y, width, height);
2628 _tbm_surface_mutex_unlock();
2634 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2636 struct _tbm_surface *surf;
2638 _tbm_surface_mutex_lock();
2639 _tbm_set_last_result(TBM_ERROR_NONE);
2641 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2643 surf = (struct _tbm_surface *)surface;
2645 if (x) *x = surf->damage.x;
2646 if (y) *y = surf->damage.y;
2647 if (width) *width = surf->damage.width;
2648 if (height) *height = surf->damage.height;
2650 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2651 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2653 _tbm_surface_mutex_unlock();
2659 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2661 struct _tbm_surface *surf;
2662 tbm_surface_destroy_func_info *func_info = NULL;
2664 _tbm_surface_mutex_lock();
2665 _tbm_set_last_result(TBM_ERROR_NONE);
2667 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2668 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2670 surf = (struct _tbm_surface *)surface;
2671 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2672 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2673 TBM_ERR("can't add twice");
2674 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2675 _tbm_surface_mutex_unlock();
2680 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2681 if (func_info == NULL) {
2682 TBM_ERR("alloc failed");
2683 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2684 _tbm_surface_mutex_unlock();
2688 func_info->destroy_func = func;
2689 func_info->user_data = user_data;
2691 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2693 _tbm_surface_mutex_unlock();
2699 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2701 struct _tbm_surface *surf;
2702 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2704 _tbm_surface_mutex_lock();
2705 _tbm_set_last_result(TBM_ERROR_NONE);
2707 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2708 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2710 surf = (struct _tbm_surface *)surface;
2711 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2712 if (func_info->destroy_func != func || func_info->user_data != user_data)
2715 LIST_DEL(&func_info->item_link);
2718 _tbm_surface_mutex_unlock();
2723 _tbm_surface_mutex_unlock();