1 /**************************************************************************
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
37 #include "tbm_bufmgr.h"
38 #include "tbm_bufmgr_int.h"
39 #include "tbm_surface_internal.h"
44 #define TBM_SURFACE_MAGIC 0xBF021234
46 static tbm_bufmgr g_surface_bufmgr;
47 static pthread_mutex_t tbm_surface_lock = PTHREAD_MUTEX_INITIALIZER;
48 void _tbm_surface_mutex_unlock(void);
50 #define C(b, m) (((b) >> (m)) & 0xFF)
51 #define B(c, s) ((((unsigned int)(c)) & 0xff) << (s))
52 #define FOURCC(a, b, c, d) (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
53 #define FOURCC_STR(id) C(id, 0), C(id, 8), C(id, 16), C(id, 24)
54 #define FOURCC_ID(str) FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
57 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
59 TBM_ERR("'%s' failed.\n", #cond);\
60 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
61 _tbm_surface_mutex_unlock();\
66 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
68 TBM_ERR("'%s' failed.\n", #cond);\
69 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
70 _tbm_surface_mutex_unlock();\
77 _tbm_surface_internal_get_time(void)
82 clock_gettime(CLOCK_MONOTONIC, &tp);
83 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
89 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
91 LIST_DEL(&debug_data->item_link);
93 if (debug_data->key) free(debug_data->key);
94 if (debug_data->value) free(debug_data->value);
99 _tbm_surface_internal_format_to_str(tbm_format format)
103 return "TBM_FORMAT_C8";
104 case TBM_FORMAT_RGB332:
105 return "TBM_FORMAT_RGB332";
106 case TBM_FORMAT_BGR233:
107 return "TBM_FORMAT_BGR233";
108 case TBM_FORMAT_XRGB4444:
109 return "TBM_FORMAT_XRGB4444";
110 case TBM_FORMAT_XBGR4444:
111 return "TBM_FORMAT_XBGR4444";
112 case TBM_FORMAT_RGBX4444:
113 return "TBM_FORMAT_RGBX4444";
114 case TBM_FORMAT_BGRX4444:
115 return "TBM_FORMAT_BGRX4444";
116 case TBM_FORMAT_ARGB4444:
117 return "TBM_FORMAT_ARGB4444";
118 case TBM_FORMAT_ABGR4444:
119 return "TBM_FORMAT_ABGR4444";
120 case TBM_FORMAT_RGBA4444:
121 return "TBM_FORMAT_RGBA4444";
122 case TBM_FORMAT_BGRA4444:
123 return "TBM_FORMAT_BGRA4444";
124 case TBM_FORMAT_XRGB1555:
125 return "TBM_FORMAT_XRGB1555";
126 case TBM_FORMAT_XBGR1555:
127 return "TBM_FORMAT_XBGR1555";
128 case TBM_FORMAT_RGBX5551:
129 return "TBM_FORMAT_RGBX5551";
130 case TBM_FORMAT_BGRX5551:
131 return "TBM_FORMAT_BGRX5551";
132 case TBM_FORMAT_ARGB1555:
133 return "TBM_FORMAT_ARGB1555";
134 case TBM_FORMAT_ABGR1555:
135 return "TBM_FORMAT_ABGR1555";
136 case TBM_FORMAT_RGBA5551:
137 return "TBM_FORMAT_RGBA5551";
138 case TBM_FORMAT_BGRA5551:
139 return "TBM_FORMAT_BGRA5551";
140 case TBM_FORMAT_RGB565:
141 return "TBM_FORMAT_RGB565";
142 case TBM_FORMAT_BGR565:
143 return "TBM_FORMAT_BGR565";
144 case TBM_FORMAT_RGB888:
145 return "TBM_FORMAT_RGB888";
146 case TBM_FORMAT_BGR888:
147 return "TBM_FORMAT_BGR888";
148 case TBM_FORMAT_XRGB8888:
149 return "TBM_FORMAT_XRGB8888";
150 case TBM_FORMAT_XBGR8888:
151 return "TBM_FORMAT_XBGR8888";
152 case TBM_FORMAT_RGBX8888:
153 return "TBM_FORMAT_RGBX8888";
154 case TBM_FORMAT_BGRX8888:
155 return "TBM_FORMAT_BGRX8888";
156 case TBM_FORMAT_ARGB8888:
157 return "TBM_FORMAT_ARGB8888";
158 case TBM_FORMAT_ABGR8888:
159 return "TBM_FORMAT_ABGR8888";
160 case TBM_FORMAT_RGBA8888:
161 return "TBM_FORMAT_RGBA8888";
162 case TBM_FORMAT_BGRA8888:
163 return "TBM_FORMAT_BGRA8888";
164 case TBM_FORMAT_XRGB2101010:
165 return "TBM_FORMAT_XRGB2101010";
166 case TBM_FORMAT_XBGR2101010:
167 return "TBM_FORMAT_XBGR2101010";
168 case TBM_FORMAT_RGBX1010102:
169 return "TBM_FORMAT_RGBX1010102";
170 case TBM_FORMAT_BGRX1010102:
171 return "TBM_FORMAT_BGRX1010102";
172 case TBM_FORMAT_ARGB2101010:
173 return "TBM_FORMAT_ARGB2101010";
174 case TBM_FORMAT_ABGR2101010:
175 return "TBM_FORMAT_ABGR2101010";
176 case TBM_FORMAT_RGBA1010102:
177 return "TBM_FORMAT_RGBA1010102";
178 case TBM_FORMAT_BGRA1010102:
179 return "TBM_FORMAT_BGRA1010102";
180 case TBM_FORMAT_YUYV:
181 return "TBM_FORMAT_YUYV";
182 case TBM_FORMAT_YVYU:
183 return "TBM_FORMAT_YVYU";
184 case TBM_FORMAT_UYVY:
185 return "TBM_FORMAT_UYVY";
186 case TBM_FORMAT_VYUY:
187 return "TBM_FORMAT_VYUY";
188 case TBM_FORMAT_AYUV:
189 return "TBM_FORMAT_AYUV";
190 case TBM_FORMAT_NV12:
191 return "TBM_FORMAT_NV12";
192 case TBM_FORMAT_NV21:
193 return "TBM_FORMAT_NV21";
194 case TBM_FORMAT_NV16:
195 return "TBM_FORMAT_NV16";
196 case TBM_FORMAT_NV61:
197 return "TBM_FORMAT_NV61";
198 case TBM_FORMAT_YUV410:
199 return "TBM_FORMAT_YUV410";
200 case TBM_FORMAT_YVU410:
201 return "TBM_FORMAT_YVU410";
202 case TBM_FORMAT_YUV411:
203 return "TBM_FORMAT_YUV411";
204 case TBM_FORMAT_YVU411:
205 return "TBM_FORMAT_YVU411";
206 case TBM_FORMAT_YUV420:
207 return "TBM_FORMAT_YUV420";
208 case TBM_FORMAT_YVU420:
209 return "TBM_FORMAT_YVU420";
210 case TBM_FORMAT_YUV422:
211 return "TBM_FORMAT_YUV422";
212 case TBM_FORMAT_YVU422:
213 return "TBM_FORMAT_YVU422";
214 case TBM_FORMAT_YUV444:
215 return "TBM_FORMAT_YUV444";
216 case TBM_FORMAT_YVU444:
217 return "TBM_FORMAT_YVU444";
218 case TBM_FORMAT_NV12MT:
219 return "TBM_FORMAT_NV12MT";
226 _tbm_surface_mutex_lock(void)
228 pthread_mutex_lock(&tbm_surface_lock);
232 _tbm_surface_mutex_unlock(void)
234 pthread_mutex_unlock(&tbm_surface_lock);
238 _init_surface_bufmgr(void)
240 g_surface_bufmgr = tbm_bufmgr_init(-1);
244 _deinit_surface_bufmgr(void)
246 if (!g_surface_bufmgr)
249 tbm_bufmgr_deinit(g_surface_bufmgr);
250 g_surface_bufmgr = NULL;
255 _tbm_surface_internal_magic_check(tbm_surface_h surface)
257 if (surface->magic != TBM_SURFACE_MAGIC)
264 _tbm_surface_internal_is_valid(tbm_surface_h surface)
267 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
268 TBM_ERR("error: No valid tbm_surface is NULL\n");
272 if (!_tbm_surface_internal_magic_check(surface)) {
273 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
274 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
282 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
283 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
285 TBM_RETURN_VAL_IF_FAIL(surface, 0);
286 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
288 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
289 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
293 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
294 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
295 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
296 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
298 if (bufmgr->backend_module_data) {
299 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
300 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
304 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
305 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
306 if (error != TBM_ERROR_NONE) {
307 /* LCOV_EXCL_START */
308 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
309 _tbm_set_last_result(error);
315 if (!bufmgr->backend->surface_get_plane_data) {
316 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
320 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
321 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
323 /* LCOV_EXCL_START */
324 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
325 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
335 _tbm_surface_internal_destroy(tbm_surface_h surface)
338 tbm_bufmgr bufmgr = surface->bufmgr;
339 tbm_user_data *old_data = NULL, *tmp = NULL;
340 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
342 /* destory the user_data_list */
343 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
344 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
345 TBM_DBG("free user_data\n");
346 user_data_delete(old_data);
350 for (i = 0; i < surface->num_bos; i++) {
351 surface->bos[i]->surface = NULL;
353 tbm_bo_unref(surface->bos[i]);
354 surface->bos[i] = NULL;
357 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
358 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
359 _tbm_surface_internal_debug_data_delete(debug_old_data);
362 LIST_DEL(&surface->item_link);
368 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
369 LIST_DELINIT(&bufmgr->surf_list);
371 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
372 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
373 _tbm_surface_internal_debug_data_delete(debug_old_data);
377 _deinit_surface_bufmgr();
381 /* LCOV_EXCL_START */
383 _tbm_surface_check_file_is_symbolic_link(const char* path)
390 if (stat(path, &sb) != 0)
393 if (S_ISLNK(sb.st_mode))
401 _tbm_surface_internal_get_num_planes(tbm_format format)
407 case TBM_FORMAT_RGB332:
408 case TBM_FORMAT_BGR233:
409 case TBM_FORMAT_XRGB4444:
410 case TBM_FORMAT_XBGR4444:
411 case TBM_FORMAT_RGBX4444:
412 case TBM_FORMAT_BGRX4444:
413 case TBM_FORMAT_ARGB4444:
414 case TBM_FORMAT_ABGR4444:
415 case TBM_FORMAT_RGBA4444:
416 case TBM_FORMAT_BGRA4444:
417 case TBM_FORMAT_XRGB1555:
418 case TBM_FORMAT_XBGR1555:
419 case TBM_FORMAT_RGBX5551:
420 case TBM_FORMAT_BGRX5551:
421 case TBM_FORMAT_ARGB1555:
422 case TBM_FORMAT_ABGR1555:
423 case TBM_FORMAT_RGBA5551:
424 case TBM_FORMAT_BGRA5551:
425 case TBM_FORMAT_RGB565:
426 case TBM_FORMAT_BGR565:
427 case TBM_FORMAT_RGB888:
428 case TBM_FORMAT_BGR888:
429 case TBM_FORMAT_XRGB8888:
430 case TBM_FORMAT_XBGR8888:
431 case TBM_FORMAT_RGBX8888:
432 case TBM_FORMAT_BGRX8888:
433 case TBM_FORMAT_ARGB8888:
434 case TBM_FORMAT_ABGR8888:
435 case TBM_FORMAT_RGBA8888:
436 case TBM_FORMAT_BGRA8888:
437 case TBM_FORMAT_XRGB2101010:
438 case TBM_FORMAT_XBGR2101010:
439 case TBM_FORMAT_RGBX1010102:
440 case TBM_FORMAT_BGRX1010102:
441 case TBM_FORMAT_ARGB2101010:
442 case TBM_FORMAT_ABGR2101010:
443 case TBM_FORMAT_RGBA1010102:
444 case TBM_FORMAT_BGRA1010102:
445 case TBM_FORMAT_YUYV:
446 case TBM_FORMAT_YVYU:
447 case TBM_FORMAT_UYVY:
448 case TBM_FORMAT_VYUY:
449 case TBM_FORMAT_AYUV:
452 case TBM_FORMAT_NV12:
453 case TBM_FORMAT_NV12MT:
454 case TBM_FORMAT_NV21:
455 case TBM_FORMAT_NV16:
456 case TBM_FORMAT_NV61:
459 case TBM_FORMAT_YUV410:
460 case TBM_FORMAT_YVU410:
461 case TBM_FORMAT_YUV411:
462 case TBM_FORMAT_YVU411:
463 case TBM_FORMAT_YUV420:
464 case TBM_FORMAT_YVU420:
465 case TBM_FORMAT_YUV422:
466 case TBM_FORMAT_YVU422:
467 case TBM_FORMAT_YUV444:
468 case TBM_FORMAT_YVU444:
473 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
481 _tbm_surface_internal_get_bpp(tbm_format format)
488 case TBM_FORMAT_RGB332:
489 case TBM_FORMAT_BGR233:
492 case TBM_FORMAT_XRGB4444:
493 case TBM_FORMAT_XBGR4444:
494 case TBM_FORMAT_RGBX4444:
495 case TBM_FORMAT_BGRX4444:
496 case TBM_FORMAT_ARGB4444:
497 case TBM_FORMAT_ABGR4444:
498 case TBM_FORMAT_RGBA4444:
499 case TBM_FORMAT_BGRA4444:
500 case TBM_FORMAT_XRGB1555:
501 case TBM_FORMAT_XBGR1555:
502 case TBM_FORMAT_RGBX5551:
503 case TBM_FORMAT_BGRX5551:
504 case TBM_FORMAT_ARGB1555:
505 case TBM_FORMAT_ABGR1555:
506 case TBM_FORMAT_RGBA5551:
507 case TBM_FORMAT_BGRA5551:
508 case TBM_FORMAT_RGB565:
509 case TBM_FORMAT_BGR565:
512 case TBM_FORMAT_RGB888:
513 case TBM_FORMAT_BGR888:
516 case TBM_FORMAT_XRGB8888:
517 case TBM_FORMAT_XBGR8888:
518 case TBM_FORMAT_RGBX8888:
519 case TBM_FORMAT_BGRX8888:
520 case TBM_FORMAT_ARGB8888:
521 case TBM_FORMAT_ABGR8888:
522 case TBM_FORMAT_RGBA8888:
523 case TBM_FORMAT_BGRA8888:
524 case TBM_FORMAT_XRGB2101010:
525 case TBM_FORMAT_XBGR2101010:
526 case TBM_FORMAT_RGBX1010102:
527 case TBM_FORMAT_BGRX1010102:
528 case TBM_FORMAT_ARGB2101010:
529 case TBM_FORMAT_ABGR2101010:
530 case TBM_FORMAT_RGBA1010102:
531 case TBM_FORMAT_BGRA1010102:
532 case TBM_FORMAT_YUYV:
533 case TBM_FORMAT_YVYU:
534 case TBM_FORMAT_UYVY:
535 case TBM_FORMAT_VYUY:
536 case TBM_FORMAT_AYUV:
539 case TBM_FORMAT_NV12:
540 case TBM_FORMAT_NV12MT:
541 case TBM_FORMAT_NV21:
544 case TBM_FORMAT_NV16:
545 case TBM_FORMAT_NV61:
548 case TBM_FORMAT_YUV410:
549 case TBM_FORMAT_YVU410:
552 case TBM_FORMAT_YUV411:
553 case TBM_FORMAT_YVU411:
554 case TBM_FORMAT_YUV420:
555 case TBM_FORMAT_YVU420:
558 case TBM_FORMAT_YUV422:
559 case TBM_FORMAT_YVU422:
562 case TBM_FORMAT_YUV444:
563 case TBM_FORMAT_YVU444:
567 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
575 tbm_surface_internal_is_valid(tbm_surface_h surface)
579 _tbm_surface_mutex_lock();
580 _tbm_set_last_result(TBM_ERROR_NONE);
582 /* Return silently if surface is null. */
584 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
585 _tbm_surface_mutex_unlock();
589 ret = _tbm_surface_internal_is_valid(surface);
591 _tbm_surface_mutex_unlock();
597 tbm_surface_internal_query_supported_formats(uint32_t **formats,
600 struct _tbm_bufmgr *bufmgr;
602 bool bufmgr_initialized = false;
605 _tbm_surface_mutex_lock();
606 _tbm_set_last_result(TBM_ERROR_NONE);
608 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
609 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
611 if (!g_surface_bufmgr) {
612 _init_surface_bufmgr();
613 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
614 bufmgr_initialized = true;
617 bufmgr = g_surface_bufmgr;
619 if (bufmgr->backend_module_data) {
620 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
621 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
625 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
626 if (error != TBM_ERROR_NONE) {
627 /* LCOV_EXCL_START */
628 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
630 /* LCOV_EXCL_START */
634 if (!bufmgr->backend->surface_supported_format) {
635 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
639 ret = bufmgr->backend->surface_supported_format(formats, num);
641 /* LCOV_EXCL_START */
642 TBM_ERR("Fail to surface_supported_format.\n");
643 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
645 /* LCOV_EXCL_START */
649 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
651 if (bufmgr_initialized) {
652 LIST_DELINIT(&g_surface_bufmgr->surf_list);
653 _deinit_surface_bufmgr();
656 _tbm_surface_mutex_unlock();
660 /* LCOV_EXCL_START */
662 if (bufmgr_initialized) {
663 LIST_DELINIT(&g_surface_bufmgr->surf_list);
664 _deinit_surface_bufmgr();
666 _tbm_surface_mutex_unlock();
668 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
675 tbm_surface_internal_get_num_planes(tbm_format format)
679 _tbm_surface_mutex_lock();
680 _tbm_set_last_result(TBM_ERROR_NONE);
682 num_planes = _tbm_surface_internal_get_num_planes(format);
684 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
685 _tbm_surface_mutex_unlock();
689 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
691 _tbm_surface_mutex_unlock();
697 tbm_surface_internal_get_bpp(tbm_format format)
701 _tbm_surface_mutex_lock();
702 _tbm_set_last_result(TBM_ERROR_NONE);
704 bpp = _tbm_surface_internal_get_bpp(format);
706 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
707 _tbm_surface_mutex_unlock();
711 _tbm_surface_mutex_unlock();
713 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
719 tbm_surface_internal_create_with_flags(int width, int height,
720 int format, int flags)
722 struct _tbm_bufmgr *bufmgr;
723 struct _tbm_surface *surf = NULL;
727 uint32_t bo_size = 0;
730 bool bufmgr_initialized = false;
732 void *bo_priv = NULL;
733 tbm_backend_bo_data *bo_data = NULL;
736 _tbm_surface_mutex_lock();
737 _tbm_set_last_result(TBM_ERROR_NONE);
739 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
740 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
742 if (!g_surface_bufmgr) {
743 _init_surface_bufmgr();
744 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
745 bufmgr_initialized = true;
748 bufmgr = g_surface_bufmgr;
749 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
750 TBM_ERR("The bufmgr is invalid\n");
751 goto check_valid_fail;
754 surf = calloc(1, sizeof(struct _tbm_surface));
756 /* LCOV_EXCL_START */
757 TBM_ERR("fail to alloc surf\n");
758 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
759 goto alloc_surf_fail;
763 surf->magic = TBM_SURFACE_MAGIC;
764 surf->bufmgr = bufmgr;
765 surf->info.width = width;
766 surf->info.height = height;
767 surf->info.format = format;
768 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
769 if (!surf->info.bpp) {
770 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
773 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
774 if (!surf->info.num_planes) {
775 TBM_ERR("fail to get num_planes. error(%s)\n", tbm_error_str(tbm_get_last_error()));
776 goto num_planes_fail;
780 /* get size, stride and offset bo_idx */
781 for (i = 0; i < surf->info.num_planes; i++) {
782 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
783 &offset, &stride, &bo_idx)) {
784 TBM_ERR("fail to query plane data\n");
785 goto query_plane_data_fail;
788 surf->info.planes[i].size = size;
789 surf->info.planes[i].offset = offset;
790 surf->info.planes[i].stride = stride;
791 surf->planes_bo_idx[i] = bo_idx;
796 for (i = 0; i < surf->info.num_planes; i++) {
797 surf->info.size += surf->info.planes[i].size;
799 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
800 surf->num_bos = surf->planes_bo_idx[i] + 1;
805 for (i = 0; i < surf->num_bos; i++) {
807 for (j = 0; j < surf->info.num_planes; j++) {
808 if (surf->planes_bo_idx[j] == i)
809 bo_size += surf->info.planes[j].size;
812 if (bufmgr->backend_module_data) {
813 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
814 /* LCOV_EXCL_START */
815 bo = calloc(1, sizeof(struct _tbm_bo));
817 TBM_ERR("fail to alloc bo struct\n");
818 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
822 bo->bufmgr = surf->bufmgr;
824 _tbm_bufmgr_mutex_lock();
826 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format(bufmgr->bufmgr_data, format, i,
827 width, height, flags, &error);
829 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
830 _tbm_set_last_result(error);
832 _tbm_bufmgr_mutex_unlock();
835 bo->bo_data = bo_data;
839 LIST_INITHEAD(&bo->user_data_list);
841 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
843 _tbm_bufmgr_mutex_unlock();
847 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
848 bo = calloc(1, sizeof(struct _tbm_bo));
850 TBM_ERR("fail to alloc bo struct\n");
851 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
855 bo->bufmgr = surf->bufmgr;
857 _tbm_bufmgr_mutex_lock();
859 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format(bufmgr->bufmgr_data, width, height, surf->info.bpp/8, format, flags, i, &error);
861 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
862 _tbm_set_last_result(error);
864 _tbm_bufmgr_mutex_unlock();
867 bo->bo_data = bo_data;
871 LIST_INITHEAD(&bo->user_data_list);
873 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
875 _tbm_bufmgr_mutex_unlock();
880 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
882 TBM_ERR("fail to alloc bo idx:%d\n", i);
887 if (bufmgr->backend->surface_bo_alloc) {
888 /* LCOV_EXCL_START */
889 bo = calloc(1, sizeof(struct _tbm_bo));
891 TBM_ERR("fail to alloc bo struct\n");
892 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
896 bo->bufmgr = surf->bufmgr;
898 _tbm_bufmgr_mutex_lock();
900 bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
902 TBM_ERR("fail to alloc bo priv\n");
903 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
905 _tbm_bufmgr_mutex_unlock();
912 LIST_INITHEAD(&bo->user_data_list);
914 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
916 _tbm_bufmgr_mutex_unlock();
921 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
923 TBM_ERR("fail to alloc bo idx:%d\n", i);
929 _tbm_bo_set_surface(surf->bos[i], surf);
932 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
933 _tbm_surface_internal_format_to_str(format), flags, surf);
935 LIST_INITHEAD(&surf->user_data_list);
936 LIST_INITHEAD(&surf->debug_data_list);
938 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
940 _tbm_surface_mutex_unlock();
944 /* LCOV_EXCL_START */
946 for (j = 0; j < i; j++) {
948 tbm_bo_unref(surf->bos[j]);
950 query_plane_data_fail:
956 if (bufmgr_initialized && bufmgr) {
957 LIST_DELINIT(&bufmgr->surf_list);
958 _deinit_surface_bufmgr();
960 _tbm_surface_mutex_unlock();
962 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
964 _tbm_surface_internal_format_to_str(format), flags);
971 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
972 tbm_bo *bos, int num)
974 struct _tbm_bufmgr *bufmgr;
975 struct _tbm_surface *surf = NULL;
977 bool bufmgr_initialized = false;
979 _tbm_surface_mutex_lock();
980 _tbm_set_last_result(TBM_ERROR_NONE);
982 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
983 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
984 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
985 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
986 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
988 if (!g_surface_bufmgr) {
989 _init_surface_bufmgr();
990 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
991 bufmgr_initialized = true;
994 bufmgr = g_surface_bufmgr;
995 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
996 TBM_ERR("fail to validate the Bufmgr.\n");
997 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
998 goto check_valid_fail;
1001 surf = calloc(1, sizeof(struct _tbm_surface));
1003 /* LCOV_EXCL_START */
1004 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1005 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1006 goto alloc_surf_fail;
1007 /* LCOV_EXCL_STOP */
1010 surf->magic = TBM_SURFACE_MAGIC;
1011 surf->bufmgr = bufmgr;
1012 surf->info.width = info->width;
1013 surf->info.height = info->height;
1014 surf->info.format = info->format;
1016 surf->info.bpp = info->bpp;
1018 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1019 if (!surf->info.bpp) {
1020 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1024 surf->info.num_planes = info->num_planes;
1027 /* get size, stride and offset */
1028 for (i = 0; i < info->num_planes; i++) {
1029 surf->info.planes[i].offset = info->planes[i].offset;
1030 surf->info.planes[i].stride = info->planes[i].stride;
1032 if (info->planes[i].size > 0)
1033 surf->info.planes[i].size = info->planes[i].size;
1035 uint32_t size = 0, offset = 0, stride = 0;
1038 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1039 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1040 goto plane_data_fail;
1042 surf->info.planes[i].size = size;
1046 surf->planes_bo_idx[i] = 0;
1048 surf->planes_bo_idx[i] = i;
1051 if (info->size > 0) {
1052 surf->info.size = info->size;
1054 surf->info.size = 0;
1055 for (i = 0; i < info->num_planes; i++)
1056 surf->info.size += surf->info.planes[i].size;
1059 surf->flags = TBM_BO_DEFAULT;
1061 /* create only one bo */
1062 surf->num_bos = num;
1063 for (i = 0; i < num; i++) {
1064 if (bos[i] == NULL) {
1065 TBM_ERR("bos[%d] is null.\n", i);
1066 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1070 surf->bos[i] = tbm_bo_ref(bos[i]);
1071 _tbm_bo_set_surface(bos[i], surf);
1074 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1075 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1077 LIST_INITHEAD(&surf->user_data_list);
1078 LIST_INITHEAD(&surf->debug_data_list);
1080 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1082 _tbm_surface_mutex_unlock();
1086 /* LCOV_EXCL_START */
1090 for (i = 0; i < num; i++) {
1092 tbm_bo_unref(surf->bos[i]);
1097 if (bufmgr_initialized && bufmgr) {
1098 LIST_DELINIT(&bufmgr->surf_list);
1099 _deinit_surface_bufmgr();
1101 _tbm_surface_mutex_unlock();
1103 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1104 info->width, info->height,
1105 _tbm_surface_internal_format_to_str(info->format), num);
1106 /* LCOV_EXCL_STOP */
1112 tbm_surface_internal_destroy(tbm_surface_h surface)
1114 _tbm_surface_mutex_lock();
1115 _tbm_set_last_result(TBM_ERROR_NONE);
1117 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1121 if (surface->refcnt > 0) {
1122 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1123 _tbm_surface_mutex_unlock();
1127 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1129 if (surface->refcnt == 0)
1130 _tbm_surface_internal_destroy(surface);
1132 _tbm_surface_mutex_unlock();
1136 tbm_surface_internal_ref(tbm_surface_h surface)
1138 _tbm_surface_mutex_lock();
1139 _tbm_set_last_result(TBM_ERROR_NONE);
1141 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1145 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1147 _tbm_surface_mutex_unlock();
1151 tbm_surface_internal_unref(tbm_surface_h surface)
1153 _tbm_surface_mutex_lock();
1154 _tbm_set_last_result(TBM_ERROR_NONE);
1156 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1160 if (surface->refcnt > 0) {
1161 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1162 _tbm_surface_mutex_unlock();
1166 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1168 if (surface->refcnt == 0)
1169 _tbm_surface_internal_destroy(surface);
1171 _tbm_surface_mutex_unlock();
1175 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1177 struct _tbm_surface *surf;
1180 _tbm_surface_mutex_lock();
1181 _tbm_set_last_result(TBM_ERROR_NONE);
1183 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1185 surf = (struct _tbm_surface *)surface;
1186 num = surf->num_bos;
1189 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1191 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1193 _tbm_surface_mutex_unlock();
1199 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1201 struct _tbm_surface *surf;
1204 _tbm_surface_mutex_lock();
1205 _tbm_set_last_result(TBM_ERROR_NONE);
1207 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1208 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1210 surf = (struct _tbm_surface *)surface;
1211 bo = surf->bos[bo_idx];
1213 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1215 _tbm_surface_mutex_unlock();
1221 tbm_surface_internal_get_size(tbm_surface_h surface)
1223 struct _tbm_surface *surf;
1226 _tbm_surface_mutex_lock();
1227 _tbm_set_last_result(TBM_ERROR_NONE);
1229 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1231 surf = (struct _tbm_surface *)surface;
1232 size = surf->info.size;
1234 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1236 _tbm_surface_mutex_unlock();
1242 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1243 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1245 struct _tbm_surface *surf;
1247 _tbm_surface_mutex_lock();
1248 _tbm_set_last_result(TBM_ERROR_NONE);
1250 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1251 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1253 surf = (struct _tbm_surface *)surface;
1255 if (plane_idx >= surf->info.num_planes) {
1256 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1257 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1258 _tbm_surface_mutex_unlock();
1263 *size = surf->info.planes[plane_idx].size;
1266 *offset = surf->info.planes[plane_idx].offset;
1269 *pitch = surf->info.planes[plane_idx].stride;
1271 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1272 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1273 surf->info.planes[plane_idx].stride);
1275 _tbm_surface_mutex_unlock();
1281 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1282 tbm_surface_info_s *info, int map)
1284 struct _tbm_surface *surf;
1285 tbm_bo_handle bo_handles[4];
1288 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1291 _tbm_surface_mutex_lock();
1292 _tbm_set_last_result(TBM_ERROR_NONE);
1294 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1296 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1298 surf = (struct _tbm_surface *)surface;
1300 memset(info, 0x00, sizeof(tbm_surface_info_s));
1301 info->width = surf->info.width;
1302 info->height = surf->info.height;
1303 info->format = surf->info.format;
1304 info->bpp = surf->info.bpp;
1305 info->size = surf->info.size;
1306 info->num_planes = surf->info.num_planes;
1308 for (i = 0; i < surf->info.num_planes; i++) {
1309 info->planes[i].size = surf->info.planes[i].size;
1310 info->planes[i].offset = surf->info.planes[i].offset;
1311 info->planes[i].stride = surf->info.planes[i].stride;
1312 planes_bo_idx[i] = surf->planes_bo_idx[i];
1315 for (i = 0; i < surf->num_bos; i++)
1316 bos[i] = surf->bos[i];
1318 num_bos = surf->num_bos;
1321 _tbm_surface_mutex_unlock();
1322 for (i = 0; i < num_bos; i++) {
1323 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1324 if (bo_handles[i].ptr == NULL) {
1325 for (j = 0; j < i; j++)
1326 tbm_bo_unmap(bos[j]);
1328 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1332 _tbm_surface_mutex_lock();
1334 for (i = 0; i < num_bos; i++) {
1335 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1336 if (bo_handles[i].ptr == NULL) {
1337 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1338 _tbm_surface_mutex_unlock();
1344 for (i = 0; i < info->num_planes; i++) {
1345 if (bo_handles[planes_bo_idx[i]].ptr)
1346 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1349 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1351 _tbm_surface_mutex_unlock();
1357 tbm_surface_internal_unmap(tbm_surface_h surface)
1359 struct _tbm_surface *surf;
1362 _tbm_surface_mutex_lock();
1363 _tbm_set_last_result(TBM_ERROR_NONE);
1365 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1367 surf = (struct _tbm_surface *)surface;
1369 for (i = 0; i < surf->num_bos; i++)
1370 tbm_bo_unmap(surf->bos[i]);
1372 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1374 _tbm_surface_mutex_unlock();
1378 tbm_surface_internal_get_width(tbm_surface_h surface)
1380 struct _tbm_surface *surf;
1383 _tbm_surface_mutex_lock();
1384 _tbm_set_last_result(TBM_ERROR_NONE);
1386 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1388 surf = (struct _tbm_surface *)surface;
1389 width = surf->info.width;
1391 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1393 _tbm_surface_mutex_unlock();
1399 tbm_surface_internal_get_height(tbm_surface_h surface)
1401 struct _tbm_surface *surf;
1402 unsigned int height;
1404 _tbm_surface_mutex_lock();
1405 _tbm_set_last_result(TBM_ERROR_NONE);
1407 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1409 surf = (struct _tbm_surface *)surface;
1410 height = surf->info.height;
1412 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1414 _tbm_surface_mutex_unlock();
1421 tbm_surface_internal_get_format(tbm_surface_h surface)
1423 struct _tbm_surface *surf;
1426 _tbm_surface_mutex_lock();
1427 _tbm_set_last_result(TBM_ERROR_NONE);
1429 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1431 surf = (struct _tbm_surface *)surface;
1432 format = surf->info.format;
1434 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1436 _tbm_surface_mutex_unlock();
1442 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1444 struct _tbm_surface *surf;
1447 _tbm_surface_mutex_lock();
1448 _tbm_set_last_result(TBM_ERROR_NONE);
1450 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1451 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1453 surf = (struct _tbm_surface *)surface;
1454 bo_idx = surf->planes_bo_idx[plane_idx];
1456 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1458 _tbm_surface_mutex_unlock();
1464 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1465 tbm_data_free data_free_func)
1467 tbm_user_data *data;
1469 _tbm_surface_mutex_lock();
1470 _tbm_set_last_result(TBM_ERROR_NONE);
1472 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1474 /* check if the data according to the key exist if so, return false. */
1475 data = user_data_lookup(&surface->user_data_list, key);
1477 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1478 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1479 _tbm_surface_mutex_unlock();
1483 data = user_data_create(key, data_free_func);
1485 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1486 _tbm_surface_mutex_unlock();
1490 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1492 LIST_ADD(&data->item_link, &surface->user_data_list);
1494 _tbm_surface_mutex_unlock();
1500 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1503 tbm_user_data *old_data;
1505 _tbm_surface_mutex_lock();
1506 _tbm_set_last_result(TBM_ERROR_NONE);
1508 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1510 old_data = user_data_lookup(&surface->user_data_list, key);
1512 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1513 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1514 _tbm_surface_mutex_unlock();
1518 if (old_data->data && old_data->free_func)
1519 old_data->free_func(old_data->data);
1521 old_data->data = data;
1523 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1525 _tbm_surface_mutex_unlock();
1531 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1534 tbm_user_data *old_data;
1536 _tbm_surface_mutex_lock();
1537 _tbm_set_last_result(TBM_ERROR_NONE);
1539 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1542 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1543 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1544 _tbm_surface_mutex_unlock();
1549 old_data = user_data_lookup(&surface->user_data_list, key);
1551 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1552 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1553 _tbm_surface_mutex_unlock();
1557 *data = old_data->data;
1559 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1561 _tbm_surface_mutex_unlock();
1567 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1570 tbm_user_data *old_data = (void *)0;
1572 _tbm_surface_mutex_lock();
1573 _tbm_set_last_result(TBM_ERROR_NONE);
1575 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1577 old_data = user_data_lookup(&surface->user_data_list, key);
1579 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1580 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1581 _tbm_surface_mutex_unlock();
1585 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1587 user_data_delete(old_data);
1589 _tbm_surface_mutex_unlock();
1594 /* LCOV_EXCL_START */
1596 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1598 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1600 return surface->debug_pid;
1604 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1606 _tbm_surface_mutex_lock();
1607 _tbm_set_last_result(TBM_ERROR_NONE);
1609 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1611 surface->debug_pid = pid;
1613 _tbm_surface_mutex_unlock();
1616 static tbm_surface_debug_data *
1617 _tbm_surface_internal_debug_data_create(char *key, char *value)
1619 tbm_surface_debug_data *debug_data = NULL;
1621 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1623 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1624 TBM_ERR("fail to allocate the debug_data.");
1628 if (key) debug_data->key = strdup(key);
1629 if (value) debug_data->value = strdup(value);
1635 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1637 tbm_surface_debug_data *debug_data = NULL;
1638 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1639 tbm_bufmgr bufmgr = NULL;
1641 _tbm_surface_mutex_lock();
1642 _tbm_set_last_result(TBM_ERROR_NONE);
1644 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1645 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1647 bufmgr = surface->bufmgr;
1649 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1651 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1652 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1654 if (!strcmp(old_data->key, key)) {
1655 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1656 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1657 goto add_debug_key_list;
1660 if (old_data->value)
1661 free(old_data->value);
1664 old_data->value = strdup(value);
1666 old_data->value = NULL;
1668 goto add_debug_key_list;
1674 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1676 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1677 _tbm_surface_mutex_unlock();
1681 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1683 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1686 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1687 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1688 if (!strcmp(old_data->key, key)) {
1689 _tbm_surface_mutex_unlock();
1695 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1696 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1698 _tbm_surface_mutex_unlock();
1704 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1706 tbm_surface_debug_data *old_data = NULL;
1708 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1710 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1711 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1712 if (!strcmp(old_data->key, key))
1713 return old_data->value;
1720 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1721 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1723 struct _tbm_surface_dump_buf_info {
1733 tbm_surface_info_s info;
1735 struct list_head link;
1738 struct _tbm_surface_dump_info {
1739 char *path; // copy???
1742 struct list_head *link;
1743 struct list_head surface_list; /* link of surface */
1746 static tbm_surface_dump_info *g_dump_info = NULL;
1747 static const char *dump_postfix[2] = {"png", "yuv"};
1748 static double scale_factor;
1751 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1752 void *data2, int size2, void *data3, int size3)
1755 unsigned int *blocks;
1757 if (_tbm_surface_check_file_is_symbolic_link(file))
1758 TBM_ERR("%s is symbolic link\n", file);
1760 fp = fopen(file, "w+");
1761 TBM_RETURN_IF_FAIL(fp != NULL);
1763 blocks = (unsigned int *)data1;
1764 fwrite(blocks, 1, size1, fp);
1767 blocks = (unsigned int *)data2;
1768 fwrite(blocks, 1, size2, fp);
1772 blocks = (unsigned int *)data3;
1773 fwrite(blocks, 1, size3, fp);
1780 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1782 unsigned int *blocks = (unsigned int *)data;
1785 png_bytep *row_pointers;
1788 if (_tbm_surface_check_file_is_symbolic_link(file))
1789 TBM_ERR("%s is symbolic link\n", file);
1791 fp = fopen(file, "wb");
1792 TBM_RETURN_IF_FAIL(fp != NULL);
1794 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1797 TBM_ERR("fail to create a png write structure.\n");
1802 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1804 TBM_ERR("fail to create a png info structure.\n");
1805 png_destroy_write_struct(&pPngStruct, NULL);
1810 if (setjmp(png_jmpbuf(pPngStruct))) {
1811 /* if png has problem of writing the file, we get here */
1812 TBM_ERR("fail to write png file.\n");
1813 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1818 png_init_io(pPngStruct, fp);
1819 if (format == TBM_FORMAT_XRGB8888) {
1821 png_set_IHDR(pPngStruct,
1828 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1831 png_set_IHDR(pPngStruct,
1836 PNG_COLOR_TYPE_RGBA,
1838 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1841 png_set_bgr(pPngStruct);
1842 png_write_info(pPngStruct, pPngInfo);
1844 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1845 if (!row_pointers) {
1846 TBM_ERR("fail to allocate the png row_pointers.\n");
1847 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1852 for (y = 0; y < height; ++y) {
1856 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1858 TBM_ERR("fail to allocate the png row.\n");
1859 for (x = 0; x < y; x++)
1860 png_free(pPngStruct, row_pointers[x]);
1861 png_free(pPngStruct, row_pointers);
1862 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1866 row_pointers[y] = (png_bytep)row;
1868 for (x = 0; x < width; ++x) {
1869 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1871 if (pixel_size == 3) { // XRGB8888
1872 row[x * pixel_size] = (curBlock & 0xFF);
1873 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1874 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1875 } else { // ARGB8888
1876 row[x * pixel_size] = (curBlock & 0xFF);
1877 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1878 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1879 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1884 png_write_image(pPngStruct, row_pointers);
1885 png_write_end(pPngStruct, pPngInfo);
1887 for (y = 0; y < height; y++)
1888 png_free(pPngStruct, row_pointers[y]);
1889 png_free(pPngStruct, row_pointers);
1891 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1897 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1899 TBM_RETURN_IF_FAIL(path != NULL);
1900 TBM_RETURN_IF_FAIL(w > 0);
1901 TBM_RETURN_IF_FAIL(h > 0);
1902 TBM_RETURN_IF_FAIL(count > 0);
1904 tbm_surface_dump_buf_info *buf_info = NULL;
1905 tbm_surface_h tbm_surface;
1906 tbm_surface_info_s info;
1911 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1915 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1916 TBM_RETURN_IF_FAIL(g_dump_info);
1918 LIST_INITHEAD(&g_dump_info->surface_list);
1919 g_dump_info->count = 0;
1920 g_dump_info->dump_max = count;
1922 /* get buffer size */
1923 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1924 if (tbm_surface == NULL) {
1925 TBM_ERR("tbm_surface_create fail\n");
1931 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1932 TBM_ERR("tbm_surface_get_info fail\n");
1933 tbm_surface_destroy(tbm_surface);
1938 buffer_size = info.size;
1939 tbm_surface_destroy(tbm_surface);
1941 /* create dump lists */
1942 for (i = 0; i < count; i++) {
1945 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1946 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1948 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1950 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1955 buf_info->index = i;
1957 buf_info->size = buffer_size;
1959 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1962 g_dump_info->path = path;
1963 g_dump_info->link = &g_dump_info->surface_list;
1967 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1972 /* free resources */
1973 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1974 tbm_surface_dump_buf_info *tmp;
1976 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1977 tbm_bo_unref(buf_info->bo);
1978 LIST_DEL(&buf_info->link);
1983 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1992 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1999 tbm_surface_internal_dump_start(path, w, h, count);
2000 scale_factor = scale;
2004 tbm_surface_internal_dump_end(void)
2006 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2007 tbm_bo_handle bo_handle;
2012 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2019 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2022 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2023 if (bo_handle.ptr == NULL) {
2024 tbm_bo_unref(buf_info->bo);
2025 LIST_DEL(&buf_info->link);
2030 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2031 TBM_INFO("Dump File.. %s generated.\n", file);
2033 if (buf_info->dirty) {
2034 void *ptr1 = NULL, *ptr2 = NULL;
2036 switch (buf_info->info.format) {
2037 case TBM_FORMAT_ARGB8888:
2038 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2039 buf_info->info.planes[0].stride >> 2,
2040 buf_info->info.height,
2041 buf_info->info.planes[0].stride,
2042 TBM_FORMAT_ARGB8888);
2044 case TBM_FORMAT_XRGB8888:
2045 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2046 buf_info->info.planes[0].stride >> 2,
2047 buf_info->info.height,
2048 buf_info->info.planes[0].stride,
2049 TBM_FORMAT_XRGB8888);
2051 case TBM_FORMAT_YVU420:
2052 case TBM_FORMAT_YUV420:
2053 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2054 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
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),
2060 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2062 case TBM_FORMAT_NV12:
2063 case TBM_FORMAT_NV21:
2064 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2065 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2066 buf_info->info.planes[0].stride * buf_info->info.height,
2068 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2071 case TBM_FORMAT_YUYV:
2072 case TBM_FORMAT_UYVY:
2073 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2074 buf_info->info.planes[0].stride * buf_info->info.height,
2078 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2081 } else if (buf_info->dirty_shm)
2082 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2083 buf_info->shm_stride >> 2,
2085 buf_info->shm_stride, 0);
2087 tbm_bo_unmap(buf_info->bo);
2088 tbm_bo_unref(buf_info->bo);
2089 LIST_DEL(&buf_info->link);
2096 TBM_INFO("Dump End..\n");
2099 static pixman_format_code_t
2100 _tbm_surface_internal_pixman_format_get(tbm_format format)
2103 case TBM_FORMAT_ARGB8888:
2104 return PIXMAN_a8r8g8b8;
2105 case TBM_FORMAT_XRGB8888:
2106 return PIXMAN_x8r8g8b8;
2115 * This function supports only if a buffer has below formats.
2116 * - TBM_FORMAT_ARGB8888
2117 * - TBM_FORMAT_XRGB8888
2119 static tbm_surface_error_e
2120 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2121 int format, int src_stride, int src_w, int src_h,
2122 int dst_stride, int dst_w, int dst_h)
2124 pixman_image_t *src_img = NULL, *dst_img = NULL;
2125 pixman_format_code_t pixman_format;
2126 pixman_transform_t t;
2127 struct pixman_f_transform ft;
2128 double scale_x, scale_y;
2130 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2131 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2133 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2134 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2137 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2138 (uint32_t*)src_ptr, src_stride);
2139 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2142 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2143 (uint32_t*)dst_ptr, dst_stride);
2144 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2146 pixman_f_transform_init_identity(&ft);
2148 scale_x = (double)src_w / dst_w;
2149 scale_y = (double)src_h / dst_h;
2151 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2152 pixman_f_transform_translate(&ft, NULL, 0, 0);
2153 pixman_transform_from_pixman_f_transform(&t, &ft);
2154 pixman_image_set_transform(src_img, &t);
2156 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2157 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2159 pixman_image_unref(src_img);
2160 pixman_image_unref(dst_img);
2162 return TBM_SURFACE_ERROR_NONE;
2166 pixman_image_unref(src_img);
2168 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2171 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2172 #define KEY_LEN 5 // "_XXXX"
2173 #define KEYS_LEN KEY_LEN * MAX_BOS
2175 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2177 char *keys, temp_key[KEY_LEN + 1];
2178 struct _tbm_surface *surf;
2182 _tbm_surface_mutex_lock();
2184 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2186 surf = (struct _tbm_surface *)surface;
2188 num_bos = surf->num_bos;
2189 if (num_bos > MAX_BOS)
2192 keys = calloc(KEYS_LEN + 1, sizeof(char));
2194 TBM_ERR("Failed to alloc memory");
2195 _tbm_surface_mutex_unlock();
2199 for (i = 0; i < num_bos; i++) {
2200 memset(temp_key, 0x00, KEY_LEN + 1);
2202 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2203 strncat(keys, temp_key, KEY_LEN + 1);
2206 _tbm_surface_mutex_unlock();
2211 static void _tbm_surface_internal_put_keys(char *keys)
2218 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2220 TBM_RETURN_IF_FAIL(surface != NULL);
2221 TBM_RETURN_IF_FAIL(type != NULL);
2223 tbm_surface_dump_buf_info *buf_info;
2224 struct list_head *next_link;
2225 tbm_surface_info_s info;
2226 tbm_bo_handle bo_handle;
2227 const char *postfix;
2228 const char *format = NULL;
2235 next_link = g_dump_info->link->next;
2236 TBM_RETURN_IF_FAIL(next_link != NULL);
2238 if (next_link == &g_dump_info->surface_list) {
2239 next_link = next_link->next;
2240 TBM_RETURN_IF_FAIL(next_link != NULL);
2243 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2244 TBM_RETURN_IF_FAIL(buf_info != NULL);
2246 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2247 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2249 if (scale_factor > 0.0) {
2252 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2253 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2254 _tbm_surface_internal_format_to_str(info.format));
2255 tbm_surface_unmap(surface);
2259 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2261 buf_info->info.width = info.width * scale_factor;
2262 buf_info->info.height = info.height * scale_factor;
2263 buf_info->info.format = info.format;
2264 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2265 if (!buf_info->info.bpp) {
2266 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2267 tbm_surface_unmap(surface);
2270 buf_info->info.num_planes = 1;
2271 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2272 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2274 if (buf_info->info.size > buf_info->size) {
2275 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2276 buf_info->info.size, buf_info->size);
2277 tbm_surface_unmap(surface);
2281 if (info.size > buf_info->size) {
2282 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2283 info.size, buf_info->size);
2284 tbm_surface_unmap(surface);
2288 /* make the file information */
2289 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2292 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2293 postfix = dump_postfix[0];
2294 format = _tbm_surface_internal_format_to_str(info.format);
2296 postfix = dump_postfix[1];
2298 keys = _tbm_surface_internal_get_keys(surface);
2300 TBM_ERR("fail to get keys");
2301 tbm_surface_unmap(surface);
2306 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2307 if (!bo_handle.ptr) {
2308 TBM_ERR("fail to map bo");
2309 _tbm_surface_internal_put_keys(keys);
2310 tbm_surface_unmap(surface);
2313 memset(bo_handle.ptr, 0x00, buf_info->size);
2315 switch (info.format) {
2316 case TBM_FORMAT_ARGB8888:
2317 case TBM_FORMAT_XRGB8888:
2318 snprintf(buf_info->name, sizeof(buf_info->name),
2319 "%10.3f_%03d%s_%p_%s-%s.%s",
2320 _tbm_surface_internal_get_time(),
2321 g_dump_info->count++, keys, surface, format, type, postfix);
2323 if (scale_factor > 0.0) {
2324 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2326 buf_info->info.format,
2327 info.planes[0].stride,
2328 info.width, info.height,
2329 buf_info->info.planes[0].stride,
2330 buf_info->info.width,
2331 buf_info->info.height);
2332 if (ret != TBM_SURFACE_ERROR_NONE) {
2333 TBM_ERR("fail to scale buffer");
2334 tbm_bo_unmap(buf_info->bo);
2335 _tbm_surface_internal_put_keys(keys);
2336 tbm_surface_unmap(surface);
2340 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2342 case TBM_FORMAT_YVU420:
2343 case TBM_FORMAT_YUV420:
2344 snprintf(buf_info->name, sizeof(buf_info->name),
2345 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2346 _tbm_surface_internal_get_time(),
2347 g_dump_info->count++, keys, type, info.planes[0].stride,
2348 info.height, FOURCC_STR(info.format), postfix);
2349 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2350 bo_handle.ptr += info.planes[0].stride * info.height;
2351 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2352 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2353 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2355 case TBM_FORMAT_NV12:
2356 case TBM_FORMAT_NV21:
2357 snprintf(buf_info->name, sizeof(buf_info->name),
2358 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2359 _tbm_surface_internal_get_time(),
2360 g_dump_info->count++, keys, type, info.planes[0].stride,
2361 info.height, FOURCC_STR(info.format), postfix);
2362 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2363 bo_handle.ptr += info.planes[0].stride * info.height;
2364 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2366 case TBM_FORMAT_YUYV:
2367 case TBM_FORMAT_UYVY:
2368 snprintf(buf_info->name, sizeof(buf_info->name),
2369 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2370 _tbm_surface_internal_get_time(),
2371 g_dump_info->count++, keys, type, info.planes[0].stride,
2372 info.height, FOURCC_STR(info.format), postfix);
2373 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2376 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2377 tbm_bo_unmap(buf_info->bo);
2378 _tbm_surface_internal_put_keys(keys);
2379 tbm_surface_unmap(surface);
2383 tbm_bo_unmap(buf_info->bo);
2385 _tbm_surface_internal_put_keys(keys);
2387 tbm_surface_unmap(surface);
2389 buf_info->dirty = 1;
2390 buf_info->dirty_shm = 0;
2392 if (g_dump_info->count == 1000)
2393 g_dump_info->count = 0;
2395 g_dump_info->link = next_link;
2397 TBM_INFO("Dump %s \n", buf_info->name);
2400 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2403 TBM_RETURN_IF_FAIL(ptr != NULL);
2404 TBM_RETURN_IF_FAIL(w > 0);
2405 TBM_RETURN_IF_FAIL(h > 0);
2406 TBM_RETURN_IF_FAIL(stride > 0);
2407 TBM_RETURN_IF_FAIL(type != NULL);
2409 tbm_surface_dump_buf_info *buf_info;
2410 struct list_head *next_link;
2411 tbm_bo_handle bo_handle;
2412 int ret, size, dw = 0, dh = 0, dstride = 0;
2417 next_link = g_dump_info->link->next;
2418 TBM_RETURN_IF_FAIL(next_link != NULL);
2420 if (next_link == &g_dump_info->surface_list) {
2421 next_link = next_link->next;
2422 TBM_RETURN_IF_FAIL(next_link != NULL);
2425 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2426 TBM_RETURN_IF_FAIL(buf_info != NULL);
2428 if (scale_factor > 0.0) {
2431 dw = w * scale_factor;
2432 dh = h * scale_factor;
2434 size = dstride * dh;
2438 if (size > buf_info->size) {
2439 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2440 size, buf_info->size);
2445 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2446 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2448 memset(bo_handle.ptr, 0x00, buf_info->size);
2449 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2451 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2452 _tbm_surface_internal_get_time(),
2453 g_dump_info->count++, type, dump_postfix[0]);
2454 if (scale_factor > 0.0) {
2455 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2456 TBM_FORMAT_ARGB8888, stride,
2457 w, h, dstride, dw, dh);
2458 if (ret != TBM_SURFACE_ERROR_NONE) {
2459 TBM_ERR("fail to scale buffer");
2460 tbm_bo_unmap(buf_info->bo);
2463 buf_info->shm_stride = dstride;
2464 buf_info->shm_h = dh;
2466 memcpy(bo_handle.ptr, ptr, size);
2467 buf_info->shm_stride = stride;
2468 buf_info->shm_h = h;
2471 tbm_bo_unmap(buf_info->bo);
2473 buf_info->dirty = 0;
2474 buf_info->dirty_shm = 1;
2476 if (g_dump_info->count == 1000)
2477 g_dump_info->count = 0;
2479 g_dump_info->link = next_link;
2481 TBM_INFO("Dump %s \n", buf_info->name);
2485 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2487 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2488 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2489 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2491 tbm_surface_info_s info;
2492 const char *postfix;
2496 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2497 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2499 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2500 postfix = dump_postfix[0];
2502 postfix = dump_postfix[1];
2504 if (strcmp(postfix, type)) {
2505 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2506 tbm_surface_unmap(surface);
2510 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2512 if (!access(file, 0)) {
2513 TBM_ERR("can't capture buffer, exist file %s", file);
2514 tbm_surface_unmap(surface);
2518 switch (info.format) {
2519 case TBM_FORMAT_ARGB8888:
2520 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2523 info.planes[0].stride,
2524 TBM_FORMAT_ARGB8888);
2526 case TBM_FORMAT_XRGB8888:
2527 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2530 info.planes[0].stride,
2531 TBM_FORMAT_XRGB8888);
2533 case TBM_FORMAT_YVU420:
2534 case TBM_FORMAT_YUV420:
2535 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2536 info.planes[0].stride * info.height,
2538 info.planes[1].stride * (info.height >> 1),
2540 info.planes[2].stride * (info.height >> 1));
2542 case TBM_FORMAT_NV12:
2543 case TBM_FORMAT_NV21:
2544 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2545 info.planes[0].stride * info.height,
2547 info.planes[1].stride * (info.height >> 1),
2550 case TBM_FORMAT_YUYV:
2551 case TBM_FORMAT_UYVY:
2552 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2553 info.planes[0].stride * info.height,
2557 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2558 tbm_surface_unmap(surface);
2562 tbm_surface_unmap(surface);
2564 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2570 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2571 const char *path, const char *name, const char *type)
2573 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2574 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2575 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2576 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2577 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2578 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2582 if (strcmp(dump_postfix[0], type)) {
2583 TBM_ERR("Not supported type:%s'", type);
2587 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2589 if (!access(file, 0)) {
2590 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2594 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2596 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2602 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2604 struct _tbm_surface *surf;
2606 _tbm_surface_mutex_lock();
2607 _tbm_set_last_result(TBM_ERROR_NONE);
2609 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2610 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2611 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2613 surf = (struct _tbm_surface *)surface;
2617 surf->damage.width = width;
2618 surf->damage.height = height;
2620 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2621 surface, x, y, width, height);
2623 _tbm_surface_mutex_unlock();
2629 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2631 struct _tbm_surface *surf;
2633 _tbm_surface_mutex_lock();
2634 _tbm_set_last_result(TBM_ERROR_NONE);
2636 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2638 surf = (struct _tbm_surface *)surface;
2640 if (x) *x = surf->damage.x;
2641 if (y) *y = surf->damage.y;
2642 if (width) *width = surf->damage.width;
2643 if (height) *height = surf->damage.height;
2645 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2646 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2648 _tbm_surface_mutex_unlock();