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.", #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.", #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.", #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.", #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.", #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.", #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 */
122 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
124 LIST_DEL(&debug_data->item_link);
126 if (debug_data->key) free(debug_data->key);
127 if (debug_data->value) free(debug_data->value);
132 _tbm_surface_internal_format_to_str(tbm_format format)
136 return "TBM_FORMAT_C8";
137 case TBM_FORMAT_RGB332:
138 return "TBM_FORMAT_RGB332";
139 case TBM_FORMAT_BGR233:
140 return "TBM_FORMAT_BGR233";
141 case TBM_FORMAT_XRGB4444:
142 return "TBM_FORMAT_XRGB4444";
143 case TBM_FORMAT_XBGR4444:
144 return "TBM_FORMAT_XBGR4444";
145 case TBM_FORMAT_RGBX4444:
146 return "TBM_FORMAT_RGBX4444";
147 case TBM_FORMAT_BGRX4444:
148 return "TBM_FORMAT_BGRX4444";
149 case TBM_FORMAT_ARGB4444:
150 return "TBM_FORMAT_ARGB4444";
151 case TBM_FORMAT_ABGR4444:
152 return "TBM_FORMAT_ABGR4444";
153 case TBM_FORMAT_RGBA4444:
154 return "TBM_FORMAT_RGBA4444";
155 case TBM_FORMAT_BGRA4444:
156 return "TBM_FORMAT_BGRA4444";
157 case TBM_FORMAT_XRGB1555:
158 return "TBM_FORMAT_XRGB1555";
159 case TBM_FORMAT_XBGR1555:
160 return "TBM_FORMAT_XBGR1555";
161 case TBM_FORMAT_RGBX5551:
162 return "TBM_FORMAT_RGBX5551";
163 case TBM_FORMAT_BGRX5551:
164 return "TBM_FORMAT_BGRX5551";
165 case TBM_FORMAT_ARGB1555:
166 return "TBM_FORMAT_ARGB1555";
167 case TBM_FORMAT_ABGR1555:
168 return "TBM_FORMAT_ABGR1555";
169 case TBM_FORMAT_RGBA5551:
170 return "TBM_FORMAT_RGBA5551";
171 case TBM_FORMAT_BGRA5551:
172 return "TBM_FORMAT_BGRA5551";
173 case TBM_FORMAT_RGB565:
174 return "TBM_FORMAT_RGB565";
175 case TBM_FORMAT_BGR565:
176 return "TBM_FORMAT_BGR565";
177 case TBM_FORMAT_RGB888:
178 return "TBM_FORMAT_RGB888";
179 case TBM_FORMAT_BGR888:
180 return "TBM_FORMAT_BGR888";
181 case TBM_FORMAT_XRGB8888:
182 return "TBM_FORMAT_XRGB8888";
183 case TBM_FORMAT_XBGR8888:
184 return "TBM_FORMAT_XBGR8888";
185 case TBM_FORMAT_RGBX8888:
186 return "TBM_FORMAT_RGBX8888";
187 case TBM_FORMAT_BGRX8888:
188 return "TBM_FORMAT_BGRX8888";
189 case TBM_FORMAT_ARGB8888:
190 return "TBM_FORMAT_ARGB8888";
191 case TBM_FORMAT_ABGR8888:
192 return "TBM_FORMAT_ABGR8888";
193 case TBM_FORMAT_RGBA8888:
194 return "TBM_FORMAT_RGBA8888";
195 case TBM_FORMAT_BGRA8888:
196 return "TBM_FORMAT_BGRA8888";
197 case TBM_FORMAT_XRGB2101010:
198 return "TBM_FORMAT_XRGB2101010";
199 case TBM_FORMAT_XBGR2101010:
200 return "TBM_FORMAT_XBGR2101010";
201 case TBM_FORMAT_RGBX1010102:
202 return "TBM_FORMAT_RGBX1010102";
203 case TBM_FORMAT_BGRX1010102:
204 return "TBM_FORMAT_BGRX1010102";
205 case TBM_FORMAT_ARGB2101010:
206 return "TBM_FORMAT_ARGB2101010";
207 case TBM_FORMAT_ABGR2101010:
208 return "TBM_FORMAT_ABGR2101010";
209 case TBM_FORMAT_RGBA1010102:
210 return "TBM_FORMAT_RGBA1010102";
211 case TBM_FORMAT_BGRA1010102:
212 return "TBM_FORMAT_BGRA1010102";
213 case TBM_FORMAT_YUYV:
214 return "TBM_FORMAT_YUYV";
215 case TBM_FORMAT_YVYU:
216 return "TBM_FORMAT_YVYU";
217 case TBM_FORMAT_UYVY:
218 return "TBM_FORMAT_UYVY";
219 case TBM_FORMAT_VYUY:
220 return "TBM_FORMAT_VYUY";
221 case TBM_FORMAT_AYUV:
222 return "TBM_FORMAT_AYUV";
223 case TBM_FORMAT_NV12:
224 return "TBM_FORMAT_NV12";
225 case TBM_FORMAT_NV21:
226 return "TBM_FORMAT_NV21";
227 case TBM_FORMAT_NV16:
228 return "TBM_FORMAT_NV16";
229 case TBM_FORMAT_NV61:
230 return "TBM_FORMAT_NV61";
231 case TBM_FORMAT_YUV410:
232 return "TBM_FORMAT_YUV410";
233 case TBM_FORMAT_YVU410:
234 return "TBM_FORMAT_YVU410";
235 case TBM_FORMAT_YUV411:
236 return "TBM_FORMAT_YUV411";
237 case TBM_FORMAT_YVU411:
238 return "TBM_FORMAT_YVU411";
239 case TBM_FORMAT_YUV420:
240 return "TBM_FORMAT_YUV420";
241 case TBM_FORMAT_YVU420:
242 return "TBM_FORMAT_YVU420";
243 case TBM_FORMAT_YUV422:
244 return "TBM_FORMAT_YUV422";
245 case TBM_FORMAT_YVU422:
246 return "TBM_FORMAT_YVU422";
247 case TBM_FORMAT_YUV444:
248 return "TBM_FORMAT_YUV444";
249 case TBM_FORMAT_YVU444:
250 return "TBM_FORMAT_YVU444";
251 case TBM_FORMAT_NV12MT:
252 return "TBM_FORMAT_NV12MT";
259 _tbm_surface_mutex_lock(void)
261 pthread_mutex_lock(&tbm_surface_lock);
265 _tbm_surface_mutex_unlock(void)
267 pthread_mutex_unlock(&tbm_surface_lock);
271 _init_surface_bufmgr(void)
273 g_surface_bufmgr = tbm_bufmgr_init(-1);
277 _deinit_surface_bufmgr(void)
279 if (!g_surface_bufmgr)
282 tbm_bufmgr_deinit(g_surface_bufmgr);
283 g_surface_bufmgr = NULL;
288 _tbm_surface_internal_magic_check(tbm_surface_h surface)
290 if (surface->magic != TBM_SURFACE_MAGIC)
297 _tbm_surface_internal_is_valid(tbm_surface_h surface)
300 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
301 TBM_ERR("error: No valid tbm_surface is NULL");
305 if (!_tbm_surface_internal_magic_check(surface)) {
306 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
307 TBM_ERR("error: No valid tbm_surface(%p)", surface);
315 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
316 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
318 TBM_RETURN_VAL_IF_FAIL(surface, 0);
319 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
321 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
322 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
325 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
326 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
327 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
328 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
330 error = tbm_module_get_plane_data(bufmgr->module, surf->info.format, plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
331 if (error != TBM_ERROR_NONE) {
332 _tbm_set_last_result(error);
340 _tbm_surface_internal_destroy(tbm_surface_h surface)
343 tbm_bufmgr bufmgr = surface->bufmgr;
344 tbm_user_data *old_data = NULL, *tmp = NULL;
345 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
346 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
348 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
349 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
350 func_info->destroy_func(surface, func_info->user_data);
352 TBM_DBG("free destroy_funcs %p", surface);
353 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
354 LIST_DEL(&func_info->item_link);
359 /* destory the user_data_list */
360 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
361 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
362 TBM_DBG("free user_data");
363 user_data_delete(old_data);
367 for (i = 0; i < surface->num_bos; i++) {
368 surface->bos[i]->surface = NULL;
370 tbm_bo_unref(surface->bos[i]);
371 surface->bos[i] = NULL;
374 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
375 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
376 _tbm_surface_internal_debug_data_delete(debug_old_data);
379 LIST_DEL(&surface->item_link);
382 if (surface->surface_data) {
383 tbm_surface_data_free(surface->surface_data);
384 surface->surface_data = NULL;
390 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
391 LIST_DELINIT(&bufmgr->surf_list);
393 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
394 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
395 _tbm_surface_internal_debug_data_delete(debug_old_data);
399 _deinit_surface_bufmgr();
403 /* LCOV_EXCL_START */
405 _tbm_surface_check_file_is_symbolic_link(const char* path)
412 if (stat(path, &sb) != 0)
415 if (S_ISLNK(sb.st_mode))
423 _tbm_surface_internal_get_num_planes(tbm_format format)
429 case TBM_FORMAT_RGB332:
430 case TBM_FORMAT_BGR233:
431 case TBM_FORMAT_XRGB4444:
432 case TBM_FORMAT_XBGR4444:
433 case TBM_FORMAT_RGBX4444:
434 case TBM_FORMAT_BGRX4444:
435 case TBM_FORMAT_ARGB4444:
436 case TBM_FORMAT_ABGR4444:
437 case TBM_FORMAT_RGBA4444:
438 case TBM_FORMAT_BGRA4444:
439 case TBM_FORMAT_XRGB1555:
440 case TBM_FORMAT_XBGR1555:
441 case TBM_FORMAT_RGBX5551:
442 case TBM_FORMAT_BGRX5551:
443 case TBM_FORMAT_ARGB1555:
444 case TBM_FORMAT_ABGR1555:
445 case TBM_FORMAT_RGBA5551:
446 case TBM_FORMAT_BGRA5551:
447 case TBM_FORMAT_RGB565:
448 case TBM_FORMAT_BGR565:
449 case TBM_FORMAT_RGB888:
450 case TBM_FORMAT_BGR888:
451 case TBM_FORMAT_XRGB8888:
452 case TBM_FORMAT_XBGR8888:
453 case TBM_FORMAT_RGBX8888:
454 case TBM_FORMAT_BGRX8888:
455 case TBM_FORMAT_ARGB8888:
456 case TBM_FORMAT_ABGR8888:
457 case TBM_FORMAT_RGBA8888:
458 case TBM_FORMAT_BGRA8888:
459 case TBM_FORMAT_XRGB2101010:
460 case TBM_FORMAT_XBGR2101010:
461 case TBM_FORMAT_RGBX1010102:
462 case TBM_FORMAT_BGRX1010102:
463 case TBM_FORMAT_ARGB2101010:
464 case TBM_FORMAT_ABGR2101010:
465 case TBM_FORMAT_RGBA1010102:
466 case TBM_FORMAT_BGRA1010102:
467 case TBM_FORMAT_YUYV:
468 case TBM_FORMAT_YVYU:
469 case TBM_FORMAT_UYVY:
470 case TBM_FORMAT_VYUY:
471 case TBM_FORMAT_AYUV:
474 case TBM_FORMAT_NV12:
475 case TBM_FORMAT_NV12MT:
476 case TBM_FORMAT_NV21:
477 case TBM_FORMAT_NV16:
478 case TBM_FORMAT_NV61:
481 case TBM_FORMAT_YUV410:
482 case TBM_FORMAT_YVU410:
483 case TBM_FORMAT_YUV411:
484 case TBM_FORMAT_YVU411:
485 case TBM_FORMAT_YUV420:
486 case TBM_FORMAT_YVU420:
487 case TBM_FORMAT_YUV422:
488 case TBM_FORMAT_YVU422:
489 case TBM_FORMAT_YUV444:
490 case TBM_FORMAT_YVU444:
495 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
503 _tbm_surface_internal_get_bpp(tbm_format format)
510 case TBM_FORMAT_RGB332:
511 case TBM_FORMAT_BGR233:
514 case TBM_FORMAT_XRGB4444:
515 case TBM_FORMAT_XBGR4444:
516 case TBM_FORMAT_RGBX4444:
517 case TBM_FORMAT_BGRX4444:
518 case TBM_FORMAT_ARGB4444:
519 case TBM_FORMAT_ABGR4444:
520 case TBM_FORMAT_RGBA4444:
521 case TBM_FORMAT_BGRA4444:
522 case TBM_FORMAT_XRGB1555:
523 case TBM_FORMAT_XBGR1555:
524 case TBM_FORMAT_RGBX5551:
525 case TBM_FORMAT_BGRX5551:
526 case TBM_FORMAT_ARGB1555:
527 case TBM_FORMAT_ABGR1555:
528 case TBM_FORMAT_RGBA5551:
529 case TBM_FORMAT_BGRA5551:
530 case TBM_FORMAT_RGB565:
531 case TBM_FORMAT_BGR565:
534 case TBM_FORMAT_RGB888:
535 case TBM_FORMAT_BGR888:
538 case TBM_FORMAT_XRGB8888:
539 case TBM_FORMAT_XBGR8888:
540 case TBM_FORMAT_RGBX8888:
541 case TBM_FORMAT_BGRX8888:
542 case TBM_FORMAT_ARGB8888:
543 case TBM_FORMAT_ABGR8888:
544 case TBM_FORMAT_RGBA8888:
545 case TBM_FORMAT_BGRA8888:
546 case TBM_FORMAT_XRGB2101010:
547 case TBM_FORMAT_XBGR2101010:
548 case TBM_FORMAT_RGBX1010102:
549 case TBM_FORMAT_BGRX1010102:
550 case TBM_FORMAT_ARGB2101010:
551 case TBM_FORMAT_ABGR2101010:
552 case TBM_FORMAT_RGBA1010102:
553 case TBM_FORMAT_BGRA1010102:
556 case TBM_FORMAT_YUYV:
557 case TBM_FORMAT_YVYU:
558 case TBM_FORMAT_UYVY:
559 case TBM_FORMAT_VYUY:
562 case TBM_FORMAT_AYUV:
565 case TBM_FORMAT_NV12:
566 case TBM_FORMAT_NV12MT:
567 case TBM_FORMAT_NV21:
570 case TBM_FORMAT_NV16:
571 case TBM_FORMAT_NV61:
574 case TBM_FORMAT_YUV410:
575 case TBM_FORMAT_YVU410:
578 case TBM_FORMAT_YUV411:
579 case TBM_FORMAT_YVU411:
580 case TBM_FORMAT_YUV420:
581 case TBM_FORMAT_YVU420:
584 case TBM_FORMAT_YUV422:
585 case TBM_FORMAT_YVU422:
588 case TBM_FORMAT_YUV444:
589 case TBM_FORMAT_YVU444:
593 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
601 _tbm_surface_internal_free(struct _tbm_surface *surf)
609 static struct _tbm_surface *
610 _tbm_surface_internal_alloc(tbm_bufmgr bufmgr, int width, int height, int format, tbm_error_e *error)
612 struct _tbm_surface *surf = NULL;
614 surf = calloc(1, sizeof(struct _tbm_surface));
616 /* LCOV_EXCL_START */
617 TBM_ERR("memory allocation failed.");
618 *error = TBM_ERROR_OUT_OF_MEMORY;
624 surf->magic = TBM_SURFACE_MAGIC;
625 surf->bufmgr = bufmgr;
626 surf->info.width = width;
627 surf->info.height = height;
628 surf->info.format = format;
629 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
630 if (!surf->info.bpp) {
631 /* LCOV_EXCL_START */
632 TBM_ERR("_tbm_surface_internal_get_bpp failed. format:%d error:%s", format, tbm_error_str(*error));
633 *error = tbm_get_last_error();
639 // get number of planes
640 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
641 if (!surf->info.num_planes) {
642 /* LCOV_EXCL_START */
643 TBM_ERR("_tbm_surface_internal_get_num_planes failed. format:%d error:%s", format, tbm_error_str(*error));
644 *error = tbm_get_last_error();
654 _tbm_surface_internal_set_data(struct _tbm_surface *surf, int flags, int can_share_surface)
657 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;;
659 tbm_bo_data **bo_data_array = NULL;
663 // set data with surface
664 if (can_share_surface) {
665 // set infomation of planes
666 for (i = 0; i < surf->info.num_planes; i++) {
667 error = tbm_surface_data_get_plane_data(surf->surface_data, i, &size, &offset, &stride, &bo_idx);
668 if (error != TBM_ERROR_NONE) {
669 TBM_ERR("tbm_surface_data_get_plane_data failed. error:%s", tbm_error_str(error));
673 surf->info.planes[i].size = size;
674 surf->info.planes[i].offset = offset;
675 surf->info.planes[i].stride = stride;
676 surf->planes_bo_idx[i] = bo_idx;
679 // calculate the size of a surface
680 for (i = 0; i < surf->info.num_planes; i++)
681 surf->info.size += surf->info.planes[i].size;
683 // get the bo_data_array
684 bo_data_array = tbm_surface_data_get_bo_data_array(surf->surface_data, &num_bos, &memory_types, &error);
685 if (!bo_data_array) {
686 TBM_ERR("tbm_surface_data_get_bo_data_array failed. error:%s", tbm_error_str(error));
691 surf->num_bos = num_bos;
694 surf->flags = memory_types;
696 // allocate the array of tbm_bos
697 for (i = 0; i < num_bos; i++) {
698 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_bo_data(surf->bufmgr, bo_data_array[i], memory_types, &error);
700 TBM_ERR("tbm_bufmgr_internal_alloc_bo_with_bo_data failed. error:%s idx:%d", tbm_error_str(error), i);
704 _tbm_bo_set_surface(surf->bos[i], surf);
707 // only free the pointers of the arrary, not the item(tbm_bo_data).
708 // the item(tbm_bo_data) is set to the tbm_bo. tbm_bo handles the life cycle of the tbm_bo_data.
711 // set infomation of planes
712 for (i = 0; i < surf->info.num_planes; i++) {
713 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
714 TBM_ERR("_tbm_surface_internal_query_plane_data failed.");
715 error = tbm_get_last_error();
719 surf->info.planes[i].size = size;
720 surf->info.planes[i].offset = offset;
721 surf->info.planes[i].stride = stride;
722 surf->planes_bo_idx[i] = bo_idx;
725 // calculate the number of bos
727 for (i = 0; i < surf->info.num_planes; i++) {
728 surf->info.size += surf->info.planes[i].size;
730 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
731 surf->num_bos = surf->planes_bo_idx[i] + 1;
737 // allocate the array of tbm_bos
738 for (i = 0; i < surf->num_bos; i++) {
740 for (j = 0; j < surf->info.num_planes; j++) {
741 if (surf->planes_bo_idx[j] == i)
742 bo_size += surf->info.planes[j].size;
745 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_format(surf->bufmgr,
746 surf->info.format, i, surf->info.width, surf->info.height,
747 surf->info.bpp/8, flags, &error);
749 surf->bos[i] = tbm_bo_alloc(surf->bufmgr, bo_size, flags);
751 TBM_ERR("tbm_bo_alloc failed. idx:%d", i);
752 error = tbm_get_last_error();
757 _tbm_bo_set_surface(surf->bos[i], surf);
761 return TBM_ERROR_NONE;
764 if (can_share_surface) {
765 for (j = 0; j < num_bos; j++) {
766 if (bo_data_array[j]) {
767 free(bo_data_array[j]);
774 for (j = 0; j < i; j++) {
776 tbm_bo_unref(surf->bos[j]);
782 static struct _tbm_surface *
783 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
785 struct _tbm_surface *surf;
786 int can_share_surface = 0;
788 surf = _tbm_surface_internal_alloc(bufmgr, width, height, format, error);
790 /* LCOV_EXCL_START */
791 TBM_ERR("_tbm_surface_internal_alloc failed.");
796 can_share_surface = tbm_bufmgr_internal_support_capabilites(bufmgr, TBM_BUFMGR_CAPABILITY_SHARE_SURFACE);
797 if (can_share_surface) {
798 // alloc surface_data
799 surf->surface_data = tbm_module_alloc_surface_data(bufmgr->module, width, height, format, flags, error);
800 if (!surf->surface_data) {
801 TBM_ERR("tbm_module_alloc_surface_data failed. width:%d height:%d format:%d error:%s",
802 width, height, format, tbm_error_str(*error));
803 _tbm_surface_internal_free(surf);
808 // set the surface data
809 *error = _tbm_surface_internal_set_data(surf, flags, can_share_surface);
810 if (*error != TBM_ERROR_NONE) {
811 tbm_surface_data_free(surf->surface_data);
812 surf->surface_data = NULL;
813 _tbm_surface_internal_free(surf);
820 static struct _tbm_surface *
821 _tbm_surface_internal_import_surface(tbm_bufmgr bufmgr, int width, int height, int format, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
823 struct _tbm_surface *surf = NULL;
825 surf = _tbm_surface_internal_alloc(bufmgr, width, height, format, error);
827 /* LCOV_EXCL_START */
828 TBM_ERR("_tbm_surface_internal_alloc failed.");
833 // import surface_data
834 surf->surface_data = tbm_module_import_surface_data(bufmgr->module, width, height, format, buffer_data, error);
835 if (!surf->surface_data) {
836 /* LCOV_EXCL_START */
837 TBM_ERR("tbm_module_import_surface_data failed. width:%d height:%d format:%d error:%s",
838 width, height, format, tbm_error_str(*error));
839 _tbm_surface_internal_free(surf);
844 // set the surface data
845 *error = _tbm_surface_internal_set_data(surf, TBM_BO_DEFAULT, 1);
846 if (*error != TBM_ERROR_NONE) {
847 /* LCOV_EXCL_START */
848 tbm_surface_data_free(surf->surface_data);
849 surf->surface_data = NULL;
850 _tbm_surface_internal_free(surf);
859 tbm_surface_internal_is_valid(tbm_surface_h surface)
863 _tbm_surface_mutex_lock();
864 _tbm_set_last_result(TBM_ERROR_NONE);
866 /* Return silently if surface is null. */
868 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
869 _tbm_surface_mutex_unlock();
873 ret = _tbm_surface_internal_is_valid(surface);
875 _tbm_surface_mutex_unlock();
881 tbm_surface_internal_query_supported_formats(uint32_t **formats,
884 struct _tbm_bufmgr *bufmgr;
885 bool bufmgr_initialized = false;
888 _tbm_surface_mutex_lock();
889 _tbm_set_last_result(TBM_ERROR_NONE);
891 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
892 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
894 if (!g_surface_bufmgr) {
895 _init_surface_bufmgr();
896 if (!g_surface_bufmgr) {
897 TBM_ERR("fail bufmgr initialization");
898 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
901 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
902 bufmgr_initialized = true;
905 bufmgr = g_surface_bufmgr;
907 error = tbm_module_get_supported_formats(bufmgr->module, formats, num);
908 if (error != TBM_ERROR_NONE) {
909 _tbm_set_last_result(error);
913 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)", g_surface_bufmgr, *num);
915 if (bufmgr_initialized) {
916 LIST_DELINIT(&g_surface_bufmgr->surf_list);
917 _deinit_surface_bufmgr();
920 _tbm_surface_mutex_unlock();
924 /* LCOV_EXCL_START */
926 if (bufmgr_initialized) {
927 LIST_DELINIT(&g_surface_bufmgr->surf_list);
928 _deinit_surface_bufmgr();
930 _tbm_surface_mutex_unlock();
932 TBM_ERR("error: tbm_bufmgr(%p)", g_surface_bufmgr);
939 tbm_surface_internal_get_num_planes(tbm_format format)
943 _tbm_surface_mutex_lock();
944 _tbm_set_last_result(TBM_ERROR_NONE);
946 num_planes = _tbm_surface_internal_get_num_planes(format);
948 TBM_ERR("error: tbm_error(%s)", tbm_error_str(tbm_get_last_error()));
949 _tbm_surface_mutex_unlock();
953 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)", _tbm_surface_internal_format_to_str(format), num_planes);
955 _tbm_surface_mutex_unlock();
961 tbm_surface_internal_get_bpp(tbm_format format)
965 _tbm_surface_mutex_lock();
966 _tbm_set_last_result(TBM_ERROR_NONE);
968 bpp = _tbm_surface_internal_get_bpp(format);
970 TBM_ERR("error: tbm_error(%s)", tbm_error_str(tbm_get_last_error()));
971 _tbm_surface_mutex_unlock();
975 _tbm_surface_mutex_unlock();
977 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)", _tbm_surface_internal_format_to_str(format), bpp);
983 tbm_surface_internal_create_with_flags(int width, int height,
984 int format, int flags)
986 struct _tbm_bufmgr *bufmgr;
987 struct _tbm_surface *surf = NULL;
988 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
989 bool bufmgr_initialized = false;
991 _tbm_surface_mutex_lock();
992 _tbm_set_last_result(TBM_ERROR_NONE);
994 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
995 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
997 if (!g_surface_bufmgr) {
998 _init_surface_bufmgr();
999 if (!g_surface_bufmgr) {
1000 TBM_ERR("fail bufmgr initialization");
1001 error = TBM_ERROR_INVALID_OPERATION;
1002 goto check_valid_fail;
1004 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1005 bufmgr_initialized = true;
1008 bufmgr = g_surface_bufmgr;
1009 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1010 TBM_ERR("The bufmgr is invalid");
1011 error = TBM_ERROR_INVALID_PARAMETER;
1012 goto check_valid_fail;
1015 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1017 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1018 goto surface_alloc_fail;
1021 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)",
1022 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1024 LIST_INITHEAD(&surf->user_data_list);
1025 LIST_INITHEAD(&surf->debug_data_list);
1026 LIST_INITHEAD(&surf->destroy_funcs);
1028 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1030 _tbm_set_last_result(error);
1031 _tbm_surface_mutex_unlock();
1035 /* LCOV_EXCL_START */
1039 if (bufmgr_initialized && bufmgr) {
1040 LIST_DELINIT(&bufmgr->surf_list);
1041 _deinit_surface_bufmgr();
1044 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)",
1045 width, height, _tbm_surface_internal_format_to_str(format), flags);
1047 _tbm_set_last_result(error);
1048 _tbm_surface_mutex_unlock();
1050 /* LCOV_EXCL_STOP */
1056 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1057 tbm_bo *bos, int num)
1059 struct _tbm_bufmgr *bufmgr;
1060 struct _tbm_surface *surf = NULL;
1062 bool bufmgr_initialized = false;
1064 _tbm_surface_mutex_lock();
1065 _tbm_set_last_result(TBM_ERROR_NONE);
1067 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1068 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1069 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1070 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1071 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1073 if (!g_surface_bufmgr) {
1074 _init_surface_bufmgr();
1075 if (!g_surface_bufmgr) {
1076 TBM_ERR("fail bufmgr initialization");
1077 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1078 goto check_valid_fail;
1080 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1081 bufmgr_initialized = true;
1084 bufmgr = g_surface_bufmgr;
1085 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1086 TBM_ERR("fail to validate the Bufmgr.");
1087 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1088 goto check_valid_fail;
1091 surf = calloc(1, sizeof(struct _tbm_surface));
1093 /* LCOV_EXCL_START */
1094 TBM_ERR("fail to allocate struct _tbm_surface.");
1095 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1096 goto alloc_surf_fail;
1097 /* LCOV_EXCL_STOP */
1100 surf->magic = TBM_SURFACE_MAGIC;
1101 surf->bufmgr = bufmgr;
1102 surf->info.width = info->width;
1103 surf->info.height = info->height;
1104 surf->info.format = info->format;
1106 surf->info.bpp = info->bpp;
1108 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1109 if (!surf->info.bpp) {
1110 TBM_ERR("fail to get bpp. error(%s)", tbm_error_str(tbm_get_last_error()));
1114 surf->info.num_planes = info->num_planes;
1117 /* get size, stride and offset */
1118 for (i = 0; i < info->num_planes; i++) {
1119 surf->info.planes[i].offset = info->planes[i].offset;
1120 surf->info.planes[i].stride = info->planes[i].stride;
1122 if (info->planes[i].size > 0)
1123 surf->info.planes[i].size = info->planes[i].size;
1125 uint32_t size = 0, offset = 0, stride = 0;
1128 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1129 TBM_ERR("fail to get plane_data. error(%s)", tbm_error_str(tbm_get_last_error()));
1130 goto plane_data_fail;
1132 surf->info.planes[i].size = size;
1136 surf->planes_bo_idx[i] = 0;
1138 surf->planes_bo_idx[i] = i;
1141 if (info->size > 0) {
1142 surf->info.size = info->size;
1144 surf->info.size = 0;
1145 for (i = 0; i < info->num_planes; i++)
1146 surf->info.size += surf->info.planes[i].size;
1149 surf->flags = TBM_BO_DEFAULT;
1151 /* create only one bo */
1152 surf->num_bos = num;
1153 for (i = 0; i < num; i++) {
1154 if (bos[i] == NULL) {
1155 TBM_ERR("bos[%d] is null.", i);
1156 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1160 surf->bos[i] = tbm_bo_ref(bos[i]);
1161 _tbm_bo_set_surface(bos[i], surf);
1164 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)", surf,
1165 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1167 LIST_INITHEAD(&surf->user_data_list);
1168 LIST_INITHEAD(&surf->debug_data_list);
1169 LIST_INITHEAD(&surf->destroy_funcs);
1171 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1173 _tbm_surface_mutex_unlock();
1177 /* LCOV_EXCL_START */
1181 for (i = 0; i < num; i++) {
1183 tbm_bo_unref(surf->bos[i]);
1188 if (bufmgr_initialized && bufmgr) {
1189 LIST_DELINIT(&bufmgr->surf_list);
1190 _deinit_surface_bufmgr();
1192 _tbm_surface_mutex_unlock();
1194 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)",
1195 info->width, info->height,
1196 _tbm_surface_internal_format_to_str(info->format), num);
1197 /* LCOV_EXCL_STOP */
1203 tbm_surface_internal_destroy(tbm_surface_h surface)
1205 _tbm_surface_mutex_lock();
1206 _tbm_set_last_result(TBM_ERROR_NONE);
1208 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1212 if (surface->refcnt > 0) {
1213 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)", surface->refcnt, surface);
1214 _tbm_surface_mutex_unlock();
1218 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)", surface, surface->refcnt);
1220 if (surface->refcnt == 0)
1221 _tbm_surface_internal_destroy(surface);
1222 else // if (surface->refcnt < 0)
1223 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1225 _tbm_surface_mutex_unlock();
1229 tbm_surface_internal_ref(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 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)", surface, surface->refcnt);
1240 _tbm_surface_mutex_unlock();
1244 tbm_surface_internal_unref(tbm_surface_h surface)
1246 _tbm_surface_mutex_lock();
1247 _tbm_set_last_result(TBM_ERROR_NONE);
1249 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1253 if (surface->refcnt > 0) {
1254 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)", surface->refcnt, surface);
1255 _tbm_surface_mutex_unlock();
1259 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)", surface, surface->refcnt);
1261 if (surface->refcnt == 0)
1262 _tbm_surface_internal_destroy(surface);
1264 _tbm_surface_mutex_unlock();
1268 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1270 struct _tbm_surface *surf;
1273 _tbm_surface_mutex_lock();
1274 _tbm_set_last_result(TBM_ERROR_NONE);
1276 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1278 surf = (struct _tbm_surface *)surface;
1279 num = surf->num_bos;
1282 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1284 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)", surface, num);
1286 _tbm_surface_mutex_unlock();
1292 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1294 struct _tbm_surface *surf;
1297 _tbm_surface_mutex_lock();
1298 _tbm_set_last_result(TBM_ERROR_NONE);
1300 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1301 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1303 surf = (struct _tbm_surface *)surface;
1304 bo = surf->bos[bo_idx];
1306 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)", surface, bo_idx, bo);
1308 _tbm_surface_mutex_unlock();
1314 tbm_surface_internal_get_size(tbm_surface_h surface)
1316 struct _tbm_surface *surf;
1319 _tbm_surface_mutex_lock();
1320 _tbm_set_last_result(TBM_ERROR_NONE);
1322 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1324 surf = (struct _tbm_surface *)surface;
1325 size = surf->info.size;
1327 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)", surface, size);
1329 _tbm_surface_mutex_unlock();
1335 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1336 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1338 struct _tbm_surface *surf;
1340 _tbm_surface_mutex_lock();
1341 _tbm_set_last_result(TBM_ERROR_NONE);
1343 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1344 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1346 surf = (struct _tbm_surface *)surface;
1348 if (plane_idx >= surf->info.num_planes) {
1349 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)", surface, plane_idx);
1350 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1351 _tbm_surface_mutex_unlock();
1356 *size = surf->info.planes[plane_idx].size;
1359 *offset = surf->info.planes[plane_idx].offset;
1362 *pitch = surf->info.planes[plane_idx].stride;
1364 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)", surface, plane_idx,
1365 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1366 surf->info.planes[plane_idx].stride);
1368 _tbm_surface_mutex_unlock();
1374 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1375 tbm_surface_info_s *info, int map)
1377 struct _tbm_surface *surf;
1378 tbm_bo_handle bo_handles[4];
1381 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1385 _tbm_surface_mutex_lock();
1386 _tbm_set_last_result(TBM_ERROR_NONE);
1388 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1390 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1392 surf = (struct _tbm_surface *)surface;
1394 memset(info, 0x00, sizeof(tbm_surface_info_s));
1395 info->width = surf->info.width;
1396 info->height = surf->info.height;
1397 info->format = surf->info.format;
1398 info->bpp = surf->info.bpp;
1399 info->size = surf->info.size;
1400 info->num_planes = surf->info.num_planes;
1402 for (i = 0; i < surf->info.num_planes; i++) {
1403 info->planes[i].size = surf->info.planes[i].size;
1404 info->planes[i].offset = surf->info.planes[i].offset;
1405 info->planes[i].stride = surf->info.planes[i].stride;
1406 planes_bo_idx[i] = surf->planes_bo_idx[i];
1409 for (i = 0; i < surf->num_bos; i++)
1410 bos[i] = surf->bos[i];
1412 num_bos = surf->num_bos;
1415 _tbm_surface_mutex_unlock();
1416 for (i = 0; i < num_bos; i++) {
1417 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1418 if (bo_handles[i].ptr == NULL) {
1419 error = tbm_get_last_error();
1420 for (j = 0; j < i; j++)
1421 tbm_bo_unmap(bos[j]);
1423 _tbm_set_last_result(error);
1424 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)", surface, opt, map);
1428 _tbm_surface_mutex_lock();
1430 for (i = 0; i < num_bos; i++) {
1431 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1432 if (bo_handles[i].ptr == NULL) {
1433 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)", surface, opt, map);
1434 _tbm_surface_mutex_unlock();
1440 for (i = 0; i < info->num_planes; i++) {
1441 if (bo_handles[planes_bo_idx[i]].ptr)
1442 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1445 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)", surface, opt, map);
1447 _tbm_surface_mutex_unlock();
1453 tbm_surface_internal_unmap(tbm_surface_h surface)
1455 struct _tbm_surface *surf;
1458 _tbm_surface_mutex_lock();
1459 _tbm_set_last_result(TBM_ERROR_NONE);
1461 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1463 surf = (struct _tbm_surface *)surface;
1465 for (i = 0; i < surf->num_bos; i++)
1466 tbm_bo_unmap(surf->bos[i]);
1468 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surface);
1470 _tbm_surface_mutex_unlock();
1474 tbm_surface_internal_get_width(tbm_surface_h surface)
1476 struct _tbm_surface *surf;
1479 _tbm_surface_mutex_lock();
1480 _tbm_set_last_result(TBM_ERROR_NONE);
1482 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1484 surf = (struct _tbm_surface *)surface;
1485 width = surf->info.width;
1487 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)", surface, width);
1489 _tbm_surface_mutex_unlock();
1495 tbm_surface_internal_get_height(tbm_surface_h surface)
1497 struct _tbm_surface *surf;
1498 unsigned int height;
1500 _tbm_surface_mutex_lock();
1501 _tbm_set_last_result(TBM_ERROR_NONE);
1503 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1505 surf = (struct _tbm_surface *)surface;
1506 height = surf->info.height;
1508 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)", surface, height);
1510 _tbm_surface_mutex_unlock();
1517 tbm_surface_internal_get_format(tbm_surface_h surface)
1519 struct _tbm_surface *surf;
1522 _tbm_surface_mutex_lock();
1523 _tbm_set_last_result(TBM_ERROR_NONE);
1525 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1527 surf = (struct _tbm_surface *)surface;
1528 format = surf->info.format;
1530 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)", surface, _tbm_surface_internal_format_to_str(format));
1532 _tbm_surface_mutex_unlock();
1538 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1540 struct _tbm_surface *surf;
1543 _tbm_surface_mutex_lock();
1544 _tbm_set_last_result(TBM_ERROR_NONE);
1546 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1547 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1549 surf = (struct _tbm_surface *)surface;
1550 bo_idx = surf->planes_bo_idx[plane_idx];
1552 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)", surface, plane_idx, bo_idx);
1554 _tbm_surface_mutex_unlock();
1560 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1561 tbm_data_free data_free_func)
1563 tbm_user_data *data;
1565 _tbm_surface_mutex_lock();
1566 _tbm_set_last_result(TBM_ERROR_NONE);
1568 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1570 /* check if the data according to the key exist if so, return false. */
1571 data = user_data_lookup(&surface->user_data_list, key);
1573 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)", surface, key);
1574 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1575 _tbm_surface_mutex_unlock();
1579 data = user_data_create(key, data_free_func);
1581 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)", surface, key);
1582 _tbm_surface_mutex_unlock();
1586 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)", surface, key, data);
1588 LIST_ADD(&data->item_link, &surface->user_data_list);
1590 _tbm_surface_mutex_unlock();
1596 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1599 tbm_user_data *old_data;
1601 _tbm_surface_mutex_lock();
1602 _tbm_set_last_result(TBM_ERROR_NONE);
1604 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1606 old_data = user_data_lookup(&surface->user_data_list, key);
1608 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)", surface, key);
1609 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1610 _tbm_surface_mutex_unlock();
1614 if (old_data->data && old_data->free_func)
1615 old_data->free_func(old_data->data);
1617 old_data->data = data;
1619 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)", surface, key, old_data->data);
1621 _tbm_surface_mutex_unlock();
1627 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1630 tbm_user_data *old_data;
1632 _tbm_surface_mutex_lock();
1633 _tbm_set_last_result(TBM_ERROR_NONE);
1635 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1638 TBM_ERR("error: tbm_surface(%p) key(%lu)", surface, key);
1639 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1640 _tbm_surface_mutex_unlock();
1645 old_data = user_data_lookup(&surface->user_data_list, key);
1647 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)", surface, key);
1648 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1649 _tbm_surface_mutex_unlock();
1653 *data = old_data->data;
1655 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)", surface, key, old_data->data);
1657 _tbm_surface_mutex_unlock();
1663 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1666 tbm_user_data *old_data = (void *)0;
1668 _tbm_surface_mutex_lock();
1669 _tbm_set_last_result(TBM_ERROR_NONE);
1671 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1673 old_data = user_data_lookup(&surface->user_data_list, key);
1675 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)", surface, key);
1676 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1677 _tbm_surface_mutex_unlock();
1681 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)", surface, key, old_data->data);
1683 user_data_delete(old_data);
1685 _tbm_surface_mutex_unlock();
1690 /* LCOV_EXCL_START */
1692 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1694 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1696 return surface->debug_pid;
1700 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1702 _tbm_surface_mutex_lock();
1703 _tbm_set_last_result(TBM_ERROR_NONE);
1705 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1707 surface->debug_pid = pid;
1709 _tbm_surface_mutex_unlock();
1712 static tbm_surface_debug_data *
1713 _tbm_surface_internal_debug_data_create(char *key, char *value)
1715 tbm_surface_debug_data *debug_data = NULL;
1717 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1719 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1720 TBM_ERR("fail to allocate the debug_data.");
1724 if (key) debug_data->key = strdup(key);
1725 if (value) debug_data->value = strdup(value);
1731 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1733 if (!debug_data->value && !value)
1736 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1739 if (debug_data->value)
1740 free(debug_data->value);
1743 debug_data->value = strdup(value);
1745 debug_data->value = NULL;
1748 static tbm_surface_debug_data *
1749 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1751 tbm_surface_debug_data *debug_data = NULL;
1753 if (LIST_IS_EMPTY(list))
1756 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1757 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1765 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1767 tbm_surface_debug_data *debug_data = NULL;
1768 tbm_bufmgr bufmgr = NULL;
1770 _tbm_surface_mutex_lock();
1771 _tbm_set_last_result(TBM_ERROR_NONE);
1773 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1774 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1776 bufmgr = surface->bufmgr;
1778 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1780 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1782 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1784 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1786 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)", surface, key, value);
1787 _tbm_surface_mutex_unlock();
1791 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1794 /* add new debug key to list */
1795 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1797 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1799 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1802 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)", surface, key, value);
1804 _tbm_surface_mutex_unlock();
1810 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1812 tbm_surface_debug_data *old_data = NULL;
1814 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1816 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1817 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1818 if (!strcmp(old_data->key, key))
1819 return old_data->value;
1826 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1827 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1829 struct _tbm_surface_dump_buf_info {
1839 tbm_surface_info_s info;
1841 struct list_head link;
1844 struct _tbm_surface_dump_info {
1845 char *path; // copy???
1848 struct list_head *link;
1849 struct list_head surface_list; /* link of surface */
1852 static tbm_surface_dump_info *g_dump_info = NULL;
1853 static const char *dump_postfix[2] = {"png", "yuv"};
1854 static double scale_factor;
1857 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1858 void *data2, int size2, void *data3, int size3)
1861 unsigned int *blocks;
1863 if (_tbm_surface_check_file_is_symbolic_link(file))
1864 TBM_ERR("%s is symbolic link", file);
1866 fp = fopen(file, "w+");
1867 TBM_RETURN_IF_FAIL(fp != NULL);
1869 blocks = (unsigned int *)data1;
1870 fwrite(blocks, 1, size1, fp);
1873 blocks = (unsigned int *)data2;
1874 fwrite(blocks, 1, size2, fp);
1878 blocks = (unsigned int *)data3;
1879 fwrite(blocks, 1, size3, fp);
1886 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1888 unsigned int *blocks = (unsigned int *)data;
1891 png_bytep *row_pointers;
1894 if (_tbm_surface_check_file_is_symbolic_link(file))
1895 TBM_ERR("%s is symbolic link", file);
1897 fp = fopen(file, "wb");
1898 TBM_RETURN_IF_FAIL(fp != NULL);
1900 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1903 TBM_ERR("fail to create a png write structure.");
1908 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1910 TBM_ERR("fail to create a png info structure.");
1911 png_destroy_write_struct(&pPngStruct, NULL);
1916 if (setjmp(png_jmpbuf(pPngStruct))) {
1917 /* if png has problem of writing the file, we get here */
1918 TBM_ERR("fail to write png file.");
1919 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1924 png_init_io(pPngStruct, fp);
1925 if (format == TBM_FORMAT_XRGB8888) {
1927 png_set_IHDR(pPngStruct,
1934 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1937 png_set_IHDR(pPngStruct,
1942 PNG_COLOR_TYPE_RGBA,
1944 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1947 png_set_bgr(pPngStruct);
1948 png_write_info(pPngStruct, pPngInfo);
1950 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1951 if (!row_pointers) {
1952 TBM_ERR("fail to allocate the png row_pointers.");
1953 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1958 for (y = 0; y < height; ++y) {
1962 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1964 TBM_ERR("fail to allocate the png row.");
1965 for (x = 0; x < y; x++)
1966 png_free(pPngStruct, row_pointers[x]);
1967 png_free(pPngStruct, row_pointers);
1968 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1972 row_pointers[y] = (png_bytep)row;
1974 for (x = 0; x < width; ++x) {
1975 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1977 if (pixel_size == 3) { // XRGB8888 or XBGR8888
1978 if (format == TBM_FORMAT_XRGB8888) {
1979 row[x * pixel_size] = (curBlock & 0xFF);
1980 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1981 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1983 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
1984 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1985 row[2 + x * pixel_size] = (curBlock & 0xFF);
1987 } else { // ARGB8888 or ABGR8888
1988 if (format == TBM_FORMAT_ARGB8888) {
1989 row[x * pixel_size] = (curBlock & 0xFF);
1990 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1991 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1992 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1994 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
1995 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1996 row[2 + x * pixel_size] = (curBlock & 0xFF);
1997 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2003 png_write_image(pPngStruct, row_pointers);
2004 png_write_end(pPngStruct, pPngInfo);
2006 for (y = 0; y < height; y++)
2007 png_free(pPngStruct, row_pointers[y]);
2008 png_free(pPngStruct, row_pointers);
2010 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2016 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2018 TBM_RETURN_IF_FAIL(path != NULL);
2019 TBM_RETURN_IF_FAIL(w > 0);
2020 TBM_RETURN_IF_FAIL(h > 0);
2021 TBM_RETURN_IF_FAIL(count > 0);
2023 tbm_surface_dump_buf_info *buf_info = NULL;
2024 tbm_surface_h tbm_surface;
2025 tbm_surface_info_s info;
2030 TBM_WRN("waring already running the tbm_surface_internal_dump.");
2034 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2035 TBM_RETURN_IF_FAIL(g_dump_info);
2037 LIST_INITHEAD(&g_dump_info->surface_list);
2038 g_dump_info->count = 0;
2039 g_dump_info->dump_max = count;
2041 /* get buffer size */
2042 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2043 if (tbm_surface == NULL) {
2044 TBM_ERR("tbm_surface_create fail");
2050 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2051 TBM_ERR("tbm_surface_get_info fail");
2052 tbm_surface_destroy(tbm_surface);
2057 buffer_size = info.size;
2058 tbm_surface_destroy(tbm_surface);
2060 /* create dump lists */
2061 for (i = 0; i < count; i++) {
2064 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2065 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2067 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2069 TBM_ERR("fail to allocate the tbm_bo[%d]", i);
2074 buf_info->index = i;
2076 buf_info->size = buffer_size;
2078 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2081 g_dump_info->path = path;
2082 g_dump_info->link = &g_dump_info->surface_list;
2086 TBM_INFO("Dump Start.. path:%s, count:%d", g_dump_info->path, count);
2091 /* free resources */
2092 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2093 tbm_surface_dump_buf_info *tmp;
2095 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2096 tbm_bo_unref(buf_info->bo);
2097 LIST_DEL(&buf_info->link);
2102 TBM_ERR("Dump Start fail.. path:%s", g_dump_info->path);
2111 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2118 tbm_surface_internal_dump_start(path, w, h, count);
2119 scale_factor = scale;
2123 tbm_surface_internal_dump_end(void)
2125 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2126 tbm_bo_handle bo_handle;
2131 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2138 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2141 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2142 if (bo_handle.ptr == NULL) {
2143 tbm_bo_unref(buf_info->bo);
2144 LIST_DEL(&buf_info->link);
2149 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2150 TBM_INFO("Dump File.. %s generated.", file);
2152 if (buf_info->dirty) {
2153 void *ptr1 = NULL, *ptr2 = NULL;
2155 switch (buf_info->info.format) {
2156 case TBM_FORMAT_ARGB8888:
2157 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2158 buf_info->info.planes[0].stride >> 2,
2159 buf_info->info.height,
2160 buf_info->info.planes[0].stride,
2161 TBM_FORMAT_ARGB8888);
2163 case TBM_FORMAT_XRGB8888:
2164 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2165 buf_info->info.planes[0].stride >> 2,
2166 buf_info->info.height,
2167 buf_info->info.planes[0].stride,
2168 TBM_FORMAT_XRGB8888);
2170 case TBM_FORMAT_ABGR8888:
2171 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2172 buf_info->info.planes[0].stride >> 2,
2173 buf_info->info.height,
2174 buf_info->info.planes[0].stride,
2175 TBM_FORMAT_ABGR8888);
2177 case TBM_FORMAT_XBGR8888:
2178 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2179 buf_info->info.planes[0].stride >> 2,
2180 buf_info->info.height,
2181 buf_info->info.planes[0].stride,
2182 TBM_FORMAT_XBGR8888);
2184 case TBM_FORMAT_YVU420:
2185 case TBM_FORMAT_YUV420:
2186 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2187 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2188 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2189 buf_info->info.planes[0].stride * buf_info->info.height,
2191 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2193 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2195 case TBM_FORMAT_NV12:
2196 case TBM_FORMAT_NV21:
2197 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2198 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2199 buf_info->info.planes[0].stride * buf_info->info.height,
2201 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2204 case TBM_FORMAT_YUYV:
2205 case TBM_FORMAT_UYVY:
2206 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2207 buf_info->info.planes[0].stride * buf_info->info.height,
2211 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2214 } else if (buf_info->dirty_shm)
2215 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2216 buf_info->shm_stride >> 2,
2218 buf_info->shm_stride, 0);
2220 tbm_bo_unmap(buf_info->bo);
2221 tbm_bo_unref(buf_info->bo);
2222 LIST_DEL(&buf_info->link);
2229 TBM_INFO("Dump End..");
2232 static pixman_format_code_t
2233 _tbm_surface_internal_pixman_format_get(tbm_format format)
2236 case TBM_FORMAT_ARGB8888:
2237 case TBM_FORMAT_ABGR8888:
2238 return PIXMAN_a8r8g8b8;
2239 case TBM_FORMAT_XRGB8888:
2240 case TBM_FORMAT_XBGR8888:
2241 return PIXMAN_x8r8g8b8;
2250 * This function supports only if a buffer has below formats.
2251 * - TBM_FORMAT_ARGB8888
2252 * - TBM_FORMAT_XRGB8888
2253 * - TBM_FORMAT_ABGR8888
2254 * - TBM_FORMAT_XBGR8888
2256 static tbm_surface_error_e
2257 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2258 int format, int src_stride, int src_w, int src_h,
2259 int dst_stride, int dst_w, int dst_h)
2261 pixman_image_t *src_img = NULL, *dst_img = NULL;
2262 pixman_format_code_t pixman_format;
2263 pixman_transform_t t;
2264 struct pixman_f_transform ft;
2265 double scale_x, scale_y;
2267 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2268 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2270 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2271 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2274 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2275 (uint32_t*)src_ptr, src_stride);
2276 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2279 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2280 (uint32_t*)dst_ptr, dst_stride);
2281 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2283 pixman_f_transform_init_identity(&ft);
2285 scale_x = (double)src_w / dst_w;
2286 scale_y = (double)src_h / dst_h;
2288 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2289 pixman_f_transform_translate(&ft, NULL, 0, 0);
2290 pixman_transform_from_pixman_f_transform(&t, &ft);
2291 pixman_image_set_transform(src_img, &t);
2293 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2294 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2296 pixman_image_unref(src_img);
2297 pixman_image_unref(dst_img);
2299 return TBM_SURFACE_ERROR_NONE;
2303 pixman_image_unref(src_img);
2305 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2308 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2309 #define KEY_LEN 5 // "_XXXX"
2310 #define KEYS_LEN KEY_LEN * MAX_BOS
2312 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2314 char *keys, temp_key[KEY_LEN + 1];
2315 struct _tbm_surface *surf;
2319 _tbm_surface_mutex_lock();
2321 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2323 surf = (struct _tbm_surface *)surface;
2325 num_bos = surf->num_bos;
2326 if (num_bos > MAX_BOS)
2329 keys = calloc(KEYS_LEN + 1, sizeof(char));
2331 TBM_ERR("Failed to alloc memory");
2332 _tbm_surface_mutex_unlock();
2336 for (i = 0; i < num_bos; i++) {
2337 memset(temp_key, 0x00, KEY_LEN + 1);
2339 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2340 strncat(keys, temp_key, KEY_LEN + 1);
2343 _tbm_surface_mutex_unlock();
2348 static void _tbm_surface_internal_put_keys(char *keys)
2355 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2357 TBM_RETURN_IF_FAIL(surface != NULL);
2358 TBM_RETURN_IF_FAIL(type != NULL);
2360 tbm_surface_dump_buf_info *buf_info;
2361 struct list_head *next_link;
2362 tbm_surface_info_s info;
2363 tbm_bo_handle bo_handle;
2364 const char *postfix;
2365 const char *format = NULL;
2373 next_link = g_dump_info->link->next;
2374 TBM_RETURN_IF_FAIL(next_link != NULL);
2376 if (next_link == &g_dump_info->surface_list) {
2377 next_link = next_link->next;
2378 TBM_RETURN_IF_FAIL(next_link != NULL);
2381 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2382 TBM_RETURN_IF_FAIL(buf_info != NULL);
2384 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2385 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2387 if (scale_factor > 0.0) {
2390 if ((info.format != TBM_FORMAT_ARGB8888) && (info.format != TBM_FORMAT_XRGB8888) &&
2391 (info.format != TBM_FORMAT_ABGR8888) && (info.format != TBM_FORMAT_XBGR8888)) {
2392 TBM_WRN("Dump with scale skip. unsupported format(%s)",
2393 _tbm_surface_internal_format_to_str(info.format));
2394 tbm_surface_unmap(surface);
2398 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2400 buf_info->info.width = info.width * scale_factor;
2401 buf_info->info.height = info.height * scale_factor;
2402 buf_info->info.format = info.format;
2403 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2404 if (!buf_info->info.bpp) {
2405 TBM_ERR("fail to get bpp. error(%s)", tbm_error_str(tbm_get_last_error()));
2406 tbm_surface_unmap(surface);
2409 buf_info->info.num_planes = 1;
2410 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2411 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2413 if (buf_info->info.size > buf_info->size) {
2414 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)",
2415 buf_info->info.size, buf_info->size);
2416 tbm_surface_unmap(surface);
2420 if (info.size > buf_info->size) {
2421 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)",
2422 info.size, buf_info->size);
2423 tbm_surface_unmap(surface);
2427 /* make the file information */
2428 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2431 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2432 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888)) {
2433 postfix = dump_postfix[0];
2434 format = _tbm_surface_internal_format_to_str(info.format);
2436 postfix = dump_postfix[1];
2438 keys = _tbm_surface_internal_get_keys(surface);
2440 TBM_ERR("fail to get keys");
2441 tbm_surface_unmap(surface);
2446 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2447 if (!bo_handle.ptr) {
2448 TBM_ERR("fail to map bo");
2449 _tbm_surface_internal_put_keys(keys);
2450 tbm_surface_unmap(surface);
2453 memset(bo_handle.ptr, 0x00, buf_info->size);
2455 clock_gettime(CLOCK_MONOTONIC, &tp);
2457 switch (info.format) {
2458 case TBM_FORMAT_ARGB8888:
2459 case TBM_FORMAT_XRGB8888:
2460 case TBM_FORMAT_ABGR8888:
2461 case TBM_FORMAT_XBGR8888:
2462 snprintf(buf_info->name, sizeof(buf_info->name),
2463 "%d.%03d_%03d%s_%p_%s-%s.%s",
2464 (int)tp.tv_sec, (int)tp.tv_nsec / 1000000,
2465 g_dump_info->count++, keys, surface, format, type, postfix);
2467 if (scale_factor > 0.0) {
2468 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2470 buf_info->info.format,
2471 info.planes[0].stride,
2472 info.width, info.height,
2473 buf_info->info.planes[0].stride,
2474 buf_info->info.width,
2475 buf_info->info.height);
2476 if (ret != TBM_SURFACE_ERROR_NONE) {
2477 TBM_ERR("fail to scale buffer");
2478 tbm_bo_unmap(buf_info->bo);
2479 _tbm_surface_internal_put_keys(keys);
2480 tbm_surface_unmap(surface);
2484 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2486 case TBM_FORMAT_YVU420:
2487 case TBM_FORMAT_YUV420:
2488 snprintf(buf_info->name, sizeof(buf_info->name),
2489 "%d.%03d_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2490 (int)tp.tv_sec, (int)tp.tv_nsec / 1000000,
2491 g_dump_info->count++, keys, type, info.planes[0].stride,
2492 info.height, FOURCC_STR(info.format), postfix);
2493 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2494 bo_handle.ptr += info.planes[0].stride * info.height;
2495 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2496 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2497 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2499 case TBM_FORMAT_NV12:
2500 case TBM_FORMAT_NV21:
2501 snprintf(buf_info->name, sizeof(buf_info->name),
2502 "%d.%03d_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2503 (int)tp.tv_sec, (int)tp.tv_nsec / 1000000,
2504 g_dump_info->count++, keys, type, info.planes[0].stride,
2505 info.height, FOURCC_STR(info.format), postfix);
2506 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2507 bo_handle.ptr += info.planes[0].stride * info.height;
2508 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2510 case TBM_FORMAT_YUYV:
2511 case TBM_FORMAT_UYVY:
2512 snprintf(buf_info->name, sizeof(buf_info->name),
2513 "%d.%03d_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2514 (int)tp.tv_sec, (int)tp.tv_nsec / 1000000,
2515 g_dump_info->count++, keys, type, info.planes[0].stride,
2516 info.height, FOURCC_STR(info.format), postfix);
2517 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2520 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2521 tbm_bo_unmap(buf_info->bo);
2522 _tbm_surface_internal_put_keys(keys);
2523 tbm_surface_unmap(surface);
2527 tbm_bo_unmap(buf_info->bo);
2529 _tbm_surface_internal_put_keys(keys);
2531 tbm_surface_unmap(surface);
2533 buf_info->dirty = 1;
2534 buf_info->dirty_shm = 0;
2536 if (g_dump_info->count == 1000)
2537 g_dump_info->count = 0;
2539 g_dump_info->link = next_link;
2541 TBM_INFO("Dump %s ", buf_info->name);
2544 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2547 TBM_RETURN_IF_FAIL(ptr != NULL);
2548 TBM_RETURN_IF_FAIL(w > 0);
2549 TBM_RETURN_IF_FAIL(h > 0);
2550 TBM_RETURN_IF_FAIL(stride > 0);
2551 TBM_RETURN_IF_FAIL(type != NULL);
2553 tbm_surface_dump_buf_info *buf_info;
2554 struct list_head *next_link;
2555 tbm_bo_handle bo_handle;
2556 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)",
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 clock_gettime(CLOCK_MONOTONIC, &tp);
2598 snprintf(buf_info->name, sizeof(buf_info->name), "%d.%03d_%03d-%s.%s",
2599 (int)tp.tv_sec, (int)tp.tv_nsec / 1000000,
2600 g_dump_info->count++, type, dump_postfix[0]);
2601 if (scale_factor > 0.0) {
2602 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2603 TBM_FORMAT_ARGB8888, stride,
2604 w, h, dstride, dw, dh);
2605 if (ret != TBM_SURFACE_ERROR_NONE) {
2606 TBM_ERR("fail to scale buffer");
2607 tbm_bo_unmap(buf_info->bo);
2610 buf_info->shm_stride = dstride;
2611 buf_info->shm_h = dh;
2613 memcpy(bo_handle.ptr, ptr, size);
2614 buf_info->shm_stride = stride;
2615 buf_info->shm_h = h;
2618 tbm_bo_unmap(buf_info->bo);
2620 buf_info->dirty = 0;
2621 buf_info->dirty_shm = 1;
2623 if (g_dump_info->count == 1000)
2624 g_dump_info->count = 0;
2626 g_dump_info->link = next_link;
2628 TBM_INFO("Dump %s ", buf_info->name);
2632 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2634 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2635 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2636 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2638 tbm_surface_info_s info;
2639 const char *postfix;
2643 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2644 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2646 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2647 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888))
2648 postfix = dump_postfix[0];
2650 postfix = dump_postfix[1];
2652 if (strcmp(postfix, type)) {
2653 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2654 tbm_surface_unmap(surface);
2658 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2660 if (!access(file, 0)) {
2661 TBM_ERR("can't capture buffer, exist file %s", file);
2662 tbm_surface_unmap(surface);
2666 switch (info.format) {
2667 case TBM_FORMAT_ARGB8888:
2668 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2671 info.planes[0].stride,
2672 TBM_FORMAT_ARGB8888);
2674 case TBM_FORMAT_XRGB8888:
2675 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2678 info.planes[0].stride,
2679 TBM_FORMAT_XRGB8888);
2681 case TBM_FORMAT_ABGR8888:
2682 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2685 info.planes[0].stride,
2686 TBM_FORMAT_ABGR8888);
2688 case TBM_FORMAT_XBGR8888:
2689 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2692 info.planes[0].stride,
2693 TBM_FORMAT_XBGR8888);
2695 case TBM_FORMAT_YVU420:
2696 case TBM_FORMAT_YUV420:
2697 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2698 info.planes[0].stride * info.height,
2700 info.planes[1].stride * (info.height >> 1),
2702 info.planes[2].stride * (info.height >> 1));
2704 case TBM_FORMAT_NV12:
2705 case TBM_FORMAT_NV21:
2706 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2707 info.planes[0].stride * info.height,
2709 info.planes[1].stride * (info.height >> 1),
2712 case TBM_FORMAT_YUYV:
2713 case TBM_FORMAT_UYVY:
2714 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2715 info.planes[0].stride * info.height,
2719 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2720 tbm_surface_unmap(surface);
2724 tbm_surface_unmap(surface);
2726 TBM_TRACE_SURFACE_INTERNAL("Capture %s ", file);
2732 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2733 const char *path, const char *name, const char *type)
2735 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2736 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2737 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2738 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2739 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2740 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2744 if (strcmp(dump_postfix[0], type)) {
2745 TBM_ERR("Not supported type:%s'", type);
2749 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2751 if (!access(file, 0)) {
2752 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2756 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2758 TBM_TRACE_SURFACE_INTERNAL("Capture %s ", file);
2764 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2766 struct _tbm_surface *surf;
2768 _tbm_surface_mutex_lock();
2769 _tbm_set_last_result(TBM_ERROR_NONE);
2771 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2772 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2773 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2775 surf = (struct _tbm_surface *)surface;
2779 surf->damage.width = width;
2780 surf->damage.height = height;
2782 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)",
2783 surface, x, y, width, height);
2785 _tbm_surface_mutex_unlock();
2791 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2793 struct _tbm_surface *surf;
2795 _tbm_surface_mutex_lock();
2796 _tbm_set_last_result(TBM_ERROR_NONE);
2798 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2800 surf = (struct _tbm_surface *)surface;
2802 if (x) *x = surf->damage.x;
2803 if (y) *y = surf->damage.y;
2804 if (width) *width = surf->damage.width;
2805 if (height) *height = surf->damage.height;
2807 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)",
2808 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2810 _tbm_surface_mutex_unlock();
2816 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2818 struct _tbm_surface *surf;
2819 tbm_surface_destroy_func_info *func_info = NULL;
2821 _tbm_surface_mutex_lock();
2822 _tbm_set_last_result(TBM_ERROR_NONE);
2824 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2825 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2827 surf = (struct _tbm_surface *)surface;
2828 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2829 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2830 TBM_ERR("can't add twice");
2831 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2832 _tbm_surface_mutex_unlock();
2837 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2838 if (func_info == NULL) {
2839 TBM_ERR("alloc failed");
2840 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2841 _tbm_surface_mutex_unlock();
2845 func_info->destroy_func = func;
2846 func_info->user_data = user_data;
2848 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2850 _tbm_surface_mutex_unlock();
2856 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2858 struct _tbm_surface *surf;
2859 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2861 _tbm_surface_mutex_lock();
2862 _tbm_set_last_result(TBM_ERROR_NONE);
2864 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2865 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2867 surf = (struct _tbm_surface *)surface;
2868 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2869 if (func_info->destroy_func != func || func_info->user_data != user_data)
2872 LIST_DEL(&func_info->item_link);
2875 _tbm_surface_mutex_unlock();
2880 _tbm_surface_mutex_unlock();
2883 tbm_surface_buffer_data *
2884 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2886 tbm_surface_buffer_data *buffer_data = NULL;
2887 struct _tbm_bufmgr *bufmgr;
2889 _tbm_surface_mutex_lock();
2891 bufmgr = g_surface_bufmgr;
2892 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2894 // this function supports when the module suppport surface_data.
2895 TBM_SURFACE_RETURN_VAL_SET_ERR_NO_LOG_IF_FAIL(tbm_bufmgr_internal_support_capabilites(bufmgr, TBM_BUFMGR_CAPABILITY_SHARE_SURFACE), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2897 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, error, TBM_ERROR_INVALID_PARAMETER);
2900 buffer_data = tbm_surface_data_export(surface->surface_data, error);
2901 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
2903 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
2905 _tbm_set_last_result(TBM_ERROR_NONE);
2906 _tbm_surface_mutex_unlock();
2912 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
2914 struct _tbm_surface *surf;
2915 struct _tbm_bufmgr *bufmgr;
2917 _tbm_surface_mutex_lock();
2919 bufmgr = g_surface_bufmgr;
2920 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2922 // this function supports when the module suppport surface_data.
2923 TBM_SURFACE_RETURN_VAL_SET_ERR_NO_LOG_IF_FAIL(tbm_bufmgr_internal_support_capabilites(bufmgr, TBM_BUFMGR_CAPABILITY_SHARE_SURFACE), NULL, error, TBM_ERROR_NOT_SUPPORTED);
2925 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2926 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2927 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2928 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2931 surf = _tbm_surface_internal_import_surface(bufmgr,
2932 (int)surface_info->width,
2933 (int)surface_info->height,
2934 (int)surface_info->format,
2937 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
2939 LIST_INITHEAD(&surf->user_data_list);
2940 LIST_INITHEAD(&surf->debug_data_list);
2941 LIST_INITHEAD(&surf->destroy_funcs);
2943 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
2945 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
2947 _tbm_set_last_result(TBM_ERROR_NONE);
2948 _tbm_surface_mutex_unlock();
2950 return (tbm_surface_h)surf;