1 /**************************************************************************
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
37 #include "tbm_bufmgr.h"
38 #include "tbm_bufmgr_int.h"
39 #include "tbm_surface_internal.h"
44 #define TBM_SURFACE_MAGIC 0xBF021234
46 static tbm_bufmgr g_surface_bufmgr;
47 static pthread_mutex_t tbm_surface_lock = PTHREAD_MUTEX_INITIALIZER;
48 void _tbm_surface_mutex_unlock(void);
51 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
53 TBM_ERR("'%s' failed.\n", #cond);\
54 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
55 _tbm_surface_mutex_unlock();\
60 #define TBM_SURFACE_RETURN_ERR_IF_FAIL(cond, error_type) {\
62 TBM_ERR("'%s' failed.\n", #cond);\
63 _tbm_set_last_result(error_type);\
64 _tbm_surface_mutex_unlock();\
69 #define TBM_SURFACE_RETURN_SET_ERR_IF_FAIL(cond, error, error_type) {\
71 TBM_ERR("'%s' failed.\n", #cond);\
73 _tbm_set_last_result(error_type);\
74 _tbm_surface_mutex_unlock();\
79 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
81 TBM_ERR("'%s' failed.\n", #cond);\
82 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
83 _tbm_surface_mutex_unlock();\
89 #define TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(cond, val, error_type) {\
91 TBM_ERR("'%s' failed.\n", #cond);\
92 _tbm_set_last_result(error_type);\
93 _tbm_surface_mutex_unlock();\
98 #define TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(cond, val, error, error_type) {\
100 TBM_ERR("'%s' failed.\n", #cond);\
102 *error = error_type;\
103 _tbm_set_last_result(error_type);\
104 _tbm_surface_mutex_unlock();\
109 /* LCOV_EXCL_START */
111 _tbm_surface_internal_get_time(void)
116 clock_gettime(CLOCK_MONOTONIC, &tp);
117 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
119 return time / 1000.0;
123 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
125 LIST_DEL(&debug_data->item_link);
127 if (debug_data->key) free(debug_data->key);
128 if (debug_data->value) free(debug_data->value);
133 _tbm_surface_internal_format_to_str(tbm_format format)
137 return "TBM_FORMAT_C8";
138 case TBM_FORMAT_RGB332:
139 return "TBM_FORMAT_RGB332";
140 case TBM_FORMAT_BGR233:
141 return "TBM_FORMAT_BGR233";
142 case TBM_FORMAT_XRGB4444:
143 return "TBM_FORMAT_XRGB4444";
144 case TBM_FORMAT_XBGR4444:
145 return "TBM_FORMAT_XBGR4444";
146 case TBM_FORMAT_RGBX4444:
147 return "TBM_FORMAT_RGBX4444";
148 case TBM_FORMAT_BGRX4444:
149 return "TBM_FORMAT_BGRX4444";
150 case TBM_FORMAT_ARGB4444:
151 return "TBM_FORMAT_ARGB4444";
152 case TBM_FORMAT_ABGR4444:
153 return "TBM_FORMAT_ABGR4444";
154 case TBM_FORMAT_RGBA4444:
155 return "TBM_FORMAT_RGBA4444";
156 case TBM_FORMAT_BGRA4444:
157 return "TBM_FORMAT_BGRA4444";
158 case TBM_FORMAT_XRGB1555:
159 return "TBM_FORMAT_XRGB1555";
160 case TBM_FORMAT_XBGR1555:
161 return "TBM_FORMAT_XBGR1555";
162 case TBM_FORMAT_RGBX5551:
163 return "TBM_FORMAT_RGBX5551";
164 case TBM_FORMAT_BGRX5551:
165 return "TBM_FORMAT_BGRX5551";
166 case TBM_FORMAT_ARGB1555:
167 return "TBM_FORMAT_ARGB1555";
168 case TBM_FORMAT_ABGR1555:
169 return "TBM_FORMAT_ABGR1555";
170 case TBM_FORMAT_RGBA5551:
171 return "TBM_FORMAT_RGBA5551";
172 case TBM_FORMAT_BGRA5551:
173 return "TBM_FORMAT_BGRA5551";
174 case TBM_FORMAT_RGB565:
175 return "TBM_FORMAT_RGB565";
176 case TBM_FORMAT_BGR565:
177 return "TBM_FORMAT_BGR565";
178 case TBM_FORMAT_RGB888:
179 return "TBM_FORMAT_RGB888";
180 case TBM_FORMAT_BGR888:
181 return "TBM_FORMAT_BGR888";
182 case TBM_FORMAT_XRGB8888:
183 return "TBM_FORMAT_XRGB8888";
184 case TBM_FORMAT_XBGR8888:
185 return "TBM_FORMAT_XBGR8888";
186 case TBM_FORMAT_RGBX8888:
187 return "TBM_FORMAT_RGBX8888";
188 case TBM_FORMAT_BGRX8888:
189 return "TBM_FORMAT_BGRX8888";
190 case TBM_FORMAT_ARGB8888:
191 return "TBM_FORMAT_ARGB8888";
192 case TBM_FORMAT_ABGR8888:
193 return "TBM_FORMAT_ABGR8888";
194 case TBM_FORMAT_RGBA8888:
195 return "TBM_FORMAT_RGBA8888";
196 case TBM_FORMAT_BGRA8888:
197 return "TBM_FORMAT_BGRA8888";
198 case TBM_FORMAT_XRGB2101010:
199 return "TBM_FORMAT_XRGB2101010";
200 case TBM_FORMAT_XBGR2101010:
201 return "TBM_FORMAT_XBGR2101010";
202 case TBM_FORMAT_RGBX1010102:
203 return "TBM_FORMAT_RGBX1010102";
204 case TBM_FORMAT_BGRX1010102:
205 return "TBM_FORMAT_BGRX1010102";
206 case TBM_FORMAT_ARGB2101010:
207 return "TBM_FORMAT_ARGB2101010";
208 case TBM_FORMAT_ABGR2101010:
209 return "TBM_FORMAT_ABGR2101010";
210 case TBM_FORMAT_RGBA1010102:
211 return "TBM_FORMAT_RGBA1010102";
212 case TBM_FORMAT_BGRA1010102:
213 return "TBM_FORMAT_BGRA1010102";
214 case TBM_FORMAT_YUYV:
215 return "TBM_FORMAT_YUYV";
216 case TBM_FORMAT_YVYU:
217 return "TBM_FORMAT_YVYU";
218 case TBM_FORMAT_UYVY:
219 return "TBM_FORMAT_UYVY";
220 case TBM_FORMAT_VYUY:
221 return "TBM_FORMAT_VYUY";
222 case TBM_FORMAT_AYUV:
223 return "TBM_FORMAT_AYUV";
224 case TBM_FORMAT_NV12:
225 return "TBM_FORMAT_NV12";
226 case TBM_FORMAT_NV21:
227 return "TBM_FORMAT_NV21";
228 case TBM_FORMAT_NV16:
229 return "TBM_FORMAT_NV16";
230 case TBM_FORMAT_NV61:
231 return "TBM_FORMAT_NV61";
232 case TBM_FORMAT_YUV410:
233 return "TBM_FORMAT_YUV410";
234 case TBM_FORMAT_YVU410:
235 return "TBM_FORMAT_YVU410";
236 case TBM_FORMAT_YUV411:
237 return "TBM_FORMAT_YUV411";
238 case TBM_FORMAT_YVU411:
239 return "TBM_FORMAT_YVU411";
240 case TBM_FORMAT_YUV420:
241 return "TBM_FORMAT_YUV420";
242 case TBM_FORMAT_YVU420:
243 return "TBM_FORMAT_YVU420";
244 case TBM_FORMAT_YUV422:
245 return "TBM_FORMAT_YUV422";
246 case TBM_FORMAT_YVU422:
247 return "TBM_FORMAT_YVU422";
248 case TBM_FORMAT_YUV444:
249 return "TBM_FORMAT_YUV444";
250 case TBM_FORMAT_YVU444:
251 return "TBM_FORMAT_YVU444";
252 case TBM_FORMAT_NV12MT:
253 return "TBM_FORMAT_NV12MT";
260 _tbm_surface_mutex_lock(void)
262 pthread_mutex_lock(&tbm_surface_lock);
266 _tbm_surface_mutex_unlock(void)
268 pthread_mutex_unlock(&tbm_surface_lock);
272 _init_surface_bufmgr(void)
274 g_surface_bufmgr = tbm_bufmgr_init(-1);
278 _deinit_surface_bufmgr(void)
280 if (!g_surface_bufmgr)
283 tbm_bufmgr_deinit(g_surface_bufmgr);
284 g_surface_bufmgr = NULL;
289 _tbm_surface_internal_magic_check(tbm_surface_h surface)
291 if (surface->magic != TBM_SURFACE_MAGIC)
298 _tbm_surface_internal_is_valid(tbm_surface_h surface)
301 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
302 TBM_ERR("error: No valid tbm_surface is NULL\n");
306 if (!_tbm_surface_internal_magic_check(surface)) {
307 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
308 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
316 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
317 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
319 TBM_RETURN_VAL_IF_FAIL(surface, 0);
320 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
322 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
323 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
326 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
327 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
328 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
329 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
331 error = tbm_module_get_plane_data(bufmgr->module, surf->info.format, plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
332 if (error != TBM_ERROR_NONE) {
333 _tbm_set_last_result(error);
341 _tbm_surface_internal_destroy(tbm_surface_h surface)
344 tbm_bufmgr bufmgr = surface->bufmgr;
345 tbm_user_data *old_data = NULL, *tmp = NULL;
346 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
347 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
349 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
350 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
351 func_info->destroy_func(surface, func_info->user_data);
353 TBM_DBG("free destroy_funcs %p\n", surface);
354 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
355 LIST_DEL(&func_info->item_link);
360 /* destory the user_data_list */
361 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
362 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
363 TBM_DBG("free user_data\n");
364 user_data_delete(old_data);
368 for (i = 0; i < surface->num_bos; i++) {
369 surface->bos[i]->surface = NULL;
371 tbm_bo_unref(surface->bos[i]);
372 surface->bos[i] = NULL;
375 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
376 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
377 _tbm_surface_internal_debug_data_delete(debug_old_data);
380 LIST_DEL(&surface->item_link);
383 if (surface->surface_data) {
384 tbm_surface_data_free(surface->surface_data);
385 surface->surface_data = NULL;
391 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
392 LIST_DELINIT(&bufmgr->surf_list);
394 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
395 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
396 _tbm_surface_internal_debug_data_delete(debug_old_data);
400 _deinit_surface_bufmgr();
404 /* LCOV_EXCL_START */
406 _tbm_surface_check_file_is_symbolic_link(const char* path)
413 if (stat(path, &sb) != 0)
416 if (S_ISLNK(sb.st_mode))
424 _tbm_surface_internal_get_num_planes(tbm_format format)
430 case TBM_FORMAT_RGB332:
431 case TBM_FORMAT_BGR233:
432 case TBM_FORMAT_XRGB4444:
433 case TBM_FORMAT_XBGR4444:
434 case TBM_FORMAT_RGBX4444:
435 case TBM_FORMAT_BGRX4444:
436 case TBM_FORMAT_ARGB4444:
437 case TBM_FORMAT_ABGR4444:
438 case TBM_FORMAT_RGBA4444:
439 case TBM_FORMAT_BGRA4444:
440 case TBM_FORMAT_XRGB1555:
441 case TBM_FORMAT_XBGR1555:
442 case TBM_FORMAT_RGBX5551:
443 case TBM_FORMAT_BGRX5551:
444 case TBM_FORMAT_ARGB1555:
445 case TBM_FORMAT_ABGR1555:
446 case TBM_FORMAT_RGBA5551:
447 case TBM_FORMAT_BGRA5551:
448 case TBM_FORMAT_RGB565:
449 case TBM_FORMAT_BGR565:
450 case TBM_FORMAT_RGB888:
451 case TBM_FORMAT_BGR888:
452 case TBM_FORMAT_XRGB8888:
453 case TBM_FORMAT_XBGR8888:
454 case TBM_FORMAT_RGBX8888:
455 case TBM_FORMAT_BGRX8888:
456 case TBM_FORMAT_ARGB8888:
457 case TBM_FORMAT_ABGR8888:
458 case TBM_FORMAT_RGBA8888:
459 case TBM_FORMAT_BGRA8888:
460 case TBM_FORMAT_XRGB2101010:
461 case TBM_FORMAT_XBGR2101010:
462 case TBM_FORMAT_RGBX1010102:
463 case TBM_FORMAT_BGRX1010102:
464 case TBM_FORMAT_ARGB2101010:
465 case TBM_FORMAT_ABGR2101010:
466 case TBM_FORMAT_RGBA1010102:
467 case TBM_FORMAT_BGRA1010102:
468 case TBM_FORMAT_YUYV:
469 case TBM_FORMAT_YVYU:
470 case TBM_FORMAT_UYVY:
471 case TBM_FORMAT_VYUY:
472 case TBM_FORMAT_AYUV:
475 case TBM_FORMAT_NV12:
476 case TBM_FORMAT_NV12MT:
477 case TBM_FORMAT_NV21:
478 case TBM_FORMAT_NV16:
479 case TBM_FORMAT_NV61:
482 case TBM_FORMAT_YUV410:
483 case TBM_FORMAT_YVU410:
484 case TBM_FORMAT_YUV411:
485 case TBM_FORMAT_YVU411:
486 case TBM_FORMAT_YUV420:
487 case TBM_FORMAT_YVU420:
488 case TBM_FORMAT_YUV422:
489 case TBM_FORMAT_YVU422:
490 case TBM_FORMAT_YUV444:
491 case TBM_FORMAT_YVU444:
496 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
504 _tbm_surface_internal_get_bpp(tbm_format format)
511 case TBM_FORMAT_RGB332:
512 case TBM_FORMAT_BGR233:
515 case TBM_FORMAT_XRGB4444:
516 case TBM_FORMAT_XBGR4444:
517 case TBM_FORMAT_RGBX4444:
518 case TBM_FORMAT_BGRX4444:
519 case TBM_FORMAT_ARGB4444:
520 case TBM_FORMAT_ABGR4444:
521 case TBM_FORMAT_RGBA4444:
522 case TBM_FORMAT_BGRA4444:
523 case TBM_FORMAT_XRGB1555:
524 case TBM_FORMAT_XBGR1555:
525 case TBM_FORMAT_RGBX5551:
526 case TBM_FORMAT_BGRX5551:
527 case TBM_FORMAT_ARGB1555:
528 case TBM_FORMAT_ABGR1555:
529 case TBM_FORMAT_RGBA5551:
530 case TBM_FORMAT_BGRA5551:
531 case TBM_FORMAT_RGB565:
532 case TBM_FORMAT_BGR565:
535 case TBM_FORMAT_RGB888:
536 case TBM_FORMAT_BGR888:
539 case TBM_FORMAT_XRGB8888:
540 case TBM_FORMAT_XBGR8888:
541 case TBM_FORMAT_RGBX8888:
542 case TBM_FORMAT_BGRX8888:
543 case TBM_FORMAT_ARGB8888:
544 case TBM_FORMAT_ABGR8888:
545 case TBM_FORMAT_RGBA8888:
546 case TBM_FORMAT_BGRA8888:
547 case TBM_FORMAT_XRGB2101010:
548 case TBM_FORMAT_XBGR2101010:
549 case TBM_FORMAT_RGBX1010102:
550 case TBM_FORMAT_BGRX1010102:
551 case TBM_FORMAT_ARGB2101010:
552 case TBM_FORMAT_ABGR2101010:
553 case TBM_FORMAT_RGBA1010102:
554 case TBM_FORMAT_BGRA1010102:
555 case TBM_FORMAT_YUYV:
556 case TBM_FORMAT_YVYU:
557 case TBM_FORMAT_UYVY:
558 case TBM_FORMAT_VYUY:
559 case TBM_FORMAT_AYUV:
562 case TBM_FORMAT_NV12:
563 case TBM_FORMAT_NV12MT:
564 case TBM_FORMAT_NV21:
567 case TBM_FORMAT_NV16:
568 case TBM_FORMAT_NV61:
571 case TBM_FORMAT_YUV410:
572 case TBM_FORMAT_YVU410:
575 case TBM_FORMAT_YUV411:
576 case TBM_FORMAT_YVU411:
577 case TBM_FORMAT_YUV420:
578 case TBM_FORMAT_YVU420:
581 case TBM_FORMAT_YUV422:
582 case TBM_FORMAT_YVU422:
585 case TBM_FORMAT_YUV444:
586 case TBM_FORMAT_YVU444:
590 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
598 _tbm_surface_internal_free(struct _tbm_surface *surf)
606 static struct _tbm_surface *
607 _tbm_surface_internal_alloc(tbm_bufmgr bufmgr, int width, int height, int format, tbm_error_e *error)
609 struct _tbm_surface *surf = NULL;
611 surf = calloc(1, sizeof(struct _tbm_surface));
613 /* LCOV_EXCL_START */
614 TBM_ERR("memory allocation failed.");
615 *error = TBM_ERROR_OUT_OF_MEMORY;
621 surf->magic = TBM_SURFACE_MAGIC;
622 surf->bufmgr = bufmgr;
623 surf->info.width = width;
624 surf->info.height = height;
625 surf->info.format = format;
626 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
627 if (!surf->info.bpp) {
628 /* LCOV_EXCL_START */
629 TBM_ERR("_tbm_surface_internal_get_bpp failed. format:%d error:%s", format, tbm_error_str(*error));
630 *error = tbm_get_last_error();
636 // get number of planes
637 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
638 if (!surf->info.num_planes) {
639 /* LCOV_EXCL_START */
640 TBM_ERR("_tbm_surface_internal_get_num_planes failed. format:%d error:%s", format, tbm_error_str(*error));
641 *error = tbm_get_last_error();
651 _tbm_surface_internal_set_data(struct _tbm_surface *surf, int flags, int is_surface_data)
654 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;;
656 tbm_bo_data **bo_data_array = NULL;
660 // set data with surface
661 if (is_surface_data) {
662 // set infomation of planes
663 for (i = 0; i < surf->info.num_planes; i++) {
664 error = tbm_surface_data_get_plane_data(surf->surface_data, i, &size, &offset, &stride, &bo_idx);
665 if (error != TBM_ERROR_NONE) {
666 TBM_ERR("tbm_surface_data_get_plane_data failed. error:%s", tbm_error_str(error));
670 surf->info.planes[i].size = size;
671 surf->info.planes[i].offset = offset;
672 surf->info.planes[i].stride = stride;
673 surf->planes_bo_idx[i] = bo_idx;
676 // calculate the size of a surface
677 for (i = 0; i < surf->info.num_planes; i++)
678 surf->info.size += surf->info.planes[i].size;
680 // get the bo_data_array
681 bo_data_array = tbm_surface_data_get_bo_data_array(surf->surface_data, &num_bos, &memory_types, &error);
682 if (!bo_data_array) {
683 TBM_ERR("tbm_surface_data_get_bo_data_array failed. error:%s", tbm_error_str(error));
688 surf->num_bos = num_bos;
691 surf->flags = memory_types;
693 // allocate the array of tbm_bos
694 for (i = 0; i < num_bos; i++) {
695 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_bo_data(surf->bufmgr, bo_data_array[i], memory_types, &error);
697 TBM_ERR("tbm_bufmgr_internal_alloc_bo_with_bo_data failed. error:%s idx:%d", tbm_error_str(error), i);
701 _tbm_bo_set_surface(surf->bos[i], surf);
704 // only free the pointers of the arrary, not the item(tbm_bo_data).
705 // the item(tbm_bo_data) is set to the tbm_bo. tbm_bo handles the life cycle of the tbm_bo_data.
708 // set infomation of planes
709 for (i = 0; i < surf->info.num_planes; i++) {
710 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
711 TBM_ERR("_tbm_surface_internal_query_plane_data failed.");
712 error = tbm_get_last_error();
716 surf->info.planes[i].size = size;
717 surf->info.planes[i].offset = offset;
718 surf->info.planes[i].stride = stride;
719 surf->planes_bo_idx[i] = bo_idx;
722 // calculate the number of bos
724 for (i = 0; i < surf->info.num_planes; i++) {
725 surf->info.size += surf->info.planes[i].size;
727 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
728 surf->num_bos = surf->planes_bo_idx[i] + 1;
734 // allocate the array of tbm_bos
735 for (i = 0; i < surf->num_bos; i++) {
737 for (j = 0; j < surf->info.num_planes; j++) {
738 if (surf->planes_bo_idx[j] == i)
739 bo_size += surf->info.planes[j].size;
742 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_format(surf->bufmgr,
743 surf->info.format, i, surf->info.width, surf->info.height,
744 surf->info.bpp/8, flags, &error);
746 surf->bos[i] = tbm_bo_alloc(surf->bufmgr, bo_size, flags);
748 TBM_ERR("tbm_bo_alloc failed. idx:%d", i);
749 error = tbm_get_last_error();
754 _tbm_bo_set_surface(surf->bos[i], surf);
758 return TBM_ERROR_NONE;
761 if (is_surface_data) {
762 for (j = 0; j < num_bos; j++) {
763 if (bo_data_array[j]) {
764 free(bo_data_array[j]);
771 for (j = 0; j < i; j++) {
773 tbm_bo_unref(surf->bos[j]);
779 static struct _tbm_surface *
780 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
782 struct _tbm_surface *surf;
783 int is_surface_data = 0;
785 surf = _tbm_surface_internal_alloc(bufmgr, width, height, format, error);
787 /* LCOV_EXCL_START */
788 TBM_ERR("_tbm_surface_internal_alloc failed.");
793 is_surface_data = tbm_module_support_surface_data(bufmgr->module);
794 if (is_surface_data) {
795 // alloc surface_data
796 surf->surface_data = tbm_module_alloc_surface_data(bufmgr->module, width, height, format, flags, error);
797 if (!surf->surface_data) {
798 TBM_ERR("tbm_module_alloc_surface_data failed. width:%d height:%d format:%d error:%s",
799 width, height, format, tbm_error_str(*error));
800 _tbm_surface_internal_free(surf);
805 // set the surface data
806 *error = _tbm_surface_internal_set_data(surf, flags, is_surface_data);
807 if (*error != TBM_ERROR_NONE) {
808 tbm_surface_data_free(surf->surface_data);
809 surf->surface_data = NULL;
810 _tbm_surface_internal_free(surf);
817 static struct _tbm_surface *
818 _tbm_surface_internal_import_surface(tbm_bufmgr bufmgr, int width, int height, int format, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
820 struct _tbm_surface *surf = NULL;
822 surf = _tbm_surface_internal_alloc(bufmgr, width, height, format, error);
824 /* LCOV_EXCL_START */
825 TBM_ERR("_tbm_surface_internal_alloc failed.");
830 // import surface_data
831 surf->surface_data = tbm_module_import_surface_data(bufmgr->module, width, height, format, buffer_data, error);
832 if (!surf->surface_data) {
833 /* LCOV_EXCL_START */
834 TBM_ERR("tbm_module_import_surface_data failed. width:%d height:%d format:%d error:%s",
835 width, height, format, tbm_error_str(*error));
836 _tbm_surface_internal_free(surf);
841 // set the surface data
842 *error = _tbm_surface_internal_set_data(surf, TBM_BO_DEFAULT, 1);
843 if (*error != TBM_ERROR_NONE) {
844 /* LCOV_EXCL_START */
845 tbm_surface_data_free(surf->surface_data);
846 surf->surface_data = NULL;
847 _tbm_surface_internal_free(surf);
856 tbm_surface_internal_is_valid(tbm_surface_h surface)
860 _tbm_surface_mutex_lock();
861 _tbm_set_last_result(TBM_ERROR_NONE);
863 /* Return silently if surface is null. */
865 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
866 _tbm_surface_mutex_unlock();
870 ret = _tbm_surface_internal_is_valid(surface);
872 _tbm_surface_mutex_unlock();
878 tbm_surface_internal_query_supported_formats(uint32_t **formats,
881 struct _tbm_bufmgr *bufmgr;
882 bool bufmgr_initialized = false;
885 _tbm_surface_mutex_lock();
886 _tbm_set_last_result(TBM_ERROR_NONE);
888 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
889 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
891 if (!g_surface_bufmgr) {
892 _init_surface_bufmgr();
893 if (!g_surface_bufmgr) {
894 TBM_ERR("fail bufmgr initialization\n");
895 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
898 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
899 bufmgr_initialized = true;
902 bufmgr = g_surface_bufmgr;
904 error = tbm_module_get_supported_formats(bufmgr->module, formats, num);
905 if (error != TBM_ERROR_NONE) {
906 _tbm_set_last_result(error);
910 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
912 if (bufmgr_initialized) {
913 LIST_DELINIT(&g_surface_bufmgr->surf_list);
914 _deinit_surface_bufmgr();
917 _tbm_surface_mutex_unlock();
921 /* LCOV_EXCL_START */
923 if (bufmgr_initialized) {
924 LIST_DELINIT(&g_surface_bufmgr->surf_list);
925 _deinit_surface_bufmgr();
927 _tbm_surface_mutex_unlock();
929 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
936 tbm_surface_internal_get_num_planes(tbm_format format)
940 _tbm_surface_mutex_lock();
941 _tbm_set_last_result(TBM_ERROR_NONE);
943 num_planes = _tbm_surface_internal_get_num_planes(format);
945 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
946 _tbm_surface_mutex_unlock();
950 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
952 _tbm_surface_mutex_unlock();
958 tbm_surface_internal_get_bpp(tbm_format format)
962 _tbm_surface_mutex_lock();
963 _tbm_set_last_result(TBM_ERROR_NONE);
965 bpp = _tbm_surface_internal_get_bpp(format);
967 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
968 _tbm_surface_mutex_unlock();
972 _tbm_surface_mutex_unlock();
974 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
980 tbm_surface_internal_create_with_flags(int width, int height,
981 int format, int flags)
983 struct _tbm_bufmgr *bufmgr;
984 struct _tbm_surface *surf = NULL;
985 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
986 bool bufmgr_initialized = false;
988 _tbm_surface_mutex_lock();
989 _tbm_set_last_result(TBM_ERROR_NONE);
991 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
992 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
994 if (!g_surface_bufmgr) {
995 _init_surface_bufmgr();
996 if (!g_surface_bufmgr) {
997 TBM_ERR("fail bufmgr initialization\n");
998 error = TBM_ERROR_INVALID_OPERATION;
999 goto check_valid_fail;
1001 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1002 bufmgr_initialized = true;
1005 bufmgr = g_surface_bufmgr;
1006 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1007 TBM_ERR("The bufmgr is invalid\n");
1008 error = TBM_ERROR_INVALID_PARAMETER;
1009 goto check_valid_fail;
1012 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1014 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1015 goto surface_alloc_fail;
1018 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1019 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1021 LIST_INITHEAD(&surf->user_data_list);
1022 LIST_INITHEAD(&surf->debug_data_list);
1023 LIST_INITHEAD(&surf->destroy_funcs);
1025 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1027 _tbm_set_last_result(error);
1028 _tbm_surface_mutex_unlock();
1032 /* LCOV_EXCL_START */
1036 if (bufmgr_initialized && bufmgr) {
1037 LIST_DELINIT(&bufmgr->surf_list);
1038 _deinit_surface_bufmgr();
1041 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1042 width, height, _tbm_surface_internal_format_to_str(format), flags);
1044 _tbm_set_last_result(error);
1045 _tbm_surface_mutex_unlock();
1047 /* LCOV_EXCL_STOP */
1053 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1054 tbm_bo *bos, int num)
1056 struct _tbm_bufmgr *bufmgr;
1057 struct _tbm_surface *surf = NULL;
1059 bool bufmgr_initialized = false;
1061 _tbm_surface_mutex_lock();
1062 _tbm_set_last_result(TBM_ERROR_NONE);
1064 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1065 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1066 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1067 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1068 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1070 if (!g_surface_bufmgr) {
1071 _init_surface_bufmgr();
1072 if (!g_surface_bufmgr) {
1073 TBM_ERR("fail bufmgr initialization\n");
1074 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1075 goto check_valid_fail;
1077 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1078 bufmgr_initialized = true;
1081 bufmgr = g_surface_bufmgr;
1082 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1083 TBM_ERR("fail to validate the Bufmgr.\n");
1084 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1085 goto check_valid_fail;
1088 surf = calloc(1, sizeof(struct _tbm_surface));
1090 /* LCOV_EXCL_START */
1091 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1092 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1093 goto alloc_surf_fail;
1094 /* LCOV_EXCL_STOP */
1097 surf->magic = TBM_SURFACE_MAGIC;
1098 surf->bufmgr = bufmgr;
1099 surf->info.width = info->width;
1100 surf->info.height = info->height;
1101 surf->info.format = info->format;
1103 surf->info.bpp = info->bpp;
1105 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1106 if (!surf->info.bpp) {
1107 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1111 surf->info.num_planes = info->num_planes;
1114 /* get size, stride and offset */
1115 for (i = 0; i < info->num_planes; i++) {
1116 surf->info.planes[i].offset = info->planes[i].offset;
1117 surf->info.planes[i].stride = info->planes[i].stride;
1119 if (info->planes[i].size > 0)
1120 surf->info.planes[i].size = info->planes[i].size;
1122 uint32_t size = 0, offset = 0, stride = 0;
1125 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1126 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1127 goto plane_data_fail;
1129 surf->info.planes[i].size = size;
1133 surf->planes_bo_idx[i] = 0;
1135 surf->planes_bo_idx[i] = i;
1138 if (info->size > 0) {
1139 surf->info.size = info->size;
1141 surf->info.size = 0;
1142 for (i = 0; i < info->num_planes; i++)
1143 surf->info.size += surf->info.planes[i].size;
1146 surf->flags = TBM_BO_DEFAULT;
1148 /* create only one bo */
1149 surf->num_bos = num;
1150 for (i = 0; i < num; i++) {
1151 if (bos[i] == NULL) {
1152 TBM_ERR("bos[%d] is null.\n", i);
1153 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1157 surf->bos[i] = tbm_bo_ref(bos[i]);
1158 _tbm_bo_set_surface(bos[i], surf);
1161 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1162 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1164 LIST_INITHEAD(&surf->user_data_list);
1165 LIST_INITHEAD(&surf->debug_data_list);
1166 LIST_INITHEAD(&surf->destroy_funcs);
1168 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1170 _tbm_surface_mutex_unlock();
1174 /* LCOV_EXCL_START */
1178 for (i = 0; i < num; i++) {
1180 tbm_bo_unref(surf->bos[i]);
1185 if (bufmgr_initialized && bufmgr) {
1186 LIST_DELINIT(&bufmgr->surf_list);
1187 _deinit_surface_bufmgr();
1189 _tbm_surface_mutex_unlock();
1191 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1192 info->width, info->height,
1193 _tbm_surface_internal_format_to_str(info->format), num);
1194 /* LCOV_EXCL_STOP */
1200 tbm_surface_internal_destroy(tbm_surface_h surface)
1202 _tbm_surface_mutex_lock();
1203 _tbm_set_last_result(TBM_ERROR_NONE);
1205 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1209 if (surface->refcnt > 0) {
1210 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1211 _tbm_surface_mutex_unlock();
1215 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1217 if (surface->refcnt == 0)
1218 _tbm_surface_internal_destroy(surface);
1219 else // if (surface->refcnt < 0)
1220 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1222 _tbm_surface_mutex_unlock();
1226 tbm_surface_internal_ref(tbm_surface_h surface)
1228 _tbm_surface_mutex_lock();
1229 _tbm_set_last_result(TBM_ERROR_NONE);
1231 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1235 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1237 _tbm_surface_mutex_unlock();
1241 tbm_surface_internal_unref(tbm_surface_h surface)
1243 _tbm_surface_mutex_lock();
1244 _tbm_set_last_result(TBM_ERROR_NONE);
1246 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1250 if (surface->refcnt > 0) {
1251 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1252 _tbm_surface_mutex_unlock();
1256 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1258 if (surface->refcnt == 0)
1259 _tbm_surface_internal_destroy(surface);
1261 _tbm_surface_mutex_unlock();
1265 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1267 struct _tbm_surface *surf;
1270 _tbm_surface_mutex_lock();
1271 _tbm_set_last_result(TBM_ERROR_NONE);
1273 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1275 surf = (struct _tbm_surface *)surface;
1276 num = surf->num_bos;
1279 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1281 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1283 _tbm_surface_mutex_unlock();
1289 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1291 struct _tbm_surface *surf;
1294 _tbm_surface_mutex_lock();
1295 _tbm_set_last_result(TBM_ERROR_NONE);
1297 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1298 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1300 surf = (struct _tbm_surface *)surface;
1301 bo = surf->bos[bo_idx];
1303 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1305 _tbm_surface_mutex_unlock();
1311 tbm_surface_internal_get_size(tbm_surface_h surface)
1313 struct _tbm_surface *surf;
1316 _tbm_surface_mutex_lock();
1317 _tbm_set_last_result(TBM_ERROR_NONE);
1319 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1321 surf = (struct _tbm_surface *)surface;
1322 size = surf->info.size;
1324 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1326 _tbm_surface_mutex_unlock();
1332 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1333 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1335 struct _tbm_surface *surf;
1337 _tbm_surface_mutex_lock();
1338 _tbm_set_last_result(TBM_ERROR_NONE);
1340 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1341 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1343 surf = (struct _tbm_surface *)surface;
1345 if (plane_idx >= surf->info.num_planes) {
1346 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1347 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1348 _tbm_surface_mutex_unlock();
1353 *size = surf->info.planes[plane_idx].size;
1356 *offset = surf->info.planes[plane_idx].offset;
1359 *pitch = surf->info.planes[plane_idx].stride;
1361 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1362 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1363 surf->info.planes[plane_idx].stride);
1365 _tbm_surface_mutex_unlock();
1371 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1372 tbm_surface_info_s *info, int map)
1374 struct _tbm_surface *surf;
1375 tbm_bo_handle bo_handles[4];
1378 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1381 _tbm_surface_mutex_lock();
1382 _tbm_set_last_result(TBM_ERROR_NONE);
1384 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1386 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1388 surf = (struct _tbm_surface *)surface;
1390 memset(info, 0x00, sizeof(tbm_surface_info_s));
1391 info->width = surf->info.width;
1392 info->height = surf->info.height;
1393 info->format = surf->info.format;
1394 info->bpp = surf->info.bpp;
1395 info->size = surf->info.size;
1396 info->num_planes = surf->info.num_planes;
1398 for (i = 0; i < surf->info.num_planes; i++) {
1399 info->planes[i].size = surf->info.planes[i].size;
1400 info->planes[i].offset = surf->info.planes[i].offset;
1401 info->planes[i].stride = surf->info.planes[i].stride;
1402 planes_bo_idx[i] = surf->planes_bo_idx[i];
1405 for (i = 0; i < surf->num_bos; i++)
1406 bos[i] = surf->bos[i];
1408 num_bos = surf->num_bos;
1411 _tbm_surface_mutex_unlock();
1412 for (i = 0; i < num_bos; i++) {
1413 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1414 if (bo_handles[i].ptr == NULL) {
1415 for (j = 0; j < i; j++)
1416 tbm_bo_unmap(bos[j]);
1418 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1422 _tbm_surface_mutex_lock();
1424 for (i = 0; i < num_bos; i++) {
1425 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1426 if (bo_handles[i].ptr == NULL) {
1427 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1428 _tbm_surface_mutex_unlock();
1434 for (i = 0; i < info->num_planes; i++) {
1435 if (bo_handles[planes_bo_idx[i]].ptr)
1436 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1439 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1441 _tbm_surface_mutex_unlock();
1447 tbm_surface_internal_unmap(tbm_surface_h surface)
1449 struct _tbm_surface *surf;
1452 _tbm_surface_mutex_lock();
1453 _tbm_set_last_result(TBM_ERROR_NONE);
1455 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1457 surf = (struct _tbm_surface *)surface;
1459 for (i = 0; i < surf->num_bos; i++)
1460 tbm_bo_unmap(surf->bos[i]);
1462 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1464 _tbm_surface_mutex_unlock();
1468 tbm_surface_internal_get_width(tbm_surface_h surface)
1470 struct _tbm_surface *surf;
1473 _tbm_surface_mutex_lock();
1474 _tbm_set_last_result(TBM_ERROR_NONE);
1476 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1478 surf = (struct _tbm_surface *)surface;
1479 width = surf->info.width;
1481 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1483 _tbm_surface_mutex_unlock();
1489 tbm_surface_internal_get_height(tbm_surface_h surface)
1491 struct _tbm_surface *surf;
1492 unsigned int height;
1494 _tbm_surface_mutex_lock();
1495 _tbm_set_last_result(TBM_ERROR_NONE);
1497 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1499 surf = (struct _tbm_surface *)surface;
1500 height = surf->info.height;
1502 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1504 _tbm_surface_mutex_unlock();
1511 tbm_surface_internal_get_format(tbm_surface_h surface)
1513 struct _tbm_surface *surf;
1516 _tbm_surface_mutex_lock();
1517 _tbm_set_last_result(TBM_ERROR_NONE);
1519 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1521 surf = (struct _tbm_surface *)surface;
1522 format = surf->info.format;
1524 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1526 _tbm_surface_mutex_unlock();
1532 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1534 struct _tbm_surface *surf;
1537 _tbm_surface_mutex_lock();
1538 _tbm_set_last_result(TBM_ERROR_NONE);
1540 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1541 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1543 surf = (struct _tbm_surface *)surface;
1544 bo_idx = surf->planes_bo_idx[plane_idx];
1546 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1548 _tbm_surface_mutex_unlock();
1554 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1555 tbm_data_free data_free_func)
1557 tbm_user_data *data;
1559 _tbm_surface_mutex_lock();
1560 _tbm_set_last_result(TBM_ERROR_NONE);
1562 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1564 /* check if the data according to the key exist if so, return false. */
1565 data = user_data_lookup(&surface->user_data_list, key);
1567 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1568 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1569 _tbm_surface_mutex_unlock();
1573 data = user_data_create(key, data_free_func);
1575 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1576 _tbm_surface_mutex_unlock();
1580 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1582 LIST_ADD(&data->item_link, &surface->user_data_list);
1584 _tbm_surface_mutex_unlock();
1590 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1593 tbm_user_data *old_data;
1595 _tbm_surface_mutex_lock();
1596 _tbm_set_last_result(TBM_ERROR_NONE);
1598 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1600 old_data = user_data_lookup(&surface->user_data_list, key);
1602 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1603 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1604 _tbm_surface_mutex_unlock();
1608 if (old_data->data && old_data->free_func)
1609 old_data->free_func(old_data->data);
1611 old_data->data = data;
1613 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1615 _tbm_surface_mutex_unlock();
1621 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1624 tbm_user_data *old_data;
1626 _tbm_surface_mutex_lock();
1627 _tbm_set_last_result(TBM_ERROR_NONE);
1629 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1632 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1633 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1634 _tbm_surface_mutex_unlock();
1639 old_data = user_data_lookup(&surface->user_data_list, key);
1641 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1642 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1643 _tbm_surface_mutex_unlock();
1647 *data = old_data->data;
1649 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1651 _tbm_surface_mutex_unlock();
1657 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1660 tbm_user_data *old_data = (void *)0;
1662 _tbm_surface_mutex_lock();
1663 _tbm_set_last_result(TBM_ERROR_NONE);
1665 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1667 old_data = user_data_lookup(&surface->user_data_list, key);
1669 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1670 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1671 _tbm_surface_mutex_unlock();
1675 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1677 user_data_delete(old_data);
1679 _tbm_surface_mutex_unlock();
1684 /* LCOV_EXCL_START */
1686 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1688 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1690 return surface->debug_pid;
1694 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1696 _tbm_surface_mutex_lock();
1697 _tbm_set_last_result(TBM_ERROR_NONE);
1699 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1701 surface->debug_pid = pid;
1703 _tbm_surface_mutex_unlock();
1706 static tbm_surface_debug_data *
1707 _tbm_surface_internal_debug_data_create(char *key, char *value)
1709 tbm_surface_debug_data *debug_data = NULL;
1711 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1713 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1714 TBM_ERR("fail to allocate the debug_data.");
1718 if (key) debug_data->key = strdup(key);
1719 if (value) debug_data->value = strdup(value);
1725 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1727 if (!debug_data->value && !value)
1730 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1733 if (debug_data->value)
1734 free(debug_data->value);
1737 debug_data->value = strdup(value);
1739 debug_data->value = NULL;
1742 static tbm_surface_debug_data *
1743 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1745 tbm_surface_debug_data *debug_data = NULL;
1747 if (LIST_IS_EMPTY(list))
1750 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1751 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1759 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1761 tbm_surface_debug_data *debug_data = NULL;
1762 tbm_bufmgr bufmgr = NULL;
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);
1768 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1770 bufmgr = surface->bufmgr;
1772 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1774 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1776 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1778 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1780 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1781 _tbm_surface_mutex_unlock();
1785 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1788 /* add new debug key to list */
1789 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1791 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1793 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1796 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1798 _tbm_surface_mutex_unlock();
1804 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1806 tbm_surface_debug_data *old_data = NULL;
1808 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1810 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1811 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1812 if (!strcmp(old_data->key, key))
1813 return old_data->value;
1820 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1821 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1823 struct _tbm_surface_dump_buf_info {
1833 tbm_surface_info_s info;
1835 struct list_head link;
1838 struct _tbm_surface_dump_info {
1839 char *path; // copy???
1842 struct list_head *link;
1843 struct list_head surface_list; /* link of surface */
1846 static tbm_surface_dump_info *g_dump_info = NULL;
1847 static const char *dump_postfix[2] = {"png", "yuv"};
1848 static double scale_factor;
1851 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1852 void *data2, int size2, void *data3, int size3)
1855 unsigned int *blocks;
1857 if (_tbm_surface_check_file_is_symbolic_link(file))
1858 TBM_ERR("%s is symbolic link\n", file);
1860 fp = fopen(file, "w+");
1861 TBM_RETURN_IF_FAIL(fp != NULL);
1863 blocks = (unsigned int *)data1;
1864 fwrite(blocks, 1, size1, fp);
1867 blocks = (unsigned int *)data2;
1868 fwrite(blocks, 1, size2, fp);
1872 blocks = (unsigned int *)data3;
1873 fwrite(blocks, 1, size3, fp);
1880 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1882 unsigned int *blocks = (unsigned int *)data;
1885 png_bytep *row_pointers;
1888 if (_tbm_surface_check_file_is_symbolic_link(file))
1889 TBM_ERR("%s is symbolic link\n", file);
1891 fp = fopen(file, "wb");
1892 TBM_RETURN_IF_FAIL(fp != NULL);
1894 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1897 TBM_ERR("fail to create a png write structure.\n");
1902 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1904 TBM_ERR("fail to create a png info structure.\n");
1905 png_destroy_write_struct(&pPngStruct, NULL);
1910 if (setjmp(png_jmpbuf(pPngStruct))) {
1911 /* if png has problem of writing the file, we get here */
1912 TBM_ERR("fail to write png file.\n");
1913 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1918 png_init_io(pPngStruct, fp);
1919 if (format == TBM_FORMAT_XRGB8888) {
1921 png_set_IHDR(pPngStruct,
1928 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1931 png_set_IHDR(pPngStruct,
1936 PNG_COLOR_TYPE_RGBA,
1938 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1941 png_set_bgr(pPngStruct);
1942 png_write_info(pPngStruct, pPngInfo);
1944 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1945 if (!row_pointers) {
1946 TBM_ERR("fail to allocate the png row_pointers.\n");
1947 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1952 for (y = 0; y < height; ++y) {
1956 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1958 TBM_ERR("fail to allocate the png row.\n");
1959 for (x = 0; x < y; x++)
1960 png_free(pPngStruct, row_pointers[x]);
1961 png_free(pPngStruct, row_pointers);
1962 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1966 row_pointers[y] = (png_bytep)row;
1968 for (x = 0; x < width; ++x) {
1969 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1971 if (pixel_size == 3) { // XRGB8888 or XBGR8888
1972 if (format == TBM_FORMAT_XRGB8888) {
1973 row[x * pixel_size] = (curBlock & 0xFF);
1974 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1975 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1977 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
1978 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1979 row[2 + x * pixel_size] = (curBlock & 0xFF);
1981 } else { // ARGB8888 or ABGR8888
1982 if (format == TBM_FORMAT_ARGB8888) {
1983 row[x * pixel_size] = (curBlock & 0xFF);
1984 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1985 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1986 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1988 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
1989 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1990 row[2 + x * pixel_size] = (curBlock & 0xFF);
1991 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1997 png_write_image(pPngStruct, row_pointers);
1998 png_write_end(pPngStruct, pPngInfo);
2000 for (y = 0; y < height; y++)
2001 png_free(pPngStruct, row_pointers[y]);
2002 png_free(pPngStruct, row_pointers);
2004 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2010 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2012 TBM_RETURN_IF_FAIL(path != NULL);
2013 TBM_RETURN_IF_FAIL(w > 0);
2014 TBM_RETURN_IF_FAIL(h > 0);
2015 TBM_RETURN_IF_FAIL(count > 0);
2017 tbm_surface_dump_buf_info *buf_info = NULL;
2018 tbm_surface_h tbm_surface;
2019 tbm_surface_info_s info;
2024 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2028 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2029 TBM_RETURN_IF_FAIL(g_dump_info);
2031 LIST_INITHEAD(&g_dump_info->surface_list);
2032 g_dump_info->count = 0;
2033 g_dump_info->dump_max = count;
2035 /* get buffer size */
2036 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2037 if (tbm_surface == NULL) {
2038 TBM_ERR("tbm_surface_create fail\n");
2044 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2045 TBM_ERR("tbm_surface_get_info fail\n");
2046 tbm_surface_destroy(tbm_surface);
2051 buffer_size = info.size;
2052 tbm_surface_destroy(tbm_surface);
2054 /* create dump lists */
2055 for (i = 0; i < count; i++) {
2058 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2059 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2061 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2063 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2068 buf_info->index = i;
2070 buf_info->size = buffer_size;
2072 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2075 g_dump_info->path = path;
2076 g_dump_info->link = &g_dump_info->surface_list;
2080 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2085 /* free resources */
2086 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2087 tbm_surface_dump_buf_info *tmp;
2089 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2090 tbm_bo_unref(buf_info->bo);
2091 LIST_DEL(&buf_info->link);
2096 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2105 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2112 tbm_surface_internal_dump_start(path, w, h, count);
2113 scale_factor = scale;
2117 tbm_surface_internal_dump_end(void)
2119 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2120 tbm_bo_handle bo_handle;
2125 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2132 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2135 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2136 if (bo_handle.ptr == NULL) {
2137 tbm_bo_unref(buf_info->bo);
2138 LIST_DEL(&buf_info->link);
2143 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2144 TBM_INFO("Dump File.. %s generated.\n", file);
2146 if (buf_info->dirty) {
2147 void *ptr1 = NULL, *ptr2 = NULL;
2149 switch (buf_info->info.format) {
2150 case TBM_FORMAT_ARGB8888:
2151 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2152 buf_info->info.planes[0].stride >> 2,
2153 buf_info->info.height,
2154 buf_info->info.planes[0].stride,
2155 TBM_FORMAT_ARGB8888);
2157 case TBM_FORMAT_XRGB8888:
2158 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2159 buf_info->info.planes[0].stride >> 2,
2160 buf_info->info.height,
2161 buf_info->info.planes[0].stride,
2162 TBM_FORMAT_XRGB8888);
2164 case TBM_FORMAT_ABGR8888:
2165 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2166 buf_info->info.planes[0].stride >> 2,
2167 buf_info->info.height,
2168 buf_info->info.planes[0].stride,
2169 TBM_FORMAT_ABGR8888);
2171 case TBM_FORMAT_XBGR8888:
2172 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2173 buf_info->info.planes[0].stride >> 2,
2174 buf_info->info.height,
2175 buf_info->info.planes[0].stride,
2176 TBM_FORMAT_XBGR8888);
2178 case TBM_FORMAT_YVU420:
2179 case TBM_FORMAT_YUV420:
2180 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2181 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2182 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2183 buf_info->info.planes[0].stride * buf_info->info.height,
2185 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2187 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2189 case TBM_FORMAT_NV12:
2190 case TBM_FORMAT_NV21:
2191 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2192 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2193 buf_info->info.planes[0].stride * buf_info->info.height,
2195 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2198 case TBM_FORMAT_YUYV:
2199 case TBM_FORMAT_UYVY:
2200 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2201 buf_info->info.planes[0].stride * buf_info->info.height,
2205 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2208 } else if (buf_info->dirty_shm)
2209 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2210 buf_info->shm_stride >> 2,
2212 buf_info->shm_stride, 0);
2214 tbm_bo_unmap(buf_info->bo);
2215 tbm_bo_unref(buf_info->bo);
2216 LIST_DEL(&buf_info->link);
2223 TBM_INFO("Dump End..\n");
2226 static pixman_format_code_t
2227 _tbm_surface_internal_pixman_format_get(tbm_format format)
2230 case TBM_FORMAT_ARGB8888:
2231 case TBM_FORMAT_ABGR8888:
2232 return PIXMAN_a8r8g8b8;
2233 case TBM_FORMAT_XRGB8888:
2234 case TBM_FORMAT_XBGR8888:
2235 return PIXMAN_x8r8g8b8;
2244 * This function supports only if a buffer has below formats.
2245 * - TBM_FORMAT_ARGB8888
2246 * - TBM_FORMAT_XRGB8888
2247 * - TBM_FORMAT_ABGR8888
2248 * - TBM_FORMAT_XBGR8888
2250 static tbm_surface_error_e
2251 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2252 int format, int src_stride, int src_w, int src_h,
2253 int dst_stride, int dst_w, int dst_h)
2255 pixman_image_t *src_img = NULL, *dst_img = NULL;
2256 pixman_format_code_t pixman_format;
2257 pixman_transform_t t;
2258 struct pixman_f_transform ft;
2259 double scale_x, scale_y;
2261 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2262 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2264 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2265 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2268 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2269 (uint32_t*)src_ptr, src_stride);
2270 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2273 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2274 (uint32_t*)dst_ptr, dst_stride);
2275 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2277 pixman_f_transform_init_identity(&ft);
2279 scale_x = (double)src_w / dst_w;
2280 scale_y = (double)src_h / dst_h;
2282 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2283 pixman_f_transform_translate(&ft, NULL, 0, 0);
2284 pixman_transform_from_pixman_f_transform(&t, &ft);
2285 pixman_image_set_transform(src_img, &t);
2287 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2288 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2290 pixman_image_unref(src_img);
2291 pixman_image_unref(dst_img);
2293 return TBM_SURFACE_ERROR_NONE;
2297 pixman_image_unref(src_img);
2299 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2302 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2303 #define KEY_LEN 5 // "_XXXX"
2304 #define KEYS_LEN KEY_LEN * MAX_BOS
2306 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2308 char *keys, temp_key[KEY_LEN + 1];
2309 struct _tbm_surface *surf;
2313 _tbm_surface_mutex_lock();
2315 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2317 surf = (struct _tbm_surface *)surface;
2319 num_bos = surf->num_bos;
2320 if (num_bos > MAX_BOS)
2323 keys = calloc(KEYS_LEN + 1, sizeof(char));
2325 TBM_ERR("Failed to alloc memory");
2326 _tbm_surface_mutex_unlock();
2330 for (i = 0; i < num_bos; i++) {
2331 memset(temp_key, 0x00, KEY_LEN + 1);
2333 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2334 strncat(keys, temp_key, KEY_LEN + 1);
2337 _tbm_surface_mutex_unlock();
2342 static void _tbm_surface_internal_put_keys(char *keys)
2349 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2351 TBM_RETURN_IF_FAIL(surface != NULL);
2352 TBM_RETURN_IF_FAIL(type != NULL);
2354 tbm_surface_dump_buf_info *buf_info;
2355 struct list_head *next_link;
2356 tbm_surface_info_s info;
2357 tbm_bo_handle bo_handle;
2358 const char *postfix;
2359 const char *format = NULL;
2366 next_link = g_dump_info->link->next;
2367 TBM_RETURN_IF_FAIL(next_link != NULL);
2369 if (next_link == &g_dump_info->surface_list) {
2370 next_link = next_link->next;
2371 TBM_RETURN_IF_FAIL(next_link != NULL);
2374 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2375 TBM_RETURN_IF_FAIL(buf_info != NULL);
2377 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2378 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2380 if (scale_factor > 0.0) {
2383 if ((info.format != TBM_FORMAT_ARGB8888) && (info.format != TBM_FORMAT_XRGB8888) &&
2384 (info.format != TBM_FORMAT_ABGR8888) && (info.format != TBM_FORMAT_XBGR8888)) {
2385 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2386 _tbm_surface_internal_format_to_str(info.format));
2387 tbm_surface_unmap(surface);
2391 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2393 buf_info->info.width = info.width * scale_factor;
2394 buf_info->info.height = info.height * scale_factor;
2395 buf_info->info.format = info.format;
2396 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2397 if (!buf_info->info.bpp) {
2398 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2399 tbm_surface_unmap(surface);
2402 buf_info->info.num_planes = 1;
2403 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2404 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2406 if (buf_info->info.size > buf_info->size) {
2407 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2408 buf_info->info.size, buf_info->size);
2409 tbm_surface_unmap(surface);
2413 if (info.size > buf_info->size) {
2414 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2415 info.size, buf_info->size);
2416 tbm_surface_unmap(surface);
2420 /* make the file information */
2421 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2424 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2425 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888)) {
2426 postfix = dump_postfix[0];
2427 format = _tbm_surface_internal_format_to_str(info.format);
2429 postfix = dump_postfix[1];
2431 keys = _tbm_surface_internal_get_keys(surface);
2433 TBM_ERR("fail to get keys");
2434 tbm_surface_unmap(surface);
2439 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2440 if (!bo_handle.ptr) {
2441 TBM_ERR("fail to map bo");
2442 _tbm_surface_internal_put_keys(keys);
2443 tbm_surface_unmap(surface);
2446 memset(bo_handle.ptr, 0x00, buf_info->size);
2448 switch (info.format) {
2449 case TBM_FORMAT_ARGB8888:
2450 case TBM_FORMAT_XRGB8888:
2451 case TBM_FORMAT_ABGR8888:
2452 case TBM_FORMAT_XBGR8888:
2453 snprintf(buf_info->name, sizeof(buf_info->name),
2454 "%10.3f_%03d%s_%p_%s-%s.%s",
2455 _tbm_surface_internal_get_time(),
2456 g_dump_info->count++, keys, surface, format, type, postfix);
2458 if (scale_factor > 0.0) {
2459 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2461 buf_info->info.format,
2462 info.planes[0].stride,
2463 info.width, info.height,
2464 buf_info->info.planes[0].stride,
2465 buf_info->info.width,
2466 buf_info->info.height);
2467 if (ret != TBM_SURFACE_ERROR_NONE) {
2468 TBM_ERR("fail to scale buffer");
2469 tbm_bo_unmap(buf_info->bo);
2470 _tbm_surface_internal_put_keys(keys);
2471 tbm_surface_unmap(surface);
2475 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2477 case TBM_FORMAT_YVU420:
2478 case TBM_FORMAT_YUV420:
2479 snprintf(buf_info->name, sizeof(buf_info->name),
2480 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2481 _tbm_surface_internal_get_time(),
2482 g_dump_info->count++, keys, type, info.planes[0].stride,
2483 info.height, FOURCC_STR(info.format), postfix);
2484 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2485 bo_handle.ptr += info.planes[0].stride * info.height;
2486 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2487 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2488 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2490 case TBM_FORMAT_NV12:
2491 case TBM_FORMAT_NV21:
2492 snprintf(buf_info->name, sizeof(buf_info->name),
2493 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2494 _tbm_surface_internal_get_time(),
2495 g_dump_info->count++, keys, type, info.planes[0].stride,
2496 info.height, FOURCC_STR(info.format), postfix);
2497 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2498 bo_handle.ptr += info.planes[0].stride * info.height;
2499 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2501 case TBM_FORMAT_YUYV:
2502 case TBM_FORMAT_UYVY:
2503 snprintf(buf_info->name, sizeof(buf_info->name),
2504 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2505 _tbm_surface_internal_get_time(),
2506 g_dump_info->count++, keys, type, info.planes[0].stride,
2507 info.height, FOURCC_STR(info.format), postfix);
2508 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2511 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2512 tbm_bo_unmap(buf_info->bo);
2513 _tbm_surface_internal_put_keys(keys);
2514 tbm_surface_unmap(surface);
2518 tbm_bo_unmap(buf_info->bo);
2520 _tbm_surface_internal_put_keys(keys);
2522 tbm_surface_unmap(surface);
2524 buf_info->dirty = 1;
2525 buf_info->dirty_shm = 0;
2527 if (g_dump_info->count == 1000)
2528 g_dump_info->count = 0;
2530 g_dump_info->link = next_link;
2532 TBM_INFO("Dump %s \n", buf_info->name);
2535 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2538 TBM_RETURN_IF_FAIL(ptr != NULL);
2539 TBM_RETURN_IF_FAIL(w > 0);
2540 TBM_RETURN_IF_FAIL(h > 0);
2541 TBM_RETURN_IF_FAIL(stride > 0);
2542 TBM_RETURN_IF_FAIL(type != NULL);
2544 tbm_surface_dump_buf_info *buf_info;
2545 struct list_head *next_link;
2546 tbm_bo_handle bo_handle;
2547 int ret, size, dw = 0, dh = 0, dstride = 0;
2552 next_link = g_dump_info->link->next;
2553 TBM_RETURN_IF_FAIL(next_link != NULL);
2555 if (next_link == &g_dump_info->surface_list) {
2556 next_link = next_link->next;
2557 TBM_RETURN_IF_FAIL(next_link != NULL);
2560 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2561 TBM_RETURN_IF_FAIL(buf_info != NULL);
2563 if (scale_factor > 0.0) {
2566 dw = w * scale_factor;
2567 dh = h * scale_factor;
2569 size = dstride * dh;
2573 if (size > buf_info->size) {
2574 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2575 size, buf_info->size);
2580 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2581 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2583 memset(bo_handle.ptr, 0x00, buf_info->size);
2584 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2586 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2587 _tbm_surface_internal_get_time(),
2588 g_dump_info->count++, type, dump_postfix[0]);
2589 if (scale_factor > 0.0) {
2590 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2591 TBM_FORMAT_ARGB8888, stride,
2592 w, h, dstride, dw, dh);
2593 if (ret != TBM_SURFACE_ERROR_NONE) {
2594 TBM_ERR("fail to scale buffer");
2595 tbm_bo_unmap(buf_info->bo);
2598 buf_info->shm_stride = dstride;
2599 buf_info->shm_h = dh;
2601 memcpy(bo_handle.ptr, ptr, size);
2602 buf_info->shm_stride = stride;
2603 buf_info->shm_h = h;
2606 tbm_bo_unmap(buf_info->bo);
2608 buf_info->dirty = 0;
2609 buf_info->dirty_shm = 1;
2611 if (g_dump_info->count == 1000)
2612 g_dump_info->count = 0;
2614 g_dump_info->link = next_link;
2616 TBM_INFO("Dump %s \n", buf_info->name);
2620 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2622 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2623 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2624 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2626 tbm_surface_info_s info;
2627 const char *postfix;
2631 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2632 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2634 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2635 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888))
2636 postfix = dump_postfix[0];
2638 postfix = dump_postfix[1];
2640 if (strcmp(postfix, type)) {
2641 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2642 tbm_surface_unmap(surface);
2646 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2648 if (!access(file, 0)) {
2649 TBM_ERR("can't capture buffer, exist file %s", file);
2650 tbm_surface_unmap(surface);
2654 switch (info.format) {
2655 case TBM_FORMAT_ARGB8888:
2656 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2659 info.planes[0].stride,
2660 TBM_FORMAT_ARGB8888);
2662 case TBM_FORMAT_XRGB8888:
2663 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2666 info.planes[0].stride,
2667 TBM_FORMAT_XRGB8888);
2669 case TBM_FORMAT_ABGR8888:
2670 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2673 info.planes[0].stride,
2674 TBM_FORMAT_ABGR8888);
2676 case TBM_FORMAT_XBGR8888:
2677 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2680 info.planes[0].stride,
2681 TBM_FORMAT_XBGR8888);
2683 case TBM_FORMAT_YVU420:
2684 case TBM_FORMAT_YUV420:
2685 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2686 info.planes[0].stride * info.height,
2688 info.planes[1].stride * (info.height >> 1),
2690 info.planes[2].stride * (info.height >> 1));
2692 case TBM_FORMAT_NV12:
2693 case TBM_FORMAT_NV21:
2694 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2695 info.planes[0].stride * info.height,
2697 info.planes[1].stride * (info.height >> 1),
2700 case TBM_FORMAT_YUYV:
2701 case TBM_FORMAT_UYVY:
2702 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2703 info.planes[0].stride * info.height,
2707 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2708 tbm_surface_unmap(surface);
2712 tbm_surface_unmap(surface);
2714 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2720 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2721 const char *path, const char *name, const char *type)
2723 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2724 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2725 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2726 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2727 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2728 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2732 if (strcmp(dump_postfix[0], type)) {
2733 TBM_ERR("Not supported type:%s'", type);
2737 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2739 if (!access(file, 0)) {
2740 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2744 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2746 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2752 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2754 struct _tbm_surface *surf;
2756 _tbm_surface_mutex_lock();
2757 _tbm_set_last_result(TBM_ERROR_NONE);
2759 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2760 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2761 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2763 surf = (struct _tbm_surface *)surface;
2767 surf->damage.width = width;
2768 surf->damage.height = height;
2770 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2771 surface, x, y, width, height);
2773 _tbm_surface_mutex_unlock();
2779 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2781 struct _tbm_surface *surf;
2783 _tbm_surface_mutex_lock();
2784 _tbm_set_last_result(TBM_ERROR_NONE);
2786 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2788 surf = (struct _tbm_surface *)surface;
2790 if (x) *x = surf->damage.x;
2791 if (y) *y = surf->damage.y;
2792 if (width) *width = surf->damage.width;
2793 if (height) *height = surf->damage.height;
2795 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2796 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2798 _tbm_surface_mutex_unlock();
2804 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2806 struct _tbm_surface *surf;
2807 tbm_surface_destroy_func_info *func_info = NULL;
2809 _tbm_surface_mutex_lock();
2810 _tbm_set_last_result(TBM_ERROR_NONE);
2812 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2813 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2815 surf = (struct _tbm_surface *)surface;
2816 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2817 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2818 TBM_ERR("can't add twice");
2819 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2820 _tbm_surface_mutex_unlock();
2825 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2826 if (func_info == NULL) {
2827 TBM_ERR("alloc failed");
2828 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2829 _tbm_surface_mutex_unlock();
2833 func_info->destroy_func = func;
2834 func_info->user_data = user_data;
2836 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2838 _tbm_surface_mutex_unlock();
2844 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2846 struct _tbm_surface *surf;
2847 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2849 _tbm_surface_mutex_lock();
2850 _tbm_set_last_result(TBM_ERROR_NONE);
2852 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2853 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2855 surf = (struct _tbm_surface *)surface;
2856 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2857 if (func_info->destroy_func != func || func_info->user_data != user_data)
2860 LIST_DEL(&func_info->item_link);
2863 _tbm_surface_mutex_unlock();
2868 _tbm_surface_mutex_unlock();
2871 tbm_surface_buffer_data *
2872 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2874 tbm_surface_buffer_data *buffer_data = NULL;
2875 struct _tbm_bufmgr *bufmgr;
2877 _tbm_surface_mutex_lock();
2879 bufmgr = g_surface_bufmgr;
2880 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2882 // this function supports when the module suppport surface_data.
2883 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(tbm_module_support_surface_data(bufmgr->module), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2885 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, error, TBM_ERROR_INVALID_PARAMETER);
2888 buffer_data = tbm_surface_data_export(surface->surface_data, error);
2889 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
2891 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
2893 _tbm_set_last_result(TBM_ERROR_NONE);
2894 _tbm_surface_mutex_unlock();
2900 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
2902 struct _tbm_surface *surf;
2903 struct _tbm_bufmgr *bufmgr;
2905 _tbm_surface_mutex_lock();
2907 bufmgr = g_surface_bufmgr;
2908 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2910 // this function supports when the module suppport surface_data.
2911 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(tbm_module_support_surface_data(bufmgr->module), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2913 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2914 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2915 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2916 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2919 surf = _tbm_surface_internal_import_surface(bufmgr,
2920 (int)surface_info->width,
2921 (int)surface_info->height,
2922 (int)surface_info->format,
2925 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
2927 LIST_INITHEAD(&surf->user_data_list);
2928 LIST_INITHEAD(&surf->debug_data_list);
2929 LIST_INITHEAD(&surf->destroy_funcs);
2931 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
2933 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
2935 _tbm_set_last_result(TBM_ERROR_NONE);
2936 _tbm_surface_mutex_unlock();
2938 return (tbm_surface_h)surf;