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);
51 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
53 TBM_ERR("'%s' failed.\n", #cond);\
54 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
55 _tbm_surface_mutex_unlock();\
60 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
62 TBM_ERR("'%s' failed.\n", #cond);\
63 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
64 _tbm_surface_mutex_unlock();\
71 _tbm_surface_internal_get_time(void)
76 clock_gettime(CLOCK_MONOTONIC, &tp);
77 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
83 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
85 LIST_DEL(&debug_data->item_link);
87 if (debug_data->key) free(debug_data->key);
88 if (debug_data->value) free(debug_data->value);
93 _tbm_surface_internal_format_to_str(tbm_format format)
97 return "TBM_FORMAT_C8";
98 case TBM_FORMAT_RGB332:
99 return "TBM_FORMAT_RGB332";
100 case TBM_FORMAT_BGR233:
101 return "TBM_FORMAT_BGR233";
102 case TBM_FORMAT_XRGB4444:
103 return "TBM_FORMAT_XRGB4444";
104 case TBM_FORMAT_XBGR4444:
105 return "TBM_FORMAT_XBGR4444";
106 case TBM_FORMAT_RGBX4444:
107 return "TBM_FORMAT_RGBX4444";
108 case TBM_FORMAT_BGRX4444:
109 return "TBM_FORMAT_BGRX4444";
110 case TBM_FORMAT_ARGB4444:
111 return "TBM_FORMAT_ARGB4444";
112 case TBM_FORMAT_ABGR4444:
113 return "TBM_FORMAT_ABGR4444";
114 case TBM_FORMAT_RGBA4444:
115 return "TBM_FORMAT_RGBA4444";
116 case TBM_FORMAT_BGRA4444:
117 return "TBM_FORMAT_BGRA4444";
118 case TBM_FORMAT_XRGB1555:
119 return "TBM_FORMAT_XRGB1555";
120 case TBM_FORMAT_XBGR1555:
121 return "TBM_FORMAT_XBGR1555";
122 case TBM_FORMAT_RGBX5551:
123 return "TBM_FORMAT_RGBX5551";
124 case TBM_FORMAT_BGRX5551:
125 return "TBM_FORMAT_BGRX5551";
126 case TBM_FORMAT_ARGB1555:
127 return "TBM_FORMAT_ARGB1555";
128 case TBM_FORMAT_ABGR1555:
129 return "TBM_FORMAT_ABGR1555";
130 case TBM_FORMAT_RGBA5551:
131 return "TBM_FORMAT_RGBA5551";
132 case TBM_FORMAT_BGRA5551:
133 return "TBM_FORMAT_BGRA5551";
134 case TBM_FORMAT_RGB565:
135 return "TBM_FORMAT_RGB565";
136 case TBM_FORMAT_BGR565:
137 return "TBM_FORMAT_BGR565";
138 case TBM_FORMAT_RGB888:
139 return "TBM_FORMAT_RGB888";
140 case TBM_FORMAT_BGR888:
141 return "TBM_FORMAT_BGR888";
142 case TBM_FORMAT_XRGB8888:
143 return "TBM_FORMAT_XRGB8888";
144 case TBM_FORMAT_XBGR8888:
145 return "TBM_FORMAT_XBGR8888";
146 case TBM_FORMAT_RGBX8888:
147 return "TBM_FORMAT_RGBX8888";
148 case TBM_FORMAT_BGRX8888:
149 return "TBM_FORMAT_BGRX8888";
150 case TBM_FORMAT_ARGB8888:
151 return "TBM_FORMAT_ARGB8888";
152 case TBM_FORMAT_ABGR8888:
153 return "TBM_FORMAT_ABGR8888";
154 case TBM_FORMAT_RGBA8888:
155 return "TBM_FORMAT_RGBA8888";
156 case TBM_FORMAT_BGRA8888:
157 return "TBM_FORMAT_BGRA8888";
158 case TBM_FORMAT_XRGB2101010:
159 return "TBM_FORMAT_XRGB2101010";
160 case TBM_FORMAT_XBGR2101010:
161 return "TBM_FORMAT_XBGR2101010";
162 case TBM_FORMAT_RGBX1010102:
163 return "TBM_FORMAT_RGBX1010102";
164 case TBM_FORMAT_BGRX1010102:
165 return "TBM_FORMAT_BGRX1010102";
166 case TBM_FORMAT_ARGB2101010:
167 return "TBM_FORMAT_ARGB2101010";
168 case TBM_FORMAT_ABGR2101010:
169 return "TBM_FORMAT_ABGR2101010";
170 case TBM_FORMAT_RGBA1010102:
171 return "TBM_FORMAT_RGBA1010102";
172 case TBM_FORMAT_BGRA1010102:
173 return "TBM_FORMAT_BGRA1010102";
174 case TBM_FORMAT_YUYV:
175 return "TBM_FORMAT_YUYV";
176 case TBM_FORMAT_YVYU:
177 return "TBM_FORMAT_YVYU";
178 case TBM_FORMAT_UYVY:
179 return "TBM_FORMAT_UYVY";
180 case TBM_FORMAT_VYUY:
181 return "TBM_FORMAT_VYUY";
182 case TBM_FORMAT_AYUV:
183 return "TBM_FORMAT_AYUV";
184 case TBM_FORMAT_NV12:
185 return "TBM_FORMAT_NV12";
186 case TBM_FORMAT_NV21:
187 return "TBM_FORMAT_NV21";
188 case TBM_FORMAT_NV16:
189 return "TBM_FORMAT_NV16";
190 case TBM_FORMAT_NV61:
191 return "TBM_FORMAT_NV61";
192 case TBM_FORMAT_YUV410:
193 return "TBM_FORMAT_YUV410";
194 case TBM_FORMAT_YVU410:
195 return "TBM_FORMAT_YVU410";
196 case TBM_FORMAT_YUV411:
197 return "TBM_FORMAT_YUV411";
198 case TBM_FORMAT_YVU411:
199 return "TBM_FORMAT_YVU411";
200 case TBM_FORMAT_YUV420:
201 return "TBM_FORMAT_YUV420";
202 case TBM_FORMAT_YVU420:
203 return "TBM_FORMAT_YVU420";
204 case TBM_FORMAT_YUV422:
205 return "TBM_FORMAT_YUV422";
206 case TBM_FORMAT_YVU422:
207 return "TBM_FORMAT_YVU422";
208 case TBM_FORMAT_YUV444:
209 return "TBM_FORMAT_YUV444";
210 case TBM_FORMAT_YVU444:
211 return "TBM_FORMAT_YVU444";
212 case TBM_FORMAT_NV12MT:
213 return "TBM_FORMAT_NV12MT";
220 _tbm_surface_mutex_lock(void)
222 pthread_mutex_lock(&tbm_surface_lock);
226 _tbm_surface_mutex_unlock(void)
228 pthread_mutex_unlock(&tbm_surface_lock);
232 _init_surface_bufmgr(void)
234 g_surface_bufmgr = tbm_bufmgr_init(-1);
238 _deinit_surface_bufmgr(void)
240 if (!g_surface_bufmgr)
243 tbm_bufmgr_deinit(g_surface_bufmgr);
244 g_surface_bufmgr = NULL;
249 _tbm_surface_internal_magic_check(tbm_surface_h surface)
251 if (surface->magic != TBM_SURFACE_MAGIC)
258 _tbm_surface_internal_is_valid(tbm_surface_h surface)
261 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
262 TBM_ERR("error: No valid tbm_surface is NULL\n");
266 if (!_tbm_surface_internal_magic_check(surface)) {
267 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
268 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
276 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
277 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
279 TBM_RETURN_VAL_IF_FAIL(surface, 0);
280 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
282 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
283 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
287 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
288 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
289 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
290 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
292 if (bufmgr->use_hal_tbm) {
293 error = (tbm_error_e)hal_tbm_bufmgr_get_plane_data(bufmgr->hal_bufmgr, (hal_tbm_format)surf->info.format,
294 plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
295 /* LCOV_EXCL_START */
296 if (error == TBM_ERROR_NOT_SUPPORTED) {
297 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
299 } else if (error != TBM_ERROR_NONE) {
300 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
301 _tbm_set_last_result(error);
306 } else if (bufmgr->backend_module_data) {
307 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
308 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
312 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
313 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
314 if (error != TBM_ERROR_NONE) {
315 /* LCOV_EXCL_START */
316 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
317 _tbm_set_last_result(error);
323 if (!bufmgr->backend->surface_get_plane_data) {
324 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
328 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
329 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
331 /* LCOV_EXCL_START */
332 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
333 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
343 _tbm_surface_internal_destroy(tbm_surface_h surface)
346 tbm_bufmgr bufmgr = surface->bufmgr;
347 tbm_user_data *old_data = NULL, *tmp = NULL;
348 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
349 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
351 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
352 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
353 func_info->destroy_func(surface, func_info->user_data);
355 TBM_DBG("free destroy_funcs %p\n", surface);
356 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
357 LIST_DEL(&func_info->item_link);
362 /* destory the user_data_list */
363 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
364 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
365 TBM_DBG("free user_data\n");
366 user_data_delete(old_data);
370 for (i = 0; i < surface->num_bos; i++) {
371 surface->bos[i]->surface = NULL;
373 tbm_bo_unref(surface->bos[i]);
374 surface->bos[i] = NULL;
377 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
378 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
379 _tbm_surface_internal_debug_data_delete(debug_old_data);
382 LIST_DEL(&surface->item_link);
388 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
389 LIST_DELINIT(&bufmgr->surf_list);
391 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
392 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
393 _tbm_surface_internal_debug_data_delete(debug_old_data);
397 _deinit_surface_bufmgr();
401 /* LCOV_EXCL_START */
403 _tbm_surface_check_file_is_symbolic_link(const char* path)
410 if (stat(path, &sb) != 0)
413 if (S_ISLNK(sb.st_mode))
421 _tbm_surface_internal_get_num_planes(tbm_format format)
427 case TBM_FORMAT_RGB332:
428 case TBM_FORMAT_BGR233:
429 case TBM_FORMAT_XRGB4444:
430 case TBM_FORMAT_XBGR4444:
431 case TBM_FORMAT_RGBX4444:
432 case TBM_FORMAT_BGRX4444:
433 case TBM_FORMAT_ARGB4444:
434 case TBM_FORMAT_ABGR4444:
435 case TBM_FORMAT_RGBA4444:
436 case TBM_FORMAT_BGRA4444:
437 case TBM_FORMAT_XRGB1555:
438 case TBM_FORMAT_XBGR1555:
439 case TBM_FORMAT_RGBX5551:
440 case TBM_FORMAT_BGRX5551:
441 case TBM_FORMAT_ARGB1555:
442 case TBM_FORMAT_ABGR1555:
443 case TBM_FORMAT_RGBA5551:
444 case TBM_FORMAT_BGRA5551:
445 case TBM_FORMAT_RGB565:
446 case TBM_FORMAT_BGR565:
447 case TBM_FORMAT_RGB888:
448 case TBM_FORMAT_BGR888:
449 case TBM_FORMAT_XRGB8888:
450 case TBM_FORMAT_XBGR8888:
451 case TBM_FORMAT_RGBX8888:
452 case TBM_FORMAT_BGRX8888:
453 case TBM_FORMAT_ARGB8888:
454 case TBM_FORMAT_ABGR8888:
455 case TBM_FORMAT_RGBA8888:
456 case TBM_FORMAT_BGRA8888:
457 case TBM_FORMAT_XRGB2101010:
458 case TBM_FORMAT_XBGR2101010:
459 case TBM_FORMAT_RGBX1010102:
460 case TBM_FORMAT_BGRX1010102:
461 case TBM_FORMAT_ARGB2101010:
462 case TBM_FORMAT_ABGR2101010:
463 case TBM_FORMAT_RGBA1010102:
464 case TBM_FORMAT_BGRA1010102:
465 case TBM_FORMAT_YUYV:
466 case TBM_FORMAT_YVYU:
467 case TBM_FORMAT_UYVY:
468 case TBM_FORMAT_VYUY:
469 case TBM_FORMAT_AYUV:
472 case TBM_FORMAT_NV12:
473 case TBM_FORMAT_NV12MT:
474 case TBM_FORMAT_NV21:
475 case TBM_FORMAT_NV16:
476 case TBM_FORMAT_NV61:
479 case TBM_FORMAT_YUV410:
480 case TBM_FORMAT_YVU410:
481 case TBM_FORMAT_YUV411:
482 case TBM_FORMAT_YVU411:
483 case TBM_FORMAT_YUV420:
484 case TBM_FORMAT_YVU420:
485 case TBM_FORMAT_YUV422:
486 case TBM_FORMAT_YVU422:
487 case TBM_FORMAT_YUV444:
488 case TBM_FORMAT_YVU444:
493 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
501 _tbm_surface_internal_get_bpp(tbm_format format)
508 case TBM_FORMAT_RGB332:
509 case TBM_FORMAT_BGR233:
512 case TBM_FORMAT_XRGB4444:
513 case TBM_FORMAT_XBGR4444:
514 case TBM_FORMAT_RGBX4444:
515 case TBM_FORMAT_BGRX4444:
516 case TBM_FORMAT_ARGB4444:
517 case TBM_FORMAT_ABGR4444:
518 case TBM_FORMAT_RGBA4444:
519 case TBM_FORMAT_BGRA4444:
520 case TBM_FORMAT_XRGB1555:
521 case TBM_FORMAT_XBGR1555:
522 case TBM_FORMAT_RGBX5551:
523 case TBM_FORMAT_BGRX5551:
524 case TBM_FORMAT_ARGB1555:
525 case TBM_FORMAT_ABGR1555:
526 case TBM_FORMAT_RGBA5551:
527 case TBM_FORMAT_BGRA5551:
528 case TBM_FORMAT_RGB565:
529 case TBM_FORMAT_BGR565:
532 case TBM_FORMAT_RGB888:
533 case TBM_FORMAT_BGR888:
536 case TBM_FORMAT_XRGB8888:
537 case TBM_FORMAT_XBGR8888:
538 case TBM_FORMAT_RGBX8888:
539 case TBM_FORMAT_BGRX8888:
540 case TBM_FORMAT_ARGB8888:
541 case TBM_FORMAT_ABGR8888:
542 case TBM_FORMAT_RGBA8888:
543 case TBM_FORMAT_BGRA8888:
544 case TBM_FORMAT_XRGB2101010:
545 case TBM_FORMAT_XBGR2101010:
546 case TBM_FORMAT_RGBX1010102:
547 case TBM_FORMAT_BGRX1010102:
548 case TBM_FORMAT_ARGB2101010:
549 case TBM_FORMAT_ABGR2101010:
550 case TBM_FORMAT_RGBA1010102:
551 case TBM_FORMAT_BGRA1010102:
552 case TBM_FORMAT_YUYV:
553 case TBM_FORMAT_YVYU:
554 case TBM_FORMAT_UYVY:
555 case TBM_FORMAT_VYUY:
556 case TBM_FORMAT_AYUV:
559 case TBM_FORMAT_NV12:
560 case TBM_FORMAT_NV12MT:
561 case TBM_FORMAT_NV21:
564 case TBM_FORMAT_NV16:
565 case TBM_FORMAT_NV61:
568 case TBM_FORMAT_YUV410:
569 case TBM_FORMAT_YVU410:
572 case TBM_FORMAT_YUV411:
573 case TBM_FORMAT_YVU411:
574 case TBM_FORMAT_YUV420:
575 case TBM_FORMAT_YVU420:
578 case TBM_FORMAT_YUV422:
579 case TBM_FORMAT_YVU422:
582 case TBM_FORMAT_YUV444:
583 case TBM_FORMAT_YVU444:
587 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
594 static struct _tbm_surface *
595 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
597 struct _tbm_surface *surf = NULL;
598 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
601 surf = calloc(1, sizeof(struct _tbm_surface));
603 /* LCOV_EXCL_START */
604 TBM_ERR("fail to alloc surf\n");
605 *error = TBM_ERROR_OUT_OF_MEMORY;
606 goto alloc_surf_fail;
610 surf->magic = TBM_SURFACE_MAGIC;
611 surf->bufmgr = bufmgr;
612 surf->info.width = width;
613 surf->info.height = height;
614 surf->info.format = format;
615 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
616 if (!surf->info.bpp) {
617 TBM_ERR("fail to get bpp from format(%d), error(%s)\n", format, tbm_error_str(*error));
618 *error = tbm_get_last_error();
622 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
623 if (!surf->info.num_planes) {
624 TBM_ERR("fail to get num_planes from format(%d), error(%s)\n", format, tbm_error_str(*error));
625 *error = tbm_get_last_error();
626 goto num_planes_fail;
630 /* get size, stride and offset bo_idx */
631 for (i = 0; i < surf->info.num_planes; i++) {
632 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
633 TBM_ERR("fail to query plane data\n");
634 *error = tbm_get_last_error();
635 goto query_plane_data_fail;
638 surf->info.planes[i].size = size;
639 surf->info.planes[i].offset = offset;
640 surf->info.planes[i].stride = stride;
641 surf->planes_bo_idx[i] = bo_idx;
646 for (i = 0; i < surf->info.num_planes; i++) {
647 surf->info.size += surf->info.planes[i].size;
649 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
650 surf->num_bos = surf->planes_bo_idx[i] + 1;
655 for (i = 0; i < surf->num_bos; i++) {
657 for (j = 0; j < surf->info.num_planes; j++) {
658 if (surf->planes_bo_idx[j] == i)
659 bo_size += surf->info.planes[j].size;
662 if (bufmgr->use_hal_tbm) {
663 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
664 if (*error == TBM_ERROR_NOT_SUPPORTED) {
665 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
667 TBM_ERR("fail to alloc bo idx:%d\n", i);
668 *error = tbm_get_last_error();
672 } else if (bufmgr->backend_module_data) {
673 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
674 /* LCOV_EXCL_START */
675 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
677 TBM_ERR("fail to tbm_bo_alloc_with_format idx:%d\n", i);
678 *error = tbm_get_last_error();
682 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
683 /* LCOV_EXCL_START */
684 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, error);
686 TBM_ERR("fail to tbm_bo_alloc_with_tiled_format idx:%d\n", i);
687 *error = tbm_get_last_error();
692 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
694 TBM_ERR("fail to alloc bo idx:%d\n", i);
695 *error = tbm_get_last_error();
700 if (bufmgr->backend->surface_bo_alloc) {
701 /* LCOV_EXCL_START */
702 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
704 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
705 *error = tbm_get_last_error();
710 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
712 TBM_ERR("fail to alloc bo idx:%d\n", i);
713 *error = tbm_get_last_error();
719 _tbm_bo_set_surface(surf->bos[i], surf);
722 *error = TBM_ERROR_NONE;
727 for (j = 0; j < i; j++) {
729 tbm_bo_unref(surf->bos[j]);
731 query_plane_data_fail:
741 tbm_surface_internal_is_valid(tbm_surface_h surface)
745 _tbm_surface_mutex_lock();
746 _tbm_set_last_result(TBM_ERROR_NONE);
748 /* Return silently if surface is null. */
750 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
751 _tbm_surface_mutex_unlock();
755 ret = _tbm_surface_internal_is_valid(surface);
757 _tbm_surface_mutex_unlock();
763 tbm_surface_internal_query_supported_formats(uint32_t **formats,
766 struct _tbm_bufmgr *bufmgr;
768 bool bufmgr_initialized = false;
771 _tbm_surface_mutex_lock();
772 _tbm_set_last_result(TBM_ERROR_NONE);
774 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
775 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
777 if (!g_surface_bufmgr) {
778 _init_surface_bufmgr();
779 if (!g_surface_bufmgr) {
780 TBM_ERR("fail bufmgr initialization\n");
781 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
784 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
785 bufmgr_initialized = true;
788 bufmgr = g_surface_bufmgr;
790 if (bufmgr->use_hal_tbm) {
791 error = (tbm_error_e)hal_tbm_bufmgr_get_supported_formats(bufmgr->hal_bufmgr, formats, num);
792 /* LCOV_EXCL_START */
793 if (error == TBM_ERROR_NOT_SUPPORTED) {
794 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
796 } else if (error != TBM_ERROR_NONE) {
797 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
802 } else if (bufmgr->backend_module_data) {
803 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
804 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
808 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
809 if (error != TBM_ERROR_NONE) {
810 /* LCOV_EXCL_START */
811 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
813 /* LCOV_EXCL_START */
817 if (!bufmgr->backend->surface_supported_format) {
818 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
822 ret = bufmgr->backend->surface_supported_format(formats, num);
824 /* LCOV_EXCL_START */
825 TBM_ERR("Fail to surface_supported_format.\n");
826 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
828 /* LCOV_EXCL_START */
832 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
834 if (bufmgr_initialized) {
835 LIST_DELINIT(&g_surface_bufmgr->surf_list);
836 _deinit_surface_bufmgr();
839 _tbm_surface_mutex_unlock();
843 /* LCOV_EXCL_START */
845 if (bufmgr_initialized) {
846 LIST_DELINIT(&g_surface_bufmgr->surf_list);
847 _deinit_surface_bufmgr();
849 _tbm_surface_mutex_unlock();
851 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
858 tbm_surface_internal_get_num_planes(tbm_format format)
862 _tbm_surface_mutex_lock();
863 _tbm_set_last_result(TBM_ERROR_NONE);
865 num_planes = _tbm_surface_internal_get_num_planes(format);
867 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
868 _tbm_surface_mutex_unlock();
872 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
874 _tbm_surface_mutex_unlock();
880 tbm_surface_internal_get_bpp(tbm_format format)
884 _tbm_surface_mutex_lock();
885 _tbm_set_last_result(TBM_ERROR_NONE);
887 bpp = _tbm_surface_internal_get_bpp(format);
889 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
890 _tbm_surface_mutex_unlock();
894 _tbm_surface_mutex_unlock();
896 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
902 tbm_surface_internal_create_with_flags(int width, int height,
903 int format, int flags)
905 struct _tbm_bufmgr *bufmgr;
906 struct _tbm_surface *surf = NULL;
907 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
908 bool bufmgr_initialized = false;
910 _tbm_surface_mutex_lock();
911 _tbm_set_last_result(TBM_ERROR_NONE);
913 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
914 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
916 if (!g_surface_bufmgr) {
917 _init_surface_bufmgr();
918 if (!g_surface_bufmgr) {
919 TBM_ERR("fail bufmgr initialization\n");
920 error = TBM_ERROR_INVALID_OPERATION;
921 goto check_valid_fail;
923 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
924 bufmgr_initialized = true;
927 bufmgr = g_surface_bufmgr;
928 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
929 TBM_ERR("The bufmgr is invalid\n");
930 error = TBM_ERROR_INVALID_PARAMETER;
931 goto check_valid_fail;
935 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
937 TBM_ERR("_tbm_surface_internal_create_surface failed.");
938 goto surface_alloc_fail;
941 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
942 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
944 LIST_INITHEAD(&surf->user_data_list);
945 LIST_INITHEAD(&surf->debug_data_list);
946 LIST_INITHEAD(&surf->destroy_funcs);
948 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
950 _tbm_set_last_result(error);
951 _tbm_surface_mutex_unlock();
955 /* LCOV_EXCL_START */
959 if (bufmgr_initialized && bufmgr) {
960 LIST_DELINIT(&bufmgr->surf_list);
961 _deinit_surface_bufmgr();
964 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
965 width, height, _tbm_surface_internal_format_to_str(format), flags);
967 _tbm_set_last_result(error);
968 _tbm_surface_mutex_unlock();
976 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
977 tbm_bo *bos, int num)
979 struct _tbm_bufmgr *bufmgr;
980 struct _tbm_surface *surf = NULL;
982 bool bufmgr_initialized = false;
984 _tbm_surface_mutex_lock();
985 _tbm_set_last_result(TBM_ERROR_NONE);
987 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
988 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
989 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
990 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
991 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
993 if (!g_surface_bufmgr) {
994 _init_surface_bufmgr();
995 if (!g_surface_bufmgr) {
996 TBM_ERR("fail bufmgr initialization\n");
997 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
998 goto check_valid_fail;
1000 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1001 bufmgr_initialized = true;
1004 bufmgr = g_surface_bufmgr;
1005 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1006 TBM_ERR("fail to validate the Bufmgr.\n");
1007 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1008 goto check_valid_fail;
1011 surf = calloc(1, sizeof(struct _tbm_surface));
1013 /* LCOV_EXCL_START */
1014 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1015 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1016 goto alloc_surf_fail;
1017 /* LCOV_EXCL_STOP */
1020 surf->magic = TBM_SURFACE_MAGIC;
1021 surf->bufmgr = bufmgr;
1022 surf->info.width = info->width;
1023 surf->info.height = info->height;
1024 surf->info.format = info->format;
1026 surf->info.bpp = info->bpp;
1028 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1029 if (!surf->info.bpp) {
1030 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1034 surf->info.num_planes = info->num_planes;
1037 /* get size, stride and offset */
1038 for (i = 0; i < info->num_planes; i++) {
1039 surf->info.planes[i].offset = info->planes[i].offset;
1040 surf->info.planes[i].stride = info->planes[i].stride;
1042 if (info->planes[i].size > 0)
1043 surf->info.planes[i].size = info->planes[i].size;
1045 uint32_t size = 0, offset = 0, stride = 0;
1048 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1049 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1050 goto plane_data_fail;
1052 surf->info.planes[i].size = size;
1056 surf->planes_bo_idx[i] = 0;
1058 surf->planes_bo_idx[i] = i;
1061 if (info->size > 0) {
1062 surf->info.size = info->size;
1064 surf->info.size = 0;
1065 for (i = 0; i < info->num_planes; i++)
1066 surf->info.size += surf->info.planes[i].size;
1069 surf->flags = TBM_BO_DEFAULT;
1071 /* create only one bo */
1072 surf->num_bos = num;
1073 for (i = 0; i < num; i++) {
1074 if (bos[i] == NULL) {
1075 TBM_ERR("bos[%d] is null.\n", i);
1076 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1080 surf->bos[i] = tbm_bo_ref(bos[i]);
1081 _tbm_bo_set_surface(bos[i], surf);
1084 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1085 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1087 LIST_INITHEAD(&surf->user_data_list);
1088 LIST_INITHEAD(&surf->debug_data_list);
1089 LIST_INITHEAD(&surf->destroy_funcs);
1091 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1093 _tbm_surface_mutex_unlock();
1097 /* LCOV_EXCL_START */
1101 for (i = 0; i < num; i++) {
1103 tbm_bo_unref(surf->bos[i]);
1108 if (bufmgr_initialized && bufmgr) {
1109 LIST_DELINIT(&bufmgr->surf_list);
1110 _deinit_surface_bufmgr();
1112 _tbm_surface_mutex_unlock();
1114 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1115 info->width, info->height,
1116 _tbm_surface_internal_format_to_str(info->format), num);
1117 /* LCOV_EXCL_STOP */
1123 tbm_surface_internal_destroy(tbm_surface_h surface)
1125 _tbm_surface_mutex_lock();
1126 _tbm_set_last_result(TBM_ERROR_NONE);
1128 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1132 if (surface->refcnt > 0) {
1133 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1134 _tbm_surface_mutex_unlock();
1138 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1140 if (surface->refcnt == 0)
1141 _tbm_surface_internal_destroy(surface);
1142 else // if (surface->refcnt < 0)
1143 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1145 _tbm_surface_mutex_unlock();
1149 tbm_surface_internal_ref(tbm_surface_h surface)
1151 _tbm_surface_mutex_lock();
1152 _tbm_set_last_result(TBM_ERROR_NONE);
1154 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1158 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1160 _tbm_surface_mutex_unlock();
1164 tbm_surface_internal_unref(tbm_surface_h surface)
1166 _tbm_surface_mutex_lock();
1167 _tbm_set_last_result(TBM_ERROR_NONE);
1169 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1173 if (surface->refcnt > 0) {
1174 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1175 _tbm_surface_mutex_unlock();
1179 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1181 if (surface->refcnt == 0)
1182 _tbm_surface_internal_destroy(surface);
1184 _tbm_surface_mutex_unlock();
1188 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1190 struct _tbm_surface *surf;
1193 _tbm_surface_mutex_lock();
1194 _tbm_set_last_result(TBM_ERROR_NONE);
1196 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1198 surf = (struct _tbm_surface *)surface;
1199 num = surf->num_bos;
1202 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1204 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1206 _tbm_surface_mutex_unlock();
1212 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1214 struct _tbm_surface *surf;
1217 _tbm_surface_mutex_lock();
1218 _tbm_set_last_result(TBM_ERROR_NONE);
1220 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1221 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1223 surf = (struct _tbm_surface *)surface;
1224 bo = surf->bos[bo_idx];
1226 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1228 _tbm_surface_mutex_unlock();
1234 tbm_surface_internal_get_size(tbm_surface_h surface)
1236 struct _tbm_surface *surf;
1239 _tbm_surface_mutex_lock();
1240 _tbm_set_last_result(TBM_ERROR_NONE);
1242 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1244 surf = (struct _tbm_surface *)surface;
1245 size = surf->info.size;
1247 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1249 _tbm_surface_mutex_unlock();
1255 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1256 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1258 struct _tbm_surface *surf;
1260 _tbm_surface_mutex_lock();
1261 _tbm_set_last_result(TBM_ERROR_NONE);
1263 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1264 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1266 surf = (struct _tbm_surface *)surface;
1268 if (plane_idx >= surf->info.num_planes) {
1269 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1270 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1271 _tbm_surface_mutex_unlock();
1276 *size = surf->info.planes[plane_idx].size;
1279 *offset = surf->info.planes[plane_idx].offset;
1282 *pitch = surf->info.planes[plane_idx].stride;
1284 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1285 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1286 surf->info.planes[plane_idx].stride);
1288 _tbm_surface_mutex_unlock();
1294 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1295 tbm_surface_info_s *info, int map)
1297 struct _tbm_surface *surf;
1298 tbm_bo_handle bo_handles[4];
1301 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1304 _tbm_surface_mutex_lock();
1305 _tbm_set_last_result(TBM_ERROR_NONE);
1307 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1309 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1311 surf = (struct _tbm_surface *)surface;
1313 memset(info, 0x00, sizeof(tbm_surface_info_s));
1314 info->width = surf->info.width;
1315 info->height = surf->info.height;
1316 info->format = surf->info.format;
1317 info->bpp = surf->info.bpp;
1318 info->size = surf->info.size;
1319 info->num_planes = surf->info.num_planes;
1321 for (i = 0; i < surf->info.num_planes; i++) {
1322 info->planes[i].size = surf->info.planes[i].size;
1323 info->planes[i].offset = surf->info.planes[i].offset;
1324 info->planes[i].stride = surf->info.planes[i].stride;
1325 planes_bo_idx[i] = surf->planes_bo_idx[i];
1328 for (i = 0; i < surf->num_bos; i++)
1329 bos[i] = surf->bos[i];
1331 num_bos = surf->num_bos;
1334 _tbm_surface_mutex_unlock();
1335 for (i = 0; i < num_bos; i++) {
1336 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1337 if (bo_handles[i].ptr == NULL) {
1338 for (j = 0; j < i; j++)
1339 tbm_bo_unmap(bos[j]);
1341 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1345 _tbm_surface_mutex_lock();
1347 for (i = 0; i < num_bos; i++) {
1348 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1349 if (bo_handles[i].ptr == NULL) {
1350 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1351 _tbm_surface_mutex_unlock();
1357 for (i = 0; i < info->num_planes; i++) {
1358 if (bo_handles[planes_bo_idx[i]].ptr)
1359 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1362 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1364 _tbm_surface_mutex_unlock();
1370 tbm_surface_internal_unmap(tbm_surface_h surface)
1372 struct _tbm_surface *surf;
1375 _tbm_surface_mutex_lock();
1376 _tbm_set_last_result(TBM_ERROR_NONE);
1378 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1380 surf = (struct _tbm_surface *)surface;
1382 for (i = 0; i < surf->num_bos; i++)
1383 tbm_bo_unmap(surf->bos[i]);
1385 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1387 _tbm_surface_mutex_unlock();
1391 tbm_surface_internal_get_width(tbm_surface_h surface)
1393 struct _tbm_surface *surf;
1396 _tbm_surface_mutex_lock();
1397 _tbm_set_last_result(TBM_ERROR_NONE);
1399 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1401 surf = (struct _tbm_surface *)surface;
1402 width = surf->info.width;
1404 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1406 _tbm_surface_mutex_unlock();
1412 tbm_surface_internal_get_height(tbm_surface_h surface)
1414 struct _tbm_surface *surf;
1415 unsigned int height;
1417 _tbm_surface_mutex_lock();
1418 _tbm_set_last_result(TBM_ERROR_NONE);
1420 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1422 surf = (struct _tbm_surface *)surface;
1423 height = surf->info.height;
1425 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1427 _tbm_surface_mutex_unlock();
1434 tbm_surface_internal_get_format(tbm_surface_h surface)
1436 struct _tbm_surface *surf;
1439 _tbm_surface_mutex_lock();
1440 _tbm_set_last_result(TBM_ERROR_NONE);
1442 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1444 surf = (struct _tbm_surface *)surface;
1445 format = surf->info.format;
1447 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1449 _tbm_surface_mutex_unlock();
1455 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1457 struct _tbm_surface *surf;
1460 _tbm_surface_mutex_lock();
1461 _tbm_set_last_result(TBM_ERROR_NONE);
1463 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1464 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1466 surf = (struct _tbm_surface *)surface;
1467 bo_idx = surf->planes_bo_idx[plane_idx];
1469 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1471 _tbm_surface_mutex_unlock();
1477 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1478 tbm_data_free data_free_func)
1480 tbm_user_data *data;
1482 _tbm_surface_mutex_lock();
1483 _tbm_set_last_result(TBM_ERROR_NONE);
1485 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1487 /* check if the data according to the key exist if so, return false. */
1488 data = user_data_lookup(&surface->user_data_list, key);
1490 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1491 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1492 _tbm_surface_mutex_unlock();
1496 data = user_data_create(key, data_free_func);
1498 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1499 _tbm_surface_mutex_unlock();
1503 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1505 LIST_ADD(&data->item_link, &surface->user_data_list);
1507 _tbm_surface_mutex_unlock();
1513 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1516 tbm_user_data *old_data;
1518 _tbm_surface_mutex_lock();
1519 _tbm_set_last_result(TBM_ERROR_NONE);
1521 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1523 old_data = user_data_lookup(&surface->user_data_list, key);
1525 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1526 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1527 _tbm_surface_mutex_unlock();
1531 if (old_data->data && old_data->free_func)
1532 old_data->free_func(old_data->data);
1534 old_data->data = data;
1536 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1538 _tbm_surface_mutex_unlock();
1544 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1547 tbm_user_data *old_data;
1549 _tbm_surface_mutex_lock();
1550 _tbm_set_last_result(TBM_ERROR_NONE);
1552 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1555 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1556 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1557 _tbm_surface_mutex_unlock();
1562 old_data = user_data_lookup(&surface->user_data_list, key);
1564 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1565 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1566 _tbm_surface_mutex_unlock();
1570 *data = old_data->data;
1572 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1574 _tbm_surface_mutex_unlock();
1580 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1583 tbm_user_data *old_data = (void *)0;
1585 _tbm_surface_mutex_lock();
1586 _tbm_set_last_result(TBM_ERROR_NONE);
1588 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1590 old_data = user_data_lookup(&surface->user_data_list, key);
1592 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1593 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1594 _tbm_surface_mutex_unlock();
1598 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1600 user_data_delete(old_data);
1602 _tbm_surface_mutex_unlock();
1607 /* LCOV_EXCL_START */
1609 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1611 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1613 return surface->debug_pid;
1617 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1619 _tbm_surface_mutex_lock();
1620 _tbm_set_last_result(TBM_ERROR_NONE);
1622 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1624 surface->debug_pid = pid;
1626 _tbm_surface_mutex_unlock();
1629 static tbm_surface_debug_data *
1630 _tbm_surface_internal_debug_data_create(char *key, char *value)
1632 tbm_surface_debug_data *debug_data = NULL;
1634 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1636 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1637 TBM_ERR("fail to allocate the debug_data.");
1641 if (key) debug_data->key = strdup(key);
1642 if (value) debug_data->value = strdup(value);
1648 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1650 if (!debug_data->value && !value)
1653 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1656 if (debug_data->value)
1657 free(debug_data->value);
1660 debug_data->value = strdup(value);
1662 debug_data->value = NULL;
1665 static tbm_surface_debug_data *
1666 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1668 tbm_surface_debug_data *debug_data = NULL;
1670 if (LIST_IS_EMPTY(list))
1673 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1674 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1682 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1684 tbm_surface_debug_data *debug_data = NULL;
1685 tbm_bufmgr bufmgr = NULL;
1687 _tbm_surface_mutex_lock();
1688 _tbm_set_last_result(TBM_ERROR_NONE);
1690 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1691 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1693 bufmgr = surface->bufmgr;
1695 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1697 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1699 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1701 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1703 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1704 _tbm_surface_mutex_unlock();
1708 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1711 /* add new debug key to list */
1712 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1714 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1716 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1719 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1721 _tbm_surface_mutex_unlock();
1727 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1729 tbm_surface_debug_data *old_data = NULL;
1731 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1733 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1734 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1735 if (!strcmp(old_data->key, key))
1736 return old_data->value;
1743 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1744 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1746 struct _tbm_surface_dump_buf_info {
1756 tbm_surface_info_s info;
1758 struct list_head link;
1761 struct _tbm_surface_dump_info {
1762 char *path; // copy???
1765 struct list_head *link;
1766 struct list_head surface_list; /* link of surface */
1769 static tbm_surface_dump_info *g_dump_info = NULL;
1770 static const char *dump_postfix[2] = {"png", "yuv"};
1771 static double scale_factor;
1774 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1775 void *data2, int size2, void *data3, int size3)
1778 unsigned int *blocks;
1780 if (_tbm_surface_check_file_is_symbolic_link(file))
1781 TBM_ERR("%s is symbolic link\n", file);
1783 fp = fopen(file, "w+");
1784 TBM_RETURN_IF_FAIL(fp != NULL);
1786 blocks = (unsigned int *)data1;
1787 fwrite(blocks, 1, size1, fp);
1790 blocks = (unsigned int *)data2;
1791 fwrite(blocks, 1, size2, fp);
1795 blocks = (unsigned int *)data3;
1796 fwrite(blocks, 1, size3, fp);
1803 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1805 unsigned int *blocks = (unsigned int *)data;
1808 png_bytep *row_pointers;
1811 if (_tbm_surface_check_file_is_symbolic_link(file))
1812 TBM_ERR("%s is symbolic link\n", file);
1814 fp = fopen(file, "wb");
1815 TBM_RETURN_IF_FAIL(fp != NULL);
1817 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1820 TBM_ERR("fail to create a png write structure.\n");
1825 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1827 TBM_ERR("fail to create a png info structure.\n");
1828 png_destroy_write_struct(&pPngStruct, NULL);
1833 if (setjmp(png_jmpbuf(pPngStruct))) {
1834 /* if png has problem of writing the file, we get here */
1835 TBM_ERR("fail to write png file.\n");
1836 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1841 png_init_io(pPngStruct, fp);
1842 if (format == TBM_FORMAT_XRGB8888) {
1844 png_set_IHDR(pPngStruct,
1851 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1854 png_set_IHDR(pPngStruct,
1859 PNG_COLOR_TYPE_RGBA,
1861 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1864 png_set_bgr(pPngStruct);
1865 png_write_info(pPngStruct, pPngInfo);
1867 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1868 if (!row_pointers) {
1869 TBM_ERR("fail to allocate the png row_pointers.\n");
1870 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1875 for (y = 0; y < height; ++y) {
1879 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1881 TBM_ERR("fail to allocate the png row.\n");
1882 for (x = 0; x < y; x++)
1883 png_free(pPngStruct, row_pointers[x]);
1884 png_free(pPngStruct, row_pointers);
1885 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1889 row_pointers[y] = (png_bytep)row;
1891 for (x = 0; x < width; ++x) {
1892 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1894 if (pixel_size == 3) { // XRGB8888
1895 row[x * pixel_size] = (curBlock & 0xFF);
1896 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1897 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1898 } else { // ARGB8888
1899 row[x * pixel_size] = (curBlock & 0xFF);
1900 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1901 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1902 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1907 png_write_image(pPngStruct, row_pointers);
1908 png_write_end(pPngStruct, pPngInfo);
1910 for (y = 0; y < height; y++)
1911 png_free(pPngStruct, row_pointers[y]);
1912 png_free(pPngStruct, row_pointers);
1914 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1920 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1922 TBM_RETURN_IF_FAIL(path != NULL);
1923 TBM_RETURN_IF_FAIL(w > 0);
1924 TBM_RETURN_IF_FAIL(h > 0);
1925 TBM_RETURN_IF_FAIL(count > 0);
1927 tbm_surface_dump_buf_info *buf_info = NULL;
1928 tbm_surface_h tbm_surface;
1929 tbm_surface_info_s info;
1934 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1938 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1939 TBM_RETURN_IF_FAIL(g_dump_info);
1941 LIST_INITHEAD(&g_dump_info->surface_list);
1942 g_dump_info->count = 0;
1943 g_dump_info->dump_max = count;
1945 /* get buffer size */
1946 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1947 if (tbm_surface == NULL) {
1948 TBM_ERR("tbm_surface_create fail\n");
1954 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1955 TBM_ERR("tbm_surface_get_info fail\n");
1956 tbm_surface_destroy(tbm_surface);
1961 buffer_size = info.size;
1962 tbm_surface_destroy(tbm_surface);
1964 /* create dump lists */
1965 for (i = 0; i < count; i++) {
1968 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1969 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1971 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1973 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1978 buf_info->index = i;
1980 buf_info->size = buffer_size;
1982 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1985 g_dump_info->path = path;
1986 g_dump_info->link = &g_dump_info->surface_list;
1990 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1995 /* free resources */
1996 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1997 tbm_surface_dump_buf_info *tmp;
1999 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2000 tbm_bo_unref(buf_info->bo);
2001 LIST_DEL(&buf_info->link);
2006 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2015 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2022 tbm_surface_internal_dump_start(path, w, h, count);
2023 scale_factor = scale;
2027 tbm_surface_internal_dump_end(void)
2029 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2030 tbm_bo_handle bo_handle;
2035 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2042 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2045 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2046 if (bo_handle.ptr == NULL) {
2047 tbm_bo_unref(buf_info->bo);
2048 LIST_DEL(&buf_info->link);
2053 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2054 TBM_INFO("Dump File.. %s generated.\n", file);
2056 if (buf_info->dirty) {
2057 void *ptr1 = NULL, *ptr2 = NULL;
2059 switch (buf_info->info.format) {
2060 case TBM_FORMAT_ARGB8888:
2061 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2062 buf_info->info.planes[0].stride >> 2,
2063 buf_info->info.height,
2064 buf_info->info.planes[0].stride,
2065 TBM_FORMAT_ARGB8888);
2067 case TBM_FORMAT_XRGB8888:
2068 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2069 buf_info->info.planes[0].stride >> 2,
2070 buf_info->info.height,
2071 buf_info->info.planes[0].stride,
2072 TBM_FORMAT_XRGB8888);
2074 case TBM_FORMAT_YVU420:
2075 case TBM_FORMAT_YUV420:
2076 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2077 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2078 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2079 buf_info->info.planes[0].stride * buf_info->info.height,
2081 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2083 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2085 case TBM_FORMAT_NV12:
2086 case TBM_FORMAT_NV21:
2087 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2088 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2089 buf_info->info.planes[0].stride * buf_info->info.height,
2091 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2094 case TBM_FORMAT_YUYV:
2095 case TBM_FORMAT_UYVY:
2096 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2097 buf_info->info.planes[0].stride * buf_info->info.height,
2101 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2104 } else if (buf_info->dirty_shm)
2105 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2106 buf_info->shm_stride >> 2,
2108 buf_info->shm_stride, 0);
2110 tbm_bo_unmap(buf_info->bo);
2111 tbm_bo_unref(buf_info->bo);
2112 LIST_DEL(&buf_info->link);
2119 TBM_INFO("Dump End..\n");
2122 static pixman_format_code_t
2123 _tbm_surface_internal_pixman_format_get(tbm_format format)
2126 case TBM_FORMAT_ARGB8888:
2127 return PIXMAN_a8r8g8b8;
2128 case TBM_FORMAT_XRGB8888:
2129 return PIXMAN_x8r8g8b8;
2138 * This function supports only if a buffer has below formats.
2139 * - TBM_FORMAT_ARGB8888
2140 * - TBM_FORMAT_XRGB8888
2142 static tbm_surface_error_e
2143 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2144 int format, int src_stride, int src_w, int src_h,
2145 int dst_stride, int dst_w, int dst_h)
2147 pixman_image_t *src_img = NULL, *dst_img = NULL;
2148 pixman_format_code_t pixman_format;
2149 pixman_transform_t t;
2150 struct pixman_f_transform ft;
2151 double scale_x, scale_y;
2153 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2154 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2156 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2157 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2160 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2161 (uint32_t*)src_ptr, src_stride);
2162 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2165 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2166 (uint32_t*)dst_ptr, dst_stride);
2167 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2169 pixman_f_transform_init_identity(&ft);
2171 scale_x = (double)src_w / dst_w;
2172 scale_y = (double)src_h / dst_h;
2174 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2175 pixman_f_transform_translate(&ft, NULL, 0, 0);
2176 pixman_transform_from_pixman_f_transform(&t, &ft);
2177 pixman_image_set_transform(src_img, &t);
2179 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2180 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2182 pixman_image_unref(src_img);
2183 pixman_image_unref(dst_img);
2185 return TBM_SURFACE_ERROR_NONE;
2189 pixman_image_unref(src_img);
2191 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2194 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2195 #define KEY_LEN 5 // "_XXXX"
2196 #define KEYS_LEN KEY_LEN * MAX_BOS
2198 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2200 char *keys, temp_key[KEY_LEN + 1];
2201 struct _tbm_surface *surf;
2205 _tbm_surface_mutex_lock();
2207 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2209 surf = (struct _tbm_surface *)surface;
2211 num_bos = surf->num_bos;
2212 if (num_bos > MAX_BOS)
2215 keys = calloc(KEYS_LEN + 1, sizeof(char));
2217 TBM_ERR("Failed to alloc memory");
2218 _tbm_surface_mutex_unlock();
2222 for (i = 0; i < num_bos; i++) {
2223 memset(temp_key, 0x00, KEY_LEN + 1);
2225 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2226 strncat(keys, temp_key, KEY_LEN + 1);
2229 _tbm_surface_mutex_unlock();
2234 static void _tbm_surface_internal_put_keys(char *keys)
2241 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2243 TBM_RETURN_IF_FAIL(surface != NULL);
2244 TBM_RETURN_IF_FAIL(type != NULL);
2246 tbm_surface_dump_buf_info *buf_info;
2247 struct list_head *next_link;
2248 tbm_surface_info_s info;
2249 tbm_bo_handle bo_handle;
2250 const char *postfix;
2251 const char *format = NULL;
2258 next_link = g_dump_info->link->next;
2259 TBM_RETURN_IF_FAIL(next_link != NULL);
2261 if (next_link == &g_dump_info->surface_list) {
2262 next_link = next_link->next;
2263 TBM_RETURN_IF_FAIL(next_link != NULL);
2266 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2267 TBM_RETURN_IF_FAIL(buf_info != NULL);
2269 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2270 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2272 if (scale_factor > 0.0) {
2275 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2276 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2277 _tbm_surface_internal_format_to_str(info.format));
2278 tbm_surface_unmap(surface);
2282 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2284 buf_info->info.width = info.width * scale_factor;
2285 buf_info->info.height = info.height * scale_factor;
2286 buf_info->info.format = info.format;
2287 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2288 if (!buf_info->info.bpp) {
2289 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2290 tbm_surface_unmap(surface);
2293 buf_info->info.num_planes = 1;
2294 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2295 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2297 if (buf_info->info.size > buf_info->size) {
2298 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2299 buf_info->info.size, buf_info->size);
2300 tbm_surface_unmap(surface);
2304 if (info.size > buf_info->size) {
2305 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2306 info.size, buf_info->size);
2307 tbm_surface_unmap(surface);
2311 /* make the file information */
2312 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2315 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2316 postfix = dump_postfix[0];
2317 format = _tbm_surface_internal_format_to_str(info.format);
2319 postfix = dump_postfix[1];
2321 keys = _tbm_surface_internal_get_keys(surface);
2323 TBM_ERR("fail to get keys");
2324 tbm_surface_unmap(surface);
2329 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2330 if (!bo_handle.ptr) {
2331 TBM_ERR("fail to map bo");
2332 _tbm_surface_internal_put_keys(keys);
2333 tbm_surface_unmap(surface);
2336 memset(bo_handle.ptr, 0x00, buf_info->size);
2338 switch (info.format) {
2339 case TBM_FORMAT_ARGB8888:
2340 case TBM_FORMAT_XRGB8888:
2341 snprintf(buf_info->name, sizeof(buf_info->name),
2342 "%10.3f_%03d%s_%p_%s-%s.%s",
2343 _tbm_surface_internal_get_time(),
2344 g_dump_info->count++, keys, surface, format, type, postfix);
2346 if (scale_factor > 0.0) {
2347 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2349 buf_info->info.format,
2350 info.planes[0].stride,
2351 info.width, info.height,
2352 buf_info->info.planes[0].stride,
2353 buf_info->info.width,
2354 buf_info->info.height);
2355 if (ret != TBM_SURFACE_ERROR_NONE) {
2356 TBM_ERR("fail to scale buffer");
2357 tbm_bo_unmap(buf_info->bo);
2358 _tbm_surface_internal_put_keys(keys);
2359 tbm_surface_unmap(surface);
2363 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2365 case TBM_FORMAT_YVU420:
2366 case TBM_FORMAT_YUV420:
2367 snprintf(buf_info->name, sizeof(buf_info->name),
2368 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2369 _tbm_surface_internal_get_time(),
2370 g_dump_info->count++, keys, type, info.planes[0].stride,
2371 info.height, FOURCC_STR(info.format), postfix);
2372 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2373 bo_handle.ptr += info.planes[0].stride * info.height;
2374 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2375 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2376 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2378 case TBM_FORMAT_NV12:
2379 case TBM_FORMAT_NV21:
2380 snprintf(buf_info->name, sizeof(buf_info->name),
2381 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2382 _tbm_surface_internal_get_time(),
2383 g_dump_info->count++, keys, type, info.planes[0].stride,
2384 info.height, FOURCC_STR(info.format), postfix);
2385 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2386 bo_handle.ptr += info.planes[0].stride * info.height;
2387 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2389 case TBM_FORMAT_YUYV:
2390 case TBM_FORMAT_UYVY:
2391 snprintf(buf_info->name, sizeof(buf_info->name),
2392 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2393 _tbm_surface_internal_get_time(),
2394 g_dump_info->count++, keys, type, info.planes[0].stride,
2395 info.height, FOURCC_STR(info.format), postfix);
2396 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2399 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2400 tbm_bo_unmap(buf_info->bo);
2401 _tbm_surface_internal_put_keys(keys);
2402 tbm_surface_unmap(surface);
2406 tbm_bo_unmap(buf_info->bo);
2408 _tbm_surface_internal_put_keys(keys);
2410 tbm_surface_unmap(surface);
2412 buf_info->dirty = 1;
2413 buf_info->dirty_shm = 0;
2415 if (g_dump_info->count == 1000)
2416 g_dump_info->count = 0;
2418 g_dump_info->link = next_link;
2420 TBM_INFO("Dump %s \n", buf_info->name);
2423 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2426 TBM_RETURN_IF_FAIL(ptr != NULL);
2427 TBM_RETURN_IF_FAIL(w > 0);
2428 TBM_RETURN_IF_FAIL(h > 0);
2429 TBM_RETURN_IF_FAIL(stride > 0);
2430 TBM_RETURN_IF_FAIL(type != NULL);
2432 tbm_surface_dump_buf_info *buf_info;
2433 struct list_head *next_link;
2434 tbm_bo_handle bo_handle;
2435 int ret, size, dw = 0, dh = 0, dstride = 0;
2440 next_link = g_dump_info->link->next;
2441 TBM_RETURN_IF_FAIL(next_link != NULL);
2443 if (next_link == &g_dump_info->surface_list) {
2444 next_link = next_link->next;
2445 TBM_RETURN_IF_FAIL(next_link != NULL);
2448 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2449 TBM_RETURN_IF_FAIL(buf_info != NULL);
2451 if (scale_factor > 0.0) {
2454 dw = w * scale_factor;
2455 dh = h * scale_factor;
2457 size = dstride * dh;
2461 if (size > buf_info->size) {
2462 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2463 size, buf_info->size);
2468 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2469 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2471 memset(bo_handle.ptr, 0x00, buf_info->size);
2472 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2474 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2475 _tbm_surface_internal_get_time(),
2476 g_dump_info->count++, type, dump_postfix[0]);
2477 if (scale_factor > 0.0) {
2478 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2479 TBM_FORMAT_ARGB8888, stride,
2480 w, h, dstride, dw, dh);
2481 if (ret != TBM_SURFACE_ERROR_NONE) {
2482 TBM_ERR("fail to scale buffer");
2483 tbm_bo_unmap(buf_info->bo);
2486 buf_info->shm_stride = dstride;
2487 buf_info->shm_h = dh;
2489 memcpy(bo_handle.ptr, ptr, size);
2490 buf_info->shm_stride = stride;
2491 buf_info->shm_h = h;
2494 tbm_bo_unmap(buf_info->bo);
2496 buf_info->dirty = 0;
2497 buf_info->dirty_shm = 1;
2499 if (g_dump_info->count == 1000)
2500 g_dump_info->count = 0;
2502 g_dump_info->link = next_link;
2504 TBM_INFO("Dump %s \n", buf_info->name);
2508 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2510 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2511 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2512 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2514 tbm_surface_info_s info;
2515 const char *postfix;
2519 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2520 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2522 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2523 postfix = dump_postfix[0];
2525 postfix = dump_postfix[1];
2527 if (strcmp(postfix, type)) {
2528 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2529 tbm_surface_unmap(surface);
2533 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2535 if (!access(file, 0)) {
2536 TBM_ERR("can't capture buffer, exist file %s", file);
2537 tbm_surface_unmap(surface);
2541 switch (info.format) {
2542 case TBM_FORMAT_ARGB8888:
2543 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2546 info.planes[0].stride,
2547 TBM_FORMAT_ARGB8888);
2549 case TBM_FORMAT_XRGB8888:
2550 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2553 info.planes[0].stride,
2554 TBM_FORMAT_XRGB8888);
2556 case TBM_FORMAT_YVU420:
2557 case TBM_FORMAT_YUV420:
2558 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2559 info.planes[0].stride * info.height,
2561 info.planes[1].stride * (info.height >> 1),
2563 info.planes[2].stride * (info.height >> 1));
2565 case TBM_FORMAT_NV12:
2566 case TBM_FORMAT_NV21:
2567 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2568 info.planes[0].stride * info.height,
2570 info.planes[1].stride * (info.height >> 1),
2573 case TBM_FORMAT_YUYV:
2574 case TBM_FORMAT_UYVY:
2575 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2576 info.planes[0].stride * info.height,
2580 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2581 tbm_surface_unmap(surface);
2585 tbm_surface_unmap(surface);
2587 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2593 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2594 const char *path, const char *name, const char *type)
2596 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2597 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2598 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2599 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2600 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2601 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2605 if (strcmp(dump_postfix[0], type)) {
2606 TBM_ERR("Not supported type:%s'", type);
2610 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2612 if (!access(file, 0)) {
2613 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2617 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2619 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2625 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2627 struct _tbm_surface *surf;
2629 _tbm_surface_mutex_lock();
2630 _tbm_set_last_result(TBM_ERROR_NONE);
2632 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2633 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2634 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2636 surf = (struct _tbm_surface *)surface;
2640 surf->damage.width = width;
2641 surf->damage.height = height;
2643 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2644 surface, x, y, width, height);
2646 _tbm_surface_mutex_unlock();
2652 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2654 struct _tbm_surface *surf;
2656 _tbm_surface_mutex_lock();
2657 _tbm_set_last_result(TBM_ERROR_NONE);
2659 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2661 surf = (struct _tbm_surface *)surface;
2663 if (x) *x = surf->damage.x;
2664 if (y) *y = surf->damage.y;
2665 if (width) *width = surf->damage.width;
2666 if (height) *height = surf->damage.height;
2668 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2669 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2671 _tbm_surface_mutex_unlock();
2677 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2679 struct _tbm_surface *surf;
2680 tbm_surface_destroy_func_info *func_info = NULL;
2682 _tbm_surface_mutex_lock();
2683 _tbm_set_last_result(TBM_ERROR_NONE);
2685 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2686 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2688 surf = (struct _tbm_surface *)surface;
2689 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2690 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2691 TBM_ERR("can't add twice");
2692 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2693 _tbm_surface_mutex_unlock();
2698 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2699 if (func_info == NULL) {
2700 TBM_ERR("alloc failed");
2701 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2702 _tbm_surface_mutex_unlock();
2706 func_info->destroy_func = func;
2707 func_info->user_data = user_data;
2709 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2711 _tbm_surface_mutex_unlock();
2717 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2719 struct _tbm_surface *surf;
2720 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2722 _tbm_surface_mutex_lock();
2723 _tbm_set_last_result(TBM_ERROR_NONE);
2725 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2726 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2728 surf = (struct _tbm_surface *)surface;
2729 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2730 if (func_info->destroy_func != func || func_info->user_data != user_data)
2733 LIST_DEL(&func_info->item_link);
2736 _tbm_surface_mutex_unlock();
2741 _tbm_surface_mutex_unlock();
2744 tbm_surface_buffer_data *
2745 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2752 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)