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->backend_module_data) {
293 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
294 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
298 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
299 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
300 if (error != TBM_ERROR_NONE) {
301 /* LCOV_EXCL_START */
302 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
303 _tbm_set_last_result(error);
309 if (!bufmgr->backend->surface_get_plane_data) {
310 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
314 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
315 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
317 /* LCOV_EXCL_START */
318 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
319 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
329 _tbm_surface_internal_destroy(tbm_surface_h surface)
332 tbm_bufmgr bufmgr = surface->bufmgr;
333 tbm_user_data *old_data = NULL, *tmp = NULL;
334 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
336 /* destory the user_data_list */
337 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
338 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
339 TBM_DBG("free user_data\n");
340 user_data_delete(old_data);
344 for (i = 0; i < surface->num_bos; i++) {
345 surface->bos[i]->surface = NULL;
347 tbm_bo_unref(surface->bos[i]);
348 surface->bos[i] = NULL;
351 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
352 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
353 _tbm_surface_internal_debug_data_delete(debug_old_data);
356 LIST_DEL(&surface->item_link);
362 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
363 LIST_DELINIT(&bufmgr->surf_list);
365 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
366 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
367 _tbm_surface_internal_debug_data_delete(debug_old_data);
371 _deinit_surface_bufmgr();
375 /* LCOV_EXCL_START */
377 _tbm_surface_check_file_is_symbolic_link(const char* path)
384 if (stat(path, &sb) != 0)
387 if (S_ISLNK(sb.st_mode))
395 _tbm_surface_internal_get_num_planes(tbm_format format)
401 case TBM_FORMAT_RGB332:
402 case TBM_FORMAT_BGR233:
403 case TBM_FORMAT_XRGB4444:
404 case TBM_FORMAT_XBGR4444:
405 case TBM_FORMAT_RGBX4444:
406 case TBM_FORMAT_BGRX4444:
407 case TBM_FORMAT_ARGB4444:
408 case TBM_FORMAT_ABGR4444:
409 case TBM_FORMAT_RGBA4444:
410 case TBM_FORMAT_BGRA4444:
411 case TBM_FORMAT_XRGB1555:
412 case TBM_FORMAT_XBGR1555:
413 case TBM_FORMAT_RGBX5551:
414 case TBM_FORMAT_BGRX5551:
415 case TBM_FORMAT_ARGB1555:
416 case TBM_FORMAT_ABGR1555:
417 case TBM_FORMAT_RGBA5551:
418 case TBM_FORMAT_BGRA5551:
419 case TBM_FORMAT_RGB565:
420 case TBM_FORMAT_BGR565:
421 case TBM_FORMAT_RGB888:
422 case TBM_FORMAT_BGR888:
423 case TBM_FORMAT_XRGB8888:
424 case TBM_FORMAT_XBGR8888:
425 case TBM_FORMAT_RGBX8888:
426 case TBM_FORMAT_BGRX8888:
427 case TBM_FORMAT_ARGB8888:
428 case TBM_FORMAT_ABGR8888:
429 case TBM_FORMAT_RGBA8888:
430 case TBM_FORMAT_BGRA8888:
431 case TBM_FORMAT_XRGB2101010:
432 case TBM_FORMAT_XBGR2101010:
433 case TBM_FORMAT_RGBX1010102:
434 case TBM_FORMAT_BGRX1010102:
435 case TBM_FORMAT_ARGB2101010:
436 case TBM_FORMAT_ABGR2101010:
437 case TBM_FORMAT_RGBA1010102:
438 case TBM_FORMAT_BGRA1010102:
439 case TBM_FORMAT_YUYV:
440 case TBM_FORMAT_YVYU:
441 case TBM_FORMAT_UYVY:
442 case TBM_FORMAT_VYUY:
443 case TBM_FORMAT_AYUV:
446 case TBM_FORMAT_NV12:
447 case TBM_FORMAT_NV12MT:
448 case TBM_FORMAT_NV21:
449 case TBM_FORMAT_NV16:
450 case TBM_FORMAT_NV61:
453 case TBM_FORMAT_YUV410:
454 case TBM_FORMAT_YVU410:
455 case TBM_FORMAT_YUV411:
456 case TBM_FORMAT_YVU411:
457 case TBM_FORMAT_YUV420:
458 case TBM_FORMAT_YVU420:
459 case TBM_FORMAT_YUV422:
460 case TBM_FORMAT_YVU422:
461 case TBM_FORMAT_YUV444:
462 case TBM_FORMAT_YVU444:
467 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
475 _tbm_surface_internal_get_bpp(tbm_format format)
482 case TBM_FORMAT_RGB332:
483 case TBM_FORMAT_BGR233:
486 case TBM_FORMAT_XRGB4444:
487 case TBM_FORMAT_XBGR4444:
488 case TBM_FORMAT_RGBX4444:
489 case TBM_FORMAT_BGRX4444:
490 case TBM_FORMAT_ARGB4444:
491 case TBM_FORMAT_ABGR4444:
492 case TBM_FORMAT_RGBA4444:
493 case TBM_FORMAT_BGRA4444:
494 case TBM_FORMAT_XRGB1555:
495 case TBM_FORMAT_XBGR1555:
496 case TBM_FORMAT_RGBX5551:
497 case TBM_FORMAT_BGRX5551:
498 case TBM_FORMAT_ARGB1555:
499 case TBM_FORMAT_ABGR1555:
500 case TBM_FORMAT_RGBA5551:
501 case TBM_FORMAT_BGRA5551:
502 case TBM_FORMAT_RGB565:
503 case TBM_FORMAT_BGR565:
506 case TBM_FORMAT_RGB888:
507 case TBM_FORMAT_BGR888:
510 case TBM_FORMAT_XRGB8888:
511 case TBM_FORMAT_XBGR8888:
512 case TBM_FORMAT_RGBX8888:
513 case TBM_FORMAT_BGRX8888:
514 case TBM_FORMAT_ARGB8888:
515 case TBM_FORMAT_ABGR8888:
516 case TBM_FORMAT_RGBA8888:
517 case TBM_FORMAT_BGRA8888:
518 case TBM_FORMAT_XRGB2101010:
519 case TBM_FORMAT_XBGR2101010:
520 case TBM_FORMAT_RGBX1010102:
521 case TBM_FORMAT_BGRX1010102:
522 case TBM_FORMAT_ARGB2101010:
523 case TBM_FORMAT_ABGR2101010:
524 case TBM_FORMAT_RGBA1010102:
525 case TBM_FORMAT_BGRA1010102:
526 case TBM_FORMAT_YUYV:
527 case TBM_FORMAT_YVYU:
528 case TBM_FORMAT_UYVY:
529 case TBM_FORMAT_VYUY:
530 case TBM_FORMAT_AYUV:
533 case TBM_FORMAT_NV12:
534 case TBM_FORMAT_NV12MT:
535 case TBM_FORMAT_NV21:
538 case TBM_FORMAT_NV16:
539 case TBM_FORMAT_NV61:
542 case TBM_FORMAT_YUV410:
543 case TBM_FORMAT_YVU410:
546 case TBM_FORMAT_YUV411:
547 case TBM_FORMAT_YVU411:
548 case TBM_FORMAT_YUV420:
549 case TBM_FORMAT_YVU420:
552 case TBM_FORMAT_YUV422:
553 case TBM_FORMAT_YVU422:
556 case TBM_FORMAT_YUV444:
557 case TBM_FORMAT_YVU444:
561 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
569 tbm_surface_internal_is_valid(tbm_surface_h surface)
573 _tbm_surface_mutex_lock();
574 _tbm_set_last_result(TBM_ERROR_NONE);
576 /* Return silently if surface is null. */
578 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
579 _tbm_surface_mutex_unlock();
583 ret = _tbm_surface_internal_is_valid(surface);
585 _tbm_surface_mutex_unlock();
591 tbm_surface_internal_query_supported_formats(uint32_t **formats,
594 struct _tbm_bufmgr *bufmgr;
596 bool bufmgr_initialized = false;
599 _tbm_surface_mutex_lock();
600 _tbm_set_last_result(TBM_ERROR_NONE);
602 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
603 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
605 if (!g_surface_bufmgr) {
606 _init_surface_bufmgr();
607 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
608 bufmgr_initialized = true;
611 bufmgr = g_surface_bufmgr;
613 if (bufmgr->backend_module_data) {
614 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
615 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
619 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
620 if (error != TBM_ERROR_NONE) {
621 /* LCOV_EXCL_START */
622 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
624 /* LCOV_EXCL_START */
628 if (!bufmgr->backend->surface_supported_format) {
629 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
633 ret = bufmgr->backend->surface_supported_format(formats, num);
635 /* LCOV_EXCL_START */
636 TBM_ERR("Fail to surface_supported_format.\n");
637 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
639 /* LCOV_EXCL_START */
643 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
645 if (bufmgr_initialized) {
646 LIST_DELINIT(&g_surface_bufmgr->surf_list);
647 _deinit_surface_bufmgr();
650 _tbm_surface_mutex_unlock();
654 /* LCOV_EXCL_START */
656 if (bufmgr_initialized) {
657 LIST_DELINIT(&g_surface_bufmgr->surf_list);
658 _deinit_surface_bufmgr();
660 _tbm_surface_mutex_unlock();
662 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
669 tbm_surface_internal_get_num_planes(tbm_format format)
673 _tbm_surface_mutex_lock();
674 _tbm_set_last_result(TBM_ERROR_NONE);
676 num_planes = _tbm_surface_internal_get_num_planes(format);
678 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
679 _tbm_surface_mutex_unlock();
683 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
685 _tbm_surface_mutex_unlock();
691 tbm_surface_internal_get_bpp(tbm_format format)
695 _tbm_surface_mutex_lock();
696 _tbm_set_last_result(TBM_ERROR_NONE);
698 bpp = _tbm_surface_internal_get_bpp(format);
700 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
701 _tbm_surface_mutex_unlock();
705 _tbm_surface_mutex_unlock();
707 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
713 tbm_surface_internal_create_with_flags(int width, int height,
714 int format, int flags)
716 struct _tbm_bufmgr *bufmgr;
717 struct _tbm_surface *surf = NULL;
721 uint32_t bo_size = 0;
724 bool bufmgr_initialized = false;
727 _tbm_surface_mutex_lock();
728 _tbm_set_last_result(TBM_ERROR_NONE);
730 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
731 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
733 if (!g_surface_bufmgr) {
734 _init_surface_bufmgr();
735 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
736 bufmgr_initialized = true;
739 bufmgr = g_surface_bufmgr;
740 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
741 TBM_ERR("The bufmgr is invalid\n");
742 goto check_valid_fail;
745 surf = calloc(1, sizeof(struct _tbm_surface));
747 /* LCOV_EXCL_START */
748 TBM_ERR("fail to alloc surf\n");
749 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
750 goto alloc_surf_fail;
754 surf->magic = TBM_SURFACE_MAGIC;
755 surf->bufmgr = bufmgr;
756 surf->info.width = width;
757 surf->info.height = height;
758 surf->info.format = format;
759 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
760 if (!surf->info.bpp) {
761 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
764 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
765 if (!surf->info.num_planes) {
766 TBM_ERR("fail to get num_planes. error(%s)\n", tbm_error_str(tbm_get_last_error()));
767 goto num_planes_fail;
771 /* get size, stride and offset bo_idx */
772 for (i = 0; i < surf->info.num_planes; i++) {
773 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
774 &offset, &stride, &bo_idx)) {
775 TBM_ERR("fail to query plane data\n");
776 goto query_plane_data_fail;
779 surf->info.planes[i].size = size;
780 surf->info.planes[i].offset = offset;
781 surf->info.planes[i].stride = stride;
782 surf->planes_bo_idx[i] = bo_idx;
787 for (i = 0; i < surf->info.num_planes; i++) {
788 surf->info.size += surf->info.planes[i].size;
790 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
791 surf->num_bos = surf->planes_bo_idx[i] + 1;
796 for (i = 0; i < surf->num_bos; i++) {
798 for (j = 0; j < surf->info.num_planes; j++) {
799 if (surf->planes_bo_idx[j] == i)
800 bo_size += surf->info.planes[j].size;
803 if (bufmgr->backend_module_data) {
804 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
805 /* LCOV_EXCL_START */
806 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, flags, &error);
808 TBM_ERR("fail to tbm_bo_alloc_with_format idx:%d\n", i);
812 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
813 /* LCOV_EXCL_START */
814 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, &error);
816 TBM_ERR("fail to tbm_bo_alloc_with_tiled_format idx:%d\n", i);
821 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
823 TBM_ERR("fail to alloc bo idx:%d\n", i);
828 if (bufmgr->backend->surface_bo_alloc) {
829 /* LCOV_EXCL_START */
830 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
832 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
837 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
839 TBM_ERR("fail to alloc bo idx:%d\n", i);
845 _tbm_bo_set_surface(surf->bos[i], surf);
848 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
849 _tbm_surface_internal_format_to_str(format), flags, surf);
851 LIST_INITHEAD(&surf->user_data_list);
852 LIST_INITHEAD(&surf->debug_data_list);
854 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
856 _tbm_surface_mutex_unlock();
860 /* LCOV_EXCL_START */
862 for (j = 0; j < i; j++) {
864 tbm_bo_unref(surf->bos[j]);
866 query_plane_data_fail:
872 if (bufmgr_initialized && bufmgr) {
873 LIST_DELINIT(&bufmgr->surf_list);
874 _deinit_surface_bufmgr();
876 _tbm_surface_mutex_unlock();
878 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
880 _tbm_surface_internal_format_to_str(format), flags);
887 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
888 tbm_bo *bos, int num)
890 struct _tbm_bufmgr *bufmgr;
891 struct _tbm_surface *surf = NULL;
893 bool bufmgr_initialized = false;
895 _tbm_surface_mutex_lock();
896 _tbm_set_last_result(TBM_ERROR_NONE);
898 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
899 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
900 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
901 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
902 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
904 if (!g_surface_bufmgr) {
905 _init_surface_bufmgr();
906 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
907 bufmgr_initialized = true;
910 bufmgr = g_surface_bufmgr;
911 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
912 TBM_ERR("fail to validate the Bufmgr.\n");
913 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
914 goto check_valid_fail;
917 surf = calloc(1, sizeof(struct _tbm_surface));
919 /* LCOV_EXCL_START */
920 TBM_ERR("fail to allocate struct _tbm_surface.\n");
921 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
922 goto alloc_surf_fail;
926 surf->magic = TBM_SURFACE_MAGIC;
927 surf->bufmgr = bufmgr;
928 surf->info.width = info->width;
929 surf->info.height = info->height;
930 surf->info.format = info->format;
932 surf->info.bpp = info->bpp;
934 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
935 if (!surf->info.bpp) {
936 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
940 surf->info.num_planes = info->num_planes;
943 /* get size, stride and offset */
944 for (i = 0; i < info->num_planes; i++) {
945 surf->info.planes[i].offset = info->planes[i].offset;
946 surf->info.planes[i].stride = info->planes[i].stride;
948 if (info->planes[i].size > 0)
949 surf->info.planes[i].size = info->planes[i].size;
951 uint32_t size = 0, offset = 0, stride = 0;
954 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
955 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
956 goto plane_data_fail;
958 surf->info.planes[i].size = size;
962 surf->planes_bo_idx[i] = 0;
964 surf->planes_bo_idx[i] = i;
967 if (info->size > 0) {
968 surf->info.size = info->size;
971 for (i = 0; i < info->num_planes; i++)
972 surf->info.size += surf->info.planes[i].size;
975 surf->flags = TBM_BO_DEFAULT;
977 /* create only one bo */
979 for (i = 0; i < num; i++) {
980 if (bos[i] == NULL) {
981 TBM_ERR("bos[%d] is null.\n", i);
982 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
986 surf->bos[i] = tbm_bo_ref(bos[i]);
987 _tbm_bo_set_surface(bos[i], surf);
990 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
991 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
993 LIST_INITHEAD(&surf->user_data_list);
994 LIST_INITHEAD(&surf->debug_data_list);
996 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
998 _tbm_surface_mutex_unlock();
1002 /* LCOV_EXCL_START */
1006 for (i = 0; i < num; i++) {
1008 tbm_bo_unref(surf->bos[i]);
1013 if (bufmgr_initialized && bufmgr) {
1014 LIST_DELINIT(&bufmgr->surf_list);
1015 _deinit_surface_bufmgr();
1017 _tbm_surface_mutex_unlock();
1019 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1020 info->width, info->height,
1021 _tbm_surface_internal_format_to_str(info->format), num);
1022 /* LCOV_EXCL_STOP */
1028 tbm_surface_internal_destroy(tbm_surface_h surface)
1030 _tbm_surface_mutex_lock();
1031 _tbm_set_last_result(TBM_ERROR_NONE);
1033 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1037 if (surface->refcnt > 0) {
1038 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1039 _tbm_surface_mutex_unlock();
1043 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1045 if (surface->refcnt == 0)
1046 _tbm_surface_internal_destroy(surface);
1048 _tbm_surface_mutex_unlock();
1052 tbm_surface_internal_ref(tbm_surface_h surface)
1054 _tbm_surface_mutex_lock();
1055 _tbm_set_last_result(TBM_ERROR_NONE);
1057 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1061 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1063 _tbm_surface_mutex_unlock();
1067 tbm_surface_internal_unref(tbm_surface_h surface)
1069 _tbm_surface_mutex_lock();
1070 _tbm_set_last_result(TBM_ERROR_NONE);
1072 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1076 if (surface->refcnt > 0) {
1077 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1078 _tbm_surface_mutex_unlock();
1082 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1084 if (surface->refcnt == 0)
1085 _tbm_surface_internal_destroy(surface);
1087 _tbm_surface_mutex_unlock();
1091 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1093 struct _tbm_surface *surf;
1096 _tbm_surface_mutex_lock();
1097 _tbm_set_last_result(TBM_ERROR_NONE);
1099 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1101 surf = (struct _tbm_surface *)surface;
1102 num = surf->num_bos;
1105 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1107 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1109 _tbm_surface_mutex_unlock();
1115 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1117 struct _tbm_surface *surf;
1120 _tbm_surface_mutex_lock();
1121 _tbm_set_last_result(TBM_ERROR_NONE);
1123 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1124 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1126 surf = (struct _tbm_surface *)surface;
1127 bo = surf->bos[bo_idx];
1129 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1131 _tbm_surface_mutex_unlock();
1137 tbm_surface_internal_get_size(tbm_surface_h surface)
1139 struct _tbm_surface *surf;
1142 _tbm_surface_mutex_lock();
1143 _tbm_set_last_result(TBM_ERROR_NONE);
1145 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1147 surf = (struct _tbm_surface *)surface;
1148 size = surf->info.size;
1150 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1152 _tbm_surface_mutex_unlock();
1158 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1159 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1161 struct _tbm_surface *surf;
1163 _tbm_surface_mutex_lock();
1164 _tbm_set_last_result(TBM_ERROR_NONE);
1166 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1167 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1169 surf = (struct _tbm_surface *)surface;
1171 if (plane_idx >= surf->info.num_planes) {
1172 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1173 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1174 _tbm_surface_mutex_unlock();
1179 *size = surf->info.planes[plane_idx].size;
1182 *offset = surf->info.planes[plane_idx].offset;
1185 *pitch = surf->info.planes[plane_idx].stride;
1187 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1188 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1189 surf->info.planes[plane_idx].stride);
1191 _tbm_surface_mutex_unlock();
1197 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1198 tbm_surface_info_s *info, int map)
1200 struct _tbm_surface *surf;
1201 tbm_bo_handle bo_handles[4];
1204 int planes_bo_idx[TBM_SURF_PLANE_MAX];
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 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1214 surf = (struct _tbm_surface *)surface;
1216 memset(info, 0x00, sizeof(tbm_surface_info_s));
1217 info->width = surf->info.width;
1218 info->height = surf->info.height;
1219 info->format = surf->info.format;
1220 info->bpp = surf->info.bpp;
1221 info->size = surf->info.size;
1222 info->num_planes = surf->info.num_planes;
1224 for (i = 0; i < surf->info.num_planes; i++) {
1225 info->planes[i].size = surf->info.planes[i].size;
1226 info->planes[i].offset = surf->info.planes[i].offset;
1227 info->planes[i].stride = surf->info.planes[i].stride;
1228 planes_bo_idx[i] = surf->planes_bo_idx[i];
1231 for (i = 0; i < surf->num_bos; i++)
1232 bos[i] = surf->bos[i];
1234 num_bos = surf->num_bos;
1237 _tbm_surface_mutex_unlock();
1238 for (i = 0; i < num_bos; i++) {
1239 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1240 if (bo_handles[i].ptr == NULL) {
1241 for (j = 0; j < i; j++)
1242 tbm_bo_unmap(bos[j]);
1244 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1248 _tbm_surface_mutex_lock();
1250 for (i = 0; i < num_bos; i++) {
1251 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1252 if (bo_handles[i].ptr == NULL) {
1253 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1254 _tbm_surface_mutex_unlock();
1260 for (i = 0; i < info->num_planes; i++) {
1261 if (bo_handles[planes_bo_idx[i]].ptr)
1262 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1265 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1267 _tbm_surface_mutex_unlock();
1273 tbm_surface_internal_unmap(tbm_surface_h surface)
1275 struct _tbm_surface *surf;
1278 _tbm_surface_mutex_lock();
1279 _tbm_set_last_result(TBM_ERROR_NONE);
1281 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1283 surf = (struct _tbm_surface *)surface;
1285 for (i = 0; i < surf->num_bos; i++)
1286 tbm_bo_unmap(surf->bos[i]);
1288 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1290 _tbm_surface_mutex_unlock();
1294 tbm_surface_internal_get_width(tbm_surface_h surface)
1296 struct _tbm_surface *surf;
1299 _tbm_surface_mutex_lock();
1300 _tbm_set_last_result(TBM_ERROR_NONE);
1302 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1304 surf = (struct _tbm_surface *)surface;
1305 width = surf->info.width;
1307 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1309 _tbm_surface_mutex_unlock();
1315 tbm_surface_internal_get_height(tbm_surface_h surface)
1317 struct _tbm_surface *surf;
1318 unsigned int height;
1320 _tbm_surface_mutex_lock();
1321 _tbm_set_last_result(TBM_ERROR_NONE);
1323 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1325 surf = (struct _tbm_surface *)surface;
1326 height = surf->info.height;
1328 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1330 _tbm_surface_mutex_unlock();
1337 tbm_surface_internal_get_format(tbm_surface_h surface)
1339 struct _tbm_surface *surf;
1342 _tbm_surface_mutex_lock();
1343 _tbm_set_last_result(TBM_ERROR_NONE);
1345 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1347 surf = (struct _tbm_surface *)surface;
1348 format = surf->info.format;
1350 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1352 _tbm_surface_mutex_unlock();
1358 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1360 struct _tbm_surface *surf;
1363 _tbm_surface_mutex_lock();
1364 _tbm_set_last_result(TBM_ERROR_NONE);
1366 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1367 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1369 surf = (struct _tbm_surface *)surface;
1370 bo_idx = surf->planes_bo_idx[plane_idx];
1372 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1374 _tbm_surface_mutex_unlock();
1380 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1381 tbm_data_free data_free_func)
1383 tbm_user_data *data;
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 /* check if the data according to the key exist if so, return false. */
1391 data = user_data_lookup(&surface->user_data_list, key);
1393 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1394 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1395 _tbm_surface_mutex_unlock();
1399 data = user_data_create(key, data_free_func);
1401 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1402 _tbm_surface_mutex_unlock();
1406 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1408 LIST_ADD(&data->item_link, &surface->user_data_list);
1410 _tbm_surface_mutex_unlock();
1416 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1419 tbm_user_data *old_data;
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 old_data = user_data_lookup(&surface->user_data_list, key);
1428 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1429 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1430 _tbm_surface_mutex_unlock();
1434 if (old_data->data && old_data->free_func)
1435 old_data->free_func(old_data->data);
1437 old_data->data = data;
1439 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1441 _tbm_surface_mutex_unlock();
1447 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1450 tbm_user_data *old_data;
1452 _tbm_surface_mutex_lock();
1453 _tbm_set_last_result(TBM_ERROR_NONE);
1455 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1458 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1459 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1460 _tbm_surface_mutex_unlock();
1465 old_data = user_data_lookup(&surface->user_data_list, key);
1467 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1468 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1469 _tbm_surface_mutex_unlock();
1473 *data = old_data->data;
1475 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1477 _tbm_surface_mutex_unlock();
1483 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1486 tbm_user_data *old_data = (void *)0;
1488 _tbm_surface_mutex_lock();
1489 _tbm_set_last_result(TBM_ERROR_NONE);
1491 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1493 old_data = user_data_lookup(&surface->user_data_list, key);
1495 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1496 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1497 _tbm_surface_mutex_unlock();
1501 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1503 user_data_delete(old_data);
1505 _tbm_surface_mutex_unlock();
1510 /* LCOV_EXCL_START */
1512 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1514 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1516 return surface->debug_pid;
1520 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1522 _tbm_surface_mutex_lock();
1523 _tbm_set_last_result(TBM_ERROR_NONE);
1525 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1527 surface->debug_pid = pid;
1529 _tbm_surface_mutex_unlock();
1532 static tbm_surface_debug_data *
1533 _tbm_surface_internal_debug_data_create(char *key, char *value)
1535 tbm_surface_debug_data *debug_data = NULL;
1537 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1539 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1540 TBM_ERR("fail to allocate the debug_data.");
1544 if (key) debug_data->key = strdup(key);
1545 if (value) debug_data->value = strdup(value);
1551 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1553 tbm_surface_debug_data *debug_data = NULL;
1554 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1555 tbm_bufmgr bufmgr = NULL;
1557 _tbm_surface_mutex_lock();
1558 _tbm_set_last_result(TBM_ERROR_NONE);
1560 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1561 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1563 bufmgr = surface->bufmgr;
1565 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1567 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1568 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1570 if (!strcmp(old_data->key, key)) {
1571 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1572 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1573 goto add_debug_key_list;
1576 if (old_data->value)
1577 free(old_data->value);
1580 old_data->value = strdup(value);
1582 old_data->value = NULL;
1584 goto add_debug_key_list;
1590 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1592 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1593 _tbm_surface_mutex_unlock();
1597 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1599 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1602 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1603 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1604 if (!strcmp(old_data->key, key)) {
1605 _tbm_surface_mutex_unlock();
1611 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1612 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1614 _tbm_surface_mutex_unlock();
1620 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1622 tbm_surface_debug_data *old_data = NULL;
1624 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1626 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1627 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1628 if (!strcmp(old_data->key, key))
1629 return old_data->value;
1636 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1637 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1639 struct _tbm_surface_dump_buf_info {
1649 tbm_surface_info_s info;
1651 struct list_head link;
1654 struct _tbm_surface_dump_info {
1655 char *path; // copy???
1658 struct list_head *link;
1659 struct list_head surface_list; /* link of surface */
1662 static tbm_surface_dump_info *g_dump_info = NULL;
1663 static const char *dump_postfix[2] = {"png", "yuv"};
1664 static double scale_factor;
1667 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1668 void *data2, int size2, void *data3, int size3)
1671 unsigned int *blocks;
1673 if (_tbm_surface_check_file_is_symbolic_link(file))
1674 TBM_ERR("%s is symbolic link\n", file);
1676 fp = fopen(file, "w+");
1677 TBM_RETURN_IF_FAIL(fp != NULL);
1679 blocks = (unsigned int *)data1;
1680 fwrite(blocks, 1, size1, fp);
1683 blocks = (unsigned int *)data2;
1684 fwrite(blocks, 1, size2, fp);
1688 blocks = (unsigned int *)data3;
1689 fwrite(blocks, 1, size3, fp);
1696 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1698 unsigned int *blocks = (unsigned int *)data;
1701 png_bytep *row_pointers;
1704 if (_tbm_surface_check_file_is_symbolic_link(file))
1705 TBM_ERR("%s is symbolic link\n", file);
1707 fp = fopen(file, "wb");
1708 TBM_RETURN_IF_FAIL(fp != NULL);
1710 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1713 TBM_ERR("fail to create a png write structure.\n");
1718 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1720 TBM_ERR("fail to create a png info structure.\n");
1721 png_destroy_write_struct(&pPngStruct, NULL);
1726 if (setjmp(png_jmpbuf(pPngStruct))) {
1727 /* if png has problem of writing the file, we get here */
1728 TBM_ERR("fail to write png file.\n");
1729 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1734 png_init_io(pPngStruct, fp);
1735 if (format == TBM_FORMAT_XRGB8888) {
1737 png_set_IHDR(pPngStruct,
1744 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1747 png_set_IHDR(pPngStruct,
1752 PNG_COLOR_TYPE_RGBA,
1754 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1757 png_set_bgr(pPngStruct);
1758 png_write_info(pPngStruct, pPngInfo);
1760 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1761 if (!row_pointers) {
1762 TBM_ERR("fail to allocate the png row_pointers.\n");
1763 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1768 for (y = 0; y < height; ++y) {
1772 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1774 TBM_ERR("fail to allocate the png row.\n");
1775 for (x = 0; x < y; x++)
1776 png_free(pPngStruct, row_pointers[x]);
1777 png_free(pPngStruct, row_pointers);
1778 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1782 row_pointers[y] = (png_bytep)row;
1784 for (x = 0; x < width; ++x) {
1785 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1787 if (pixel_size == 3) { // XRGB8888
1788 row[x * pixel_size] = (curBlock & 0xFF);
1789 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1790 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1791 } else { // ARGB8888
1792 row[x * pixel_size] = (curBlock & 0xFF);
1793 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1794 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1795 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1800 png_write_image(pPngStruct, row_pointers);
1801 png_write_end(pPngStruct, pPngInfo);
1803 for (y = 0; y < height; y++)
1804 png_free(pPngStruct, row_pointers[y]);
1805 png_free(pPngStruct, row_pointers);
1807 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1813 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1815 TBM_RETURN_IF_FAIL(path != NULL);
1816 TBM_RETURN_IF_FAIL(w > 0);
1817 TBM_RETURN_IF_FAIL(h > 0);
1818 TBM_RETURN_IF_FAIL(count > 0);
1820 tbm_surface_dump_buf_info *buf_info = NULL;
1821 tbm_surface_h tbm_surface;
1822 tbm_surface_info_s info;
1827 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1831 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1832 TBM_RETURN_IF_FAIL(g_dump_info);
1834 LIST_INITHEAD(&g_dump_info->surface_list);
1835 g_dump_info->count = 0;
1836 g_dump_info->dump_max = count;
1838 /* get buffer size */
1839 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1840 if (tbm_surface == NULL) {
1841 TBM_ERR("tbm_surface_create fail\n");
1847 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1848 TBM_ERR("tbm_surface_get_info fail\n");
1849 tbm_surface_destroy(tbm_surface);
1854 buffer_size = info.size;
1855 tbm_surface_destroy(tbm_surface);
1857 /* create dump lists */
1858 for (i = 0; i < count; i++) {
1861 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1862 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1864 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1866 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1871 buf_info->index = i;
1873 buf_info->size = buffer_size;
1875 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1878 g_dump_info->path = path;
1879 g_dump_info->link = &g_dump_info->surface_list;
1883 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1888 /* free resources */
1889 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1890 tbm_surface_dump_buf_info *tmp;
1892 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1893 tbm_bo_unref(buf_info->bo);
1894 LIST_DEL(&buf_info->link);
1899 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1908 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1915 tbm_surface_internal_dump_start(path, w, h, count);
1916 scale_factor = scale;
1920 tbm_surface_internal_dump_end(void)
1922 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1923 tbm_bo_handle bo_handle;
1928 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1935 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1938 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1939 if (bo_handle.ptr == NULL) {
1940 tbm_bo_unref(buf_info->bo);
1941 LIST_DEL(&buf_info->link);
1946 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1947 TBM_INFO("Dump File.. %s generated.\n", file);
1949 if (buf_info->dirty) {
1950 void *ptr1 = NULL, *ptr2 = NULL;
1952 switch (buf_info->info.format) {
1953 case TBM_FORMAT_ARGB8888:
1954 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1955 buf_info->info.planes[0].stride >> 2,
1956 buf_info->info.height,
1957 buf_info->info.planes[0].stride,
1958 TBM_FORMAT_ARGB8888);
1960 case TBM_FORMAT_XRGB8888:
1961 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1962 buf_info->info.planes[0].stride >> 2,
1963 buf_info->info.height,
1964 buf_info->info.planes[0].stride,
1965 TBM_FORMAT_XRGB8888);
1967 case TBM_FORMAT_YVU420:
1968 case TBM_FORMAT_YUV420:
1969 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1970 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1971 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1972 buf_info->info.planes[0].stride * buf_info->info.height,
1974 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1976 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1978 case TBM_FORMAT_NV12:
1979 case TBM_FORMAT_NV21:
1980 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1981 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1982 buf_info->info.planes[0].stride * buf_info->info.height,
1984 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1987 case TBM_FORMAT_YUYV:
1988 case TBM_FORMAT_UYVY:
1989 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1990 buf_info->info.planes[0].stride * buf_info->info.height,
1994 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1997 } else if (buf_info->dirty_shm)
1998 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1999 buf_info->shm_stride >> 2,
2001 buf_info->shm_stride, 0);
2003 tbm_bo_unmap(buf_info->bo);
2004 tbm_bo_unref(buf_info->bo);
2005 LIST_DEL(&buf_info->link);
2012 TBM_INFO("Dump End..\n");
2015 static pixman_format_code_t
2016 _tbm_surface_internal_pixman_format_get(tbm_format format)
2019 case TBM_FORMAT_ARGB8888:
2020 return PIXMAN_a8r8g8b8;
2021 case TBM_FORMAT_XRGB8888:
2022 return PIXMAN_x8r8g8b8;
2031 * This function supports only if a buffer has below formats.
2032 * - TBM_FORMAT_ARGB8888
2033 * - TBM_FORMAT_XRGB8888
2035 static tbm_surface_error_e
2036 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2037 int format, int src_stride, int src_w, int src_h,
2038 int dst_stride, int dst_w, int dst_h)
2040 pixman_image_t *src_img = NULL, *dst_img = NULL;
2041 pixman_format_code_t pixman_format;
2042 pixman_transform_t t;
2043 struct pixman_f_transform ft;
2044 double scale_x, scale_y;
2046 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2047 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2049 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2050 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2053 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2054 (uint32_t*)src_ptr, src_stride);
2055 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2058 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2059 (uint32_t*)dst_ptr, dst_stride);
2060 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2062 pixman_f_transform_init_identity(&ft);
2064 scale_x = (double)src_w / dst_w;
2065 scale_y = (double)src_h / dst_h;
2067 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2068 pixman_f_transform_translate(&ft, NULL, 0, 0);
2069 pixman_transform_from_pixman_f_transform(&t, &ft);
2070 pixman_image_set_transform(src_img, &t);
2072 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2073 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2075 pixman_image_unref(src_img);
2076 pixman_image_unref(dst_img);
2078 return TBM_SURFACE_ERROR_NONE;
2082 pixman_image_unref(src_img);
2084 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2087 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2088 #define KEY_LEN 5 // "_XXXX"
2089 #define KEYS_LEN KEY_LEN * MAX_BOS
2091 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2093 char *keys, temp_key[KEY_LEN + 1];
2094 struct _tbm_surface *surf;
2098 _tbm_surface_mutex_lock();
2100 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2102 surf = (struct _tbm_surface *)surface;
2104 num_bos = surf->num_bos;
2105 if (num_bos > MAX_BOS)
2108 keys = calloc(KEYS_LEN + 1, sizeof(char));
2110 TBM_ERR("Failed to alloc memory");
2111 _tbm_surface_mutex_unlock();
2115 for (i = 0; i < num_bos; i++) {
2116 memset(temp_key, 0x00, KEY_LEN + 1);
2118 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2119 strncat(keys, temp_key, KEY_LEN + 1);
2122 _tbm_surface_mutex_unlock();
2127 static void _tbm_surface_internal_put_keys(char *keys)
2134 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2136 TBM_RETURN_IF_FAIL(surface != NULL);
2137 TBM_RETURN_IF_FAIL(type != NULL);
2139 tbm_surface_dump_buf_info *buf_info;
2140 struct list_head *next_link;
2141 tbm_surface_info_s info;
2142 tbm_bo_handle bo_handle;
2143 const char *postfix;
2144 const char *format = NULL;
2151 next_link = g_dump_info->link->next;
2152 TBM_RETURN_IF_FAIL(next_link != NULL);
2154 if (next_link == &g_dump_info->surface_list) {
2155 next_link = next_link->next;
2156 TBM_RETURN_IF_FAIL(next_link != NULL);
2159 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2160 TBM_RETURN_IF_FAIL(buf_info != NULL);
2162 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2163 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2165 if (scale_factor > 0.0) {
2168 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2169 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2170 _tbm_surface_internal_format_to_str(info.format));
2171 tbm_surface_unmap(surface);
2175 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2177 buf_info->info.width = info.width * scale_factor;
2178 buf_info->info.height = info.height * scale_factor;
2179 buf_info->info.format = info.format;
2180 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2181 if (!buf_info->info.bpp) {
2182 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2183 tbm_surface_unmap(surface);
2186 buf_info->info.num_planes = 1;
2187 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2188 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2190 if (buf_info->info.size > buf_info->size) {
2191 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2192 buf_info->info.size, buf_info->size);
2193 tbm_surface_unmap(surface);
2197 if (info.size > buf_info->size) {
2198 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2199 info.size, buf_info->size);
2200 tbm_surface_unmap(surface);
2204 /* make the file information */
2205 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2208 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2209 postfix = dump_postfix[0];
2210 format = _tbm_surface_internal_format_to_str(info.format);
2212 postfix = dump_postfix[1];
2214 keys = _tbm_surface_internal_get_keys(surface);
2216 TBM_ERR("fail to get keys");
2217 tbm_surface_unmap(surface);
2222 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2223 if (!bo_handle.ptr) {
2224 TBM_ERR("fail to map bo");
2225 _tbm_surface_internal_put_keys(keys);
2226 tbm_surface_unmap(surface);
2229 memset(bo_handle.ptr, 0x00, buf_info->size);
2231 switch (info.format) {
2232 case TBM_FORMAT_ARGB8888:
2233 case TBM_FORMAT_XRGB8888:
2234 snprintf(buf_info->name, sizeof(buf_info->name),
2235 "%10.3f_%03d%s_%p_%s-%s.%s",
2236 _tbm_surface_internal_get_time(),
2237 g_dump_info->count++, keys, surface, format, type, postfix);
2239 if (scale_factor > 0.0) {
2240 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2242 buf_info->info.format,
2243 info.planes[0].stride,
2244 info.width, info.height,
2245 buf_info->info.planes[0].stride,
2246 buf_info->info.width,
2247 buf_info->info.height);
2248 if (ret != TBM_SURFACE_ERROR_NONE) {
2249 TBM_ERR("fail to scale buffer");
2250 tbm_bo_unmap(buf_info->bo);
2251 _tbm_surface_internal_put_keys(keys);
2252 tbm_surface_unmap(surface);
2256 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2258 case TBM_FORMAT_YVU420:
2259 case TBM_FORMAT_YUV420:
2260 snprintf(buf_info->name, sizeof(buf_info->name),
2261 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2262 _tbm_surface_internal_get_time(),
2263 g_dump_info->count++, keys, type, info.planes[0].stride,
2264 info.height, FOURCC_STR(info.format), postfix);
2265 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2266 bo_handle.ptr += info.planes[0].stride * info.height;
2267 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2268 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2269 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2271 case TBM_FORMAT_NV12:
2272 case TBM_FORMAT_NV21:
2273 snprintf(buf_info->name, sizeof(buf_info->name),
2274 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2275 _tbm_surface_internal_get_time(),
2276 g_dump_info->count++, keys, type, info.planes[0].stride,
2277 info.height, FOURCC_STR(info.format), postfix);
2278 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2279 bo_handle.ptr += info.planes[0].stride * info.height;
2280 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2282 case TBM_FORMAT_YUYV:
2283 case TBM_FORMAT_UYVY:
2284 snprintf(buf_info->name, sizeof(buf_info->name),
2285 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2286 _tbm_surface_internal_get_time(),
2287 g_dump_info->count++, keys, type, info.planes[0].stride,
2288 info.height, FOURCC_STR(info.format), postfix);
2289 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2292 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2293 tbm_bo_unmap(buf_info->bo);
2294 _tbm_surface_internal_put_keys(keys);
2295 tbm_surface_unmap(surface);
2299 tbm_bo_unmap(buf_info->bo);
2301 _tbm_surface_internal_put_keys(keys);
2303 tbm_surface_unmap(surface);
2305 buf_info->dirty = 1;
2306 buf_info->dirty_shm = 0;
2308 if (g_dump_info->count == 1000)
2309 g_dump_info->count = 0;
2311 g_dump_info->link = next_link;
2313 TBM_INFO("Dump %s \n", buf_info->name);
2316 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2319 TBM_RETURN_IF_FAIL(ptr != NULL);
2320 TBM_RETURN_IF_FAIL(w > 0);
2321 TBM_RETURN_IF_FAIL(h > 0);
2322 TBM_RETURN_IF_FAIL(stride > 0);
2323 TBM_RETURN_IF_FAIL(type != NULL);
2325 tbm_surface_dump_buf_info *buf_info;
2326 struct list_head *next_link;
2327 tbm_bo_handle bo_handle;
2328 int ret, size, dw = 0, dh = 0, dstride = 0;
2333 next_link = g_dump_info->link->next;
2334 TBM_RETURN_IF_FAIL(next_link != NULL);
2336 if (next_link == &g_dump_info->surface_list) {
2337 next_link = next_link->next;
2338 TBM_RETURN_IF_FAIL(next_link != NULL);
2341 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2342 TBM_RETURN_IF_FAIL(buf_info != NULL);
2344 if (scale_factor > 0.0) {
2347 dw = w * scale_factor;
2348 dh = h * scale_factor;
2350 size = dstride * dh;
2354 if (size > buf_info->size) {
2355 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2356 size, buf_info->size);
2361 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2362 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2364 memset(bo_handle.ptr, 0x00, buf_info->size);
2365 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2367 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2368 _tbm_surface_internal_get_time(),
2369 g_dump_info->count++, type, dump_postfix[0]);
2370 if (scale_factor > 0.0) {
2371 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2372 TBM_FORMAT_ARGB8888, stride,
2373 w, h, dstride, dw, dh);
2374 if (ret != TBM_SURFACE_ERROR_NONE) {
2375 TBM_ERR("fail to scale buffer");
2376 tbm_bo_unmap(buf_info->bo);
2379 buf_info->shm_stride = dstride;
2380 buf_info->shm_h = dh;
2382 memcpy(bo_handle.ptr, ptr, size);
2383 buf_info->shm_stride = stride;
2384 buf_info->shm_h = h;
2387 tbm_bo_unmap(buf_info->bo);
2389 buf_info->dirty = 0;
2390 buf_info->dirty_shm = 1;
2392 if (g_dump_info->count == 1000)
2393 g_dump_info->count = 0;
2395 g_dump_info->link = next_link;
2397 TBM_INFO("Dump %s \n", buf_info->name);
2401 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2403 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2404 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2405 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2407 tbm_surface_info_s info;
2408 const char *postfix;
2412 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2413 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2415 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2416 postfix = dump_postfix[0];
2418 postfix = dump_postfix[1];
2420 if (strcmp(postfix, type)) {
2421 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2422 tbm_surface_unmap(surface);
2426 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2428 if (!access(file, 0)) {
2429 TBM_ERR("can't capture buffer, exist file %s", file);
2430 tbm_surface_unmap(surface);
2434 switch (info.format) {
2435 case TBM_FORMAT_ARGB8888:
2436 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2439 info.planes[0].stride,
2440 TBM_FORMAT_ARGB8888);
2442 case TBM_FORMAT_XRGB8888:
2443 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2446 info.planes[0].stride,
2447 TBM_FORMAT_XRGB8888);
2449 case TBM_FORMAT_YVU420:
2450 case TBM_FORMAT_YUV420:
2451 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2452 info.planes[0].stride * info.height,
2454 info.planes[1].stride * (info.height >> 1),
2456 info.planes[2].stride * (info.height >> 1));
2458 case TBM_FORMAT_NV12:
2459 case TBM_FORMAT_NV21:
2460 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2461 info.planes[0].stride * info.height,
2463 info.planes[1].stride * (info.height >> 1),
2466 case TBM_FORMAT_YUYV:
2467 case TBM_FORMAT_UYVY:
2468 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2469 info.planes[0].stride * info.height,
2473 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2474 tbm_surface_unmap(surface);
2478 tbm_surface_unmap(surface);
2480 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2486 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2487 const char *path, const char *name, const char *type)
2489 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2490 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2491 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2492 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2493 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2494 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2498 if (strcmp(dump_postfix[0], type)) {
2499 TBM_ERR("Not supported type:%s'", type);
2503 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2505 if (!access(file, 0)) {
2506 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2510 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2512 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2518 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2520 struct _tbm_surface *surf;
2522 _tbm_surface_mutex_lock();
2523 _tbm_set_last_result(TBM_ERROR_NONE);
2525 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2526 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2527 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2529 surf = (struct _tbm_surface *)surface;
2533 surf->damage.width = width;
2534 surf->damage.height = height;
2536 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2537 surface, x, y, width, height);
2539 _tbm_surface_mutex_unlock();
2545 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2547 struct _tbm_surface *surf;
2549 _tbm_surface_mutex_lock();
2550 _tbm_set_last_result(TBM_ERROR_NONE);
2552 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2554 surf = (struct _tbm_surface *)surface;
2556 if (x) *x = surf->damage.x;
2557 if (y) *y = surf->damage.y;
2558 if (width) *width = surf->damage.width;
2559 if (height) *height = surf->damage.height;
2561 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2562 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2564 _tbm_surface_mutex_unlock();