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, void *data, int width, int height, int format)
1774 png_bytep *row_pointers;
1777 if (_tbm_surface_check_file_is_symbolic_link(file))
1778 TBM_ERR("%s is symbolic link\n", file);
1780 fp = fopen(file, "wb");
1781 TBM_RETURN_IF_FAIL(fp != NULL);
1783 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1786 TBM_ERR("fail to create a png write structure.\n");
1791 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1793 TBM_ERR("fail to create a png info structure.\n");
1794 png_destroy_write_struct(&pPngStruct, NULL);
1799 png_init_io(pPngStruct, fp);
1800 if (format == TBM_FORMAT_XRGB8888) {
1802 png_set_IHDR(pPngStruct,
1809 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1812 png_set_IHDR(pPngStruct,
1817 PNG_COLOR_TYPE_RGBA,
1819 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1822 png_set_bgr(pPngStruct);
1823 png_write_info(pPngStruct, pPngInfo);
1825 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1826 if (!row_pointers) {
1827 TBM_ERR("fail to allocate the png row_pointers.\n");
1828 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1833 for (int y = 0; y < height; ++y)
1834 row_pointers[y] = data + width * pixel_size * y;
1836 png_write_image(pPngStruct, row_pointers);
1837 png_write_end(pPngStruct, pPngInfo);
1839 png_free(pPngStruct, row_pointers);
1841 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1847 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1849 TBM_RETURN_IF_FAIL(path != NULL);
1850 TBM_RETURN_IF_FAIL(w > 0);
1851 TBM_RETURN_IF_FAIL(h > 0);
1852 TBM_RETURN_IF_FAIL(count > 0);
1854 tbm_surface_dump_buf_info *buf_info = NULL;
1855 tbm_surface_h tbm_surface;
1856 tbm_surface_info_s info;
1861 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1865 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1866 TBM_RETURN_IF_FAIL(g_dump_info);
1868 LIST_INITHEAD(&g_dump_info->surface_list);
1869 g_dump_info->count = 0;
1870 g_dump_info->dump_max = count;
1872 /* get buffer size */
1873 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1874 if (tbm_surface == NULL) {
1875 TBM_ERR("tbm_surface_create fail\n");
1881 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1882 TBM_ERR("tbm_surface_get_info fail\n");
1883 tbm_surface_destroy(tbm_surface);
1888 buffer_size = info.size;
1889 tbm_surface_destroy(tbm_surface);
1891 /* create dump lists */
1892 for (i = 0; i < count; i++) {
1895 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1896 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1898 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1900 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1905 buf_info->index = i;
1907 buf_info->size = buffer_size;
1909 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1912 g_dump_info->path = path;
1913 g_dump_info->link = &g_dump_info->surface_list;
1917 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1922 /* free resources */
1923 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1924 tbm_surface_dump_buf_info *tmp;
1926 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1927 tbm_bo_unref(buf_info->bo);
1928 LIST_DEL(&buf_info->link);
1933 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1942 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1949 tbm_surface_internal_dump_start(path, w, h, count);
1950 scale_factor = scale;
1954 tbm_surface_internal_dump_end(void)
1956 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1957 tbm_bo_handle bo_handle;
1962 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1969 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1972 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1973 if (bo_handle.ptr == NULL) {
1974 tbm_bo_unref(buf_info->bo);
1975 LIST_DEL(&buf_info->link);
1980 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1981 TBM_INFO("Dump File.. %s generated.\n", file);
1983 if (buf_info->dirty) {
1984 void *ptr1 = NULL, *ptr2 = NULL;
1986 switch (buf_info->info.format) {
1987 case TBM_FORMAT_ARGB8888:
1988 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1989 buf_info->info.planes[0].stride >> 2,
1990 buf_info->info.height, TBM_FORMAT_ARGB8888);
1992 case TBM_FORMAT_XRGB8888:
1993 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1994 buf_info->info.planes[0].stride >> 2,
1995 buf_info->info.height, TBM_FORMAT_XRGB8888);
1997 case TBM_FORMAT_YVU420:
1998 case TBM_FORMAT_YUV420:
1999 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2000 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2001 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2002 buf_info->info.planes[0].stride * buf_info->info.height,
2004 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2006 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2008 case TBM_FORMAT_NV12:
2009 case TBM_FORMAT_NV21:
2010 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2011 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2012 buf_info->info.planes[0].stride * buf_info->info.height,
2014 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2017 case TBM_FORMAT_YUYV:
2018 case TBM_FORMAT_UYVY:
2019 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2020 buf_info->info.planes[0].stride * buf_info->info.height,
2024 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2027 } else if (buf_info->dirty_shm)
2028 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2029 buf_info->shm_stride >> 2,
2030 buf_info->shm_h, 0);
2032 tbm_bo_unmap(buf_info->bo);
2033 tbm_bo_unref(buf_info->bo);
2034 LIST_DEL(&buf_info->link);
2041 TBM_INFO("Dump End..\n");
2044 static pixman_format_code_t
2045 _tbm_surface_internal_pixman_format_get(tbm_format format)
2048 case TBM_FORMAT_ARGB8888:
2049 return PIXMAN_a8r8g8b8;
2050 case TBM_FORMAT_XRGB8888:
2051 return PIXMAN_x8r8g8b8;
2060 * This function supports only if a buffer has below formats.
2061 * - TBM_FORMAT_ARGB8888
2062 * - TBM_FORMAT_XRGB8888
2064 static tbm_surface_error_e
2065 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2066 int format, int src_stride, int src_w, int src_h,
2067 int dst_stride, int dst_w, int dst_h)
2069 pixman_image_t *src_img = NULL, *dst_img = NULL;
2070 pixman_format_code_t pixman_format;
2071 pixman_transform_t t;
2072 struct pixman_f_transform ft;
2073 double scale_x, scale_y;
2075 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2076 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2078 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2079 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2082 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2083 (uint32_t*)src_ptr, src_stride);
2084 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2087 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2088 (uint32_t*)dst_ptr, dst_stride);
2089 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2091 pixman_f_transform_init_identity(&ft);
2093 scale_x = (double)src_w / dst_w;
2094 scale_y = (double)src_h / dst_h;
2096 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2097 pixman_f_transform_translate(&ft, NULL, 0, 0);
2098 pixman_transform_from_pixman_f_transform(&t, &ft);
2099 pixman_image_set_transform(src_img, &t);
2101 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2102 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2104 pixman_image_unref(src_img);
2105 pixman_image_unref(dst_img);
2107 return TBM_SURFACE_ERROR_NONE;
2111 pixman_image_unref(src_img);
2113 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2116 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2117 #define KEY_LEN 5 // "_XXXX"
2118 #define KEYS_LEN KEY_LEN * MAX_BOS
2120 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2122 char *keys, temp_key[KEY_LEN + 1];
2123 struct _tbm_surface *surf;
2127 _tbm_surface_mutex_lock();
2129 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2131 surf = (struct _tbm_surface *)surface;
2133 num_bos = surf->num_bos;
2134 if (num_bos > MAX_BOS)
2137 keys = calloc(KEYS_LEN + 1, sizeof(char));
2139 TBM_ERR("Failed to alloc memory");
2140 _tbm_surface_mutex_unlock();
2144 for (i = 0; i < num_bos; i++) {
2145 memset(temp_key, 0x00, KEY_LEN + 1);
2147 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2148 strncat(keys, temp_key, KEY_LEN);
2151 _tbm_surface_mutex_unlock();
2156 static void _tbm_surface_internal_put_keys(char *keys)
2163 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2165 TBM_RETURN_IF_FAIL(surface != NULL);
2166 TBM_RETURN_IF_FAIL(type != NULL);
2168 tbm_surface_dump_buf_info *buf_info;
2169 struct list_head *next_link;
2170 tbm_surface_info_s info;
2171 tbm_bo_handle bo_handle;
2172 const char *postfix;
2173 const char *format = NULL;
2180 next_link = g_dump_info->link->next;
2181 TBM_RETURN_IF_FAIL(next_link != NULL);
2183 if (next_link == &g_dump_info->surface_list) {
2184 next_link = next_link->next;
2185 TBM_RETURN_IF_FAIL(next_link != NULL);
2188 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2189 TBM_RETURN_IF_FAIL(buf_info != NULL);
2191 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2192 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2194 if (scale_factor > 0.0) {
2197 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2198 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2199 _tbm_surface_internal_format_to_str(info.format));
2200 tbm_surface_unmap(surface);
2204 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2206 buf_info->info.width = info.width * scale_factor;
2207 buf_info->info.height = info.height * scale_factor;
2208 buf_info->info.format = info.format;
2209 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2210 if (!buf_info->info.bpp) {
2211 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2212 tbm_surface_unmap(surface);
2215 buf_info->info.num_planes = 1;
2216 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2217 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2219 if (buf_info->info.size > buf_info->size) {
2220 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2221 buf_info->info.size, buf_info->size);
2222 tbm_surface_unmap(surface);
2226 if (info.size > buf_info->size) {
2227 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2228 info.size, buf_info->size);
2229 tbm_surface_unmap(surface);
2233 /* make the file information */
2234 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2237 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2238 postfix = dump_postfix[0];
2239 format = _tbm_surface_internal_format_to_str(info.format);
2241 postfix = dump_postfix[1];
2243 keys = _tbm_surface_internal_get_keys(surface);
2245 TBM_ERR("fail to get keys");
2246 tbm_surface_unmap(surface);
2251 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2252 if (!bo_handle.ptr) {
2253 TBM_ERR("fail to map bo");
2254 _tbm_surface_internal_put_keys(keys);
2255 tbm_surface_unmap(surface);
2258 memset(bo_handle.ptr, 0x00, buf_info->size);
2260 switch (info.format) {
2261 case TBM_FORMAT_ARGB8888:
2262 case TBM_FORMAT_XRGB8888:
2263 snprintf(buf_info->name, sizeof(buf_info->name),
2264 "%10.3f_%03d%s_%p_%s-%s.%s",
2265 _tbm_surface_internal_get_time(),
2266 g_dump_info->count++, keys, surface, format, type, postfix);
2268 if (scale_factor > 0.0) {
2269 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2271 buf_info->info.format,
2272 info.planes[0].stride,
2273 info.width, info.height,
2274 buf_info->info.planes[0].stride,
2275 buf_info->info.width,
2276 buf_info->info.height);
2277 if (ret != TBM_SURFACE_ERROR_NONE) {
2278 TBM_ERR("fail to scale buffer");
2279 tbm_bo_unmap(buf_info->bo);
2280 _tbm_surface_internal_put_keys(keys);
2281 tbm_surface_unmap(surface);
2285 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2287 case TBM_FORMAT_YVU420:
2288 case TBM_FORMAT_YUV420:
2289 snprintf(buf_info->name, sizeof(buf_info->name),
2290 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2291 _tbm_surface_internal_get_time(),
2292 g_dump_info->count++, keys, type, info.planes[0].stride,
2293 info.height, FOURCC_STR(info.format), postfix);
2294 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2295 bo_handle.ptr += info.planes[0].stride * info.height;
2296 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2297 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2298 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2300 case TBM_FORMAT_NV12:
2301 case TBM_FORMAT_NV21:
2302 snprintf(buf_info->name, sizeof(buf_info->name),
2303 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2304 _tbm_surface_internal_get_time(),
2305 g_dump_info->count++, keys, type, info.planes[0].stride,
2306 info.height, FOURCC_STR(info.format), postfix);
2307 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2308 bo_handle.ptr += info.planes[0].stride * info.height;
2309 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2311 case TBM_FORMAT_YUYV:
2312 case TBM_FORMAT_UYVY:
2313 snprintf(buf_info->name, sizeof(buf_info->name),
2314 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2315 _tbm_surface_internal_get_time(),
2316 g_dump_info->count++, keys, type, info.planes[0].stride,
2317 info.height, FOURCC_STR(info.format), postfix);
2318 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2321 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2322 tbm_bo_unmap(buf_info->bo);
2323 _tbm_surface_internal_put_keys(keys);
2324 tbm_surface_unmap(surface);
2328 tbm_bo_unmap(buf_info->bo);
2330 _tbm_surface_internal_put_keys(keys);
2332 tbm_surface_unmap(surface);
2334 buf_info->dirty = 1;
2335 buf_info->dirty_shm = 0;
2337 if (g_dump_info->count == 1000)
2338 g_dump_info->count = 0;
2340 g_dump_info->link = next_link;
2342 TBM_INFO("Dump %s \n", buf_info->name);
2345 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2348 TBM_RETURN_IF_FAIL(ptr != NULL);
2349 TBM_RETURN_IF_FAIL(w > 0);
2350 TBM_RETURN_IF_FAIL(h > 0);
2351 TBM_RETURN_IF_FAIL(stride > 0);
2352 TBM_RETURN_IF_FAIL(type != NULL);
2354 tbm_surface_dump_buf_info *buf_info;
2355 struct list_head *next_link;
2356 tbm_bo_handle bo_handle;
2357 int ret, size, dw = 0, dh = 0, dstride = 0;
2362 next_link = g_dump_info->link->next;
2363 TBM_RETURN_IF_FAIL(next_link != NULL);
2365 if (next_link == &g_dump_info->surface_list) {
2366 next_link = next_link->next;
2367 TBM_RETURN_IF_FAIL(next_link != NULL);
2370 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2371 TBM_RETURN_IF_FAIL(buf_info != NULL);
2373 if (scale_factor > 0.0) {
2376 dw = w * scale_factor;
2377 dh = h * scale_factor;
2379 size = dstride * dh;
2383 if (size > buf_info->size) {
2384 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2385 size, buf_info->size);
2390 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2391 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2393 memset(bo_handle.ptr, 0x00, buf_info->size);
2394 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2396 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2397 _tbm_surface_internal_get_time(),
2398 g_dump_info->count++, type, dump_postfix[0]);
2399 if (scale_factor > 0.0) {
2400 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2401 TBM_FORMAT_ARGB8888, stride,
2402 w, h, dstride, dw, dh);
2403 if (ret != TBM_SURFACE_ERROR_NONE) {
2404 TBM_ERR("fail to scale buffer");
2405 tbm_bo_unmap(buf_info->bo);
2408 buf_info->shm_stride = dstride;
2409 buf_info->shm_h = dh;
2411 memcpy(bo_handle.ptr, ptr, size);
2412 buf_info->shm_stride = stride;
2413 buf_info->shm_h = h;
2416 tbm_bo_unmap(buf_info->bo);
2418 buf_info->dirty = 0;
2419 buf_info->dirty_shm = 1;
2421 if (g_dump_info->count == 1000)
2422 g_dump_info->count = 0;
2424 g_dump_info->link = next_link;
2426 TBM_INFO("Dump %s \n", buf_info->name);
2430 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2432 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2433 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2434 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2436 tbm_surface_info_s info;
2437 const char *postfix;
2441 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2442 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2444 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2445 postfix = dump_postfix[0];
2447 postfix = dump_postfix[1];
2449 if (strcmp(postfix, type)) {
2450 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2451 tbm_surface_unmap(surface);
2455 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2457 if (!access(file, 0)) {
2458 TBM_ERR("can't capture buffer, exist file %s", file);
2459 tbm_surface_unmap(surface);
2463 switch (info.format) {
2464 case TBM_FORMAT_ARGB8888:
2465 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2466 info.planes[0].stride >> 2,
2467 info.height, TBM_FORMAT_ARGB8888);
2469 case TBM_FORMAT_XRGB8888:
2470 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2471 info.planes[0].stride >> 2,
2472 info.height, TBM_FORMAT_XRGB8888);
2474 case TBM_FORMAT_YVU420:
2475 case TBM_FORMAT_YUV420:
2476 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2477 info.planes[0].stride * info.height,
2479 info.planes[1].stride * (info.height >> 1),
2481 info.planes[2].stride * (info.height >> 1));
2483 case TBM_FORMAT_NV12:
2484 case TBM_FORMAT_NV21:
2485 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2486 info.planes[0].stride * info.height,
2488 info.planes[1].stride * (info.height >> 1),
2491 case TBM_FORMAT_YUYV:
2492 case TBM_FORMAT_UYVY:
2493 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2494 info.planes[0].stride * info.height,
2498 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2499 tbm_surface_unmap(surface);
2503 tbm_surface_unmap(surface);
2505 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2511 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2512 const char *path, const char *name, const char *type)
2514 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2515 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2516 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2517 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2518 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2519 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2523 if (strcmp(dump_postfix[0], type)) {
2524 TBM_ERR("Not supported type:%s'", type);
2528 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2530 if (!access(file, 0)) {
2531 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2535 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2537 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2543 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2545 struct _tbm_surface *surf;
2547 _tbm_surface_mutex_lock();
2548 _tbm_set_last_result(TBM_ERROR_NONE);
2550 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2551 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2552 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2554 surf = (struct _tbm_surface *)surface;
2558 surf->damage.width = width;
2559 surf->damage.height = height;
2561 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2562 surface, x, y, width, height);
2564 _tbm_surface_mutex_unlock();
2570 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2572 struct _tbm_surface *surf;
2574 _tbm_surface_mutex_lock();
2575 _tbm_set_last_result(TBM_ERROR_NONE);
2577 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2579 surf = (struct _tbm_surface *)surface;
2581 if (x) *x = surf->damage.x;
2582 if (y) *y = surf->damage.y;
2583 if (width) *width = surf->damage.width;
2584 if (height) *height = surf->damage.height;
2586 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2587 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2589 _tbm_surface_mutex_unlock();