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 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
708 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
710 TBM_ERR("fail to alloc bo idx:%d\n", i);
711 *error = tbm_get_last_error();
716 _tbm_bo_set_surface(surf->bos[i], surf);
719 *error = TBM_ERROR_NONE;
724 for (j = 0; j < i; j++) {
726 tbm_bo_unref(surf->bos[j]);
728 query_plane_data_fail:
737 static struct _tbm_surface *
738 _tbm_surface_internal_hal_tbm_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
740 struct _tbm_surface *surf = NULL;
741 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
743 hal_tbm_surface *hal_surface = NULL;
744 hal_tbm_bo **hal_bos = NULL;
747 surf = calloc(1, sizeof(struct _tbm_surface));
749 /* LCOV_EXCL_START */
750 TBM_ERR("fail to alloc surf");
751 *error = TBM_ERROR_OUT_OF_MEMORY;
752 goto alloc_surf_fail;
757 surf->magic = TBM_SURFACE_MAGIC;
758 surf->bufmgr = bufmgr;
759 surf->info.width = width;
760 surf->info.height = height;
761 surf->info.format = format;
762 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
763 if (!surf->info.bpp) {
764 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
765 *error = tbm_get_last_error();
770 // get number of planes
771 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
772 if (!surf->info.num_planes) {
773 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
774 *error = tbm_get_last_error();
775 goto num_planes_fail;
778 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);
781 surf->hal_surface = hal_surface;
783 // set infomation of planes
784 for (i = 0; i < surf->info.num_planes; i++) {
785 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
786 if (*error != TBM_ERROR_NONE) {
787 goto query_plane_data_fail;
789 surf->info.planes[i].size = size;
790 surf->info.planes[i].offset = offset;
791 surf->info.planes[i].stride = stride;
792 surf->planes_bo_idx[i] = bo_idx;
795 // set infomation of bos
796 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
798 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
801 surf->num_bos = num_bos;
803 for (i = 0; i < surf->info.num_planes; i++) {
804 surf->info.size += surf->info.planes[i].size;
806 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
807 surf->num_bos = surf->planes_bo_idx[i] + 1;
810 for (i = 0; i < num_bos; i++) {
811 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
813 TBM_ERR("fail to alloc bo idx:%d", i);
814 *error = tbm_get_last_error();
818 _tbm_bo_set_surface(surf->bos[i], surf);
821 // set infomation of planes
822 for (i = 0; i < surf->info.num_planes; i++) {
823 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
824 TBM_ERR("fail to query plane data");
825 *error = tbm_get_last_error();
826 goto query_plane_data_fail;
828 surf->info.planes[i].size = size;
829 surf->info.planes[i].offset = offset;
830 surf->info.planes[i].stride = stride;
831 surf->planes_bo_idx[i] = bo_idx;
834 // count number of bos
836 for (i = 0; i < surf->info.num_planes; i++) {
837 surf->info.size += surf->info.planes[i].size;
839 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
840 surf->num_bos = surf->planes_bo_idx[i] + 1;
843 // set infomation of bos
844 for (i = 0; i < surf->num_bos; i++) {
846 for (j = 0; j < surf->info.num_planes; j++) {
847 if (surf->planes_bo_idx[j] == i)
848 bo_size += surf->info.planes[j].size;
851 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp / 8, flags, error);
852 if (*error == TBM_ERROR_NOT_SUPPORTED) {
853 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
855 TBM_ERR("fail to alloc bo idx:%d", i);
856 *error = tbm_get_last_error();
861 _tbm_bo_set_surface(surf->bos[i], surf);
865 *error = TBM_ERROR_NONE;
871 query_plane_data_fail:
873 hal_tbm_surface_free(hal_surface);
875 for (j = 0; j < i; j++) {
877 tbm_bo_unref(surf->bos[j]);
889 static struct _tbm_surface *
890 _tbm_surface_internal_hal_tbm_import_surface(tbm_bufmgr bufmgr, int width, int height, int format, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
892 struct _tbm_surface *surf = NULL;
893 uint32_t size = 0, offset = 0, stride = 0;
895 hal_tbm_surface *hal_surface = NULL;
896 hal_tbm_bo **hal_bos = NULL;
900 surf = calloc(1, sizeof(struct _tbm_surface));
902 /* LCOV_EXCL_START */
903 TBM_ERR("fail to alloc surf");
904 *error = TBM_ERROR_OUT_OF_MEMORY;
905 goto alloc_surf_fail;
910 surf->magic = TBM_SURFACE_MAGIC;
911 surf->bufmgr = bufmgr;
912 surf->info.width = width;
913 surf->info.height = height;
914 surf->info.format = format;
915 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
916 if (!surf->info.bpp) {
917 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
918 *error = tbm_get_last_error();
922 // get number of planes
923 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
924 if (!surf->info.num_planes) {
925 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
926 *error = tbm_get_last_error();
927 goto num_planes_fail;
931 hal_surface = hal_tbm_bufmgr_import_surface(bufmgr->hal_bufmgr,
934 (hal_tbm_format)format,
935 (hal_tbm_surface_buffer_data *)buffer_data,
936 (hal_tbm_error *)error);
938 TBM_ERR("hal_tbm_bufmgr_import_surface failed.(width:%d height:%d format:%d error:%s)",
939 width, height, format, tbm_error_str(*error));
940 goto import_surface_fail;
942 surf->hal_surface = hal_surface;
944 // set infomation of planes
945 for (i = 0; i < surf->info.num_planes; i++) {
946 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
947 if (*error != TBM_ERROR_NONE) {
948 goto query_plane_data_fail;
950 surf->info.planes[i].size = size;
951 surf->info.planes[i].offset = offset;
952 surf->info.planes[i].stride = stride;
953 surf->planes_bo_idx[i] = bo_idx;
956 // set infomation of bos
957 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
959 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
962 surf->num_bos = num_bos;
964 for (i = 0; i < surf->info.num_planes; i++) {
965 surf->info.size += surf->info.planes[i].size;
967 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
968 surf->num_bos = surf->planes_bo_idx[i] + 1;
971 // get memory_types(bo flags)
972 flags = (int)hal_tbm_bo_get_memory_types(hal_bos[0], (hal_tbm_error *)error);
973 if (*error != TBM_ERROR_NONE) {
974 TBM_ERR("hal_tbm_bo_get_memory_types failed.");
975 goto get_memory_types_fail;
979 for (i = 0; i < num_bos; i++) {
980 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
982 TBM_ERR("fail to alloc bo idx:%d", i);
983 *error = tbm_get_last_error();
987 _tbm_bo_set_surface(surf->bos[i], surf);
990 *error = TBM_ERROR_NONE;
995 get_memory_types_fail:
997 query_plane_data_fail:
999 hal_tbm_surface_free(hal_surface);
1001 for (j = 0; j < i; j++) {
1003 tbm_bo_unref(surf->bos[j]);
1006 import_surface_fail:
1017 tbm_surface_internal_is_valid(tbm_surface_h surface)
1021 _tbm_surface_mutex_lock();
1022 _tbm_set_last_result(TBM_ERROR_NONE);
1024 /* Return silently if surface is null. */
1026 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1027 _tbm_surface_mutex_unlock();
1031 ret = _tbm_surface_internal_is_valid(surface);
1033 _tbm_surface_mutex_unlock();
1039 tbm_surface_internal_query_supported_formats(uint32_t **formats,
1042 struct _tbm_bufmgr *bufmgr;
1043 bool bufmgr_initialized = false;
1046 _tbm_surface_mutex_lock();
1047 _tbm_set_last_result(TBM_ERROR_NONE);
1049 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
1050 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
1052 if (!g_surface_bufmgr) {
1053 _init_surface_bufmgr();
1054 if (!g_surface_bufmgr) {
1055 TBM_ERR("fail bufmgr initialization\n");
1056 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1059 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1060 bufmgr_initialized = true;
1063 bufmgr = g_surface_bufmgr;
1065 error = tbm_module_bufmgr_get_supported_formats(bufmgr->module, formats, num);
1066 if (error != TBM_ERROR_NONE) {
1067 _tbm_set_last_result(error);
1071 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
1073 if (bufmgr_initialized) {
1074 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1075 _deinit_surface_bufmgr();
1078 _tbm_surface_mutex_unlock();
1082 /* LCOV_EXCL_START */
1084 if (bufmgr_initialized) {
1085 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1086 _deinit_surface_bufmgr();
1088 _tbm_surface_mutex_unlock();
1090 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
1093 /* LCOV_EXCL_STOP */
1097 tbm_surface_internal_get_num_planes(tbm_format format)
1101 _tbm_surface_mutex_lock();
1102 _tbm_set_last_result(TBM_ERROR_NONE);
1104 num_planes = _tbm_surface_internal_get_num_planes(format);
1106 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1107 _tbm_surface_mutex_unlock();
1111 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
1113 _tbm_surface_mutex_unlock();
1119 tbm_surface_internal_get_bpp(tbm_format format)
1123 _tbm_surface_mutex_lock();
1124 _tbm_set_last_result(TBM_ERROR_NONE);
1126 bpp = _tbm_surface_internal_get_bpp(format);
1128 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1129 _tbm_surface_mutex_unlock();
1133 _tbm_surface_mutex_unlock();
1135 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
1141 tbm_surface_internal_create_with_flags(int width, int height,
1142 int format, int flags)
1144 struct _tbm_bufmgr *bufmgr;
1145 struct _tbm_surface *surf = NULL;
1146 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
1147 bool bufmgr_initialized = false;
1149 _tbm_surface_mutex_lock();
1150 _tbm_set_last_result(TBM_ERROR_NONE);
1152 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
1153 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
1155 if (!g_surface_bufmgr) {
1156 _init_surface_bufmgr();
1157 if (!g_surface_bufmgr) {
1158 TBM_ERR("fail bufmgr initialization\n");
1159 error = TBM_ERROR_INVALID_OPERATION;
1160 goto check_valid_fail;
1162 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1163 bufmgr_initialized = true;
1166 bufmgr = g_surface_bufmgr;
1167 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1168 TBM_ERR("The bufmgr is invalid\n");
1169 error = TBM_ERROR_INVALID_PARAMETER;
1170 goto check_valid_fail;
1173 if (bufmgr->use_hal_tbm) {
1174 surf = _tbm_surface_internal_hal_tbm_create_surface(bufmgr, width, height, format, flags, &error);
1176 TBM_ERR("_tbm_surface_internal_hal_tbm_create_surface failed.");
1177 goto surface_alloc_fail;
1180 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1182 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1183 goto surface_alloc_fail;
1187 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1188 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1190 LIST_INITHEAD(&surf->user_data_list);
1191 LIST_INITHEAD(&surf->debug_data_list);
1192 LIST_INITHEAD(&surf->destroy_funcs);
1194 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1196 _tbm_set_last_result(error);
1197 _tbm_surface_mutex_unlock();
1201 /* LCOV_EXCL_START */
1205 if (bufmgr_initialized && bufmgr) {
1206 LIST_DELINIT(&bufmgr->surf_list);
1207 _deinit_surface_bufmgr();
1210 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1211 width, height, _tbm_surface_internal_format_to_str(format), flags);
1213 _tbm_set_last_result(error);
1214 _tbm_surface_mutex_unlock();
1216 /* LCOV_EXCL_STOP */
1222 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1223 tbm_bo *bos, int num)
1225 struct _tbm_bufmgr *bufmgr;
1226 struct _tbm_surface *surf = NULL;
1228 bool bufmgr_initialized = false;
1230 _tbm_surface_mutex_lock();
1231 _tbm_set_last_result(TBM_ERROR_NONE);
1233 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1234 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1235 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1236 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1237 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1239 if (!g_surface_bufmgr) {
1240 _init_surface_bufmgr();
1241 if (!g_surface_bufmgr) {
1242 TBM_ERR("fail bufmgr initialization\n");
1243 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1244 goto check_valid_fail;
1246 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1247 bufmgr_initialized = true;
1250 bufmgr = g_surface_bufmgr;
1251 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1252 TBM_ERR("fail to validate the Bufmgr.\n");
1253 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1254 goto check_valid_fail;
1257 surf = calloc(1, sizeof(struct _tbm_surface));
1259 /* LCOV_EXCL_START */
1260 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1261 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1262 goto alloc_surf_fail;
1263 /* LCOV_EXCL_STOP */
1266 surf->magic = TBM_SURFACE_MAGIC;
1267 surf->bufmgr = bufmgr;
1268 surf->info.width = info->width;
1269 surf->info.height = info->height;
1270 surf->info.format = info->format;
1272 surf->info.bpp = info->bpp;
1274 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1275 if (!surf->info.bpp) {
1276 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1280 surf->info.num_planes = info->num_planes;
1283 /* get size, stride and offset */
1284 for (i = 0; i < info->num_planes; i++) {
1285 surf->info.planes[i].offset = info->planes[i].offset;
1286 surf->info.planes[i].stride = info->planes[i].stride;
1288 if (info->planes[i].size > 0)
1289 surf->info.planes[i].size = info->planes[i].size;
1291 uint32_t size = 0, offset = 0, stride = 0;
1294 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1295 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1296 goto plane_data_fail;
1298 surf->info.planes[i].size = size;
1302 surf->planes_bo_idx[i] = 0;
1304 surf->planes_bo_idx[i] = i;
1307 if (info->size > 0) {
1308 surf->info.size = info->size;
1310 surf->info.size = 0;
1311 for (i = 0; i < info->num_planes; i++)
1312 surf->info.size += surf->info.planes[i].size;
1315 surf->flags = TBM_BO_DEFAULT;
1317 /* create only one bo */
1318 surf->num_bos = num;
1319 for (i = 0; i < num; i++) {
1320 if (bos[i] == NULL) {
1321 TBM_ERR("bos[%d] is null.\n", i);
1322 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1326 surf->bos[i] = tbm_bo_ref(bos[i]);
1327 _tbm_bo_set_surface(bos[i], surf);
1330 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1331 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1333 LIST_INITHEAD(&surf->user_data_list);
1334 LIST_INITHEAD(&surf->debug_data_list);
1335 LIST_INITHEAD(&surf->destroy_funcs);
1337 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1339 _tbm_surface_mutex_unlock();
1343 /* LCOV_EXCL_START */
1347 for (i = 0; i < num; i++) {
1349 tbm_bo_unref(surf->bos[i]);
1354 if (bufmgr_initialized && bufmgr) {
1355 LIST_DELINIT(&bufmgr->surf_list);
1356 _deinit_surface_bufmgr();
1358 _tbm_surface_mutex_unlock();
1360 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1361 info->width, info->height,
1362 _tbm_surface_internal_format_to_str(info->format), num);
1363 /* LCOV_EXCL_STOP */
1369 tbm_surface_internal_destroy(tbm_surface_h surface)
1371 _tbm_surface_mutex_lock();
1372 _tbm_set_last_result(TBM_ERROR_NONE);
1374 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1378 if (surface->refcnt > 0) {
1379 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1380 _tbm_surface_mutex_unlock();
1384 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1386 if (surface->refcnt == 0)
1387 _tbm_surface_internal_destroy(surface);
1388 else // if (surface->refcnt < 0)
1389 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1391 _tbm_surface_mutex_unlock();
1395 tbm_surface_internal_ref(tbm_surface_h surface)
1397 _tbm_surface_mutex_lock();
1398 _tbm_set_last_result(TBM_ERROR_NONE);
1400 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1404 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1406 _tbm_surface_mutex_unlock();
1410 tbm_surface_internal_unref(tbm_surface_h surface)
1412 _tbm_surface_mutex_lock();
1413 _tbm_set_last_result(TBM_ERROR_NONE);
1415 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1419 if (surface->refcnt > 0) {
1420 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1421 _tbm_surface_mutex_unlock();
1425 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1427 if (surface->refcnt == 0)
1428 _tbm_surface_internal_destroy(surface);
1430 _tbm_surface_mutex_unlock();
1434 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1436 struct _tbm_surface *surf;
1439 _tbm_surface_mutex_lock();
1440 _tbm_set_last_result(TBM_ERROR_NONE);
1442 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1444 surf = (struct _tbm_surface *)surface;
1445 num = surf->num_bos;
1448 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1450 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1452 _tbm_surface_mutex_unlock();
1458 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1460 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), NULL);
1467 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1469 surf = (struct _tbm_surface *)surface;
1470 bo = surf->bos[bo_idx];
1472 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1474 _tbm_surface_mutex_unlock();
1480 tbm_surface_internal_get_size(tbm_surface_h surface)
1482 struct _tbm_surface *surf;
1485 _tbm_surface_mutex_lock();
1486 _tbm_set_last_result(TBM_ERROR_NONE);
1488 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1490 surf = (struct _tbm_surface *)surface;
1491 size = surf->info.size;
1493 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1495 _tbm_surface_mutex_unlock();
1501 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1502 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1504 struct _tbm_surface *surf;
1506 _tbm_surface_mutex_lock();
1507 _tbm_set_last_result(TBM_ERROR_NONE);
1509 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1510 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1512 surf = (struct _tbm_surface *)surface;
1514 if (plane_idx >= surf->info.num_planes) {
1515 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1516 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1517 _tbm_surface_mutex_unlock();
1522 *size = surf->info.planes[plane_idx].size;
1525 *offset = surf->info.planes[plane_idx].offset;
1528 *pitch = surf->info.planes[plane_idx].stride;
1530 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1531 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1532 surf->info.planes[plane_idx].stride);
1534 _tbm_surface_mutex_unlock();
1540 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1541 tbm_surface_info_s *info, int map)
1543 struct _tbm_surface *surf;
1544 tbm_bo_handle bo_handles[4];
1547 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1550 _tbm_surface_mutex_lock();
1551 _tbm_set_last_result(TBM_ERROR_NONE);
1553 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1555 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1557 surf = (struct _tbm_surface *)surface;
1559 memset(info, 0x00, sizeof(tbm_surface_info_s));
1560 info->width = surf->info.width;
1561 info->height = surf->info.height;
1562 info->format = surf->info.format;
1563 info->bpp = surf->info.bpp;
1564 info->size = surf->info.size;
1565 info->num_planes = surf->info.num_planes;
1567 for (i = 0; i < surf->info.num_planes; i++) {
1568 info->planes[i].size = surf->info.planes[i].size;
1569 info->planes[i].offset = surf->info.planes[i].offset;
1570 info->planes[i].stride = surf->info.planes[i].stride;
1571 planes_bo_idx[i] = surf->planes_bo_idx[i];
1574 for (i = 0; i < surf->num_bos; i++)
1575 bos[i] = surf->bos[i];
1577 num_bos = surf->num_bos;
1580 _tbm_surface_mutex_unlock();
1581 for (i = 0; i < num_bos; i++) {
1582 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1583 if (bo_handles[i].ptr == NULL) {
1584 for (j = 0; j < i; j++)
1585 tbm_bo_unmap(bos[j]);
1587 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1591 _tbm_surface_mutex_lock();
1593 for (i = 0; i < num_bos; i++) {
1594 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1595 if (bo_handles[i].ptr == NULL) {
1596 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1597 _tbm_surface_mutex_unlock();
1603 for (i = 0; i < info->num_planes; i++) {
1604 if (bo_handles[planes_bo_idx[i]].ptr)
1605 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1608 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1610 _tbm_surface_mutex_unlock();
1616 tbm_surface_internal_unmap(tbm_surface_h surface)
1618 struct _tbm_surface *surf;
1621 _tbm_surface_mutex_lock();
1622 _tbm_set_last_result(TBM_ERROR_NONE);
1624 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1626 surf = (struct _tbm_surface *)surface;
1628 for (i = 0; i < surf->num_bos; i++)
1629 tbm_bo_unmap(surf->bos[i]);
1631 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1633 _tbm_surface_mutex_unlock();
1637 tbm_surface_internal_get_width(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 width = surf->info.width;
1650 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1652 _tbm_surface_mutex_unlock();
1658 tbm_surface_internal_get_height(tbm_surface_h surface)
1660 struct _tbm_surface *surf;
1661 unsigned int height;
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);
1668 surf = (struct _tbm_surface *)surface;
1669 height = surf->info.height;
1671 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1673 _tbm_surface_mutex_unlock();
1680 tbm_surface_internal_get_format(tbm_surface_h surface)
1682 struct _tbm_surface *surf;
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 surf = (struct _tbm_surface *)surface;
1691 format = surf->info.format;
1693 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1695 _tbm_surface_mutex_unlock();
1701 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1703 struct _tbm_surface *surf;
1706 _tbm_surface_mutex_lock();
1707 _tbm_set_last_result(TBM_ERROR_NONE);
1709 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1710 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1712 surf = (struct _tbm_surface *)surface;
1713 bo_idx = surf->planes_bo_idx[plane_idx];
1715 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1717 _tbm_surface_mutex_unlock();
1723 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1724 tbm_data_free data_free_func)
1726 tbm_user_data *data;
1728 _tbm_surface_mutex_lock();
1729 _tbm_set_last_result(TBM_ERROR_NONE);
1731 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1733 /* check if the data according to the key exist if so, return false. */
1734 data = user_data_lookup(&surface->user_data_list, key);
1736 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1737 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1738 _tbm_surface_mutex_unlock();
1742 data = user_data_create(key, data_free_func);
1744 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1745 _tbm_surface_mutex_unlock();
1749 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1751 LIST_ADD(&data->item_link, &surface->user_data_list);
1753 _tbm_surface_mutex_unlock();
1759 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1762 tbm_user_data *old_data;
1764 _tbm_surface_mutex_lock();
1765 _tbm_set_last_result(TBM_ERROR_NONE);
1767 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1769 old_data = user_data_lookup(&surface->user_data_list, key);
1771 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1772 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1773 _tbm_surface_mutex_unlock();
1777 if (old_data->data && old_data->free_func)
1778 old_data->free_func(old_data->data);
1780 old_data->data = data;
1782 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1784 _tbm_surface_mutex_unlock();
1790 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1793 tbm_user_data *old_data;
1795 _tbm_surface_mutex_lock();
1796 _tbm_set_last_result(TBM_ERROR_NONE);
1798 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1801 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1802 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1803 _tbm_surface_mutex_unlock();
1808 old_data = user_data_lookup(&surface->user_data_list, key);
1810 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1811 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1812 _tbm_surface_mutex_unlock();
1816 *data = old_data->data;
1818 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1820 _tbm_surface_mutex_unlock();
1826 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1829 tbm_user_data *old_data = (void *)0;
1831 _tbm_surface_mutex_lock();
1832 _tbm_set_last_result(TBM_ERROR_NONE);
1834 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1836 old_data = user_data_lookup(&surface->user_data_list, key);
1838 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1839 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1840 _tbm_surface_mutex_unlock();
1844 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1846 user_data_delete(old_data);
1848 _tbm_surface_mutex_unlock();
1853 /* LCOV_EXCL_START */
1855 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1857 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1859 return surface->debug_pid;
1863 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1865 _tbm_surface_mutex_lock();
1866 _tbm_set_last_result(TBM_ERROR_NONE);
1868 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1870 surface->debug_pid = pid;
1872 _tbm_surface_mutex_unlock();
1875 static tbm_surface_debug_data *
1876 _tbm_surface_internal_debug_data_create(char *key, char *value)
1878 tbm_surface_debug_data *debug_data = NULL;
1880 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1882 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1883 TBM_ERR("fail to allocate the debug_data.");
1887 if (key) debug_data->key = strdup(key);
1888 if (value) debug_data->value = strdup(value);
1894 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1896 if (!debug_data->value && !value)
1899 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1902 if (debug_data->value)
1903 free(debug_data->value);
1906 debug_data->value = strdup(value);
1908 debug_data->value = NULL;
1911 static tbm_surface_debug_data *
1912 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1914 tbm_surface_debug_data *debug_data = NULL;
1916 if (LIST_IS_EMPTY(list))
1919 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1920 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1928 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1930 tbm_surface_debug_data *debug_data = NULL;
1931 tbm_bufmgr bufmgr = NULL;
1933 _tbm_surface_mutex_lock();
1934 _tbm_set_last_result(TBM_ERROR_NONE);
1936 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1937 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1939 bufmgr = surface->bufmgr;
1941 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1943 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1945 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1947 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1949 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1950 _tbm_surface_mutex_unlock();
1954 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1957 /* add new debug key to list */
1958 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1960 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1962 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1965 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1967 _tbm_surface_mutex_unlock();
1973 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1975 tbm_surface_debug_data *old_data = NULL;
1977 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1979 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1980 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1981 if (!strcmp(old_data->key, key))
1982 return old_data->value;
1989 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1990 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1992 struct _tbm_surface_dump_buf_info {
2002 tbm_surface_info_s info;
2004 struct list_head link;
2007 struct _tbm_surface_dump_info {
2008 char *path; // copy???
2011 struct list_head *link;
2012 struct list_head surface_list; /* link of surface */
2015 static tbm_surface_dump_info *g_dump_info = NULL;
2016 static const char *dump_postfix[2] = {"png", "yuv"};
2017 static double scale_factor;
2020 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
2021 void *data2, int size2, void *data3, int size3)
2024 unsigned int *blocks;
2026 if (_tbm_surface_check_file_is_symbolic_link(file))
2027 TBM_ERR("%s is symbolic link\n", file);
2029 fp = fopen(file, "w+");
2030 TBM_RETURN_IF_FAIL(fp != NULL);
2032 blocks = (unsigned int *)data1;
2033 fwrite(blocks, 1, size1, fp);
2036 blocks = (unsigned int *)data2;
2037 fwrite(blocks, 1, size2, fp);
2041 blocks = (unsigned int *)data3;
2042 fwrite(blocks, 1, size3, fp);
2049 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
2051 unsigned int *blocks = (unsigned int *)data;
2054 png_bytep *row_pointers;
2057 if (_tbm_surface_check_file_is_symbolic_link(file))
2058 TBM_ERR("%s is symbolic link\n", file);
2060 fp = fopen(file, "wb");
2061 TBM_RETURN_IF_FAIL(fp != NULL);
2063 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
2066 TBM_ERR("fail to create a png write structure.\n");
2071 png_infop pPngInfo = png_create_info_struct(pPngStruct);
2073 TBM_ERR("fail to create a png info structure.\n");
2074 png_destroy_write_struct(&pPngStruct, NULL);
2079 if (setjmp(png_jmpbuf(pPngStruct))) {
2080 /* if png has problem of writing the file, we get here */
2081 TBM_ERR("fail to write png file.\n");
2082 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2087 png_init_io(pPngStruct, fp);
2088 if (format == TBM_FORMAT_XRGB8888) {
2090 png_set_IHDR(pPngStruct,
2097 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2100 png_set_IHDR(pPngStruct,
2105 PNG_COLOR_TYPE_RGBA,
2107 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2110 png_set_bgr(pPngStruct);
2111 png_write_info(pPngStruct, pPngInfo);
2113 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
2114 if (!row_pointers) {
2115 TBM_ERR("fail to allocate the png row_pointers.\n");
2116 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2121 for (y = 0; y < height; ++y) {
2125 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
2127 TBM_ERR("fail to allocate the png row.\n");
2128 for (x = 0; x < y; x++)
2129 png_free(pPngStruct, row_pointers[x]);
2130 png_free(pPngStruct, row_pointers);
2131 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2135 row_pointers[y] = (png_bytep)row;
2137 for (x = 0; x < width; ++x) {
2138 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
2140 if (pixel_size == 3) { // XRGB8888
2141 row[x * pixel_size] = (curBlock & 0xFF);
2142 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2143 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2144 } else { // ARGB8888
2145 row[x * pixel_size] = (curBlock & 0xFF);
2146 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2147 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2148 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2153 png_write_image(pPngStruct, row_pointers);
2154 png_write_end(pPngStruct, pPngInfo);
2156 for (y = 0; y < height; y++)
2157 png_free(pPngStruct, row_pointers[y]);
2158 png_free(pPngStruct, row_pointers);
2160 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2166 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2168 TBM_RETURN_IF_FAIL(path != NULL);
2169 TBM_RETURN_IF_FAIL(w > 0);
2170 TBM_RETURN_IF_FAIL(h > 0);
2171 TBM_RETURN_IF_FAIL(count > 0);
2173 tbm_surface_dump_buf_info *buf_info = NULL;
2174 tbm_surface_h tbm_surface;
2175 tbm_surface_info_s info;
2180 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2184 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2185 TBM_RETURN_IF_FAIL(g_dump_info);
2187 LIST_INITHEAD(&g_dump_info->surface_list);
2188 g_dump_info->count = 0;
2189 g_dump_info->dump_max = count;
2191 /* get buffer size */
2192 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2193 if (tbm_surface == NULL) {
2194 TBM_ERR("tbm_surface_create fail\n");
2200 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2201 TBM_ERR("tbm_surface_get_info fail\n");
2202 tbm_surface_destroy(tbm_surface);
2207 buffer_size = info.size;
2208 tbm_surface_destroy(tbm_surface);
2210 /* create dump lists */
2211 for (i = 0; i < count; i++) {
2214 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2215 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2217 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2219 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2224 buf_info->index = i;
2226 buf_info->size = buffer_size;
2228 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2231 g_dump_info->path = path;
2232 g_dump_info->link = &g_dump_info->surface_list;
2236 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2241 /* free resources */
2242 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2243 tbm_surface_dump_buf_info *tmp;
2245 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2246 tbm_bo_unref(buf_info->bo);
2247 LIST_DEL(&buf_info->link);
2252 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2261 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2268 tbm_surface_internal_dump_start(path, w, h, count);
2269 scale_factor = scale;
2273 tbm_surface_internal_dump_end(void)
2275 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2276 tbm_bo_handle bo_handle;
2281 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2288 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2291 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2292 if (bo_handle.ptr == NULL) {
2293 tbm_bo_unref(buf_info->bo);
2294 LIST_DEL(&buf_info->link);
2299 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2300 TBM_INFO("Dump File.. %s generated.\n", file);
2302 if (buf_info->dirty) {
2303 void *ptr1 = NULL, *ptr2 = NULL;
2305 switch (buf_info->info.format) {
2306 case TBM_FORMAT_ARGB8888:
2307 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2308 buf_info->info.planes[0].stride >> 2,
2309 buf_info->info.height,
2310 buf_info->info.planes[0].stride,
2311 TBM_FORMAT_ARGB8888);
2313 case TBM_FORMAT_XRGB8888:
2314 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2315 buf_info->info.planes[0].stride >> 2,
2316 buf_info->info.height,
2317 buf_info->info.planes[0].stride,
2318 TBM_FORMAT_XRGB8888);
2320 case TBM_FORMAT_YVU420:
2321 case TBM_FORMAT_YUV420:
2322 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2323 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2324 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2325 buf_info->info.planes[0].stride * buf_info->info.height,
2327 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2329 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2331 case TBM_FORMAT_NV12:
2332 case TBM_FORMAT_NV21:
2333 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2334 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2335 buf_info->info.planes[0].stride * buf_info->info.height,
2337 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2340 case TBM_FORMAT_YUYV:
2341 case TBM_FORMAT_UYVY:
2342 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2343 buf_info->info.planes[0].stride * buf_info->info.height,
2347 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2350 } else if (buf_info->dirty_shm)
2351 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2352 buf_info->shm_stride >> 2,
2354 buf_info->shm_stride, 0);
2356 tbm_bo_unmap(buf_info->bo);
2357 tbm_bo_unref(buf_info->bo);
2358 LIST_DEL(&buf_info->link);
2365 TBM_INFO("Dump End..\n");
2368 static pixman_format_code_t
2369 _tbm_surface_internal_pixman_format_get(tbm_format format)
2372 case TBM_FORMAT_ARGB8888:
2373 return PIXMAN_a8r8g8b8;
2374 case TBM_FORMAT_XRGB8888:
2375 return PIXMAN_x8r8g8b8;
2384 * This function supports only if a buffer has below formats.
2385 * - TBM_FORMAT_ARGB8888
2386 * - TBM_FORMAT_XRGB8888
2388 static tbm_surface_error_e
2389 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2390 int format, int src_stride, int src_w, int src_h,
2391 int dst_stride, int dst_w, int dst_h)
2393 pixman_image_t *src_img = NULL, *dst_img = NULL;
2394 pixman_format_code_t pixman_format;
2395 pixman_transform_t t;
2396 struct pixman_f_transform ft;
2397 double scale_x, scale_y;
2399 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2400 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2402 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2403 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2406 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2407 (uint32_t*)src_ptr, src_stride);
2408 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2411 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2412 (uint32_t*)dst_ptr, dst_stride);
2413 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2415 pixman_f_transform_init_identity(&ft);
2417 scale_x = (double)src_w / dst_w;
2418 scale_y = (double)src_h / dst_h;
2420 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2421 pixman_f_transform_translate(&ft, NULL, 0, 0);
2422 pixman_transform_from_pixman_f_transform(&t, &ft);
2423 pixman_image_set_transform(src_img, &t);
2425 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2426 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2428 pixman_image_unref(src_img);
2429 pixman_image_unref(dst_img);
2431 return TBM_SURFACE_ERROR_NONE;
2435 pixman_image_unref(src_img);
2437 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2440 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2441 #define KEY_LEN 5 // "_XXXX"
2442 #define KEYS_LEN KEY_LEN * MAX_BOS
2444 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2446 char *keys, temp_key[KEY_LEN + 1];
2447 struct _tbm_surface *surf;
2451 _tbm_surface_mutex_lock();
2453 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2455 surf = (struct _tbm_surface *)surface;
2457 num_bos = surf->num_bos;
2458 if (num_bos > MAX_BOS)
2461 keys = calloc(KEYS_LEN + 1, sizeof(char));
2463 TBM_ERR("Failed to alloc memory");
2464 _tbm_surface_mutex_unlock();
2468 for (i = 0; i < num_bos; i++) {
2469 memset(temp_key, 0x00, KEY_LEN + 1);
2471 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2472 strncat(keys, temp_key, KEY_LEN + 1);
2475 _tbm_surface_mutex_unlock();
2480 static void _tbm_surface_internal_put_keys(char *keys)
2487 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2489 TBM_RETURN_IF_FAIL(surface != NULL);
2490 TBM_RETURN_IF_FAIL(type != NULL);
2492 tbm_surface_dump_buf_info *buf_info;
2493 struct list_head *next_link;
2494 tbm_surface_info_s info;
2495 tbm_bo_handle bo_handle;
2496 const char *postfix;
2497 const char *format = NULL;
2504 next_link = g_dump_info->link->next;
2505 TBM_RETURN_IF_FAIL(next_link != NULL);
2507 if (next_link == &g_dump_info->surface_list) {
2508 next_link = next_link->next;
2509 TBM_RETURN_IF_FAIL(next_link != NULL);
2512 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2513 TBM_RETURN_IF_FAIL(buf_info != NULL);
2515 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2516 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2518 if (scale_factor > 0.0) {
2521 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2522 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2523 _tbm_surface_internal_format_to_str(info.format));
2524 tbm_surface_unmap(surface);
2528 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2530 buf_info->info.width = info.width * scale_factor;
2531 buf_info->info.height = info.height * scale_factor;
2532 buf_info->info.format = info.format;
2533 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2534 if (!buf_info->info.bpp) {
2535 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2536 tbm_surface_unmap(surface);
2539 buf_info->info.num_planes = 1;
2540 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2541 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2543 if (buf_info->info.size > buf_info->size) {
2544 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2545 buf_info->info.size, buf_info->size);
2546 tbm_surface_unmap(surface);
2550 if (info.size > buf_info->size) {
2551 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2552 info.size, buf_info->size);
2553 tbm_surface_unmap(surface);
2557 /* make the file information */
2558 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2561 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2562 postfix = dump_postfix[0];
2563 format = _tbm_surface_internal_format_to_str(info.format);
2565 postfix = dump_postfix[1];
2567 keys = _tbm_surface_internal_get_keys(surface);
2569 TBM_ERR("fail to get keys");
2570 tbm_surface_unmap(surface);
2575 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2576 if (!bo_handle.ptr) {
2577 TBM_ERR("fail to map bo");
2578 _tbm_surface_internal_put_keys(keys);
2579 tbm_surface_unmap(surface);
2582 memset(bo_handle.ptr, 0x00, buf_info->size);
2584 switch (info.format) {
2585 case TBM_FORMAT_ARGB8888:
2586 case TBM_FORMAT_XRGB8888:
2587 snprintf(buf_info->name, sizeof(buf_info->name),
2588 "%10.3f_%03d%s_%p_%s-%s.%s",
2589 _tbm_surface_internal_get_time(),
2590 g_dump_info->count++, keys, surface, format, type, postfix);
2592 if (scale_factor > 0.0) {
2593 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2595 buf_info->info.format,
2596 info.planes[0].stride,
2597 info.width, info.height,
2598 buf_info->info.planes[0].stride,
2599 buf_info->info.width,
2600 buf_info->info.height);
2601 if (ret != TBM_SURFACE_ERROR_NONE) {
2602 TBM_ERR("fail to scale buffer");
2603 tbm_bo_unmap(buf_info->bo);
2604 _tbm_surface_internal_put_keys(keys);
2605 tbm_surface_unmap(surface);
2609 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2611 case TBM_FORMAT_YVU420:
2612 case TBM_FORMAT_YUV420:
2613 snprintf(buf_info->name, sizeof(buf_info->name),
2614 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2615 _tbm_surface_internal_get_time(),
2616 g_dump_info->count++, keys, type, info.planes[0].stride,
2617 info.height, FOURCC_STR(info.format), postfix);
2618 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2619 bo_handle.ptr += info.planes[0].stride * info.height;
2620 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2621 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2622 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2624 case TBM_FORMAT_NV12:
2625 case TBM_FORMAT_NV21:
2626 snprintf(buf_info->name, sizeof(buf_info->name),
2627 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2628 _tbm_surface_internal_get_time(),
2629 g_dump_info->count++, keys, type, info.planes[0].stride,
2630 info.height, FOURCC_STR(info.format), postfix);
2631 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2632 bo_handle.ptr += info.planes[0].stride * info.height;
2633 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2635 case TBM_FORMAT_YUYV:
2636 case TBM_FORMAT_UYVY:
2637 snprintf(buf_info->name, sizeof(buf_info->name),
2638 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2639 _tbm_surface_internal_get_time(),
2640 g_dump_info->count++, keys, type, info.planes[0].stride,
2641 info.height, FOURCC_STR(info.format), postfix);
2642 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2645 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2646 tbm_bo_unmap(buf_info->bo);
2647 _tbm_surface_internal_put_keys(keys);
2648 tbm_surface_unmap(surface);
2652 tbm_bo_unmap(buf_info->bo);
2654 _tbm_surface_internal_put_keys(keys);
2656 tbm_surface_unmap(surface);
2658 buf_info->dirty = 1;
2659 buf_info->dirty_shm = 0;
2661 if (g_dump_info->count == 1000)
2662 g_dump_info->count = 0;
2664 g_dump_info->link = next_link;
2666 TBM_INFO("Dump %s \n", buf_info->name);
2669 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2672 TBM_RETURN_IF_FAIL(ptr != NULL);
2673 TBM_RETURN_IF_FAIL(w > 0);
2674 TBM_RETURN_IF_FAIL(h > 0);
2675 TBM_RETURN_IF_FAIL(stride > 0);
2676 TBM_RETURN_IF_FAIL(type != NULL);
2678 tbm_surface_dump_buf_info *buf_info;
2679 struct list_head *next_link;
2680 tbm_bo_handle bo_handle;
2681 int ret, size, dw = 0, dh = 0, dstride = 0;
2686 next_link = g_dump_info->link->next;
2687 TBM_RETURN_IF_FAIL(next_link != NULL);
2689 if (next_link == &g_dump_info->surface_list) {
2690 next_link = next_link->next;
2691 TBM_RETURN_IF_FAIL(next_link != NULL);
2694 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2695 TBM_RETURN_IF_FAIL(buf_info != NULL);
2697 if (scale_factor > 0.0) {
2700 dw = w * scale_factor;
2701 dh = h * scale_factor;
2703 size = dstride * dh;
2707 if (size > buf_info->size) {
2708 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2709 size, buf_info->size);
2714 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2715 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2717 memset(bo_handle.ptr, 0x00, buf_info->size);
2718 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2720 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2721 _tbm_surface_internal_get_time(),
2722 g_dump_info->count++, type, dump_postfix[0]);
2723 if (scale_factor > 0.0) {
2724 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2725 TBM_FORMAT_ARGB8888, stride,
2726 w, h, dstride, dw, dh);
2727 if (ret != TBM_SURFACE_ERROR_NONE) {
2728 TBM_ERR("fail to scale buffer");
2729 tbm_bo_unmap(buf_info->bo);
2732 buf_info->shm_stride = dstride;
2733 buf_info->shm_h = dh;
2735 memcpy(bo_handle.ptr, ptr, size);
2736 buf_info->shm_stride = stride;
2737 buf_info->shm_h = h;
2740 tbm_bo_unmap(buf_info->bo);
2742 buf_info->dirty = 0;
2743 buf_info->dirty_shm = 1;
2745 if (g_dump_info->count == 1000)
2746 g_dump_info->count = 0;
2748 g_dump_info->link = next_link;
2750 TBM_INFO("Dump %s \n", buf_info->name);
2754 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2756 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2757 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2758 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2760 tbm_surface_info_s info;
2761 const char *postfix;
2765 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2766 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2768 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2769 postfix = dump_postfix[0];
2771 postfix = dump_postfix[1];
2773 if (strcmp(postfix, type)) {
2774 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2775 tbm_surface_unmap(surface);
2779 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2781 if (!access(file, 0)) {
2782 TBM_ERR("can't capture buffer, exist file %s", file);
2783 tbm_surface_unmap(surface);
2787 switch (info.format) {
2788 case TBM_FORMAT_ARGB8888:
2789 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2792 info.planes[0].stride,
2793 TBM_FORMAT_ARGB8888);
2795 case TBM_FORMAT_XRGB8888:
2796 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2799 info.planes[0].stride,
2800 TBM_FORMAT_XRGB8888);
2802 case TBM_FORMAT_YVU420:
2803 case TBM_FORMAT_YUV420:
2804 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2805 info.planes[0].stride * info.height,
2807 info.planes[1].stride * (info.height >> 1),
2809 info.planes[2].stride * (info.height >> 1));
2811 case TBM_FORMAT_NV12:
2812 case TBM_FORMAT_NV21:
2813 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2814 info.planes[0].stride * info.height,
2816 info.planes[1].stride * (info.height >> 1),
2819 case TBM_FORMAT_YUYV:
2820 case TBM_FORMAT_UYVY:
2821 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2822 info.planes[0].stride * info.height,
2826 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2827 tbm_surface_unmap(surface);
2831 tbm_surface_unmap(surface);
2833 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2839 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2840 const char *path, const char *name, const char *type)
2842 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2843 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2844 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2845 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2846 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2847 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2851 if (strcmp(dump_postfix[0], type)) {
2852 TBM_ERR("Not supported type:%s'", type);
2856 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2858 if (!access(file, 0)) {
2859 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2863 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2865 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2871 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2873 struct _tbm_surface *surf;
2875 _tbm_surface_mutex_lock();
2876 _tbm_set_last_result(TBM_ERROR_NONE);
2878 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2879 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2880 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2882 surf = (struct _tbm_surface *)surface;
2886 surf->damage.width = width;
2887 surf->damage.height = height;
2889 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2890 surface, x, y, width, height);
2892 _tbm_surface_mutex_unlock();
2898 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2900 struct _tbm_surface *surf;
2902 _tbm_surface_mutex_lock();
2903 _tbm_set_last_result(TBM_ERROR_NONE);
2905 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2907 surf = (struct _tbm_surface *)surface;
2909 if (x) *x = surf->damage.x;
2910 if (y) *y = surf->damage.y;
2911 if (width) *width = surf->damage.width;
2912 if (height) *height = surf->damage.height;
2914 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2915 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2917 _tbm_surface_mutex_unlock();
2923 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2925 struct _tbm_surface *surf;
2926 tbm_surface_destroy_func_info *func_info = NULL;
2928 _tbm_surface_mutex_lock();
2929 _tbm_set_last_result(TBM_ERROR_NONE);
2931 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2932 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2934 surf = (struct _tbm_surface *)surface;
2935 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2936 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2937 TBM_ERR("can't add twice");
2938 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2939 _tbm_surface_mutex_unlock();
2944 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2945 if (func_info == NULL) {
2946 TBM_ERR("alloc failed");
2947 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2948 _tbm_surface_mutex_unlock();
2952 func_info->destroy_func = func;
2953 func_info->user_data = user_data;
2955 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2957 _tbm_surface_mutex_unlock();
2963 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2965 struct _tbm_surface *surf;
2966 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2968 _tbm_surface_mutex_lock();
2969 _tbm_set_last_result(TBM_ERROR_NONE);
2971 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2972 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2974 surf = (struct _tbm_surface *)surface;
2975 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2976 if (func_info->destroy_func != func || func_info->user_data != user_data)
2979 LIST_DEL(&func_info->item_link);
2982 _tbm_surface_mutex_unlock();
2987 _tbm_surface_mutex_unlock();
2990 tbm_surface_buffer_data *
2991 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2993 tbm_surface_buffer_data *buffer_data = NULL;
2994 struct _tbm_surface *surf;
2995 struct _tbm_bufmgr *bufmgr;
2997 _tbm_surface_mutex_lock();
2999 surf = (struct _tbm_surface *)surface;
3000 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3002 bufmgr = surf->bufmgr;
3003 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3005 // this function supports when it comes to be use_hal.
3006 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
3009 buffer_data = (tbm_surface_buffer_data *)hal_tbm_surface_export((hal_tbm_surface *)surf->hal_surface,
3010 (hal_tbm_error *)error);
3011 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
3013 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
3016 *error = TBM_ERROR_NONE;
3018 _tbm_set_last_result(TBM_ERROR_NONE);
3019 _tbm_surface_mutex_unlock();
3025 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
3027 struct _tbm_surface *surf;
3028 struct _tbm_bufmgr *bufmgr;
3030 _tbm_surface_mutex_lock();
3032 bufmgr = g_surface_bufmgr;
3033 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3035 // this function supports when it comes to be use_hal.
3036 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
3038 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3039 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3040 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3041 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3044 surf = _tbm_surface_internal_hal_tbm_import_surface(bufmgr,
3045 (int)surface_info->width,
3046 (int)surface_info->height,
3047 (int)surface_info->format,
3050 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
3052 LIST_INITHEAD(&surf->user_data_list);
3053 LIST_INITHEAD(&surf->debug_data_list);
3054 LIST_INITHEAD(&surf->destroy_funcs);
3056 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
3058 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
3061 *error = TBM_ERROR_NONE;
3063 _tbm_set_last_result(TBM_ERROR_NONE);
3064 _tbm_surface_mutex_unlock();
3066 return (tbm_surface_h)surf;