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 png_init_io(pPngStruct, fp);
1801 if (format == TBM_FORMAT_XRGB8888) {
1803 png_set_IHDR(pPngStruct,
1810 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1813 png_set_IHDR(pPngStruct,
1818 PNG_COLOR_TYPE_RGBA,
1820 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1823 png_set_bgr(pPngStruct);
1824 png_write_info(pPngStruct, pPngInfo);
1826 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1827 if (!row_pointers) {
1828 TBM_ERR("fail to allocate the png row_pointers.\n");
1829 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1834 for (y = 0; y < height; ++y) {
1838 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1840 TBM_ERR("fail to allocate the png row.\n");
1841 for (x = 0; x < y; x++)
1842 png_free(pPngStruct, row_pointers[x]);
1843 png_free(pPngStruct, row_pointers);
1844 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1848 row_pointers[y] = (png_bytep)row;
1850 for (x = 0; x < width; ++x) {
1851 unsigned int curBlock = blocks[y * width + x];
1853 if (pixel_size == 3) { // XRGB8888
1854 row[x * pixel_size] = (curBlock & 0xFF);
1855 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1856 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1857 } else { // ARGB8888
1858 row[x * pixel_size] = (curBlock & 0xFF);
1859 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1860 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1861 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1866 png_write_image(pPngStruct, row_pointers);
1867 png_write_end(pPngStruct, pPngInfo);
1869 for (y = 0; y < height; y++)
1870 png_free(pPngStruct, row_pointers[y]);
1871 png_free(pPngStruct, row_pointers);
1873 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1879 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1881 TBM_RETURN_IF_FAIL(path != NULL);
1882 TBM_RETURN_IF_FAIL(w > 0);
1883 TBM_RETURN_IF_FAIL(h > 0);
1884 TBM_RETURN_IF_FAIL(count > 0);
1886 tbm_surface_dump_buf_info *buf_info = NULL;
1887 tbm_surface_h tbm_surface;
1888 tbm_surface_info_s info;
1893 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1897 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1898 TBM_RETURN_IF_FAIL(g_dump_info);
1900 LIST_INITHEAD(&g_dump_info->surface_list);
1901 g_dump_info->count = 0;
1902 g_dump_info->dump_max = count;
1904 /* get buffer size */
1905 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1906 if (tbm_surface == NULL) {
1907 TBM_ERR("tbm_surface_create fail\n");
1913 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1914 TBM_ERR("tbm_surface_get_info fail\n");
1915 tbm_surface_destroy(tbm_surface);
1920 buffer_size = info.size;
1921 tbm_surface_destroy(tbm_surface);
1923 /* create dump lists */
1924 for (i = 0; i < count; i++) {
1927 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1928 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1930 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1932 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1937 buf_info->index = i;
1939 buf_info->size = buffer_size;
1941 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1944 g_dump_info->path = path;
1945 g_dump_info->link = &g_dump_info->surface_list;
1949 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1954 /* free resources */
1955 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1956 tbm_surface_dump_buf_info *tmp;
1958 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1959 tbm_bo_unref(buf_info->bo);
1960 LIST_DEL(&buf_info->link);
1965 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1974 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1981 tbm_surface_internal_dump_start(path, w, h, count);
1982 scale_factor = scale;
1986 tbm_surface_internal_dump_end(void)
1988 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1989 tbm_bo_handle bo_handle;
1994 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2001 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2004 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2005 if (bo_handle.ptr == NULL) {
2006 tbm_bo_unref(buf_info->bo);
2007 LIST_DEL(&buf_info->link);
2012 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2013 TBM_INFO("Dump File.. %s generated.\n", file);
2015 if (buf_info->dirty) {
2016 void *ptr1 = NULL, *ptr2 = NULL;
2018 switch (buf_info->info.format) {
2019 case TBM_FORMAT_ARGB8888:
2020 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2021 buf_info->info.planes[0].stride >> 2,
2022 buf_info->info.height, TBM_FORMAT_ARGB8888);
2024 case TBM_FORMAT_XRGB8888:
2025 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2026 buf_info->info.planes[0].stride >> 2,
2027 buf_info->info.height, TBM_FORMAT_XRGB8888);
2029 case TBM_FORMAT_YVU420:
2030 case TBM_FORMAT_YUV420:
2031 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2032 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2033 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2034 buf_info->info.planes[0].stride * buf_info->info.height,
2036 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2038 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2040 case TBM_FORMAT_NV12:
2041 case TBM_FORMAT_NV21:
2042 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2043 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2044 buf_info->info.planes[0].stride * buf_info->info.height,
2046 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2049 case TBM_FORMAT_YUYV:
2050 case TBM_FORMAT_UYVY:
2051 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2052 buf_info->info.planes[0].stride * buf_info->info.height,
2056 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2059 } else if (buf_info->dirty_shm)
2060 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2061 buf_info->shm_stride >> 2,
2062 buf_info->shm_h, 0);
2064 tbm_bo_unmap(buf_info->bo);
2065 tbm_bo_unref(buf_info->bo);
2066 LIST_DEL(&buf_info->link);
2073 TBM_INFO("Dump End..\n");
2076 static pixman_format_code_t
2077 _tbm_surface_internal_pixman_format_get(tbm_format format)
2080 case TBM_FORMAT_ARGB8888:
2081 return PIXMAN_a8r8g8b8;
2082 case TBM_FORMAT_XRGB8888:
2083 return PIXMAN_x8r8g8b8;
2092 * This function supports only if a buffer has below formats.
2093 * - TBM_FORMAT_ARGB8888
2094 * - TBM_FORMAT_XRGB8888
2096 static tbm_surface_error_e
2097 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2098 int format, int src_stride, int src_w, int src_h,
2099 int dst_stride, int dst_w, int dst_h)
2101 pixman_image_t *src_img = NULL, *dst_img = NULL;
2102 pixman_format_code_t pixman_format;
2103 pixman_transform_t t;
2104 struct pixman_f_transform ft;
2105 double scale_x, scale_y;
2107 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2108 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2110 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2111 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2114 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2115 (uint32_t*)src_ptr, src_stride);
2116 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2119 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2120 (uint32_t*)dst_ptr, dst_stride);
2121 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2123 pixman_f_transform_init_identity(&ft);
2125 scale_x = (double)src_w / dst_w;
2126 scale_y = (double)src_h / dst_h;
2128 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2129 pixman_f_transform_translate(&ft, NULL, 0, 0);
2130 pixman_transform_from_pixman_f_transform(&t, &ft);
2131 pixman_image_set_transform(src_img, &t);
2133 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2134 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2136 pixman_image_unref(src_img);
2137 pixman_image_unref(dst_img);
2139 return TBM_SURFACE_ERROR_NONE;
2143 pixman_image_unref(src_img);
2145 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2148 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2149 #define KEY_LEN 5 // "_XXXX"
2150 #define KEYS_LEN KEY_LEN * MAX_BOS
2152 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2154 char *keys, temp_key[KEY_LEN + 1];
2155 struct _tbm_surface *surf;
2159 _tbm_surface_mutex_lock();
2161 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2163 surf = (struct _tbm_surface *)surface;
2165 num_bos = surf->num_bos;
2166 if (num_bos > MAX_BOS)
2169 keys = calloc(KEYS_LEN + 1, sizeof(char));
2171 TBM_ERR("Failed to alloc memory");
2172 _tbm_surface_mutex_unlock();
2176 for (i = 0; i < num_bos; i++) {
2177 memset(temp_key, 0x00, KEY_LEN + 1);
2179 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2180 strncat(keys, temp_key, KEY_LEN);
2183 _tbm_surface_mutex_unlock();
2188 static void _tbm_surface_internal_put_keys(char *keys)
2195 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2197 TBM_RETURN_IF_FAIL(surface != NULL);
2198 TBM_RETURN_IF_FAIL(type != NULL);
2200 tbm_surface_dump_buf_info *buf_info;
2201 struct list_head *next_link;
2202 tbm_surface_info_s info;
2203 tbm_bo_handle bo_handle;
2204 const char *postfix;
2205 const char *format = NULL;
2212 next_link = g_dump_info->link->next;
2213 TBM_RETURN_IF_FAIL(next_link != NULL);
2215 if (next_link == &g_dump_info->surface_list) {
2216 next_link = next_link->next;
2217 TBM_RETURN_IF_FAIL(next_link != NULL);
2220 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2221 TBM_RETURN_IF_FAIL(buf_info != NULL);
2223 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2224 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2226 if (scale_factor > 0.0) {
2229 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2230 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2231 _tbm_surface_internal_format_to_str(info.format));
2232 tbm_surface_unmap(surface);
2236 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2238 buf_info->info.width = info.width * scale_factor;
2239 buf_info->info.height = info.height * scale_factor;
2240 buf_info->info.format = info.format;
2241 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2242 if (!buf_info->info.bpp) {
2243 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2244 tbm_surface_unmap(surface);
2247 buf_info->info.num_planes = 1;
2248 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2249 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2251 if (buf_info->info.size > buf_info->size) {
2252 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2253 buf_info->info.size, buf_info->size);
2254 tbm_surface_unmap(surface);
2258 if (info.size > buf_info->size) {
2259 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2260 info.size, buf_info->size);
2261 tbm_surface_unmap(surface);
2265 /* make the file information */
2266 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2269 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2270 postfix = dump_postfix[0];
2271 format = _tbm_surface_internal_format_to_str(info.format);
2273 postfix = dump_postfix[1];
2275 keys = _tbm_surface_internal_get_keys(surface);
2277 TBM_ERR("fail to get keys");
2278 tbm_surface_unmap(surface);
2283 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2284 if (!bo_handle.ptr) {
2285 TBM_ERR("fail to map bo");
2286 _tbm_surface_internal_put_keys(keys);
2287 tbm_surface_unmap(surface);
2290 memset(bo_handle.ptr, 0x00, buf_info->size);
2292 switch (info.format) {
2293 case TBM_FORMAT_ARGB8888:
2294 case TBM_FORMAT_XRGB8888:
2295 snprintf(buf_info->name, sizeof(buf_info->name),
2296 "%10.3f_%03d%s_%p_%s-%s.%s",
2297 _tbm_surface_internal_get_time(),
2298 g_dump_info->count++, keys, surface, format, type, postfix);
2300 if (scale_factor > 0.0) {
2301 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2303 buf_info->info.format,
2304 info.planes[0].stride,
2305 info.width, info.height,
2306 buf_info->info.planes[0].stride,
2307 buf_info->info.width,
2308 buf_info->info.height);
2309 if (ret != TBM_SURFACE_ERROR_NONE) {
2310 TBM_ERR("fail to scale buffer");
2311 tbm_bo_unmap(buf_info->bo);
2312 _tbm_surface_internal_put_keys(keys);
2313 tbm_surface_unmap(surface);
2317 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2319 case TBM_FORMAT_YVU420:
2320 case TBM_FORMAT_YUV420:
2321 snprintf(buf_info->name, sizeof(buf_info->name),
2322 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2323 _tbm_surface_internal_get_time(),
2324 g_dump_info->count++, keys, type, info.planes[0].stride,
2325 info.height, FOURCC_STR(info.format), postfix);
2326 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2327 bo_handle.ptr += info.planes[0].stride * info.height;
2328 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2329 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2330 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2332 case TBM_FORMAT_NV12:
2333 case TBM_FORMAT_NV21:
2334 snprintf(buf_info->name, sizeof(buf_info->name),
2335 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2336 _tbm_surface_internal_get_time(),
2337 g_dump_info->count++, keys, type, info.planes[0].stride,
2338 info.height, FOURCC_STR(info.format), postfix);
2339 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2340 bo_handle.ptr += info.planes[0].stride * info.height;
2341 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2343 case TBM_FORMAT_YUYV:
2344 case TBM_FORMAT_UYVY:
2345 snprintf(buf_info->name, sizeof(buf_info->name),
2346 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2347 _tbm_surface_internal_get_time(),
2348 g_dump_info->count++, keys, type, info.planes[0].stride,
2349 info.height, FOURCC_STR(info.format), postfix);
2350 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2353 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2354 tbm_bo_unmap(buf_info->bo);
2355 _tbm_surface_internal_put_keys(keys);
2356 tbm_surface_unmap(surface);
2360 tbm_bo_unmap(buf_info->bo);
2362 _tbm_surface_internal_put_keys(keys);
2364 tbm_surface_unmap(surface);
2366 buf_info->dirty = 1;
2367 buf_info->dirty_shm = 0;
2369 if (g_dump_info->count == 1000)
2370 g_dump_info->count = 0;
2372 g_dump_info->link = next_link;
2374 TBM_INFO("Dump %s \n", buf_info->name);
2377 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2380 TBM_RETURN_IF_FAIL(ptr != NULL);
2381 TBM_RETURN_IF_FAIL(w > 0);
2382 TBM_RETURN_IF_FAIL(h > 0);
2383 TBM_RETURN_IF_FAIL(stride > 0);
2384 TBM_RETURN_IF_FAIL(type != NULL);
2386 tbm_surface_dump_buf_info *buf_info;
2387 struct list_head *next_link;
2388 tbm_bo_handle bo_handle;
2389 int ret, size, dw = 0, dh = 0, dstride = 0;
2394 next_link = g_dump_info->link->next;
2395 TBM_RETURN_IF_FAIL(next_link != NULL);
2397 if (next_link == &g_dump_info->surface_list) {
2398 next_link = next_link->next;
2399 TBM_RETURN_IF_FAIL(next_link != NULL);
2402 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2403 TBM_RETURN_IF_FAIL(buf_info != NULL);
2405 if (scale_factor > 0.0) {
2408 dw = w * scale_factor;
2409 dh = h * scale_factor;
2411 size = dstride * dh;
2415 if (size > buf_info->size) {
2416 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2417 size, buf_info->size);
2422 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2423 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2425 memset(bo_handle.ptr, 0x00, buf_info->size);
2426 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2428 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2429 _tbm_surface_internal_get_time(),
2430 g_dump_info->count++, type, dump_postfix[0]);
2431 if (scale_factor > 0.0) {
2432 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2433 TBM_FORMAT_ARGB8888, stride,
2434 w, h, dstride, dw, dh);
2435 if (ret != TBM_SURFACE_ERROR_NONE) {
2436 TBM_ERR("fail to scale buffer");
2437 tbm_bo_unmap(buf_info->bo);
2440 buf_info->shm_stride = dstride;
2441 buf_info->shm_h = dh;
2443 memcpy(bo_handle.ptr, ptr, size);
2444 buf_info->shm_stride = stride;
2445 buf_info->shm_h = h;
2448 tbm_bo_unmap(buf_info->bo);
2450 buf_info->dirty = 0;
2451 buf_info->dirty_shm = 1;
2453 if (g_dump_info->count == 1000)
2454 g_dump_info->count = 0;
2456 g_dump_info->link = next_link;
2458 TBM_INFO("Dump %s \n", buf_info->name);
2462 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2464 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2465 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2466 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2468 tbm_surface_info_s info;
2469 const char *postfix;
2473 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2474 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2476 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2477 postfix = dump_postfix[0];
2479 postfix = dump_postfix[1];
2481 if (strcmp(postfix, type)) {
2482 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2483 tbm_surface_unmap(surface);
2487 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2489 if (!access(file, 0)) {
2490 TBM_ERR("can't capture buffer, exist file %s", file);
2491 tbm_surface_unmap(surface);
2495 switch (info.format) {
2496 case TBM_FORMAT_ARGB8888:
2497 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2498 info.planes[0].stride >> 2,
2499 info.height, TBM_FORMAT_ARGB8888);
2501 case TBM_FORMAT_XRGB8888:
2502 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2503 info.planes[0].stride >> 2,
2504 info.height, TBM_FORMAT_XRGB8888);
2506 case TBM_FORMAT_YVU420:
2507 case TBM_FORMAT_YUV420:
2508 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2509 info.planes[0].stride * info.height,
2511 info.planes[1].stride * (info.height >> 1),
2513 info.planes[2].stride * (info.height >> 1));
2515 case TBM_FORMAT_NV12:
2516 case TBM_FORMAT_NV21:
2517 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2518 info.planes[0].stride * info.height,
2520 info.planes[1].stride * (info.height >> 1),
2523 case TBM_FORMAT_YUYV:
2524 case TBM_FORMAT_UYVY:
2525 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2526 info.planes[0].stride * info.height,
2530 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2531 tbm_surface_unmap(surface);
2535 tbm_surface_unmap(surface);
2537 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2543 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2544 const char *path, const char *name, const char *type)
2546 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2547 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2548 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2549 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2550 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2551 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2555 if (strcmp(dump_postfix[0], type)) {
2556 TBM_ERR("Not supported type:%s'", type);
2560 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2562 if (!access(file, 0)) {
2563 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2567 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2569 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2575 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2577 struct _tbm_surface *surf;
2579 _tbm_surface_mutex_lock();
2580 _tbm_set_last_result(TBM_ERROR_NONE);
2582 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2583 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2584 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2586 surf = (struct _tbm_surface *)surface;
2590 surf->damage.width = width;
2591 surf->damage.height = height;
2593 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2594 surface, x, y, width, height);
2596 _tbm_surface_mutex_unlock();
2602 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2604 struct _tbm_surface *surf;
2606 _tbm_surface_mutex_lock();
2607 _tbm_set_last_result(TBM_ERROR_NONE);
2609 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2611 surf = (struct _tbm_surface *)surface;
2613 if (x) *x = surf->damage.x;
2614 if (y) *y = surf->damage.y;
2615 if (width) *width = surf->damage.width;
2616 if (height) *height = surf->damage.height;
2618 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2619 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2621 _tbm_surface_mutex_unlock();