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 static tbm_bufmgr g_surface_bufmgr;
45 static pthread_mutex_t tbm_surface_lock = PTHREAD_MUTEX_INITIALIZER;
46 void _tbm_surface_mutex_unlock(void);
48 #define C(b, m) (((b) >> (m)) & 0xFF)
49 #define B(c, s) ((((unsigned int)(c)) & 0xff) << (s))
50 #define FOURCC(a, b, c, d) (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
51 #define FOURCC_STR(id) C(id, 0), C(id, 8), C(id, 16), C(id, 24)
52 #define FOURCC_ID(str) FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
55 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
57 TBM_ERR("'%s' failed.\n", #cond);\
58 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
59 _tbm_surface_mutex_unlock();\
64 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
66 TBM_ERR("'%s' failed.\n", #cond);\
67 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
68 _tbm_surface_mutex_unlock();\
75 _tbm_surface_internal_get_time(void)
80 clock_gettime(CLOCK_MONOTONIC, &tp);
81 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
87 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
89 LIST_DEL(&debug_data->item_link);
91 if (debug_data->key) free(debug_data->key);
92 if (debug_data->value) free(debug_data->value);
97 _tbm_surface_internal_format_to_str(tbm_format format)
101 return "TBM_FORMAT_C8";
102 case TBM_FORMAT_RGB332:
103 return "TBM_FORMAT_RGB332";
104 case TBM_FORMAT_BGR233:
105 return "TBM_FORMAT_BGR233";
106 case TBM_FORMAT_XRGB4444:
107 return "TBM_FORMAT_XRGB4444";
108 case TBM_FORMAT_XBGR4444:
109 return "TBM_FORMAT_XBGR4444";
110 case TBM_FORMAT_RGBX4444:
111 return "TBM_FORMAT_RGBX4444";
112 case TBM_FORMAT_BGRX4444:
113 return "TBM_FORMAT_BGRX4444";
114 case TBM_FORMAT_ARGB4444:
115 return "TBM_FORMAT_ARGB4444";
116 case TBM_FORMAT_ABGR4444:
117 return "TBM_FORMAT_ABGR4444";
118 case TBM_FORMAT_RGBA4444:
119 return "TBM_FORMAT_RGBA4444";
120 case TBM_FORMAT_BGRA4444:
121 return "TBM_FORMAT_BGRA4444";
122 case TBM_FORMAT_XRGB1555:
123 return "TBM_FORMAT_XRGB1555";
124 case TBM_FORMAT_XBGR1555:
125 return "TBM_FORMAT_XBGR1555";
126 case TBM_FORMAT_RGBX5551:
127 return "TBM_FORMAT_RGBX5551";
128 case TBM_FORMAT_BGRX5551:
129 return "TBM_FORMAT_BGRX5551";
130 case TBM_FORMAT_ARGB1555:
131 return "TBM_FORMAT_ARGB1555";
132 case TBM_FORMAT_ABGR1555:
133 return "TBM_FORMAT_ABGR1555";
134 case TBM_FORMAT_RGBA5551:
135 return "TBM_FORMAT_RGBA5551";
136 case TBM_FORMAT_BGRA5551:
137 return "TBM_FORMAT_BGRA5551";
138 case TBM_FORMAT_RGB565:
139 return "TBM_FORMAT_RGB565";
140 case TBM_FORMAT_BGR565:
141 return "TBM_FORMAT_BGR565";
142 case TBM_FORMAT_RGB888:
143 return "TBM_FORMAT_RGB888";
144 case TBM_FORMAT_BGR888:
145 return "TBM_FORMAT_BGR888";
146 case TBM_FORMAT_XRGB8888:
147 return "TBM_FORMAT_XRGB8888";
148 case TBM_FORMAT_XBGR8888:
149 return "TBM_FORMAT_XBGR8888";
150 case TBM_FORMAT_RGBX8888:
151 return "TBM_FORMAT_RGBX8888";
152 case TBM_FORMAT_BGRX8888:
153 return "TBM_FORMAT_BGRX8888";
154 case TBM_FORMAT_ARGB8888:
155 return "TBM_FORMAT_ARGB8888";
156 case TBM_FORMAT_ABGR8888:
157 return "TBM_FORMAT_ABGR8888";
158 case TBM_FORMAT_RGBA8888:
159 return "TBM_FORMAT_RGBA8888";
160 case TBM_FORMAT_BGRA8888:
161 return "TBM_FORMAT_BGRA8888";
162 case TBM_FORMAT_XRGB2101010:
163 return "TBM_FORMAT_XRGB2101010";
164 case TBM_FORMAT_XBGR2101010:
165 return "TBM_FORMAT_XBGR2101010";
166 case TBM_FORMAT_RGBX1010102:
167 return "TBM_FORMAT_RGBX1010102";
168 case TBM_FORMAT_BGRX1010102:
169 return "TBM_FORMAT_BGRX1010102";
170 case TBM_FORMAT_ARGB2101010:
171 return "TBM_FORMAT_ARGB2101010";
172 case TBM_FORMAT_ABGR2101010:
173 return "TBM_FORMAT_ABGR2101010";
174 case TBM_FORMAT_RGBA1010102:
175 return "TBM_FORMAT_RGBA1010102";
176 case TBM_FORMAT_BGRA1010102:
177 return "TBM_FORMAT_BGRA1010102";
178 case TBM_FORMAT_YUYV:
179 return "TBM_FORMAT_YUYV";
180 case TBM_FORMAT_YVYU:
181 return "TBM_FORMAT_YVYU";
182 case TBM_FORMAT_UYVY:
183 return "TBM_FORMAT_UYVY";
184 case TBM_FORMAT_VYUY:
185 return "TBM_FORMAT_VYUY";
186 case TBM_FORMAT_AYUV:
187 return "TBM_FORMAT_AYUV";
188 case TBM_FORMAT_NV12:
189 return "TBM_FORMAT_NV12";
190 case TBM_FORMAT_NV21:
191 return "TBM_FORMAT_NV21";
192 case TBM_FORMAT_NV16:
193 return "TBM_FORMAT_NV16";
194 case TBM_FORMAT_NV61:
195 return "TBM_FORMAT_NV61";
196 case TBM_FORMAT_YUV410:
197 return "TBM_FORMAT_YUV410";
198 case TBM_FORMAT_YVU410:
199 return "TBM_FORMAT_YVU410";
200 case TBM_FORMAT_YUV411:
201 return "TBM_FORMAT_YUV411";
202 case TBM_FORMAT_YVU411:
203 return "TBM_FORMAT_YVU411";
204 case TBM_FORMAT_YUV420:
205 return "TBM_FORMAT_YUV420";
206 case TBM_FORMAT_YVU420:
207 return "TBM_FORMAT_YVU420";
208 case TBM_FORMAT_YUV422:
209 return "TBM_FORMAT_YUV422";
210 case TBM_FORMAT_YVU422:
211 return "TBM_FORMAT_YVU422";
212 case TBM_FORMAT_YUV444:
213 return "TBM_FORMAT_YUV444";
214 case TBM_FORMAT_YVU444:
215 return "TBM_FORMAT_YVU444";
216 case TBM_FORMAT_NV12MT:
217 return "TBM_FORMAT_NV12MT";
224 _tbm_surface_mutex_lock(void)
226 pthread_mutex_lock(&tbm_surface_lock);
230 _tbm_surface_mutex_unlock(void)
232 pthread_mutex_unlock(&tbm_surface_lock);
236 _init_surface_bufmgr(void)
238 g_surface_bufmgr = tbm_bufmgr_init(-1);
242 _deinit_surface_bufmgr(void)
244 if (!g_surface_bufmgr)
247 tbm_bufmgr_deinit(g_surface_bufmgr);
248 g_surface_bufmgr = NULL;
253 _tbm_surface_internal_is_valid(tbm_surface_h surface)
255 tbm_surface_h old_data = NULL;
257 TBM_RETURN_VAL_IF_FAIL(g_surface_bufmgr, 0);
258 TBM_RETURN_VAL_IF_FAIL(surface, 0);
260 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
261 LIST_FOR_EACH_ENTRY(old_data, &g_surface_bufmgr->surf_list, item_link) {
262 if (old_data == surface)
267 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
269 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
275 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
276 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
278 TBM_RETURN_VAL_IF_FAIL(surface, 0);
279 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
281 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
282 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
286 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
287 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
288 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
289 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
291 if (bufmgr->backend_module_data) {
292 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
293 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
297 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
298 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
299 if (error != TBM_ERROR_NONE) {
300 /* LCOV_EXCL_START */
301 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
302 _tbm_set_last_result(error);
308 if (!bufmgr->backend->surface_get_plane_data) {
309 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
313 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
314 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
316 /* LCOV_EXCL_START */
317 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
318 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
328 _tbm_surface_internal_destroy(tbm_surface_h surface)
331 tbm_bufmgr bufmgr = surface->bufmgr;
332 tbm_user_data *old_data = NULL, *tmp = NULL;
333 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
335 /* destory the user_data_list */
336 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
337 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
338 TBM_DBG("free user_data\n");
339 user_data_delete(old_data);
343 for (i = 0; i < surface->num_bos; i++) {
344 surface->bos[i]->surface = NULL;
346 tbm_bo_unref(surface->bos[i]);
347 surface->bos[i] = NULL;
350 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
351 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
352 _tbm_surface_internal_debug_data_delete(debug_old_data);
355 LIST_DEL(&surface->item_link);
360 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
361 LIST_DELINIT(&bufmgr->surf_list);
363 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
364 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
365 _tbm_surface_internal_debug_data_delete(debug_old_data);
369 _deinit_surface_bufmgr();
373 /* LCOV_EXCL_START */
375 _tbm_surface_check_file_is_symbolic_link(const char* path)
382 if (stat(path, &sb) != 0)
385 if (S_ISLNK(sb.st_mode))
393 _tbm_surface_internal_get_num_planes(tbm_format format)
399 case TBM_FORMAT_RGB332:
400 case TBM_FORMAT_BGR233:
401 case TBM_FORMAT_XRGB4444:
402 case TBM_FORMAT_XBGR4444:
403 case TBM_FORMAT_RGBX4444:
404 case TBM_FORMAT_BGRX4444:
405 case TBM_FORMAT_ARGB4444:
406 case TBM_FORMAT_ABGR4444:
407 case TBM_FORMAT_RGBA4444:
408 case TBM_FORMAT_BGRA4444:
409 case TBM_FORMAT_XRGB1555:
410 case TBM_FORMAT_XBGR1555:
411 case TBM_FORMAT_RGBX5551:
412 case TBM_FORMAT_BGRX5551:
413 case TBM_FORMAT_ARGB1555:
414 case TBM_FORMAT_ABGR1555:
415 case TBM_FORMAT_RGBA5551:
416 case TBM_FORMAT_BGRA5551:
417 case TBM_FORMAT_RGB565:
418 case TBM_FORMAT_BGR565:
419 case TBM_FORMAT_RGB888:
420 case TBM_FORMAT_BGR888:
421 case TBM_FORMAT_XRGB8888:
422 case TBM_FORMAT_XBGR8888:
423 case TBM_FORMAT_RGBX8888:
424 case TBM_FORMAT_BGRX8888:
425 case TBM_FORMAT_ARGB8888:
426 case TBM_FORMAT_ABGR8888:
427 case TBM_FORMAT_RGBA8888:
428 case TBM_FORMAT_BGRA8888:
429 case TBM_FORMAT_XRGB2101010:
430 case TBM_FORMAT_XBGR2101010:
431 case TBM_FORMAT_RGBX1010102:
432 case TBM_FORMAT_BGRX1010102:
433 case TBM_FORMAT_ARGB2101010:
434 case TBM_FORMAT_ABGR2101010:
435 case TBM_FORMAT_RGBA1010102:
436 case TBM_FORMAT_BGRA1010102:
437 case TBM_FORMAT_YUYV:
438 case TBM_FORMAT_YVYU:
439 case TBM_FORMAT_UYVY:
440 case TBM_FORMAT_VYUY:
441 case TBM_FORMAT_AYUV:
444 case TBM_FORMAT_NV12:
445 case TBM_FORMAT_NV12MT:
446 case TBM_FORMAT_NV21:
447 case TBM_FORMAT_NV16:
448 case TBM_FORMAT_NV61:
451 case TBM_FORMAT_YUV410:
452 case TBM_FORMAT_YVU410:
453 case TBM_FORMAT_YUV411:
454 case TBM_FORMAT_YVU411:
455 case TBM_FORMAT_YUV420:
456 case TBM_FORMAT_YVU420:
457 case TBM_FORMAT_YUV422:
458 case TBM_FORMAT_YVU422:
459 case TBM_FORMAT_YUV444:
460 case TBM_FORMAT_YVU444:
465 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
473 _tbm_surface_internal_get_bpp(tbm_format format)
480 case TBM_FORMAT_RGB332:
481 case TBM_FORMAT_BGR233:
484 case TBM_FORMAT_XRGB4444:
485 case TBM_FORMAT_XBGR4444:
486 case TBM_FORMAT_RGBX4444:
487 case TBM_FORMAT_BGRX4444:
488 case TBM_FORMAT_ARGB4444:
489 case TBM_FORMAT_ABGR4444:
490 case TBM_FORMAT_RGBA4444:
491 case TBM_FORMAT_BGRA4444:
492 case TBM_FORMAT_XRGB1555:
493 case TBM_FORMAT_XBGR1555:
494 case TBM_FORMAT_RGBX5551:
495 case TBM_FORMAT_BGRX5551:
496 case TBM_FORMAT_ARGB1555:
497 case TBM_FORMAT_ABGR1555:
498 case TBM_FORMAT_RGBA5551:
499 case TBM_FORMAT_BGRA5551:
500 case TBM_FORMAT_RGB565:
501 case TBM_FORMAT_BGR565:
504 case TBM_FORMAT_RGB888:
505 case TBM_FORMAT_BGR888:
508 case TBM_FORMAT_XRGB8888:
509 case TBM_FORMAT_XBGR8888:
510 case TBM_FORMAT_RGBX8888:
511 case TBM_FORMAT_BGRX8888:
512 case TBM_FORMAT_ARGB8888:
513 case TBM_FORMAT_ABGR8888:
514 case TBM_FORMAT_RGBA8888:
515 case TBM_FORMAT_BGRA8888:
516 case TBM_FORMAT_XRGB2101010:
517 case TBM_FORMAT_XBGR2101010:
518 case TBM_FORMAT_RGBX1010102:
519 case TBM_FORMAT_BGRX1010102:
520 case TBM_FORMAT_ARGB2101010:
521 case TBM_FORMAT_ABGR2101010:
522 case TBM_FORMAT_RGBA1010102:
523 case TBM_FORMAT_BGRA1010102:
524 case TBM_FORMAT_YUYV:
525 case TBM_FORMAT_YVYU:
526 case TBM_FORMAT_UYVY:
527 case TBM_FORMAT_VYUY:
528 case TBM_FORMAT_AYUV:
531 case TBM_FORMAT_NV12:
532 case TBM_FORMAT_NV12MT:
533 case TBM_FORMAT_NV21:
536 case TBM_FORMAT_NV16:
537 case TBM_FORMAT_NV61:
540 case TBM_FORMAT_YUV410:
541 case TBM_FORMAT_YVU410:
544 case TBM_FORMAT_YUV411:
545 case TBM_FORMAT_YVU411:
546 case TBM_FORMAT_YUV420:
547 case TBM_FORMAT_YVU420:
550 case TBM_FORMAT_YUV422:
551 case TBM_FORMAT_YVU422:
554 case TBM_FORMAT_YUV444:
555 case TBM_FORMAT_YVU444:
559 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
567 tbm_surface_internal_is_valid(tbm_surface_h surface)
571 _tbm_surface_mutex_lock();
572 _tbm_set_last_result(TBM_ERROR_NONE);
574 /* Return silently if surface is null. */
576 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
577 _tbm_surface_mutex_unlock();
581 ret = _tbm_surface_internal_is_valid(surface);
583 _tbm_surface_mutex_unlock();
589 tbm_surface_internal_query_supported_formats(uint32_t **formats,
592 struct _tbm_bufmgr *bufmgr;
594 bool bufmgr_initialized = false;
597 _tbm_surface_mutex_lock();
598 _tbm_set_last_result(TBM_ERROR_NONE);
600 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
601 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
603 if (!g_surface_bufmgr) {
604 _init_surface_bufmgr();
605 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
606 bufmgr_initialized = true;
609 bufmgr = g_surface_bufmgr;
611 if (bufmgr->backend_module_data) {
612 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
613 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
617 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
618 if (error != TBM_ERROR_NONE) {
619 /* LCOV_EXCL_START */
620 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
622 /* LCOV_EXCL_START */
626 if (!bufmgr->backend->surface_supported_format) {
627 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
631 ret = bufmgr->backend->surface_supported_format(formats, num);
633 /* LCOV_EXCL_START */
634 TBM_ERR("Fail to surface_supported_format.\n");
635 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
637 /* LCOV_EXCL_START */
641 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
643 if (bufmgr_initialized) {
644 LIST_DELINIT(&g_surface_bufmgr->surf_list);
645 _deinit_surface_bufmgr();
648 _tbm_surface_mutex_unlock();
652 /* LCOV_EXCL_START */
654 if (bufmgr_initialized) {
655 LIST_DELINIT(&g_surface_bufmgr->surf_list);
656 _deinit_surface_bufmgr();
658 _tbm_surface_mutex_unlock();
660 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
667 tbm_surface_internal_get_num_planes(tbm_format format)
671 _tbm_surface_mutex_lock();
672 _tbm_set_last_result(TBM_ERROR_NONE);
674 num_planes = _tbm_surface_internal_get_num_planes(format);
676 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
677 _tbm_surface_mutex_unlock();
681 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
683 _tbm_surface_mutex_unlock();
689 tbm_surface_internal_get_bpp(tbm_format format)
693 _tbm_surface_mutex_lock();
694 _tbm_set_last_result(TBM_ERROR_NONE);
696 bpp = _tbm_surface_internal_get_bpp(format);
698 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
699 _tbm_surface_mutex_unlock();
703 _tbm_surface_mutex_unlock();
705 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
711 tbm_surface_internal_create_with_flags(int width, int height,
712 int format, int flags)
714 struct _tbm_bufmgr *bufmgr;
715 struct _tbm_surface *surf = NULL;
719 uint32_t bo_size = 0;
722 bool bufmgr_initialized = false;
724 void *bo_priv = NULL;
725 tbm_backend_bo_data *bo_data = NULL;
728 _tbm_surface_mutex_lock();
729 _tbm_set_last_result(TBM_ERROR_NONE);
731 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
732 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
734 if (!g_surface_bufmgr) {
735 _init_surface_bufmgr();
736 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
737 bufmgr_initialized = true;
740 bufmgr = g_surface_bufmgr;
741 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
742 TBM_ERR("The bufmgr is invalid\n");
743 goto check_valid_fail;
746 surf = calloc(1, sizeof(struct _tbm_surface));
748 /* LCOV_EXCL_START */
749 TBM_ERR("fail to alloc surf\n");
750 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
751 goto alloc_surf_fail;
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 bo = calloc(1, sizeof(struct _tbm_bo));
808 TBM_ERR("fail to alloc bo struct\n");
809 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
813 bo->bufmgr = surf->bufmgr;
815 _tbm_bufmgr_mutex_lock();
817 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format(bufmgr->bufmgr_data, format, i,
818 width, height, flags, &error);
820 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
821 _tbm_set_last_result(error);
823 _tbm_bufmgr_mutex_unlock();
826 bo->bo_data = bo_data;
830 LIST_INITHEAD(&bo->user_data_list);
832 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
834 _tbm_bufmgr_mutex_unlock();
838 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
839 bo = calloc(1, sizeof(struct _tbm_bo));
841 TBM_ERR("fail to alloc bo struct\n");
842 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
846 bo->bufmgr = surf->bufmgr;
848 _tbm_bufmgr_mutex_lock();
850 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format(bufmgr->bufmgr_data, width, height, surf->info.bpp/8, format, flags, i, &error);
852 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
853 _tbm_set_last_result(error);
855 _tbm_bufmgr_mutex_unlock();
858 bo->bo_data = bo_data;
862 LIST_INITHEAD(&bo->user_data_list);
864 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
866 _tbm_bufmgr_mutex_unlock();
871 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
873 TBM_ERR("fail to alloc bo idx:%d\n", i);
878 if (bufmgr->backend->surface_bo_alloc) {
879 /* LCOV_EXCL_START */
880 bo = calloc(1, sizeof(struct _tbm_bo));
882 TBM_ERR("fail to alloc bo struct\n");
883 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
887 bo->bufmgr = surf->bufmgr;
889 _tbm_bufmgr_mutex_lock();
891 bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
893 TBM_ERR("fail to alloc bo priv\n");
894 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
896 _tbm_bufmgr_mutex_unlock();
903 LIST_INITHEAD(&bo->user_data_list);
905 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
907 _tbm_bufmgr_mutex_unlock();
912 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
914 TBM_ERR("fail to alloc bo idx:%d\n", i);
920 _tbm_bo_set_surface(surf->bos[i], surf);
923 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
924 _tbm_surface_internal_format_to_str(format), flags, surf);
926 LIST_INITHEAD(&surf->user_data_list);
927 LIST_INITHEAD(&surf->debug_data_list);
929 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
931 _tbm_surface_mutex_unlock();
935 /* LCOV_EXCL_START */
937 for (j = 0; j < i; j++) {
939 tbm_bo_unref(surf->bos[j]);
941 query_plane_data_fail:
947 if (bufmgr_initialized && bufmgr) {
948 LIST_DELINIT(&bufmgr->surf_list);
949 _deinit_surface_bufmgr();
951 _tbm_surface_mutex_unlock();
953 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
955 _tbm_surface_internal_format_to_str(format), flags);
962 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
963 tbm_bo *bos, int num)
965 struct _tbm_bufmgr *bufmgr;
966 struct _tbm_surface *surf = NULL;
968 bool bufmgr_initialized = false;
970 _tbm_surface_mutex_lock();
971 _tbm_set_last_result(TBM_ERROR_NONE);
973 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
974 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
975 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
976 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
977 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
979 if (!g_surface_bufmgr) {
980 _init_surface_bufmgr();
981 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
982 bufmgr_initialized = true;
985 bufmgr = g_surface_bufmgr;
986 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
987 TBM_ERR("fail to validate the Bufmgr.\n");
988 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
989 goto check_valid_fail;
992 surf = calloc(1, sizeof(struct _tbm_surface));
994 /* LCOV_EXCL_START */
995 TBM_ERR("fail to allocate struct _tbm_surface.\n");
996 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
997 goto alloc_surf_fail;
1001 surf->bufmgr = bufmgr;
1002 surf->info.width = info->width;
1003 surf->info.height = info->height;
1004 surf->info.format = info->format;
1006 surf->info.bpp = info->bpp;
1008 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1009 if (!surf->info.bpp) {
1010 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1014 surf->info.num_planes = info->num_planes;
1017 /* get size, stride and offset */
1018 for (i = 0; i < info->num_planes; i++) {
1019 surf->info.planes[i].offset = info->planes[i].offset;
1020 surf->info.planes[i].stride = info->planes[i].stride;
1022 if (info->planes[i].size > 0)
1023 surf->info.planes[i].size = info->planes[i].size;
1025 uint32_t size = 0, offset = 0, stride = 0;
1028 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1029 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1030 goto plane_data_fail;
1032 surf->info.planes[i].size = size;
1036 surf->planes_bo_idx[i] = 0;
1038 surf->planes_bo_idx[i] = i;
1041 if (info->size > 0) {
1042 surf->info.size = info->size;
1044 surf->info.size = 0;
1045 for (i = 0; i < info->num_planes; i++)
1046 surf->info.size += surf->info.planes[i].size;
1049 surf->flags = TBM_BO_DEFAULT;
1051 /* create only one bo */
1052 surf->num_bos = num;
1053 for (i = 0; i < num; i++) {
1054 if (bos[i] == NULL) {
1055 TBM_ERR("bos[%d] is null.\n", i);
1056 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1060 surf->bos[i] = tbm_bo_ref(bos[i]);
1061 _tbm_bo_set_surface(bos[i], surf);
1064 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1065 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1067 LIST_INITHEAD(&surf->user_data_list);
1068 LIST_INITHEAD(&surf->debug_data_list);
1070 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1072 _tbm_surface_mutex_unlock();
1076 /* LCOV_EXCL_START */
1080 for (i = 0; i < num; i++) {
1082 tbm_bo_unref(surf->bos[i]);
1087 if (bufmgr_initialized && bufmgr) {
1088 LIST_DELINIT(&bufmgr->surf_list);
1089 _deinit_surface_bufmgr();
1091 _tbm_surface_mutex_unlock();
1093 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1094 info->width, info->height,
1095 _tbm_surface_internal_format_to_str(info->format), num);
1096 /* LCOV_EXCL_STOP */
1102 tbm_surface_internal_destroy(tbm_surface_h surface)
1104 _tbm_surface_mutex_lock();
1105 _tbm_set_last_result(TBM_ERROR_NONE);
1107 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1111 if (surface->refcnt > 0) {
1112 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1113 _tbm_surface_mutex_unlock();
1117 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1119 if (surface->refcnt == 0)
1120 _tbm_surface_internal_destroy(surface);
1122 _tbm_surface_mutex_unlock();
1126 tbm_surface_internal_ref(tbm_surface_h surface)
1128 _tbm_surface_mutex_lock();
1129 _tbm_set_last_result(TBM_ERROR_NONE);
1131 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1135 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1137 _tbm_surface_mutex_unlock();
1141 tbm_surface_internal_unref(tbm_surface_h surface)
1143 _tbm_surface_mutex_lock();
1144 _tbm_set_last_result(TBM_ERROR_NONE);
1146 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1150 if (surface->refcnt > 0) {
1151 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1152 _tbm_surface_mutex_unlock();
1156 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1158 if (surface->refcnt == 0)
1159 _tbm_surface_internal_destroy(surface);
1161 _tbm_surface_mutex_unlock();
1165 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1167 struct _tbm_surface *surf;
1170 _tbm_surface_mutex_lock();
1171 _tbm_set_last_result(TBM_ERROR_NONE);
1173 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1175 surf = (struct _tbm_surface *)surface;
1176 num = surf->num_bos;
1179 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1181 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1183 _tbm_surface_mutex_unlock();
1189 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1191 struct _tbm_surface *surf;
1194 _tbm_surface_mutex_lock();
1195 _tbm_set_last_result(TBM_ERROR_NONE);
1197 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1198 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1200 surf = (struct _tbm_surface *)surface;
1201 bo = surf->bos[bo_idx];
1203 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1205 _tbm_surface_mutex_unlock();
1211 tbm_surface_internal_get_size(tbm_surface_h surface)
1213 struct _tbm_surface *surf;
1216 _tbm_surface_mutex_lock();
1217 _tbm_set_last_result(TBM_ERROR_NONE);
1219 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1221 surf = (struct _tbm_surface *)surface;
1222 size = surf->info.size;
1224 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1226 _tbm_surface_mutex_unlock();
1232 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1233 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1235 struct _tbm_surface *surf;
1237 _tbm_surface_mutex_lock();
1238 _tbm_set_last_result(TBM_ERROR_NONE);
1240 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1241 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1243 surf = (struct _tbm_surface *)surface;
1245 if (plane_idx >= surf->info.num_planes) {
1246 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1247 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1248 _tbm_surface_mutex_unlock();
1253 *size = surf->info.planes[plane_idx].size;
1256 *offset = surf->info.planes[plane_idx].offset;
1259 *pitch = surf->info.planes[plane_idx].stride;
1261 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1262 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1263 surf->info.planes[plane_idx].stride);
1265 _tbm_surface_mutex_unlock();
1271 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1272 tbm_surface_info_s *info, int map)
1274 struct _tbm_surface *surf;
1275 tbm_bo_handle bo_handles[4];
1278 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1281 _tbm_surface_mutex_lock();
1282 _tbm_set_last_result(TBM_ERROR_NONE);
1284 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1286 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1288 surf = (struct _tbm_surface *)surface;
1290 memset(info, 0x00, sizeof(tbm_surface_info_s));
1291 info->width = surf->info.width;
1292 info->height = surf->info.height;
1293 info->format = surf->info.format;
1294 info->bpp = surf->info.bpp;
1295 info->size = surf->info.size;
1296 info->num_planes = surf->info.num_planes;
1298 for (i = 0; i < surf->info.num_planes; i++) {
1299 info->planes[i].size = surf->info.planes[i].size;
1300 info->planes[i].offset = surf->info.planes[i].offset;
1301 info->planes[i].stride = surf->info.planes[i].stride;
1302 planes_bo_idx[i] = surf->planes_bo_idx[i];
1305 for (i = 0; i < surf->num_bos; i++)
1306 bos[i] = surf->bos[i];
1308 num_bos = surf->num_bos;
1311 _tbm_surface_mutex_unlock();
1312 for (i = 0; i < num_bos; i++) {
1313 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1314 if (bo_handles[i].ptr == NULL) {
1315 for (j = 0; j < i; j++)
1316 tbm_bo_unmap(bos[j]);
1318 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1322 _tbm_surface_mutex_lock();
1324 for (i = 0; i < num_bos; i++) {
1325 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1326 if (bo_handles[i].ptr == NULL) {
1327 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1328 _tbm_surface_mutex_unlock();
1334 for (i = 0; i < info->num_planes; i++) {
1335 if (bo_handles[planes_bo_idx[i]].ptr)
1336 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1339 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1341 _tbm_surface_mutex_unlock();
1347 tbm_surface_internal_unmap(tbm_surface_h surface)
1349 struct _tbm_surface *surf;
1352 _tbm_surface_mutex_lock();
1353 _tbm_set_last_result(TBM_ERROR_NONE);
1355 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1357 surf = (struct _tbm_surface *)surface;
1359 for (i = 0; i < surf->num_bos; i++)
1360 tbm_bo_unmap(surf->bos[i]);
1362 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1364 _tbm_surface_mutex_unlock();
1368 tbm_surface_internal_get_width(tbm_surface_h surface)
1370 struct _tbm_surface *surf;
1373 _tbm_surface_mutex_lock();
1374 _tbm_set_last_result(TBM_ERROR_NONE);
1376 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1378 surf = (struct _tbm_surface *)surface;
1379 width = surf->info.width;
1381 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1383 _tbm_surface_mutex_unlock();
1389 tbm_surface_internal_get_height(tbm_surface_h surface)
1391 struct _tbm_surface *surf;
1392 unsigned int height;
1394 _tbm_surface_mutex_lock();
1395 _tbm_set_last_result(TBM_ERROR_NONE);
1397 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1399 surf = (struct _tbm_surface *)surface;
1400 height = surf->info.height;
1402 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1404 _tbm_surface_mutex_unlock();
1411 tbm_surface_internal_get_format(tbm_surface_h surface)
1413 struct _tbm_surface *surf;
1416 _tbm_surface_mutex_lock();
1417 _tbm_set_last_result(TBM_ERROR_NONE);
1419 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1421 surf = (struct _tbm_surface *)surface;
1422 format = surf->info.format;
1424 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1426 _tbm_surface_mutex_unlock();
1432 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1434 struct _tbm_surface *surf;
1437 _tbm_surface_mutex_lock();
1438 _tbm_set_last_result(TBM_ERROR_NONE);
1440 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1441 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1443 surf = (struct _tbm_surface *)surface;
1444 bo_idx = surf->planes_bo_idx[plane_idx];
1446 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1448 _tbm_surface_mutex_unlock();
1454 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1455 tbm_data_free data_free_func)
1457 tbm_user_data *data;
1459 _tbm_surface_mutex_lock();
1460 _tbm_set_last_result(TBM_ERROR_NONE);
1462 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1464 /* check if the data according to the key exist if so, return false. */
1465 data = user_data_lookup(&surface->user_data_list, key);
1467 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1468 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1469 _tbm_surface_mutex_unlock();
1473 data = user_data_create(key, data_free_func);
1475 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1476 _tbm_surface_mutex_unlock();
1480 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1482 LIST_ADD(&data->item_link, &surface->user_data_list);
1484 _tbm_surface_mutex_unlock();
1490 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1493 tbm_user_data *old_data;
1495 _tbm_surface_mutex_lock();
1496 _tbm_set_last_result(TBM_ERROR_NONE);
1498 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1500 old_data = user_data_lookup(&surface->user_data_list, key);
1502 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1503 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1504 _tbm_surface_mutex_unlock();
1508 if (old_data->data && old_data->free_func)
1509 old_data->free_func(old_data->data);
1511 old_data->data = data;
1513 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1515 _tbm_surface_mutex_unlock();
1521 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1524 tbm_user_data *old_data;
1526 _tbm_surface_mutex_lock();
1527 _tbm_set_last_result(TBM_ERROR_NONE);
1529 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1532 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1533 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1534 _tbm_surface_mutex_unlock();
1539 old_data = user_data_lookup(&surface->user_data_list, key);
1541 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1542 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1543 _tbm_surface_mutex_unlock();
1547 *data = old_data->data;
1549 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1551 _tbm_surface_mutex_unlock();
1557 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1560 tbm_user_data *old_data = (void *)0;
1562 _tbm_surface_mutex_lock();
1563 _tbm_set_last_result(TBM_ERROR_NONE);
1565 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1567 old_data = user_data_lookup(&surface->user_data_list, key);
1569 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1570 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1571 _tbm_surface_mutex_unlock();
1575 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1577 user_data_delete(old_data);
1579 _tbm_surface_mutex_unlock();
1584 /* LCOV_EXCL_START */
1586 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1588 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1590 return surface->debug_pid;
1594 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1596 _tbm_surface_mutex_lock();
1597 _tbm_set_last_result(TBM_ERROR_NONE);
1599 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1601 surface->debug_pid = pid;
1603 _tbm_surface_mutex_unlock();
1606 static tbm_surface_debug_data *
1607 _tbm_surface_internal_debug_data_create(char *key, char *value)
1609 tbm_surface_debug_data *debug_data = NULL;
1611 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1613 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1614 TBM_ERR("fail to allocate the debug_data.");
1618 if (key) debug_data->key = strdup(key);
1619 if (value) debug_data->value = strdup(value);
1625 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1627 tbm_surface_debug_data *debug_data = NULL;
1628 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1629 tbm_bufmgr bufmgr = NULL;
1631 _tbm_surface_mutex_lock();
1632 _tbm_set_last_result(TBM_ERROR_NONE);
1634 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1635 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1637 bufmgr = surface->bufmgr;
1639 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1641 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1642 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1644 if (!strcmp(old_data->key, key)) {
1645 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1646 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1647 goto add_debug_key_list;
1650 if (old_data->value)
1651 free(old_data->value);
1654 old_data->value = strdup(value);
1656 old_data->value = NULL;
1658 goto add_debug_key_list;
1664 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1666 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1667 _tbm_surface_mutex_unlock();
1671 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1673 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1676 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1677 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1678 if (!strcmp(old_data->key, key)) {
1679 _tbm_surface_mutex_unlock();
1685 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1686 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1688 _tbm_surface_mutex_unlock();
1694 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1696 tbm_surface_debug_data *old_data = NULL;
1698 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1700 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1701 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1702 if (!strcmp(old_data->key, key))
1703 return old_data->value;
1710 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1711 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1713 struct _tbm_surface_dump_buf_info {
1723 tbm_surface_info_s info;
1725 struct list_head link;
1728 struct _tbm_surface_dump_info {
1729 char *path; // copy???
1732 struct list_head *link;
1733 struct list_head surface_list; /* link of surface */
1736 static tbm_surface_dump_info *g_dump_info = NULL;
1737 static const char *dump_postfix[2] = {"png", "yuv"};
1738 static double scale_factor;
1741 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1742 void *data2, int size2, void *data3, int size3)
1745 unsigned int *blocks;
1747 if (_tbm_surface_check_file_is_symbolic_link(file))
1748 TBM_ERR("%s is symbolic link\n", file);
1750 fp = fopen(file, "w+");
1751 TBM_RETURN_IF_FAIL(fp != NULL);
1753 blocks = (unsigned int *)data1;
1754 fwrite(blocks, 1, size1, fp);
1757 blocks = (unsigned int *)data2;
1758 fwrite(blocks, 1, size2, fp);
1762 blocks = (unsigned int *)data3;
1763 fwrite(blocks, 1, size3, fp);
1770 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1772 unsigned int *blocks = (unsigned int *)data;
1775 png_bytep *row_pointers;
1778 if (_tbm_surface_check_file_is_symbolic_link(file))
1779 TBM_ERR("%s is symbolic link\n", file);
1781 fp = fopen(file, "wb");
1782 TBM_RETURN_IF_FAIL(fp != NULL);
1784 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1787 TBM_ERR("fail to create a png write structure.\n");
1792 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1794 TBM_ERR("fail to create a png info structure.\n");
1795 png_destroy_write_struct(&pPngStruct, NULL);
1800 if (setjmp(png_jmpbuf(pPngStruct))) {
1801 /* if png has problem of writing the file, we get here */
1802 TBM_ERR("fail to write png file.\n");
1803 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1808 png_init_io(pPngStruct, fp);
1809 if (format == TBM_FORMAT_XRGB8888) {
1811 png_set_IHDR(pPngStruct,
1818 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1821 png_set_IHDR(pPngStruct,
1826 PNG_COLOR_TYPE_RGBA,
1828 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1831 png_set_bgr(pPngStruct);
1832 png_write_info(pPngStruct, pPngInfo);
1834 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1835 if (!row_pointers) {
1836 TBM_ERR("fail to allocate the png row_pointers.\n");
1837 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1842 for (y = 0; y < height; ++y) {
1846 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1848 TBM_ERR("fail to allocate the png row.\n");
1849 for (x = 0; x < y; x++)
1850 png_free(pPngStruct, row_pointers[x]);
1851 png_free(pPngStruct, row_pointers);
1852 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1856 row_pointers[y] = (png_bytep)row;
1858 for (x = 0; x < width; ++x) {
1859 unsigned int curBlock = blocks[y * width + x];
1861 if (pixel_size == 3) { // XRGB8888
1862 row[x * pixel_size] = (curBlock & 0xFF);
1863 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1864 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1865 } else { // ARGB8888
1866 row[x * pixel_size] = (curBlock & 0xFF);
1867 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1868 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1869 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1874 png_write_image(pPngStruct, row_pointers);
1875 png_write_end(pPngStruct, pPngInfo);
1877 for (y = 0; y < height; y++)
1878 png_free(pPngStruct, row_pointers[y]);
1879 png_free(pPngStruct, row_pointers);
1881 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1887 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1889 TBM_RETURN_IF_FAIL(path != NULL);
1890 TBM_RETURN_IF_FAIL(w > 0);
1891 TBM_RETURN_IF_FAIL(h > 0);
1892 TBM_RETURN_IF_FAIL(count > 0);
1894 tbm_surface_dump_buf_info *buf_info = NULL;
1895 tbm_surface_h tbm_surface;
1896 tbm_surface_info_s info;
1901 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1905 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1906 TBM_RETURN_IF_FAIL(g_dump_info);
1908 LIST_INITHEAD(&g_dump_info->surface_list);
1909 g_dump_info->count = 0;
1910 g_dump_info->dump_max = count;
1912 /* get buffer size */
1913 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1914 if (tbm_surface == NULL) {
1915 TBM_ERR("tbm_surface_create fail\n");
1921 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1922 TBM_ERR("tbm_surface_get_info fail\n");
1923 tbm_surface_destroy(tbm_surface);
1928 buffer_size = info.size;
1929 tbm_surface_destroy(tbm_surface);
1931 /* create dump lists */
1932 for (i = 0; i < count; i++) {
1935 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1936 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1938 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1940 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1945 buf_info->index = i;
1947 buf_info->size = buffer_size;
1949 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1952 g_dump_info->path = path;
1953 g_dump_info->link = &g_dump_info->surface_list;
1957 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1962 /* free resources */
1963 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1964 tbm_surface_dump_buf_info *tmp;
1966 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1967 tbm_bo_unref(buf_info->bo);
1968 LIST_DEL(&buf_info->link);
1973 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1982 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1989 tbm_surface_internal_dump_start(path, w, h, count);
1990 scale_factor = scale;
1994 tbm_surface_internal_dump_end(void)
1996 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1997 tbm_bo_handle bo_handle;
2002 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2009 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2012 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2013 if (bo_handle.ptr == NULL) {
2014 tbm_bo_unref(buf_info->bo);
2015 LIST_DEL(&buf_info->link);
2020 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2021 TBM_INFO("Dump File.. %s generated.\n", file);
2023 if (buf_info->dirty) {
2024 void *ptr1 = NULL, *ptr2 = NULL;
2026 switch (buf_info->info.format) {
2027 case TBM_FORMAT_ARGB8888:
2028 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2029 buf_info->info.planes[0].stride >> 2,
2030 buf_info->info.height, TBM_FORMAT_ARGB8888);
2032 case TBM_FORMAT_XRGB8888:
2033 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2034 buf_info->info.planes[0].stride >> 2,
2035 buf_info->info.height, TBM_FORMAT_XRGB8888);
2037 case TBM_FORMAT_YVU420:
2038 case TBM_FORMAT_YUV420:
2039 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2040 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2041 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2042 buf_info->info.planes[0].stride * buf_info->info.height,
2044 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2046 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2048 case TBM_FORMAT_NV12:
2049 case TBM_FORMAT_NV21:
2050 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2051 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2052 buf_info->info.planes[0].stride * buf_info->info.height,
2054 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2057 case TBM_FORMAT_YUYV:
2058 case TBM_FORMAT_UYVY:
2059 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2060 buf_info->info.planes[0].stride * buf_info->info.height,
2064 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2067 } else if (buf_info->dirty_shm)
2068 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2069 buf_info->shm_stride >> 2,
2070 buf_info->shm_h, 0);
2072 tbm_bo_unmap(buf_info->bo);
2073 tbm_bo_unref(buf_info->bo);
2074 LIST_DEL(&buf_info->link);
2081 TBM_INFO("Dump End..\n");
2084 static pixman_format_code_t
2085 _tbm_surface_internal_pixman_format_get(tbm_format format)
2088 case TBM_FORMAT_ARGB8888:
2089 return PIXMAN_a8r8g8b8;
2090 case TBM_FORMAT_XRGB8888:
2091 return PIXMAN_x8r8g8b8;
2100 * This function supports only if a buffer has below formats.
2101 * - TBM_FORMAT_ARGB8888
2102 * - TBM_FORMAT_XRGB8888
2104 static tbm_surface_error_e
2105 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2106 int format, int src_stride, int src_w, int src_h,
2107 int dst_stride, int dst_w, int dst_h)
2109 pixman_image_t *src_img = NULL, *dst_img = NULL;
2110 pixman_format_code_t pixman_format;
2111 pixman_transform_t t;
2112 struct pixman_f_transform ft;
2113 double scale_x, scale_y;
2115 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2116 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2118 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2119 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2122 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2123 (uint32_t*)src_ptr, src_stride);
2124 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2127 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2128 (uint32_t*)dst_ptr, dst_stride);
2129 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2131 pixman_f_transform_init_identity(&ft);
2133 scale_x = (double)src_w / dst_w;
2134 scale_y = (double)src_h / dst_h;
2136 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2137 pixman_f_transform_translate(&ft, NULL, 0, 0);
2138 pixman_transform_from_pixman_f_transform(&t, &ft);
2139 pixman_image_set_transform(src_img, &t);
2141 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2142 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2144 pixman_image_unref(src_img);
2145 pixman_image_unref(dst_img);
2147 return TBM_SURFACE_ERROR_NONE;
2151 pixman_image_unref(src_img);
2153 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2156 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2157 #define KEY_LEN 5 // "_XXXX"
2158 #define KEYS_LEN KEY_LEN * MAX_BOS
2160 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2162 char *keys, temp_key[KEY_LEN + 1];
2163 struct _tbm_surface *surf;
2167 _tbm_surface_mutex_lock();
2169 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2171 surf = (struct _tbm_surface *)surface;
2173 num_bos = surf->num_bos;
2174 if (num_bos > MAX_BOS)
2177 keys = calloc(KEYS_LEN + 1, sizeof(char));
2179 TBM_ERR("Failed to alloc memory");
2180 _tbm_surface_mutex_unlock();
2184 for (i = 0; i < num_bos; i++) {
2185 memset(temp_key, 0x00, KEY_LEN + 1);
2187 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2188 strncat(keys, temp_key, KEY_LEN + 1);
2191 _tbm_surface_mutex_unlock();
2196 static void _tbm_surface_internal_put_keys(char *keys)
2203 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2205 TBM_RETURN_IF_FAIL(surface != NULL);
2206 TBM_RETURN_IF_FAIL(type != NULL);
2208 tbm_surface_dump_buf_info *buf_info;
2209 struct list_head *next_link;
2210 tbm_surface_info_s info;
2211 tbm_bo_handle bo_handle;
2212 const char *postfix;
2213 const char *format = NULL;
2220 next_link = g_dump_info->link->next;
2221 TBM_RETURN_IF_FAIL(next_link != NULL);
2223 if (next_link == &g_dump_info->surface_list) {
2224 next_link = next_link->next;
2225 TBM_RETURN_IF_FAIL(next_link != NULL);
2228 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2229 TBM_RETURN_IF_FAIL(buf_info != NULL);
2231 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2232 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2234 if (scale_factor > 0.0) {
2237 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2238 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2239 _tbm_surface_internal_format_to_str(info.format));
2240 tbm_surface_unmap(surface);
2244 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2246 buf_info->info.width = info.width * scale_factor;
2247 buf_info->info.height = info.height * scale_factor;
2248 buf_info->info.format = info.format;
2249 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2250 if (!buf_info->info.bpp) {
2251 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2252 tbm_surface_unmap(surface);
2255 buf_info->info.num_planes = 1;
2256 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2257 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2259 if (buf_info->info.size > buf_info->size) {
2260 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2261 buf_info->info.size, buf_info->size);
2262 tbm_surface_unmap(surface);
2266 if (info.size > buf_info->size) {
2267 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2268 info.size, buf_info->size);
2269 tbm_surface_unmap(surface);
2273 /* make the file information */
2274 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2277 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2278 postfix = dump_postfix[0];
2279 format = _tbm_surface_internal_format_to_str(info.format);
2281 postfix = dump_postfix[1];
2283 keys = _tbm_surface_internal_get_keys(surface);
2285 TBM_ERR("fail to get keys");
2286 tbm_surface_unmap(surface);
2291 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2292 if (!bo_handle.ptr) {
2293 TBM_ERR("fail to map bo");
2294 _tbm_surface_internal_put_keys(keys);
2295 tbm_surface_unmap(surface);
2298 memset(bo_handle.ptr, 0x00, buf_info->size);
2300 switch (info.format) {
2301 case TBM_FORMAT_ARGB8888:
2302 case TBM_FORMAT_XRGB8888:
2303 snprintf(buf_info->name, sizeof(buf_info->name),
2304 "%10.3f_%03d%s_%p_%s-%s.%s",
2305 _tbm_surface_internal_get_time(),
2306 g_dump_info->count++, keys, surface, format, type, postfix);
2308 if (scale_factor > 0.0) {
2309 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2311 buf_info->info.format,
2312 info.planes[0].stride,
2313 info.width, info.height,
2314 buf_info->info.planes[0].stride,
2315 buf_info->info.width,
2316 buf_info->info.height);
2317 if (ret != TBM_SURFACE_ERROR_NONE) {
2318 TBM_ERR("fail to scale buffer");
2319 tbm_bo_unmap(buf_info->bo);
2320 _tbm_surface_internal_put_keys(keys);
2321 tbm_surface_unmap(surface);
2325 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2327 case TBM_FORMAT_YVU420:
2328 case TBM_FORMAT_YUV420:
2329 snprintf(buf_info->name, sizeof(buf_info->name),
2330 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2331 _tbm_surface_internal_get_time(),
2332 g_dump_info->count++, keys, type, info.planes[0].stride,
2333 info.height, FOURCC_STR(info.format), postfix);
2334 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2335 bo_handle.ptr += info.planes[0].stride * info.height;
2336 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2337 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2338 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2340 case TBM_FORMAT_NV12:
2341 case TBM_FORMAT_NV21:
2342 snprintf(buf_info->name, sizeof(buf_info->name),
2343 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2344 _tbm_surface_internal_get_time(),
2345 g_dump_info->count++, keys, type, info.planes[0].stride,
2346 info.height, FOURCC_STR(info.format), postfix);
2347 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2348 bo_handle.ptr += info.planes[0].stride * info.height;
2349 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2351 case TBM_FORMAT_YUYV:
2352 case TBM_FORMAT_UYVY:
2353 snprintf(buf_info->name, sizeof(buf_info->name),
2354 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2355 _tbm_surface_internal_get_time(),
2356 g_dump_info->count++, keys, type, info.planes[0].stride,
2357 info.height, FOURCC_STR(info.format), postfix);
2358 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2361 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2362 tbm_bo_unmap(buf_info->bo);
2363 _tbm_surface_internal_put_keys(keys);
2364 tbm_surface_unmap(surface);
2368 tbm_bo_unmap(buf_info->bo);
2370 _tbm_surface_internal_put_keys(keys);
2372 tbm_surface_unmap(surface);
2374 buf_info->dirty = 1;
2375 buf_info->dirty_shm = 0;
2377 if (g_dump_info->count == 1000)
2378 g_dump_info->count = 0;
2380 g_dump_info->link = next_link;
2382 TBM_INFO("Dump %s \n", buf_info->name);
2385 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2388 TBM_RETURN_IF_FAIL(ptr != NULL);
2389 TBM_RETURN_IF_FAIL(w > 0);
2390 TBM_RETURN_IF_FAIL(h > 0);
2391 TBM_RETURN_IF_FAIL(stride > 0);
2392 TBM_RETURN_IF_FAIL(type != NULL);
2394 tbm_surface_dump_buf_info *buf_info;
2395 struct list_head *next_link;
2396 tbm_bo_handle bo_handle;
2397 int ret, size, dw = 0, dh = 0, dstride = 0;
2402 next_link = g_dump_info->link->next;
2403 TBM_RETURN_IF_FAIL(next_link != NULL);
2405 if (next_link == &g_dump_info->surface_list) {
2406 next_link = next_link->next;
2407 TBM_RETURN_IF_FAIL(next_link != NULL);
2410 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2411 TBM_RETURN_IF_FAIL(buf_info != NULL);
2413 if (scale_factor > 0.0) {
2416 dw = w * scale_factor;
2417 dh = h * scale_factor;
2419 size = dstride * dh;
2423 if (size > buf_info->size) {
2424 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2425 size, buf_info->size);
2430 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2431 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2433 memset(bo_handle.ptr, 0x00, buf_info->size);
2434 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2436 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2437 _tbm_surface_internal_get_time(),
2438 g_dump_info->count++, type, dump_postfix[0]);
2439 if (scale_factor > 0.0) {
2440 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2441 TBM_FORMAT_ARGB8888, stride,
2442 w, h, dstride, dw, dh);
2443 if (ret != TBM_SURFACE_ERROR_NONE) {
2444 TBM_ERR("fail to scale buffer");
2445 tbm_bo_unmap(buf_info->bo);
2448 buf_info->shm_stride = dstride;
2449 buf_info->shm_h = dh;
2451 memcpy(bo_handle.ptr, ptr, size);
2452 buf_info->shm_stride = stride;
2453 buf_info->shm_h = h;
2456 tbm_bo_unmap(buf_info->bo);
2458 buf_info->dirty = 0;
2459 buf_info->dirty_shm = 1;
2461 if (g_dump_info->count == 1000)
2462 g_dump_info->count = 0;
2464 g_dump_info->link = next_link;
2466 TBM_INFO("Dump %s \n", buf_info->name);
2470 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2472 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2473 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2474 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2476 tbm_surface_info_s info;
2477 const char *postfix;
2481 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2482 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2484 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2485 postfix = dump_postfix[0];
2487 postfix = dump_postfix[1];
2489 if (strcmp(postfix, type)) {
2490 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2491 tbm_surface_unmap(surface);
2495 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2497 if (!access(file, 0)) {
2498 TBM_ERR("can't capture buffer, exist file %s", file);
2499 tbm_surface_unmap(surface);
2503 switch (info.format) {
2504 case TBM_FORMAT_ARGB8888:
2505 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2506 info.planes[0].stride >> 2,
2507 info.height, TBM_FORMAT_ARGB8888);
2509 case TBM_FORMAT_XRGB8888:
2510 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2511 info.planes[0].stride >> 2,
2512 info.height, TBM_FORMAT_XRGB8888);
2514 case TBM_FORMAT_YVU420:
2515 case TBM_FORMAT_YUV420:
2516 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2517 info.planes[0].stride * info.height,
2519 info.planes[1].stride * (info.height >> 1),
2521 info.planes[2].stride * (info.height >> 1));
2523 case TBM_FORMAT_NV12:
2524 case TBM_FORMAT_NV21:
2525 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2526 info.planes[0].stride * info.height,
2528 info.planes[1].stride * (info.height >> 1),
2531 case TBM_FORMAT_YUYV:
2532 case TBM_FORMAT_UYVY:
2533 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2534 info.planes[0].stride * info.height,
2538 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2539 tbm_surface_unmap(surface);
2543 tbm_surface_unmap(surface);
2545 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2551 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2552 const char *path, const char *name, const char *type)
2554 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2555 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2556 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2557 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2558 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2559 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2563 if (strcmp(dump_postfix[0], type)) {
2564 TBM_ERR("Not supported type:%s'", type);
2568 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2570 if (!access(file, 0)) {
2571 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2575 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2577 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2583 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2585 struct _tbm_surface *surf;
2587 _tbm_surface_mutex_lock();
2588 _tbm_set_last_result(TBM_ERROR_NONE);
2590 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2591 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2592 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2594 surf = (struct _tbm_surface *)surface;
2598 surf->damage.width = width;
2599 surf->damage.height = height;
2601 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2602 surface, x, y, width, height);
2604 _tbm_surface_mutex_unlock();
2610 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2612 struct _tbm_surface *surf;
2614 _tbm_surface_mutex_lock();
2615 _tbm_set_last_result(TBM_ERROR_NONE);
2617 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2619 surf = (struct _tbm_surface *)surface;
2621 if (x) *x = surf->damage.x;
2622 if (y) *y = surf->damage.y;
2623 if (width) *width = surf->damage.width;
2624 if (height) *height = surf->damage.height;
2626 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2627 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2629 _tbm_surface_mutex_unlock();