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_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1553 if (!debug_data->value && !value)
1556 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1559 if (debug_data->value)
1560 free(debug_data->value);
1563 debug_data->value = strdup(value);
1565 debug_data->value = NULL;
1568 static tbm_surface_debug_data *
1569 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1571 tbm_surface_debug_data *debug_data = NULL;
1573 if (LIST_IS_EMPTY(list))
1576 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1577 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1585 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1587 tbm_surface_debug_data *debug_data = NULL;
1588 tbm_bufmgr bufmgr = NULL;
1590 _tbm_surface_mutex_lock();
1591 _tbm_set_last_result(TBM_ERROR_NONE);
1593 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1594 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1596 bufmgr = surface->bufmgr;
1598 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1600 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1602 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1604 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1606 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1607 _tbm_surface_mutex_unlock();
1611 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1614 /* add new debug key to list */
1615 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1617 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1619 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1622 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1624 _tbm_surface_mutex_unlock();
1630 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1632 tbm_surface_debug_data *old_data = NULL;
1634 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1636 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1637 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1638 if (!strcmp(old_data->key, key))
1639 return old_data->value;
1646 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1647 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1649 struct _tbm_surface_dump_buf_info {
1659 tbm_surface_info_s info;
1661 struct list_head link;
1664 struct _tbm_surface_dump_info {
1665 char *path; // copy???
1668 struct list_head *link;
1669 struct list_head surface_list; /* link of surface */
1672 static tbm_surface_dump_info *g_dump_info = NULL;
1673 static const char *dump_postfix[2] = {"png", "yuv"};
1674 static double scale_factor;
1677 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1678 void *data2, int size2, void *data3, int size3)
1681 unsigned int *blocks;
1683 if (_tbm_surface_check_file_is_symbolic_link(file))
1684 TBM_ERR("%s is symbolic link\n", file);
1686 fp = fopen(file, "w+");
1687 TBM_RETURN_IF_FAIL(fp != NULL);
1689 blocks = (unsigned int *)data1;
1690 fwrite(blocks, 1, size1, fp);
1693 blocks = (unsigned int *)data2;
1694 fwrite(blocks, 1, size2, fp);
1698 blocks = (unsigned int *)data3;
1699 fwrite(blocks, 1, size3, fp);
1706 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1708 unsigned int *blocks = (unsigned int *)data;
1711 png_bytep *row_pointers;
1714 if (_tbm_surface_check_file_is_symbolic_link(file))
1715 TBM_ERR("%s is symbolic link\n", file);
1717 fp = fopen(file, "wb");
1718 TBM_RETURN_IF_FAIL(fp != NULL);
1720 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1723 TBM_ERR("fail to create a png write structure.\n");
1728 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1730 TBM_ERR("fail to create a png info structure.\n");
1731 png_destroy_write_struct(&pPngStruct, NULL);
1736 if (setjmp(png_jmpbuf(pPngStruct))) {
1737 /* if png has problem of writing the file, we get here */
1738 TBM_ERR("fail to write png file.\n");
1739 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1744 png_init_io(pPngStruct, fp);
1745 if (format == TBM_FORMAT_XRGB8888) {
1747 png_set_IHDR(pPngStruct,
1754 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1757 png_set_IHDR(pPngStruct,
1762 PNG_COLOR_TYPE_RGBA,
1764 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1767 png_set_bgr(pPngStruct);
1768 png_write_info(pPngStruct, pPngInfo);
1770 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1771 if (!row_pointers) {
1772 TBM_ERR("fail to allocate the png row_pointers.\n");
1773 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1778 for (y = 0; y < height; ++y) {
1782 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1784 TBM_ERR("fail to allocate the png row.\n");
1785 for (x = 0; x < y; x++)
1786 png_free(pPngStruct, row_pointers[x]);
1787 png_free(pPngStruct, row_pointers);
1788 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1792 row_pointers[y] = (png_bytep)row;
1794 for (x = 0; x < width; ++x) {
1795 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1797 if (pixel_size == 3) { // XRGB8888
1798 row[x * pixel_size] = (curBlock & 0xFF);
1799 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1800 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1801 } else { // ARGB8888
1802 row[x * pixel_size] = (curBlock & 0xFF);
1803 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1804 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1805 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1810 png_write_image(pPngStruct, row_pointers);
1811 png_write_end(pPngStruct, pPngInfo);
1813 for (y = 0; y < height; y++)
1814 png_free(pPngStruct, row_pointers[y]);
1815 png_free(pPngStruct, row_pointers);
1817 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1823 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1825 TBM_RETURN_IF_FAIL(path != NULL);
1826 TBM_RETURN_IF_FAIL(w > 0);
1827 TBM_RETURN_IF_FAIL(h > 0);
1828 TBM_RETURN_IF_FAIL(count > 0);
1830 tbm_surface_dump_buf_info *buf_info = NULL;
1831 tbm_surface_h tbm_surface;
1832 tbm_surface_info_s info;
1837 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1841 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1842 TBM_RETURN_IF_FAIL(g_dump_info);
1844 LIST_INITHEAD(&g_dump_info->surface_list);
1845 g_dump_info->count = 0;
1846 g_dump_info->dump_max = count;
1848 /* get buffer size */
1849 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1850 if (tbm_surface == NULL) {
1851 TBM_ERR("tbm_surface_create fail\n");
1857 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1858 TBM_ERR("tbm_surface_get_info fail\n");
1859 tbm_surface_destroy(tbm_surface);
1864 buffer_size = info.size;
1865 tbm_surface_destroy(tbm_surface);
1867 /* create dump lists */
1868 for (i = 0; i < count; i++) {
1871 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1872 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1874 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1876 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1881 buf_info->index = i;
1883 buf_info->size = buffer_size;
1885 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1888 g_dump_info->path = path;
1889 g_dump_info->link = &g_dump_info->surface_list;
1893 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1898 /* free resources */
1899 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1900 tbm_surface_dump_buf_info *tmp;
1902 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1903 tbm_bo_unref(buf_info->bo);
1904 LIST_DEL(&buf_info->link);
1909 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1918 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1925 tbm_surface_internal_dump_start(path, w, h, count);
1926 scale_factor = scale;
1930 tbm_surface_internal_dump_end(void)
1932 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1933 tbm_bo_handle bo_handle;
1938 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1945 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1948 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1949 if (bo_handle.ptr == NULL) {
1950 tbm_bo_unref(buf_info->bo);
1951 LIST_DEL(&buf_info->link);
1956 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1957 TBM_INFO("Dump File.. %s generated.\n", file);
1959 if (buf_info->dirty) {
1960 void *ptr1 = NULL, *ptr2 = NULL;
1962 switch (buf_info->info.format) {
1963 case TBM_FORMAT_ARGB8888:
1964 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1965 buf_info->info.planes[0].stride >> 2,
1966 buf_info->info.height,
1967 buf_info->info.planes[0].stride,
1968 TBM_FORMAT_ARGB8888);
1970 case TBM_FORMAT_XRGB8888:
1971 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1972 buf_info->info.planes[0].stride >> 2,
1973 buf_info->info.height,
1974 buf_info->info.planes[0].stride,
1975 TBM_FORMAT_XRGB8888);
1977 case TBM_FORMAT_YVU420:
1978 case TBM_FORMAT_YUV420:
1979 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1980 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
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),
1986 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1988 case TBM_FORMAT_NV12:
1989 case TBM_FORMAT_NV21:
1990 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1991 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1992 buf_info->info.planes[0].stride * buf_info->info.height,
1994 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1997 case TBM_FORMAT_YUYV:
1998 case TBM_FORMAT_UYVY:
1999 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2000 buf_info->info.planes[0].stride * buf_info->info.height,
2004 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2007 } else if (buf_info->dirty_shm)
2008 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2009 buf_info->shm_stride >> 2,
2011 buf_info->shm_stride, 0);
2013 tbm_bo_unmap(buf_info->bo);
2014 tbm_bo_unref(buf_info->bo);
2015 LIST_DEL(&buf_info->link);
2022 TBM_INFO("Dump End..\n");
2025 static pixman_format_code_t
2026 _tbm_surface_internal_pixman_format_get(tbm_format format)
2029 case TBM_FORMAT_ARGB8888:
2030 return PIXMAN_a8r8g8b8;
2031 case TBM_FORMAT_XRGB8888:
2032 return PIXMAN_x8r8g8b8;
2041 * This function supports only if a buffer has below formats.
2042 * - TBM_FORMAT_ARGB8888
2043 * - TBM_FORMAT_XRGB8888
2045 static tbm_surface_error_e
2046 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2047 int format, int src_stride, int src_w, int src_h,
2048 int dst_stride, int dst_w, int dst_h)
2050 pixman_image_t *src_img = NULL, *dst_img = NULL;
2051 pixman_format_code_t pixman_format;
2052 pixman_transform_t t;
2053 struct pixman_f_transform ft;
2054 double scale_x, scale_y;
2056 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2057 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2059 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2060 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2063 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2064 (uint32_t*)src_ptr, src_stride);
2065 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2068 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2069 (uint32_t*)dst_ptr, dst_stride);
2070 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2072 pixman_f_transform_init_identity(&ft);
2074 scale_x = (double)src_w / dst_w;
2075 scale_y = (double)src_h / dst_h;
2077 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2078 pixman_f_transform_translate(&ft, NULL, 0, 0);
2079 pixman_transform_from_pixman_f_transform(&t, &ft);
2080 pixman_image_set_transform(src_img, &t);
2082 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2083 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2085 pixman_image_unref(src_img);
2086 pixman_image_unref(dst_img);
2088 return TBM_SURFACE_ERROR_NONE;
2092 pixman_image_unref(src_img);
2094 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2097 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2098 #define KEY_LEN 5 // "_XXXX"
2099 #define KEYS_LEN KEY_LEN * MAX_BOS
2101 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2103 char *keys, temp_key[KEY_LEN + 1];
2104 struct _tbm_surface *surf;
2108 _tbm_surface_mutex_lock();
2110 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2112 surf = (struct _tbm_surface *)surface;
2114 num_bos = surf->num_bos;
2115 if (num_bos > MAX_BOS)
2118 keys = calloc(KEYS_LEN + 1, sizeof(char));
2120 TBM_ERR("Failed to alloc memory");
2121 _tbm_surface_mutex_unlock();
2125 for (i = 0; i < num_bos; i++) {
2126 memset(temp_key, 0x00, KEY_LEN + 1);
2128 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2129 strncat(keys, temp_key, KEY_LEN + 1);
2132 _tbm_surface_mutex_unlock();
2137 static void _tbm_surface_internal_put_keys(char *keys)
2144 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2146 TBM_RETURN_IF_FAIL(surface != NULL);
2147 TBM_RETURN_IF_FAIL(type != NULL);
2149 tbm_surface_dump_buf_info *buf_info;
2150 struct list_head *next_link;
2151 tbm_surface_info_s info;
2152 tbm_bo_handle bo_handle;
2153 const char *postfix;
2154 const char *format = NULL;
2161 next_link = g_dump_info->link->next;
2162 TBM_RETURN_IF_FAIL(next_link != NULL);
2164 if (next_link == &g_dump_info->surface_list) {
2165 next_link = next_link->next;
2166 TBM_RETURN_IF_FAIL(next_link != NULL);
2169 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2170 TBM_RETURN_IF_FAIL(buf_info != NULL);
2172 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2173 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2175 if (scale_factor > 0.0) {
2178 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2179 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2180 _tbm_surface_internal_format_to_str(info.format));
2181 tbm_surface_unmap(surface);
2185 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2187 buf_info->info.width = info.width * scale_factor;
2188 buf_info->info.height = info.height * scale_factor;
2189 buf_info->info.format = info.format;
2190 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2191 if (!buf_info->info.bpp) {
2192 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2193 tbm_surface_unmap(surface);
2196 buf_info->info.num_planes = 1;
2197 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2198 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2200 if (buf_info->info.size > buf_info->size) {
2201 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2202 buf_info->info.size, buf_info->size);
2203 tbm_surface_unmap(surface);
2207 if (info.size > buf_info->size) {
2208 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2209 info.size, buf_info->size);
2210 tbm_surface_unmap(surface);
2214 /* make the file information */
2215 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2218 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2219 postfix = dump_postfix[0];
2220 format = _tbm_surface_internal_format_to_str(info.format);
2222 postfix = dump_postfix[1];
2224 keys = _tbm_surface_internal_get_keys(surface);
2226 TBM_ERR("fail to get keys");
2227 tbm_surface_unmap(surface);
2232 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2233 if (!bo_handle.ptr) {
2234 TBM_ERR("fail to map bo");
2235 _tbm_surface_internal_put_keys(keys);
2236 tbm_surface_unmap(surface);
2239 memset(bo_handle.ptr, 0x00, buf_info->size);
2241 switch (info.format) {
2242 case TBM_FORMAT_ARGB8888:
2243 case TBM_FORMAT_XRGB8888:
2244 snprintf(buf_info->name, sizeof(buf_info->name),
2245 "%10.3f_%03d%s_%p_%s-%s.%s",
2246 _tbm_surface_internal_get_time(),
2247 g_dump_info->count++, keys, surface, format, type, postfix);
2249 if (scale_factor > 0.0) {
2250 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2252 buf_info->info.format,
2253 info.planes[0].stride,
2254 info.width, info.height,
2255 buf_info->info.planes[0].stride,
2256 buf_info->info.width,
2257 buf_info->info.height);
2258 if (ret != TBM_SURFACE_ERROR_NONE) {
2259 TBM_ERR("fail to scale buffer");
2260 tbm_bo_unmap(buf_info->bo);
2261 _tbm_surface_internal_put_keys(keys);
2262 tbm_surface_unmap(surface);
2266 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2268 case TBM_FORMAT_YVU420:
2269 case TBM_FORMAT_YUV420:
2270 snprintf(buf_info->name, sizeof(buf_info->name),
2271 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2272 _tbm_surface_internal_get_time(),
2273 g_dump_info->count++, keys, type, info.planes[0].stride,
2274 info.height, FOURCC_STR(info.format), postfix);
2275 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2276 bo_handle.ptr += info.planes[0].stride * info.height;
2277 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2278 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2279 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2281 case TBM_FORMAT_NV12:
2282 case TBM_FORMAT_NV21:
2283 snprintf(buf_info->name, sizeof(buf_info->name),
2284 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2285 _tbm_surface_internal_get_time(),
2286 g_dump_info->count++, keys, type, info.planes[0].stride,
2287 info.height, FOURCC_STR(info.format), postfix);
2288 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2289 bo_handle.ptr += info.planes[0].stride * info.height;
2290 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2292 case TBM_FORMAT_YUYV:
2293 case TBM_FORMAT_UYVY:
2294 snprintf(buf_info->name, sizeof(buf_info->name),
2295 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2296 _tbm_surface_internal_get_time(),
2297 g_dump_info->count++, keys, type, info.planes[0].stride,
2298 info.height, FOURCC_STR(info.format), postfix);
2299 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2302 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2303 tbm_bo_unmap(buf_info->bo);
2304 _tbm_surface_internal_put_keys(keys);
2305 tbm_surface_unmap(surface);
2309 tbm_bo_unmap(buf_info->bo);
2311 _tbm_surface_internal_put_keys(keys);
2313 tbm_surface_unmap(surface);
2315 buf_info->dirty = 1;
2316 buf_info->dirty_shm = 0;
2318 if (g_dump_info->count == 1000)
2319 g_dump_info->count = 0;
2321 g_dump_info->link = next_link;
2323 TBM_INFO("Dump %s \n", buf_info->name);
2326 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2329 TBM_RETURN_IF_FAIL(ptr != NULL);
2330 TBM_RETURN_IF_FAIL(w > 0);
2331 TBM_RETURN_IF_FAIL(h > 0);
2332 TBM_RETURN_IF_FAIL(stride > 0);
2333 TBM_RETURN_IF_FAIL(type != NULL);
2335 tbm_surface_dump_buf_info *buf_info;
2336 struct list_head *next_link;
2337 tbm_bo_handle bo_handle;
2338 int ret, size, dw = 0, dh = 0, dstride = 0;
2343 next_link = g_dump_info->link->next;
2344 TBM_RETURN_IF_FAIL(next_link != NULL);
2346 if (next_link == &g_dump_info->surface_list) {
2347 next_link = next_link->next;
2348 TBM_RETURN_IF_FAIL(next_link != NULL);
2351 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2352 TBM_RETURN_IF_FAIL(buf_info != NULL);
2354 if (scale_factor > 0.0) {
2357 dw = w * scale_factor;
2358 dh = h * scale_factor;
2360 size = dstride * dh;
2364 if (size > buf_info->size) {
2365 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2366 size, buf_info->size);
2371 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2372 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2374 memset(bo_handle.ptr, 0x00, buf_info->size);
2375 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2377 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2378 _tbm_surface_internal_get_time(),
2379 g_dump_info->count++, type, dump_postfix[0]);
2380 if (scale_factor > 0.0) {
2381 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2382 TBM_FORMAT_ARGB8888, stride,
2383 w, h, dstride, dw, dh);
2384 if (ret != TBM_SURFACE_ERROR_NONE) {
2385 TBM_ERR("fail to scale buffer");
2386 tbm_bo_unmap(buf_info->bo);
2389 buf_info->shm_stride = dstride;
2390 buf_info->shm_h = dh;
2392 memcpy(bo_handle.ptr, ptr, size);
2393 buf_info->shm_stride = stride;
2394 buf_info->shm_h = h;
2397 tbm_bo_unmap(buf_info->bo);
2399 buf_info->dirty = 0;
2400 buf_info->dirty_shm = 1;
2402 if (g_dump_info->count == 1000)
2403 g_dump_info->count = 0;
2405 g_dump_info->link = next_link;
2407 TBM_INFO("Dump %s \n", buf_info->name);
2411 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2413 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2414 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2415 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2417 tbm_surface_info_s info;
2418 const char *postfix;
2422 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2423 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2425 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2426 postfix = dump_postfix[0];
2428 postfix = dump_postfix[1];
2430 if (strcmp(postfix, type)) {
2431 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2432 tbm_surface_unmap(surface);
2436 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2438 if (!access(file, 0)) {
2439 TBM_ERR("can't capture buffer, exist file %s", file);
2440 tbm_surface_unmap(surface);
2444 switch (info.format) {
2445 case TBM_FORMAT_ARGB8888:
2446 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2449 info.planes[0].stride,
2450 TBM_FORMAT_ARGB8888);
2452 case TBM_FORMAT_XRGB8888:
2453 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2456 info.planes[0].stride,
2457 TBM_FORMAT_XRGB8888);
2459 case TBM_FORMAT_YVU420:
2460 case TBM_FORMAT_YUV420:
2461 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2462 info.planes[0].stride * info.height,
2464 info.planes[1].stride * (info.height >> 1),
2466 info.planes[2].stride * (info.height >> 1));
2468 case TBM_FORMAT_NV12:
2469 case TBM_FORMAT_NV21:
2470 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2471 info.planes[0].stride * info.height,
2473 info.planes[1].stride * (info.height >> 1),
2476 case TBM_FORMAT_YUYV:
2477 case TBM_FORMAT_UYVY:
2478 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2479 info.planes[0].stride * info.height,
2483 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2484 tbm_surface_unmap(surface);
2488 tbm_surface_unmap(surface);
2490 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2496 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2497 const char *path, const char *name, const char *type)
2499 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2500 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2501 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2502 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2503 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2504 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2508 if (strcmp(dump_postfix[0], type)) {
2509 TBM_ERR("Not supported type:%s'", type);
2513 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2515 if (!access(file, 0)) {
2516 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2520 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2522 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2528 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2530 struct _tbm_surface *surf;
2532 _tbm_surface_mutex_lock();
2533 _tbm_set_last_result(TBM_ERROR_NONE);
2535 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2536 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2537 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2539 surf = (struct _tbm_surface *)surface;
2543 surf->damage.width = width;
2544 surf->damage.height = height;
2546 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2547 surface, x, y, width, height);
2549 _tbm_surface_mutex_unlock();
2555 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2557 struct _tbm_surface *surf;
2559 _tbm_surface_mutex_lock();
2560 _tbm_set_last_result(TBM_ERROR_NONE);
2562 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2564 surf = (struct _tbm_surface *)surface;
2566 if (x) *x = surf->damage.x;
2567 if (y) *y = surf->damage.y;
2568 if (width) *width = surf->damage.width;
2569 if (height) *height = surf->damage.height;
2571 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2572 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2574 _tbm_surface_mutex_unlock();