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_ERR_IF_FAIL(cond, error_type) {\
62 TBM_ERR("'%s' failed.\n", #cond);\
63 _tbm_set_last_result(error_type);\
64 _tbm_surface_mutex_unlock();\
69 #define TBM_SURFACE_RETURN_SET_ERR_IF_FAIL(cond, error, error_type) {\
71 TBM_ERR("'%s' failed.\n", #cond);\
73 _tbm_set_last_result(error_type);\
74 _tbm_surface_mutex_unlock();\
79 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
81 TBM_ERR("'%s' failed.\n", #cond);\
82 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
83 _tbm_surface_mutex_unlock();\
89 #define TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(cond, val, error_type) {\
91 TBM_ERR("'%s' failed.\n", #cond);\
92 _tbm_set_last_result(error_type);\
93 _tbm_surface_mutex_unlock();\
98 #define TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(cond, val, error, error_type) {\
100 TBM_ERR("'%s' failed.\n", #cond);\
102 *error = error_type;\
103 _tbm_set_last_result(error_type);\
104 _tbm_surface_mutex_unlock();\
109 /* LCOV_EXCL_START */
111 _tbm_surface_internal_get_time(void)
116 clock_gettime(CLOCK_MONOTONIC, &tp);
117 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
119 return time / 1000.0;
123 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
125 LIST_DEL(&debug_data->item_link);
127 if (debug_data->key) free(debug_data->key);
128 if (debug_data->value) free(debug_data->value);
133 _tbm_surface_internal_format_to_str(tbm_format format)
137 return "TBM_FORMAT_C8";
138 case TBM_FORMAT_RGB332:
139 return "TBM_FORMAT_RGB332";
140 case TBM_FORMAT_BGR233:
141 return "TBM_FORMAT_BGR233";
142 case TBM_FORMAT_XRGB4444:
143 return "TBM_FORMAT_XRGB4444";
144 case TBM_FORMAT_XBGR4444:
145 return "TBM_FORMAT_XBGR4444";
146 case TBM_FORMAT_RGBX4444:
147 return "TBM_FORMAT_RGBX4444";
148 case TBM_FORMAT_BGRX4444:
149 return "TBM_FORMAT_BGRX4444";
150 case TBM_FORMAT_ARGB4444:
151 return "TBM_FORMAT_ARGB4444";
152 case TBM_FORMAT_ABGR4444:
153 return "TBM_FORMAT_ABGR4444";
154 case TBM_FORMAT_RGBA4444:
155 return "TBM_FORMAT_RGBA4444";
156 case TBM_FORMAT_BGRA4444:
157 return "TBM_FORMAT_BGRA4444";
158 case TBM_FORMAT_XRGB1555:
159 return "TBM_FORMAT_XRGB1555";
160 case TBM_FORMAT_XBGR1555:
161 return "TBM_FORMAT_XBGR1555";
162 case TBM_FORMAT_RGBX5551:
163 return "TBM_FORMAT_RGBX5551";
164 case TBM_FORMAT_BGRX5551:
165 return "TBM_FORMAT_BGRX5551";
166 case TBM_FORMAT_ARGB1555:
167 return "TBM_FORMAT_ARGB1555";
168 case TBM_FORMAT_ABGR1555:
169 return "TBM_FORMAT_ABGR1555";
170 case TBM_FORMAT_RGBA5551:
171 return "TBM_FORMAT_RGBA5551";
172 case TBM_FORMAT_BGRA5551:
173 return "TBM_FORMAT_BGRA5551";
174 case TBM_FORMAT_RGB565:
175 return "TBM_FORMAT_RGB565";
176 case TBM_FORMAT_BGR565:
177 return "TBM_FORMAT_BGR565";
178 case TBM_FORMAT_RGB888:
179 return "TBM_FORMAT_RGB888";
180 case TBM_FORMAT_BGR888:
181 return "TBM_FORMAT_BGR888";
182 case TBM_FORMAT_XRGB8888:
183 return "TBM_FORMAT_XRGB8888";
184 case TBM_FORMAT_XBGR8888:
185 return "TBM_FORMAT_XBGR8888";
186 case TBM_FORMAT_RGBX8888:
187 return "TBM_FORMAT_RGBX8888";
188 case TBM_FORMAT_BGRX8888:
189 return "TBM_FORMAT_BGRX8888";
190 case TBM_FORMAT_ARGB8888:
191 return "TBM_FORMAT_ARGB8888";
192 case TBM_FORMAT_ABGR8888:
193 return "TBM_FORMAT_ABGR8888";
194 case TBM_FORMAT_RGBA8888:
195 return "TBM_FORMAT_RGBA8888";
196 case TBM_FORMAT_BGRA8888:
197 return "TBM_FORMAT_BGRA8888";
198 case TBM_FORMAT_XRGB2101010:
199 return "TBM_FORMAT_XRGB2101010";
200 case TBM_FORMAT_XBGR2101010:
201 return "TBM_FORMAT_XBGR2101010";
202 case TBM_FORMAT_RGBX1010102:
203 return "TBM_FORMAT_RGBX1010102";
204 case TBM_FORMAT_BGRX1010102:
205 return "TBM_FORMAT_BGRX1010102";
206 case TBM_FORMAT_ARGB2101010:
207 return "TBM_FORMAT_ARGB2101010";
208 case TBM_FORMAT_ABGR2101010:
209 return "TBM_FORMAT_ABGR2101010";
210 case TBM_FORMAT_RGBA1010102:
211 return "TBM_FORMAT_RGBA1010102";
212 case TBM_FORMAT_BGRA1010102:
213 return "TBM_FORMAT_BGRA1010102";
214 case TBM_FORMAT_YUYV:
215 return "TBM_FORMAT_YUYV";
216 case TBM_FORMAT_YVYU:
217 return "TBM_FORMAT_YVYU";
218 case TBM_FORMAT_UYVY:
219 return "TBM_FORMAT_UYVY";
220 case TBM_FORMAT_VYUY:
221 return "TBM_FORMAT_VYUY";
222 case TBM_FORMAT_AYUV:
223 return "TBM_FORMAT_AYUV";
224 case TBM_FORMAT_NV12:
225 return "TBM_FORMAT_NV12";
226 case TBM_FORMAT_NV21:
227 return "TBM_FORMAT_NV21";
228 case TBM_FORMAT_NV16:
229 return "TBM_FORMAT_NV16";
230 case TBM_FORMAT_NV61:
231 return "TBM_FORMAT_NV61";
232 case TBM_FORMAT_YUV410:
233 return "TBM_FORMAT_YUV410";
234 case TBM_FORMAT_YVU410:
235 return "TBM_FORMAT_YVU410";
236 case TBM_FORMAT_YUV411:
237 return "TBM_FORMAT_YUV411";
238 case TBM_FORMAT_YVU411:
239 return "TBM_FORMAT_YVU411";
240 case TBM_FORMAT_YUV420:
241 return "TBM_FORMAT_YUV420";
242 case TBM_FORMAT_YVU420:
243 return "TBM_FORMAT_YVU420";
244 case TBM_FORMAT_YUV422:
245 return "TBM_FORMAT_YUV422";
246 case TBM_FORMAT_YVU422:
247 return "TBM_FORMAT_YVU422";
248 case TBM_FORMAT_YUV444:
249 return "TBM_FORMAT_YUV444";
250 case TBM_FORMAT_YVU444:
251 return "TBM_FORMAT_YVU444";
252 case TBM_FORMAT_NV12MT:
253 return "TBM_FORMAT_NV12MT";
260 _tbm_surface_mutex_lock(void)
262 pthread_mutex_lock(&tbm_surface_lock);
266 _tbm_surface_mutex_unlock(void)
268 pthread_mutex_unlock(&tbm_surface_lock);
272 _init_surface_bufmgr(void)
274 g_surface_bufmgr = tbm_bufmgr_init(-1);
278 _deinit_surface_bufmgr(void)
280 if (!g_surface_bufmgr)
283 tbm_bufmgr_deinit(g_surface_bufmgr);
284 g_surface_bufmgr = NULL;
289 _tbm_surface_internal_magic_check(tbm_surface_h surface)
291 if (surface->magic != TBM_SURFACE_MAGIC)
298 _tbm_surface_internal_is_valid(tbm_surface_h surface)
301 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
302 TBM_ERR("error: No valid tbm_surface is NULL\n");
306 if (!_tbm_surface_internal_magic_check(surface)) {
307 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
308 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
316 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
317 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
319 TBM_RETURN_VAL_IF_FAIL(surface, 0);
320 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
322 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
323 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
326 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
327 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
328 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
329 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
331 error = tbm_module_get_plane_data(bufmgr->module, surf->info.format, plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
332 if (error != TBM_ERROR_NONE) {
333 _tbm_set_last_result(error);
341 _tbm_surface_internal_destroy(tbm_surface_h surface)
344 tbm_bufmgr bufmgr = surface->bufmgr;
345 tbm_user_data *old_data = NULL, *tmp = NULL;
346 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
347 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
349 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
350 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
351 func_info->destroy_func(surface, func_info->user_data);
353 TBM_DBG("free destroy_funcs %p\n", surface);
354 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
355 LIST_DEL(&func_info->item_link);
360 /* destory the user_data_list */
361 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
362 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
363 TBM_DBG("free user_data\n");
364 user_data_delete(old_data);
368 for (i = 0; i < surface->num_bos; i++) {
369 surface->bos[i]->surface = NULL;
371 tbm_bo_unref(surface->bos[i]);
372 surface->bos[i] = NULL;
375 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
376 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
377 _tbm_surface_internal_debug_data_delete(debug_old_data);
380 LIST_DEL(&surface->item_link);
383 if (surface->surface_data) {
384 tbm_surface_data_free(surface->surface_data);
385 surface->surface_data = NULL;
391 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
392 LIST_DELINIT(&bufmgr->surf_list);
394 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
395 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
396 _tbm_surface_internal_debug_data_delete(debug_old_data);
400 _deinit_surface_bufmgr();
404 /* LCOV_EXCL_START */
406 _tbm_surface_check_file_is_symbolic_link(const char* path)
413 if (stat(path, &sb) != 0)
416 if (S_ISLNK(sb.st_mode))
424 _tbm_surface_internal_get_num_planes(tbm_format format)
430 case TBM_FORMAT_RGB332:
431 case TBM_FORMAT_BGR233:
432 case TBM_FORMAT_XRGB4444:
433 case TBM_FORMAT_XBGR4444:
434 case TBM_FORMAT_RGBX4444:
435 case TBM_FORMAT_BGRX4444:
436 case TBM_FORMAT_ARGB4444:
437 case TBM_FORMAT_ABGR4444:
438 case TBM_FORMAT_RGBA4444:
439 case TBM_FORMAT_BGRA4444:
440 case TBM_FORMAT_XRGB1555:
441 case TBM_FORMAT_XBGR1555:
442 case TBM_FORMAT_RGBX5551:
443 case TBM_FORMAT_BGRX5551:
444 case TBM_FORMAT_ARGB1555:
445 case TBM_FORMAT_ABGR1555:
446 case TBM_FORMAT_RGBA5551:
447 case TBM_FORMAT_BGRA5551:
448 case TBM_FORMAT_RGB565:
449 case TBM_FORMAT_BGR565:
450 case TBM_FORMAT_RGB888:
451 case TBM_FORMAT_BGR888:
452 case TBM_FORMAT_XRGB8888:
453 case TBM_FORMAT_XBGR8888:
454 case TBM_FORMAT_RGBX8888:
455 case TBM_FORMAT_BGRX8888:
456 case TBM_FORMAT_ARGB8888:
457 case TBM_FORMAT_ABGR8888:
458 case TBM_FORMAT_RGBA8888:
459 case TBM_FORMAT_BGRA8888:
460 case TBM_FORMAT_XRGB2101010:
461 case TBM_FORMAT_XBGR2101010:
462 case TBM_FORMAT_RGBX1010102:
463 case TBM_FORMAT_BGRX1010102:
464 case TBM_FORMAT_ARGB2101010:
465 case TBM_FORMAT_ABGR2101010:
466 case TBM_FORMAT_RGBA1010102:
467 case TBM_FORMAT_BGRA1010102:
468 case TBM_FORMAT_YUYV:
469 case TBM_FORMAT_YVYU:
470 case TBM_FORMAT_UYVY:
471 case TBM_FORMAT_VYUY:
472 case TBM_FORMAT_AYUV:
475 case TBM_FORMAT_NV12:
476 case TBM_FORMAT_NV12MT:
477 case TBM_FORMAT_NV21:
478 case TBM_FORMAT_NV16:
479 case TBM_FORMAT_NV61:
482 case TBM_FORMAT_YUV410:
483 case TBM_FORMAT_YVU410:
484 case TBM_FORMAT_YUV411:
485 case TBM_FORMAT_YVU411:
486 case TBM_FORMAT_YUV420:
487 case TBM_FORMAT_YVU420:
488 case TBM_FORMAT_YUV422:
489 case TBM_FORMAT_YVU422:
490 case TBM_FORMAT_YUV444:
491 case TBM_FORMAT_YVU444:
496 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
504 _tbm_surface_internal_get_bpp(tbm_format format)
511 case TBM_FORMAT_RGB332:
512 case TBM_FORMAT_BGR233:
515 case TBM_FORMAT_XRGB4444:
516 case TBM_FORMAT_XBGR4444:
517 case TBM_FORMAT_RGBX4444:
518 case TBM_FORMAT_BGRX4444:
519 case TBM_FORMAT_ARGB4444:
520 case TBM_FORMAT_ABGR4444:
521 case TBM_FORMAT_RGBA4444:
522 case TBM_FORMAT_BGRA4444:
523 case TBM_FORMAT_XRGB1555:
524 case TBM_FORMAT_XBGR1555:
525 case TBM_FORMAT_RGBX5551:
526 case TBM_FORMAT_BGRX5551:
527 case TBM_FORMAT_ARGB1555:
528 case TBM_FORMAT_ABGR1555:
529 case TBM_FORMAT_RGBA5551:
530 case TBM_FORMAT_BGRA5551:
531 case TBM_FORMAT_RGB565:
532 case TBM_FORMAT_BGR565:
535 case TBM_FORMAT_RGB888:
536 case TBM_FORMAT_BGR888:
539 case TBM_FORMAT_XRGB8888:
540 case TBM_FORMAT_XBGR8888:
541 case TBM_FORMAT_RGBX8888:
542 case TBM_FORMAT_BGRX8888:
543 case TBM_FORMAT_ARGB8888:
544 case TBM_FORMAT_ABGR8888:
545 case TBM_FORMAT_RGBA8888:
546 case TBM_FORMAT_BGRA8888:
547 case TBM_FORMAT_XRGB2101010:
548 case TBM_FORMAT_XBGR2101010:
549 case TBM_FORMAT_RGBX1010102:
550 case TBM_FORMAT_BGRX1010102:
551 case TBM_FORMAT_ARGB2101010:
552 case TBM_FORMAT_ABGR2101010:
553 case TBM_FORMAT_RGBA1010102:
554 case TBM_FORMAT_BGRA1010102:
555 case TBM_FORMAT_YUYV:
556 case TBM_FORMAT_YVYU:
557 case TBM_FORMAT_UYVY:
558 case TBM_FORMAT_VYUY:
559 case TBM_FORMAT_AYUV:
562 case TBM_FORMAT_NV12:
563 case TBM_FORMAT_NV12MT:
564 case TBM_FORMAT_NV21:
567 case TBM_FORMAT_NV16:
568 case TBM_FORMAT_NV61:
571 case TBM_FORMAT_YUV410:
572 case TBM_FORMAT_YVU410:
575 case TBM_FORMAT_YUV411:
576 case TBM_FORMAT_YVU411:
577 case TBM_FORMAT_YUV420:
578 case TBM_FORMAT_YVU420:
581 case TBM_FORMAT_YUV422:
582 case TBM_FORMAT_YVU422:
585 case TBM_FORMAT_YUV444:
586 case TBM_FORMAT_YVU444:
590 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
597 static struct _tbm_surface *
598 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
600 struct _tbm_surface *surf = NULL;
601 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
604 surf = calloc(1, sizeof(struct _tbm_surface));
606 /* LCOV_EXCL_START */
607 TBM_ERR("fail to alloc surf\n");
608 *error = TBM_ERROR_OUT_OF_MEMORY;
609 goto alloc_surf_fail;
613 surf->magic = TBM_SURFACE_MAGIC;
614 surf->bufmgr = bufmgr;
615 surf->info.width = width;
616 surf->info.height = height;
617 surf->info.format = format;
618 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
619 if (!surf->info.bpp) {
620 TBM_ERR("fail to get bpp from format(%d), error(%s)\n", format, tbm_error_str(*error));
621 *error = tbm_get_last_error();
625 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
626 if (!surf->info.num_planes) {
627 TBM_ERR("fail to get num_planes from format(%d), error(%s)\n", format, tbm_error_str(*error));
628 *error = tbm_get_last_error();
629 goto num_planes_fail;
633 /* get size, stride and offset bo_idx */
634 for (i = 0; i < surf->info.num_planes; i++) {
635 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
636 TBM_ERR("fail to query plane data\n");
637 *error = tbm_get_last_error();
638 goto query_plane_data_fail;
641 surf->info.planes[i].size = size;
642 surf->info.planes[i].offset = offset;
643 surf->info.planes[i].stride = stride;
644 surf->planes_bo_idx[i] = bo_idx;
649 for (i = 0; i < surf->info.num_planes; i++) {
650 surf->info.size += surf->info.planes[i].size;
652 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
653 surf->num_bos = surf->planes_bo_idx[i] + 1;
658 for (i = 0; i < surf->num_bos; i++) {
660 for (j = 0; j < surf->info.num_planes; j++) {
661 if (surf->planes_bo_idx[j] == i)
662 bo_size += surf->info.planes[j].size;
665 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
667 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
669 TBM_ERR("fail to alloc bo idx:%d\n", i);
670 *error = tbm_get_last_error();
675 _tbm_bo_set_surface(surf->bos[i], surf);
678 *error = TBM_ERROR_NONE;
683 for (j = 0; j < i; j++) {
685 tbm_bo_unref(surf->bos[j]);
687 query_plane_data_fail:
696 static struct _tbm_surface *
697 _tbm_surface_internal_create_surface_data(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
699 struct _tbm_surface *surf = NULL;
700 uint32_t size = 0, offset = 0, stride = 0;
702 tbm_bo_data **bo_data_array = NULL;
705 surf = calloc(1, sizeof(struct _tbm_surface));
707 /* LCOV_EXCL_START */
708 TBM_ERR("fail to alloc surf");
709 *error = TBM_ERROR_OUT_OF_MEMORY;
710 goto alloc_surf_fail;
715 surf->magic = TBM_SURFACE_MAGIC;
716 surf->bufmgr = bufmgr;
717 surf->info.width = width;
718 surf->info.height = height;
719 surf->info.format = format;
720 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
721 if (!surf->info.bpp) {
722 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
723 *error = tbm_get_last_error();
728 // get number of planes
729 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
730 if (!surf->info.num_planes) {
731 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
732 *error = tbm_get_last_error();
733 goto num_planes_fail;
736 surf->surface_data = tbm_module_alloc_surface_data(bufmgr->module, width, height, format, flags, error);
737 if (!surf->surface_data) {
738 TBM_ERR("tbm_module_alloc_surface_data failed. error:%s", tbm_error_str(*error));
739 goto alloc_surface_data_fail;
742 // set infomation of planes
743 for (i = 0; i < surf->info.num_planes; i++) {
744 *error = tbm_surface_data_get_plane_data(surf->surface_data, i, &size, &offset, &stride, &bo_idx);
745 if (*error != TBM_ERROR_NONE) {
746 goto query_plane_data_fail;
748 surf->info.planes[i].size = size;
749 surf->info.planes[i].offset = offset;
750 surf->info.planes[i].stride = stride;
751 surf->planes_bo_idx[i] = bo_idx;
754 // set infomation of bos
755 bo_data_array = tbm_surface_data_get_bo_data_array(surf->surface_data, &num_bos, error);
756 if (!bo_data_array) {
757 TBM_ERR("tbm_surface_data_get_bo_data_array failed. error:%s", tbm_error_str(*error));
760 surf->num_bos = num_bos;
762 for (i = 0; i < surf->info.num_planes; i++) {
763 surf->info.size += surf->info.planes[i].size;
765 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
766 surf->num_bos = surf->planes_bo_idx[i] + 1;
769 for (i = 0; i < num_bos; i++) {
770 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_bo_data(bufmgr, bo_data_array[i], flags);
772 TBM_ERR("fail to alloc bo idx:%d", i);
773 *error = tbm_get_last_error();
777 _tbm_bo_set_surface(surf->bos[i], surf);
780 *error = TBM_ERROR_NONE;
785 for (j = 0; j < i; j++) {
787 tbm_bo_unref(surf->bos[j]);
790 query_plane_data_fail:
791 if (surf->surface_data)
792 tbm_surface_data_free(surf->surface_data);
793 alloc_surface_data_fail:
803 static struct _tbm_surface *
804 _tbm_surface_internal_import_surface_data(tbm_bufmgr bufmgr, int width, int height, int format, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
806 struct _tbm_surface *surf = NULL;
807 uint32_t size = 0, offset = 0, stride = 0;
809 tbm_bo_data **bo_data_array = NULL;
813 surf = calloc(1, sizeof(struct _tbm_surface));
815 /* LCOV_EXCL_START */
816 TBM_ERR("fail to alloc surf");
817 *error = TBM_ERROR_OUT_OF_MEMORY;
818 goto alloc_surf_fail;
823 surf->magic = TBM_SURFACE_MAGIC;
824 surf->bufmgr = bufmgr;
825 surf->info.width = width;
826 surf->info.height = height;
827 surf->info.format = format;
828 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
829 if (!surf->info.bpp) {
830 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
831 *error = tbm_get_last_error();
835 // get number of planes
836 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
837 if (!surf->info.num_planes) {
838 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
839 *error = tbm_get_last_error();
840 goto num_planes_fail;
844 surf->surface_data = tbm_module_import_surface_data(bufmgr->module, width, height, format, buffer_data, error);
845 if (surf->surface_data) {
846 TBM_ERR("tbm_module_import_surface_data failed. width:%d height:%d format:%d error:%s",
847 width, height, format, tbm_error_str(*error));
848 goto import_surface_fail;
851 // set infomation of planes
852 for (i = 0; i < surf->info.num_planes; i++) {
853 *error = tbm_surface_data_get_plane_data(surf->surface_data, i, &size, &offset, &stride, &bo_idx);
854 if (*error != TBM_ERROR_NONE) {
855 goto query_plane_data_fail;
857 surf->info.planes[i].size = size;
858 surf->info.planes[i].offset = offset;
859 surf->info.planes[i].stride = stride;
860 surf->planes_bo_idx[i] = bo_idx;
863 // set infomation of bos
864 bo_data_array = tbm_surface_data_get_bo_data_array(surf->surface_data, &num_bos, error);
865 if (!bo_data_array) {
866 TBM_ERR("tbm_surface_data_get_bo_data_array failed. error:%s", tbm_error_str(*error));
869 surf->num_bos = num_bos;
871 for (i = 0; i < surf->info.num_planes; i++) {
872 surf->info.size += surf->info.planes[i].size;
874 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
875 surf->num_bos = surf->planes_bo_idx[i] + 1;
878 // get memory_types(bo flags)
879 flags = tbm_module_bo_get_memory_types(bufmgr->module, NULL, bo_data_array[0], error);
880 if (*error != TBM_ERROR_NONE) {
881 TBM_ERR("tbm_module_bo_get_memory_types failed.error:%s", tbm_error_str(*error));
882 goto get_memory_types_fail;
886 for (i = 0; i < num_bos; i++) {
887 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_bo_data(bufmgr, bo_data_array[i], flags);
889 TBM_ERR("fail to alloc bo idx:%d", i);
890 *error = tbm_get_last_error();
894 _tbm_bo_set_surface(surf->bos[i], surf);
900 for (j = 0; j < i; j++) {
902 tbm_bo_unref(surf->bos[j]);
904 get_memory_types_fail:
906 query_plane_data_fail:
907 if (surf->surface_data)
908 tbm_surface_data_free(surf->surface_data);
920 tbm_surface_internal_is_valid(tbm_surface_h surface)
924 _tbm_surface_mutex_lock();
925 _tbm_set_last_result(TBM_ERROR_NONE);
927 /* Return silently if surface is null. */
929 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
930 _tbm_surface_mutex_unlock();
934 ret = _tbm_surface_internal_is_valid(surface);
936 _tbm_surface_mutex_unlock();
942 tbm_surface_internal_query_supported_formats(uint32_t **formats,
945 struct _tbm_bufmgr *bufmgr;
946 bool bufmgr_initialized = false;
949 _tbm_surface_mutex_lock();
950 _tbm_set_last_result(TBM_ERROR_NONE);
952 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
953 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
955 if (!g_surface_bufmgr) {
956 _init_surface_bufmgr();
957 if (!g_surface_bufmgr) {
958 TBM_ERR("fail bufmgr initialization\n");
959 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
962 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
963 bufmgr_initialized = true;
966 bufmgr = g_surface_bufmgr;
968 error = tbm_module_get_supported_formats(bufmgr->module, formats, num);
969 if (error != TBM_ERROR_NONE) {
970 _tbm_set_last_result(error);
974 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
976 if (bufmgr_initialized) {
977 LIST_DELINIT(&g_surface_bufmgr->surf_list);
978 _deinit_surface_bufmgr();
981 _tbm_surface_mutex_unlock();
985 /* LCOV_EXCL_START */
987 if (bufmgr_initialized) {
988 LIST_DELINIT(&g_surface_bufmgr->surf_list);
989 _deinit_surface_bufmgr();
991 _tbm_surface_mutex_unlock();
993 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
1000 tbm_surface_internal_get_num_planes(tbm_format format)
1004 _tbm_surface_mutex_lock();
1005 _tbm_set_last_result(TBM_ERROR_NONE);
1007 num_planes = _tbm_surface_internal_get_num_planes(format);
1009 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1010 _tbm_surface_mutex_unlock();
1014 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
1016 _tbm_surface_mutex_unlock();
1022 tbm_surface_internal_get_bpp(tbm_format format)
1026 _tbm_surface_mutex_lock();
1027 _tbm_set_last_result(TBM_ERROR_NONE);
1029 bpp = _tbm_surface_internal_get_bpp(format);
1031 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1032 _tbm_surface_mutex_unlock();
1036 _tbm_surface_mutex_unlock();
1038 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
1044 tbm_surface_internal_create_with_flags(int width, int height,
1045 int format, int flags)
1047 struct _tbm_bufmgr *bufmgr;
1048 struct _tbm_surface *surf = NULL;
1049 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
1050 bool bufmgr_initialized = false;
1052 _tbm_surface_mutex_lock();
1053 _tbm_set_last_result(TBM_ERROR_NONE);
1055 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
1056 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
1058 if (!g_surface_bufmgr) {
1059 _init_surface_bufmgr();
1060 if (!g_surface_bufmgr) {
1061 TBM_ERR("fail bufmgr initialization\n");
1062 error = TBM_ERROR_INVALID_OPERATION;
1063 goto check_valid_fail;
1065 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1066 bufmgr_initialized = true;
1069 bufmgr = g_surface_bufmgr;
1070 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1071 TBM_ERR("The bufmgr is invalid\n");
1072 error = TBM_ERROR_INVALID_PARAMETER;
1073 goto check_valid_fail;
1076 if (tbm_module_support_surface_data(bufmgr->module)) {
1077 surf = _tbm_surface_internal_create_surface_data(bufmgr, width, height, format, flags, &error);
1079 TBM_ERR("_tbm_surface_internal_create_surface_data failed.");
1080 goto surface_alloc_fail;
1083 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1085 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1086 goto surface_alloc_fail;
1090 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1091 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1093 LIST_INITHEAD(&surf->user_data_list);
1094 LIST_INITHEAD(&surf->debug_data_list);
1095 LIST_INITHEAD(&surf->destroy_funcs);
1097 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1099 _tbm_set_last_result(error);
1100 _tbm_surface_mutex_unlock();
1104 /* LCOV_EXCL_START */
1108 if (bufmgr_initialized && bufmgr) {
1109 LIST_DELINIT(&bufmgr->surf_list);
1110 _deinit_surface_bufmgr();
1113 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1114 width, height, _tbm_surface_internal_format_to_str(format), flags);
1116 _tbm_set_last_result(error);
1117 _tbm_surface_mutex_unlock();
1119 /* LCOV_EXCL_STOP */
1125 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1126 tbm_bo *bos, int num)
1128 struct _tbm_bufmgr *bufmgr;
1129 struct _tbm_surface *surf = NULL;
1131 bool bufmgr_initialized = false;
1133 _tbm_surface_mutex_lock();
1134 _tbm_set_last_result(TBM_ERROR_NONE);
1136 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1137 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1138 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1139 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1140 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1142 if (!g_surface_bufmgr) {
1143 _init_surface_bufmgr();
1144 if (!g_surface_bufmgr) {
1145 TBM_ERR("fail bufmgr initialization\n");
1146 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1147 goto check_valid_fail;
1149 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1150 bufmgr_initialized = true;
1153 bufmgr = g_surface_bufmgr;
1154 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1155 TBM_ERR("fail to validate the Bufmgr.\n");
1156 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1157 goto check_valid_fail;
1160 surf = calloc(1, sizeof(struct _tbm_surface));
1162 /* LCOV_EXCL_START */
1163 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1164 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1165 goto alloc_surf_fail;
1166 /* LCOV_EXCL_STOP */
1169 surf->magic = TBM_SURFACE_MAGIC;
1170 surf->bufmgr = bufmgr;
1171 surf->info.width = info->width;
1172 surf->info.height = info->height;
1173 surf->info.format = info->format;
1175 surf->info.bpp = info->bpp;
1177 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1178 if (!surf->info.bpp) {
1179 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1183 surf->info.num_planes = info->num_planes;
1186 /* get size, stride and offset */
1187 for (i = 0; i < info->num_planes; i++) {
1188 surf->info.planes[i].offset = info->planes[i].offset;
1189 surf->info.planes[i].stride = info->planes[i].stride;
1191 if (info->planes[i].size > 0)
1192 surf->info.planes[i].size = info->planes[i].size;
1194 uint32_t size = 0, offset = 0, stride = 0;
1197 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1198 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1199 goto plane_data_fail;
1201 surf->info.planes[i].size = size;
1205 surf->planes_bo_idx[i] = 0;
1207 surf->planes_bo_idx[i] = i;
1210 if (info->size > 0) {
1211 surf->info.size = info->size;
1213 surf->info.size = 0;
1214 for (i = 0; i < info->num_planes; i++)
1215 surf->info.size += surf->info.planes[i].size;
1218 surf->flags = TBM_BO_DEFAULT;
1220 /* create only one bo */
1221 surf->num_bos = num;
1222 for (i = 0; i < num; i++) {
1223 if (bos[i] == NULL) {
1224 TBM_ERR("bos[%d] is null.\n", i);
1225 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1229 surf->bos[i] = tbm_bo_ref(bos[i]);
1230 _tbm_bo_set_surface(bos[i], surf);
1233 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1234 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1236 LIST_INITHEAD(&surf->user_data_list);
1237 LIST_INITHEAD(&surf->debug_data_list);
1238 LIST_INITHEAD(&surf->destroy_funcs);
1240 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1242 _tbm_surface_mutex_unlock();
1246 /* LCOV_EXCL_START */
1250 for (i = 0; i < num; i++) {
1252 tbm_bo_unref(surf->bos[i]);
1257 if (bufmgr_initialized && bufmgr) {
1258 LIST_DELINIT(&bufmgr->surf_list);
1259 _deinit_surface_bufmgr();
1261 _tbm_surface_mutex_unlock();
1263 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1264 info->width, info->height,
1265 _tbm_surface_internal_format_to_str(info->format), num);
1266 /* LCOV_EXCL_STOP */
1272 tbm_surface_internal_destroy(tbm_surface_h surface)
1274 _tbm_surface_mutex_lock();
1275 _tbm_set_last_result(TBM_ERROR_NONE);
1277 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1281 if (surface->refcnt > 0) {
1282 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1283 _tbm_surface_mutex_unlock();
1287 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1289 if (surface->refcnt == 0)
1290 _tbm_surface_internal_destroy(surface);
1291 else // if (surface->refcnt < 0)
1292 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1294 _tbm_surface_mutex_unlock();
1298 tbm_surface_internal_ref(tbm_surface_h surface)
1300 _tbm_surface_mutex_lock();
1301 _tbm_set_last_result(TBM_ERROR_NONE);
1303 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1307 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1309 _tbm_surface_mutex_unlock();
1313 tbm_surface_internal_unref(tbm_surface_h surface)
1315 _tbm_surface_mutex_lock();
1316 _tbm_set_last_result(TBM_ERROR_NONE);
1318 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1322 if (surface->refcnt > 0) {
1323 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1324 _tbm_surface_mutex_unlock();
1328 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1330 if (surface->refcnt == 0)
1331 _tbm_surface_internal_destroy(surface);
1333 _tbm_surface_mutex_unlock();
1337 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1339 struct _tbm_surface *surf;
1342 _tbm_surface_mutex_lock();
1343 _tbm_set_last_result(TBM_ERROR_NONE);
1345 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1347 surf = (struct _tbm_surface *)surface;
1348 num = surf->num_bos;
1351 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1353 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1355 _tbm_surface_mutex_unlock();
1361 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1363 struct _tbm_surface *surf;
1366 _tbm_surface_mutex_lock();
1367 _tbm_set_last_result(TBM_ERROR_NONE);
1369 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1370 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1372 surf = (struct _tbm_surface *)surface;
1373 bo = surf->bos[bo_idx];
1375 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1377 _tbm_surface_mutex_unlock();
1383 tbm_surface_internal_get_size(tbm_surface_h surface)
1385 struct _tbm_surface *surf;
1388 _tbm_surface_mutex_lock();
1389 _tbm_set_last_result(TBM_ERROR_NONE);
1391 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1393 surf = (struct _tbm_surface *)surface;
1394 size = surf->info.size;
1396 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1398 _tbm_surface_mutex_unlock();
1404 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1405 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1407 struct _tbm_surface *surf;
1409 _tbm_surface_mutex_lock();
1410 _tbm_set_last_result(TBM_ERROR_NONE);
1412 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1413 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1415 surf = (struct _tbm_surface *)surface;
1417 if (plane_idx >= surf->info.num_planes) {
1418 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1419 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1420 _tbm_surface_mutex_unlock();
1425 *size = surf->info.planes[plane_idx].size;
1428 *offset = surf->info.planes[plane_idx].offset;
1431 *pitch = surf->info.planes[plane_idx].stride;
1433 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1434 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1435 surf->info.planes[plane_idx].stride);
1437 _tbm_surface_mutex_unlock();
1443 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1444 tbm_surface_info_s *info, int map)
1446 struct _tbm_surface *surf;
1447 tbm_bo_handle bo_handles[4];
1450 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1453 _tbm_surface_mutex_lock();
1454 _tbm_set_last_result(TBM_ERROR_NONE);
1456 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1458 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1460 surf = (struct _tbm_surface *)surface;
1462 memset(info, 0x00, sizeof(tbm_surface_info_s));
1463 info->width = surf->info.width;
1464 info->height = surf->info.height;
1465 info->format = surf->info.format;
1466 info->bpp = surf->info.bpp;
1467 info->size = surf->info.size;
1468 info->num_planes = surf->info.num_planes;
1470 for (i = 0; i < surf->info.num_planes; i++) {
1471 info->planes[i].size = surf->info.planes[i].size;
1472 info->planes[i].offset = surf->info.planes[i].offset;
1473 info->planes[i].stride = surf->info.planes[i].stride;
1474 planes_bo_idx[i] = surf->planes_bo_idx[i];
1477 for (i = 0; i < surf->num_bos; i++)
1478 bos[i] = surf->bos[i];
1480 num_bos = surf->num_bos;
1483 _tbm_surface_mutex_unlock();
1484 for (i = 0; i < num_bos; i++) {
1485 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1486 if (bo_handles[i].ptr == NULL) {
1487 for (j = 0; j < i; j++)
1488 tbm_bo_unmap(bos[j]);
1490 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1494 _tbm_surface_mutex_lock();
1496 for (i = 0; i < num_bos; i++) {
1497 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1498 if (bo_handles[i].ptr == NULL) {
1499 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1500 _tbm_surface_mutex_unlock();
1506 for (i = 0; i < info->num_planes; i++) {
1507 if (bo_handles[planes_bo_idx[i]].ptr)
1508 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1511 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1513 _tbm_surface_mutex_unlock();
1519 tbm_surface_internal_unmap(tbm_surface_h surface)
1521 struct _tbm_surface *surf;
1524 _tbm_surface_mutex_lock();
1525 _tbm_set_last_result(TBM_ERROR_NONE);
1527 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1529 surf = (struct _tbm_surface *)surface;
1531 for (i = 0; i < surf->num_bos; i++)
1532 tbm_bo_unmap(surf->bos[i]);
1534 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1536 _tbm_surface_mutex_unlock();
1540 tbm_surface_internal_get_width(tbm_surface_h surface)
1542 struct _tbm_surface *surf;
1545 _tbm_surface_mutex_lock();
1546 _tbm_set_last_result(TBM_ERROR_NONE);
1548 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1550 surf = (struct _tbm_surface *)surface;
1551 width = surf->info.width;
1553 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1555 _tbm_surface_mutex_unlock();
1561 tbm_surface_internal_get_height(tbm_surface_h surface)
1563 struct _tbm_surface *surf;
1564 unsigned int height;
1566 _tbm_surface_mutex_lock();
1567 _tbm_set_last_result(TBM_ERROR_NONE);
1569 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1571 surf = (struct _tbm_surface *)surface;
1572 height = surf->info.height;
1574 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1576 _tbm_surface_mutex_unlock();
1583 tbm_surface_internal_get_format(tbm_surface_h surface)
1585 struct _tbm_surface *surf;
1588 _tbm_surface_mutex_lock();
1589 _tbm_set_last_result(TBM_ERROR_NONE);
1591 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1593 surf = (struct _tbm_surface *)surface;
1594 format = surf->info.format;
1596 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1598 _tbm_surface_mutex_unlock();
1604 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1606 struct _tbm_surface *surf;
1609 _tbm_surface_mutex_lock();
1610 _tbm_set_last_result(TBM_ERROR_NONE);
1612 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1613 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1615 surf = (struct _tbm_surface *)surface;
1616 bo_idx = surf->planes_bo_idx[plane_idx];
1618 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1620 _tbm_surface_mutex_unlock();
1626 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1627 tbm_data_free data_free_func)
1629 tbm_user_data *data;
1631 _tbm_surface_mutex_lock();
1632 _tbm_set_last_result(TBM_ERROR_NONE);
1634 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1636 /* check if the data according to the key exist if so, return false. */
1637 data = user_data_lookup(&surface->user_data_list, key);
1639 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1640 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1641 _tbm_surface_mutex_unlock();
1645 data = user_data_create(key, data_free_func);
1647 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1648 _tbm_surface_mutex_unlock();
1652 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1654 LIST_ADD(&data->item_link, &surface->user_data_list);
1656 _tbm_surface_mutex_unlock();
1662 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1665 tbm_user_data *old_data;
1667 _tbm_surface_mutex_lock();
1668 _tbm_set_last_result(TBM_ERROR_NONE);
1670 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1672 old_data = user_data_lookup(&surface->user_data_list, key);
1674 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1675 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1676 _tbm_surface_mutex_unlock();
1680 if (old_data->data && old_data->free_func)
1681 old_data->free_func(old_data->data);
1683 old_data->data = data;
1685 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1687 _tbm_surface_mutex_unlock();
1693 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1696 tbm_user_data *old_data;
1698 _tbm_surface_mutex_lock();
1699 _tbm_set_last_result(TBM_ERROR_NONE);
1701 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1704 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1705 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1706 _tbm_surface_mutex_unlock();
1711 old_data = user_data_lookup(&surface->user_data_list, key);
1713 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1714 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1715 _tbm_surface_mutex_unlock();
1719 *data = old_data->data;
1721 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1723 _tbm_surface_mutex_unlock();
1729 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1732 tbm_user_data *old_data = (void *)0;
1734 _tbm_surface_mutex_lock();
1735 _tbm_set_last_result(TBM_ERROR_NONE);
1737 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1739 old_data = user_data_lookup(&surface->user_data_list, key);
1741 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1742 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1743 _tbm_surface_mutex_unlock();
1747 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1749 user_data_delete(old_data);
1751 _tbm_surface_mutex_unlock();
1756 /* LCOV_EXCL_START */
1758 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1760 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1762 return surface->debug_pid;
1766 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1768 _tbm_surface_mutex_lock();
1769 _tbm_set_last_result(TBM_ERROR_NONE);
1771 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1773 surface->debug_pid = pid;
1775 _tbm_surface_mutex_unlock();
1778 static tbm_surface_debug_data *
1779 _tbm_surface_internal_debug_data_create(char *key, char *value)
1781 tbm_surface_debug_data *debug_data = NULL;
1783 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1785 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1786 TBM_ERR("fail to allocate the debug_data.");
1790 if (key) debug_data->key = strdup(key);
1791 if (value) debug_data->value = strdup(value);
1797 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1799 if (!debug_data->value && !value)
1802 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1805 if (debug_data->value)
1806 free(debug_data->value);
1809 debug_data->value = strdup(value);
1811 debug_data->value = NULL;
1814 static tbm_surface_debug_data *
1815 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1817 tbm_surface_debug_data *debug_data = NULL;
1819 if (LIST_IS_EMPTY(list))
1822 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1823 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1831 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1833 tbm_surface_debug_data *debug_data = NULL;
1834 tbm_bufmgr bufmgr = NULL;
1836 _tbm_surface_mutex_lock();
1837 _tbm_set_last_result(TBM_ERROR_NONE);
1839 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1840 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1842 bufmgr = surface->bufmgr;
1844 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1846 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1848 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1850 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1852 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1853 _tbm_surface_mutex_unlock();
1857 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1860 /* add new debug key to list */
1861 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1863 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1865 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1868 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1870 _tbm_surface_mutex_unlock();
1876 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1878 tbm_surface_debug_data *old_data = NULL;
1880 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1882 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1883 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1884 if (!strcmp(old_data->key, key))
1885 return old_data->value;
1892 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1893 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1895 struct _tbm_surface_dump_buf_info {
1905 tbm_surface_info_s info;
1907 struct list_head link;
1910 struct _tbm_surface_dump_info {
1911 char *path; // copy???
1914 struct list_head *link;
1915 struct list_head surface_list; /* link of surface */
1918 static tbm_surface_dump_info *g_dump_info = NULL;
1919 static const char *dump_postfix[2] = {"png", "yuv"};
1920 static double scale_factor;
1923 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1924 void *data2, int size2, void *data3, int size3)
1927 unsigned int *blocks;
1929 if (_tbm_surface_check_file_is_symbolic_link(file))
1930 TBM_ERR("%s is symbolic link\n", file);
1932 fp = fopen(file, "w+");
1933 TBM_RETURN_IF_FAIL(fp != NULL);
1935 blocks = (unsigned int *)data1;
1936 fwrite(blocks, 1, size1, fp);
1939 blocks = (unsigned int *)data2;
1940 fwrite(blocks, 1, size2, fp);
1944 blocks = (unsigned int *)data3;
1945 fwrite(blocks, 1, size3, fp);
1952 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1954 unsigned int *blocks = (unsigned int *)data;
1957 png_bytep *row_pointers;
1960 if (_tbm_surface_check_file_is_symbolic_link(file))
1961 TBM_ERR("%s is symbolic link\n", file);
1963 fp = fopen(file, "wb");
1964 TBM_RETURN_IF_FAIL(fp != NULL);
1966 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1969 TBM_ERR("fail to create a png write structure.\n");
1974 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1976 TBM_ERR("fail to create a png info structure.\n");
1977 png_destroy_write_struct(&pPngStruct, NULL);
1982 if (setjmp(png_jmpbuf(pPngStruct))) {
1983 /* if png has problem of writing the file, we get here */
1984 TBM_ERR("fail to write png file.\n");
1985 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1990 png_init_io(pPngStruct, fp);
1991 if (format == TBM_FORMAT_XRGB8888) {
1993 png_set_IHDR(pPngStruct,
2000 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2003 png_set_IHDR(pPngStruct,
2008 PNG_COLOR_TYPE_RGBA,
2010 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2013 png_set_bgr(pPngStruct);
2014 png_write_info(pPngStruct, pPngInfo);
2016 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
2017 if (!row_pointers) {
2018 TBM_ERR("fail to allocate the png row_pointers.\n");
2019 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2024 for (y = 0; y < height; ++y) {
2028 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
2030 TBM_ERR("fail to allocate the png row.\n");
2031 for (x = 0; x < y; x++)
2032 png_free(pPngStruct, row_pointers[x]);
2033 png_free(pPngStruct, row_pointers);
2034 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2038 row_pointers[y] = (png_bytep)row;
2040 for (x = 0; x < width; ++x) {
2041 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
2043 if (pixel_size == 3) { // XRGB8888 or XBGR8888
2044 if (format == TBM_FORMAT_XRGB8888) {
2045 row[x * pixel_size] = (curBlock & 0xFF);
2046 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2047 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2049 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
2050 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2051 row[2 + x * pixel_size] = (curBlock & 0xFF);
2053 } else { // ARGB8888 or ABGR8888
2054 if (format == TBM_FORMAT_ARGB8888) {
2055 row[x * pixel_size] = (curBlock & 0xFF);
2056 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2057 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2058 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2060 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
2061 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2062 row[2 + x * pixel_size] = (curBlock & 0xFF);
2063 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2069 png_write_image(pPngStruct, row_pointers);
2070 png_write_end(pPngStruct, pPngInfo);
2072 for (y = 0; y < height; y++)
2073 png_free(pPngStruct, row_pointers[y]);
2074 png_free(pPngStruct, row_pointers);
2076 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2082 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2084 TBM_RETURN_IF_FAIL(path != NULL);
2085 TBM_RETURN_IF_FAIL(w > 0);
2086 TBM_RETURN_IF_FAIL(h > 0);
2087 TBM_RETURN_IF_FAIL(count > 0);
2089 tbm_surface_dump_buf_info *buf_info = NULL;
2090 tbm_surface_h tbm_surface;
2091 tbm_surface_info_s info;
2096 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2100 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2101 TBM_RETURN_IF_FAIL(g_dump_info);
2103 LIST_INITHEAD(&g_dump_info->surface_list);
2104 g_dump_info->count = 0;
2105 g_dump_info->dump_max = count;
2107 /* get buffer size */
2108 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2109 if (tbm_surface == NULL) {
2110 TBM_ERR("tbm_surface_create fail\n");
2116 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2117 TBM_ERR("tbm_surface_get_info fail\n");
2118 tbm_surface_destroy(tbm_surface);
2123 buffer_size = info.size;
2124 tbm_surface_destroy(tbm_surface);
2126 /* create dump lists */
2127 for (i = 0; i < count; i++) {
2130 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2131 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2133 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2135 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2140 buf_info->index = i;
2142 buf_info->size = buffer_size;
2144 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2147 g_dump_info->path = path;
2148 g_dump_info->link = &g_dump_info->surface_list;
2152 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2157 /* free resources */
2158 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2159 tbm_surface_dump_buf_info *tmp;
2161 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2162 tbm_bo_unref(buf_info->bo);
2163 LIST_DEL(&buf_info->link);
2168 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2177 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2184 tbm_surface_internal_dump_start(path, w, h, count);
2185 scale_factor = scale;
2189 tbm_surface_internal_dump_end(void)
2191 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2192 tbm_bo_handle bo_handle;
2197 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2204 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2207 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2208 if (bo_handle.ptr == NULL) {
2209 tbm_bo_unref(buf_info->bo);
2210 LIST_DEL(&buf_info->link);
2215 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2216 TBM_INFO("Dump File.. %s generated.\n", file);
2218 if (buf_info->dirty) {
2219 void *ptr1 = NULL, *ptr2 = NULL;
2221 switch (buf_info->info.format) {
2222 case TBM_FORMAT_ARGB8888:
2223 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2224 buf_info->info.planes[0].stride >> 2,
2225 buf_info->info.height,
2226 buf_info->info.planes[0].stride,
2227 TBM_FORMAT_ARGB8888);
2229 case TBM_FORMAT_XRGB8888:
2230 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2231 buf_info->info.planes[0].stride >> 2,
2232 buf_info->info.height,
2233 buf_info->info.planes[0].stride,
2234 TBM_FORMAT_XRGB8888);
2236 case TBM_FORMAT_ABGR8888:
2237 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2238 buf_info->info.planes[0].stride >> 2,
2239 buf_info->info.height,
2240 buf_info->info.planes[0].stride,
2241 TBM_FORMAT_ABGR8888);
2243 case TBM_FORMAT_XBGR8888:
2244 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2245 buf_info->info.planes[0].stride >> 2,
2246 buf_info->info.height,
2247 buf_info->info.planes[0].stride,
2248 TBM_FORMAT_XBGR8888);
2250 case TBM_FORMAT_YVU420:
2251 case TBM_FORMAT_YUV420:
2252 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2253 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2254 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2255 buf_info->info.planes[0].stride * buf_info->info.height,
2257 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2259 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2261 case TBM_FORMAT_NV12:
2262 case TBM_FORMAT_NV21:
2263 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2264 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2265 buf_info->info.planes[0].stride * buf_info->info.height,
2267 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2270 case TBM_FORMAT_YUYV:
2271 case TBM_FORMAT_UYVY:
2272 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2273 buf_info->info.planes[0].stride * buf_info->info.height,
2277 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2280 } else if (buf_info->dirty_shm)
2281 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2282 buf_info->shm_stride >> 2,
2284 buf_info->shm_stride, 0);
2286 tbm_bo_unmap(buf_info->bo);
2287 tbm_bo_unref(buf_info->bo);
2288 LIST_DEL(&buf_info->link);
2295 TBM_INFO("Dump End..\n");
2298 static pixman_format_code_t
2299 _tbm_surface_internal_pixman_format_get(tbm_format format)
2302 case TBM_FORMAT_ARGB8888:
2303 case TBM_FORMAT_ABGR8888:
2304 return PIXMAN_a8r8g8b8;
2305 case TBM_FORMAT_XRGB8888:
2306 case TBM_FORMAT_XBGR8888:
2307 return PIXMAN_x8r8g8b8;
2316 * This function supports only if a buffer has below formats.
2317 * - TBM_FORMAT_ARGB8888
2318 * - TBM_FORMAT_XRGB8888
2319 * - TBM_FORMAT_ABGR8888
2320 * - TBM_FORMAT_XBGR8888
2322 static tbm_surface_error_e
2323 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2324 int format, int src_stride, int src_w, int src_h,
2325 int dst_stride, int dst_w, int dst_h)
2327 pixman_image_t *src_img = NULL, *dst_img = NULL;
2328 pixman_format_code_t pixman_format;
2329 pixman_transform_t t;
2330 struct pixman_f_transform ft;
2331 double scale_x, scale_y;
2333 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2334 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2336 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2337 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2340 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2341 (uint32_t*)src_ptr, src_stride);
2342 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2345 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2346 (uint32_t*)dst_ptr, dst_stride);
2347 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2349 pixman_f_transform_init_identity(&ft);
2351 scale_x = (double)src_w / dst_w;
2352 scale_y = (double)src_h / dst_h;
2354 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2355 pixman_f_transform_translate(&ft, NULL, 0, 0);
2356 pixman_transform_from_pixman_f_transform(&t, &ft);
2357 pixman_image_set_transform(src_img, &t);
2359 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2360 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2362 pixman_image_unref(src_img);
2363 pixman_image_unref(dst_img);
2365 return TBM_SURFACE_ERROR_NONE;
2369 pixman_image_unref(src_img);
2371 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2374 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2375 #define KEY_LEN 5 // "_XXXX"
2376 #define KEYS_LEN KEY_LEN * MAX_BOS
2378 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2380 char *keys, temp_key[KEY_LEN + 1];
2381 struct _tbm_surface *surf;
2385 _tbm_surface_mutex_lock();
2387 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2389 surf = (struct _tbm_surface *)surface;
2391 num_bos = surf->num_bos;
2392 if (num_bos > MAX_BOS)
2395 keys = calloc(KEYS_LEN + 1, sizeof(char));
2397 TBM_ERR("Failed to alloc memory");
2398 _tbm_surface_mutex_unlock();
2402 for (i = 0; i < num_bos; i++) {
2403 memset(temp_key, 0x00, KEY_LEN + 1);
2405 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2406 strncat(keys, temp_key, KEY_LEN + 1);
2409 _tbm_surface_mutex_unlock();
2414 static void _tbm_surface_internal_put_keys(char *keys)
2421 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2423 TBM_RETURN_IF_FAIL(surface != NULL);
2424 TBM_RETURN_IF_FAIL(type != NULL);
2426 tbm_surface_dump_buf_info *buf_info;
2427 struct list_head *next_link;
2428 tbm_surface_info_s info;
2429 tbm_bo_handle bo_handle;
2430 const char *postfix;
2431 const char *format = NULL;
2438 next_link = g_dump_info->link->next;
2439 TBM_RETURN_IF_FAIL(next_link != NULL);
2441 if (next_link == &g_dump_info->surface_list) {
2442 next_link = next_link->next;
2443 TBM_RETURN_IF_FAIL(next_link != NULL);
2446 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2447 TBM_RETURN_IF_FAIL(buf_info != NULL);
2449 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2450 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2452 if (scale_factor > 0.0) {
2455 if ((info.format != TBM_FORMAT_ARGB8888) && (info.format != TBM_FORMAT_XRGB8888) &&
2456 (info.format != TBM_FORMAT_ABGR8888) && (info.format != TBM_FORMAT_XBGR8888)) {
2457 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2458 _tbm_surface_internal_format_to_str(info.format));
2459 tbm_surface_unmap(surface);
2463 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2465 buf_info->info.width = info.width * scale_factor;
2466 buf_info->info.height = info.height * scale_factor;
2467 buf_info->info.format = info.format;
2468 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2469 if (!buf_info->info.bpp) {
2470 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2471 tbm_surface_unmap(surface);
2474 buf_info->info.num_planes = 1;
2475 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2476 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2478 if (buf_info->info.size > buf_info->size) {
2479 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2480 buf_info->info.size, buf_info->size);
2481 tbm_surface_unmap(surface);
2485 if (info.size > buf_info->size) {
2486 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2487 info.size, buf_info->size);
2488 tbm_surface_unmap(surface);
2492 /* make the file information */
2493 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2496 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2497 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888)) {
2498 postfix = dump_postfix[0];
2499 format = _tbm_surface_internal_format_to_str(info.format);
2501 postfix = dump_postfix[1];
2503 keys = _tbm_surface_internal_get_keys(surface);
2505 TBM_ERR("fail to get keys");
2506 tbm_surface_unmap(surface);
2511 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2512 if (!bo_handle.ptr) {
2513 TBM_ERR("fail to map bo");
2514 _tbm_surface_internal_put_keys(keys);
2515 tbm_surface_unmap(surface);
2518 memset(bo_handle.ptr, 0x00, buf_info->size);
2520 switch (info.format) {
2521 case TBM_FORMAT_ARGB8888:
2522 case TBM_FORMAT_XRGB8888:
2523 case TBM_FORMAT_ABGR8888:
2524 case TBM_FORMAT_XBGR8888:
2525 snprintf(buf_info->name, sizeof(buf_info->name),
2526 "%10.3f_%03d%s_%p_%s-%s.%s",
2527 _tbm_surface_internal_get_time(),
2528 g_dump_info->count++, keys, surface, format, type, postfix);
2530 if (scale_factor > 0.0) {
2531 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2533 buf_info->info.format,
2534 info.planes[0].stride,
2535 info.width, info.height,
2536 buf_info->info.planes[0].stride,
2537 buf_info->info.width,
2538 buf_info->info.height);
2539 if (ret != TBM_SURFACE_ERROR_NONE) {
2540 TBM_ERR("fail to scale buffer");
2541 tbm_bo_unmap(buf_info->bo);
2542 _tbm_surface_internal_put_keys(keys);
2543 tbm_surface_unmap(surface);
2547 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2549 case TBM_FORMAT_YVU420:
2550 case TBM_FORMAT_YUV420:
2551 snprintf(buf_info->name, sizeof(buf_info->name),
2552 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2553 _tbm_surface_internal_get_time(),
2554 g_dump_info->count++, keys, type, info.planes[0].stride,
2555 info.height, FOURCC_STR(info.format), postfix);
2556 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2557 bo_handle.ptr += info.planes[0].stride * info.height;
2558 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2559 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2560 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2562 case TBM_FORMAT_NV12:
2563 case TBM_FORMAT_NV21:
2564 snprintf(buf_info->name, sizeof(buf_info->name),
2565 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2566 _tbm_surface_internal_get_time(),
2567 g_dump_info->count++, keys, type, info.planes[0].stride,
2568 info.height, FOURCC_STR(info.format), postfix);
2569 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2570 bo_handle.ptr += info.planes[0].stride * info.height;
2571 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2573 case TBM_FORMAT_YUYV:
2574 case TBM_FORMAT_UYVY:
2575 snprintf(buf_info->name, sizeof(buf_info->name),
2576 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2577 _tbm_surface_internal_get_time(),
2578 g_dump_info->count++, keys, type, info.planes[0].stride,
2579 info.height, FOURCC_STR(info.format), postfix);
2580 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2583 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2584 tbm_bo_unmap(buf_info->bo);
2585 _tbm_surface_internal_put_keys(keys);
2586 tbm_surface_unmap(surface);
2590 tbm_bo_unmap(buf_info->bo);
2592 _tbm_surface_internal_put_keys(keys);
2594 tbm_surface_unmap(surface);
2596 buf_info->dirty = 1;
2597 buf_info->dirty_shm = 0;
2599 if (g_dump_info->count == 1000)
2600 g_dump_info->count = 0;
2602 g_dump_info->link = next_link;
2604 TBM_INFO("Dump %s \n", buf_info->name);
2607 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2610 TBM_RETURN_IF_FAIL(ptr != NULL);
2611 TBM_RETURN_IF_FAIL(w > 0);
2612 TBM_RETURN_IF_FAIL(h > 0);
2613 TBM_RETURN_IF_FAIL(stride > 0);
2614 TBM_RETURN_IF_FAIL(type != NULL);
2616 tbm_surface_dump_buf_info *buf_info;
2617 struct list_head *next_link;
2618 tbm_bo_handle bo_handle;
2619 int ret, size, dw = 0, dh = 0, dstride = 0;
2624 next_link = g_dump_info->link->next;
2625 TBM_RETURN_IF_FAIL(next_link != NULL);
2627 if (next_link == &g_dump_info->surface_list) {
2628 next_link = next_link->next;
2629 TBM_RETURN_IF_FAIL(next_link != NULL);
2632 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2633 TBM_RETURN_IF_FAIL(buf_info != NULL);
2635 if (scale_factor > 0.0) {
2638 dw = w * scale_factor;
2639 dh = h * scale_factor;
2641 size = dstride * dh;
2645 if (size > buf_info->size) {
2646 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2647 size, buf_info->size);
2652 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2653 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2655 memset(bo_handle.ptr, 0x00, buf_info->size);
2656 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2658 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2659 _tbm_surface_internal_get_time(),
2660 g_dump_info->count++, type, dump_postfix[0]);
2661 if (scale_factor > 0.0) {
2662 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2663 TBM_FORMAT_ARGB8888, stride,
2664 w, h, dstride, dw, dh);
2665 if (ret != TBM_SURFACE_ERROR_NONE) {
2666 TBM_ERR("fail to scale buffer");
2667 tbm_bo_unmap(buf_info->bo);
2670 buf_info->shm_stride = dstride;
2671 buf_info->shm_h = dh;
2673 memcpy(bo_handle.ptr, ptr, size);
2674 buf_info->shm_stride = stride;
2675 buf_info->shm_h = h;
2678 tbm_bo_unmap(buf_info->bo);
2680 buf_info->dirty = 0;
2681 buf_info->dirty_shm = 1;
2683 if (g_dump_info->count == 1000)
2684 g_dump_info->count = 0;
2686 g_dump_info->link = next_link;
2688 TBM_INFO("Dump %s \n", buf_info->name);
2692 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2694 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2695 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2696 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2698 tbm_surface_info_s info;
2699 const char *postfix;
2703 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2704 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2706 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2707 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888))
2708 postfix = dump_postfix[0];
2710 postfix = dump_postfix[1];
2712 if (strcmp(postfix, type)) {
2713 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2714 tbm_surface_unmap(surface);
2718 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2720 if (!access(file, 0)) {
2721 TBM_ERR("can't capture buffer, exist file %s", file);
2722 tbm_surface_unmap(surface);
2726 switch (info.format) {
2727 case TBM_FORMAT_ARGB8888:
2728 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2731 info.planes[0].stride,
2732 TBM_FORMAT_ARGB8888);
2734 case TBM_FORMAT_XRGB8888:
2735 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2738 info.planes[0].stride,
2739 TBM_FORMAT_XRGB8888);
2741 case TBM_FORMAT_ABGR8888:
2742 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2745 info.planes[0].stride,
2746 TBM_FORMAT_ABGR8888);
2748 case TBM_FORMAT_XBGR8888:
2749 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2752 info.planes[0].stride,
2753 TBM_FORMAT_XBGR8888);
2755 case TBM_FORMAT_YVU420:
2756 case TBM_FORMAT_YUV420:
2757 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2758 info.planes[0].stride * info.height,
2760 info.planes[1].stride * (info.height >> 1),
2762 info.planes[2].stride * (info.height >> 1));
2764 case TBM_FORMAT_NV12:
2765 case TBM_FORMAT_NV21:
2766 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2767 info.planes[0].stride * info.height,
2769 info.planes[1].stride * (info.height >> 1),
2772 case TBM_FORMAT_YUYV:
2773 case TBM_FORMAT_UYVY:
2774 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2775 info.planes[0].stride * info.height,
2779 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2780 tbm_surface_unmap(surface);
2784 tbm_surface_unmap(surface);
2786 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2792 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2793 const char *path, const char *name, const char *type)
2795 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2796 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2797 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2798 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2799 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2800 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2804 if (strcmp(dump_postfix[0], type)) {
2805 TBM_ERR("Not supported type:%s'", type);
2809 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2811 if (!access(file, 0)) {
2812 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2816 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2818 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2824 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2826 struct _tbm_surface *surf;
2828 _tbm_surface_mutex_lock();
2829 _tbm_set_last_result(TBM_ERROR_NONE);
2831 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2832 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2833 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2835 surf = (struct _tbm_surface *)surface;
2839 surf->damage.width = width;
2840 surf->damage.height = height;
2842 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2843 surface, x, y, width, height);
2845 _tbm_surface_mutex_unlock();
2851 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2853 struct _tbm_surface *surf;
2855 _tbm_surface_mutex_lock();
2856 _tbm_set_last_result(TBM_ERROR_NONE);
2858 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2860 surf = (struct _tbm_surface *)surface;
2862 if (x) *x = surf->damage.x;
2863 if (y) *y = surf->damage.y;
2864 if (width) *width = surf->damage.width;
2865 if (height) *height = surf->damage.height;
2867 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2868 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2870 _tbm_surface_mutex_unlock();
2876 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2878 struct _tbm_surface *surf;
2879 tbm_surface_destroy_func_info *func_info = NULL;
2881 _tbm_surface_mutex_lock();
2882 _tbm_set_last_result(TBM_ERROR_NONE);
2884 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2885 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2887 surf = (struct _tbm_surface *)surface;
2888 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2889 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2890 TBM_ERR("can't add twice");
2891 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2892 _tbm_surface_mutex_unlock();
2897 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2898 if (func_info == NULL) {
2899 TBM_ERR("alloc failed");
2900 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2901 _tbm_surface_mutex_unlock();
2905 func_info->destroy_func = func;
2906 func_info->user_data = user_data;
2908 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2910 _tbm_surface_mutex_unlock();
2916 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2918 struct _tbm_surface *surf;
2919 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2921 _tbm_surface_mutex_lock();
2922 _tbm_set_last_result(TBM_ERROR_NONE);
2924 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2925 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2927 surf = (struct _tbm_surface *)surface;
2928 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2929 if (func_info->destroy_func != func || func_info->user_data != user_data)
2932 LIST_DEL(&func_info->item_link);
2935 _tbm_surface_mutex_unlock();
2940 _tbm_surface_mutex_unlock();
2943 tbm_surface_buffer_data *
2944 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2946 tbm_surface_buffer_data *buffer_data = NULL;
2947 struct _tbm_bufmgr *bufmgr;
2949 _tbm_surface_mutex_lock();
2951 bufmgr = g_surface_bufmgr;
2952 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2954 // this function supports when the module suppport surface_data.
2955 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(tbm_module_support_surface_data(bufmgr->module), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2957 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, error, TBM_ERROR_INVALID_PARAMETER);
2960 buffer_data = tbm_surface_data_export(surface->surface_data, error);
2961 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
2963 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
2965 _tbm_set_last_result(TBM_ERROR_NONE);
2966 _tbm_surface_mutex_unlock();
2972 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
2974 struct _tbm_surface *surf;
2975 struct _tbm_bufmgr *bufmgr;
2977 _tbm_surface_mutex_lock();
2979 bufmgr = g_surface_bufmgr;
2980 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2982 // this function supports when the module suppport surface_data.
2983 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(tbm_module_support_surface_data(bufmgr->module), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2985 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2986 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2987 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2988 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2991 surf = _tbm_surface_internal_import_surface_data(bufmgr,
2992 (int)surface_info->width,
2993 (int)surface_info->height,
2994 (int)surface_info->format,
2997 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
2999 LIST_INITHEAD(&surf->user_data_list);
3000 LIST_INITHEAD(&surf->debug_data_list);
3001 LIST_INITHEAD(&surf->destroy_funcs);
3003 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
3005 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
3007 _tbm_set_last_result(TBM_ERROR_NONE);
3008 _tbm_surface_mutex_unlock();
3010 return (tbm_surface_h)surf;