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 can_share_surface)
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 (can_share_surface) {
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 (can_share_surface) {
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 can_share_surface = 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 can_share_surface = tbm_bufmgr_internal_support_capabilites(bufmgr, TBM_BUFMGR_CAPABILITY_SHARE_SURFACE);
804 if (can_share_surface) {
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, can_share_surface);
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];
1392 _tbm_surface_mutex_lock();
1393 _tbm_set_last_result(TBM_ERROR_NONE);
1395 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1397 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1399 surf = (struct _tbm_surface *)surface;
1401 memset(info, 0x00, sizeof(tbm_surface_info_s));
1402 info->width = surf->info.width;
1403 info->height = surf->info.height;
1404 info->format = surf->info.format;
1405 info->bpp = surf->info.bpp;
1406 info->size = surf->info.size;
1407 info->num_planes = surf->info.num_planes;
1409 for (i = 0; i < surf->info.num_planes; i++) {
1410 info->planes[i].size = surf->info.planes[i].size;
1411 info->planes[i].offset = surf->info.planes[i].offset;
1412 info->planes[i].stride = surf->info.planes[i].stride;
1413 planes_bo_idx[i] = surf->planes_bo_idx[i];
1416 for (i = 0; i < surf->num_bos; i++)
1417 bos[i] = surf->bos[i];
1419 num_bos = surf->num_bos;
1422 _tbm_surface_mutex_unlock();
1423 for (i = 0; i < num_bos; i++) {
1424 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1425 if (bo_handles[i].ptr == NULL) {
1426 error = tbm_get_last_error();
1427 for (j = 0; j < i; j++)
1428 tbm_bo_unmap(bos[j]);
1430 _tbm_set_last_result(error);
1431 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1435 _tbm_surface_mutex_lock();
1437 for (i = 0; i < num_bos; i++) {
1438 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1439 if (bo_handles[i].ptr == NULL) {
1440 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1441 _tbm_surface_mutex_unlock();
1447 for (i = 0; i < info->num_planes; i++) {
1448 if (bo_handles[planes_bo_idx[i]].ptr)
1449 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1452 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1454 _tbm_surface_mutex_unlock();
1460 tbm_surface_internal_unmap(tbm_surface_h surface)
1462 struct _tbm_surface *surf;
1465 _tbm_surface_mutex_lock();
1466 _tbm_set_last_result(TBM_ERROR_NONE);
1468 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1470 surf = (struct _tbm_surface *)surface;
1472 for (i = 0; i < surf->num_bos; i++)
1473 tbm_bo_unmap(surf->bos[i]);
1475 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1477 _tbm_surface_mutex_unlock();
1481 tbm_surface_internal_get_width(tbm_surface_h surface)
1483 struct _tbm_surface *surf;
1486 _tbm_surface_mutex_lock();
1487 _tbm_set_last_result(TBM_ERROR_NONE);
1489 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1491 surf = (struct _tbm_surface *)surface;
1492 width = surf->info.width;
1494 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1496 _tbm_surface_mutex_unlock();
1502 tbm_surface_internal_get_height(tbm_surface_h surface)
1504 struct _tbm_surface *surf;
1505 unsigned int height;
1507 _tbm_surface_mutex_lock();
1508 _tbm_set_last_result(TBM_ERROR_NONE);
1510 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1512 surf = (struct _tbm_surface *)surface;
1513 height = surf->info.height;
1515 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1517 _tbm_surface_mutex_unlock();
1524 tbm_surface_internal_get_format(tbm_surface_h surface)
1526 struct _tbm_surface *surf;
1529 _tbm_surface_mutex_lock();
1530 _tbm_set_last_result(TBM_ERROR_NONE);
1532 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1534 surf = (struct _tbm_surface *)surface;
1535 format = surf->info.format;
1537 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1539 _tbm_surface_mutex_unlock();
1545 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1547 struct _tbm_surface *surf;
1550 _tbm_surface_mutex_lock();
1551 _tbm_set_last_result(TBM_ERROR_NONE);
1553 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1554 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1556 surf = (struct _tbm_surface *)surface;
1557 bo_idx = surf->planes_bo_idx[plane_idx];
1559 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1561 _tbm_surface_mutex_unlock();
1567 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1568 tbm_data_free data_free_func)
1570 tbm_user_data *data;
1572 _tbm_surface_mutex_lock();
1573 _tbm_set_last_result(TBM_ERROR_NONE);
1575 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1577 /* check if the data according to the key exist if so, return false. */
1578 data = user_data_lookup(&surface->user_data_list, key);
1580 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1581 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1582 _tbm_surface_mutex_unlock();
1586 data = user_data_create(key, data_free_func);
1588 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1589 _tbm_surface_mutex_unlock();
1593 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1595 LIST_ADD(&data->item_link, &surface->user_data_list);
1597 _tbm_surface_mutex_unlock();
1603 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1606 tbm_user_data *old_data;
1608 _tbm_surface_mutex_lock();
1609 _tbm_set_last_result(TBM_ERROR_NONE);
1611 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1613 old_data = user_data_lookup(&surface->user_data_list, key);
1615 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1616 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1617 _tbm_surface_mutex_unlock();
1621 if (old_data->data && old_data->free_func)
1622 old_data->free_func(old_data->data);
1624 old_data->data = data;
1626 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1628 _tbm_surface_mutex_unlock();
1634 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1637 tbm_user_data *old_data;
1639 _tbm_surface_mutex_lock();
1640 _tbm_set_last_result(TBM_ERROR_NONE);
1642 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1645 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1646 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1647 _tbm_surface_mutex_unlock();
1652 old_data = user_data_lookup(&surface->user_data_list, key);
1654 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1655 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1656 _tbm_surface_mutex_unlock();
1660 *data = old_data->data;
1662 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1664 _tbm_surface_mutex_unlock();
1670 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1673 tbm_user_data *old_data = (void *)0;
1675 _tbm_surface_mutex_lock();
1676 _tbm_set_last_result(TBM_ERROR_NONE);
1678 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1680 old_data = user_data_lookup(&surface->user_data_list, key);
1682 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1683 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1684 _tbm_surface_mutex_unlock();
1688 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1690 user_data_delete(old_data);
1692 _tbm_surface_mutex_unlock();
1697 /* LCOV_EXCL_START */
1699 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1701 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1703 return surface->debug_pid;
1707 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1709 _tbm_surface_mutex_lock();
1710 _tbm_set_last_result(TBM_ERROR_NONE);
1712 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1714 surface->debug_pid = pid;
1716 _tbm_surface_mutex_unlock();
1719 static tbm_surface_debug_data *
1720 _tbm_surface_internal_debug_data_create(char *key, char *value)
1722 tbm_surface_debug_data *debug_data = NULL;
1724 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1726 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1727 TBM_ERR("fail to allocate the debug_data.");
1731 if (key) debug_data->key = strdup(key);
1732 if (value) debug_data->value = strdup(value);
1738 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1740 if (!debug_data->value && !value)
1743 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1746 if (debug_data->value)
1747 free(debug_data->value);
1750 debug_data->value = strdup(value);
1752 debug_data->value = NULL;
1755 static tbm_surface_debug_data *
1756 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1758 tbm_surface_debug_data *debug_data = NULL;
1760 if (LIST_IS_EMPTY(list))
1763 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1764 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1772 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1774 tbm_surface_debug_data *debug_data = NULL;
1775 tbm_bufmgr bufmgr = NULL;
1777 _tbm_surface_mutex_lock();
1778 _tbm_set_last_result(TBM_ERROR_NONE);
1780 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1781 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1783 bufmgr = surface->bufmgr;
1785 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1787 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1789 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1791 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1793 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1794 _tbm_surface_mutex_unlock();
1798 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1801 /* add new debug key to list */
1802 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1804 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1806 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1809 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1811 _tbm_surface_mutex_unlock();
1817 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1819 tbm_surface_debug_data *old_data = NULL;
1821 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1823 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1824 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1825 if (!strcmp(old_data->key, key))
1826 return old_data->value;
1833 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1834 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1836 struct _tbm_surface_dump_buf_info {
1846 tbm_surface_info_s info;
1848 struct list_head link;
1851 struct _tbm_surface_dump_info {
1852 char *path; // copy???
1855 struct list_head *link;
1856 struct list_head surface_list; /* link of surface */
1859 static tbm_surface_dump_info *g_dump_info = NULL;
1860 static const char *dump_postfix[2] = {"png", "yuv"};
1861 static double scale_factor;
1864 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1865 void *data2, int size2, void *data3, int size3)
1868 unsigned int *blocks;
1870 if (_tbm_surface_check_file_is_symbolic_link(file))
1871 TBM_ERR("%s is symbolic link\n", file);
1873 fp = fopen(file, "w+");
1874 TBM_RETURN_IF_FAIL(fp != NULL);
1876 blocks = (unsigned int *)data1;
1877 fwrite(blocks, 1, size1, fp);
1880 blocks = (unsigned int *)data2;
1881 fwrite(blocks, 1, size2, fp);
1885 blocks = (unsigned int *)data3;
1886 fwrite(blocks, 1, size3, fp);
1893 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1895 unsigned int *blocks = (unsigned int *)data;
1898 png_bytep *row_pointers;
1901 if (_tbm_surface_check_file_is_symbolic_link(file))
1902 TBM_ERR("%s is symbolic link\n", file);
1904 fp = fopen(file, "wb");
1905 TBM_RETURN_IF_FAIL(fp != NULL);
1907 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1910 TBM_ERR("fail to create a png write structure.\n");
1915 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1917 TBM_ERR("fail to create a png info structure.\n");
1918 png_destroy_write_struct(&pPngStruct, NULL);
1923 if (setjmp(png_jmpbuf(pPngStruct))) {
1924 /* if png has problem of writing the file, we get here */
1925 TBM_ERR("fail to write png file.\n");
1926 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1931 png_init_io(pPngStruct, fp);
1932 if (format == TBM_FORMAT_XRGB8888) {
1934 png_set_IHDR(pPngStruct,
1941 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1944 png_set_IHDR(pPngStruct,
1949 PNG_COLOR_TYPE_RGBA,
1951 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1954 png_set_bgr(pPngStruct);
1955 png_write_info(pPngStruct, pPngInfo);
1957 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1958 if (!row_pointers) {
1959 TBM_ERR("fail to allocate the png row_pointers.\n");
1960 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1965 for (y = 0; y < height; ++y) {
1969 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1971 TBM_ERR("fail to allocate the png row.\n");
1972 for (x = 0; x < y; x++)
1973 png_free(pPngStruct, row_pointers[x]);
1974 png_free(pPngStruct, row_pointers);
1975 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1979 row_pointers[y] = (png_bytep)row;
1981 for (x = 0; x < width; ++x) {
1982 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1984 if (pixel_size == 3) { // XRGB8888 or XBGR8888
1985 if (format == TBM_FORMAT_XRGB8888) {
1986 row[x * pixel_size] = (curBlock & 0xFF);
1987 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1988 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1990 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
1991 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1992 row[2 + x * pixel_size] = (curBlock & 0xFF);
1994 } else { // ARGB8888 or ABGR8888
1995 if (format == TBM_FORMAT_ARGB8888) {
1996 row[x * pixel_size] = (curBlock & 0xFF);
1997 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1998 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1999 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2001 row[x * pixel_size] = (curBlock >> 16) & 0xFF;
2002 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2003 row[2 + x * pixel_size] = (curBlock & 0xFF);
2004 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2010 png_write_image(pPngStruct, row_pointers);
2011 png_write_end(pPngStruct, pPngInfo);
2013 for (y = 0; y < height; y++)
2014 png_free(pPngStruct, row_pointers[y]);
2015 png_free(pPngStruct, row_pointers);
2017 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2023 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2025 TBM_RETURN_IF_FAIL(path != NULL);
2026 TBM_RETURN_IF_FAIL(w > 0);
2027 TBM_RETURN_IF_FAIL(h > 0);
2028 TBM_RETURN_IF_FAIL(count > 0);
2030 tbm_surface_dump_buf_info *buf_info = NULL;
2031 tbm_surface_h tbm_surface;
2032 tbm_surface_info_s info;
2037 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2041 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2042 TBM_RETURN_IF_FAIL(g_dump_info);
2044 LIST_INITHEAD(&g_dump_info->surface_list);
2045 g_dump_info->count = 0;
2046 g_dump_info->dump_max = count;
2048 /* get buffer size */
2049 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2050 if (tbm_surface == NULL) {
2051 TBM_ERR("tbm_surface_create fail\n");
2057 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2058 TBM_ERR("tbm_surface_get_info fail\n");
2059 tbm_surface_destroy(tbm_surface);
2064 buffer_size = info.size;
2065 tbm_surface_destroy(tbm_surface);
2067 /* create dump lists */
2068 for (i = 0; i < count; i++) {
2071 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2072 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2074 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2076 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2081 buf_info->index = i;
2083 buf_info->size = buffer_size;
2085 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2088 g_dump_info->path = path;
2089 g_dump_info->link = &g_dump_info->surface_list;
2093 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2098 /* free resources */
2099 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2100 tbm_surface_dump_buf_info *tmp;
2102 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2103 tbm_bo_unref(buf_info->bo);
2104 LIST_DEL(&buf_info->link);
2109 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2118 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2125 tbm_surface_internal_dump_start(path, w, h, count);
2126 scale_factor = scale;
2130 tbm_surface_internal_dump_end(void)
2132 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2133 tbm_bo_handle bo_handle;
2138 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2145 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2148 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2149 if (bo_handle.ptr == NULL) {
2150 tbm_bo_unref(buf_info->bo);
2151 LIST_DEL(&buf_info->link);
2156 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2157 TBM_INFO("Dump File.. %s generated.\n", file);
2159 if (buf_info->dirty) {
2160 void *ptr1 = NULL, *ptr2 = NULL;
2162 switch (buf_info->info.format) {
2163 case TBM_FORMAT_ARGB8888:
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_ARGB8888);
2170 case TBM_FORMAT_XRGB8888:
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_XRGB8888);
2177 case TBM_FORMAT_ABGR8888:
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_ABGR8888);
2184 case TBM_FORMAT_XBGR8888:
2185 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2186 buf_info->info.planes[0].stride >> 2,
2187 buf_info->info.height,
2188 buf_info->info.planes[0].stride,
2189 TBM_FORMAT_XBGR8888);
2191 case TBM_FORMAT_YVU420:
2192 case TBM_FORMAT_YUV420:
2193 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2194 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2195 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2196 buf_info->info.planes[0].stride * buf_info->info.height,
2198 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2200 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2202 case TBM_FORMAT_NV12:
2203 case TBM_FORMAT_NV21:
2204 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2205 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2206 buf_info->info.planes[0].stride * buf_info->info.height,
2208 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2211 case TBM_FORMAT_YUYV:
2212 case TBM_FORMAT_UYVY:
2213 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2214 buf_info->info.planes[0].stride * buf_info->info.height,
2218 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2221 } else if (buf_info->dirty_shm)
2222 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2223 buf_info->shm_stride >> 2,
2225 buf_info->shm_stride, 0);
2227 tbm_bo_unmap(buf_info->bo);
2228 tbm_bo_unref(buf_info->bo);
2229 LIST_DEL(&buf_info->link);
2236 TBM_INFO("Dump End..\n");
2239 static pixman_format_code_t
2240 _tbm_surface_internal_pixman_format_get(tbm_format format)
2243 case TBM_FORMAT_ARGB8888:
2244 case TBM_FORMAT_ABGR8888:
2245 return PIXMAN_a8r8g8b8;
2246 case TBM_FORMAT_XRGB8888:
2247 case TBM_FORMAT_XBGR8888:
2248 return PIXMAN_x8r8g8b8;
2257 * This function supports only if a buffer has below formats.
2258 * - TBM_FORMAT_ARGB8888
2259 * - TBM_FORMAT_XRGB8888
2260 * - TBM_FORMAT_ABGR8888
2261 * - TBM_FORMAT_XBGR8888
2263 static tbm_surface_error_e
2264 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2265 int format, int src_stride, int src_w, int src_h,
2266 int dst_stride, int dst_w, int dst_h)
2268 pixman_image_t *src_img = NULL, *dst_img = NULL;
2269 pixman_format_code_t pixman_format;
2270 pixman_transform_t t;
2271 struct pixman_f_transform ft;
2272 double scale_x, scale_y;
2274 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2275 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2277 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2278 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2281 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2282 (uint32_t*)src_ptr, src_stride);
2283 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2286 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2287 (uint32_t*)dst_ptr, dst_stride);
2288 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2290 pixman_f_transform_init_identity(&ft);
2292 scale_x = (double)src_w / dst_w;
2293 scale_y = (double)src_h / dst_h;
2295 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2296 pixman_f_transform_translate(&ft, NULL, 0, 0);
2297 pixman_transform_from_pixman_f_transform(&t, &ft);
2298 pixman_image_set_transform(src_img, &t);
2300 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2301 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2303 pixman_image_unref(src_img);
2304 pixman_image_unref(dst_img);
2306 return TBM_SURFACE_ERROR_NONE;
2310 pixman_image_unref(src_img);
2312 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2315 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2316 #define KEY_LEN 5 // "_XXXX"
2317 #define KEYS_LEN KEY_LEN * MAX_BOS
2319 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2321 char *keys, temp_key[KEY_LEN + 1];
2322 struct _tbm_surface *surf;
2326 _tbm_surface_mutex_lock();
2328 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2330 surf = (struct _tbm_surface *)surface;
2332 num_bos = surf->num_bos;
2333 if (num_bos > MAX_BOS)
2336 keys = calloc(KEYS_LEN + 1, sizeof(char));
2338 TBM_ERR("Failed to alloc memory");
2339 _tbm_surface_mutex_unlock();
2343 for (i = 0; i < num_bos; i++) {
2344 memset(temp_key, 0x00, KEY_LEN + 1);
2346 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2347 strncat(keys, temp_key, KEY_LEN + 1);
2350 _tbm_surface_mutex_unlock();
2355 static void _tbm_surface_internal_put_keys(char *keys)
2362 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2364 TBM_RETURN_IF_FAIL(surface != NULL);
2365 TBM_RETURN_IF_FAIL(type != NULL);
2367 tbm_surface_dump_buf_info *buf_info;
2368 struct list_head *next_link;
2369 tbm_surface_info_s info;
2370 tbm_bo_handle bo_handle;
2371 const char *postfix;
2372 const char *format = NULL;
2379 next_link = g_dump_info->link->next;
2380 TBM_RETURN_IF_FAIL(next_link != NULL);
2382 if (next_link == &g_dump_info->surface_list) {
2383 next_link = next_link->next;
2384 TBM_RETURN_IF_FAIL(next_link != NULL);
2387 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2388 TBM_RETURN_IF_FAIL(buf_info != NULL);
2390 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2391 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2393 if (scale_factor > 0.0) {
2396 if ((info.format != TBM_FORMAT_ARGB8888) && (info.format != TBM_FORMAT_XRGB8888) &&
2397 (info.format != TBM_FORMAT_ABGR8888) && (info.format != TBM_FORMAT_XBGR8888)) {
2398 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2399 _tbm_surface_internal_format_to_str(info.format));
2400 tbm_surface_unmap(surface);
2404 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2406 buf_info->info.width = info.width * scale_factor;
2407 buf_info->info.height = info.height * scale_factor;
2408 buf_info->info.format = info.format;
2409 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2410 if (!buf_info->info.bpp) {
2411 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2412 tbm_surface_unmap(surface);
2415 buf_info->info.num_planes = 1;
2416 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2417 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2419 if (buf_info->info.size > buf_info->size) {
2420 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2421 buf_info->info.size, buf_info->size);
2422 tbm_surface_unmap(surface);
2426 if (info.size > buf_info->size) {
2427 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2428 info.size, buf_info->size);
2429 tbm_surface_unmap(surface);
2433 /* make the file information */
2434 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2437 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2438 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888)) {
2439 postfix = dump_postfix[0];
2440 format = _tbm_surface_internal_format_to_str(info.format);
2442 postfix = dump_postfix[1];
2444 keys = _tbm_surface_internal_get_keys(surface);
2446 TBM_ERR("fail to get keys");
2447 tbm_surface_unmap(surface);
2452 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2453 if (!bo_handle.ptr) {
2454 TBM_ERR("fail to map bo");
2455 _tbm_surface_internal_put_keys(keys);
2456 tbm_surface_unmap(surface);
2459 memset(bo_handle.ptr, 0x00, buf_info->size);
2461 switch (info.format) {
2462 case TBM_FORMAT_ARGB8888:
2463 case TBM_FORMAT_XRGB8888:
2464 case TBM_FORMAT_ABGR8888:
2465 case TBM_FORMAT_XBGR8888:
2466 snprintf(buf_info->name, sizeof(buf_info->name),
2467 "%10.3f_%03d%s_%p_%s-%s.%s",
2468 _tbm_surface_internal_get_time(),
2469 g_dump_info->count++, keys, surface, format, type, postfix);
2471 if (scale_factor > 0.0) {
2472 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2474 buf_info->info.format,
2475 info.planes[0].stride,
2476 info.width, info.height,
2477 buf_info->info.planes[0].stride,
2478 buf_info->info.width,
2479 buf_info->info.height);
2480 if (ret != TBM_SURFACE_ERROR_NONE) {
2481 TBM_ERR("fail to scale buffer");
2482 tbm_bo_unmap(buf_info->bo);
2483 _tbm_surface_internal_put_keys(keys);
2484 tbm_surface_unmap(surface);
2488 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2490 case TBM_FORMAT_YVU420:
2491 case TBM_FORMAT_YUV420:
2492 snprintf(buf_info->name, sizeof(buf_info->name),
2493 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2494 _tbm_surface_internal_get_time(),
2495 g_dump_info->count++, keys, type, info.planes[0].stride,
2496 info.height, FOURCC_STR(info.format), postfix);
2497 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2498 bo_handle.ptr += info.planes[0].stride * info.height;
2499 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2500 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2501 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2503 case TBM_FORMAT_NV12:
2504 case TBM_FORMAT_NV21:
2505 snprintf(buf_info->name, sizeof(buf_info->name),
2506 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2507 _tbm_surface_internal_get_time(),
2508 g_dump_info->count++, keys, type, info.planes[0].stride,
2509 info.height, FOURCC_STR(info.format), postfix);
2510 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2511 bo_handle.ptr += info.planes[0].stride * info.height;
2512 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2514 case TBM_FORMAT_YUYV:
2515 case TBM_FORMAT_UYVY:
2516 snprintf(buf_info->name, sizeof(buf_info->name),
2517 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2518 _tbm_surface_internal_get_time(),
2519 g_dump_info->count++, keys, type, info.planes[0].stride,
2520 info.height, FOURCC_STR(info.format), postfix);
2521 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2524 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2525 tbm_bo_unmap(buf_info->bo);
2526 _tbm_surface_internal_put_keys(keys);
2527 tbm_surface_unmap(surface);
2531 tbm_bo_unmap(buf_info->bo);
2533 _tbm_surface_internal_put_keys(keys);
2535 tbm_surface_unmap(surface);
2537 buf_info->dirty = 1;
2538 buf_info->dirty_shm = 0;
2540 if (g_dump_info->count == 1000)
2541 g_dump_info->count = 0;
2543 g_dump_info->link = next_link;
2545 TBM_INFO("Dump %s \n", buf_info->name);
2548 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2551 TBM_RETURN_IF_FAIL(ptr != NULL);
2552 TBM_RETURN_IF_FAIL(w > 0);
2553 TBM_RETURN_IF_FAIL(h > 0);
2554 TBM_RETURN_IF_FAIL(stride > 0);
2555 TBM_RETURN_IF_FAIL(type != NULL);
2557 tbm_surface_dump_buf_info *buf_info;
2558 struct list_head *next_link;
2559 tbm_bo_handle bo_handle;
2560 int ret, size, dw = 0, dh = 0, dstride = 0;
2565 next_link = g_dump_info->link->next;
2566 TBM_RETURN_IF_FAIL(next_link != NULL);
2568 if (next_link == &g_dump_info->surface_list) {
2569 next_link = next_link->next;
2570 TBM_RETURN_IF_FAIL(next_link != NULL);
2573 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2574 TBM_RETURN_IF_FAIL(buf_info != NULL);
2576 if (scale_factor > 0.0) {
2579 dw = w * scale_factor;
2580 dh = h * scale_factor;
2582 size = dstride * dh;
2586 if (size > buf_info->size) {
2587 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2588 size, buf_info->size);
2593 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2594 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2596 memset(bo_handle.ptr, 0x00, buf_info->size);
2597 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2599 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2600 _tbm_surface_internal_get_time(),
2601 g_dump_info->count++, type, dump_postfix[0]);
2602 if (scale_factor > 0.0) {
2603 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2604 TBM_FORMAT_ARGB8888, stride,
2605 w, h, dstride, dw, dh);
2606 if (ret != TBM_SURFACE_ERROR_NONE) {
2607 TBM_ERR("fail to scale buffer");
2608 tbm_bo_unmap(buf_info->bo);
2611 buf_info->shm_stride = dstride;
2612 buf_info->shm_h = dh;
2614 memcpy(bo_handle.ptr, ptr, size);
2615 buf_info->shm_stride = stride;
2616 buf_info->shm_h = h;
2619 tbm_bo_unmap(buf_info->bo);
2621 buf_info->dirty = 0;
2622 buf_info->dirty_shm = 1;
2624 if (g_dump_info->count == 1000)
2625 g_dump_info->count = 0;
2627 g_dump_info->link = next_link;
2629 TBM_INFO("Dump %s \n", buf_info->name);
2633 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2635 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2636 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2637 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2639 tbm_surface_info_s info;
2640 const char *postfix;
2644 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2645 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2647 if ((info.format == TBM_FORMAT_ARGB8888) || (info.format == TBM_FORMAT_XRGB8888) ||
2648 (info.format == TBM_FORMAT_ABGR8888) || (info.format == TBM_FORMAT_XBGR8888))
2649 postfix = dump_postfix[0];
2651 postfix = dump_postfix[1];
2653 if (strcmp(postfix, type)) {
2654 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2655 tbm_surface_unmap(surface);
2659 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2661 if (!access(file, 0)) {
2662 TBM_ERR("can't capture buffer, exist file %s", file);
2663 tbm_surface_unmap(surface);
2667 switch (info.format) {
2668 case TBM_FORMAT_ARGB8888:
2669 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2672 info.planes[0].stride,
2673 TBM_FORMAT_ARGB8888);
2675 case TBM_FORMAT_XRGB8888:
2676 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2679 info.planes[0].stride,
2680 TBM_FORMAT_XRGB8888);
2682 case TBM_FORMAT_ABGR8888:
2683 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2686 info.planes[0].stride,
2687 TBM_FORMAT_ABGR8888);
2689 case TBM_FORMAT_XBGR8888:
2690 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2693 info.planes[0].stride,
2694 TBM_FORMAT_XBGR8888);
2696 case TBM_FORMAT_YVU420:
2697 case TBM_FORMAT_YUV420:
2698 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2699 info.planes[0].stride * info.height,
2701 info.planes[1].stride * (info.height >> 1),
2703 info.planes[2].stride * (info.height >> 1));
2705 case TBM_FORMAT_NV12:
2706 case TBM_FORMAT_NV21:
2707 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2708 info.planes[0].stride * info.height,
2710 info.planes[1].stride * (info.height >> 1),
2713 case TBM_FORMAT_YUYV:
2714 case TBM_FORMAT_UYVY:
2715 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2716 info.planes[0].stride * info.height,
2720 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2721 tbm_surface_unmap(surface);
2725 tbm_surface_unmap(surface);
2727 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2733 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2734 const char *path, const char *name, const char *type)
2736 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2737 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2738 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2739 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2740 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2741 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2745 if (strcmp(dump_postfix[0], type)) {
2746 TBM_ERR("Not supported type:%s'", type);
2750 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2752 if (!access(file, 0)) {
2753 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2757 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2759 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2765 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2767 struct _tbm_surface *surf;
2769 _tbm_surface_mutex_lock();
2770 _tbm_set_last_result(TBM_ERROR_NONE);
2772 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2773 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2774 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2776 surf = (struct _tbm_surface *)surface;
2780 surf->damage.width = width;
2781 surf->damage.height = height;
2783 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2784 surface, x, y, width, height);
2786 _tbm_surface_mutex_unlock();
2792 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2794 struct _tbm_surface *surf;
2796 _tbm_surface_mutex_lock();
2797 _tbm_set_last_result(TBM_ERROR_NONE);
2799 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2801 surf = (struct _tbm_surface *)surface;
2803 if (x) *x = surf->damage.x;
2804 if (y) *y = surf->damage.y;
2805 if (width) *width = surf->damage.width;
2806 if (height) *height = surf->damage.height;
2808 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2809 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2811 _tbm_surface_mutex_unlock();
2817 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2819 struct _tbm_surface *surf;
2820 tbm_surface_destroy_func_info *func_info = NULL;
2822 _tbm_surface_mutex_lock();
2823 _tbm_set_last_result(TBM_ERROR_NONE);
2825 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2826 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2828 surf = (struct _tbm_surface *)surface;
2829 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2830 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2831 TBM_ERR("can't add twice");
2832 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2833 _tbm_surface_mutex_unlock();
2838 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2839 if (func_info == NULL) {
2840 TBM_ERR("alloc failed");
2841 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2842 _tbm_surface_mutex_unlock();
2846 func_info->destroy_func = func;
2847 func_info->user_data = user_data;
2849 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2851 _tbm_surface_mutex_unlock();
2857 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2859 struct _tbm_surface *surf;
2860 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2862 _tbm_surface_mutex_lock();
2863 _tbm_set_last_result(TBM_ERROR_NONE);
2865 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2866 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2868 surf = (struct _tbm_surface *)surface;
2869 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2870 if (func_info->destroy_func != func || func_info->user_data != user_data)
2873 LIST_DEL(&func_info->item_link);
2876 _tbm_surface_mutex_unlock();
2881 _tbm_surface_mutex_unlock();
2884 tbm_surface_buffer_data *
2885 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2887 tbm_surface_buffer_data *buffer_data = NULL;
2888 struct _tbm_bufmgr *bufmgr;
2890 _tbm_surface_mutex_lock();
2892 bufmgr = g_surface_bufmgr;
2893 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2895 // this function supports when the module suppport surface_data.
2896 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);
2898 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, error, TBM_ERROR_INVALID_PARAMETER);
2901 buffer_data = tbm_surface_data_export(surface->surface_data, error);
2902 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
2904 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
2906 _tbm_set_last_result(TBM_ERROR_NONE);
2907 _tbm_surface_mutex_unlock();
2913 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
2915 struct _tbm_surface *surf;
2916 struct _tbm_bufmgr *bufmgr;
2918 _tbm_surface_mutex_lock();
2920 bufmgr = g_surface_bufmgr;
2921 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_OPERATION);
2923 // this function supports when the module suppport surface_data.
2924 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);
2926 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2927 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2928 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2929 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2932 surf = _tbm_surface_internal_import_surface(bufmgr,
2933 (int)surface_info->width,
2934 (int)surface_info->height,
2935 (int)surface_info->format,
2938 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
2940 LIST_INITHEAD(&surf->user_data_list);
2941 LIST_INITHEAD(&surf->debug_data_list);
2942 LIST_INITHEAD(&surf->destroy_funcs);
2944 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
2946 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
2948 _tbm_set_last_result(TBM_ERROR_NONE);
2949 _tbm_surface_mutex_unlock();
2951 return (tbm_surface_h)surf;