1 /**************************************************************************
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
37 #include "tbm_bufmgr.h"
38 #include "tbm_bufmgr_int.h"
39 #include "tbm_surface_internal.h"
44 #define TBM_SURFACE_MAGIC 0xBF021234
46 static tbm_bufmgr g_surface_bufmgr;
47 static pthread_mutex_t tbm_surface_lock = PTHREAD_MUTEX_INITIALIZER;
48 void _tbm_surface_mutex_unlock(void);
51 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
53 TBM_ERR("'%s' failed.\n", #cond);\
54 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
55 _tbm_surface_mutex_unlock();\
60 #define TBM_SURFACE_RETURN_ERR_IF_FAIL(cond, error_type) {\
62 TBM_ERR("'%s' failed.\n", #cond);\
63 _tbm_set_last_result(error_type);\
64 _tbm_surface_mutex_unlock();\
69 #define TBM_SURFACE_RETURN_SET_ERR_IF_FAIL(cond, error, error_type) {\
71 TBM_ERR("'%s' failed.\n", #cond);\
73 _tbm_set_last_result(error_type);\
74 _tbm_surface_mutex_unlock();\
79 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
81 TBM_ERR("'%s' failed.\n", #cond);\
82 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
83 _tbm_surface_mutex_unlock();\
89 #define TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(cond, val, error_type) {\
91 TBM_ERR("'%s' failed.\n", #cond);\
92 _tbm_set_last_result(error_type);\
93 _tbm_surface_mutex_unlock();\
98 #define TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(cond, val, error, error_type) {\
100 TBM_ERR("'%s' failed.\n", #cond);\
102 *error = error_type;\
103 _tbm_set_last_result(error_type);\
104 _tbm_surface_mutex_unlock();\
109 /* LCOV_EXCL_START */
111 _tbm_surface_internal_get_time(void)
116 clock_gettime(CLOCK_MONOTONIC, &tp);
117 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
119 return time / 1000.0;
123 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
125 LIST_DEL(&debug_data->item_link);
127 if (debug_data->key) free(debug_data->key);
128 if (debug_data->value) free(debug_data->value);
133 _tbm_surface_internal_format_to_str(tbm_format format)
137 return "TBM_FORMAT_C8";
138 case TBM_FORMAT_RGB332:
139 return "TBM_FORMAT_RGB332";
140 case TBM_FORMAT_BGR233:
141 return "TBM_FORMAT_BGR233";
142 case TBM_FORMAT_XRGB4444:
143 return "TBM_FORMAT_XRGB4444";
144 case TBM_FORMAT_XBGR4444:
145 return "TBM_FORMAT_XBGR4444";
146 case TBM_FORMAT_RGBX4444:
147 return "TBM_FORMAT_RGBX4444";
148 case TBM_FORMAT_BGRX4444:
149 return "TBM_FORMAT_BGRX4444";
150 case TBM_FORMAT_ARGB4444:
151 return "TBM_FORMAT_ARGB4444";
152 case TBM_FORMAT_ABGR4444:
153 return "TBM_FORMAT_ABGR4444";
154 case TBM_FORMAT_RGBA4444:
155 return "TBM_FORMAT_RGBA4444";
156 case TBM_FORMAT_BGRA4444:
157 return "TBM_FORMAT_BGRA4444";
158 case TBM_FORMAT_XRGB1555:
159 return "TBM_FORMAT_XRGB1555";
160 case TBM_FORMAT_XBGR1555:
161 return "TBM_FORMAT_XBGR1555";
162 case TBM_FORMAT_RGBX5551:
163 return "TBM_FORMAT_RGBX5551";
164 case TBM_FORMAT_BGRX5551:
165 return "TBM_FORMAT_BGRX5551";
166 case TBM_FORMAT_ARGB1555:
167 return "TBM_FORMAT_ARGB1555";
168 case TBM_FORMAT_ABGR1555:
169 return "TBM_FORMAT_ABGR1555";
170 case TBM_FORMAT_RGBA5551:
171 return "TBM_FORMAT_RGBA5551";
172 case TBM_FORMAT_BGRA5551:
173 return "TBM_FORMAT_BGRA5551";
174 case TBM_FORMAT_RGB565:
175 return "TBM_FORMAT_RGB565";
176 case TBM_FORMAT_BGR565:
177 return "TBM_FORMAT_BGR565";
178 case TBM_FORMAT_RGB888:
179 return "TBM_FORMAT_RGB888";
180 case TBM_FORMAT_BGR888:
181 return "TBM_FORMAT_BGR888";
182 case TBM_FORMAT_XRGB8888:
183 return "TBM_FORMAT_XRGB8888";
184 case TBM_FORMAT_XBGR8888:
185 return "TBM_FORMAT_XBGR8888";
186 case TBM_FORMAT_RGBX8888:
187 return "TBM_FORMAT_RGBX8888";
188 case TBM_FORMAT_BGRX8888:
189 return "TBM_FORMAT_BGRX8888";
190 case TBM_FORMAT_ARGB8888:
191 return "TBM_FORMAT_ARGB8888";
192 case TBM_FORMAT_ABGR8888:
193 return "TBM_FORMAT_ABGR8888";
194 case TBM_FORMAT_RGBA8888:
195 return "TBM_FORMAT_RGBA8888";
196 case TBM_FORMAT_BGRA8888:
197 return "TBM_FORMAT_BGRA8888";
198 case TBM_FORMAT_XRGB2101010:
199 return "TBM_FORMAT_XRGB2101010";
200 case TBM_FORMAT_XBGR2101010:
201 return "TBM_FORMAT_XBGR2101010";
202 case TBM_FORMAT_RGBX1010102:
203 return "TBM_FORMAT_RGBX1010102";
204 case TBM_FORMAT_BGRX1010102:
205 return "TBM_FORMAT_BGRX1010102";
206 case TBM_FORMAT_ARGB2101010:
207 return "TBM_FORMAT_ARGB2101010";
208 case TBM_FORMAT_ABGR2101010:
209 return "TBM_FORMAT_ABGR2101010";
210 case TBM_FORMAT_RGBA1010102:
211 return "TBM_FORMAT_RGBA1010102";
212 case TBM_FORMAT_BGRA1010102:
213 return "TBM_FORMAT_BGRA1010102";
214 case TBM_FORMAT_YUYV:
215 return "TBM_FORMAT_YUYV";
216 case TBM_FORMAT_YVYU:
217 return "TBM_FORMAT_YVYU";
218 case TBM_FORMAT_UYVY:
219 return "TBM_FORMAT_UYVY";
220 case TBM_FORMAT_VYUY:
221 return "TBM_FORMAT_VYUY";
222 case TBM_FORMAT_AYUV:
223 return "TBM_FORMAT_AYUV";
224 case TBM_FORMAT_NV12:
225 return "TBM_FORMAT_NV12";
226 case TBM_FORMAT_NV21:
227 return "TBM_FORMAT_NV21";
228 case TBM_FORMAT_NV16:
229 return "TBM_FORMAT_NV16";
230 case TBM_FORMAT_NV61:
231 return "TBM_FORMAT_NV61";
232 case TBM_FORMAT_YUV410:
233 return "TBM_FORMAT_YUV410";
234 case TBM_FORMAT_YVU410:
235 return "TBM_FORMAT_YVU410";
236 case TBM_FORMAT_YUV411:
237 return "TBM_FORMAT_YUV411";
238 case TBM_FORMAT_YVU411:
239 return "TBM_FORMAT_YVU411";
240 case TBM_FORMAT_YUV420:
241 return "TBM_FORMAT_YUV420";
242 case TBM_FORMAT_YVU420:
243 return "TBM_FORMAT_YVU420";
244 case TBM_FORMAT_YUV422:
245 return "TBM_FORMAT_YUV422";
246 case TBM_FORMAT_YVU422:
247 return "TBM_FORMAT_YVU422";
248 case TBM_FORMAT_YUV444:
249 return "TBM_FORMAT_YUV444";
250 case TBM_FORMAT_YVU444:
251 return "TBM_FORMAT_YVU444";
252 case TBM_FORMAT_NV12MT:
253 return "TBM_FORMAT_NV12MT";
260 _tbm_surface_mutex_lock(void)
262 pthread_mutex_lock(&tbm_surface_lock);
266 _tbm_surface_mutex_unlock(void)
268 pthread_mutex_unlock(&tbm_surface_lock);
272 _init_surface_bufmgr(void)
274 g_surface_bufmgr = tbm_bufmgr_init(-1);
278 _deinit_surface_bufmgr(void)
280 if (!g_surface_bufmgr)
283 tbm_bufmgr_deinit(g_surface_bufmgr);
284 g_surface_bufmgr = NULL;
289 _tbm_surface_internal_magic_check(tbm_surface_h surface)
291 if (surface->magic != TBM_SURFACE_MAGIC)
298 _tbm_surface_internal_is_valid(tbm_surface_h surface)
301 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
302 TBM_ERR("error: No valid tbm_surface is NULL\n");
306 if (!_tbm_surface_internal_magic_check(surface)) {
307 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
308 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
316 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
317 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
319 TBM_RETURN_VAL_IF_FAIL(surface, 0);
320 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
322 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
323 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
326 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
327 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
328 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
329 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
331 error = tbm_module_bufmgr_get_plane_data(bufmgr->module, surf->info.format, plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
332 if (error != TBM_ERROR_NONE) {
333 _tbm_set_last_result(error);
341 _tbm_surface_internal_destroy(tbm_surface_h surface)
344 tbm_bufmgr bufmgr = surface->bufmgr;
345 tbm_user_data *old_data = NULL, *tmp = NULL;
346 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
347 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
349 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
350 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
351 func_info->destroy_func(surface, func_info->user_data);
353 TBM_DBG("free destroy_funcs %p\n", surface);
354 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
355 LIST_DEL(&func_info->item_link);
360 /* destory the user_data_list */
361 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
362 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
363 TBM_DBG("free user_data\n");
364 user_data_delete(old_data);
368 for (i = 0; i < surface->num_bos; i++) {
369 surface->bos[i]->surface = NULL;
371 tbm_bo_unref(surface->bos[i]);
372 surface->bos[i] = NULL;
375 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
376 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
377 _tbm_surface_internal_debug_data_delete(debug_old_data);
380 LIST_DEL(&surface->item_link);
383 if (surface->hal_surface) {
384 hal_tbm_surface_free(surface->hal_surface);
385 surface->hal_surface = NULL;
391 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
392 LIST_DELINIT(&bufmgr->surf_list);
394 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
395 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
396 _tbm_surface_internal_debug_data_delete(debug_old_data);
400 _deinit_surface_bufmgr();
404 /* LCOV_EXCL_START */
406 _tbm_surface_check_file_is_symbolic_link(const char* path)
413 if (stat(path, &sb) != 0)
416 if (S_ISLNK(sb.st_mode))
424 _tbm_surface_internal_get_num_planes(tbm_format format)
430 case TBM_FORMAT_RGB332:
431 case TBM_FORMAT_BGR233:
432 case TBM_FORMAT_XRGB4444:
433 case TBM_FORMAT_XBGR4444:
434 case TBM_FORMAT_RGBX4444:
435 case TBM_FORMAT_BGRX4444:
436 case TBM_FORMAT_ARGB4444:
437 case TBM_FORMAT_ABGR4444:
438 case TBM_FORMAT_RGBA4444:
439 case TBM_FORMAT_BGRA4444:
440 case TBM_FORMAT_XRGB1555:
441 case TBM_FORMAT_XBGR1555:
442 case TBM_FORMAT_RGBX5551:
443 case TBM_FORMAT_BGRX5551:
444 case TBM_FORMAT_ARGB1555:
445 case TBM_FORMAT_ABGR1555:
446 case TBM_FORMAT_RGBA5551:
447 case TBM_FORMAT_BGRA5551:
448 case TBM_FORMAT_RGB565:
449 case TBM_FORMAT_BGR565:
450 case TBM_FORMAT_RGB888:
451 case TBM_FORMAT_BGR888:
452 case TBM_FORMAT_XRGB8888:
453 case TBM_FORMAT_XBGR8888:
454 case TBM_FORMAT_RGBX8888:
455 case TBM_FORMAT_BGRX8888:
456 case TBM_FORMAT_ARGB8888:
457 case TBM_FORMAT_ABGR8888:
458 case TBM_FORMAT_RGBA8888:
459 case TBM_FORMAT_BGRA8888:
460 case TBM_FORMAT_XRGB2101010:
461 case TBM_FORMAT_XBGR2101010:
462 case TBM_FORMAT_RGBX1010102:
463 case TBM_FORMAT_BGRX1010102:
464 case TBM_FORMAT_ARGB2101010:
465 case TBM_FORMAT_ABGR2101010:
466 case TBM_FORMAT_RGBA1010102:
467 case TBM_FORMAT_BGRA1010102:
468 case TBM_FORMAT_YUYV:
469 case TBM_FORMAT_YVYU:
470 case TBM_FORMAT_UYVY:
471 case TBM_FORMAT_VYUY:
472 case TBM_FORMAT_AYUV:
475 case TBM_FORMAT_NV12:
476 case TBM_FORMAT_NV12MT:
477 case TBM_FORMAT_NV21:
478 case TBM_FORMAT_NV16:
479 case TBM_FORMAT_NV61:
482 case TBM_FORMAT_YUV410:
483 case TBM_FORMAT_YVU410:
484 case TBM_FORMAT_YUV411:
485 case TBM_FORMAT_YVU411:
486 case TBM_FORMAT_YUV420:
487 case TBM_FORMAT_YVU420:
488 case TBM_FORMAT_YUV422:
489 case TBM_FORMAT_YVU422:
490 case TBM_FORMAT_YUV444:
491 case TBM_FORMAT_YVU444:
496 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
504 _tbm_surface_internal_get_bpp(tbm_format format)
511 case TBM_FORMAT_RGB332:
512 case TBM_FORMAT_BGR233:
515 case TBM_FORMAT_XRGB4444:
516 case TBM_FORMAT_XBGR4444:
517 case TBM_FORMAT_RGBX4444:
518 case TBM_FORMAT_BGRX4444:
519 case TBM_FORMAT_ARGB4444:
520 case TBM_FORMAT_ABGR4444:
521 case TBM_FORMAT_RGBA4444:
522 case TBM_FORMAT_BGRA4444:
523 case TBM_FORMAT_XRGB1555:
524 case TBM_FORMAT_XBGR1555:
525 case TBM_FORMAT_RGBX5551:
526 case TBM_FORMAT_BGRX5551:
527 case TBM_FORMAT_ARGB1555:
528 case TBM_FORMAT_ABGR1555:
529 case TBM_FORMAT_RGBA5551:
530 case TBM_FORMAT_BGRA5551:
531 case TBM_FORMAT_RGB565:
532 case TBM_FORMAT_BGR565:
535 case TBM_FORMAT_RGB888:
536 case TBM_FORMAT_BGR888:
539 case TBM_FORMAT_XRGB8888:
540 case TBM_FORMAT_XBGR8888:
541 case TBM_FORMAT_RGBX8888:
542 case TBM_FORMAT_BGRX8888:
543 case TBM_FORMAT_ARGB8888:
544 case TBM_FORMAT_ABGR8888:
545 case TBM_FORMAT_RGBA8888:
546 case TBM_FORMAT_BGRA8888:
547 case TBM_FORMAT_XRGB2101010:
548 case TBM_FORMAT_XBGR2101010:
549 case TBM_FORMAT_RGBX1010102:
550 case TBM_FORMAT_BGRX1010102:
551 case TBM_FORMAT_ARGB2101010:
552 case TBM_FORMAT_ABGR2101010:
553 case TBM_FORMAT_RGBA1010102:
554 case TBM_FORMAT_BGRA1010102:
555 case TBM_FORMAT_YUYV:
556 case TBM_FORMAT_YVYU:
557 case TBM_FORMAT_UYVY:
558 case TBM_FORMAT_VYUY:
559 case TBM_FORMAT_AYUV:
562 case TBM_FORMAT_NV12:
563 case TBM_FORMAT_NV12MT:
564 case TBM_FORMAT_NV21:
567 case TBM_FORMAT_NV16:
568 case TBM_FORMAT_NV61:
571 case TBM_FORMAT_YUV410:
572 case TBM_FORMAT_YVU410:
575 case TBM_FORMAT_YUV411:
576 case TBM_FORMAT_YVU411:
577 case TBM_FORMAT_YUV420:
578 case TBM_FORMAT_YVU420:
581 case TBM_FORMAT_YUV422:
582 case TBM_FORMAT_YVU422:
585 case TBM_FORMAT_YUV444:
586 case TBM_FORMAT_YVU444:
590 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
597 static struct _tbm_surface *
598 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
600 struct _tbm_surface *surf = NULL;
601 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
604 surf = calloc(1, sizeof(struct _tbm_surface));
606 /* LCOV_EXCL_START */
607 TBM_ERR("fail to alloc surf\n");
608 *error = TBM_ERROR_OUT_OF_MEMORY;
609 goto alloc_surf_fail;
613 surf->magic = TBM_SURFACE_MAGIC;
614 surf->bufmgr = bufmgr;
615 surf->info.width = width;
616 surf->info.height = height;
617 surf->info.format = format;
618 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
619 if (!surf->info.bpp) {
620 TBM_ERR("fail to get bpp from format(%d), error(%s)\n", format, tbm_error_str(*error));
621 *error = tbm_get_last_error();
625 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
626 if (!surf->info.num_planes) {
627 TBM_ERR("fail to get num_planes from format(%d), error(%s)\n", format, tbm_error_str(*error));
628 *error = tbm_get_last_error();
629 goto num_planes_fail;
633 /* get size, stride and offset bo_idx */
634 for (i = 0; i < surf->info.num_planes; i++) {
635 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
636 TBM_ERR("fail to query plane data\n");
637 *error = tbm_get_last_error();
638 goto query_plane_data_fail;
641 surf->info.planes[i].size = size;
642 surf->info.planes[i].offset = offset;
643 surf->info.planes[i].stride = stride;
644 surf->planes_bo_idx[i] = bo_idx;
649 for (i = 0; i < surf->info.num_planes; i++) {
650 surf->info.size += surf->info.planes[i].size;
652 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
653 surf->num_bos = surf->planes_bo_idx[i] + 1;
658 for (i = 0; i < surf->num_bos; i++) {
660 for (j = 0; j < surf->info.num_planes; j++) {
661 if (surf->planes_bo_idx[j] == i)
662 bo_size += surf->info.planes[j].size;
665 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
667 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
669 TBM_ERR("fail to alloc bo idx:%d\n", i);
670 *error = tbm_get_last_error();
675 _tbm_bo_set_surface(surf->bos[i], surf);
678 *error = TBM_ERROR_NONE;
683 for (j = 0; j < i; j++) {
685 tbm_bo_unref(surf->bos[j]);
687 query_plane_data_fail:
696 static struct _tbm_surface *
697 _tbm_surface_internal_hal_tbm_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
699 struct _tbm_surface *surf = NULL;
700 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
702 hal_tbm_surface *hal_surface = NULL;
703 hal_tbm_bo **hal_bos = NULL;
706 surf = calloc(1, sizeof(struct _tbm_surface));
708 /* LCOV_EXCL_START */
709 TBM_ERR("fail to alloc surf");
710 *error = TBM_ERROR_OUT_OF_MEMORY;
711 goto alloc_surf_fail;
716 surf->magic = TBM_SURFACE_MAGIC;
717 surf->bufmgr = bufmgr;
718 surf->info.width = width;
719 surf->info.height = height;
720 surf->info.format = format;
721 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
722 if (!surf->info.bpp) {
723 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
724 *error = tbm_get_last_error();
729 // get number of planes
730 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
731 if (!surf->info.num_planes) {
732 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
733 *error = tbm_get_last_error();
734 goto num_planes_fail;
737 hal_surface = hal_tbm_bufmgr_alloc_surface(bufmgr->hal_bufmgr, (uint32_t)width, (uint32_t)height, (hal_tbm_format)format, (hal_tbm_bo_memory_type)flags, NULL, 0, (hal_tbm_error *)error);
740 surf->hal_surface = hal_surface;
742 // set infomation of planes
743 for (i = 0; i < surf->info.num_planes; i++) {
744 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
745 if (*error != TBM_ERROR_NONE) {
746 goto query_plane_data_fail;
748 surf->info.planes[i].size = size;
749 surf->info.planes[i].offset = offset;
750 surf->info.planes[i].stride = stride;
751 surf->planes_bo_idx[i] = bo_idx;
754 // set infomation of bos
755 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
757 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
760 surf->num_bos = num_bos;
762 for (i = 0; i < surf->info.num_planes; i++) {
763 surf->info.size += surf->info.planes[i].size;
765 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
766 surf->num_bos = surf->planes_bo_idx[i] + 1;
769 for (i = 0; i < num_bos; i++) {
770 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
772 TBM_ERR("fail to alloc bo idx:%d", i);
773 *error = tbm_get_last_error();
777 _tbm_bo_set_surface(surf->bos[i], surf);
780 // set infomation of planes
781 for (i = 0; i < surf->info.num_planes; i++) {
782 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
783 TBM_ERR("fail to query plane data");
784 *error = tbm_get_last_error();
785 goto query_plane_data_fail;
787 surf->info.planes[i].size = size;
788 surf->info.planes[i].offset = offset;
789 surf->info.planes[i].stride = stride;
790 surf->planes_bo_idx[i] = bo_idx;
793 // count number of bos
795 for (i = 0; i < surf->info.num_planes; i++) {
796 surf->info.size += surf->info.planes[i].size;
798 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
799 surf->num_bos = surf->planes_bo_idx[i] + 1;
802 // set infomation of bos
803 for (i = 0; i < surf->num_bos; i++) {
805 for (j = 0; j < surf->info.num_planes; j++) {
806 if (surf->planes_bo_idx[j] == i)
807 bo_size += surf->info.planes[j].size;
810 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_format(bufmgr, format, i, width, height, surf->info.bpp / 8, flags, error);
811 if (*error == TBM_ERROR_NOT_SUPPORTED) {
812 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
814 TBM_ERR("fail to alloc bo idx:%d", i);
815 *error = tbm_get_last_error();
820 _tbm_bo_set_surface(surf->bos[i], surf);
824 *error = TBM_ERROR_NONE;
830 query_plane_data_fail:
832 hal_tbm_surface_free(hal_surface);
834 for (j = 0; j < i; j++) {
836 tbm_bo_unref(surf->bos[j]);
848 static struct _tbm_surface *
849 _tbm_surface_internal_hal_tbm_import_surface(tbm_bufmgr bufmgr, int width, int height, int format, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
851 struct _tbm_surface *surf = NULL;
852 uint32_t size = 0, offset = 0, stride = 0;
854 hal_tbm_surface *hal_surface = NULL;
855 hal_tbm_bo **hal_bos = NULL;
859 surf = calloc(1, sizeof(struct _tbm_surface));
861 /* LCOV_EXCL_START */
862 TBM_ERR("fail to alloc surf");
863 *error = TBM_ERROR_OUT_OF_MEMORY;
864 goto alloc_surf_fail;
869 surf->magic = TBM_SURFACE_MAGIC;
870 surf->bufmgr = bufmgr;
871 surf->info.width = width;
872 surf->info.height = height;
873 surf->info.format = format;
874 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
875 if (!surf->info.bpp) {
876 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
877 *error = tbm_get_last_error();
881 // get number of planes
882 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
883 if (!surf->info.num_planes) {
884 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
885 *error = tbm_get_last_error();
886 goto num_planes_fail;
890 hal_surface = hal_tbm_bufmgr_import_surface(bufmgr->hal_bufmgr,
893 (hal_tbm_format)format,
894 (hal_tbm_surface_buffer_data *)buffer_data,
895 (hal_tbm_error *)error);
897 TBM_ERR("hal_tbm_bufmgr_import_surface failed.(width:%d height:%d format:%d error:%s)",
898 width, height, format, tbm_error_str(*error));
899 goto import_surface_fail;
901 surf->hal_surface = hal_surface;
903 // set infomation of planes
904 for (i = 0; i < surf->info.num_planes; i++) {
905 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
906 if (*error != TBM_ERROR_NONE) {
907 goto query_plane_data_fail;
909 surf->info.planes[i].size = size;
910 surf->info.planes[i].offset = offset;
911 surf->info.planes[i].stride = stride;
912 surf->planes_bo_idx[i] = bo_idx;
915 // set infomation of bos
916 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
918 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
921 surf->num_bos = num_bos;
923 for (i = 0; i < surf->info.num_planes; i++) {
924 surf->info.size += surf->info.planes[i].size;
926 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
927 surf->num_bos = surf->planes_bo_idx[i] + 1;
930 // get memory_types(bo flags)
931 flags = (int)hal_tbm_bo_get_memory_types(hal_bos[0], (hal_tbm_error *)error);
932 if (*error != TBM_ERROR_NONE) {
933 TBM_ERR("hal_tbm_bo_get_memory_types failed.");
934 goto get_memory_types_fail;
938 for (i = 0; i < num_bos; i++) {
939 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
941 TBM_ERR("fail to alloc bo idx:%d", i);
942 *error = tbm_get_last_error();
946 _tbm_bo_set_surface(surf->bos[i], surf);
952 for (j = 0; j < i; j++) {
954 tbm_bo_unref(surf->bos[j]);
956 get_memory_types_fail:
958 query_plane_data_fail:
959 hal_tbm_surface_free(hal_surface);
971 tbm_surface_internal_is_valid(tbm_surface_h surface)
975 _tbm_surface_mutex_lock();
976 _tbm_set_last_result(TBM_ERROR_NONE);
978 /* Return silently if surface is null. */
980 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
981 _tbm_surface_mutex_unlock();
985 ret = _tbm_surface_internal_is_valid(surface);
987 _tbm_surface_mutex_unlock();
993 tbm_surface_internal_query_supported_formats(uint32_t **formats,
996 struct _tbm_bufmgr *bufmgr;
997 bool bufmgr_initialized = false;
1000 _tbm_surface_mutex_lock();
1001 _tbm_set_last_result(TBM_ERROR_NONE);
1003 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
1004 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
1006 if (!g_surface_bufmgr) {
1007 _init_surface_bufmgr();
1008 if (!g_surface_bufmgr) {
1009 TBM_ERR("fail bufmgr initialization\n");
1010 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1013 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1014 bufmgr_initialized = true;
1017 bufmgr = g_surface_bufmgr;
1019 error = tbm_module_bufmgr_get_supported_formats(bufmgr->module, formats, num);
1020 if (error != TBM_ERROR_NONE) {
1021 _tbm_set_last_result(error);
1025 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
1027 if (bufmgr_initialized) {
1028 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1029 _deinit_surface_bufmgr();
1032 _tbm_surface_mutex_unlock();
1036 /* LCOV_EXCL_START */
1038 if (bufmgr_initialized) {
1039 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1040 _deinit_surface_bufmgr();
1042 _tbm_surface_mutex_unlock();
1044 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
1047 /* LCOV_EXCL_STOP */
1051 tbm_surface_internal_get_num_planes(tbm_format format)
1055 _tbm_surface_mutex_lock();
1056 _tbm_set_last_result(TBM_ERROR_NONE);
1058 num_planes = _tbm_surface_internal_get_num_planes(format);
1060 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1061 _tbm_surface_mutex_unlock();
1065 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
1067 _tbm_surface_mutex_unlock();
1073 tbm_surface_internal_get_bpp(tbm_format format)
1077 _tbm_surface_mutex_lock();
1078 _tbm_set_last_result(TBM_ERROR_NONE);
1080 bpp = _tbm_surface_internal_get_bpp(format);
1082 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1083 _tbm_surface_mutex_unlock();
1087 _tbm_surface_mutex_unlock();
1089 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
1095 tbm_surface_internal_create_with_flags(int width, int height,
1096 int format, int flags)
1098 struct _tbm_bufmgr *bufmgr;
1099 struct _tbm_surface *surf = NULL;
1100 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
1101 bool bufmgr_initialized = false;
1103 _tbm_surface_mutex_lock();
1104 _tbm_set_last_result(TBM_ERROR_NONE);
1106 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
1107 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
1109 if (!g_surface_bufmgr) {
1110 _init_surface_bufmgr();
1111 if (!g_surface_bufmgr) {
1112 TBM_ERR("fail bufmgr initialization\n");
1113 error = TBM_ERROR_INVALID_OPERATION;
1114 goto check_valid_fail;
1116 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1117 bufmgr_initialized = true;
1120 bufmgr = g_surface_bufmgr;
1121 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1122 TBM_ERR("The bufmgr is invalid\n");
1123 error = TBM_ERROR_INVALID_PARAMETER;
1124 goto check_valid_fail;
1127 if (bufmgr->use_hal_tbm) {
1128 surf = _tbm_surface_internal_hal_tbm_create_surface(bufmgr, width, height, format, flags, &error);
1130 TBM_ERR("_tbm_surface_internal_hal_tbm_create_surface failed.");
1131 goto surface_alloc_fail;
1134 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1136 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1137 goto surface_alloc_fail;
1141 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1142 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1144 LIST_INITHEAD(&surf->user_data_list);
1145 LIST_INITHEAD(&surf->debug_data_list);
1146 LIST_INITHEAD(&surf->destroy_funcs);
1148 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1150 _tbm_set_last_result(error);
1151 _tbm_surface_mutex_unlock();
1155 /* LCOV_EXCL_START */
1159 if (bufmgr_initialized && bufmgr) {
1160 LIST_DELINIT(&bufmgr->surf_list);
1161 _deinit_surface_bufmgr();
1164 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1165 width, height, _tbm_surface_internal_format_to_str(format), flags);
1167 _tbm_set_last_result(error);
1168 _tbm_surface_mutex_unlock();
1170 /* LCOV_EXCL_STOP */
1176 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1177 tbm_bo *bos, int num)
1179 struct _tbm_bufmgr *bufmgr;
1180 struct _tbm_surface *surf = NULL;
1182 bool bufmgr_initialized = false;
1184 _tbm_surface_mutex_lock();
1185 _tbm_set_last_result(TBM_ERROR_NONE);
1187 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1188 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1189 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1190 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1191 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1193 if (!g_surface_bufmgr) {
1194 _init_surface_bufmgr();
1195 if (!g_surface_bufmgr) {
1196 TBM_ERR("fail bufmgr initialization\n");
1197 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1198 goto check_valid_fail;
1200 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1201 bufmgr_initialized = true;
1204 bufmgr = g_surface_bufmgr;
1205 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1206 TBM_ERR("fail to validate the Bufmgr.\n");
1207 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1208 goto check_valid_fail;
1211 surf = calloc(1, sizeof(struct _tbm_surface));
1213 /* LCOV_EXCL_START */
1214 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1215 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1216 goto alloc_surf_fail;
1217 /* LCOV_EXCL_STOP */
1220 surf->magic = TBM_SURFACE_MAGIC;
1221 surf->bufmgr = bufmgr;
1222 surf->info.width = info->width;
1223 surf->info.height = info->height;
1224 surf->info.format = info->format;
1226 surf->info.bpp = info->bpp;
1228 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1229 if (!surf->info.bpp) {
1230 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1234 surf->info.num_planes = info->num_planes;
1237 /* get size, stride and offset */
1238 for (i = 0; i < info->num_planes; i++) {
1239 surf->info.planes[i].offset = info->planes[i].offset;
1240 surf->info.planes[i].stride = info->planes[i].stride;
1242 if (info->planes[i].size > 0)
1243 surf->info.planes[i].size = info->planes[i].size;
1245 uint32_t size = 0, offset = 0, stride = 0;
1248 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1249 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1250 goto plane_data_fail;
1252 surf->info.planes[i].size = size;
1256 surf->planes_bo_idx[i] = 0;
1258 surf->planes_bo_idx[i] = i;
1261 if (info->size > 0) {
1262 surf->info.size = info->size;
1264 surf->info.size = 0;
1265 for (i = 0; i < info->num_planes; i++)
1266 surf->info.size += surf->info.planes[i].size;
1269 surf->flags = TBM_BO_DEFAULT;
1271 /* create only one bo */
1272 surf->num_bos = num;
1273 for (i = 0; i < num; i++) {
1274 if (bos[i] == NULL) {
1275 TBM_ERR("bos[%d] is null.\n", i);
1276 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1280 surf->bos[i] = tbm_bo_ref(bos[i]);
1281 _tbm_bo_set_surface(bos[i], surf);
1284 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1285 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1287 LIST_INITHEAD(&surf->user_data_list);
1288 LIST_INITHEAD(&surf->debug_data_list);
1289 LIST_INITHEAD(&surf->destroy_funcs);
1291 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1293 _tbm_surface_mutex_unlock();
1297 /* LCOV_EXCL_START */
1301 for (i = 0; i < num; i++) {
1303 tbm_bo_unref(surf->bos[i]);
1308 if (bufmgr_initialized && bufmgr) {
1309 LIST_DELINIT(&bufmgr->surf_list);
1310 _deinit_surface_bufmgr();
1312 _tbm_surface_mutex_unlock();
1314 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1315 info->width, info->height,
1316 _tbm_surface_internal_format_to_str(info->format), num);
1317 /* LCOV_EXCL_STOP */
1323 tbm_surface_internal_destroy(tbm_surface_h surface)
1325 _tbm_surface_mutex_lock();
1326 _tbm_set_last_result(TBM_ERROR_NONE);
1328 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1332 if (surface->refcnt > 0) {
1333 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1334 _tbm_surface_mutex_unlock();
1338 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1340 if (surface->refcnt == 0)
1341 _tbm_surface_internal_destroy(surface);
1342 else // if (surface->refcnt < 0)
1343 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1345 _tbm_surface_mutex_unlock();
1349 tbm_surface_internal_ref(tbm_surface_h surface)
1351 _tbm_surface_mutex_lock();
1352 _tbm_set_last_result(TBM_ERROR_NONE);
1354 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1358 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1360 _tbm_surface_mutex_unlock();
1364 tbm_surface_internal_unref(tbm_surface_h surface)
1366 _tbm_surface_mutex_lock();
1367 _tbm_set_last_result(TBM_ERROR_NONE);
1369 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1373 if (surface->refcnt > 0) {
1374 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1375 _tbm_surface_mutex_unlock();
1379 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1381 if (surface->refcnt == 0)
1382 _tbm_surface_internal_destroy(surface);
1384 _tbm_surface_mutex_unlock();
1388 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1390 struct _tbm_surface *surf;
1393 _tbm_surface_mutex_lock();
1394 _tbm_set_last_result(TBM_ERROR_NONE);
1396 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1398 surf = (struct _tbm_surface *)surface;
1399 num = surf->num_bos;
1402 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1404 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1406 _tbm_surface_mutex_unlock();
1412 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1414 struct _tbm_surface *surf;
1417 _tbm_surface_mutex_lock();
1418 _tbm_set_last_result(TBM_ERROR_NONE);
1420 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1421 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1423 surf = (struct _tbm_surface *)surface;
1424 bo = surf->bos[bo_idx];
1426 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1428 _tbm_surface_mutex_unlock();
1434 tbm_surface_internal_get_size(tbm_surface_h surface)
1436 struct _tbm_surface *surf;
1439 _tbm_surface_mutex_lock();
1440 _tbm_set_last_result(TBM_ERROR_NONE);
1442 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1444 surf = (struct _tbm_surface *)surface;
1445 size = surf->info.size;
1447 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1449 _tbm_surface_mutex_unlock();
1455 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1456 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1458 struct _tbm_surface *surf;
1460 _tbm_surface_mutex_lock();
1461 _tbm_set_last_result(TBM_ERROR_NONE);
1463 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1464 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1466 surf = (struct _tbm_surface *)surface;
1468 if (plane_idx >= surf->info.num_planes) {
1469 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1470 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1471 _tbm_surface_mutex_unlock();
1476 *size = surf->info.planes[plane_idx].size;
1479 *offset = surf->info.planes[plane_idx].offset;
1482 *pitch = surf->info.planes[plane_idx].stride;
1484 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1485 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1486 surf->info.planes[plane_idx].stride);
1488 _tbm_surface_mutex_unlock();
1494 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1495 tbm_surface_info_s *info, int map)
1497 struct _tbm_surface *surf;
1498 tbm_bo_handle bo_handles[4];
1501 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1504 _tbm_surface_mutex_lock();
1505 _tbm_set_last_result(TBM_ERROR_NONE);
1507 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1509 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1511 surf = (struct _tbm_surface *)surface;
1513 memset(info, 0x00, sizeof(tbm_surface_info_s));
1514 info->width = surf->info.width;
1515 info->height = surf->info.height;
1516 info->format = surf->info.format;
1517 info->bpp = surf->info.bpp;
1518 info->size = surf->info.size;
1519 info->num_planes = surf->info.num_planes;
1521 for (i = 0; i < surf->info.num_planes; i++) {
1522 info->planes[i].size = surf->info.planes[i].size;
1523 info->planes[i].offset = surf->info.planes[i].offset;
1524 info->planes[i].stride = surf->info.planes[i].stride;
1525 planes_bo_idx[i] = surf->planes_bo_idx[i];
1528 for (i = 0; i < surf->num_bos; i++)
1529 bos[i] = surf->bos[i];
1531 num_bos = surf->num_bos;
1534 _tbm_surface_mutex_unlock();
1535 for (i = 0; i < num_bos; i++) {
1536 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1537 if (bo_handles[i].ptr == NULL) {
1538 for (j = 0; j < i; j++)
1539 tbm_bo_unmap(bos[j]);
1541 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1545 _tbm_surface_mutex_lock();
1547 for (i = 0; i < num_bos; i++) {
1548 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1549 if (bo_handles[i].ptr == NULL) {
1550 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1551 _tbm_surface_mutex_unlock();
1557 for (i = 0; i < info->num_planes; i++) {
1558 if (bo_handles[planes_bo_idx[i]].ptr)
1559 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1562 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1564 _tbm_surface_mutex_unlock();
1570 tbm_surface_internal_unmap(tbm_surface_h surface)
1572 struct _tbm_surface *surf;
1575 _tbm_surface_mutex_lock();
1576 _tbm_set_last_result(TBM_ERROR_NONE);
1578 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1580 surf = (struct _tbm_surface *)surface;
1582 for (i = 0; i < surf->num_bos; i++)
1583 tbm_bo_unmap(surf->bos[i]);
1585 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1587 _tbm_surface_mutex_unlock();
1591 tbm_surface_internal_get_width(tbm_surface_h surface)
1593 struct _tbm_surface *surf;
1596 _tbm_surface_mutex_lock();
1597 _tbm_set_last_result(TBM_ERROR_NONE);
1599 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1601 surf = (struct _tbm_surface *)surface;
1602 width = surf->info.width;
1604 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1606 _tbm_surface_mutex_unlock();
1612 tbm_surface_internal_get_height(tbm_surface_h surface)
1614 struct _tbm_surface *surf;
1615 unsigned int height;
1617 _tbm_surface_mutex_lock();
1618 _tbm_set_last_result(TBM_ERROR_NONE);
1620 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1622 surf = (struct _tbm_surface *)surface;
1623 height = surf->info.height;
1625 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1627 _tbm_surface_mutex_unlock();
1634 tbm_surface_internal_get_format(tbm_surface_h surface)
1636 struct _tbm_surface *surf;
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);
1644 surf = (struct _tbm_surface *)surface;
1645 format = surf->info.format;
1647 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1649 _tbm_surface_mutex_unlock();
1655 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1657 struct _tbm_surface *surf;
1660 _tbm_surface_mutex_lock();
1661 _tbm_set_last_result(TBM_ERROR_NONE);
1663 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1664 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1666 surf = (struct _tbm_surface *)surface;
1667 bo_idx = surf->planes_bo_idx[plane_idx];
1669 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1671 _tbm_surface_mutex_unlock();
1677 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1678 tbm_data_free data_free_func)
1680 tbm_user_data *data;
1682 _tbm_surface_mutex_lock();
1683 _tbm_set_last_result(TBM_ERROR_NONE);
1685 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1687 /* check if the data according to the key exist if so, return false. */
1688 data = user_data_lookup(&surface->user_data_list, key);
1690 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1691 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1692 _tbm_surface_mutex_unlock();
1696 data = user_data_create(key, data_free_func);
1698 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1699 _tbm_surface_mutex_unlock();
1703 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1705 LIST_ADD(&data->item_link, &surface->user_data_list);
1707 _tbm_surface_mutex_unlock();
1713 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1716 tbm_user_data *old_data;
1718 _tbm_surface_mutex_lock();
1719 _tbm_set_last_result(TBM_ERROR_NONE);
1721 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1723 old_data = user_data_lookup(&surface->user_data_list, key);
1725 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1726 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1727 _tbm_surface_mutex_unlock();
1731 if (old_data->data && old_data->free_func)
1732 old_data->free_func(old_data->data);
1734 old_data->data = data;
1736 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1738 _tbm_surface_mutex_unlock();
1744 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1747 tbm_user_data *old_data;
1749 _tbm_surface_mutex_lock();
1750 _tbm_set_last_result(TBM_ERROR_NONE);
1752 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1755 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1756 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1757 _tbm_surface_mutex_unlock();
1762 old_data = user_data_lookup(&surface->user_data_list, key);
1764 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1765 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1766 _tbm_surface_mutex_unlock();
1770 *data = old_data->data;
1772 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1774 _tbm_surface_mutex_unlock();
1780 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1783 tbm_user_data *old_data = (void *)0;
1785 _tbm_surface_mutex_lock();
1786 _tbm_set_last_result(TBM_ERROR_NONE);
1788 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1790 old_data = user_data_lookup(&surface->user_data_list, key);
1792 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1793 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1794 _tbm_surface_mutex_unlock();
1798 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1800 user_data_delete(old_data);
1802 _tbm_surface_mutex_unlock();
1807 /* LCOV_EXCL_START */
1809 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1811 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1813 return surface->debug_pid;
1817 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1819 _tbm_surface_mutex_lock();
1820 _tbm_set_last_result(TBM_ERROR_NONE);
1822 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1824 surface->debug_pid = pid;
1826 _tbm_surface_mutex_unlock();
1829 static tbm_surface_debug_data *
1830 _tbm_surface_internal_debug_data_create(char *key, char *value)
1832 tbm_surface_debug_data *debug_data = NULL;
1834 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1836 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1837 TBM_ERR("fail to allocate the debug_data.");
1841 if (key) debug_data->key = strdup(key);
1842 if (value) debug_data->value = strdup(value);
1848 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1850 if (!debug_data->value && !value)
1853 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1856 if (debug_data->value)
1857 free(debug_data->value);
1860 debug_data->value = strdup(value);
1862 debug_data->value = NULL;
1865 static tbm_surface_debug_data *
1866 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1868 tbm_surface_debug_data *debug_data = NULL;
1870 if (LIST_IS_EMPTY(list))
1873 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1874 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1882 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1884 tbm_surface_debug_data *debug_data = NULL;
1885 tbm_bufmgr bufmgr = NULL;
1887 _tbm_surface_mutex_lock();
1888 _tbm_set_last_result(TBM_ERROR_NONE);
1890 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1891 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1893 bufmgr = surface->bufmgr;
1895 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1897 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1899 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1901 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1903 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1904 _tbm_surface_mutex_unlock();
1908 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1911 /* add new debug key to list */
1912 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1914 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1916 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1919 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1921 _tbm_surface_mutex_unlock();
1927 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1929 tbm_surface_debug_data *old_data = NULL;
1931 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1933 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1934 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1935 if (!strcmp(old_data->key, key))
1936 return old_data->value;
1943 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1944 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1946 struct _tbm_surface_dump_buf_info {
1956 tbm_surface_info_s info;
1958 struct list_head link;
1961 struct _tbm_surface_dump_info {
1962 char *path; // copy???
1965 struct list_head *link;
1966 struct list_head surface_list; /* link of surface */
1969 static tbm_surface_dump_info *g_dump_info = NULL;
1970 static const char *dump_postfix[2] = {"png", "yuv"};
1971 static double scale_factor;
1974 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1975 void *data2, int size2, void *data3, int size3)
1978 unsigned int *blocks;
1980 if (_tbm_surface_check_file_is_symbolic_link(file))
1981 TBM_ERR("%s is symbolic link\n", file);
1983 fp = fopen(file, "w+");
1984 TBM_RETURN_IF_FAIL(fp != NULL);
1986 blocks = (unsigned int *)data1;
1987 fwrite(blocks, 1, size1, fp);
1990 blocks = (unsigned int *)data2;
1991 fwrite(blocks, 1, size2, fp);
1995 blocks = (unsigned int *)data3;
1996 fwrite(blocks, 1, size3, fp);
2003 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
2005 unsigned int *blocks = (unsigned int *)data;
2008 png_bytep *row_pointers;
2011 if (_tbm_surface_check_file_is_symbolic_link(file))
2012 TBM_ERR("%s is symbolic link\n", file);
2014 fp = fopen(file, "wb");
2015 TBM_RETURN_IF_FAIL(fp != NULL);
2017 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
2020 TBM_ERR("fail to create a png write structure.\n");
2025 png_infop pPngInfo = png_create_info_struct(pPngStruct);
2027 TBM_ERR("fail to create a png info structure.\n");
2028 png_destroy_write_struct(&pPngStruct, NULL);
2033 if (setjmp(png_jmpbuf(pPngStruct))) {
2034 /* if png has problem of writing the file, we get here */
2035 TBM_ERR("fail to write png file.\n");
2036 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2041 png_init_io(pPngStruct, fp);
2042 if (format == TBM_FORMAT_XRGB8888) {
2044 png_set_IHDR(pPngStruct,
2051 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2054 png_set_IHDR(pPngStruct,
2059 PNG_COLOR_TYPE_RGBA,
2061 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2064 png_set_bgr(pPngStruct);
2065 png_write_info(pPngStruct, pPngInfo);
2067 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
2068 if (!row_pointers) {
2069 TBM_ERR("fail to allocate the png row_pointers.\n");
2070 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2075 for (y = 0; y < height; ++y) {
2079 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
2081 TBM_ERR("fail to allocate the png row.\n");
2082 for (x = 0; x < y; x++)
2083 png_free(pPngStruct, row_pointers[x]);
2084 png_free(pPngStruct, row_pointers);
2085 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2089 row_pointers[y] = (png_bytep)row;
2091 for (x = 0; x < width; ++x) {
2092 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
2094 if (pixel_size == 3) { // XRGB8888
2095 row[x * pixel_size] = (curBlock & 0xFF);
2096 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2097 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2098 } else { // ARGB8888
2099 row[x * pixel_size] = (curBlock & 0xFF);
2100 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2101 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2102 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2107 png_write_image(pPngStruct, row_pointers);
2108 png_write_end(pPngStruct, pPngInfo);
2110 for (y = 0; y < height; y++)
2111 png_free(pPngStruct, row_pointers[y]);
2112 png_free(pPngStruct, row_pointers);
2114 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2120 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2122 TBM_RETURN_IF_FAIL(path != NULL);
2123 TBM_RETURN_IF_FAIL(w > 0);
2124 TBM_RETURN_IF_FAIL(h > 0);
2125 TBM_RETURN_IF_FAIL(count > 0);
2127 tbm_surface_dump_buf_info *buf_info = NULL;
2128 tbm_surface_h tbm_surface;
2129 tbm_surface_info_s info;
2134 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2138 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2139 TBM_RETURN_IF_FAIL(g_dump_info);
2141 LIST_INITHEAD(&g_dump_info->surface_list);
2142 g_dump_info->count = 0;
2143 g_dump_info->dump_max = count;
2145 /* get buffer size */
2146 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2147 if (tbm_surface == NULL) {
2148 TBM_ERR("tbm_surface_create fail\n");
2154 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2155 TBM_ERR("tbm_surface_get_info fail\n");
2156 tbm_surface_destroy(tbm_surface);
2161 buffer_size = info.size;
2162 tbm_surface_destroy(tbm_surface);
2164 /* create dump lists */
2165 for (i = 0; i < count; i++) {
2168 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2169 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2171 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2173 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2178 buf_info->index = i;
2180 buf_info->size = buffer_size;
2182 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2185 g_dump_info->path = path;
2186 g_dump_info->link = &g_dump_info->surface_list;
2190 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2195 /* free resources */
2196 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2197 tbm_surface_dump_buf_info *tmp;
2199 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2200 tbm_bo_unref(buf_info->bo);
2201 LIST_DEL(&buf_info->link);
2206 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2215 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2222 tbm_surface_internal_dump_start(path, w, h, count);
2223 scale_factor = scale;
2227 tbm_surface_internal_dump_end(void)
2229 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2230 tbm_bo_handle bo_handle;
2235 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2242 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2245 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2246 if (bo_handle.ptr == NULL) {
2247 tbm_bo_unref(buf_info->bo);
2248 LIST_DEL(&buf_info->link);
2253 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2254 TBM_INFO("Dump File.. %s generated.\n", file);
2256 if (buf_info->dirty) {
2257 void *ptr1 = NULL, *ptr2 = NULL;
2259 switch (buf_info->info.format) {
2260 case TBM_FORMAT_ARGB8888:
2261 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2262 buf_info->info.planes[0].stride >> 2,
2263 buf_info->info.height,
2264 buf_info->info.planes[0].stride,
2265 TBM_FORMAT_ARGB8888);
2267 case TBM_FORMAT_XRGB8888:
2268 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2269 buf_info->info.planes[0].stride >> 2,
2270 buf_info->info.height,
2271 buf_info->info.planes[0].stride,
2272 TBM_FORMAT_XRGB8888);
2274 case TBM_FORMAT_YVU420:
2275 case TBM_FORMAT_YUV420:
2276 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2277 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2278 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2279 buf_info->info.planes[0].stride * buf_info->info.height,
2281 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2283 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2285 case TBM_FORMAT_NV12:
2286 case TBM_FORMAT_NV21:
2287 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2288 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2289 buf_info->info.planes[0].stride * buf_info->info.height,
2291 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2294 case TBM_FORMAT_YUYV:
2295 case TBM_FORMAT_UYVY:
2296 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2297 buf_info->info.planes[0].stride * buf_info->info.height,
2301 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2304 } else if (buf_info->dirty_shm)
2305 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2306 buf_info->shm_stride >> 2,
2308 buf_info->shm_stride, 0);
2310 tbm_bo_unmap(buf_info->bo);
2311 tbm_bo_unref(buf_info->bo);
2312 LIST_DEL(&buf_info->link);
2319 TBM_INFO("Dump End..\n");
2322 static pixman_format_code_t
2323 _tbm_surface_internal_pixman_format_get(tbm_format format)
2326 case TBM_FORMAT_ARGB8888:
2327 return PIXMAN_a8r8g8b8;
2328 case TBM_FORMAT_XRGB8888:
2329 return PIXMAN_x8r8g8b8;
2338 * This function supports only if a buffer has below formats.
2339 * - TBM_FORMAT_ARGB8888
2340 * - TBM_FORMAT_XRGB8888
2342 static tbm_surface_error_e
2343 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2344 int format, int src_stride, int src_w, int src_h,
2345 int dst_stride, int dst_w, int dst_h)
2347 pixman_image_t *src_img = NULL, *dst_img = NULL;
2348 pixman_format_code_t pixman_format;
2349 pixman_transform_t t;
2350 struct pixman_f_transform ft;
2351 double scale_x, scale_y;
2353 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2354 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2356 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2357 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2360 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2361 (uint32_t*)src_ptr, src_stride);
2362 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2365 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2366 (uint32_t*)dst_ptr, dst_stride);
2367 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2369 pixman_f_transform_init_identity(&ft);
2371 scale_x = (double)src_w / dst_w;
2372 scale_y = (double)src_h / dst_h;
2374 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2375 pixman_f_transform_translate(&ft, NULL, 0, 0);
2376 pixman_transform_from_pixman_f_transform(&t, &ft);
2377 pixman_image_set_transform(src_img, &t);
2379 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2380 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2382 pixman_image_unref(src_img);
2383 pixman_image_unref(dst_img);
2385 return TBM_SURFACE_ERROR_NONE;
2389 pixman_image_unref(src_img);
2391 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2394 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2395 #define KEY_LEN 5 // "_XXXX"
2396 #define KEYS_LEN KEY_LEN * MAX_BOS
2398 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2400 char *keys, temp_key[KEY_LEN + 1];
2401 struct _tbm_surface *surf;
2405 _tbm_surface_mutex_lock();
2407 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2409 surf = (struct _tbm_surface *)surface;
2411 num_bos = surf->num_bos;
2412 if (num_bos > MAX_BOS)
2415 keys = calloc(KEYS_LEN + 1, sizeof(char));
2417 TBM_ERR("Failed to alloc memory");
2418 _tbm_surface_mutex_unlock();
2422 for (i = 0; i < num_bos; i++) {
2423 memset(temp_key, 0x00, KEY_LEN + 1);
2425 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2426 strncat(keys, temp_key, KEY_LEN + 1);
2429 _tbm_surface_mutex_unlock();
2434 static void _tbm_surface_internal_put_keys(char *keys)
2441 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2443 TBM_RETURN_IF_FAIL(surface != NULL);
2444 TBM_RETURN_IF_FAIL(type != NULL);
2446 tbm_surface_dump_buf_info *buf_info;
2447 struct list_head *next_link;
2448 tbm_surface_info_s info;
2449 tbm_bo_handle bo_handle;
2450 const char *postfix;
2451 const char *format = NULL;
2458 next_link = g_dump_info->link->next;
2459 TBM_RETURN_IF_FAIL(next_link != NULL);
2461 if (next_link == &g_dump_info->surface_list) {
2462 next_link = next_link->next;
2463 TBM_RETURN_IF_FAIL(next_link != NULL);
2466 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2467 TBM_RETURN_IF_FAIL(buf_info != NULL);
2469 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2470 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2472 if (scale_factor > 0.0) {
2475 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2476 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2477 _tbm_surface_internal_format_to_str(info.format));
2478 tbm_surface_unmap(surface);
2482 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2484 buf_info->info.width = info.width * scale_factor;
2485 buf_info->info.height = info.height * scale_factor;
2486 buf_info->info.format = info.format;
2487 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2488 if (!buf_info->info.bpp) {
2489 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2490 tbm_surface_unmap(surface);
2493 buf_info->info.num_planes = 1;
2494 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2495 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2497 if (buf_info->info.size > buf_info->size) {
2498 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2499 buf_info->info.size, buf_info->size);
2500 tbm_surface_unmap(surface);
2504 if (info.size > buf_info->size) {
2505 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2506 info.size, buf_info->size);
2507 tbm_surface_unmap(surface);
2511 /* make the file information */
2512 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2515 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2516 postfix = dump_postfix[0];
2517 format = _tbm_surface_internal_format_to_str(info.format);
2519 postfix = dump_postfix[1];
2521 keys = _tbm_surface_internal_get_keys(surface);
2523 TBM_ERR("fail to get keys");
2524 tbm_surface_unmap(surface);
2529 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2530 if (!bo_handle.ptr) {
2531 TBM_ERR("fail to map bo");
2532 _tbm_surface_internal_put_keys(keys);
2533 tbm_surface_unmap(surface);
2536 memset(bo_handle.ptr, 0x00, buf_info->size);
2538 switch (info.format) {
2539 case TBM_FORMAT_ARGB8888:
2540 case TBM_FORMAT_XRGB8888:
2541 snprintf(buf_info->name, sizeof(buf_info->name),
2542 "%10.3f_%03d%s_%p_%s-%s.%s",
2543 _tbm_surface_internal_get_time(),
2544 g_dump_info->count++, keys, surface, format, type, postfix);
2546 if (scale_factor > 0.0) {
2547 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2549 buf_info->info.format,
2550 info.planes[0].stride,
2551 info.width, info.height,
2552 buf_info->info.planes[0].stride,
2553 buf_info->info.width,
2554 buf_info->info.height);
2555 if (ret != TBM_SURFACE_ERROR_NONE) {
2556 TBM_ERR("fail to scale buffer");
2557 tbm_bo_unmap(buf_info->bo);
2558 _tbm_surface_internal_put_keys(keys);
2559 tbm_surface_unmap(surface);
2563 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2565 case TBM_FORMAT_YVU420:
2566 case TBM_FORMAT_YUV420:
2567 snprintf(buf_info->name, sizeof(buf_info->name),
2568 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2569 _tbm_surface_internal_get_time(),
2570 g_dump_info->count++, keys, type, info.planes[0].stride,
2571 info.height, FOURCC_STR(info.format), postfix);
2572 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2573 bo_handle.ptr += info.planes[0].stride * info.height;
2574 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2575 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2576 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2578 case TBM_FORMAT_NV12:
2579 case TBM_FORMAT_NV21:
2580 snprintf(buf_info->name, sizeof(buf_info->name),
2581 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2582 _tbm_surface_internal_get_time(),
2583 g_dump_info->count++, keys, type, info.planes[0].stride,
2584 info.height, FOURCC_STR(info.format), postfix);
2585 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2586 bo_handle.ptr += info.planes[0].stride * info.height;
2587 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2589 case TBM_FORMAT_YUYV:
2590 case TBM_FORMAT_UYVY:
2591 snprintf(buf_info->name, sizeof(buf_info->name),
2592 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2593 _tbm_surface_internal_get_time(),
2594 g_dump_info->count++, keys, type, info.planes[0].stride,
2595 info.height, FOURCC_STR(info.format), postfix);
2596 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2599 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2600 tbm_bo_unmap(buf_info->bo);
2601 _tbm_surface_internal_put_keys(keys);
2602 tbm_surface_unmap(surface);
2606 tbm_bo_unmap(buf_info->bo);
2608 _tbm_surface_internal_put_keys(keys);
2610 tbm_surface_unmap(surface);
2612 buf_info->dirty = 1;
2613 buf_info->dirty_shm = 0;
2615 if (g_dump_info->count == 1000)
2616 g_dump_info->count = 0;
2618 g_dump_info->link = next_link;
2620 TBM_INFO("Dump %s \n", buf_info->name);
2623 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2626 TBM_RETURN_IF_FAIL(ptr != NULL);
2627 TBM_RETURN_IF_FAIL(w > 0);
2628 TBM_RETURN_IF_FAIL(h > 0);
2629 TBM_RETURN_IF_FAIL(stride > 0);
2630 TBM_RETURN_IF_FAIL(type != NULL);
2632 tbm_surface_dump_buf_info *buf_info;
2633 struct list_head *next_link;
2634 tbm_bo_handle bo_handle;
2635 int ret, size, dw = 0, dh = 0, dstride = 0;
2640 next_link = g_dump_info->link->next;
2641 TBM_RETURN_IF_FAIL(next_link != NULL);
2643 if (next_link == &g_dump_info->surface_list) {
2644 next_link = next_link->next;
2645 TBM_RETURN_IF_FAIL(next_link != NULL);
2648 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2649 TBM_RETURN_IF_FAIL(buf_info != NULL);
2651 if (scale_factor > 0.0) {
2654 dw = w * scale_factor;
2655 dh = h * scale_factor;
2657 size = dstride * dh;
2661 if (size > buf_info->size) {
2662 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2663 size, buf_info->size);
2668 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2669 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2671 memset(bo_handle.ptr, 0x00, buf_info->size);
2672 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2674 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2675 _tbm_surface_internal_get_time(),
2676 g_dump_info->count++, type, dump_postfix[0]);
2677 if (scale_factor > 0.0) {
2678 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2679 TBM_FORMAT_ARGB8888, stride,
2680 w, h, dstride, dw, dh);
2681 if (ret != TBM_SURFACE_ERROR_NONE) {
2682 TBM_ERR("fail to scale buffer");
2683 tbm_bo_unmap(buf_info->bo);
2686 buf_info->shm_stride = dstride;
2687 buf_info->shm_h = dh;
2689 memcpy(bo_handle.ptr, ptr, size);
2690 buf_info->shm_stride = stride;
2691 buf_info->shm_h = h;
2694 tbm_bo_unmap(buf_info->bo);
2696 buf_info->dirty = 0;
2697 buf_info->dirty_shm = 1;
2699 if (g_dump_info->count == 1000)
2700 g_dump_info->count = 0;
2702 g_dump_info->link = next_link;
2704 TBM_INFO("Dump %s \n", buf_info->name);
2708 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2710 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2711 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2712 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2714 tbm_surface_info_s info;
2715 const char *postfix;
2719 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2720 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2722 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2723 postfix = dump_postfix[0];
2725 postfix = dump_postfix[1];
2727 if (strcmp(postfix, type)) {
2728 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2729 tbm_surface_unmap(surface);
2733 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2735 if (!access(file, 0)) {
2736 TBM_ERR("can't capture buffer, exist file %s", file);
2737 tbm_surface_unmap(surface);
2741 switch (info.format) {
2742 case TBM_FORMAT_ARGB8888:
2743 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2746 info.planes[0].stride,
2747 TBM_FORMAT_ARGB8888);
2749 case TBM_FORMAT_XRGB8888:
2750 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2753 info.planes[0].stride,
2754 TBM_FORMAT_XRGB8888);
2756 case TBM_FORMAT_YVU420:
2757 case TBM_FORMAT_YUV420:
2758 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2759 info.planes[0].stride * info.height,
2761 info.planes[1].stride * (info.height >> 1),
2763 info.planes[2].stride * (info.height >> 1));
2765 case TBM_FORMAT_NV12:
2766 case TBM_FORMAT_NV21:
2767 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2768 info.planes[0].stride * info.height,
2770 info.planes[1].stride * (info.height >> 1),
2773 case TBM_FORMAT_YUYV:
2774 case TBM_FORMAT_UYVY:
2775 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2776 info.planes[0].stride * info.height,
2780 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2781 tbm_surface_unmap(surface);
2785 tbm_surface_unmap(surface);
2787 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2793 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2794 const char *path, const char *name, const char *type)
2796 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2797 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2798 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2799 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2800 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2801 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2805 if (strcmp(dump_postfix[0], type)) {
2806 TBM_ERR("Not supported type:%s'", type);
2810 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2812 if (!access(file, 0)) {
2813 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2817 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2819 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2825 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2827 struct _tbm_surface *surf;
2829 _tbm_surface_mutex_lock();
2830 _tbm_set_last_result(TBM_ERROR_NONE);
2832 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2833 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2834 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2836 surf = (struct _tbm_surface *)surface;
2840 surf->damage.width = width;
2841 surf->damage.height = height;
2843 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2844 surface, x, y, width, height);
2846 _tbm_surface_mutex_unlock();
2852 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2854 struct _tbm_surface *surf;
2856 _tbm_surface_mutex_lock();
2857 _tbm_set_last_result(TBM_ERROR_NONE);
2859 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2861 surf = (struct _tbm_surface *)surface;
2863 if (x) *x = surf->damage.x;
2864 if (y) *y = surf->damage.y;
2865 if (width) *width = surf->damage.width;
2866 if (height) *height = surf->damage.height;
2868 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2869 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2871 _tbm_surface_mutex_unlock();
2877 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2879 struct _tbm_surface *surf;
2880 tbm_surface_destroy_func_info *func_info = NULL;
2882 _tbm_surface_mutex_lock();
2883 _tbm_set_last_result(TBM_ERROR_NONE);
2885 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2886 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2888 surf = (struct _tbm_surface *)surface;
2889 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2890 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2891 TBM_ERR("can't add twice");
2892 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2893 _tbm_surface_mutex_unlock();
2898 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2899 if (func_info == NULL) {
2900 TBM_ERR("alloc failed");
2901 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2902 _tbm_surface_mutex_unlock();
2906 func_info->destroy_func = func;
2907 func_info->user_data = user_data;
2909 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2911 _tbm_surface_mutex_unlock();
2917 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2919 struct _tbm_surface *surf;
2920 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2922 _tbm_surface_mutex_lock();
2923 _tbm_set_last_result(TBM_ERROR_NONE);
2925 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2926 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2928 surf = (struct _tbm_surface *)surface;
2929 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2930 if (func_info->destroy_func != func || func_info->user_data != user_data)
2933 LIST_DEL(&func_info->item_link);
2936 _tbm_surface_mutex_unlock();
2941 _tbm_surface_mutex_unlock();
2944 tbm_surface_buffer_data *
2945 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2947 tbm_surface_buffer_data *buffer_data = NULL;
2948 struct _tbm_surface *surf;
2949 struct _tbm_bufmgr *bufmgr;
2951 _tbm_surface_mutex_lock();
2953 surf = (struct _tbm_surface *)surface;
2954 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, error, TBM_ERROR_INVALID_PARAMETER);
2956 bufmgr = surf->bufmgr;
2957 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2959 // this function supports when it comes to be use_hal.
2960 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, error, TBM_ERROR_NOT_SUPPORTED);
2963 buffer_data = (tbm_surface_buffer_data *)hal_tbm_surface_export((hal_tbm_surface *)surf->hal_surface,
2964 (hal_tbm_error *)error);
2965 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
2967 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
2970 *error = TBM_ERROR_NONE;
2972 _tbm_set_last_result(TBM_ERROR_NONE);
2973 _tbm_surface_mutex_unlock();
2979 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
2981 struct _tbm_surface *surf;
2982 struct _tbm_bufmgr *bufmgr;
2984 _tbm_surface_mutex_lock();
2986 bufmgr = g_surface_bufmgr;
2987 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2989 // this function supports when it comes to be use_hal.
2990 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, error, TBM_ERROR_NOT_SUPPORTED);
2992 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2993 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2994 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2995 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, error, TBM_ERROR_INVALID_PARAMETER);
2998 surf = _tbm_surface_internal_hal_tbm_import_surface(bufmgr,
2999 (int)surface_info->width,
3000 (int)surface_info->height,
3001 (int)surface_info->format,
3004 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
3006 LIST_INITHEAD(&surf->user_data_list);
3007 LIST_INITHEAD(&surf->debug_data_list);
3008 LIST_INITHEAD(&surf->destroy_funcs);
3010 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
3012 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
3014 _tbm_set_last_result(TBM_ERROR_NONE);
3015 _tbm_surface_mutex_unlock();
3017 return (tbm_surface_h)surf;