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 _tbm_set_last_result(error_type);\
103 _tbm_surface_mutex_unlock();\
108 /* LCOV_EXCL_START */
110 _tbm_surface_internal_get_time(void)
115 clock_gettime(CLOCK_MONOTONIC, &tp);
116 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
118 return time / 1000.0;
122 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
124 LIST_DEL(&debug_data->item_link);
126 if (debug_data->key) free(debug_data->key);
127 if (debug_data->value) free(debug_data->value);
132 _tbm_surface_internal_format_to_str(tbm_format format)
136 return "TBM_FORMAT_C8";
137 case TBM_FORMAT_RGB332:
138 return "TBM_FORMAT_RGB332";
139 case TBM_FORMAT_BGR233:
140 return "TBM_FORMAT_BGR233";
141 case TBM_FORMAT_XRGB4444:
142 return "TBM_FORMAT_XRGB4444";
143 case TBM_FORMAT_XBGR4444:
144 return "TBM_FORMAT_XBGR4444";
145 case TBM_FORMAT_RGBX4444:
146 return "TBM_FORMAT_RGBX4444";
147 case TBM_FORMAT_BGRX4444:
148 return "TBM_FORMAT_BGRX4444";
149 case TBM_FORMAT_ARGB4444:
150 return "TBM_FORMAT_ARGB4444";
151 case TBM_FORMAT_ABGR4444:
152 return "TBM_FORMAT_ABGR4444";
153 case TBM_FORMAT_RGBA4444:
154 return "TBM_FORMAT_RGBA4444";
155 case TBM_FORMAT_BGRA4444:
156 return "TBM_FORMAT_BGRA4444";
157 case TBM_FORMAT_XRGB1555:
158 return "TBM_FORMAT_XRGB1555";
159 case TBM_FORMAT_XBGR1555:
160 return "TBM_FORMAT_XBGR1555";
161 case TBM_FORMAT_RGBX5551:
162 return "TBM_FORMAT_RGBX5551";
163 case TBM_FORMAT_BGRX5551:
164 return "TBM_FORMAT_BGRX5551";
165 case TBM_FORMAT_ARGB1555:
166 return "TBM_FORMAT_ARGB1555";
167 case TBM_FORMAT_ABGR1555:
168 return "TBM_FORMAT_ABGR1555";
169 case TBM_FORMAT_RGBA5551:
170 return "TBM_FORMAT_RGBA5551";
171 case TBM_FORMAT_BGRA5551:
172 return "TBM_FORMAT_BGRA5551";
173 case TBM_FORMAT_RGB565:
174 return "TBM_FORMAT_RGB565";
175 case TBM_FORMAT_BGR565:
176 return "TBM_FORMAT_BGR565";
177 case TBM_FORMAT_RGB888:
178 return "TBM_FORMAT_RGB888";
179 case TBM_FORMAT_BGR888:
180 return "TBM_FORMAT_BGR888";
181 case TBM_FORMAT_XRGB8888:
182 return "TBM_FORMAT_XRGB8888";
183 case TBM_FORMAT_XBGR8888:
184 return "TBM_FORMAT_XBGR8888";
185 case TBM_FORMAT_RGBX8888:
186 return "TBM_FORMAT_RGBX8888";
187 case TBM_FORMAT_BGRX8888:
188 return "TBM_FORMAT_BGRX8888";
189 case TBM_FORMAT_ARGB8888:
190 return "TBM_FORMAT_ARGB8888";
191 case TBM_FORMAT_ABGR8888:
192 return "TBM_FORMAT_ABGR8888";
193 case TBM_FORMAT_RGBA8888:
194 return "TBM_FORMAT_RGBA8888";
195 case TBM_FORMAT_BGRA8888:
196 return "TBM_FORMAT_BGRA8888";
197 case TBM_FORMAT_XRGB2101010:
198 return "TBM_FORMAT_XRGB2101010";
199 case TBM_FORMAT_XBGR2101010:
200 return "TBM_FORMAT_XBGR2101010";
201 case TBM_FORMAT_RGBX1010102:
202 return "TBM_FORMAT_RGBX1010102";
203 case TBM_FORMAT_BGRX1010102:
204 return "TBM_FORMAT_BGRX1010102";
205 case TBM_FORMAT_ARGB2101010:
206 return "TBM_FORMAT_ARGB2101010";
207 case TBM_FORMAT_ABGR2101010:
208 return "TBM_FORMAT_ABGR2101010";
209 case TBM_FORMAT_RGBA1010102:
210 return "TBM_FORMAT_RGBA1010102";
211 case TBM_FORMAT_BGRA1010102:
212 return "TBM_FORMAT_BGRA1010102";
213 case TBM_FORMAT_YUYV:
214 return "TBM_FORMAT_YUYV";
215 case TBM_FORMAT_YVYU:
216 return "TBM_FORMAT_YVYU";
217 case TBM_FORMAT_UYVY:
218 return "TBM_FORMAT_UYVY";
219 case TBM_FORMAT_VYUY:
220 return "TBM_FORMAT_VYUY";
221 case TBM_FORMAT_AYUV:
222 return "TBM_FORMAT_AYUV";
223 case TBM_FORMAT_NV12:
224 return "TBM_FORMAT_NV12";
225 case TBM_FORMAT_NV21:
226 return "TBM_FORMAT_NV21";
227 case TBM_FORMAT_NV16:
228 return "TBM_FORMAT_NV16";
229 case TBM_FORMAT_NV61:
230 return "TBM_FORMAT_NV61";
231 case TBM_FORMAT_YUV410:
232 return "TBM_FORMAT_YUV410";
233 case TBM_FORMAT_YVU410:
234 return "TBM_FORMAT_YVU410";
235 case TBM_FORMAT_YUV411:
236 return "TBM_FORMAT_YUV411";
237 case TBM_FORMAT_YVU411:
238 return "TBM_FORMAT_YVU411";
239 case TBM_FORMAT_YUV420:
240 return "TBM_FORMAT_YUV420";
241 case TBM_FORMAT_YVU420:
242 return "TBM_FORMAT_YVU420";
243 case TBM_FORMAT_YUV422:
244 return "TBM_FORMAT_YUV422";
245 case TBM_FORMAT_YVU422:
246 return "TBM_FORMAT_YVU422";
247 case TBM_FORMAT_YUV444:
248 return "TBM_FORMAT_YUV444";
249 case TBM_FORMAT_YVU444:
250 return "TBM_FORMAT_YVU444";
251 case TBM_FORMAT_NV12MT:
252 return "TBM_FORMAT_NV12MT";
259 _tbm_surface_mutex_lock(void)
261 pthread_mutex_lock(&tbm_surface_lock);
265 _tbm_surface_mutex_unlock(void)
267 pthread_mutex_unlock(&tbm_surface_lock);
271 _init_surface_bufmgr(void)
273 g_surface_bufmgr = tbm_bufmgr_init(-1);
277 _deinit_surface_bufmgr(void)
279 if (!g_surface_bufmgr)
282 tbm_bufmgr_deinit(g_surface_bufmgr);
283 g_surface_bufmgr = NULL;
288 _tbm_surface_internal_magic_check(tbm_surface_h surface)
290 if (surface->magic != TBM_SURFACE_MAGIC)
297 _tbm_surface_internal_is_valid(tbm_surface_h surface)
300 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
301 TBM_ERR("error: No valid tbm_surface is NULL\n");
305 if (!_tbm_surface_internal_magic_check(surface)) {
306 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
307 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
315 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
316 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
318 TBM_RETURN_VAL_IF_FAIL(surface, 0);
319 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
321 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
322 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 if (bufmgr->use_hal_tbm) {
332 error = (tbm_error_e)hal_tbm_bufmgr_get_plane_data(bufmgr->hal_bufmgr, (hal_tbm_format)surf->info.format,
333 plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
334 /* LCOV_EXCL_START */
335 if (error == TBM_ERROR_NOT_SUPPORTED) {
336 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
338 } else if (error != TBM_ERROR_NONE) {
339 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
340 _tbm_set_last_result(error);
345 } else if (bufmgr->backend_module_data) {
346 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
347 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
351 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
352 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
353 if (error != TBM_ERROR_NONE) {
354 /* LCOV_EXCL_START */
355 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
356 _tbm_set_last_result(error);
362 if (!bufmgr->backend->surface_get_plane_data) {
363 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
367 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
368 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
370 /* LCOV_EXCL_START */
371 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
372 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
382 _tbm_surface_internal_destroy(tbm_surface_h surface)
385 tbm_bufmgr bufmgr = surface->bufmgr;
386 tbm_user_data *old_data = NULL, *tmp = NULL;
387 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
388 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
390 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
391 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
392 func_info->destroy_func(surface, func_info->user_data);
394 TBM_DBG("free destroy_funcs %p\n", surface);
395 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
396 LIST_DEL(&func_info->item_link);
401 /* destory the user_data_list */
402 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
403 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
404 TBM_DBG("free user_data\n");
405 user_data_delete(old_data);
409 for (i = 0; i < surface->num_bos; i++) {
410 surface->bos[i]->surface = NULL;
412 tbm_bo_unref(surface->bos[i]);
413 surface->bos[i] = NULL;
416 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
417 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
418 _tbm_surface_internal_debug_data_delete(debug_old_data);
421 LIST_DEL(&surface->item_link);
424 if (surface->hal_surface) {
425 hal_tbm_surface_free(surface->hal_surface);
426 surface->hal_surface = NULL;
432 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
433 LIST_DELINIT(&bufmgr->surf_list);
435 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
436 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
437 _tbm_surface_internal_debug_data_delete(debug_old_data);
441 _deinit_surface_bufmgr();
445 /* LCOV_EXCL_START */
447 _tbm_surface_check_file_is_symbolic_link(const char* path)
454 if (stat(path, &sb) != 0)
457 if (S_ISLNK(sb.st_mode))
465 _tbm_surface_internal_get_num_planes(tbm_format format)
471 case TBM_FORMAT_RGB332:
472 case TBM_FORMAT_BGR233:
473 case TBM_FORMAT_XRGB4444:
474 case TBM_FORMAT_XBGR4444:
475 case TBM_FORMAT_RGBX4444:
476 case TBM_FORMAT_BGRX4444:
477 case TBM_FORMAT_ARGB4444:
478 case TBM_FORMAT_ABGR4444:
479 case TBM_FORMAT_RGBA4444:
480 case TBM_FORMAT_BGRA4444:
481 case TBM_FORMAT_XRGB1555:
482 case TBM_FORMAT_XBGR1555:
483 case TBM_FORMAT_RGBX5551:
484 case TBM_FORMAT_BGRX5551:
485 case TBM_FORMAT_ARGB1555:
486 case TBM_FORMAT_ABGR1555:
487 case TBM_FORMAT_RGBA5551:
488 case TBM_FORMAT_BGRA5551:
489 case TBM_FORMAT_RGB565:
490 case TBM_FORMAT_BGR565:
491 case TBM_FORMAT_RGB888:
492 case TBM_FORMAT_BGR888:
493 case TBM_FORMAT_XRGB8888:
494 case TBM_FORMAT_XBGR8888:
495 case TBM_FORMAT_RGBX8888:
496 case TBM_FORMAT_BGRX8888:
497 case TBM_FORMAT_ARGB8888:
498 case TBM_FORMAT_ABGR8888:
499 case TBM_FORMAT_RGBA8888:
500 case TBM_FORMAT_BGRA8888:
501 case TBM_FORMAT_XRGB2101010:
502 case TBM_FORMAT_XBGR2101010:
503 case TBM_FORMAT_RGBX1010102:
504 case TBM_FORMAT_BGRX1010102:
505 case TBM_FORMAT_ARGB2101010:
506 case TBM_FORMAT_ABGR2101010:
507 case TBM_FORMAT_RGBA1010102:
508 case TBM_FORMAT_BGRA1010102:
509 case TBM_FORMAT_YUYV:
510 case TBM_FORMAT_YVYU:
511 case TBM_FORMAT_UYVY:
512 case TBM_FORMAT_VYUY:
513 case TBM_FORMAT_AYUV:
516 case TBM_FORMAT_NV12:
517 case TBM_FORMAT_NV12MT:
518 case TBM_FORMAT_NV21:
519 case TBM_FORMAT_NV16:
520 case TBM_FORMAT_NV61:
523 case TBM_FORMAT_YUV410:
524 case TBM_FORMAT_YVU410:
525 case TBM_FORMAT_YUV411:
526 case TBM_FORMAT_YVU411:
527 case TBM_FORMAT_YUV420:
528 case TBM_FORMAT_YVU420:
529 case TBM_FORMAT_YUV422:
530 case TBM_FORMAT_YVU422:
531 case TBM_FORMAT_YUV444:
532 case TBM_FORMAT_YVU444:
537 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
545 _tbm_surface_internal_get_bpp(tbm_format format)
552 case TBM_FORMAT_RGB332:
553 case TBM_FORMAT_BGR233:
556 case TBM_FORMAT_XRGB4444:
557 case TBM_FORMAT_XBGR4444:
558 case TBM_FORMAT_RGBX4444:
559 case TBM_FORMAT_BGRX4444:
560 case TBM_FORMAT_ARGB4444:
561 case TBM_FORMAT_ABGR4444:
562 case TBM_FORMAT_RGBA4444:
563 case TBM_FORMAT_BGRA4444:
564 case TBM_FORMAT_XRGB1555:
565 case TBM_FORMAT_XBGR1555:
566 case TBM_FORMAT_RGBX5551:
567 case TBM_FORMAT_BGRX5551:
568 case TBM_FORMAT_ARGB1555:
569 case TBM_FORMAT_ABGR1555:
570 case TBM_FORMAT_RGBA5551:
571 case TBM_FORMAT_BGRA5551:
572 case TBM_FORMAT_RGB565:
573 case TBM_FORMAT_BGR565:
576 case TBM_FORMAT_RGB888:
577 case TBM_FORMAT_BGR888:
580 case TBM_FORMAT_XRGB8888:
581 case TBM_FORMAT_XBGR8888:
582 case TBM_FORMAT_RGBX8888:
583 case TBM_FORMAT_BGRX8888:
584 case TBM_FORMAT_ARGB8888:
585 case TBM_FORMAT_ABGR8888:
586 case TBM_FORMAT_RGBA8888:
587 case TBM_FORMAT_BGRA8888:
588 case TBM_FORMAT_XRGB2101010:
589 case TBM_FORMAT_XBGR2101010:
590 case TBM_FORMAT_RGBX1010102:
591 case TBM_FORMAT_BGRX1010102:
592 case TBM_FORMAT_ARGB2101010:
593 case TBM_FORMAT_ABGR2101010:
594 case TBM_FORMAT_RGBA1010102:
595 case TBM_FORMAT_BGRA1010102:
596 case TBM_FORMAT_YUYV:
597 case TBM_FORMAT_YVYU:
598 case TBM_FORMAT_UYVY:
599 case TBM_FORMAT_VYUY:
600 case TBM_FORMAT_AYUV:
603 case TBM_FORMAT_NV12:
604 case TBM_FORMAT_NV12MT:
605 case TBM_FORMAT_NV21:
608 case TBM_FORMAT_NV16:
609 case TBM_FORMAT_NV61:
612 case TBM_FORMAT_YUV410:
613 case TBM_FORMAT_YVU410:
616 case TBM_FORMAT_YUV411:
617 case TBM_FORMAT_YVU411:
618 case TBM_FORMAT_YUV420:
619 case TBM_FORMAT_YVU420:
622 case TBM_FORMAT_YUV422:
623 case TBM_FORMAT_YVU422:
626 case TBM_FORMAT_YUV444:
627 case TBM_FORMAT_YVU444:
631 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
638 static struct _tbm_surface *
639 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
641 struct _tbm_surface *surf = NULL;
642 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
645 surf = calloc(1, sizeof(struct _tbm_surface));
647 /* LCOV_EXCL_START */
648 TBM_ERR("fail to alloc surf\n");
649 *error = TBM_ERROR_OUT_OF_MEMORY;
650 goto alloc_surf_fail;
654 surf->magic = TBM_SURFACE_MAGIC;
655 surf->bufmgr = bufmgr;
656 surf->info.width = width;
657 surf->info.height = height;
658 surf->info.format = format;
659 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
660 if (!surf->info.bpp) {
661 TBM_ERR("fail to get bpp from format(%d), error(%s)\n", format, tbm_error_str(*error));
662 *error = tbm_get_last_error();
666 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
667 if (!surf->info.num_planes) {
668 TBM_ERR("fail to get num_planes from format(%d), error(%s)\n", format, tbm_error_str(*error));
669 *error = tbm_get_last_error();
670 goto num_planes_fail;
674 /* get size, stride and offset bo_idx */
675 for (i = 0; i < surf->info.num_planes; i++) {
676 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
677 TBM_ERR("fail to query plane data\n");
678 *error = tbm_get_last_error();
679 goto query_plane_data_fail;
682 surf->info.planes[i].size = size;
683 surf->info.planes[i].offset = offset;
684 surf->info.planes[i].stride = stride;
685 surf->planes_bo_idx[i] = bo_idx;
690 for (i = 0; i < surf->info.num_planes; i++) {
691 surf->info.size += surf->info.planes[i].size;
693 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
694 surf->num_bos = surf->planes_bo_idx[i] + 1;
699 for (i = 0; i < surf->num_bos; i++) {
701 for (j = 0; j < surf->info.num_planes; j++) {
702 if (surf->planes_bo_idx[j] == i)
703 bo_size += surf->info.planes[j].size;
706 if (bufmgr->use_hal_tbm) {
707 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
708 if (*error == TBM_ERROR_NOT_SUPPORTED) {
709 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
711 TBM_ERR("fail to alloc bo idx:%d\n", i);
712 *error = tbm_get_last_error();
716 } else if (bufmgr->backend_module_data) {
717 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
718 /* LCOV_EXCL_START */
719 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
721 TBM_ERR("fail to tbm_bo_alloc_with_format idx:%d\n", i);
722 *error = tbm_get_last_error();
726 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
727 /* LCOV_EXCL_START */
728 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, error);
730 TBM_ERR("fail to tbm_bo_alloc_with_tiled_format idx:%d\n", i);
731 *error = tbm_get_last_error();
736 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
738 TBM_ERR("fail to alloc bo idx:%d\n", i);
739 *error = tbm_get_last_error();
744 if (bufmgr->backend->surface_bo_alloc) {
745 /* LCOV_EXCL_START */
746 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
748 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
749 *error = tbm_get_last_error();
754 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
756 TBM_ERR("fail to alloc bo idx:%d\n", i);
757 *error = tbm_get_last_error();
763 _tbm_bo_set_surface(surf->bos[i], surf);
766 *error = TBM_ERROR_NONE;
771 for (j = 0; j < i; j++) {
773 tbm_bo_unref(surf->bos[j]);
775 query_plane_data_fail:
784 static struct _tbm_surface *
785 _tbm_surface_internal_hal_tbm_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
787 struct _tbm_surface *surf = NULL;
788 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
790 hal_tbm_surface *hal_surface = NULL;
791 hal_tbm_bo **hal_bos = NULL;
794 surf = calloc(1, sizeof(struct _tbm_surface));
796 /* LCOV_EXCL_START */
797 TBM_ERR("fail to alloc surf");
798 *error = TBM_ERROR_OUT_OF_MEMORY;
799 goto alloc_surf_fail;
804 surf->magic = TBM_SURFACE_MAGIC;
805 surf->bufmgr = bufmgr;
806 surf->info.width = width;
807 surf->info.height = height;
808 surf->info.format = format;
809 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
810 if (!surf->info.bpp) {
811 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
812 *error = tbm_get_last_error();
817 // get number of planes
818 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
819 if (!surf->info.num_planes) {
820 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
821 *error = tbm_get_last_error();
822 goto num_planes_fail;
825 hal_surface = hal_tbm_bufmgr_alloc_surface(bufmgr->hal_bufmgr, (uint32_t)width, (uint32_t)height, (hal_tbm_format)format, (hal_tbm_bo_memory_type)flags, NULL, 0, (hal_tbm_error *)error);
828 surf->hal_surface = hal_surface;
830 // set infomation of planes
831 for (i = 0; i < surf->info.num_planes; i++) {
832 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
833 if (*error != TBM_ERROR_NONE) {
834 goto query_plane_data_fail;
836 surf->info.planes[i].size = size;
837 surf->info.planes[i].offset = offset;
838 surf->info.planes[i].stride = stride;
839 surf->planes_bo_idx[i] = bo_idx;
842 // set infomation of bos
843 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
845 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
848 surf->num_bos = num_bos;
850 for (i = 0; i < surf->info.num_planes; i++) {
851 surf->info.size += surf->info.planes[i].size;
853 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
854 surf->num_bos = surf->planes_bo_idx[i] + 1;
857 for (i = 0; i < num_bos; i++) {
858 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
860 TBM_ERR("fail to alloc bo idx:%d", i);
861 *error = tbm_get_last_error();
865 _tbm_bo_set_surface(surf->bos[i], surf);
868 // set infomation of planes
869 for (i = 0; i < surf->info.num_planes; i++) {
870 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
871 TBM_ERR("fail to query plane data");
872 *error = tbm_get_last_error();
873 goto query_plane_data_fail;
875 surf->info.planes[i].size = size;
876 surf->info.planes[i].offset = offset;
877 surf->info.planes[i].stride = stride;
878 surf->planes_bo_idx[i] = bo_idx;
881 // count number of bos
883 for (i = 0; i < surf->info.num_planes; i++) {
884 surf->info.size += surf->info.planes[i].size;
886 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
887 surf->num_bos = surf->planes_bo_idx[i] + 1;
890 // set infomation of bos
891 for (i = 0; i < surf->num_bos; i++) {
893 for (j = 0; j < surf->info.num_planes; j++) {
894 if (surf->planes_bo_idx[j] == i)
895 bo_size += surf->info.planes[j].size;
898 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp / 8, flags, error);
899 if (*error == TBM_ERROR_NOT_SUPPORTED) {
900 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
902 TBM_ERR("fail to alloc bo idx:%d", i);
903 *error = tbm_get_last_error();
908 _tbm_bo_set_surface(surf->bos[i], surf);
912 *error = TBM_ERROR_NONE;
918 query_plane_data_fail:
920 hal_tbm_surface_free(hal_surface);
922 for (j = 0; j < i; j++) {
924 tbm_bo_unref(surf->bos[j]);
937 tbm_surface_internal_is_valid(tbm_surface_h surface)
941 _tbm_surface_mutex_lock();
942 _tbm_set_last_result(TBM_ERROR_NONE);
944 /* Return silently if surface is null. */
946 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
947 _tbm_surface_mutex_unlock();
951 ret = _tbm_surface_internal_is_valid(surface);
953 _tbm_surface_mutex_unlock();
959 tbm_surface_internal_query_supported_formats(uint32_t **formats,
962 struct _tbm_bufmgr *bufmgr;
964 bool bufmgr_initialized = false;
967 _tbm_surface_mutex_lock();
968 _tbm_set_last_result(TBM_ERROR_NONE);
970 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
971 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
973 if (!g_surface_bufmgr) {
974 _init_surface_bufmgr();
975 if (!g_surface_bufmgr) {
976 TBM_ERR("fail bufmgr initialization\n");
977 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
980 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
981 bufmgr_initialized = true;
984 bufmgr = g_surface_bufmgr;
986 if (bufmgr->use_hal_tbm) {
987 error = (tbm_error_e)hal_tbm_bufmgr_get_supported_formats(bufmgr->hal_bufmgr, formats, num);
988 /* LCOV_EXCL_START */
989 if (error == TBM_ERROR_NOT_SUPPORTED) {
990 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
992 } else if (error != TBM_ERROR_NONE) {
993 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
998 } else if (bufmgr->backend_module_data) {
999 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
1000 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1004 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
1005 if (error != TBM_ERROR_NONE) {
1006 /* LCOV_EXCL_START */
1007 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
1009 /* LCOV_EXCL_START */
1013 if (!bufmgr->backend->surface_supported_format) {
1014 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1018 ret = bufmgr->backend->surface_supported_format(formats, num);
1020 /* LCOV_EXCL_START */
1021 TBM_ERR("Fail to surface_supported_format.\n");
1022 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1024 /* LCOV_EXCL_START */
1028 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
1030 if (bufmgr_initialized) {
1031 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1032 _deinit_surface_bufmgr();
1035 _tbm_surface_mutex_unlock();
1039 /* LCOV_EXCL_START */
1041 if (bufmgr_initialized) {
1042 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1043 _deinit_surface_bufmgr();
1045 _tbm_surface_mutex_unlock();
1047 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
1050 /* LCOV_EXCL_STOP */
1054 tbm_surface_internal_get_num_planes(tbm_format format)
1058 _tbm_surface_mutex_lock();
1059 _tbm_set_last_result(TBM_ERROR_NONE);
1061 num_planes = _tbm_surface_internal_get_num_planes(format);
1063 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1064 _tbm_surface_mutex_unlock();
1068 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
1070 _tbm_surface_mutex_unlock();
1076 tbm_surface_internal_get_bpp(tbm_format format)
1080 _tbm_surface_mutex_lock();
1081 _tbm_set_last_result(TBM_ERROR_NONE);
1083 bpp = _tbm_surface_internal_get_bpp(format);
1085 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1086 _tbm_surface_mutex_unlock();
1090 _tbm_surface_mutex_unlock();
1092 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
1098 tbm_surface_internal_create_with_flags(int width, int height,
1099 int format, int flags)
1101 struct _tbm_bufmgr *bufmgr;
1102 struct _tbm_surface *surf = NULL;
1103 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
1104 bool bufmgr_initialized = false;
1106 _tbm_surface_mutex_lock();
1107 _tbm_set_last_result(TBM_ERROR_NONE);
1109 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
1110 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
1112 if (!g_surface_bufmgr) {
1113 _init_surface_bufmgr();
1114 if (!g_surface_bufmgr) {
1115 TBM_ERR("fail bufmgr initialization\n");
1116 error = TBM_ERROR_INVALID_OPERATION;
1117 goto check_valid_fail;
1119 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1120 bufmgr_initialized = true;
1123 bufmgr = g_surface_bufmgr;
1124 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1125 TBM_ERR("The bufmgr is invalid\n");
1126 error = TBM_ERROR_INVALID_PARAMETER;
1127 goto check_valid_fail;
1130 if (bufmgr->use_hal_tbm) {
1131 surf = _tbm_surface_internal_hal_tbm_create_surface(bufmgr, width, height, format, flags, &error);
1133 TBM_ERR("_tbm_surface_internal_hal_tbm_create_surface failed.");
1134 goto surface_alloc_fail;
1137 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1139 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1140 goto surface_alloc_fail;
1144 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1145 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1147 LIST_INITHEAD(&surf->user_data_list);
1148 LIST_INITHEAD(&surf->debug_data_list);
1149 LIST_INITHEAD(&surf->destroy_funcs);
1151 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1153 _tbm_set_last_result(error);
1154 _tbm_surface_mutex_unlock();
1158 /* LCOV_EXCL_START */
1162 if (bufmgr_initialized && bufmgr) {
1163 LIST_DELINIT(&bufmgr->surf_list);
1164 _deinit_surface_bufmgr();
1167 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1168 width, height, _tbm_surface_internal_format_to_str(format), flags);
1170 _tbm_set_last_result(error);
1171 _tbm_surface_mutex_unlock();
1173 /* LCOV_EXCL_STOP */
1179 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1180 tbm_bo *bos, int num)
1182 struct _tbm_bufmgr *bufmgr;
1183 struct _tbm_surface *surf = NULL;
1185 bool bufmgr_initialized = false;
1187 _tbm_surface_mutex_lock();
1188 _tbm_set_last_result(TBM_ERROR_NONE);
1190 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1191 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1192 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1193 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1194 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1196 if (!g_surface_bufmgr) {
1197 _init_surface_bufmgr();
1198 if (!g_surface_bufmgr) {
1199 TBM_ERR("fail bufmgr initialization\n");
1200 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1201 goto check_valid_fail;
1203 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1204 bufmgr_initialized = true;
1207 bufmgr = g_surface_bufmgr;
1208 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1209 TBM_ERR("fail to validate the Bufmgr.\n");
1210 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1211 goto check_valid_fail;
1214 surf = calloc(1, sizeof(struct _tbm_surface));
1216 /* LCOV_EXCL_START */
1217 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1218 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1219 goto alloc_surf_fail;
1220 /* LCOV_EXCL_STOP */
1223 surf->magic = TBM_SURFACE_MAGIC;
1224 surf->bufmgr = bufmgr;
1225 surf->info.width = info->width;
1226 surf->info.height = info->height;
1227 surf->info.format = info->format;
1229 surf->info.bpp = info->bpp;
1231 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1232 if (!surf->info.bpp) {
1233 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1237 surf->info.num_planes = info->num_planes;
1240 /* get size, stride and offset */
1241 for (i = 0; i < info->num_planes; i++) {
1242 surf->info.planes[i].offset = info->planes[i].offset;
1243 surf->info.planes[i].stride = info->planes[i].stride;
1245 if (info->planes[i].size > 0)
1246 surf->info.planes[i].size = info->planes[i].size;
1248 uint32_t size = 0, offset = 0, stride = 0;
1251 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1252 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1253 goto plane_data_fail;
1255 surf->info.planes[i].size = size;
1259 surf->planes_bo_idx[i] = 0;
1261 surf->planes_bo_idx[i] = i;
1264 if (info->size > 0) {
1265 surf->info.size = info->size;
1267 surf->info.size = 0;
1268 for (i = 0; i < info->num_planes; i++)
1269 surf->info.size += surf->info.planes[i].size;
1272 surf->flags = TBM_BO_DEFAULT;
1274 /* create only one bo */
1275 surf->num_bos = num;
1276 for (i = 0; i < num; i++) {
1277 if (bos[i] == NULL) {
1278 TBM_ERR("bos[%d] is null.\n", i);
1279 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1283 surf->bos[i] = tbm_bo_ref(bos[i]);
1284 _tbm_bo_set_surface(bos[i], surf);
1287 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1288 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1290 LIST_INITHEAD(&surf->user_data_list);
1291 LIST_INITHEAD(&surf->debug_data_list);
1292 LIST_INITHEAD(&surf->destroy_funcs);
1294 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1296 _tbm_surface_mutex_unlock();
1300 /* LCOV_EXCL_START */
1304 for (i = 0; i < num; i++) {
1306 tbm_bo_unref(surf->bos[i]);
1311 if (bufmgr_initialized && bufmgr) {
1312 LIST_DELINIT(&bufmgr->surf_list);
1313 _deinit_surface_bufmgr();
1315 _tbm_surface_mutex_unlock();
1317 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1318 info->width, info->height,
1319 _tbm_surface_internal_format_to_str(info->format), num);
1320 /* LCOV_EXCL_STOP */
1326 tbm_surface_internal_destroy(tbm_surface_h surface)
1328 _tbm_surface_mutex_lock();
1329 _tbm_set_last_result(TBM_ERROR_NONE);
1331 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1335 if (surface->refcnt > 0) {
1336 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1337 _tbm_surface_mutex_unlock();
1341 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1343 if (surface->refcnt == 0)
1344 _tbm_surface_internal_destroy(surface);
1345 else // if (surface->refcnt < 0)
1346 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1348 _tbm_surface_mutex_unlock();
1352 tbm_surface_internal_ref(tbm_surface_h surface)
1354 _tbm_surface_mutex_lock();
1355 _tbm_set_last_result(TBM_ERROR_NONE);
1357 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1361 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1363 _tbm_surface_mutex_unlock();
1367 tbm_surface_internal_unref(tbm_surface_h surface)
1369 _tbm_surface_mutex_lock();
1370 _tbm_set_last_result(TBM_ERROR_NONE);
1372 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1376 if (surface->refcnt > 0) {
1377 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1378 _tbm_surface_mutex_unlock();
1382 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1384 if (surface->refcnt == 0)
1385 _tbm_surface_internal_destroy(surface);
1387 _tbm_surface_mutex_unlock();
1391 tbm_surface_internal_get_num_bos(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 num = surf->num_bos;
1405 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1407 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1409 _tbm_surface_mutex_unlock();
1415 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1417 struct _tbm_surface *surf;
1420 _tbm_surface_mutex_lock();
1421 _tbm_set_last_result(TBM_ERROR_NONE);
1423 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1424 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1426 surf = (struct _tbm_surface *)surface;
1427 bo = surf->bos[bo_idx];
1429 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1431 _tbm_surface_mutex_unlock();
1437 tbm_surface_internal_get_size(tbm_surface_h surface)
1439 struct _tbm_surface *surf;
1442 _tbm_surface_mutex_lock();
1443 _tbm_set_last_result(TBM_ERROR_NONE);
1445 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1447 surf = (struct _tbm_surface *)surface;
1448 size = surf->info.size;
1450 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1452 _tbm_surface_mutex_unlock();
1458 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1459 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1461 struct _tbm_surface *surf;
1463 _tbm_surface_mutex_lock();
1464 _tbm_set_last_result(TBM_ERROR_NONE);
1466 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1467 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1469 surf = (struct _tbm_surface *)surface;
1471 if (plane_idx >= surf->info.num_planes) {
1472 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1473 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1474 _tbm_surface_mutex_unlock();
1479 *size = surf->info.planes[plane_idx].size;
1482 *offset = surf->info.planes[plane_idx].offset;
1485 *pitch = surf->info.planes[plane_idx].stride;
1487 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1488 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1489 surf->info.planes[plane_idx].stride);
1491 _tbm_surface_mutex_unlock();
1497 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1498 tbm_surface_info_s *info, int map)
1500 struct _tbm_surface *surf;
1501 tbm_bo_handle bo_handles[4];
1504 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1507 _tbm_surface_mutex_lock();
1508 _tbm_set_last_result(TBM_ERROR_NONE);
1510 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1512 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1514 surf = (struct _tbm_surface *)surface;
1516 memset(info, 0x00, sizeof(tbm_surface_info_s));
1517 info->width = surf->info.width;
1518 info->height = surf->info.height;
1519 info->format = surf->info.format;
1520 info->bpp = surf->info.bpp;
1521 info->size = surf->info.size;
1522 info->num_planes = surf->info.num_planes;
1524 for (i = 0; i < surf->info.num_planes; i++) {
1525 info->planes[i].size = surf->info.planes[i].size;
1526 info->planes[i].offset = surf->info.planes[i].offset;
1527 info->planes[i].stride = surf->info.planes[i].stride;
1528 planes_bo_idx[i] = surf->planes_bo_idx[i];
1531 for (i = 0; i < surf->num_bos; i++)
1532 bos[i] = surf->bos[i];
1534 num_bos = surf->num_bos;
1537 _tbm_surface_mutex_unlock();
1538 for (i = 0; i < num_bos; i++) {
1539 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1540 if (bo_handles[i].ptr == NULL) {
1541 for (j = 0; j < i; j++)
1542 tbm_bo_unmap(bos[j]);
1544 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1548 _tbm_surface_mutex_lock();
1550 for (i = 0; i < num_bos; i++) {
1551 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1552 if (bo_handles[i].ptr == NULL) {
1553 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1554 _tbm_surface_mutex_unlock();
1560 for (i = 0; i < info->num_planes; i++) {
1561 if (bo_handles[planes_bo_idx[i]].ptr)
1562 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1565 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1567 _tbm_surface_mutex_unlock();
1573 tbm_surface_internal_unmap(tbm_surface_h surface)
1575 struct _tbm_surface *surf;
1578 _tbm_surface_mutex_lock();
1579 _tbm_set_last_result(TBM_ERROR_NONE);
1581 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1583 surf = (struct _tbm_surface *)surface;
1585 for (i = 0; i < surf->num_bos; i++)
1586 tbm_bo_unmap(surf->bos[i]);
1588 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1590 _tbm_surface_mutex_unlock();
1594 tbm_surface_internal_get_width(tbm_surface_h surface)
1596 struct _tbm_surface *surf;
1599 _tbm_surface_mutex_lock();
1600 _tbm_set_last_result(TBM_ERROR_NONE);
1602 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1604 surf = (struct _tbm_surface *)surface;
1605 width = surf->info.width;
1607 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1609 _tbm_surface_mutex_unlock();
1615 tbm_surface_internal_get_height(tbm_surface_h surface)
1617 struct _tbm_surface *surf;
1618 unsigned int height;
1620 _tbm_surface_mutex_lock();
1621 _tbm_set_last_result(TBM_ERROR_NONE);
1623 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1625 surf = (struct _tbm_surface *)surface;
1626 height = surf->info.height;
1628 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1630 _tbm_surface_mutex_unlock();
1637 tbm_surface_internal_get_format(tbm_surface_h surface)
1639 struct _tbm_surface *surf;
1642 _tbm_surface_mutex_lock();
1643 _tbm_set_last_result(TBM_ERROR_NONE);
1645 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1647 surf = (struct _tbm_surface *)surface;
1648 format = surf->info.format;
1650 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1652 _tbm_surface_mutex_unlock();
1658 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1660 struct _tbm_surface *surf;
1663 _tbm_surface_mutex_lock();
1664 _tbm_set_last_result(TBM_ERROR_NONE);
1666 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1667 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1669 surf = (struct _tbm_surface *)surface;
1670 bo_idx = surf->planes_bo_idx[plane_idx];
1672 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1674 _tbm_surface_mutex_unlock();
1680 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1681 tbm_data_free data_free_func)
1683 tbm_user_data *data;
1685 _tbm_surface_mutex_lock();
1686 _tbm_set_last_result(TBM_ERROR_NONE);
1688 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1690 /* check if the data according to the key exist if so, return false. */
1691 data = user_data_lookup(&surface->user_data_list, key);
1693 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1694 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1695 _tbm_surface_mutex_unlock();
1699 data = user_data_create(key, data_free_func);
1701 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1702 _tbm_surface_mutex_unlock();
1706 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1708 LIST_ADD(&data->item_link, &surface->user_data_list);
1710 _tbm_surface_mutex_unlock();
1716 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1719 tbm_user_data *old_data;
1721 _tbm_surface_mutex_lock();
1722 _tbm_set_last_result(TBM_ERROR_NONE);
1724 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1726 old_data = user_data_lookup(&surface->user_data_list, key);
1728 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1729 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1730 _tbm_surface_mutex_unlock();
1734 if (old_data->data && old_data->free_func)
1735 old_data->free_func(old_data->data);
1737 old_data->data = data;
1739 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1741 _tbm_surface_mutex_unlock();
1747 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1750 tbm_user_data *old_data;
1752 _tbm_surface_mutex_lock();
1753 _tbm_set_last_result(TBM_ERROR_NONE);
1755 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1758 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1759 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1760 _tbm_surface_mutex_unlock();
1765 old_data = user_data_lookup(&surface->user_data_list, key);
1767 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1768 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1769 _tbm_surface_mutex_unlock();
1773 *data = old_data->data;
1775 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1777 _tbm_surface_mutex_unlock();
1783 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1786 tbm_user_data *old_data = (void *)0;
1788 _tbm_surface_mutex_lock();
1789 _tbm_set_last_result(TBM_ERROR_NONE);
1791 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1793 old_data = user_data_lookup(&surface->user_data_list, key);
1795 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1796 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1797 _tbm_surface_mutex_unlock();
1801 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1803 user_data_delete(old_data);
1805 _tbm_surface_mutex_unlock();
1810 /* LCOV_EXCL_START */
1812 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1814 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1816 return surface->debug_pid;
1820 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1822 _tbm_surface_mutex_lock();
1823 _tbm_set_last_result(TBM_ERROR_NONE);
1825 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1827 surface->debug_pid = pid;
1829 _tbm_surface_mutex_unlock();
1832 static tbm_surface_debug_data *
1833 _tbm_surface_internal_debug_data_create(char *key, char *value)
1835 tbm_surface_debug_data *debug_data = NULL;
1837 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1839 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1840 TBM_ERR("fail to allocate the debug_data.");
1844 if (key) debug_data->key = strdup(key);
1845 if (value) debug_data->value = strdup(value);
1851 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1853 if (!debug_data->value && !value)
1856 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1859 if (debug_data->value)
1860 free(debug_data->value);
1863 debug_data->value = strdup(value);
1865 debug_data->value = NULL;
1868 static tbm_surface_debug_data *
1869 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1871 tbm_surface_debug_data *debug_data = NULL;
1873 if (LIST_IS_EMPTY(list))
1876 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1877 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1885 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1887 tbm_surface_debug_data *debug_data = NULL;
1888 tbm_bufmgr bufmgr = NULL;
1890 _tbm_surface_mutex_lock();
1891 _tbm_set_last_result(TBM_ERROR_NONE);
1893 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1894 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1896 bufmgr = surface->bufmgr;
1898 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1900 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1902 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1904 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1906 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1907 _tbm_surface_mutex_unlock();
1911 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1914 /* add new debug key to list */
1915 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1917 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1919 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1922 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1924 _tbm_surface_mutex_unlock();
1930 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1932 tbm_surface_debug_data *old_data = NULL;
1934 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1936 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1937 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1938 if (!strcmp(old_data->key, key))
1939 return old_data->value;
1946 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1947 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1949 struct _tbm_surface_dump_buf_info {
1959 tbm_surface_info_s info;
1961 struct list_head link;
1964 struct _tbm_surface_dump_info {
1965 char *path; // copy???
1968 struct list_head *link;
1969 struct list_head surface_list; /* link of surface */
1972 static tbm_surface_dump_info *g_dump_info = NULL;
1973 static const char *dump_postfix[2] = {"png", "yuv"};
1974 static double scale_factor;
1977 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1978 void *data2, int size2, void *data3, int size3)
1981 unsigned int *blocks;
1983 if (_tbm_surface_check_file_is_symbolic_link(file))
1984 TBM_ERR("%s is symbolic link\n", file);
1986 fp = fopen(file, "w+");
1987 TBM_RETURN_IF_FAIL(fp != NULL);
1989 blocks = (unsigned int *)data1;
1990 fwrite(blocks, 1, size1, fp);
1993 blocks = (unsigned int *)data2;
1994 fwrite(blocks, 1, size2, fp);
1998 blocks = (unsigned int *)data3;
1999 fwrite(blocks, 1, size3, fp);
2006 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
2008 unsigned int *blocks = (unsigned int *)data;
2011 png_bytep *row_pointers;
2014 if (_tbm_surface_check_file_is_symbolic_link(file))
2015 TBM_ERR("%s is symbolic link\n", file);
2017 fp = fopen(file, "wb");
2018 TBM_RETURN_IF_FAIL(fp != NULL);
2020 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
2023 TBM_ERR("fail to create a png write structure.\n");
2028 png_infop pPngInfo = png_create_info_struct(pPngStruct);
2030 TBM_ERR("fail to create a png info structure.\n");
2031 png_destroy_write_struct(&pPngStruct, NULL);
2036 if (setjmp(png_jmpbuf(pPngStruct))) {
2037 /* if png has problem of writing the file, we get here */
2038 TBM_ERR("fail to write png file.\n");
2039 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2044 png_init_io(pPngStruct, fp);
2045 if (format == TBM_FORMAT_XRGB8888) {
2047 png_set_IHDR(pPngStruct,
2054 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2057 png_set_IHDR(pPngStruct,
2062 PNG_COLOR_TYPE_RGBA,
2064 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2067 png_set_bgr(pPngStruct);
2068 png_write_info(pPngStruct, pPngInfo);
2070 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
2071 if (!row_pointers) {
2072 TBM_ERR("fail to allocate the png row_pointers.\n");
2073 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2078 for (y = 0; y < height; ++y) {
2082 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
2084 TBM_ERR("fail to allocate the png row.\n");
2085 for (x = 0; x < y; x++)
2086 png_free(pPngStruct, row_pointers[x]);
2087 png_free(pPngStruct, row_pointers);
2088 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2092 row_pointers[y] = (png_bytep)row;
2094 for (x = 0; x < width; ++x) {
2095 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
2097 if (pixel_size == 3) { // XRGB8888
2098 row[x * pixel_size] = (curBlock & 0xFF);
2099 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2100 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2101 } else { // ARGB8888
2102 row[x * pixel_size] = (curBlock & 0xFF);
2103 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2104 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2105 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2110 png_write_image(pPngStruct, row_pointers);
2111 png_write_end(pPngStruct, pPngInfo);
2113 for (y = 0; y < height; y++)
2114 png_free(pPngStruct, row_pointers[y]);
2115 png_free(pPngStruct, row_pointers);
2117 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2123 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2125 TBM_RETURN_IF_FAIL(path != NULL);
2126 TBM_RETURN_IF_FAIL(w > 0);
2127 TBM_RETURN_IF_FAIL(h > 0);
2128 TBM_RETURN_IF_FAIL(count > 0);
2130 tbm_surface_dump_buf_info *buf_info = NULL;
2131 tbm_surface_h tbm_surface;
2132 tbm_surface_info_s info;
2137 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2141 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2142 TBM_RETURN_IF_FAIL(g_dump_info);
2144 LIST_INITHEAD(&g_dump_info->surface_list);
2145 g_dump_info->count = 0;
2146 g_dump_info->dump_max = count;
2148 /* get buffer size */
2149 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2150 if (tbm_surface == NULL) {
2151 TBM_ERR("tbm_surface_create fail\n");
2157 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2158 TBM_ERR("tbm_surface_get_info fail\n");
2159 tbm_surface_destroy(tbm_surface);
2164 buffer_size = info.size;
2165 tbm_surface_destroy(tbm_surface);
2167 /* create dump lists */
2168 for (i = 0; i < count; i++) {
2171 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2172 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2174 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2176 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2181 buf_info->index = i;
2183 buf_info->size = buffer_size;
2185 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2188 g_dump_info->path = path;
2189 g_dump_info->link = &g_dump_info->surface_list;
2193 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2198 /* free resources */
2199 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2200 tbm_surface_dump_buf_info *tmp;
2202 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2203 tbm_bo_unref(buf_info->bo);
2204 LIST_DEL(&buf_info->link);
2209 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2218 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2225 tbm_surface_internal_dump_start(path, w, h, count);
2226 scale_factor = scale;
2230 tbm_surface_internal_dump_end(void)
2232 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2233 tbm_bo_handle bo_handle;
2238 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2245 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2248 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2249 if (bo_handle.ptr == NULL) {
2250 tbm_bo_unref(buf_info->bo);
2251 LIST_DEL(&buf_info->link);
2256 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2257 TBM_INFO("Dump File.. %s generated.\n", file);
2259 if (buf_info->dirty) {
2260 void *ptr1 = NULL, *ptr2 = NULL;
2262 switch (buf_info->info.format) {
2263 case TBM_FORMAT_ARGB8888:
2264 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2265 buf_info->info.planes[0].stride >> 2,
2266 buf_info->info.height,
2267 buf_info->info.planes[0].stride,
2268 TBM_FORMAT_ARGB8888);
2270 case TBM_FORMAT_XRGB8888:
2271 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2272 buf_info->info.planes[0].stride >> 2,
2273 buf_info->info.height,
2274 buf_info->info.planes[0].stride,
2275 TBM_FORMAT_XRGB8888);
2277 case TBM_FORMAT_YVU420:
2278 case TBM_FORMAT_YUV420:
2279 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2280 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2281 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2282 buf_info->info.planes[0].stride * buf_info->info.height,
2284 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2286 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2288 case TBM_FORMAT_NV12:
2289 case TBM_FORMAT_NV21:
2290 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2291 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2292 buf_info->info.planes[0].stride * buf_info->info.height,
2294 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2297 case TBM_FORMAT_YUYV:
2298 case TBM_FORMAT_UYVY:
2299 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2300 buf_info->info.planes[0].stride * buf_info->info.height,
2304 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2307 } else if (buf_info->dirty_shm)
2308 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2309 buf_info->shm_stride >> 2,
2311 buf_info->shm_stride, 0);
2313 tbm_bo_unmap(buf_info->bo);
2314 tbm_bo_unref(buf_info->bo);
2315 LIST_DEL(&buf_info->link);
2322 TBM_INFO("Dump End..\n");
2325 static pixman_format_code_t
2326 _tbm_surface_internal_pixman_format_get(tbm_format format)
2329 case TBM_FORMAT_ARGB8888:
2330 return PIXMAN_a8r8g8b8;
2331 case TBM_FORMAT_XRGB8888:
2332 return PIXMAN_x8r8g8b8;
2341 * This function supports only if a buffer has below formats.
2342 * - TBM_FORMAT_ARGB8888
2343 * - TBM_FORMAT_XRGB8888
2345 static tbm_surface_error_e
2346 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2347 int format, int src_stride, int src_w, int src_h,
2348 int dst_stride, int dst_w, int dst_h)
2350 pixman_image_t *src_img = NULL, *dst_img = NULL;
2351 pixman_format_code_t pixman_format;
2352 pixman_transform_t t;
2353 struct pixman_f_transform ft;
2354 double scale_x, scale_y;
2356 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2357 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2359 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2360 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2363 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2364 (uint32_t*)src_ptr, src_stride);
2365 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2368 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2369 (uint32_t*)dst_ptr, dst_stride);
2370 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2372 pixman_f_transform_init_identity(&ft);
2374 scale_x = (double)src_w / dst_w;
2375 scale_y = (double)src_h / dst_h;
2377 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2378 pixman_f_transform_translate(&ft, NULL, 0, 0);
2379 pixman_transform_from_pixman_f_transform(&t, &ft);
2380 pixman_image_set_transform(src_img, &t);
2382 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2383 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2385 pixman_image_unref(src_img);
2386 pixman_image_unref(dst_img);
2388 return TBM_SURFACE_ERROR_NONE;
2392 pixman_image_unref(src_img);
2394 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2397 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2398 #define KEY_LEN 5 // "_XXXX"
2399 #define KEYS_LEN KEY_LEN * MAX_BOS
2401 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2403 char *keys, temp_key[KEY_LEN + 1];
2404 struct _tbm_surface *surf;
2408 _tbm_surface_mutex_lock();
2410 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2412 surf = (struct _tbm_surface *)surface;
2414 num_bos = surf->num_bos;
2415 if (num_bos > MAX_BOS)
2418 keys = calloc(KEYS_LEN + 1, sizeof(char));
2420 TBM_ERR("Failed to alloc memory");
2421 _tbm_surface_mutex_unlock();
2425 for (i = 0; i < num_bos; i++) {
2426 memset(temp_key, 0x00, KEY_LEN + 1);
2428 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2429 strncat(keys, temp_key, KEY_LEN + 1);
2432 _tbm_surface_mutex_unlock();
2437 static void _tbm_surface_internal_put_keys(char *keys)
2444 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2446 TBM_RETURN_IF_FAIL(surface != NULL);
2447 TBM_RETURN_IF_FAIL(type != NULL);
2449 tbm_surface_dump_buf_info *buf_info;
2450 struct list_head *next_link;
2451 tbm_surface_info_s info;
2452 tbm_bo_handle bo_handle;
2453 const char *postfix;
2454 const char *format = NULL;
2461 next_link = g_dump_info->link->next;
2462 TBM_RETURN_IF_FAIL(next_link != NULL);
2464 if (next_link == &g_dump_info->surface_list) {
2465 next_link = next_link->next;
2466 TBM_RETURN_IF_FAIL(next_link != NULL);
2469 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2470 TBM_RETURN_IF_FAIL(buf_info != NULL);
2472 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2473 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2475 if (scale_factor > 0.0) {
2478 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2479 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2480 _tbm_surface_internal_format_to_str(info.format));
2481 tbm_surface_unmap(surface);
2485 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2487 buf_info->info.width = info.width * scale_factor;
2488 buf_info->info.height = info.height * scale_factor;
2489 buf_info->info.format = info.format;
2490 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2491 if (!buf_info->info.bpp) {
2492 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2493 tbm_surface_unmap(surface);
2496 buf_info->info.num_planes = 1;
2497 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2498 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2500 if (buf_info->info.size > buf_info->size) {
2501 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2502 buf_info->info.size, buf_info->size);
2503 tbm_surface_unmap(surface);
2507 if (info.size > buf_info->size) {
2508 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2509 info.size, buf_info->size);
2510 tbm_surface_unmap(surface);
2514 /* make the file information */
2515 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2518 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2519 postfix = dump_postfix[0];
2520 format = _tbm_surface_internal_format_to_str(info.format);
2522 postfix = dump_postfix[1];
2524 keys = _tbm_surface_internal_get_keys(surface);
2526 TBM_ERR("fail to get keys");
2527 tbm_surface_unmap(surface);
2532 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2533 if (!bo_handle.ptr) {
2534 TBM_ERR("fail to map bo");
2535 _tbm_surface_internal_put_keys(keys);
2536 tbm_surface_unmap(surface);
2539 memset(bo_handle.ptr, 0x00, buf_info->size);
2541 switch (info.format) {
2542 case TBM_FORMAT_ARGB8888:
2543 case TBM_FORMAT_XRGB8888:
2544 snprintf(buf_info->name, sizeof(buf_info->name),
2545 "%10.3f_%03d%s_%p_%s-%s.%s",
2546 _tbm_surface_internal_get_time(),
2547 g_dump_info->count++, keys, surface, format, type, postfix);
2549 if (scale_factor > 0.0) {
2550 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2552 buf_info->info.format,
2553 info.planes[0].stride,
2554 info.width, info.height,
2555 buf_info->info.planes[0].stride,
2556 buf_info->info.width,
2557 buf_info->info.height);
2558 if (ret != TBM_SURFACE_ERROR_NONE) {
2559 TBM_ERR("fail to scale buffer");
2560 tbm_bo_unmap(buf_info->bo);
2561 _tbm_surface_internal_put_keys(keys);
2562 tbm_surface_unmap(surface);
2566 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2568 case TBM_FORMAT_YVU420:
2569 case TBM_FORMAT_YUV420:
2570 snprintf(buf_info->name, sizeof(buf_info->name),
2571 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2572 _tbm_surface_internal_get_time(),
2573 g_dump_info->count++, keys, type, info.planes[0].stride,
2574 info.height, FOURCC_STR(info.format), postfix);
2575 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2576 bo_handle.ptr += info.planes[0].stride * info.height;
2577 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2578 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2579 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2581 case TBM_FORMAT_NV12:
2582 case TBM_FORMAT_NV21:
2583 snprintf(buf_info->name, sizeof(buf_info->name),
2584 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2585 _tbm_surface_internal_get_time(),
2586 g_dump_info->count++, keys, type, info.planes[0].stride,
2587 info.height, FOURCC_STR(info.format), postfix);
2588 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2589 bo_handle.ptr += info.planes[0].stride * info.height;
2590 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2592 case TBM_FORMAT_YUYV:
2593 case TBM_FORMAT_UYVY:
2594 snprintf(buf_info->name, sizeof(buf_info->name),
2595 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2596 _tbm_surface_internal_get_time(),
2597 g_dump_info->count++, keys, type, info.planes[0].stride,
2598 info.height, FOURCC_STR(info.format), postfix);
2599 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2602 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2603 tbm_bo_unmap(buf_info->bo);
2604 _tbm_surface_internal_put_keys(keys);
2605 tbm_surface_unmap(surface);
2609 tbm_bo_unmap(buf_info->bo);
2611 _tbm_surface_internal_put_keys(keys);
2613 tbm_surface_unmap(surface);
2615 buf_info->dirty = 1;
2616 buf_info->dirty_shm = 0;
2618 if (g_dump_info->count == 1000)
2619 g_dump_info->count = 0;
2621 g_dump_info->link = next_link;
2623 TBM_INFO("Dump %s \n", buf_info->name);
2626 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2629 TBM_RETURN_IF_FAIL(ptr != NULL);
2630 TBM_RETURN_IF_FAIL(w > 0);
2631 TBM_RETURN_IF_FAIL(h > 0);
2632 TBM_RETURN_IF_FAIL(stride > 0);
2633 TBM_RETURN_IF_FAIL(type != NULL);
2635 tbm_surface_dump_buf_info *buf_info;
2636 struct list_head *next_link;
2637 tbm_bo_handle bo_handle;
2638 int ret, size, dw = 0, dh = 0, dstride = 0;
2643 next_link = g_dump_info->link->next;
2644 TBM_RETURN_IF_FAIL(next_link != NULL);
2646 if (next_link == &g_dump_info->surface_list) {
2647 next_link = next_link->next;
2648 TBM_RETURN_IF_FAIL(next_link != NULL);
2651 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2652 TBM_RETURN_IF_FAIL(buf_info != NULL);
2654 if (scale_factor > 0.0) {
2657 dw = w * scale_factor;
2658 dh = h * scale_factor;
2660 size = dstride * dh;
2664 if (size > buf_info->size) {
2665 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2666 size, buf_info->size);
2671 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2672 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2674 memset(bo_handle.ptr, 0x00, buf_info->size);
2675 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2677 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2678 _tbm_surface_internal_get_time(),
2679 g_dump_info->count++, type, dump_postfix[0]);
2680 if (scale_factor > 0.0) {
2681 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2682 TBM_FORMAT_ARGB8888, stride,
2683 w, h, dstride, dw, dh);
2684 if (ret != TBM_SURFACE_ERROR_NONE) {
2685 TBM_ERR("fail to scale buffer");
2686 tbm_bo_unmap(buf_info->bo);
2689 buf_info->shm_stride = dstride;
2690 buf_info->shm_h = dh;
2692 memcpy(bo_handle.ptr, ptr, size);
2693 buf_info->shm_stride = stride;
2694 buf_info->shm_h = h;
2697 tbm_bo_unmap(buf_info->bo);
2699 buf_info->dirty = 0;
2700 buf_info->dirty_shm = 1;
2702 if (g_dump_info->count == 1000)
2703 g_dump_info->count = 0;
2705 g_dump_info->link = next_link;
2707 TBM_INFO("Dump %s \n", buf_info->name);
2711 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2713 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2714 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2715 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2717 tbm_surface_info_s info;
2718 const char *postfix;
2722 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2723 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2725 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2726 postfix = dump_postfix[0];
2728 postfix = dump_postfix[1];
2730 if (strcmp(postfix, type)) {
2731 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2732 tbm_surface_unmap(surface);
2736 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2738 if (!access(file, 0)) {
2739 TBM_ERR("can't capture buffer, exist file %s", file);
2740 tbm_surface_unmap(surface);
2744 switch (info.format) {
2745 case TBM_FORMAT_ARGB8888:
2746 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2749 info.planes[0].stride,
2750 TBM_FORMAT_ARGB8888);
2752 case TBM_FORMAT_XRGB8888:
2753 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2756 info.planes[0].stride,
2757 TBM_FORMAT_XRGB8888);
2759 case TBM_FORMAT_YVU420:
2760 case TBM_FORMAT_YUV420:
2761 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2762 info.planes[0].stride * info.height,
2764 info.planes[1].stride * (info.height >> 1),
2766 info.planes[2].stride * (info.height >> 1));
2768 case TBM_FORMAT_NV12:
2769 case TBM_FORMAT_NV21:
2770 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2771 info.planes[0].stride * info.height,
2773 info.planes[1].stride * (info.height >> 1),
2776 case TBM_FORMAT_YUYV:
2777 case TBM_FORMAT_UYVY:
2778 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2779 info.planes[0].stride * info.height,
2783 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2784 tbm_surface_unmap(surface);
2788 tbm_surface_unmap(surface);
2790 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2796 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2797 const char *path, const char *name, const char *type)
2799 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2800 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2801 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2802 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2803 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2804 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2808 if (strcmp(dump_postfix[0], type)) {
2809 TBM_ERR("Not supported type:%s'", type);
2813 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2815 if (!access(file, 0)) {
2816 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2820 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2822 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2828 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2830 struct _tbm_surface *surf;
2832 _tbm_surface_mutex_lock();
2833 _tbm_set_last_result(TBM_ERROR_NONE);
2835 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2836 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2837 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2839 surf = (struct _tbm_surface *)surface;
2843 surf->damage.width = width;
2844 surf->damage.height = height;
2846 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2847 surface, x, y, width, height);
2849 _tbm_surface_mutex_unlock();
2855 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2857 struct _tbm_surface *surf;
2859 _tbm_surface_mutex_lock();
2860 _tbm_set_last_result(TBM_ERROR_NONE);
2862 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2864 surf = (struct _tbm_surface *)surface;
2866 if (x) *x = surf->damage.x;
2867 if (y) *y = surf->damage.y;
2868 if (width) *width = surf->damage.width;
2869 if (height) *height = surf->damage.height;
2871 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2872 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2874 _tbm_surface_mutex_unlock();
2880 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2882 struct _tbm_surface *surf;
2883 tbm_surface_destroy_func_info *func_info = NULL;
2885 _tbm_surface_mutex_lock();
2886 _tbm_set_last_result(TBM_ERROR_NONE);
2888 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2889 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2891 surf = (struct _tbm_surface *)surface;
2892 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2893 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2894 TBM_ERR("can't add twice");
2895 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2896 _tbm_surface_mutex_unlock();
2901 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2902 if (func_info == NULL) {
2903 TBM_ERR("alloc failed");
2904 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2905 _tbm_surface_mutex_unlock();
2909 func_info->destroy_func = func;
2910 func_info->user_data = user_data;
2912 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2914 _tbm_surface_mutex_unlock();
2920 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2922 struct _tbm_surface *surf;
2923 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2925 _tbm_surface_mutex_lock();
2926 _tbm_set_last_result(TBM_ERROR_NONE);
2928 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2929 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2931 surf = (struct _tbm_surface *)surface;
2932 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2933 if (func_info->destroy_func != func || func_info->user_data != user_data)
2936 LIST_DEL(&func_info->item_link);
2939 _tbm_surface_mutex_unlock();
2944 _tbm_surface_mutex_unlock();
2947 tbm_surface_buffer_data *
2948 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2955 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)