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 #define TBM_SURFACE_RETURN_VAL_SET_ERR_NO_LOG_IF_FAIL(cond, val, error, error_type) {\
112 *error = error_type;\
113 _tbm_set_last_result(error_type);\
114 _tbm_surface_mutex_unlock();\
119 /* LCOV_EXCL_START */
121 _tbm_surface_internal_get_time(void)
126 clock_gettime(CLOCK_MONOTONIC, &tp);
127 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
129 return time / 1000.0;
133 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
135 LIST_DEL(&debug_data->item_link);
137 if (debug_data->key) free(debug_data->key);
138 if (debug_data->value) free(debug_data->value);
143 _tbm_surface_internal_format_to_str(tbm_format format)
147 return "TBM_FORMAT_C8";
148 case TBM_FORMAT_RGB332:
149 return "TBM_FORMAT_RGB332";
150 case TBM_FORMAT_BGR233:
151 return "TBM_FORMAT_BGR233";
152 case TBM_FORMAT_XRGB4444:
153 return "TBM_FORMAT_XRGB4444";
154 case TBM_FORMAT_XBGR4444:
155 return "TBM_FORMAT_XBGR4444";
156 case TBM_FORMAT_RGBX4444:
157 return "TBM_FORMAT_RGBX4444";
158 case TBM_FORMAT_BGRX4444:
159 return "TBM_FORMAT_BGRX4444";
160 case TBM_FORMAT_ARGB4444:
161 return "TBM_FORMAT_ARGB4444";
162 case TBM_FORMAT_ABGR4444:
163 return "TBM_FORMAT_ABGR4444";
164 case TBM_FORMAT_RGBA4444:
165 return "TBM_FORMAT_RGBA4444";
166 case TBM_FORMAT_BGRA4444:
167 return "TBM_FORMAT_BGRA4444";
168 case TBM_FORMAT_XRGB1555:
169 return "TBM_FORMAT_XRGB1555";
170 case TBM_FORMAT_XBGR1555:
171 return "TBM_FORMAT_XBGR1555";
172 case TBM_FORMAT_RGBX5551:
173 return "TBM_FORMAT_RGBX5551";
174 case TBM_FORMAT_BGRX5551:
175 return "TBM_FORMAT_BGRX5551";
176 case TBM_FORMAT_ARGB1555:
177 return "TBM_FORMAT_ARGB1555";
178 case TBM_FORMAT_ABGR1555:
179 return "TBM_FORMAT_ABGR1555";
180 case TBM_FORMAT_RGBA5551:
181 return "TBM_FORMAT_RGBA5551";
182 case TBM_FORMAT_BGRA5551:
183 return "TBM_FORMAT_BGRA5551";
184 case TBM_FORMAT_RGB565:
185 return "TBM_FORMAT_RGB565";
186 case TBM_FORMAT_BGR565:
187 return "TBM_FORMAT_BGR565";
188 case TBM_FORMAT_RGB888:
189 return "TBM_FORMAT_RGB888";
190 case TBM_FORMAT_BGR888:
191 return "TBM_FORMAT_BGR888";
192 case TBM_FORMAT_XRGB8888:
193 return "TBM_FORMAT_XRGB8888";
194 case TBM_FORMAT_XBGR8888:
195 return "TBM_FORMAT_XBGR8888";
196 case TBM_FORMAT_RGBX8888:
197 return "TBM_FORMAT_RGBX8888";
198 case TBM_FORMAT_BGRX8888:
199 return "TBM_FORMAT_BGRX8888";
200 case TBM_FORMAT_ARGB8888:
201 return "TBM_FORMAT_ARGB8888";
202 case TBM_FORMAT_ABGR8888:
203 return "TBM_FORMAT_ABGR8888";
204 case TBM_FORMAT_RGBA8888:
205 return "TBM_FORMAT_RGBA8888";
206 case TBM_FORMAT_BGRA8888:
207 return "TBM_FORMAT_BGRA8888";
208 case TBM_FORMAT_XRGB2101010:
209 return "TBM_FORMAT_XRGB2101010";
210 case TBM_FORMAT_XBGR2101010:
211 return "TBM_FORMAT_XBGR2101010";
212 case TBM_FORMAT_RGBX1010102:
213 return "TBM_FORMAT_RGBX1010102";
214 case TBM_FORMAT_BGRX1010102:
215 return "TBM_FORMAT_BGRX1010102";
216 case TBM_FORMAT_ARGB2101010:
217 return "TBM_FORMAT_ARGB2101010";
218 case TBM_FORMAT_ABGR2101010:
219 return "TBM_FORMAT_ABGR2101010";
220 case TBM_FORMAT_RGBA1010102:
221 return "TBM_FORMAT_RGBA1010102";
222 case TBM_FORMAT_BGRA1010102:
223 return "TBM_FORMAT_BGRA1010102";
224 case TBM_FORMAT_YUYV:
225 return "TBM_FORMAT_YUYV";
226 case TBM_FORMAT_YVYU:
227 return "TBM_FORMAT_YVYU";
228 case TBM_FORMAT_UYVY:
229 return "TBM_FORMAT_UYVY";
230 case TBM_FORMAT_VYUY:
231 return "TBM_FORMAT_VYUY";
232 case TBM_FORMAT_AYUV:
233 return "TBM_FORMAT_AYUV";
234 case TBM_FORMAT_NV12:
235 return "TBM_FORMAT_NV12";
236 case TBM_FORMAT_NV21:
237 return "TBM_FORMAT_NV21";
238 case TBM_FORMAT_NV16:
239 return "TBM_FORMAT_NV16";
240 case TBM_FORMAT_NV61:
241 return "TBM_FORMAT_NV61";
242 case TBM_FORMAT_YUV410:
243 return "TBM_FORMAT_YUV410";
244 case TBM_FORMAT_YVU410:
245 return "TBM_FORMAT_YVU410";
246 case TBM_FORMAT_YUV411:
247 return "TBM_FORMAT_YUV411";
248 case TBM_FORMAT_YVU411:
249 return "TBM_FORMAT_YVU411";
250 case TBM_FORMAT_YUV420:
251 return "TBM_FORMAT_YUV420";
252 case TBM_FORMAT_YVU420:
253 return "TBM_FORMAT_YVU420";
254 case TBM_FORMAT_YUV422:
255 return "TBM_FORMAT_YUV422";
256 case TBM_FORMAT_YVU422:
257 return "TBM_FORMAT_YVU422";
258 case TBM_FORMAT_YUV444:
259 return "TBM_FORMAT_YUV444";
260 case TBM_FORMAT_YVU444:
261 return "TBM_FORMAT_YVU444";
262 case TBM_FORMAT_NV12MT:
263 return "TBM_FORMAT_NV12MT";
270 _tbm_surface_mutex_lock(void)
272 pthread_mutex_lock(&tbm_surface_lock);
276 _tbm_surface_mutex_unlock(void)
278 pthread_mutex_unlock(&tbm_surface_lock);
282 _init_surface_bufmgr(void)
284 g_surface_bufmgr = tbm_bufmgr_init(-1);
288 _deinit_surface_bufmgr(void)
290 if (!g_surface_bufmgr)
293 tbm_bufmgr_deinit(g_surface_bufmgr);
294 g_surface_bufmgr = NULL;
299 _tbm_surface_internal_magic_check(tbm_surface_h surface)
301 if (surface->magic != TBM_SURFACE_MAGIC)
308 _tbm_surface_internal_is_valid(tbm_surface_h surface)
311 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
312 TBM_ERR("error: No valid tbm_surface is NULL\n");
316 if (!_tbm_surface_internal_magic_check(surface)) {
317 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
318 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
326 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
327 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
329 TBM_RETURN_VAL_IF_FAIL(surface, 0);
330 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
332 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
333 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
336 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
337 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
338 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
339 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
341 error = tbm_module_get_plane_data(bufmgr->module, surf->info.format, plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
342 if (error != TBM_ERROR_NONE) {
343 _tbm_set_last_result(error);
351 _tbm_surface_internal_destroy(tbm_surface_h surface)
354 tbm_bufmgr bufmgr = surface->bufmgr;
355 tbm_user_data *old_data = NULL, *tmp = NULL;
356 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
357 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
359 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
360 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
361 func_info->destroy_func(surface, func_info->user_data);
363 TBM_DBG("free destroy_funcs %p\n", surface);
364 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
365 LIST_DEL(&func_info->item_link);
370 /* destory the user_data_list */
371 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
372 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
373 TBM_DBG("free user_data\n");
374 user_data_delete(old_data);
378 for (i = 0; i < surface->num_bos; i++) {
379 surface->bos[i]->surface = NULL;
381 tbm_bo_unref(surface->bos[i]);
382 surface->bos[i] = NULL;
385 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
386 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
387 _tbm_surface_internal_debug_data_delete(debug_old_data);
390 LIST_DEL(&surface->item_link);
393 if (surface->surface_data) {
394 tbm_surface_data_free(surface->surface_data);
395 surface->surface_data = NULL;
401 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
402 LIST_DELINIT(&bufmgr->surf_list);
404 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
405 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
406 _tbm_surface_internal_debug_data_delete(debug_old_data);
410 _deinit_surface_bufmgr();
414 /* LCOV_EXCL_START */
416 _tbm_surface_check_file_is_symbolic_link(const char* path)
423 if (stat(path, &sb) != 0)
426 if (S_ISLNK(sb.st_mode))
434 _tbm_surface_internal_get_num_planes(tbm_format format)
440 case TBM_FORMAT_RGB332:
441 case TBM_FORMAT_BGR233:
442 case TBM_FORMAT_XRGB4444:
443 case TBM_FORMAT_XBGR4444:
444 case TBM_FORMAT_RGBX4444:
445 case TBM_FORMAT_BGRX4444:
446 case TBM_FORMAT_ARGB4444:
447 case TBM_FORMAT_ABGR4444:
448 case TBM_FORMAT_RGBA4444:
449 case TBM_FORMAT_BGRA4444:
450 case TBM_FORMAT_XRGB1555:
451 case TBM_FORMAT_XBGR1555:
452 case TBM_FORMAT_RGBX5551:
453 case TBM_FORMAT_BGRX5551:
454 case TBM_FORMAT_ARGB1555:
455 case TBM_FORMAT_ABGR1555:
456 case TBM_FORMAT_RGBA5551:
457 case TBM_FORMAT_BGRA5551:
458 case TBM_FORMAT_RGB565:
459 case TBM_FORMAT_BGR565:
460 case TBM_FORMAT_RGB888:
461 case TBM_FORMAT_BGR888:
462 case TBM_FORMAT_XRGB8888:
463 case TBM_FORMAT_XBGR8888:
464 case TBM_FORMAT_RGBX8888:
465 case TBM_FORMAT_BGRX8888:
466 case TBM_FORMAT_ARGB8888:
467 case TBM_FORMAT_ABGR8888:
468 case TBM_FORMAT_RGBA8888:
469 case TBM_FORMAT_BGRA8888:
470 case TBM_FORMAT_XRGB2101010:
471 case TBM_FORMAT_XBGR2101010:
472 case TBM_FORMAT_RGBX1010102:
473 case TBM_FORMAT_BGRX1010102:
474 case TBM_FORMAT_ARGB2101010:
475 case TBM_FORMAT_ABGR2101010:
476 case TBM_FORMAT_RGBA1010102:
477 case TBM_FORMAT_BGRA1010102:
478 case TBM_FORMAT_YUYV:
479 case TBM_FORMAT_YVYU:
480 case TBM_FORMAT_UYVY:
481 case TBM_FORMAT_VYUY:
482 case TBM_FORMAT_AYUV:
485 case TBM_FORMAT_NV12:
486 case TBM_FORMAT_NV12MT:
487 case TBM_FORMAT_NV21:
488 case TBM_FORMAT_NV16:
489 case TBM_FORMAT_NV61:
492 case TBM_FORMAT_YUV410:
493 case TBM_FORMAT_YVU410:
494 case TBM_FORMAT_YUV411:
495 case TBM_FORMAT_YVU411:
496 case TBM_FORMAT_YUV420:
497 case TBM_FORMAT_YVU420:
498 case TBM_FORMAT_YUV422:
499 case TBM_FORMAT_YVU422:
500 case TBM_FORMAT_YUV444:
501 case TBM_FORMAT_YVU444:
506 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
514 _tbm_surface_internal_get_bpp(tbm_format format)
521 case TBM_FORMAT_RGB332:
522 case TBM_FORMAT_BGR233:
525 case TBM_FORMAT_XRGB4444:
526 case TBM_FORMAT_XBGR4444:
527 case TBM_FORMAT_RGBX4444:
528 case TBM_FORMAT_BGRX4444:
529 case TBM_FORMAT_ARGB4444:
530 case TBM_FORMAT_ABGR4444:
531 case TBM_FORMAT_RGBA4444:
532 case TBM_FORMAT_BGRA4444:
533 case TBM_FORMAT_XRGB1555:
534 case TBM_FORMAT_XBGR1555:
535 case TBM_FORMAT_RGBX5551:
536 case TBM_FORMAT_BGRX5551:
537 case TBM_FORMAT_ARGB1555:
538 case TBM_FORMAT_ABGR1555:
539 case TBM_FORMAT_RGBA5551:
540 case TBM_FORMAT_BGRA5551:
541 case TBM_FORMAT_RGB565:
542 case TBM_FORMAT_BGR565:
545 case TBM_FORMAT_RGB888:
546 case TBM_FORMAT_BGR888:
549 case TBM_FORMAT_XRGB8888:
550 case TBM_FORMAT_XBGR8888:
551 case TBM_FORMAT_RGBX8888:
552 case TBM_FORMAT_BGRX8888:
553 case TBM_FORMAT_ARGB8888:
554 case TBM_FORMAT_ABGR8888:
555 case TBM_FORMAT_RGBA8888:
556 case TBM_FORMAT_BGRA8888:
557 case TBM_FORMAT_XRGB2101010:
558 case TBM_FORMAT_XBGR2101010:
559 case TBM_FORMAT_RGBX1010102:
560 case TBM_FORMAT_BGRX1010102:
561 case TBM_FORMAT_ARGB2101010:
562 case TBM_FORMAT_ABGR2101010:
563 case TBM_FORMAT_RGBA1010102:
564 case TBM_FORMAT_BGRA1010102:
565 case TBM_FORMAT_YUYV:
566 case TBM_FORMAT_YVYU:
567 case TBM_FORMAT_UYVY:
568 case TBM_FORMAT_VYUY:
569 case TBM_FORMAT_AYUV:
572 case TBM_FORMAT_NV12:
573 case TBM_FORMAT_NV12MT:
574 case TBM_FORMAT_NV21:
577 case TBM_FORMAT_NV16:
578 case TBM_FORMAT_NV61:
581 case TBM_FORMAT_YUV410:
582 case TBM_FORMAT_YVU410:
585 case TBM_FORMAT_YUV411:
586 case TBM_FORMAT_YVU411:
587 case TBM_FORMAT_YUV420:
588 case TBM_FORMAT_YVU420:
591 case TBM_FORMAT_YUV422:
592 case TBM_FORMAT_YVU422:
595 case TBM_FORMAT_YUV444:
596 case TBM_FORMAT_YVU444:
600 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
608 _tbm_surface_internal_free(struct _tbm_surface *surf)
616 static struct _tbm_surface *
617 _tbm_surface_internal_alloc(tbm_bufmgr bufmgr, int width, int height, int format, tbm_error_e *error)
619 struct _tbm_surface *surf = NULL;
621 surf = calloc(1, sizeof(struct _tbm_surface));
623 /* LCOV_EXCL_START */
624 TBM_ERR("memory allocation failed.");
625 *error = TBM_ERROR_OUT_OF_MEMORY;
631 surf->magic = TBM_SURFACE_MAGIC;
632 surf->bufmgr = bufmgr;
633 surf->info.width = width;
634 surf->info.height = height;
635 surf->info.format = format;
636 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
637 if (!surf->info.bpp) {
638 /* LCOV_EXCL_START */
639 TBM_ERR("_tbm_surface_internal_get_bpp failed. format:%d error:%s", format, tbm_error_str(*error));
640 *error = tbm_get_last_error();
646 // get number of planes
647 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
648 if (!surf->info.num_planes) {
649 /* LCOV_EXCL_START */
650 TBM_ERR("_tbm_surface_internal_get_num_planes failed. format:%d error:%s", format, tbm_error_str(*error));
651 *error = tbm_get_last_error();
661 _tbm_surface_internal_set_data(struct _tbm_surface *surf, int flags, int is_surface_data)
664 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;;
666 tbm_bo_data **bo_data_array = NULL;
670 // set data with surface
671 if (is_surface_data) {
672 // set infomation of planes
673 for (i = 0; i < surf->info.num_planes; i++) {
674 error = tbm_surface_data_get_plane_data(surf->surface_data, i, &size, &offset, &stride, &bo_idx);
675 if (error != TBM_ERROR_NONE) {
676 TBM_ERR("tbm_surface_data_get_plane_data failed. error:%s", tbm_error_str(error));
680 surf->info.planes[i].size = size;
681 surf->info.planes[i].offset = offset;
682 surf->info.planes[i].stride = stride;
683 surf->planes_bo_idx[i] = bo_idx;
686 // calculate the size of a surface
687 for (i = 0; i < surf->info.num_planes; i++)
688 surf->info.size += surf->info.planes[i].size;
690 // get the bo_data_array
691 bo_data_array = tbm_surface_data_get_bo_data_array(surf->surface_data, &num_bos, &memory_types, &error);
692 if (!bo_data_array) {
693 TBM_ERR("tbm_surface_data_get_bo_data_array failed. error:%s", tbm_error_str(error));
698 surf->num_bos = num_bos;
701 surf->flags = memory_types;
703 // allocate the array of tbm_bos
704 for (i = 0; i < num_bos; i++) {
705 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_bo_data(surf->bufmgr, bo_data_array[i], memory_types, &error);
707 TBM_ERR("tbm_bufmgr_internal_alloc_bo_with_bo_data failed. error:%s idx:%d", tbm_error_str(error), i);
711 _tbm_bo_set_surface(surf->bos[i], surf);
714 // only free the pointers of the arrary, not the item(tbm_bo_data).
715 // the item(tbm_bo_data) is set to the tbm_bo. tbm_bo handles the life cycle of the tbm_bo_data.
718 // set infomation of planes
719 for (i = 0; i < surf->info.num_planes; i++) {
720 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
721 TBM_ERR("_tbm_surface_internal_query_plane_data failed.");
722 error = tbm_get_last_error();
726 surf->info.planes[i].size = size;
727 surf->info.planes[i].offset = offset;
728 surf->info.planes[i].stride = stride;
729 surf->planes_bo_idx[i] = bo_idx;
732 // calculate the number of bos
734 for (i = 0; i < surf->info.num_planes; i++) {
735 surf->info.size += surf->info.planes[i].size;
737 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
738 surf->num_bos = surf->planes_bo_idx[i] + 1;
744 // allocate the array of tbm_bos
745 for (i = 0; i < surf->num_bos; i++) {
747 for (j = 0; j < surf->info.num_planes; j++) {
748 if (surf->planes_bo_idx[j] == i)
749 bo_size += surf->info.planes[j].size;
752 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_format(surf->bufmgr,
753 surf->info.format, i, surf->info.width, surf->info.height,
754 surf->info.bpp/8, flags, &error);
756 surf->bos[i] = tbm_bo_alloc(surf->bufmgr, bo_size, flags);
758 TBM_ERR("tbm_bo_alloc failed. idx:%d", i);
759 error = tbm_get_last_error();
764 _tbm_bo_set_surface(surf->bos[i], surf);
768 return TBM_ERROR_NONE;
771 if (is_surface_data) {
772 for (j = 0; j < num_bos; j++) {
773 if (bo_data_array[j]) {
774 free(bo_data_array[j]);
781 for (j = 0; j < i; j++) {
783 tbm_bo_unref(surf->bos[j]);
789 static struct _tbm_surface *
790 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
792 struct _tbm_surface *surf;
793 int is_surface_data = 0;
795 surf = _tbm_surface_internal_alloc(bufmgr, width, height, format, error);
797 /* LCOV_EXCL_START */
798 TBM_ERR("_tbm_surface_internal_alloc failed.");
803 is_surface_data = tbm_module_support_surface_data(bufmgr->module);
804 if (is_surface_data) {
805 // alloc surface_data
806 surf->surface_data = tbm_module_alloc_surface_data(bufmgr->module, width, height, format, flags, error);
807 if (!surf->surface_data) {
808 TBM_ERR("tbm_module_alloc_surface_data failed. width:%d height:%d format:%d error:%s",
809 width, height, format, tbm_error_str(*error));
810 _tbm_surface_internal_free(surf);
815 // set the surface data
816 *error = _tbm_surface_internal_set_data(surf, flags, is_surface_data);
817 if (*error != TBM_ERROR_NONE) {
818 tbm_surface_data_free(surf->surface_data);
819 surf->surface_data = NULL;
820 _tbm_surface_internal_free(surf);
827 static struct _tbm_surface *
828 _tbm_surface_internal_import_surface(tbm_bufmgr bufmgr, int width, int height, int format, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
830 struct _tbm_surface *surf = NULL;
832 surf = _tbm_surface_internal_alloc(bufmgr, width, height, format, error);
834 /* LCOV_EXCL_START */
835 TBM_ERR("_tbm_surface_internal_alloc failed.");
840 // import surface_data
841 surf->surface_data = tbm_module_import_surface_data(bufmgr->module, width, height, format, buffer_data, error);
842 if (!surf->surface_data) {
843 /* LCOV_EXCL_START */
844 TBM_ERR("tbm_module_import_surface_data failed. width:%d height:%d format:%d error:%s",
845 width, height, format, tbm_error_str(*error));
846 _tbm_surface_internal_free(surf);
851 // set the surface data
852 *error = _tbm_surface_internal_set_data(surf, TBM_BO_DEFAULT, 1);
853 if (*error != TBM_ERROR_NONE) {
854 /* LCOV_EXCL_START */
855 tbm_surface_data_free(surf->surface_data);
856 surf->surface_data = NULL;
857 _tbm_surface_internal_free(surf);
866 tbm_surface_internal_is_valid(tbm_surface_h surface)
870 _tbm_surface_mutex_lock();
871 _tbm_set_last_result(TBM_ERROR_NONE);
873 /* Return silently if surface is null. */
875 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
876 _tbm_surface_mutex_unlock();
880 ret = _tbm_surface_internal_is_valid(surface);
882 _tbm_surface_mutex_unlock();
888 tbm_surface_internal_query_supported_formats(uint32_t **formats,
891 struct _tbm_bufmgr *bufmgr;
892 bool bufmgr_initialized = false;
895 _tbm_surface_mutex_lock();
896 _tbm_set_last_result(TBM_ERROR_NONE);
898 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
899 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
901 if (!g_surface_bufmgr) {
902 _init_surface_bufmgr();
903 if (!g_surface_bufmgr) {
904 TBM_ERR("fail bufmgr initialization\n");
905 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
908 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
909 bufmgr_initialized = true;
912 bufmgr = g_surface_bufmgr;
914 error = tbm_module_get_supported_formats(bufmgr->module, formats, num);
915 if (error != TBM_ERROR_NONE) {
916 _tbm_set_last_result(error);
920 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
922 if (bufmgr_initialized) {
923 LIST_DELINIT(&g_surface_bufmgr->surf_list);
924 _deinit_surface_bufmgr();
927 _tbm_surface_mutex_unlock();
931 /* LCOV_EXCL_START */
933 if (bufmgr_initialized) {
934 LIST_DELINIT(&g_surface_bufmgr->surf_list);
935 _deinit_surface_bufmgr();
937 _tbm_surface_mutex_unlock();
939 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
946 tbm_surface_internal_get_num_planes(tbm_format format)
950 _tbm_surface_mutex_lock();
951 _tbm_set_last_result(TBM_ERROR_NONE);
953 num_planes = _tbm_surface_internal_get_num_planes(format);
955 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
956 _tbm_surface_mutex_unlock();
960 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
962 _tbm_surface_mutex_unlock();
968 tbm_surface_internal_get_bpp(tbm_format format)
972 _tbm_surface_mutex_lock();
973 _tbm_set_last_result(TBM_ERROR_NONE);
975 bpp = _tbm_surface_internal_get_bpp(format);
977 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
978 _tbm_surface_mutex_unlock();
982 _tbm_surface_mutex_unlock();
984 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
990 tbm_surface_internal_create_with_flags(int width, int height,
991 int format, int flags)
993 struct _tbm_bufmgr *bufmgr;
994 struct _tbm_surface *surf = NULL;
995 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
996 bool bufmgr_initialized = false;
998 _tbm_surface_mutex_lock();
999 _tbm_set_last_result(TBM_ERROR_NONE);
1001 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
1002 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
1004 if (!g_surface_bufmgr) {
1005 _init_surface_bufmgr();
1006 if (!g_surface_bufmgr) {
1007 TBM_ERR("fail bufmgr initialization\n");
1008 error = TBM_ERROR_INVALID_OPERATION;
1009 goto check_valid_fail;
1011 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1012 bufmgr_initialized = true;
1015 bufmgr = g_surface_bufmgr;
1016 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1017 TBM_ERR("The bufmgr is invalid\n");
1018 error = TBM_ERROR_INVALID_PARAMETER;
1019 goto check_valid_fail;
1022 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1024 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1025 goto surface_alloc_fail;
1028 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1029 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1031 LIST_INITHEAD(&surf->user_data_list);
1032 LIST_INITHEAD(&surf->debug_data_list);
1033 LIST_INITHEAD(&surf->destroy_funcs);
1035 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1037 _tbm_set_last_result(error);
1038 _tbm_surface_mutex_unlock();
1042 /* LCOV_EXCL_START */
1046 if (bufmgr_initialized && bufmgr) {
1047 LIST_DELINIT(&bufmgr->surf_list);
1048 _deinit_surface_bufmgr();
1051 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1052 width, height, _tbm_surface_internal_format_to_str(format), flags);
1054 _tbm_set_last_result(error);
1055 _tbm_surface_mutex_unlock();
1057 /* LCOV_EXCL_STOP */
1063 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1064 tbm_bo *bos, int num)
1066 struct _tbm_bufmgr *bufmgr;
1067 struct _tbm_surface *surf = NULL;
1069 bool bufmgr_initialized = false;
1071 _tbm_surface_mutex_lock();
1072 _tbm_set_last_result(TBM_ERROR_NONE);
1074 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1075 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1076 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1077 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1078 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1080 if (!g_surface_bufmgr) {
1081 _init_surface_bufmgr();
1082 if (!g_surface_bufmgr) {
1083 TBM_ERR("fail bufmgr initialization\n");
1084 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1085 goto check_valid_fail;
1087 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1088 bufmgr_initialized = true;
1091 bufmgr = g_surface_bufmgr;
1092 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1093 TBM_ERR("fail to validate the Bufmgr.\n");
1094 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1095 goto check_valid_fail;
1098 surf = calloc(1, sizeof(struct _tbm_surface));
1100 /* LCOV_EXCL_START */
1101 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1102 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1103 goto alloc_surf_fail;
1104 /* LCOV_EXCL_STOP */
1107 surf->magic = TBM_SURFACE_MAGIC;
1108 surf->bufmgr = bufmgr;
1109 surf->info.width = info->width;
1110 surf->info.height = info->height;
1111 surf->info.format = info->format;
1113 surf->info.bpp = info->bpp;
1115 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1116 if (!surf->info.bpp) {
1117 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1121 surf->info.num_planes = info->num_planes;
1124 /* get size, stride and offset */
1125 for (i = 0; i < info->num_planes; i++) {
1126 surf->info.planes[i].offset = info->planes[i].offset;
1127 surf->info.planes[i].stride = info->planes[i].stride;
1129 if (info->planes[i].size > 0)
1130 surf->info.planes[i].size = info->planes[i].size;
1132 uint32_t size = 0, offset = 0, stride = 0;
1135 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1136 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1137 goto plane_data_fail;
1139 surf->info.planes[i].size = size;
1143 surf->planes_bo_idx[i] = 0;
1145 surf->planes_bo_idx[i] = i;
1148 if (info->size > 0) {
1149 surf->info.size = info->size;
1151 surf->info.size = 0;
1152 for (i = 0; i < info->num_planes; i++)
1153 surf->info.size += surf->info.planes[i].size;
1156 surf->flags = TBM_BO_DEFAULT;
1158 /* create only one bo */
1159 surf->num_bos = num;
1160 for (i = 0; i < num; i++) {
1161 if (bos[i] == NULL) {
1162 TBM_ERR("bos[%d] is null.\n", i);
1163 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1167 surf->bos[i] = tbm_bo_ref(bos[i]);
1168 _tbm_bo_set_surface(bos[i], surf);
1171 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1172 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1174 LIST_INITHEAD(&surf->user_data_list);
1175 LIST_INITHEAD(&surf->debug_data_list);
1176 LIST_INITHEAD(&surf->destroy_funcs);
1178 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1180 _tbm_surface_mutex_unlock();
1184 /* LCOV_EXCL_START */
1188 for (i = 0; i < num; i++) {
1190 tbm_bo_unref(surf->bos[i]);
1195 if (bufmgr_initialized && bufmgr) {
1196 LIST_DELINIT(&bufmgr->surf_list);
1197 _deinit_surface_bufmgr();
1199 _tbm_surface_mutex_unlock();
1201 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1202 info->width, info->height,
1203 _tbm_surface_internal_format_to_str(info->format), num);
1204 /* LCOV_EXCL_STOP */
1210 tbm_surface_internal_destroy(tbm_surface_h surface)
1212 _tbm_surface_mutex_lock();
1213 _tbm_set_last_result(TBM_ERROR_NONE);
1215 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1219 if (surface->refcnt > 0) {
1220 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1221 _tbm_surface_mutex_unlock();
1225 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1227 if (surface->refcnt == 0)
1228 _tbm_surface_internal_destroy(surface);
1229 else // if (surface->refcnt < 0)
1230 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1232 _tbm_surface_mutex_unlock();
1236 tbm_surface_internal_ref(tbm_surface_h surface)
1238 _tbm_surface_mutex_lock();
1239 _tbm_set_last_result(TBM_ERROR_NONE);
1241 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1245 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1247 _tbm_surface_mutex_unlock();
1251 tbm_surface_internal_unref(tbm_surface_h surface)
1253 _tbm_surface_mutex_lock();
1254 _tbm_set_last_result(TBM_ERROR_NONE);
1256 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1260 if (surface->refcnt > 0) {
1261 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1262 _tbm_surface_mutex_unlock();
1266 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1268 if (surface->refcnt == 0)
1269 _tbm_surface_internal_destroy(surface);
1271 _tbm_surface_mutex_unlock();
1275 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1277 struct _tbm_surface *surf;
1280 _tbm_surface_mutex_lock();
1281 _tbm_set_last_result(TBM_ERROR_NONE);
1283 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1285 surf = (struct _tbm_surface *)surface;
1286 num = surf->num_bos;
1289 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1291 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1293 _tbm_surface_mutex_unlock();
1299 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
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), NULL);
1308 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1310 surf = (struct _tbm_surface *)surface;
1311 bo = surf->bos[bo_idx];
1313 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1315 _tbm_surface_mutex_unlock();
1321 tbm_surface_internal_get_size(tbm_surface_h surface)
1323 struct _tbm_surface *surf;
1326 _tbm_surface_mutex_lock();
1327 _tbm_set_last_result(TBM_ERROR_NONE);
1329 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1331 surf = (struct _tbm_surface *)surface;
1332 size = surf->info.size;
1334 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1336 _tbm_surface_mutex_unlock();
1342 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1343 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1345 struct _tbm_surface *surf;
1347 _tbm_surface_mutex_lock();
1348 _tbm_set_last_result(TBM_ERROR_NONE);
1350 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1351 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1353 surf = (struct _tbm_surface *)surface;
1355 if (plane_idx >= surf->info.num_planes) {
1356 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1357 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1358 _tbm_surface_mutex_unlock();
1363 *size = surf->info.planes[plane_idx].size;
1366 *offset = surf->info.planes[plane_idx].offset;
1369 *pitch = surf->info.planes[plane_idx].stride;
1371 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1372 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1373 surf->info.planes[plane_idx].stride);
1375 _tbm_surface_mutex_unlock();
1381 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1382 tbm_surface_info_s *info, int map)
1384 struct _tbm_surface *surf;
1385 tbm_bo_handle bo_handles[4];
1388 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1391 _tbm_surface_mutex_lock();
1392 _tbm_set_last_result(TBM_ERROR_NONE);
1394 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1396 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1398 surf = (struct _tbm_surface *)surface;
1400 memset(info, 0x00, sizeof(tbm_surface_info_s));
1401 info->width = surf->info.width;
1402 info->height = surf->info.height;
1403 info->format = surf->info.format;
1404 info->bpp = surf->info.bpp;
1405 info->size = surf->info.size;
1406 info->num_planes = surf->info.num_planes;
1408 for (i = 0; i < surf->info.num_planes; i++) {
1409 info->planes[i].size = surf->info.planes[i].size;
1410 info->planes[i].offset = surf->info.planes[i].offset;
1411 info->planes[i].stride = surf->info.planes[i].stride;
1412 planes_bo_idx[i] = surf->planes_bo_idx[i];
1415 for (i = 0; i < surf->num_bos; i++)
1416 bos[i] = surf->bos[i];
1418 num_bos = surf->num_bos;
1421 _tbm_surface_mutex_unlock();
1422 for (i = 0; i < num_bos; i++) {
1423 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1424 if (bo_handles[i].ptr == NULL) {
1425 for (j = 0; j < i; j++)
1426 tbm_bo_unmap(bos[j]);
1428 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1432 _tbm_surface_mutex_lock();
1434 for (i = 0; i < num_bos; i++) {
1435 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1436 if (bo_handles[i].ptr == NULL) {
1437 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1438 _tbm_surface_mutex_unlock();
1444 for (i = 0; i < info->num_planes; i++) {
1445 if (bo_handles[planes_bo_idx[i]].ptr)
1446 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1449 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1451 _tbm_surface_mutex_unlock();
1457 tbm_surface_internal_unmap(tbm_surface_h surface)
1459 struct _tbm_surface *surf;
1462 _tbm_surface_mutex_lock();
1463 _tbm_set_last_result(TBM_ERROR_NONE);
1465 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1467 surf = (struct _tbm_surface *)surface;
1469 for (i = 0; i < surf->num_bos; i++)
1470 tbm_bo_unmap(surf->bos[i]);
1472 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1474 _tbm_surface_mutex_unlock();
1478 tbm_surface_internal_get_width(tbm_surface_h surface)
1480 struct _tbm_surface *surf;
1483 _tbm_surface_mutex_lock();
1484 _tbm_set_last_result(TBM_ERROR_NONE);
1486 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1488 surf = (struct _tbm_surface *)surface;
1489 width = surf->info.width;
1491 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1493 _tbm_surface_mutex_unlock();
1499 tbm_surface_internal_get_height(tbm_surface_h surface)
1501 struct _tbm_surface *surf;
1502 unsigned int height;
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 height = surf->info.height;
1512 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1514 _tbm_surface_mutex_unlock();
1521 tbm_surface_internal_get_format(tbm_surface_h surface)
1523 struct _tbm_surface *surf;
1526 _tbm_surface_mutex_lock();
1527 _tbm_set_last_result(TBM_ERROR_NONE);
1529 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1531 surf = (struct _tbm_surface *)surface;
1532 format = surf->info.format;
1534 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1536 _tbm_surface_mutex_unlock();
1542 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1544 struct _tbm_surface *surf;
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);
1551 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1553 surf = (struct _tbm_surface *)surface;
1554 bo_idx = surf->planes_bo_idx[plane_idx];
1556 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1558 _tbm_surface_mutex_unlock();
1564 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1565 tbm_data_free data_free_func)
1567 tbm_user_data *data;
1569 _tbm_surface_mutex_lock();
1570 _tbm_set_last_result(TBM_ERROR_NONE);
1572 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1574 /* check if the data according to the key exist if so, return false. */
1575 data = user_data_lookup(&surface->user_data_list, key);
1577 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1578 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1579 _tbm_surface_mutex_unlock();
1583 data = user_data_create(key, data_free_func);
1585 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1586 _tbm_surface_mutex_unlock();
1590 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1592 LIST_ADD(&data->item_link, &surface->user_data_list);
1594 _tbm_surface_mutex_unlock();
1600 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1603 tbm_user_data *old_data;
1605 _tbm_surface_mutex_lock();
1606 _tbm_set_last_result(TBM_ERROR_NONE);
1608 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1610 old_data = user_data_lookup(&surface->user_data_list, key);
1612 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1613 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1614 _tbm_surface_mutex_unlock();
1618 if (old_data->data && old_data->free_func)
1619 old_data->free_func(old_data->data);
1621 old_data->data = data;
1623 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1625 _tbm_surface_mutex_unlock();
1631 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1634 tbm_user_data *old_data;
1636 _tbm_surface_mutex_lock();
1637 _tbm_set_last_result(TBM_ERROR_NONE);
1639 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1642 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1643 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1644 _tbm_surface_mutex_unlock();
1649 old_data = user_data_lookup(&surface->user_data_list, key);
1651 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1652 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1653 _tbm_surface_mutex_unlock();
1657 *data = old_data->data;
1659 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1661 _tbm_surface_mutex_unlock();
1667 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1670 tbm_user_data *old_data = (void *)0;
1672 _tbm_surface_mutex_lock();
1673 _tbm_set_last_result(TBM_ERROR_NONE);
1675 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1677 old_data = user_data_lookup(&surface->user_data_list, key);
1679 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1680 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1681 _tbm_surface_mutex_unlock();
1685 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1687 user_data_delete(old_data);
1689 _tbm_surface_mutex_unlock();
1694 /* LCOV_EXCL_START */
1696 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1698 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1700 return surface->debug_pid;
1704 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1706 _tbm_surface_mutex_lock();
1707 _tbm_set_last_result(TBM_ERROR_NONE);
1709 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1711 surface->debug_pid = pid;
1713 _tbm_surface_mutex_unlock();
1716 static tbm_surface_debug_data *
1717 _tbm_surface_internal_debug_data_create(char *key, char *value)
1719 tbm_surface_debug_data *debug_data = NULL;
1721 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1723 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1724 TBM_ERR("fail to allocate the debug_data.");
1728 if (key) debug_data->key = strdup(key);
1729 if (value) debug_data->value = strdup(value);
1735 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1737 if (!debug_data->value && !value)
1740 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1743 if (debug_data->value)
1744 free(debug_data->value);
1747 debug_data->value = strdup(value);
1749 debug_data->value = NULL;
1752 static tbm_surface_debug_data *
1753 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1755 tbm_surface_debug_data *debug_data = NULL;
1757 if (LIST_IS_EMPTY(list))
1760 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1761 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1769 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1771 tbm_surface_debug_data *debug_data = NULL;
1772 tbm_bufmgr bufmgr = NULL;
1774 _tbm_surface_mutex_lock();
1775 _tbm_set_last_result(TBM_ERROR_NONE);
1777 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1778 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1780 bufmgr = surface->bufmgr;
1782 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1784 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1786 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1788 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1790 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1791 _tbm_surface_mutex_unlock();
1795 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1798 /* add new debug key to list */
1799 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1801 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1803 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1806 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1808 _tbm_surface_mutex_unlock();
1814 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1816 tbm_surface_debug_data *old_data = NULL;
1818 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1820 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1821 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1822 if (!strcmp(old_data->key, key))
1823 return old_data->value;
1830 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1831 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1833 struct _tbm_surface_dump_buf_info {
1843 tbm_surface_info_s info;
1845 struct list_head link;
1848 struct _tbm_surface_dump_info {
1849 char *path; // copy???
1852 struct list_head *link;
1853 struct list_head surface_list; /* link of surface */
1856 static tbm_surface_dump_info *g_dump_info = NULL;
1857 static const char *dump_postfix[2] = {"png", "yuv"};
1858 static double scale_factor;
1861 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1862 void *data2, int size2, void *data3, int size3)
1865 unsigned int *blocks;
1867 if (_tbm_surface_check_file_is_symbolic_link(file))
1868 TBM_ERR("%s is symbolic link\n", file);
1870 fp = fopen(file, "w+");
1871 TBM_RETURN_IF_FAIL(fp != NULL);
1873 blocks = (unsigned int *)data1;
1874 fwrite(blocks, 1, size1, fp);
1877 blocks = (unsigned int *)data2;
1878 fwrite(blocks, 1, size2, fp);
1882 blocks = (unsigned int *)data3;
1883 fwrite(blocks, 1, size3, fp);
1890 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1892 unsigned int *blocks = (unsigned int *)data;
1895 png_bytep *row_pointers;
1898 if (_tbm_surface_check_file_is_symbolic_link(file))
1899 TBM_ERR("%s is symbolic link\n", file);
1901 fp = fopen(file, "wb");
1902 TBM_RETURN_IF_FAIL(fp != NULL);
1904 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1907 TBM_ERR("fail to create a png write structure.\n");
1912 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1914 TBM_ERR("fail to create a png info structure.\n");
1915 png_destroy_write_struct(&pPngStruct, NULL);
1920 if (setjmp(png_jmpbuf(pPngStruct))) {
1921 /* if png has problem of writing the file, we get here */
1922 TBM_ERR("fail to write png file.\n");
1923 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1928 png_init_io(pPngStruct, fp);
1929 if (format == TBM_FORMAT_XRGB8888) {
1931 png_set_IHDR(pPngStruct,
1938 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1941 png_set_IHDR(pPngStruct,
1946 PNG_COLOR_TYPE_RGBA,
1948 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1951 png_set_bgr(pPngStruct);
1952 png_write_info(pPngStruct, pPngInfo);
1954 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1955 if (!row_pointers) {
1956 TBM_ERR("fail to allocate the png row_pointers.\n");
1957 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1962 for (y = 0; y < height; ++y) {
1966 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1968 TBM_ERR("fail to allocate the png row.\n");
1969 for (x = 0; x < y; x++)
1970 png_free(pPngStruct, row_pointers[x]);
1971 png_free(pPngStruct, row_pointers);
1972 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1976 row_pointers[y] = (png_bytep)row;
1978 for (x = 0; x < width; ++x) {
1979 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1981 if (pixel_size == 3) { // XRGB8888 or XBGR8888
1982 if (format == TBM_FORMAT_XRGB8888) {
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;
1987 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
1988 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1989 row[2 + x * pixel_size] = (curBlock & 0xFF);
1991 } else { // ARGB8888 or ABGR8888
1992 if (format == TBM_FORMAT_ARGB8888) {
1993 row[x * pixel_size] = (curBlock & 0xFF);
1994 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1995 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1996 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1998 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
1999 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2000 row[2 + x * pixel_size] = (curBlock & 0xFF);
2001 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2007 png_write_image(pPngStruct, row_pointers);
2008 png_write_end(pPngStruct, pPngInfo);
2010 for (y = 0; y < height; y++)
2011 png_free(pPngStruct, row_pointers[y]);
2012 png_free(pPngStruct, row_pointers);
2014 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2020 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2022 TBM_RETURN_IF_FAIL(path != NULL);
2023 TBM_RETURN_IF_FAIL(w > 0);
2024 TBM_RETURN_IF_FAIL(h > 0);
2025 TBM_RETURN_IF_FAIL(count > 0);
2027 tbm_surface_dump_buf_info *buf_info = NULL;
2028 tbm_surface_h tbm_surface;
2029 tbm_surface_info_s info;
2034 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2038 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2039 TBM_RETURN_IF_FAIL(g_dump_info);
2041 LIST_INITHEAD(&g_dump_info->surface_list);
2042 g_dump_info->count = 0;
2043 g_dump_info->dump_max = count;
2045 /* get buffer size */
2046 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2047 if (tbm_surface == NULL) {
2048 TBM_ERR("tbm_surface_create fail\n");
2054 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2055 TBM_ERR("tbm_surface_get_info fail\n");
2056 tbm_surface_destroy(tbm_surface);
2061 buffer_size = info.size;
2062 tbm_surface_destroy(tbm_surface);
2064 /* create dump lists */
2065 for (i = 0; i < count; i++) {
2068 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2069 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2071 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2073 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2078 buf_info->index = i;
2080 buf_info->size = buffer_size;
2082 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2085 g_dump_info->path = path;
2086 g_dump_info->link = &g_dump_info->surface_list;
2090 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2095 /* free resources */
2096 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2097 tbm_surface_dump_buf_info *tmp;
2099 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2100 tbm_bo_unref(buf_info->bo);
2101 LIST_DEL(&buf_info->link);
2106 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2115 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2122 tbm_surface_internal_dump_start(path, w, h, count);
2123 scale_factor = scale;
2127 tbm_surface_internal_dump_end(void)
2129 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2130 tbm_bo_handle bo_handle;
2135 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2142 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2145 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2146 if (bo_handle.ptr == NULL) {
2147 tbm_bo_unref(buf_info->bo);
2148 LIST_DEL(&buf_info->link);
2153 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2154 TBM_INFO("Dump File.. %s generated.\n", file);
2156 if (buf_info->dirty) {
2157 void *ptr1 = NULL, *ptr2 = NULL;
2159 switch (buf_info->info.format) {
2160 case TBM_FORMAT_ARGB8888:
2161 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2162 buf_info->info.planes[0].stride >> 2,
2163 buf_info->info.height,
2164 buf_info->info.planes[0].stride,
2165 TBM_FORMAT_ARGB8888);
2167 case TBM_FORMAT_XRGB8888:
2168 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2169 buf_info->info.planes[0].stride >> 2,
2170 buf_info->info.height,
2171 buf_info->info.planes[0].stride,
2172 TBM_FORMAT_XRGB8888);
2174 case TBM_FORMAT_ABGR8888:
2175 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2176 buf_info->info.planes[0].stride >> 2,
2177 buf_info->info.height,
2178 buf_info->info.planes[0].stride,
2179 TBM_FORMAT_ABGR8888);
2181 case TBM_FORMAT_XBGR8888:
2182 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2183 buf_info->info.planes[0].stride >> 2,
2184 buf_info->info.height,
2185 buf_info->info.planes[0].stride,
2186 TBM_FORMAT_XBGR8888);
2188 case TBM_FORMAT_YVU420:
2189 case TBM_FORMAT_YUV420:
2190 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2191 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
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),
2197 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2199 case TBM_FORMAT_NV12:
2200 case TBM_FORMAT_NV21:
2201 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2202 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2203 buf_info->info.planes[0].stride * buf_info->info.height,
2205 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2208 case TBM_FORMAT_YUYV:
2209 case TBM_FORMAT_UYVY:
2210 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2211 buf_info->info.planes[0].stride * buf_info->info.height,
2215 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2218 } else if (buf_info->dirty_shm)
2219 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2220 buf_info->shm_stride >> 2,
2222 buf_info->shm_stride, 0);
2224 tbm_bo_unmap(buf_info->bo);
2225 tbm_bo_unref(buf_info->bo);
2226 LIST_DEL(&buf_info->link);
2233 TBM_INFO("Dump End..\n");
2236 static pixman_format_code_t
2237 _tbm_surface_internal_pixman_format_get(tbm_format format)
2240 case TBM_FORMAT_ARGB8888:
2241 case TBM_FORMAT_ABGR8888:
2242 return PIXMAN_a8r8g8b8;
2243 case TBM_FORMAT_XRGB8888:
2244 case TBM_FORMAT_XBGR8888:
2245 return PIXMAN_x8r8g8b8;
2254 * This function supports only if a buffer has below formats.
2255 * - TBM_FORMAT_ARGB8888
2256 * - TBM_FORMAT_XRGB8888
2257 * - TBM_FORMAT_ABGR8888
2258 * - TBM_FORMAT_XBGR8888
2260 static tbm_surface_error_e
2261 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2262 int format, int src_stride, int src_w, int src_h,
2263 int dst_stride, int dst_w, int dst_h)
2265 pixman_image_t *src_img = NULL, *dst_img = NULL;
2266 pixman_format_code_t pixman_format;
2267 pixman_transform_t t;
2268 struct pixman_f_transform ft;
2269 double scale_x, scale_y;
2271 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2272 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2274 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2275 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2278 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2279 (uint32_t*)src_ptr, src_stride);
2280 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2283 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2284 (uint32_t*)dst_ptr, dst_stride);
2285 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2287 pixman_f_transform_init_identity(&ft);
2289 scale_x = (double)src_w / dst_w;
2290 scale_y = (double)src_h / dst_h;
2292 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2293 pixman_f_transform_translate(&ft, NULL, 0, 0);
2294 pixman_transform_from_pixman_f_transform(&t, &ft);
2295 pixman_image_set_transform(src_img, &t);
2297 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2298 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2300 pixman_image_unref(src_img);
2301 pixman_image_unref(dst_img);
2303 return TBM_SURFACE_ERROR_NONE;
2307 pixman_image_unref(src_img);
2309 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2312 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2313 #define KEY_LEN 5 // "_XXXX"
2314 #define KEYS_LEN KEY_LEN * MAX_BOS
2316 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2318 char *keys, temp_key[KEY_LEN + 1];
2319 struct _tbm_surface *surf;
2323 _tbm_surface_mutex_lock();
2325 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2327 surf = (struct _tbm_surface *)surface;
2329 num_bos = surf->num_bos;
2330 if (num_bos > MAX_BOS)
2333 keys = calloc(KEYS_LEN + 1, sizeof(char));
2335 TBM_ERR("Failed to alloc memory");
2336 _tbm_surface_mutex_unlock();
2340 for (i = 0; i < num_bos; i++) {
2341 memset(temp_key, 0x00, KEY_LEN + 1);
2343 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2344 strncat(keys, temp_key, KEY_LEN + 1);
2347 _tbm_surface_mutex_unlock();
2352 static void _tbm_surface_internal_put_keys(char *keys)
2359 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2361 TBM_RETURN_IF_FAIL(surface != NULL);
2362 TBM_RETURN_IF_FAIL(type != NULL);
2364 tbm_surface_dump_buf_info *buf_info;
2365 struct list_head *next_link;
2366 tbm_surface_info_s info;
2367 tbm_bo_handle bo_handle;
2368 const char *postfix;
2369 const char *format = NULL;
2376 next_link = g_dump_info->link->next;
2377 TBM_RETURN_IF_FAIL(next_link != NULL);
2379 if (next_link == &g_dump_info->surface_list) {
2380 next_link = next_link->next;
2381 TBM_RETURN_IF_FAIL(next_link != NULL);
2384 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2385 TBM_RETURN_IF_FAIL(buf_info != NULL);
2387 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2388 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2390 if (scale_factor > 0.0) {
2393 if ((info.format != TBM_FORMAT_ARGB8888) && (info.format != TBM_FORMAT_XRGB8888) &&
2394 (info.format != TBM_FORMAT_ABGR8888) && (info.format != TBM_FORMAT_XBGR8888)) {
2395 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2396 _tbm_surface_internal_format_to_str(info.format));
2397 tbm_surface_unmap(surface);
2401 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2403 buf_info->info.width = info.width * scale_factor;
2404 buf_info->info.height = info.height * scale_factor;
2405 buf_info->info.format = info.format;
2406 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2407 if (!buf_info->info.bpp) {
2408 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2409 tbm_surface_unmap(surface);
2412 buf_info->info.num_planes = 1;
2413 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2414 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2416 if (buf_info->info.size > buf_info->size) {
2417 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2418 buf_info->info.size, buf_info->size);
2419 tbm_surface_unmap(surface);
2423 if (info.size > buf_info->size) {
2424 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2425 info.size, buf_info->size);
2426 tbm_surface_unmap(surface);
2430 /* make the file information */
2431 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2434 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2435 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888)) {
2436 postfix = dump_postfix[0];
2437 format = _tbm_surface_internal_format_to_str(info.format);
2439 postfix = dump_postfix[1];
2441 keys = _tbm_surface_internal_get_keys(surface);
2443 TBM_ERR("fail to get keys");
2444 tbm_surface_unmap(surface);
2449 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2450 if (!bo_handle.ptr) {
2451 TBM_ERR("fail to map bo");
2452 _tbm_surface_internal_put_keys(keys);
2453 tbm_surface_unmap(surface);
2456 memset(bo_handle.ptr, 0x00, buf_info->size);
2458 switch (info.format) {
2459 case TBM_FORMAT_ARGB8888:
2460 case TBM_FORMAT_XRGB8888:
2461 case TBM_FORMAT_ABGR8888:
2462 case TBM_FORMAT_XBGR8888:
2463 snprintf(buf_info->name, sizeof(buf_info->name),
2464 "%10.3f_%03d%s_%p_%s-%s.%s",
2465 _tbm_surface_internal_get_time(),
2466 g_dump_info->count++, keys, surface, format, type, postfix);
2468 if (scale_factor > 0.0) {
2469 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2471 buf_info->info.format,
2472 info.planes[0].stride,
2473 info.width, info.height,
2474 buf_info->info.planes[0].stride,
2475 buf_info->info.width,
2476 buf_info->info.height);
2477 if (ret != TBM_SURFACE_ERROR_NONE) {
2478 TBM_ERR("fail to scale buffer");
2479 tbm_bo_unmap(buf_info->bo);
2480 _tbm_surface_internal_put_keys(keys);
2481 tbm_surface_unmap(surface);
2485 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2487 case TBM_FORMAT_YVU420:
2488 case TBM_FORMAT_YUV420:
2489 snprintf(buf_info->name, sizeof(buf_info->name),
2490 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2491 _tbm_surface_internal_get_time(),
2492 g_dump_info->count++, keys, type, info.planes[0].stride,
2493 info.height, FOURCC_STR(info.format), postfix);
2494 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2495 bo_handle.ptr += info.planes[0].stride * info.height;
2496 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2497 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2498 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2500 case TBM_FORMAT_NV12:
2501 case TBM_FORMAT_NV21:
2502 snprintf(buf_info->name, sizeof(buf_info->name),
2503 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2504 _tbm_surface_internal_get_time(),
2505 g_dump_info->count++, keys, type, info.planes[0].stride,
2506 info.height, FOURCC_STR(info.format), postfix);
2507 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2508 bo_handle.ptr += info.planes[0].stride * info.height;
2509 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2511 case TBM_FORMAT_YUYV:
2512 case TBM_FORMAT_UYVY:
2513 snprintf(buf_info->name, sizeof(buf_info->name),
2514 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2515 _tbm_surface_internal_get_time(),
2516 g_dump_info->count++, keys, type, info.planes[0].stride,
2517 info.height, FOURCC_STR(info.format), postfix);
2518 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2521 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2522 tbm_bo_unmap(buf_info->bo);
2523 _tbm_surface_internal_put_keys(keys);
2524 tbm_surface_unmap(surface);
2528 tbm_bo_unmap(buf_info->bo);
2530 _tbm_surface_internal_put_keys(keys);
2532 tbm_surface_unmap(surface);
2534 buf_info->dirty = 1;
2535 buf_info->dirty_shm = 0;
2537 if (g_dump_info->count == 1000)
2538 g_dump_info->count = 0;
2540 g_dump_info->link = next_link;
2542 TBM_INFO("Dump %s \n", buf_info->name);
2545 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2548 TBM_RETURN_IF_FAIL(ptr != NULL);
2549 TBM_RETURN_IF_FAIL(w > 0);
2550 TBM_RETURN_IF_FAIL(h > 0);
2551 TBM_RETURN_IF_FAIL(stride > 0);
2552 TBM_RETURN_IF_FAIL(type != NULL);
2554 tbm_surface_dump_buf_info *buf_info;
2555 struct list_head *next_link;
2556 tbm_bo_handle bo_handle;
2557 int ret, size, dw = 0, dh = 0, dstride = 0;
2562 next_link = g_dump_info->link->next;
2563 TBM_RETURN_IF_FAIL(next_link != NULL);
2565 if (next_link == &g_dump_info->surface_list) {
2566 next_link = next_link->next;
2567 TBM_RETURN_IF_FAIL(next_link != NULL);
2570 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2571 TBM_RETURN_IF_FAIL(buf_info != NULL);
2573 if (scale_factor > 0.0) {
2576 dw = w * scale_factor;
2577 dh = h * scale_factor;
2579 size = dstride * dh;
2583 if (size > buf_info->size) {
2584 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2585 size, buf_info->size);
2590 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2591 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2593 memset(bo_handle.ptr, 0x00, buf_info->size);
2594 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2596 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2597 _tbm_surface_internal_get_time(),
2598 g_dump_info->count++, type, dump_postfix[0]);
2599 if (scale_factor > 0.0) {
2600 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2601 TBM_FORMAT_ARGB8888, stride,
2602 w, h, dstride, dw, dh);
2603 if (ret != TBM_SURFACE_ERROR_NONE) {
2604 TBM_ERR("fail to scale buffer");
2605 tbm_bo_unmap(buf_info->bo);
2608 buf_info->shm_stride = dstride;
2609 buf_info->shm_h = dh;
2611 memcpy(bo_handle.ptr, ptr, size);
2612 buf_info->shm_stride = stride;
2613 buf_info->shm_h = h;
2616 tbm_bo_unmap(buf_info->bo);
2618 buf_info->dirty = 0;
2619 buf_info->dirty_shm = 1;
2621 if (g_dump_info->count == 1000)
2622 g_dump_info->count = 0;
2624 g_dump_info->link = next_link;
2626 TBM_INFO("Dump %s \n", buf_info->name);
2630 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2632 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2633 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2634 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2636 tbm_surface_info_s info;
2637 const char *postfix;
2641 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2642 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2644 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2645 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888))
2646 postfix = dump_postfix[0];
2648 postfix = dump_postfix[1];
2650 if (strcmp(postfix, type)) {
2651 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2652 tbm_surface_unmap(surface);
2656 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2658 if (!access(file, 0)) {
2659 TBM_ERR("can't capture buffer, exist file %s", file);
2660 tbm_surface_unmap(surface);
2664 switch (info.format) {
2665 case TBM_FORMAT_ARGB8888:
2666 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2669 info.planes[0].stride,
2670 TBM_FORMAT_ARGB8888);
2672 case TBM_FORMAT_XRGB8888:
2673 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2676 info.planes[0].stride,
2677 TBM_FORMAT_XRGB8888);
2679 case TBM_FORMAT_ABGR8888:
2680 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2683 info.planes[0].stride,
2684 TBM_FORMAT_ABGR8888);
2686 case TBM_FORMAT_XBGR8888:
2687 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2690 info.planes[0].stride,
2691 TBM_FORMAT_XBGR8888);
2693 case TBM_FORMAT_YVU420:
2694 case TBM_FORMAT_YUV420:
2695 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2696 info.planes[0].stride * info.height,
2698 info.planes[1].stride * (info.height >> 1),
2700 info.planes[2].stride * (info.height >> 1));
2702 case TBM_FORMAT_NV12:
2703 case TBM_FORMAT_NV21:
2704 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2705 info.planes[0].stride * info.height,
2707 info.planes[1].stride * (info.height >> 1),
2710 case TBM_FORMAT_YUYV:
2711 case TBM_FORMAT_UYVY:
2712 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2713 info.planes[0].stride * info.height,
2717 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2718 tbm_surface_unmap(surface);
2722 tbm_surface_unmap(surface);
2724 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2730 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2731 const char *path, const char *name, const char *type)
2733 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2734 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2735 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2736 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2737 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2738 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2742 if (strcmp(dump_postfix[0], type)) {
2743 TBM_ERR("Not supported type:%s'", type);
2747 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2749 if (!access(file, 0)) {
2750 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2754 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2756 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2762 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2764 struct _tbm_surface *surf;
2766 _tbm_surface_mutex_lock();
2767 _tbm_set_last_result(TBM_ERROR_NONE);
2769 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2770 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2771 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2773 surf = (struct _tbm_surface *)surface;
2777 surf->damage.width = width;
2778 surf->damage.height = height;
2780 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2781 surface, x, y, width, height);
2783 _tbm_surface_mutex_unlock();
2789 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2791 struct _tbm_surface *surf;
2793 _tbm_surface_mutex_lock();
2794 _tbm_set_last_result(TBM_ERROR_NONE);
2796 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2798 surf = (struct _tbm_surface *)surface;
2800 if (x) *x = surf->damage.x;
2801 if (y) *y = surf->damage.y;
2802 if (width) *width = surf->damage.width;
2803 if (height) *height = surf->damage.height;
2805 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2806 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2808 _tbm_surface_mutex_unlock();
2814 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2816 struct _tbm_surface *surf;
2817 tbm_surface_destroy_func_info *func_info = NULL;
2819 _tbm_surface_mutex_lock();
2820 _tbm_set_last_result(TBM_ERROR_NONE);
2822 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2823 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2825 surf = (struct _tbm_surface *)surface;
2826 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2827 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2828 TBM_ERR("can't add twice");
2829 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2830 _tbm_surface_mutex_unlock();
2835 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2836 if (func_info == NULL) {
2837 TBM_ERR("alloc failed");
2838 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2839 _tbm_surface_mutex_unlock();
2843 func_info->destroy_func = func;
2844 func_info->user_data = user_data;
2846 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2848 _tbm_surface_mutex_unlock();
2854 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2856 struct _tbm_surface *surf;
2857 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2859 _tbm_surface_mutex_lock();
2860 _tbm_set_last_result(TBM_ERROR_NONE);
2862 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2863 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2865 surf = (struct _tbm_surface *)surface;
2866 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2867 if (func_info->destroy_func != func || func_info->user_data != user_data)
2870 LIST_DEL(&func_info->item_link);
2873 _tbm_surface_mutex_unlock();
2878 _tbm_surface_mutex_unlock();
2881 tbm_surface_buffer_data *
2882 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2884 tbm_surface_buffer_data *buffer_data = NULL;
2885 struct _tbm_bufmgr *bufmgr;
2887 _tbm_surface_mutex_lock();
2889 bufmgr = g_surface_bufmgr;
2890 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2892 // this function supports when the module suppport surface_data.
2893 TBM_SURFACE_RETURN_VAL_SET_ERR_NO_LOG_IF_FAIL(tbm_module_support_surface_data(bufmgr->module), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2895 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, error, TBM_ERROR_INVALID_PARAMETER);
2898 buffer_data = tbm_surface_data_export(surface->surface_data, error);
2899 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
2901 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
2903 _tbm_set_last_result(TBM_ERROR_NONE);
2904 _tbm_surface_mutex_unlock();
2910 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
2912 struct _tbm_surface *surf;
2913 struct _tbm_bufmgr *bufmgr;
2915 _tbm_surface_mutex_lock();
2917 bufmgr = g_surface_bufmgr;
2918 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2920 // this function supports when the module suppport surface_data.
2921 TBM_SURFACE_RETURN_VAL_SET_ERR_NO_LOG_IF_FAIL(tbm_module_support_surface_data(bufmgr->module), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2923 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2924 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2925 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2926 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2929 surf = _tbm_surface_internal_import_surface(bufmgr,
2930 (int)surface_info->width,
2931 (int)surface_info->height,
2932 (int)surface_info->format,
2935 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
2937 LIST_INITHEAD(&surf->user_data_list);
2938 LIST_INITHEAD(&surf->debug_data_list);
2939 LIST_INITHEAD(&surf->destroy_funcs);
2941 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
2943 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
2945 _tbm_set_last_result(TBM_ERROR_NONE);
2946 _tbm_surface_mutex_unlock();
2948 return (tbm_surface_h)surf;