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 // get the bo_data_array
677 bo_data_array = tbm_surface_data_get_bo_data_array(surf->surface_data, &num_bos, &error);
678 if (!bo_data_array) {
679 TBM_ERR("tbm_surface_data_get_bo_data_array failed. error:%s", tbm_error_str(error));
682 surf->num_bos = num_bos;
684 // calculate the size of a surface
685 for (i = 0; i < surf->info.num_planes; i++)
686 surf->info.size += surf->info.planes[i].size;
688 // get memory_types(bo flags)
689 memory_types = tbm_bo_data_get_memory_types(bo_data_array[0], &error);
690 if (error != TBM_ERROR_NONE) {
691 TBM_ERR("tbm_bo_data_get_memory_types failed. error:%s", tbm_error_str(error));
695 surf->flags = memory_types;
697 // allocate the array of tbm_bos
698 for (i = 0; i < num_bos; i++) {
699 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_bo_data(surf->bufmgr, bo_data_array[i], memory_types, &error);
701 TBM_ERR("tbm_bufmgr_internal_alloc_bo_with_bo_data failed. error:%s idx:%d", tbm_error_str(error), i);
705 _tbm_bo_set_surface(surf->bos[i], surf);
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 for (j = 0; j < i; j++) {
763 tbm_bo_unref(surf->bos[j]);
769 static struct _tbm_surface *
770 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
772 struct _tbm_surface *surf;
773 int is_surface_data = 0;
775 surf = _tbm_surface_internal_alloc(bufmgr, width, height, format, error);
777 /* LCOV_EXCL_START */
778 TBM_ERR("_tbm_surface_internal_alloc failed.");
783 is_surface_data = tbm_module_support_surface_data(bufmgr->module);
784 if (is_surface_data) {
785 // alloc surface_data
786 surf->surface_data = tbm_module_alloc_surface_data(bufmgr->module, width, height, format, flags, error);
787 if (!surf->surface_data) {
788 TBM_ERR("tbm_module_alloc_surface_data failed. width:%d height:%d format:%d error:%s",
789 width, height, format, tbm_error_str(*error));
794 // set the surface data
795 *error = _tbm_surface_internal_set_data(surf, flags, is_surface_data);
796 if (*error != TBM_ERROR_NONE) {
797 tbm_surface_data_free(surf->surface_data);
798 surf->surface_data = NULL;
799 _tbm_surface_internal_free(surf);
806 static struct _tbm_surface *
807 _tbm_surface_internal_import_surface(tbm_bufmgr bufmgr, int width, int height, int format, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
809 struct _tbm_surface *surf = NULL;
811 surf = _tbm_surface_internal_alloc(bufmgr, width, height, format, error);
813 /* LCOV_EXCL_START */
814 TBM_ERR("_tbm_surface_internal_alloc failed.");
819 // import surface_data
820 surf->surface_data = tbm_module_import_surface_data(bufmgr->module, width, height, format, buffer_data, error);
821 if (!surf->surface_data) {
822 /* LCOV_EXCL_START */
823 TBM_ERR("tbm_module_import_surface_data failed. width:%d height:%d format:%d error:%s",
824 width, height, format, tbm_error_str(*error));
829 // set the surface data
830 *error = _tbm_surface_internal_set_data(surf, TBM_BO_DEFAULT, 1);
831 if (*error != TBM_ERROR_NONE) {
832 /* LCOV_EXCL_START */
833 tbm_surface_data_free(surf->surface_data);
834 surf->surface_data = NULL;
835 _tbm_surface_internal_free(surf);
844 tbm_surface_internal_is_valid(tbm_surface_h surface)
848 _tbm_surface_mutex_lock();
849 _tbm_set_last_result(TBM_ERROR_NONE);
851 /* Return silently if surface is null. */
853 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
854 _tbm_surface_mutex_unlock();
858 ret = _tbm_surface_internal_is_valid(surface);
860 _tbm_surface_mutex_unlock();
866 tbm_surface_internal_query_supported_formats(uint32_t **formats,
869 struct _tbm_bufmgr *bufmgr;
870 bool bufmgr_initialized = false;
873 _tbm_surface_mutex_lock();
874 _tbm_set_last_result(TBM_ERROR_NONE);
876 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
877 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
879 if (!g_surface_bufmgr) {
880 _init_surface_bufmgr();
881 if (!g_surface_bufmgr) {
882 TBM_ERR("fail bufmgr initialization\n");
883 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
886 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
887 bufmgr_initialized = true;
890 bufmgr = g_surface_bufmgr;
892 error = tbm_module_get_supported_formats(bufmgr->module, formats, num);
893 if (error != TBM_ERROR_NONE) {
894 _tbm_set_last_result(error);
898 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
900 if (bufmgr_initialized) {
901 LIST_DELINIT(&g_surface_bufmgr->surf_list);
902 _deinit_surface_bufmgr();
905 _tbm_surface_mutex_unlock();
909 /* LCOV_EXCL_START */
911 if (bufmgr_initialized) {
912 LIST_DELINIT(&g_surface_bufmgr->surf_list);
913 _deinit_surface_bufmgr();
915 _tbm_surface_mutex_unlock();
917 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
924 tbm_surface_internal_get_num_planes(tbm_format format)
928 _tbm_surface_mutex_lock();
929 _tbm_set_last_result(TBM_ERROR_NONE);
931 num_planes = _tbm_surface_internal_get_num_planes(format);
933 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
934 _tbm_surface_mutex_unlock();
938 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
940 _tbm_surface_mutex_unlock();
946 tbm_surface_internal_get_bpp(tbm_format format)
950 _tbm_surface_mutex_lock();
951 _tbm_set_last_result(TBM_ERROR_NONE);
953 bpp = _tbm_surface_internal_get_bpp(format);
955 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
956 _tbm_surface_mutex_unlock();
960 _tbm_surface_mutex_unlock();
962 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
968 tbm_surface_internal_create_with_flags(int width, int height,
969 int format, int flags)
971 struct _tbm_bufmgr *bufmgr;
972 struct _tbm_surface *surf = NULL;
973 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
974 bool bufmgr_initialized = false;
976 _tbm_surface_mutex_lock();
977 _tbm_set_last_result(TBM_ERROR_NONE);
979 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
980 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
982 if (!g_surface_bufmgr) {
983 _init_surface_bufmgr();
984 if (!g_surface_bufmgr) {
985 TBM_ERR("fail bufmgr initialization\n");
986 error = TBM_ERROR_INVALID_OPERATION;
987 goto check_valid_fail;
989 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
990 bufmgr_initialized = true;
993 bufmgr = g_surface_bufmgr;
994 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
995 TBM_ERR("The bufmgr is invalid\n");
996 error = TBM_ERROR_INVALID_PARAMETER;
997 goto check_valid_fail;
1000 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1002 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1003 goto surface_alloc_fail;
1006 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1007 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1009 LIST_INITHEAD(&surf->user_data_list);
1010 LIST_INITHEAD(&surf->debug_data_list);
1011 LIST_INITHEAD(&surf->destroy_funcs);
1013 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1015 _tbm_set_last_result(error);
1016 _tbm_surface_mutex_unlock();
1020 /* LCOV_EXCL_START */
1024 if (bufmgr_initialized && bufmgr) {
1025 LIST_DELINIT(&bufmgr->surf_list);
1026 _deinit_surface_bufmgr();
1029 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1030 width, height, _tbm_surface_internal_format_to_str(format), flags);
1032 _tbm_set_last_result(error);
1033 _tbm_surface_mutex_unlock();
1035 /* LCOV_EXCL_STOP */
1041 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1042 tbm_bo *bos, int num)
1044 struct _tbm_bufmgr *bufmgr;
1045 struct _tbm_surface *surf = NULL;
1047 bool bufmgr_initialized = false;
1049 _tbm_surface_mutex_lock();
1050 _tbm_set_last_result(TBM_ERROR_NONE);
1052 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1053 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1054 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1055 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1056 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1058 if (!g_surface_bufmgr) {
1059 _init_surface_bufmgr();
1060 if (!g_surface_bufmgr) {
1061 TBM_ERR("fail bufmgr initialization\n");
1062 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1063 goto check_valid_fail;
1065 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1066 bufmgr_initialized = true;
1069 bufmgr = g_surface_bufmgr;
1070 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1071 TBM_ERR("fail to validate the Bufmgr.\n");
1072 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1073 goto check_valid_fail;
1076 surf = calloc(1, sizeof(struct _tbm_surface));
1078 /* LCOV_EXCL_START */
1079 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1080 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1081 goto alloc_surf_fail;
1082 /* LCOV_EXCL_STOP */
1085 surf->magic = TBM_SURFACE_MAGIC;
1086 surf->bufmgr = bufmgr;
1087 surf->info.width = info->width;
1088 surf->info.height = info->height;
1089 surf->info.format = info->format;
1091 surf->info.bpp = info->bpp;
1093 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1094 if (!surf->info.bpp) {
1095 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1099 surf->info.num_planes = info->num_planes;
1102 /* get size, stride and offset */
1103 for (i = 0; i < info->num_planes; i++) {
1104 surf->info.planes[i].offset = info->planes[i].offset;
1105 surf->info.planes[i].stride = info->planes[i].stride;
1107 if (info->planes[i].size > 0)
1108 surf->info.planes[i].size = info->planes[i].size;
1110 uint32_t size = 0, offset = 0, stride = 0;
1113 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1114 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1115 goto plane_data_fail;
1117 surf->info.planes[i].size = size;
1121 surf->planes_bo_idx[i] = 0;
1123 surf->planes_bo_idx[i] = i;
1126 if (info->size > 0) {
1127 surf->info.size = info->size;
1129 surf->info.size = 0;
1130 for (i = 0; i < info->num_planes; i++)
1131 surf->info.size += surf->info.planes[i].size;
1134 surf->flags = TBM_BO_DEFAULT;
1136 /* create only one bo */
1137 surf->num_bos = num;
1138 for (i = 0; i < num; i++) {
1139 if (bos[i] == NULL) {
1140 TBM_ERR("bos[%d] is null.\n", i);
1141 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1145 surf->bos[i] = tbm_bo_ref(bos[i]);
1146 _tbm_bo_set_surface(bos[i], surf);
1149 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1150 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1152 LIST_INITHEAD(&surf->user_data_list);
1153 LIST_INITHEAD(&surf->debug_data_list);
1154 LIST_INITHEAD(&surf->destroy_funcs);
1156 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1158 _tbm_surface_mutex_unlock();
1162 /* LCOV_EXCL_START */
1166 for (i = 0; i < num; i++) {
1168 tbm_bo_unref(surf->bos[i]);
1173 if (bufmgr_initialized && bufmgr) {
1174 LIST_DELINIT(&bufmgr->surf_list);
1175 _deinit_surface_bufmgr();
1177 _tbm_surface_mutex_unlock();
1179 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1180 info->width, info->height,
1181 _tbm_surface_internal_format_to_str(info->format), num);
1182 /* LCOV_EXCL_STOP */
1188 tbm_surface_internal_destroy(tbm_surface_h surface)
1190 _tbm_surface_mutex_lock();
1191 _tbm_set_last_result(TBM_ERROR_NONE);
1193 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1197 if (surface->refcnt > 0) {
1198 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1199 _tbm_surface_mutex_unlock();
1203 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1205 if (surface->refcnt == 0)
1206 _tbm_surface_internal_destroy(surface);
1207 else // if (surface->refcnt < 0)
1208 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1210 _tbm_surface_mutex_unlock();
1214 tbm_surface_internal_ref(tbm_surface_h surface)
1216 _tbm_surface_mutex_lock();
1217 _tbm_set_last_result(TBM_ERROR_NONE);
1219 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1223 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1225 _tbm_surface_mutex_unlock();
1229 tbm_surface_internal_unref(tbm_surface_h surface)
1231 _tbm_surface_mutex_lock();
1232 _tbm_set_last_result(TBM_ERROR_NONE);
1234 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1238 if (surface->refcnt > 0) {
1239 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1240 _tbm_surface_mutex_unlock();
1244 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1246 if (surface->refcnt == 0)
1247 _tbm_surface_internal_destroy(surface);
1249 _tbm_surface_mutex_unlock();
1253 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1255 struct _tbm_surface *surf;
1258 _tbm_surface_mutex_lock();
1259 _tbm_set_last_result(TBM_ERROR_NONE);
1261 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1263 surf = (struct _tbm_surface *)surface;
1264 num = surf->num_bos;
1267 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1269 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1271 _tbm_surface_mutex_unlock();
1277 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1279 struct _tbm_surface *surf;
1282 _tbm_surface_mutex_lock();
1283 _tbm_set_last_result(TBM_ERROR_NONE);
1285 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1286 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1288 surf = (struct _tbm_surface *)surface;
1289 bo = surf->bos[bo_idx];
1291 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1293 _tbm_surface_mutex_unlock();
1299 tbm_surface_internal_get_size(tbm_surface_h surface)
1301 struct _tbm_surface *surf;
1304 _tbm_surface_mutex_lock();
1305 _tbm_set_last_result(TBM_ERROR_NONE);
1307 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1309 surf = (struct _tbm_surface *)surface;
1310 size = surf->info.size;
1312 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1314 _tbm_surface_mutex_unlock();
1320 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1321 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1323 struct _tbm_surface *surf;
1325 _tbm_surface_mutex_lock();
1326 _tbm_set_last_result(TBM_ERROR_NONE);
1328 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1329 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1331 surf = (struct _tbm_surface *)surface;
1333 if (plane_idx >= surf->info.num_planes) {
1334 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1335 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1336 _tbm_surface_mutex_unlock();
1341 *size = surf->info.planes[plane_idx].size;
1344 *offset = surf->info.planes[plane_idx].offset;
1347 *pitch = surf->info.planes[plane_idx].stride;
1349 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1350 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1351 surf->info.planes[plane_idx].stride);
1353 _tbm_surface_mutex_unlock();
1359 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1360 tbm_surface_info_s *info, int map)
1362 struct _tbm_surface *surf;
1363 tbm_bo_handle bo_handles[4];
1366 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1369 _tbm_surface_mutex_lock();
1370 _tbm_set_last_result(TBM_ERROR_NONE);
1372 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1374 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1376 surf = (struct _tbm_surface *)surface;
1378 memset(info, 0x00, sizeof(tbm_surface_info_s));
1379 info->width = surf->info.width;
1380 info->height = surf->info.height;
1381 info->format = surf->info.format;
1382 info->bpp = surf->info.bpp;
1383 info->size = surf->info.size;
1384 info->num_planes = surf->info.num_planes;
1386 for (i = 0; i < surf->info.num_planes; i++) {
1387 info->planes[i].size = surf->info.planes[i].size;
1388 info->planes[i].offset = surf->info.planes[i].offset;
1389 info->planes[i].stride = surf->info.planes[i].stride;
1390 planes_bo_idx[i] = surf->planes_bo_idx[i];
1393 for (i = 0; i < surf->num_bos; i++)
1394 bos[i] = surf->bos[i];
1396 num_bos = surf->num_bos;
1399 _tbm_surface_mutex_unlock();
1400 for (i = 0; i < num_bos; i++) {
1401 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1402 if (bo_handles[i].ptr == NULL) {
1403 for (j = 0; j < i; j++)
1404 tbm_bo_unmap(bos[j]);
1406 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1410 _tbm_surface_mutex_lock();
1412 for (i = 0; i < num_bos; i++) {
1413 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1414 if (bo_handles[i].ptr == NULL) {
1415 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1416 _tbm_surface_mutex_unlock();
1422 for (i = 0; i < info->num_planes; i++) {
1423 if (bo_handles[planes_bo_idx[i]].ptr)
1424 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1427 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1429 _tbm_surface_mutex_unlock();
1435 tbm_surface_internal_unmap(tbm_surface_h surface)
1437 struct _tbm_surface *surf;
1440 _tbm_surface_mutex_lock();
1441 _tbm_set_last_result(TBM_ERROR_NONE);
1443 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1445 surf = (struct _tbm_surface *)surface;
1447 for (i = 0; i < surf->num_bos; i++)
1448 tbm_bo_unmap(surf->bos[i]);
1450 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1452 _tbm_surface_mutex_unlock();
1456 tbm_surface_internal_get_width(tbm_surface_h surface)
1458 struct _tbm_surface *surf;
1461 _tbm_surface_mutex_lock();
1462 _tbm_set_last_result(TBM_ERROR_NONE);
1464 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1466 surf = (struct _tbm_surface *)surface;
1467 width = surf->info.width;
1469 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1471 _tbm_surface_mutex_unlock();
1477 tbm_surface_internal_get_height(tbm_surface_h surface)
1479 struct _tbm_surface *surf;
1480 unsigned int height;
1482 _tbm_surface_mutex_lock();
1483 _tbm_set_last_result(TBM_ERROR_NONE);
1485 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1487 surf = (struct _tbm_surface *)surface;
1488 height = surf->info.height;
1490 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1492 _tbm_surface_mutex_unlock();
1499 tbm_surface_internal_get_format(tbm_surface_h surface)
1501 struct _tbm_surface *surf;
1504 _tbm_surface_mutex_lock();
1505 _tbm_set_last_result(TBM_ERROR_NONE);
1507 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1509 surf = (struct _tbm_surface *)surface;
1510 format = surf->info.format;
1512 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1514 _tbm_surface_mutex_unlock();
1520 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1522 struct _tbm_surface *surf;
1525 _tbm_surface_mutex_lock();
1526 _tbm_set_last_result(TBM_ERROR_NONE);
1528 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1529 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1531 surf = (struct _tbm_surface *)surface;
1532 bo_idx = surf->planes_bo_idx[plane_idx];
1534 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1536 _tbm_surface_mutex_unlock();
1542 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1543 tbm_data_free data_free_func)
1545 tbm_user_data *data;
1547 _tbm_surface_mutex_lock();
1548 _tbm_set_last_result(TBM_ERROR_NONE);
1550 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1552 /* check if the data according to the key exist if so, return false. */
1553 data = user_data_lookup(&surface->user_data_list, key);
1555 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1556 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1557 _tbm_surface_mutex_unlock();
1561 data = user_data_create(key, data_free_func);
1563 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1564 _tbm_surface_mutex_unlock();
1568 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1570 LIST_ADD(&data->item_link, &surface->user_data_list);
1572 _tbm_surface_mutex_unlock();
1578 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1581 tbm_user_data *old_data;
1583 _tbm_surface_mutex_lock();
1584 _tbm_set_last_result(TBM_ERROR_NONE);
1586 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1588 old_data = user_data_lookup(&surface->user_data_list, key);
1590 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1591 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1592 _tbm_surface_mutex_unlock();
1596 if (old_data->data && old_data->free_func)
1597 old_data->free_func(old_data->data);
1599 old_data->data = data;
1601 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1603 _tbm_surface_mutex_unlock();
1609 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1612 tbm_user_data *old_data;
1614 _tbm_surface_mutex_lock();
1615 _tbm_set_last_result(TBM_ERROR_NONE);
1617 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1620 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1621 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1622 _tbm_surface_mutex_unlock();
1627 old_data = user_data_lookup(&surface->user_data_list, key);
1629 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1630 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1631 _tbm_surface_mutex_unlock();
1635 *data = old_data->data;
1637 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1639 _tbm_surface_mutex_unlock();
1645 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1648 tbm_user_data *old_data = (void *)0;
1650 _tbm_surface_mutex_lock();
1651 _tbm_set_last_result(TBM_ERROR_NONE);
1653 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1655 old_data = user_data_lookup(&surface->user_data_list, key);
1657 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1658 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1659 _tbm_surface_mutex_unlock();
1663 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1665 user_data_delete(old_data);
1667 _tbm_surface_mutex_unlock();
1672 /* LCOV_EXCL_START */
1674 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1676 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1678 return surface->debug_pid;
1682 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1684 _tbm_surface_mutex_lock();
1685 _tbm_set_last_result(TBM_ERROR_NONE);
1687 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1689 surface->debug_pid = pid;
1691 _tbm_surface_mutex_unlock();
1694 static tbm_surface_debug_data *
1695 _tbm_surface_internal_debug_data_create(char *key, char *value)
1697 tbm_surface_debug_data *debug_data = NULL;
1699 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1701 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1702 TBM_ERR("fail to allocate the debug_data.");
1706 if (key) debug_data->key = strdup(key);
1707 if (value) debug_data->value = strdup(value);
1713 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1715 if (!debug_data->value && !value)
1718 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1721 if (debug_data->value)
1722 free(debug_data->value);
1725 debug_data->value = strdup(value);
1727 debug_data->value = NULL;
1730 static tbm_surface_debug_data *
1731 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1733 tbm_surface_debug_data *debug_data = NULL;
1735 if (LIST_IS_EMPTY(list))
1738 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1739 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1747 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1749 tbm_surface_debug_data *debug_data = NULL;
1750 tbm_bufmgr bufmgr = NULL;
1752 _tbm_surface_mutex_lock();
1753 _tbm_set_last_result(TBM_ERROR_NONE);
1755 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1756 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1758 bufmgr = surface->bufmgr;
1760 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1762 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1764 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1766 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1768 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1769 _tbm_surface_mutex_unlock();
1773 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1776 /* add new debug key to list */
1777 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1779 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1781 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1784 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1786 _tbm_surface_mutex_unlock();
1792 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1794 tbm_surface_debug_data *old_data = NULL;
1796 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1798 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1799 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1800 if (!strcmp(old_data->key, key))
1801 return old_data->value;
1808 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1809 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1811 struct _tbm_surface_dump_buf_info {
1821 tbm_surface_info_s info;
1823 struct list_head link;
1826 struct _tbm_surface_dump_info {
1827 char *path; // copy???
1830 struct list_head *link;
1831 struct list_head surface_list; /* link of surface */
1834 static tbm_surface_dump_info *g_dump_info = NULL;
1835 static const char *dump_postfix[2] = {"png", "yuv"};
1836 static double scale_factor;
1839 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1840 void *data2, int size2, void *data3, int size3)
1843 unsigned int *blocks;
1845 if (_tbm_surface_check_file_is_symbolic_link(file))
1846 TBM_ERR("%s is symbolic link\n", file);
1848 fp = fopen(file, "w+");
1849 TBM_RETURN_IF_FAIL(fp != NULL);
1851 blocks = (unsigned int *)data1;
1852 fwrite(blocks, 1, size1, fp);
1855 blocks = (unsigned int *)data2;
1856 fwrite(blocks, 1, size2, fp);
1860 blocks = (unsigned int *)data3;
1861 fwrite(blocks, 1, size3, fp);
1868 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1870 unsigned int *blocks = (unsigned int *)data;
1873 png_bytep *row_pointers;
1876 if (_tbm_surface_check_file_is_symbolic_link(file))
1877 TBM_ERR("%s is symbolic link\n", file);
1879 fp = fopen(file, "wb");
1880 TBM_RETURN_IF_FAIL(fp != NULL);
1882 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1885 TBM_ERR("fail to create a png write structure.\n");
1890 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1892 TBM_ERR("fail to create a png info structure.\n");
1893 png_destroy_write_struct(&pPngStruct, NULL);
1898 if (setjmp(png_jmpbuf(pPngStruct))) {
1899 /* if png has problem of writing the file, we get here */
1900 TBM_ERR("fail to write png file.\n");
1901 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1906 png_init_io(pPngStruct, fp);
1907 if (format == TBM_FORMAT_XRGB8888) {
1909 png_set_IHDR(pPngStruct,
1916 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1919 png_set_IHDR(pPngStruct,
1924 PNG_COLOR_TYPE_RGBA,
1926 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1929 png_set_bgr(pPngStruct);
1930 png_write_info(pPngStruct, pPngInfo);
1932 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1933 if (!row_pointers) {
1934 TBM_ERR("fail to allocate the png row_pointers.\n");
1935 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1940 for (y = 0; y < height; ++y) {
1944 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1946 TBM_ERR("fail to allocate the png row.\n");
1947 for (x = 0; x < y; x++)
1948 png_free(pPngStruct, row_pointers[x]);
1949 png_free(pPngStruct, row_pointers);
1950 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1954 row_pointers[y] = (png_bytep)row;
1956 for (x = 0; x < width; ++x) {
1957 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1959 if (pixel_size == 3) { // XRGB8888 or XBGR8888
1960 if (format == TBM_FORMAT_XRGB8888) {
1961 row[x * pixel_size] = (curBlock & 0xFF);
1962 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1963 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1965 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
1966 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1967 row[2 + x * pixel_size] = (curBlock & 0xFF);
1969 } else { // ARGB8888 or ABGR8888
1970 if (format == TBM_FORMAT_ARGB8888) {
1971 row[x * pixel_size] = (curBlock & 0xFF);
1972 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1973 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1974 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1976 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
1977 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1978 row[2 + x * pixel_size] = (curBlock & 0xFF);
1979 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1985 png_write_image(pPngStruct, row_pointers);
1986 png_write_end(pPngStruct, pPngInfo);
1988 for (y = 0; y < height; y++)
1989 png_free(pPngStruct, row_pointers[y]);
1990 png_free(pPngStruct, row_pointers);
1992 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1998 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2000 TBM_RETURN_IF_FAIL(path != NULL);
2001 TBM_RETURN_IF_FAIL(w > 0);
2002 TBM_RETURN_IF_FAIL(h > 0);
2003 TBM_RETURN_IF_FAIL(count > 0);
2005 tbm_surface_dump_buf_info *buf_info = NULL;
2006 tbm_surface_h tbm_surface;
2007 tbm_surface_info_s info;
2012 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2016 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2017 TBM_RETURN_IF_FAIL(g_dump_info);
2019 LIST_INITHEAD(&g_dump_info->surface_list);
2020 g_dump_info->count = 0;
2021 g_dump_info->dump_max = count;
2023 /* get buffer size */
2024 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2025 if (tbm_surface == NULL) {
2026 TBM_ERR("tbm_surface_create fail\n");
2032 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2033 TBM_ERR("tbm_surface_get_info fail\n");
2034 tbm_surface_destroy(tbm_surface);
2039 buffer_size = info.size;
2040 tbm_surface_destroy(tbm_surface);
2042 /* create dump lists */
2043 for (i = 0; i < count; i++) {
2046 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2047 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2049 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2051 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2056 buf_info->index = i;
2058 buf_info->size = buffer_size;
2060 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2063 g_dump_info->path = path;
2064 g_dump_info->link = &g_dump_info->surface_list;
2068 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2073 /* free resources */
2074 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2075 tbm_surface_dump_buf_info *tmp;
2077 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2078 tbm_bo_unref(buf_info->bo);
2079 LIST_DEL(&buf_info->link);
2084 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2093 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2100 tbm_surface_internal_dump_start(path, w, h, count);
2101 scale_factor = scale;
2105 tbm_surface_internal_dump_end(void)
2107 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2108 tbm_bo_handle bo_handle;
2113 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2120 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2123 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2124 if (bo_handle.ptr == NULL) {
2125 tbm_bo_unref(buf_info->bo);
2126 LIST_DEL(&buf_info->link);
2131 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2132 TBM_INFO("Dump File.. %s generated.\n", file);
2134 if (buf_info->dirty) {
2135 void *ptr1 = NULL, *ptr2 = NULL;
2137 switch (buf_info->info.format) {
2138 case TBM_FORMAT_ARGB8888:
2139 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2140 buf_info->info.planes[0].stride >> 2,
2141 buf_info->info.height,
2142 buf_info->info.planes[0].stride,
2143 TBM_FORMAT_ARGB8888);
2145 case TBM_FORMAT_XRGB8888:
2146 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2147 buf_info->info.planes[0].stride >> 2,
2148 buf_info->info.height,
2149 buf_info->info.planes[0].stride,
2150 TBM_FORMAT_XRGB8888);
2152 case TBM_FORMAT_ABGR8888:
2153 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2154 buf_info->info.planes[0].stride >> 2,
2155 buf_info->info.height,
2156 buf_info->info.planes[0].stride,
2157 TBM_FORMAT_ABGR8888);
2159 case TBM_FORMAT_XBGR8888:
2160 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2161 buf_info->info.planes[0].stride >> 2,
2162 buf_info->info.height,
2163 buf_info->info.planes[0].stride,
2164 TBM_FORMAT_XBGR8888);
2166 case TBM_FORMAT_YVU420:
2167 case TBM_FORMAT_YUV420:
2168 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2169 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2170 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2171 buf_info->info.planes[0].stride * buf_info->info.height,
2173 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2175 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2177 case TBM_FORMAT_NV12:
2178 case TBM_FORMAT_NV21:
2179 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2180 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2181 buf_info->info.planes[0].stride * buf_info->info.height,
2183 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2186 case TBM_FORMAT_YUYV:
2187 case TBM_FORMAT_UYVY:
2188 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2189 buf_info->info.planes[0].stride * buf_info->info.height,
2193 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2196 } else if (buf_info->dirty_shm)
2197 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2198 buf_info->shm_stride >> 2,
2200 buf_info->shm_stride, 0);
2202 tbm_bo_unmap(buf_info->bo);
2203 tbm_bo_unref(buf_info->bo);
2204 LIST_DEL(&buf_info->link);
2211 TBM_INFO("Dump End..\n");
2214 static pixman_format_code_t
2215 _tbm_surface_internal_pixman_format_get(tbm_format format)
2218 case TBM_FORMAT_ARGB8888:
2219 case TBM_FORMAT_ABGR8888:
2220 return PIXMAN_a8r8g8b8;
2221 case TBM_FORMAT_XRGB8888:
2222 case TBM_FORMAT_XBGR8888:
2223 return PIXMAN_x8r8g8b8;
2232 * This function supports only if a buffer has below formats.
2233 * - TBM_FORMAT_ARGB8888
2234 * - TBM_FORMAT_XRGB8888
2235 * - TBM_FORMAT_ABGR8888
2236 * - TBM_FORMAT_XBGR8888
2238 static tbm_surface_error_e
2239 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2240 int format, int src_stride, int src_w, int src_h,
2241 int dst_stride, int dst_w, int dst_h)
2243 pixman_image_t *src_img = NULL, *dst_img = NULL;
2244 pixman_format_code_t pixman_format;
2245 pixman_transform_t t;
2246 struct pixman_f_transform ft;
2247 double scale_x, scale_y;
2249 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2250 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2252 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2253 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2256 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2257 (uint32_t*)src_ptr, src_stride);
2258 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2261 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2262 (uint32_t*)dst_ptr, dst_stride);
2263 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2265 pixman_f_transform_init_identity(&ft);
2267 scale_x = (double)src_w / dst_w;
2268 scale_y = (double)src_h / dst_h;
2270 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2271 pixman_f_transform_translate(&ft, NULL, 0, 0);
2272 pixman_transform_from_pixman_f_transform(&t, &ft);
2273 pixman_image_set_transform(src_img, &t);
2275 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2276 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2278 pixman_image_unref(src_img);
2279 pixman_image_unref(dst_img);
2281 return TBM_SURFACE_ERROR_NONE;
2285 pixman_image_unref(src_img);
2287 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2290 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2291 #define KEY_LEN 5 // "_XXXX"
2292 #define KEYS_LEN KEY_LEN * MAX_BOS
2294 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2296 char *keys, temp_key[KEY_LEN + 1];
2297 struct _tbm_surface *surf;
2301 _tbm_surface_mutex_lock();
2303 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2305 surf = (struct _tbm_surface *)surface;
2307 num_bos = surf->num_bos;
2308 if (num_bos > MAX_BOS)
2311 keys = calloc(KEYS_LEN + 1, sizeof(char));
2313 TBM_ERR("Failed to alloc memory");
2314 _tbm_surface_mutex_unlock();
2318 for (i = 0; i < num_bos; i++) {
2319 memset(temp_key, 0x00, KEY_LEN + 1);
2321 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2322 strncat(keys, temp_key, KEY_LEN + 1);
2325 _tbm_surface_mutex_unlock();
2330 static void _tbm_surface_internal_put_keys(char *keys)
2337 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2339 TBM_RETURN_IF_FAIL(surface != NULL);
2340 TBM_RETURN_IF_FAIL(type != NULL);
2342 tbm_surface_dump_buf_info *buf_info;
2343 struct list_head *next_link;
2344 tbm_surface_info_s info;
2345 tbm_bo_handle bo_handle;
2346 const char *postfix;
2347 const char *format = NULL;
2354 next_link = g_dump_info->link->next;
2355 TBM_RETURN_IF_FAIL(next_link != NULL);
2357 if (next_link == &g_dump_info->surface_list) {
2358 next_link = next_link->next;
2359 TBM_RETURN_IF_FAIL(next_link != NULL);
2362 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2363 TBM_RETURN_IF_FAIL(buf_info != NULL);
2365 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2366 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2368 if (scale_factor > 0.0) {
2371 if ((info.format != TBM_FORMAT_ARGB8888) && (info.format != TBM_FORMAT_XRGB8888) &&
2372 (info.format != TBM_FORMAT_ABGR8888) && (info.format != TBM_FORMAT_XBGR8888)) {
2373 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2374 _tbm_surface_internal_format_to_str(info.format));
2375 tbm_surface_unmap(surface);
2379 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2381 buf_info->info.width = info.width * scale_factor;
2382 buf_info->info.height = info.height * scale_factor;
2383 buf_info->info.format = info.format;
2384 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2385 if (!buf_info->info.bpp) {
2386 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2387 tbm_surface_unmap(surface);
2390 buf_info->info.num_planes = 1;
2391 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2392 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2394 if (buf_info->info.size > buf_info->size) {
2395 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2396 buf_info->info.size, buf_info->size);
2397 tbm_surface_unmap(surface);
2401 if (info.size > buf_info->size) {
2402 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2403 info.size, buf_info->size);
2404 tbm_surface_unmap(surface);
2408 /* make the file information */
2409 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2412 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2413 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888)) {
2414 postfix = dump_postfix[0];
2415 format = _tbm_surface_internal_format_to_str(info.format);
2417 postfix = dump_postfix[1];
2419 keys = _tbm_surface_internal_get_keys(surface);
2421 TBM_ERR("fail to get keys");
2422 tbm_surface_unmap(surface);
2427 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2428 if (!bo_handle.ptr) {
2429 TBM_ERR("fail to map bo");
2430 _tbm_surface_internal_put_keys(keys);
2431 tbm_surface_unmap(surface);
2434 memset(bo_handle.ptr, 0x00, buf_info->size);
2436 switch (info.format) {
2437 case TBM_FORMAT_ARGB8888:
2438 case TBM_FORMAT_XRGB8888:
2439 case TBM_FORMAT_ABGR8888:
2440 case TBM_FORMAT_XBGR8888:
2441 snprintf(buf_info->name, sizeof(buf_info->name),
2442 "%10.3f_%03d%s_%p_%s-%s.%s",
2443 _tbm_surface_internal_get_time(),
2444 g_dump_info->count++, keys, surface, format, type, postfix);
2446 if (scale_factor > 0.0) {
2447 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2449 buf_info->info.format,
2450 info.planes[0].stride,
2451 info.width, info.height,
2452 buf_info->info.planes[0].stride,
2453 buf_info->info.width,
2454 buf_info->info.height);
2455 if (ret != TBM_SURFACE_ERROR_NONE) {
2456 TBM_ERR("fail to scale buffer");
2457 tbm_bo_unmap(buf_info->bo);
2458 _tbm_surface_internal_put_keys(keys);
2459 tbm_surface_unmap(surface);
2463 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2465 case TBM_FORMAT_YVU420:
2466 case TBM_FORMAT_YUV420:
2467 snprintf(buf_info->name, sizeof(buf_info->name),
2468 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2469 _tbm_surface_internal_get_time(),
2470 g_dump_info->count++, keys, type, info.planes[0].stride,
2471 info.height, FOURCC_STR(info.format), postfix);
2472 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2473 bo_handle.ptr += info.planes[0].stride * info.height;
2474 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2475 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2476 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2478 case TBM_FORMAT_NV12:
2479 case TBM_FORMAT_NV21:
2480 snprintf(buf_info->name, sizeof(buf_info->name),
2481 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2482 _tbm_surface_internal_get_time(),
2483 g_dump_info->count++, keys, type, info.planes[0].stride,
2484 info.height, FOURCC_STR(info.format), postfix);
2485 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2486 bo_handle.ptr += info.planes[0].stride * info.height;
2487 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2489 case TBM_FORMAT_YUYV:
2490 case TBM_FORMAT_UYVY:
2491 snprintf(buf_info->name, sizeof(buf_info->name),
2492 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2493 _tbm_surface_internal_get_time(),
2494 g_dump_info->count++, keys, type, info.planes[0].stride,
2495 info.height, FOURCC_STR(info.format), postfix);
2496 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2499 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2500 tbm_bo_unmap(buf_info->bo);
2501 _tbm_surface_internal_put_keys(keys);
2502 tbm_surface_unmap(surface);
2506 tbm_bo_unmap(buf_info->bo);
2508 _tbm_surface_internal_put_keys(keys);
2510 tbm_surface_unmap(surface);
2512 buf_info->dirty = 1;
2513 buf_info->dirty_shm = 0;
2515 if (g_dump_info->count == 1000)
2516 g_dump_info->count = 0;
2518 g_dump_info->link = next_link;
2520 TBM_INFO("Dump %s \n", buf_info->name);
2523 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2526 TBM_RETURN_IF_FAIL(ptr != NULL);
2527 TBM_RETURN_IF_FAIL(w > 0);
2528 TBM_RETURN_IF_FAIL(h > 0);
2529 TBM_RETURN_IF_FAIL(stride > 0);
2530 TBM_RETURN_IF_FAIL(type != NULL);
2532 tbm_surface_dump_buf_info *buf_info;
2533 struct list_head *next_link;
2534 tbm_bo_handle bo_handle;
2535 int ret, size, dw = 0, dh = 0, dstride = 0;
2540 next_link = g_dump_info->link->next;
2541 TBM_RETURN_IF_FAIL(next_link != NULL);
2543 if (next_link == &g_dump_info->surface_list) {
2544 next_link = next_link->next;
2545 TBM_RETURN_IF_FAIL(next_link != NULL);
2548 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2549 TBM_RETURN_IF_FAIL(buf_info != NULL);
2551 if (scale_factor > 0.0) {
2554 dw = w * scale_factor;
2555 dh = h * scale_factor;
2557 size = dstride * dh;
2561 if (size > buf_info->size) {
2562 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2563 size, buf_info->size);
2568 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2569 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2571 memset(bo_handle.ptr, 0x00, buf_info->size);
2572 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2574 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2575 _tbm_surface_internal_get_time(),
2576 g_dump_info->count++, type, dump_postfix[0]);
2577 if (scale_factor > 0.0) {
2578 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2579 TBM_FORMAT_ARGB8888, stride,
2580 w, h, dstride, dw, dh);
2581 if (ret != TBM_SURFACE_ERROR_NONE) {
2582 TBM_ERR("fail to scale buffer");
2583 tbm_bo_unmap(buf_info->bo);
2586 buf_info->shm_stride = dstride;
2587 buf_info->shm_h = dh;
2589 memcpy(bo_handle.ptr, ptr, size);
2590 buf_info->shm_stride = stride;
2591 buf_info->shm_h = h;
2594 tbm_bo_unmap(buf_info->bo);
2596 buf_info->dirty = 0;
2597 buf_info->dirty_shm = 1;
2599 if (g_dump_info->count == 1000)
2600 g_dump_info->count = 0;
2602 g_dump_info->link = next_link;
2604 TBM_INFO("Dump %s \n", buf_info->name);
2608 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2610 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2611 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2612 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2614 tbm_surface_info_s info;
2615 const char *postfix;
2619 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2620 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2622 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2623 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888))
2624 postfix = dump_postfix[0];
2626 postfix = dump_postfix[1];
2628 if (strcmp(postfix, type)) {
2629 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2630 tbm_surface_unmap(surface);
2634 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2636 if (!access(file, 0)) {
2637 TBM_ERR("can't capture buffer, exist file %s", file);
2638 tbm_surface_unmap(surface);
2642 switch (info.format) {
2643 case TBM_FORMAT_ARGB8888:
2644 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2647 info.planes[0].stride,
2648 TBM_FORMAT_ARGB8888);
2650 case TBM_FORMAT_XRGB8888:
2651 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2654 info.planes[0].stride,
2655 TBM_FORMAT_XRGB8888);
2657 case TBM_FORMAT_ABGR8888:
2658 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2661 info.planes[0].stride,
2662 TBM_FORMAT_ABGR8888);
2664 case TBM_FORMAT_XBGR8888:
2665 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2668 info.planes[0].stride,
2669 TBM_FORMAT_XBGR8888);
2671 case TBM_FORMAT_YVU420:
2672 case TBM_FORMAT_YUV420:
2673 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2674 info.planes[0].stride * info.height,
2676 info.planes[1].stride * (info.height >> 1),
2678 info.planes[2].stride * (info.height >> 1));
2680 case TBM_FORMAT_NV12:
2681 case TBM_FORMAT_NV21:
2682 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2683 info.planes[0].stride * info.height,
2685 info.planes[1].stride * (info.height >> 1),
2688 case TBM_FORMAT_YUYV:
2689 case TBM_FORMAT_UYVY:
2690 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2691 info.planes[0].stride * info.height,
2695 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2696 tbm_surface_unmap(surface);
2700 tbm_surface_unmap(surface);
2702 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2708 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2709 const char *path, const char *name, const char *type)
2711 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2712 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2713 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2714 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2715 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2716 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2720 if (strcmp(dump_postfix[0], type)) {
2721 TBM_ERR("Not supported type:%s'", type);
2725 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2727 if (!access(file, 0)) {
2728 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2732 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2734 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2740 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2742 struct _tbm_surface *surf;
2744 _tbm_surface_mutex_lock();
2745 _tbm_set_last_result(TBM_ERROR_NONE);
2747 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2748 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2749 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2751 surf = (struct _tbm_surface *)surface;
2755 surf->damage.width = width;
2756 surf->damage.height = height;
2758 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2759 surface, x, y, width, height);
2761 _tbm_surface_mutex_unlock();
2767 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2769 struct _tbm_surface *surf;
2771 _tbm_surface_mutex_lock();
2772 _tbm_set_last_result(TBM_ERROR_NONE);
2774 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2776 surf = (struct _tbm_surface *)surface;
2778 if (x) *x = surf->damage.x;
2779 if (y) *y = surf->damage.y;
2780 if (width) *width = surf->damage.width;
2781 if (height) *height = surf->damage.height;
2783 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2784 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2786 _tbm_surface_mutex_unlock();
2792 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2794 struct _tbm_surface *surf;
2795 tbm_surface_destroy_func_info *func_info = NULL;
2797 _tbm_surface_mutex_lock();
2798 _tbm_set_last_result(TBM_ERROR_NONE);
2800 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2801 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2803 surf = (struct _tbm_surface *)surface;
2804 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2805 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2806 TBM_ERR("can't add twice");
2807 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2808 _tbm_surface_mutex_unlock();
2813 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2814 if (func_info == NULL) {
2815 TBM_ERR("alloc failed");
2816 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2817 _tbm_surface_mutex_unlock();
2821 func_info->destroy_func = func;
2822 func_info->user_data = user_data;
2824 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2826 _tbm_surface_mutex_unlock();
2832 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2834 struct _tbm_surface *surf;
2835 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2837 _tbm_surface_mutex_lock();
2838 _tbm_set_last_result(TBM_ERROR_NONE);
2840 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2841 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2843 surf = (struct _tbm_surface *)surface;
2844 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2845 if (func_info->destroy_func != func || func_info->user_data != user_data)
2848 LIST_DEL(&func_info->item_link);
2851 _tbm_surface_mutex_unlock();
2856 _tbm_surface_mutex_unlock();
2859 tbm_surface_buffer_data *
2860 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2862 tbm_surface_buffer_data *buffer_data = NULL;
2863 struct _tbm_bufmgr *bufmgr;
2865 _tbm_surface_mutex_lock();
2867 bufmgr = g_surface_bufmgr;
2868 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2870 // this function supports when the module suppport surface_data.
2871 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(tbm_module_support_surface_data(bufmgr->module), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2873 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, error, TBM_ERROR_INVALID_PARAMETER);
2876 buffer_data = tbm_surface_data_export(surface->surface_data, error);
2877 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
2879 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
2881 _tbm_set_last_result(TBM_ERROR_NONE);
2882 _tbm_surface_mutex_unlock();
2888 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
2890 struct _tbm_surface *surf;
2891 struct _tbm_bufmgr *bufmgr;
2893 _tbm_surface_mutex_lock();
2895 bufmgr = g_surface_bufmgr;
2896 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2898 // this function supports when the module suppport surface_data.
2899 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(tbm_module_support_surface_data(bufmgr->module), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2901 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2902 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2903 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2904 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2907 surf = _tbm_surface_internal_import_surface(bufmgr,
2908 (int)surface_info->width,
2909 (int)surface_info->height,
2910 (int)surface_info->format,
2913 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
2915 LIST_INITHEAD(&surf->user_data_list);
2916 LIST_INITHEAD(&surf->debug_data_list);
2917 LIST_INITHEAD(&surf->destroy_funcs);
2919 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
2921 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
2923 _tbm_set_last_result(TBM_ERROR_NONE);
2924 _tbm_surface_mutex_unlock();
2926 return (tbm_surface_h)surf;