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_ADDTAIL(&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 stride, int format)
1772 unsigned int *blocks = (unsigned int *)data;
1775 png_bytep *row_pointers;
1778 if (_tbm_surface_check_file_is_symbolic_link(file))
1779 TBM_ERR("%s is symbolic link\n", file);
1781 fp = fopen(file, "wb");
1782 TBM_RETURN_IF_FAIL(fp != NULL);
1784 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1787 TBM_ERR("fail to create a png write structure.\n");
1792 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1794 TBM_ERR("fail to create a png info structure.\n");
1795 png_destroy_write_struct(&pPngStruct, NULL);
1800 if (setjmp(png_jmpbuf(pPngStruct))) {
1801 /* if png has problem of writing the file, we get here */
1802 TBM_ERR("fail to write png file.\n");
1803 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1808 png_init_io(pPngStruct, fp);
1809 if (format == TBM_FORMAT_XRGB8888) {
1811 png_set_IHDR(pPngStruct,
1818 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1821 png_set_IHDR(pPngStruct,
1826 PNG_COLOR_TYPE_RGBA,
1828 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1831 png_set_bgr(pPngStruct);
1832 png_write_info(pPngStruct, pPngInfo);
1834 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1835 if (!row_pointers) {
1836 TBM_ERR("fail to allocate the png row_pointers.\n");
1837 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1842 for (y = 0; y < height; ++y) {
1846 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1848 TBM_ERR("fail to allocate the png row.\n");
1849 for (x = 0; x < y; x++)
1850 png_free(pPngStruct, row_pointers[x]);
1851 png_free(pPngStruct, row_pointers);
1852 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1856 row_pointers[y] = (png_bytep)row;
1858 for (x = 0; x < width; ++x) {
1859 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1861 if (pixel_size == 3) { // XRGB8888
1862 row[x * pixel_size] = (curBlock & 0xFF);
1863 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1864 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1865 } else { // ARGB8888
1866 row[x * pixel_size] = (curBlock & 0xFF);
1867 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1868 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1869 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1874 png_write_image(pPngStruct, row_pointers);
1875 png_write_end(pPngStruct, pPngInfo);
1877 for (y = 0; y < height; y++)
1878 png_free(pPngStruct, row_pointers[y]);
1879 png_free(pPngStruct, row_pointers);
1881 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1887 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1889 TBM_RETURN_IF_FAIL(path != NULL);
1890 TBM_RETURN_IF_FAIL(w > 0);
1891 TBM_RETURN_IF_FAIL(h > 0);
1892 TBM_RETURN_IF_FAIL(count > 0);
1894 tbm_surface_dump_buf_info *buf_info = NULL;
1895 tbm_surface_h tbm_surface;
1896 tbm_surface_info_s info;
1901 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1905 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1906 TBM_RETURN_IF_FAIL(g_dump_info);
1908 LIST_INITHEAD(&g_dump_info->surface_list);
1909 g_dump_info->count = 0;
1910 g_dump_info->dump_max = count;
1912 /* get buffer size */
1913 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1914 if (tbm_surface == NULL) {
1915 TBM_ERR("tbm_surface_create fail\n");
1921 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1922 TBM_ERR("tbm_surface_get_info fail\n");
1923 tbm_surface_destroy(tbm_surface);
1928 buffer_size = info.size;
1929 tbm_surface_destroy(tbm_surface);
1931 /* create dump lists */
1932 for (i = 0; i < count; i++) {
1935 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1936 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1938 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1940 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1945 buf_info->index = i;
1947 buf_info->size = buffer_size;
1949 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1952 g_dump_info->path = path;
1953 g_dump_info->link = &g_dump_info->surface_list;
1957 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1962 /* free resources */
1963 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1964 tbm_surface_dump_buf_info *tmp;
1966 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1967 tbm_bo_unref(buf_info->bo);
1968 LIST_DEL(&buf_info->link);
1973 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1982 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1989 tbm_surface_internal_dump_start(path, w, h, count);
1990 scale_factor = scale;
1994 tbm_surface_internal_dump_end(void)
1996 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1997 tbm_bo_handle bo_handle;
2002 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2009 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2012 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2013 if (bo_handle.ptr == NULL) {
2014 tbm_bo_unref(buf_info->bo);
2015 LIST_DEL(&buf_info->link);
2020 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2021 TBM_INFO("Dump File.. %s generated.\n", file);
2023 if (buf_info->dirty) {
2024 void *ptr1 = NULL, *ptr2 = NULL;
2026 switch (buf_info->info.format) {
2027 case TBM_FORMAT_ARGB8888:
2028 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2029 buf_info->info.planes[0].stride >> 2,
2030 buf_info->info.height,
2031 buf_info->info.planes[0].stride,
2032 TBM_FORMAT_ARGB8888);
2034 case TBM_FORMAT_XRGB8888:
2035 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2036 buf_info->info.planes[0].stride >> 2,
2037 buf_info->info.height,
2038 buf_info->info.planes[0].stride,
2039 TBM_FORMAT_XRGB8888);
2041 case TBM_FORMAT_YVU420:
2042 case TBM_FORMAT_YUV420:
2043 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2044 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2045 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2046 buf_info->info.planes[0].stride * buf_info->info.height,
2048 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2050 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2052 case TBM_FORMAT_NV12:
2053 case TBM_FORMAT_NV21:
2054 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2055 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2056 buf_info->info.planes[0].stride * buf_info->info.height,
2058 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2061 case TBM_FORMAT_YUYV:
2062 case TBM_FORMAT_UYVY:
2063 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2064 buf_info->info.planes[0].stride * buf_info->info.height,
2068 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2071 } else if (buf_info->dirty_shm)
2072 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2073 buf_info->shm_stride >> 2,
2075 buf_info->shm_stride, 0);
2077 tbm_bo_unmap(buf_info->bo);
2078 tbm_bo_unref(buf_info->bo);
2079 LIST_DEL(&buf_info->link);
2086 TBM_INFO("Dump End..\n");
2089 static pixman_format_code_t
2090 _tbm_surface_internal_pixman_format_get(tbm_format format)
2093 case TBM_FORMAT_ARGB8888:
2094 return PIXMAN_a8r8g8b8;
2095 case TBM_FORMAT_XRGB8888:
2096 return PIXMAN_x8r8g8b8;
2105 * This function supports only if a buffer has below formats.
2106 * - TBM_FORMAT_ARGB8888
2107 * - TBM_FORMAT_XRGB8888
2109 static tbm_surface_error_e
2110 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2111 int format, int src_stride, int src_w, int src_h,
2112 int dst_stride, int dst_w, int dst_h)
2114 pixman_image_t *src_img = NULL, *dst_img = NULL;
2115 pixman_format_code_t pixman_format;
2116 pixman_transform_t t;
2117 struct pixman_f_transform ft;
2118 double scale_x, scale_y;
2120 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2121 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2123 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2124 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2127 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2128 (uint32_t*)src_ptr, src_stride);
2129 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2132 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2133 (uint32_t*)dst_ptr, dst_stride);
2134 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2136 pixman_f_transform_init_identity(&ft);
2138 scale_x = (double)src_w / dst_w;
2139 scale_y = (double)src_h / dst_h;
2141 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2142 pixman_f_transform_translate(&ft, NULL, 0, 0);
2143 pixman_transform_from_pixman_f_transform(&t, &ft);
2144 pixman_image_set_transform(src_img, &t);
2146 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2147 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2149 pixman_image_unref(src_img);
2150 pixman_image_unref(dst_img);
2152 return TBM_SURFACE_ERROR_NONE;
2156 pixman_image_unref(src_img);
2158 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2161 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2162 #define KEY_LEN 5 // "_XXXX"
2163 #define KEYS_LEN KEY_LEN * MAX_BOS
2165 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2167 char *keys, temp_key[KEY_LEN + 1];
2168 struct _tbm_surface *surf;
2172 _tbm_surface_mutex_lock();
2174 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2176 surf = (struct _tbm_surface *)surface;
2178 num_bos = surf->num_bos;
2179 if (num_bos > MAX_BOS)
2182 keys = calloc(KEYS_LEN + 1, sizeof(char));
2184 TBM_ERR("Failed to alloc memory");
2185 _tbm_surface_mutex_unlock();
2189 for (i = 0; i < num_bos; i++) {
2190 memset(temp_key, 0x00, KEY_LEN + 1);
2192 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2193 strncat(keys, temp_key, KEY_LEN + 1);
2196 _tbm_surface_mutex_unlock();
2201 static void _tbm_surface_internal_put_keys(char *keys)
2208 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2210 TBM_RETURN_IF_FAIL(surface != NULL);
2211 TBM_RETURN_IF_FAIL(type != NULL);
2213 tbm_surface_dump_buf_info *buf_info;
2214 struct list_head *next_link;
2215 tbm_surface_info_s info;
2216 tbm_bo_handle bo_handle;
2217 const char *postfix;
2218 const char *format = NULL;
2225 next_link = g_dump_info->link->next;
2226 TBM_RETURN_IF_FAIL(next_link != NULL);
2228 if (next_link == &g_dump_info->surface_list) {
2229 next_link = next_link->next;
2230 TBM_RETURN_IF_FAIL(next_link != NULL);
2233 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2234 TBM_RETURN_IF_FAIL(buf_info != NULL);
2236 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2237 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2239 if (scale_factor > 0.0) {
2242 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2243 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2244 _tbm_surface_internal_format_to_str(info.format));
2245 tbm_surface_unmap(surface);
2249 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2251 buf_info->info.width = info.width * scale_factor;
2252 buf_info->info.height = info.height * scale_factor;
2253 buf_info->info.format = info.format;
2254 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2255 if (!buf_info->info.bpp) {
2256 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2257 tbm_surface_unmap(surface);
2260 buf_info->info.num_planes = 1;
2261 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2262 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2264 if (buf_info->info.size > buf_info->size) {
2265 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2266 buf_info->info.size, buf_info->size);
2267 tbm_surface_unmap(surface);
2271 if (info.size > buf_info->size) {
2272 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2273 info.size, buf_info->size);
2274 tbm_surface_unmap(surface);
2278 /* make the file information */
2279 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2282 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2283 postfix = dump_postfix[0];
2284 format = _tbm_surface_internal_format_to_str(info.format);
2286 postfix = dump_postfix[1];
2288 keys = _tbm_surface_internal_get_keys(surface);
2290 TBM_ERR("fail to get keys");
2291 tbm_surface_unmap(surface);
2296 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2297 if (!bo_handle.ptr) {
2298 TBM_ERR("fail to map bo");
2299 _tbm_surface_internal_put_keys(keys);
2300 tbm_surface_unmap(surface);
2303 memset(bo_handle.ptr, 0x00, buf_info->size);
2305 switch (info.format) {
2306 case TBM_FORMAT_ARGB8888:
2307 case TBM_FORMAT_XRGB8888:
2308 snprintf(buf_info->name, sizeof(buf_info->name),
2309 "%10.3f_%03d%s_%p_%s-%s.%s",
2310 _tbm_surface_internal_get_time(),
2311 g_dump_info->count++, keys, surface, format, type, postfix);
2313 if (scale_factor > 0.0) {
2314 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2316 buf_info->info.format,
2317 info.planes[0].stride,
2318 info.width, info.height,
2319 buf_info->info.planes[0].stride,
2320 buf_info->info.width,
2321 buf_info->info.height);
2322 if (ret != TBM_SURFACE_ERROR_NONE) {
2323 TBM_ERR("fail to scale buffer");
2324 tbm_bo_unmap(buf_info->bo);
2325 _tbm_surface_internal_put_keys(keys);
2326 tbm_surface_unmap(surface);
2330 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2332 case TBM_FORMAT_YVU420:
2333 case TBM_FORMAT_YUV420:
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));
2342 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2343 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2345 case TBM_FORMAT_NV12:
2346 case TBM_FORMAT_NV21:
2347 snprintf(buf_info->name, sizeof(buf_info->name),
2348 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2349 _tbm_surface_internal_get_time(),
2350 g_dump_info->count++, keys, type, info.planes[0].stride,
2351 info.height, FOURCC_STR(info.format), postfix);
2352 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2353 bo_handle.ptr += info.planes[0].stride * info.height;
2354 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2356 case TBM_FORMAT_YUYV:
2357 case TBM_FORMAT_UYVY:
2358 snprintf(buf_info->name, sizeof(buf_info->name),
2359 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2360 _tbm_surface_internal_get_time(),
2361 g_dump_info->count++, keys, type, info.planes[0].stride,
2362 info.height, FOURCC_STR(info.format), postfix);
2363 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2366 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2367 tbm_bo_unmap(buf_info->bo);
2368 _tbm_surface_internal_put_keys(keys);
2369 tbm_surface_unmap(surface);
2373 tbm_bo_unmap(buf_info->bo);
2375 _tbm_surface_internal_put_keys(keys);
2377 tbm_surface_unmap(surface);
2379 buf_info->dirty = 1;
2380 buf_info->dirty_shm = 0;
2382 if (g_dump_info->count == 1000)
2383 g_dump_info->count = 0;
2385 g_dump_info->link = next_link;
2387 TBM_INFO("Dump %s \n", buf_info->name);
2390 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2393 TBM_RETURN_IF_FAIL(ptr != NULL);
2394 TBM_RETURN_IF_FAIL(w > 0);
2395 TBM_RETURN_IF_FAIL(h > 0);
2396 TBM_RETURN_IF_FAIL(stride > 0);
2397 TBM_RETURN_IF_FAIL(type != NULL);
2399 tbm_surface_dump_buf_info *buf_info;
2400 struct list_head *next_link;
2401 tbm_bo_handle bo_handle;
2402 int ret, size, dw = 0, dh = 0, dstride = 0;
2407 next_link = g_dump_info->link->next;
2408 TBM_RETURN_IF_FAIL(next_link != NULL);
2410 if (next_link == &g_dump_info->surface_list) {
2411 next_link = next_link->next;
2412 TBM_RETURN_IF_FAIL(next_link != NULL);
2415 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2416 TBM_RETURN_IF_FAIL(buf_info != NULL);
2418 if (scale_factor > 0.0) {
2421 dw = w * scale_factor;
2422 dh = h * scale_factor;
2424 size = dstride * dh;
2428 if (size > buf_info->size) {
2429 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2430 size, buf_info->size);
2435 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2436 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2438 memset(bo_handle.ptr, 0x00, buf_info->size);
2439 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2441 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2442 _tbm_surface_internal_get_time(),
2443 g_dump_info->count++, type, dump_postfix[0]);
2444 if (scale_factor > 0.0) {
2445 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2446 TBM_FORMAT_ARGB8888, stride,
2447 w, h, dstride, dw, dh);
2448 if (ret != TBM_SURFACE_ERROR_NONE) {
2449 TBM_ERR("fail to scale buffer");
2450 tbm_bo_unmap(buf_info->bo);
2453 buf_info->shm_stride = dstride;
2454 buf_info->shm_h = dh;
2456 memcpy(bo_handle.ptr, ptr, size);
2457 buf_info->shm_stride = stride;
2458 buf_info->shm_h = h;
2461 tbm_bo_unmap(buf_info->bo);
2463 buf_info->dirty = 0;
2464 buf_info->dirty_shm = 1;
2466 if (g_dump_info->count == 1000)
2467 g_dump_info->count = 0;
2469 g_dump_info->link = next_link;
2471 TBM_INFO("Dump %s \n", buf_info->name);
2475 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2477 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2478 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2479 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2481 tbm_surface_info_s info;
2482 const char *postfix;
2486 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2487 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2489 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2490 postfix = dump_postfix[0];
2492 postfix = dump_postfix[1];
2494 if (strcmp(postfix, type)) {
2495 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2496 tbm_surface_unmap(surface);
2500 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2502 if (!access(file, 0)) {
2503 TBM_ERR("can't capture buffer, exist file %s", file);
2504 tbm_surface_unmap(surface);
2508 switch (info.format) {
2509 case TBM_FORMAT_ARGB8888:
2510 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2513 info.planes[0].stride,
2514 TBM_FORMAT_ARGB8888);
2516 case TBM_FORMAT_XRGB8888:
2517 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2520 info.planes[0].stride,
2521 TBM_FORMAT_XRGB8888);
2523 case TBM_FORMAT_YVU420:
2524 case TBM_FORMAT_YUV420:
2525 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2526 info.planes[0].stride * info.height,
2528 info.planes[1].stride * (info.height >> 1),
2530 info.planes[2].stride * (info.height >> 1));
2532 case TBM_FORMAT_NV12:
2533 case TBM_FORMAT_NV21:
2534 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2535 info.planes[0].stride * info.height,
2537 info.planes[1].stride * (info.height >> 1),
2540 case TBM_FORMAT_YUYV:
2541 case TBM_FORMAT_UYVY:
2542 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2543 info.planes[0].stride * info.height,
2547 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2548 tbm_surface_unmap(surface);
2552 tbm_surface_unmap(surface);
2554 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2560 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2561 const char *path, const char *name, const char *type)
2563 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2564 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2565 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2566 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2567 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2568 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2572 if (strcmp(dump_postfix[0], type)) {
2573 TBM_ERR("Not supported type:%s'", type);
2577 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2579 if (!access(file, 0)) {
2580 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2584 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2586 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2592 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2594 struct _tbm_surface *surf;
2596 _tbm_surface_mutex_lock();
2597 _tbm_set_last_result(TBM_ERROR_NONE);
2599 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2600 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2601 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2603 surf = (struct _tbm_surface *)surface;
2607 surf->damage.width = width;
2608 surf->damage.height = height;
2610 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2611 surface, x, y, width, height);
2613 _tbm_surface_mutex_unlock();
2619 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2621 struct _tbm_surface *surf;
2623 _tbm_surface_mutex_lock();
2624 _tbm_set_last_result(TBM_ERROR_NONE);
2626 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2628 surf = (struct _tbm_surface *)surface;
2630 if (x) *x = surf->damage.x;
2631 if (y) *y = surf->damage.y;
2632 if (width) *width = surf->damage.width;
2633 if (height) *height = surf->damage.height;
2635 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2636 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2638 _tbm_surface_mutex_unlock();