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 _tbm_set_last_result(error_type);\
103 _tbm_surface_mutex_unlock();\
108 /* LCOV_EXCL_START */
110 _tbm_surface_internal_get_time(void)
115 clock_gettime(CLOCK_MONOTONIC, &tp);
116 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
118 return time / 1000.0;
122 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
124 LIST_DEL(&debug_data->item_link);
126 if (debug_data->key) free(debug_data->key);
127 if (debug_data->value) free(debug_data->value);
132 _tbm_surface_internal_format_to_str(tbm_format format)
136 return "TBM_FORMAT_C8";
137 case TBM_FORMAT_RGB332:
138 return "TBM_FORMAT_RGB332";
139 case TBM_FORMAT_BGR233:
140 return "TBM_FORMAT_BGR233";
141 case TBM_FORMAT_XRGB4444:
142 return "TBM_FORMAT_XRGB4444";
143 case TBM_FORMAT_XBGR4444:
144 return "TBM_FORMAT_XBGR4444";
145 case TBM_FORMAT_RGBX4444:
146 return "TBM_FORMAT_RGBX4444";
147 case TBM_FORMAT_BGRX4444:
148 return "TBM_FORMAT_BGRX4444";
149 case TBM_FORMAT_ARGB4444:
150 return "TBM_FORMAT_ARGB4444";
151 case TBM_FORMAT_ABGR4444:
152 return "TBM_FORMAT_ABGR4444";
153 case TBM_FORMAT_RGBA4444:
154 return "TBM_FORMAT_RGBA4444";
155 case TBM_FORMAT_BGRA4444:
156 return "TBM_FORMAT_BGRA4444";
157 case TBM_FORMAT_XRGB1555:
158 return "TBM_FORMAT_XRGB1555";
159 case TBM_FORMAT_XBGR1555:
160 return "TBM_FORMAT_XBGR1555";
161 case TBM_FORMAT_RGBX5551:
162 return "TBM_FORMAT_RGBX5551";
163 case TBM_FORMAT_BGRX5551:
164 return "TBM_FORMAT_BGRX5551";
165 case TBM_FORMAT_ARGB1555:
166 return "TBM_FORMAT_ARGB1555";
167 case TBM_FORMAT_ABGR1555:
168 return "TBM_FORMAT_ABGR1555";
169 case TBM_FORMAT_RGBA5551:
170 return "TBM_FORMAT_RGBA5551";
171 case TBM_FORMAT_BGRA5551:
172 return "TBM_FORMAT_BGRA5551";
173 case TBM_FORMAT_RGB565:
174 return "TBM_FORMAT_RGB565";
175 case TBM_FORMAT_BGR565:
176 return "TBM_FORMAT_BGR565";
177 case TBM_FORMAT_RGB888:
178 return "TBM_FORMAT_RGB888";
179 case TBM_FORMAT_BGR888:
180 return "TBM_FORMAT_BGR888";
181 case TBM_FORMAT_XRGB8888:
182 return "TBM_FORMAT_XRGB8888";
183 case TBM_FORMAT_XBGR8888:
184 return "TBM_FORMAT_XBGR8888";
185 case TBM_FORMAT_RGBX8888:
186 return "TBM_FORMAT_RGBX8888";
187 case TBM_FORMAT_BGRX8888:
188 return "TBM_FORMAT_BGRX8888";
189 case TBM_FORMAT_ARGB8888:
190 return "TBM_FORMAT_ARGB8888";
191 case TBM_FORMAT_ABGR8888:
192 return "TBM_FORMAT_ABGR8888";
193 case TBM_FORMAT_RGBA8888:
194 return "TBM_FORMAT_RGBA8888";
195 case TBM_FORMAT_BGRA8888:
196 return "TBM_FORMAT_BGRA8888";
197 case TBM_FORMAT_XRGB2101010:
198 return "TBM_FORMAT_XRGB2101010";
199 case TBM_FORMAT_XBGR2101010:
200 return "TBM_FORMAT_XBGR2101010";
201 case TBM_FORMAT_RGBX1010102:
202 return "TBM_FORMAT_RGBX1010102";
203 case TBM_FORMAT_BGRX1010102:
204 return "TBM_FORMAT_BGRX1010102";
205 case TBM_FORMAT_ARGB2101010:
206 return "TBM_FORMAT_ARGB2101010";
207 case TBM_FORMAT_ABGR2101010:
208 return "TBM_FORMAT_ABGR2101010";
209 case TBM_FORMAT_RGBA1010102:
210 return "TBM_FORMAT_RGBA1010102";
211 case TBM_FORMAT_BGRA1010102:
212 return "TBM_FORMAT_BGRA1010102";
213 case TBM_FORMAT_YUYV:
214 return "TBM_FORMAT_YUYV";
215 case TBM_FORMAT_YVYU:
216 return "TBM_FORMAT_YVYU";
217 case TBM_FORMAT_UYVY:
218 return "TBM_FORMAT_UYVY";
219 case TBM_FORMAT_VYUY:
220 return "TBM_FORMAT_VYUY";
221 case TBM_FORMAT_AYUV:
222 return "TBM_FORMAT_AYUV";
223 case TBM_FORMAT_NV12:
224 return "TBM_FORMAT_NV12";
225 case TBM_FORMAT_NV21:
226 return "TBM_FORMAT_NV21";
227 case TBM_FORMAT_NV16:
228 return "TBM_FORMAT_NV16";
229 case TBM_FORMAT_NV61:
230 return "TBM_FORMAT_NV61";
231 case TBM_FORMAT_YUV410:
232 return "TBM_FORMAT_YUV410";
233 case TBM_FORMAT_YVU410:
234 return "TBM_FORMAT_YVU410";
235 case TBM_FORMAT_YUV411:
236 return "TBM_FORMAT_YUV411";
237 case TBM_FORMAT_YVU411:
238 return "TBM_FORMAT_YVU411";
239 case TBM_FORMAT_YUV420:
240 return "TBM_FORMAT_YUV420";
241 case TBM_FORMAT_YVU420:
242 return "TBM_FORMAT_YVU420";
243 case TBM_FORMAT_YUV422:
244 return "TBM_FORMAT_YUV422";
245 case TBM_FORMAT_YVU422:
246 return "TBM_FORMAT_YVU422";
247 case TBM_FORMAT_YUV444:
248 return "TBM_FORMAT_YUV444";
249 case TBM_FORMAT_YVU444:
250 return "TBM_FORMAT_YVU444";
251 case TBM_FORMAT_NV12MT:
252 return "TBM_FORMAT_NV12MT";
259 _tbm_surface_mutex_lock(void)
261 pthread_mutex_lock(&tbm_surface_lock);
265 _tbm_surface_mutex_unlock(void)
267 pthread_mutex_unlock(&tbm_surface_lock);
271 _init_surface_bufmgr(void)
273 g_surface_bufmgr = tbm_bufmgr_init(-1);
277 _deinit_surface_bufmgr(void)
279 if (!g_surface_bufmgr)
282 tbm_bufmgr_deinit(g_surface_bufmgr);
283 g_surface_bufmgr = NULL;
288 _tbm_surface_internal_magic_check(tbm_surface_h surface)
290 if (surface->magic != TBM_SURFACE_MAGIC)
297 _tbm_surface_internal_is_valid(tbm_surface_h surface)
300 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
301 TBM_ERR("error: No valid tbm_surface is NULL\n");
305 if (!_tbm_surface_internal_magic_check(surface)) {
306 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
307 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
315 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
316 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
318 TBM_RETURN_VAL_IF_FAIL(surface, 0);
319 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
321 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
322 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
325 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
326 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
327 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
328 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
330 error = tbm_module_bufmgr_get_plane_data(bufmgr->module, surf->info.format, plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
331 if (error != TBM_ERROR_NONE) {
332 _tbm_set_last_result(error);
340 _tbm_surface_internal_destroy(tbm_surface_h surface)
343 tbm_bufmgr bufmgr = surface->bufmgr;
344 tbm_user_data *old_data = NULL, *tmp = NULL;
345 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
346 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
348 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
349 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
350 func_info->destroy_func(surface, func_info->user_data);
352 TBM_DBG("free destroy_funcs %p\n", surface);
353 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
354 LIST_DEL(&func_info->item_link);
359 /* destory the user_data_list */
360 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
361 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
362 TBM_DBG("free user_data\n");
363 user_data_delete(old_data);
367 for (i = 0; i < surface->num_bos; i++) {
368 surface->bos[i]->surface = NULL;
370 tbm_bo_unref(surface->bos[i]);
371 surface->bos[i] = NULL;
374 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
375 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
376 _tbm_surface_internal_debug_data_delete(debug_old_data);
379 LIST_DEL(&surface->item_link);
382 if (surface->hal_surface) {
383 hal_tbm_surface_free(surface->hal_surface);
384 surface->hal_surface = NULL;
390 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
391 LIST_DELINIT(&bufmgr->surf_list);
393 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
394 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
395 _tbm_surface_internal_debug_data_delete(debug_old_data);
399 _deinit_surface_bufmgr();
403 /* LCOV_EXCL_START */
405 _tbm_surface_check_file_is_symbolic_link(const char* path)
412 if (stat(path, &sb) != 0)
415 if (S_ISLNK(sb.st_mode))
423 _tbm_surface_internal_get_num_planes(tbm_format format)
429 case TBM_FORMAT_RGB332:
430 case TBM_FORMAT_BGR233:
431 case TBM_FORMAT_XRGB4444:
432 case TBM_FORMAT_XBGR4444:
433 case TBM_FORMAT_RGBX4444:
434 case TBM_FORMAT_BGRX4444:
435 case TBM_FORMAT_ARGB4444:
436 case TBM_FORMAT_ABGR4444:
437 case TBM_FORMAT_RGBA4444:
438 case TBM_FORMAT_BGRA4444:
439 case TBM_FORMAT_XRGB1555:
440 case TBM_FORMAT_XBGR1555:
441 case TBM_FORMAT_RGBX5551:
442 case TBM_FORMAT_BGRX5551:
443 case TBM_FORMAT_ARGB1555:
444 case TBM_FORMAT_ABGR1555:
445 case TBM_FORMAT_RGBA5551:
446 case TBM_FORMAT_BGRA5551:
447 case TBM_FORMAT_RGB565:
448 case TBM_FORMAT_BGR565:
449 case TBM_FORMAT_RGB888:
450 case TBM_FORMAT_BGR888:
451 case TBM_FORMAT_XRGB8888:
452 case TBM_FORMAT_XBGR8888:
453 case TBM_FORMAT_RGBX8888:
454 case TBM_FORMAT_BGRX8888:
455 case TBM_FORMAT_ARGB8888:
456 case TBM_FORMAT_ABGR8888:
457 case TBM_FORMAT_RGBA8888:
458 case TBM_FORMAT_BGRA8888:
459 case TBM_FORMAT_XRGB2101010:
460 case TBM_FORMAT_XBGR2101010:
461 case TBM_FORMAT_RGBX1010102:
462 case TBM_FORMAT_BGRX1010102:
463 case TBM_FORMAT_ARGB2101010:
464 case TBM_FORMAT_ABGR2101010:
465 case TBM_FORMAT_RGBA1010102:
466 case TBM_FORMAT_BGRA1010102:
467 case TBM_FORMAT_YUYV:
468 case TBM_FORMAT_YVYU:
469 case TBM_FORMAT_UYVY:
470 case TBM_FORMAT_VYUY:
471 case TBM_FORMAT_AYUV:
474 case TBM_FORMAT_NV12:
475 case TBM_FORMAT_NV12MT:
476 case TBM_FORMAT_NV21:
477 case TBM_FORMAT_NV16:
478 case TBM_FORMAT_NV61:
481 case TBM_FORMAT_YUV410:
482 case TBM_FORMAT_YVU410:
483 case TBM_FORMAT_YUV411:
484 case TBM_FORMAT_YVU411:
485 case TBM_FORMAT_YUV420:
486 case TBM_FORMAT_YVU420:
487 case TBM_FORMAT_YUV422:
488 case TBM_FORMAT_YVU422:
489 case TBM_FORMAT_YUV444:
490 case TBM_FORMAT_YVU444:
495 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
503 _tbm_surface_internal_get_bpp(tbm_format format)
510 case TBM_FORMAT_RGB332:
511 case TBM_FORMAT_BGR233:
514 case TBM_FORMAT_XRGB4444:
515 case TBM_FORMAT_XBGR4444:
516 case TBM_FORMAT_RGBX4444:
517 case TBM_FORMAT_BGRX4444:
518 case TBM_FORMAT_ARGB4444:
519 case TBM_FORMAT_ABGR4444:
520 case TBM_FORMAT_RGBA4444:
521 case TBM_FORMAT_BGRA4444:
522 case TBM_FORMAT_XRGB1555:
523 case TBM_FORMAT_XBGR1555:
524 case TBM_FORMAT_RGBX5551:
525 case TBM_FORMAT_BGRX5551:
526 case TBM_FORMAT_ARGB1555:
527 case TBM_FORMAT_ABGR1555:
528 case TBM_FORMAT_RGBA5551:
529 case TBM_FORMAT_BGRA5551:
530 case TBM_FORMAT_RGB565:
531 case TBM_FORMAT_BGR565:
534 case TBM_FORMAT_RGB888:
535 case TBM_FORMAT_BGR888:
538 case TBM_FORMAT_XRGB8888:
539 case TBM_FORMAT_XBGR8888:
540 case TBM_FORMAT_RGBX8888:
541 case TBM_FORMAT_BGRX8888:
542 case TBM_FORMAT_ARGB8888:
543 case TBM_FORMAT_ABGR8888:
544 case TBM_FORMAT_RGBA8888:
545 case TBM_FORMAT_BGRA8888:
546 case TBM_FORMAT_XRGB2101010:
547 case TBM_FORMAT_XBGR2101010:
548 case TBM_FORMAT_RGBX1010102:
549 case TBM_FORMAT_BGRX1010102:
550 case TBM_FORMAT_ARGB2101010:
551 case TBM_FORMAT_ABGR2101010:
552 case TBM_FORMAT_RGBA1010102:
553 case TBM_FORMAT_BGRA1010102:
554 case TBM_FORMAT_YUYV:
555 case TBM_FORMAT_YVYU:
556 case TBM_FORMAT_UYVY:
557 case TBM_FORMAT_VYUY:
558 case TBM_FORMAT_AYUV:
561 case TBM_FORMAT_NV12:
562 case TBM_FORMAT_NV12MT:
563 case TBM_FORMAT_NV21:
566 case TBM_FORMAT_NV16:
567 case TBM_FORMAT_NV61:
570 case TBM_FORMAT_YUV410:
571 case TBM_FORMAT_YVU410:
574 case TBM_FORMAT_YUV411:
575 case TBM_FORMAT_YVU411:
576 case TBM_FORMAT_YUV420:
577 case TBM_FORMAT_YVU420:
580 case TBM_FORMAT_YUV422:
581 case TBM_FORMAT_YVU422:
584 case TBM_FORMAT_YUV444:
585 case TBM_FORMAT_YVU444:
589 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
596 static struct _tbm_surface *
597 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
599 struct _tbm_surface *surf = NULL;
600 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
603 surf = calloc(1, sizeof(struct _tbm_surface));
605 /* LCOV_EXCL_START */
606 TBM_ERR("fail to alloc surf\n");
607 *error = TBM_ERROR_OUT_OF_MEMORY;
608 goto alloc_surf_fail;
612 surf->magic = TBM_SURFACE_MAGIC;
613 surf->bufmgr = bufmgr;
614 surf->info.width = width;
615 surf->info.height = height;
616 surf->info.format = format;
617 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
618 if (!surf->info.bpp) {
619 TBM_ERR("fail to get bpp from format(%d), error(%s)\n", format, tbm_error_str(*error));
620 *error = tbm_get_last_error();
624 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
625 if (!surf->info.num_planes) {
626 TBM_ERR("fail to get num_planes from format(%d), error(%s)\n", format, tbm_error_str(*error));
627 *error = tbm_get_last_error();
628 goto num_planes_fail;
632 /* get size, stride and offset bo_idx */
633 for (i = 0; i < surf->info.num_planes; i++) {
634 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
635 TBM_ERR("fail to query plane data\n");
636 *error = tbm_get_last_error();
637 goto query_plane_data_fail;
640 surf->info.planes[i].size = size;
641 surf->info.planes[i].offset = offset;
642 surf->info.planes[i].stride = stride;
643 surf->planes_bo_idx[i] = bo_idx;
648 for (i = 0; i < surf->info.num_planes; i++) {
649 surf->info.size += surf->info.planes[i].size;
651 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
652 surf->num_bos = surf->planes_bo_idx[i] + 1;
657 for (i = 0; i < surf->num_bos; i++) {
659 for (j = 0; j < surf->info.num_planes; j++) {
660 if (surf->planes_bo_idx[j] == i)
661 bo_size += surf->info.planes[j].size;
664 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
666 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
668 TBM_ERR("fail to alloc bo idx:%d\n", i);
669 *error = tbm_get_last_error();
674 _tbm_bo_set_surface(surf->bos[i], surf);
677 *error = TBM_ERROR_NONE;
682 for (j = 0; j < i; j++) {
684 tbm_bo_unref(surf->bos[j]);
686 query_plane_data_fail:
695 static struct _tbm_surface *
696 _tbm_surface_internal_hal_tbm_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
698 struct _tbm_surface *surf = NULL;
699 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
701 hal_tbm_surface *hal_surface = NULL;
702 hal_tbm_bo **hal_bos = NULL;
705 surf = calloc(1, sizeof(struct _tbm_surface));
707 /* LCOV_EXCL_START */
708 TBM_ERR("fail to alloc surf");
709 *error = TBM_ERROR_OUT_OF_MEMORY;
710 goto alloc_surf_fail;
715 surf->magic = TBM_SURFACE_MAGIC;
716 surf->bufmgr = bufmgr;
717 surf->info.width = width;
718 surf->info.height = height;
719 surf->info.format = format;
720 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
721 if (!surf->info.bpp) {
722 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
723 *error = tbm_get_last_error();
728 // get number of planes
729 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
730 if (!surf->info.num_planes) {
731 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
732 *error = tbm_get_last_error();
733 goto num_planes_fail;
736 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);
739 surf->hal_surface = hal_surface;
741 // set infomation of planes
742 for (i = 0; i < surf->info.num_planes; i++) {
743 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
744 if (*error != TBM_ERROR_NONE) {
745 goto query_plane_data_fail;
747 surf->info.planes[i].size = size;
748 surf->info.planes[i].offset = offset;
749 surf->info.planes[i].stride = stride;
750 surf->planes_bo_idx[i] = bo_idx;
753 // set infomation of bos
754 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
756 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
759 surf->num_bos = num_bos;
761 for (i = 0; i < surf->info.num_planes; i++) {
762 surf->info.size += surf->info.planes[i].size;
764 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
765 surf->num_bos = surf->planes_bo_idx[i] + 1;
768 for (i = 0; i < num_bos; i++) {
769 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
771 TBM_ERR("fail to alloc bo idx:%d", i);
772 *error = tbm_get_last_error();
776 _tbm_bo_set_surface(surf->bos[i], surf);
779 // set infomation of planes
780 for (i = 0; i < surf->info.num_planes; i++) {
781 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
782 TBM_ERR("fail to query plane data");
783 *error = tbm_get_last_error();
784 goto query_plane_data_fail;
786 surf->info.planes[i].size = size;
787 surf->info.planes[i].offset = offset;
788 surf->info.planes[i].stride = stride;
789 surf->planes_bo_idx[i] = bo_idx;
792 // count number of bos
794 for (i = 0; i < surf->info.num_planes; i++) {
795 surf->info.size += surf->info.planes[i].size;
797 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
798 surf->num_bos = surf->planes_bo_idx[i] + 1;
801 // set infomation of bos
802 for (i = 0; i < surf->num_bos; i++) {
804 for (j = 0; j < surf->info.num_planes; j++) {
805 if (surf->planes_bo_idx[j] == i)
806 bo_size += surf->info.planes[j].size;
809 surf->bos[i] = tbm_bufmgr_internal_alloc_bo_with_format(bufmgr, format, i, width, height, surf->info.bpp / 8, flags, error);
810 if (*error == TBM_ERROR_NOT_SUPPORTED) {
811 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
813 TBM_ERR("fail to alloc bo idx:%d", i);
814 *error = tbm_get_last_error();
819 _tbm_bo_set_surface(surf->bos[i], surf);
823 *error = TBM_ERROR_NONE;
829 query_plane_data_fail:
831 hal_tbm_surface_free(hal_surface);
833 for (j = 0; j < i; j++) {
835 tbm_bo_unref(surf->bos[j]);
847 static struct _tbm_surface *
848 _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)
850 struct _tbm_surface *surf = NULL;
851 uint32_t size = 0, offset = 0, stride = 0;
853 hal_tbm_surface *hal_surface = NULL;
854 hal_tbm_bo **hal_bos = NULL;
858 surf = calloc(1, sizeof(struct _tbm_surface));
860 /* LCOV_EXCL_START */
861 TBM_ERR("fail to alloc surf");
862 *error = TBM_ERROR_OUT_OF_MEMORY;
863 goto alloc_surf_fail;
868 surf->magic = TBM_SURFACE_MAGIC;
869 surf->bufmgr = bufmgr;
870 surf->info.width = width;
871 surf->info.height = height;
872 surf->info.format = format;
873 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
874 if (!surf->info.bpp) {
875 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
876 *error = tbm_get_last_error();
880 // get number of planes
881 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
882 if (!surf->info.num_planes) {
883 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
884 *error = tbm_get_last_error();
885 goto num_planes_fail;
889 hal_surface = hal_tbm_bufmgr_import_surface(bufmgr->hal_bufmgr,
892 (hal_tbm_format)format,
893 (hal_tbm_surface_buffer_data *)buffer_data,
894 (hal_tbm_error *)error);
896 TBM_ERR("hal_tbm_bufmgr_import_surface failed.(width:%d height:%d format:%d error:%s)",
897 width, height, format, tbm_error_str(*error));
898 goto import_surface_fail;
900 surf->hal_surface = hal_surface;
902 // set infomation of planes
903 for (i = 0; i < surf->info.num_planes; i++) {
904 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
905 if (*error != TBM_ERROR_NONE) {
906 goto query_plane_data_fail;
908 surf->info.planes[i].size = size;
909 surf->info.planes[i].offset = offset;
910 surf->info.planes[i].stride = stride;
911 surf->planes_bo_idx[i] = bo_idx;
914 // set infomation of bos
915 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
917 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
920 surf->num_bos = num_bos;
922 for (i = 0; i < surf->info.num_planes; i++) {
923 surf->info.size += surf->info.planes[i].size;
925 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
926 surf->num_bos = surf->planes_bo_idx[i] + 1;
929 // get memory_types(bo flags)
930 flags = (int)hal_tbm_bo_get_memory_types(hal_bos[0], (hal_tbm_error *)error);
931 if (*error != TBM_ERROR_NONE) {
932 TBM_ERR("hal_tbm_bo_get_memory_types failed.");
933 goto get_memory_types_fail;
937 for (i = 0; i < num_bos; i++) {
938 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
940 TBM_ERR("fail to alloc bo idx:%d", i);
941 *error = tbm_get_last_error();
945 _tbm_bo_set_surface(surf->bos[i], surf);
948 *error = TBM_ERROR_NONE;
953 get_memory_types_fail:
955 query_plane_data_fail:
957 hal_tbm_surface_free(hal_surface);
959 for (j = 0; j < i; j++) {
961 tbm_bo_unref(surf->bos[j]);
975 tbm_surface_internal_is_valid(tbm_surface_h surface)
979 _tbm_surface_mutex_lock();
980 _tbm_set_last_result(TBM_ERROR_NONE);
982 /* Return silently if surface is null. */
984 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
985 _tbm_surface_mutex_unlock();
989 ret = _tbm_surface_internal_is_valid(surface);
991 _tbm_surface_mutex_unlock();
997 tbm_surface_internal_query_supported_formats(uint32_t **formats,
1000 struct _tbm_bufmgr *bufmgr;
1001 bool bufmgr_initialized = false;
1004 _tbm_surface_mutex_lock();
1005 _tbm_set_last_result(TBM_ERROR_NONE);
1007 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
1008 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
1010 if (!g_surface_bufmgr) {
1011 _init_surface_bufmgr();
1012 if (!g_surface_bufmgr) {
1013 TBM_ERR("fail bufmgr initialization\n");
1014 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1017 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1018 bufmgr_initialized = true;
1021 bufmgr = g_surface_bufmgr;
1023 error = tbm_module_bufmgr_get_supported_formats(bufmgr->module, formats, num);
1024 if (error != TBM_ERROR_NONE) {
1025 _tbm_set_last_result(error);
1029 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
1031 if (bufmgr_initialized) {
1032 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1033 _deinit_surface_bufmgr();
1036 _tbm_surface_mutex_unlock();
1040 /* LCOV_EXCL_START */
1042 if (bufmgr_initialized) {
1043 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1044 _deinit_surface_bufmgr();
1046 _tbm_surface_mutex_unlock();
1048 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
1051 /* LCOV_EXCL_STOP */
1055 tbm_surface_internal_get_num_planes(tbm_format format)
1059 _tbm_surface_mutex_lock();
1060 _tbm_set_last_result(TBM_ERROR_NONE);
1062 num_planes = _tbm_surface_internal_get_num_planes(format);
1064 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1065 _tbm_surface_mutex_unlock();
1069 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
1071 _tbm_surface_mutex_unlock();
1077 tbm_surface_internal_get_bpp(tbm_format format)
1081 _tbm_surface_mutex_lock();
1082 _tbm_set_last_result(TBM_ERROR_NONE);
1084 bpp = _tbm_surface_internal_get_bpp(format);
1086 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1087 _tbm_surface_mutex_unlock();
1091 _tbm_surface_mutex_unlock();
1093 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
1099 tbm_surface_internal_create_with_flags(int width, int height,
1100 int format, int flags)
1102 struct _tbm_bufmgr *bufmgr;
1103 struct _tbm_surface *surf = NULL;
1104 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
1105 bool bufmgr_initialized = false;
1107 _tbm_surface_mutex_lock();
1108 _tbm_set_last_result(TBM_ERROR_NONE);
1110 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
1111 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
1113 if (!g_surface_bufmgr) {
1114 _init_surface_bufmgr();
1115 if (!g_surface_bufmgr) {
1116 TBM_ERR("fail bufmgr initialization\n");
1117 error = TBM_ERROR_INVALID_OPERATION;
1118 goto check_valid_fail;
1120 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1121 bufmgr_initialized = true;
1124 bufmgr = g_surface_bufmgr;
1125 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1126 TBM_ERR("The bufmgr is invalid\n");
1127 error = TBM_ERROR_INVALID_PARAMETER;
1128 goto check_valid_fail;
1131 if (bufmgr->use_hal_tbm) {
1132 surf = _tbm_surface_internal_hal_tbm_create_surface(bufmgr, width, height, format, flags, &error);
1134 TBM_ERR("_tbm_surface_internal_hal_tbm_create_surface failed.");
1135 goto surface_alloc_fail;
1138 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1140 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1141 goto surface_alloc_fail;
1145 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1146 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1148 LIST_INITHEAD(&surf->user_data_list);
1149 LIST_INITHEAD(&surf->debug_data_list);
1150 LIST_INITHEAD(&surf->destroy_funcs);
1152 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1154 _tbm_set_last_result(error);
1155 _tbm_surface_mutex_unlock();
1159 /* LCOV_EXCL_START */
1163 if (bufmgr_initialized && bufmgr) {
1164 LIST_DELINIT(&bufmgr->surf_list);
1165 _deinit_surface_bufmgr();
1168 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1169 width, height, _tbm_surface_internal_format_to_str(format), flags);
1171 _tbm_set_last_result(error);
1172 _tbm_surface_mutex_unlock();
1174 /* LCOV_EXCL_STOP */
1180 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1181 tbm_bo *bos, int num)
1183 struct _tbm_bufmgr *bufmgr;
1184 struct _tbm_surface *surf = NULL;
1186 bool bufmgr_initialized = false;
1188 _tbm_surface_mutex_lock();
1189 _tbm_set_last_result(TBM_ERROR_NONE);
1191 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1192 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1193 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1194 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1195 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1197 if (!g_surface_bufmgr) {
1198 _init_surface_bufmgr();
1199 if (!g_surface_bufmgr) {
1200 TBM_ERR("fail bufmgr initialization\n");
1201 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1202 goto check_valid_fail;
1204 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1205 bufmgr_initialized = true;
1208 bufmgr = g_surface_bufmgr;
1209 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1210 TBM_ERR("fail to validate the Bufmgr.\n");
1211 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1212 goto check_valid_fail;
1215 surf = calloc(1, sizeof(struct _tbm_surface));
1217 /* LCOV_EXCL_START */
1218 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1219 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1220 goto alloc_surf_fail;
1221 /* LCOV_EXCL_STOP */
1224 surf->magic = TBM_SURFACE_MAGIC;
1225 surf->bufmgr = bufmgr;
1226 surf->info.width = info->width;
1227 surf->info.height = info->height;
1228 surf->info.format = info->format;
1230 surf->info.bpp = info->bpp;
1232 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1233 if (!surf->info.bpp) {
1234 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1238 surf->info.num_planes = info->num_planes;
1241 /* get size, stride and offset */
1242 for (i = 0; i < info->num_planes; i++) {
1243 surf->info.planes[i].offset = info->planes[i].offset;
1244 surf->info.planes[i].stride = info->planes[i].stride;
1246 if (info->planes[i].size > 0)
1247 surf->info.planes[i].size = info->planes[i].size;
1249 uint32_t size = 0, offset = 0, stride = 0;
1252 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1253 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1254 goto plane_data_fail;
1256 surf->info.planes[i].size = size;
1260 surf->planes_bo_idx[i] = 0;
1262 surf->planes_bo_idx[i] = i;
1265 if (info->size > 0) {
1266 surf->info.size = info->size;
1268 surf->info.size = 0;
1269 for (i = 0; i < info->num_planes; i++)
1270 surf->info.size += surf->info.planes[i].size;
1273 surf->flags = TBM_BO_DEFAULT;
1275 /* create only one bo */
1276 surf->num_bos = num;
1277 for (i = 0; i < num; i++) {
1278 if (bos[i] == NULL) {
1279 TBM_ERR("bos[%d] is null.\n", i);
1280 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1284 surf->bos[i] = tbm_bo_ref(bos[i]);
1285 _tbm_bo_set_surface(bos[i], surf);
1288 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1289 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1291 LIST_INITHEAD(&surf->user_data_list);
1292 LIST_INITHEAD(&surf->debug_data_list);
1293 LIST_INITHEAD(&surf->destroy_funcs);
1295 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1297 _tbm_surface_mutex_unlock();
1301 /* LCOV_EXCL_START */
1305 for (i = 0; i < num; i++) {
1307 tbm_bo_unref(surf->bos[i]);
1312 if (bufmgr_initialized && bufmgr) {
1313 LIST_DELINIT(&bufmgr->surf_list);
1314 _deinit_surface_bufmgr();
1316 _tbm_surface_mutex_unlock();
1318 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1319 info->width, info->height,
1320 _tbm_surface_internal_format_to_str(info->format), num);
1321 /* LCOV_EXCL_STOP */
1327 tbm_surface_internal_destroy(tbm_surface_h surface)
1329 _tbm_surface_mutex_lock();
1330 _tbm_set_last_result(TBM_ERROR_NONE);
1332 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1336 if (surface->refcnt > 0) {
1337 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1338 _tbm_surface_mutex_unlock();
1342 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1344 if (surface->refcnt == 0)
1345 _tbm_surface_internal_destroy(surface);
1346 else // if (surface->refcnt < 0)
1347 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1349 _tbm_surface_mutex_unlock();
1353 tbm_surface_internal_ref(tbm_surface_h surface)
1355 _tbm_surface_mutex_lock();
1356 _tbm_set_last_result(TBM_ERROR_NONE);
1358 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1362 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1364 _tbm_surface_mutex_unlock();
1368 tbm_surface_internal_unref(tbm_surface_h surface)
1370 _tbm_surface_mutex_lock();
1371 _tbm_set_last_result(TBM_ERROR_NONE);
1373 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1377 if (surface->refcnt > 0) {
1378 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1379 _tbm_surface_mutex_unlock();
1383 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1385 if (surface->refcnt == 0)
1386 _tbm_surface_internal_destroy(surface);
1388 _tbm_surface_mutex_unlock();
1392 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1394 struct _tbm_surface *surf;
1397 _tbm_surface_mutex_lock();
1398 _tbm_set_last_result(TBM_ERROR_NONE);
1400 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1402 surf = (struct _tbm_surface *)surface;
1403 num = surf->num_bos;
1406 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1408 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1410 _tbm_surface_mutex_unlock();
1416 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1418 struct _tbm_surface *surf;
1421 _tbm_surface_mutex_lock();
1422 _tbm_set_last_result(TBM_ERROR_NONE);
1424 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1425 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1427 surf = (struct _tbm_surface *)surface;
1428 bo = surf->bos[bo_idx];
1430 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1432 _tbm_surface_mutex_unlock();
1438 tbm_surface_internal_get_size(tbm_surface_h surface)
1440 struct _tbm_surface *surf;
1443 _tbm_surface_mutex_lock();
1444 _tbm_set_last_result(TBM_ERROR_NONE);
1446 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1448 surf = (struct _tbm_surface *)surface;
1449 size = surf->info.size;
1451 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1453 _tbm_surface_mutex_unlock();
1459 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1460 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1462 struct _tbm_surface *surf;
1464 _tbm_surface_mutex_lock();
1465 _tbm_set_last_result(TBM_ERROR_NONE);
1467 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1468 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1470 surf = (struct _tbm_surface *)surface;
1472 if (plane_idx >= surf->info.num_planes) {
1473 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1474 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1475 _tbm_surface_mutex_unlock();
1480 *size = surf->info.planes[plane_idx].size;
1483 *offset = surf->info.planes[plane_idx].offset;
1486 *pitch = surf->info.planes[plane_idx].stride;
1488 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1489 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1490 surf->info.planes[plane_idx].stride);
1492 _tbm_surface_mutex_unlock();
1498 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1499 tbm_surface_info_s *info, int map)
1501 struct _tbm_surface *surf;
1502 tbm_bo_handle bo_handles[4];
1505 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1508 _tbm_surface_mutex_lock();
1509 _tbm_set_last_result(TBM_ERROR_NONE);
1511 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1513 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1515 surf = (struct _tbm_surface *)surface;
1517 memset(info, 0x00, sizeof(tbm_surface_info_s));
1518 info->width = surf->info.width;
1519 info->height = surf->info.height;
1520 info->format = surf->info.format;
1521 info->bpp = surf->info.bpp;
1522 info->size = surf->info.size;
1523 info->num_planes = surf->info.num_planes;
1525 for (i = 0; i < surf->info.num_planes; i++) {
1526 info->planes[i].size = surf->info.planes[i].size;
1527 info->planes[i].offset = surf->info.planes[i].offset;
1528 info->planes[i].stride = surf->info.planes[i].stride;
1529 planes_bo_idx[i] = surf->planes_bo_idx[i];
1532 for (i = 0; i < surf->num_bos; i++)
1533 bos[i] = surf->bos[i];
1535 num_bos = surf->num_bos;
1538 _tbm_surface_mutex_unlock();
1539 for (i = 0; i < num_bos; i++) {
1540 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1541 if (bo_handles[i].ptr == NULL) {
1542 for (j = 0; j < i; j++)
1543 tbm_bo_unmap(bos[j]);
1545 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1549 _tbm_surface_mutex_lock();
1551 for (i = 0; i < num_bos; i++) {
1552 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1553 if (bo_handles[i].ptr == NULL) {
1554 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1555 _tbm_surface_mutex_unlock();
1561 for (i = 0; i < info->num_planes; i++) {
1562 if (bo_handles[planes_bo_idx[i]].ptr)
1563 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1566 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1568 _tbm_surface_mutex_unlock();
1574 tbm_surface_internal_unmap(tbm_surface_h surface)
1576 struct _tbm_surface *surf;
1579 _tbm_surface_mutex_lock();
1580 _tbm_set_last_result(TBM_ERROR_NONE);
1582 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1584 surf = (struct _tbm_surface *)surface;
1586 for (i = 0; i < surf->num_bos; i++)
1587 tbm_bo_unmap(surf->bos[i]);
1589 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1591 _tbm_surface_mutex_unlock();
1595 tbm_surface_internal_get_width(tbm_surface_h surface)
1597 struct _tbm_surface *surf;
1600 _tbm_surface_mutex_lock();
1601 _tbm_set_last_result(TBM_ERROR_NONE);
1603 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1605 surf = (struct _tbm_surface *)surface;
1606 width = surf->info.width;
1608 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1610 _tbm_surface_mutex_unlock();
1616 tbm_surface_internal_get_height(tbm_surface_h surface)
1618 struct _tbm_surface *surf;
1619 unsigned int height;
1621 _tbm_surface_mutex_lock();
1622 _tbm_set_last_result(TBM_ERROR_NONE);
1624 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1626 surf = (struct _tbm_surface *)surface;
1627 height = surf->info.height;
1629 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1631 _tbm_surface_mutex_unlock();
1638 tbm_surface_internal_get_format(tbm_surface_h surface)
1640 struct _tbm_surface *surf;
1643 _tbm_surface_mutex_lock();
1644 _tbm_set_last_result(TBM_ERROR_NONE);
1646 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1648 surf = (struct _tbm_surface *)surface;
1649 format = surf->info.format;
1651 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1653 _tbm_surface_mutex_unlock();
1659 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1661 struct _tbm_surface *surf;
1664 _tbm_surface_mutex_lock();
1665 _tbm_set_last_result(TBM_ERROR_NONE);
1667 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1668 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1670 surf = (struct _tbm_surface *)surface;
1671 bo_idx = surf->planes_bo_idx[plane_idx];
1673 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1675 _tbm_surface_mutex_unlock();
1681 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1682 tbm_data_free data_free_func)
1684 tbm_user_data *data;
1686 _tbm_surface_mutex_lock();
1687 _tbm_set_last_result(TBM_ERROR_NONE);
1689 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1691 /* check if the data according to the key exist if so, return false. */
1692 data = user_data_lookup(&surface->user_data_list, key);
1694 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1695 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1696 _tbm_surface_mutex_unlock();
1700 data = user_data_create(key, data_free_func);
1702 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1703 _tbm_surface_mutex_unlock();
1707 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1709 LIST_ADD(&data->item_link, &surface->user_data_list);
1711 _tbm_surface_mutex_unlock();
1717 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1720 tbm_user_data *old_data;
1722 _tbm_surface_mutex_lock();
1723 _tbm_set_last_result(TBM_ERROR_NONE);
1725 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1727 old_data = user_data_lookup(&surface->user_data_list, key);
1729 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1730 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1731 _tbm_surface_mutex_unlock();
1735 if (old_data->data && old_data->free_func)
1736 old_data->free_func(old_data->data);
1738 old_data->data = data;
1740 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1742 _tbm_surface_mutex_unlock();
1748 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1751 tbm_user_data *old_data;
1753 _tbm_surface_mutex_lock();
1754 _tbm_set_last_result(TBM_ERROR_NONE);
1756 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1759 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1760 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1761 _tbm_surface_mutex_unlock();
1766 old_data = user_data_lookup(&surface->user_data_list, key);
1768 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1769 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1770 _tbm_surface_mutex_unlock();
1774 *data = old_data->data;
1776 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1778 _tbm_surface_mutex_unlock();
1784 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1787 tbm_user_data *old_data = (void *)0;
1789 _tbm_surface_mutex_lock();
1790 _tbm_set_last_result(TBM_ERROR_NONE);
1792 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1794 old_data = user_data_lookup(&surface->user_data_list, key);
1796 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1797 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1798 _tbm_surface_mutex_unlock();
1802 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1804 user_data_delete(old_data);
1806 _tbm_surface_mutex_unlock();
1811 /* LCOV_EXCL_START */
1813 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1815 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1817 return surface->debug_pid;
1821 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1823 _tbm_surface_mutex_lock();
1824 _tbm_set_last_result(TBM_ERROR_NONE);
1826 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1828 surface->debug_pid = pid;
1830 _tbm_surface_mutex_unlock();
1833 static tbm_surface_debug_data *
1834 _tbm_surface_internal_debug_data_create(char *key, char *value)
1836 tbm_surface_debug_data *debug_data = NULL;
1838 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1840 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1841 TBM_ERR("fail to allocate the debug_data.");
1845 if (key) debug_data->key = strdup(key);
1846 if (value) debug_data->value = strdup(value);
1852 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1854 if (!debug_data->value && !value)
1857 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1860 if (debug_data->value)
1861 free(debug_data->value);
1864 debug_data->value = strdup(value);
1866 debug_data->value = NULL;
1869 static tbm_surface_debug_data *
1870 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1872 tbm_surface_debug_data *debug_data = NULL;
1874 if (LIST_IS_EMPTY(list))
1877 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1878 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1886 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1888 tbm_surface_debug_data *debug_data = NULL;
1889 tbm_bufmgr bufmgr = NULL;
1891 _tbm_surface_mutex_lock();
1892 _tbm_set_last_result(TBM_ERROR_NONE);
1894 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1895 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1897 bufmgr = surface->bufmgr;
1899 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1901 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1903 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1905 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1907 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1908 _tbm_surface_mutex_unlock();
1912 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1915 /* add new debug key to list */
1916 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1918 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1920 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1923 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1925 _tbm_surface_mutex_unlock();
1931 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1933 tbm_surface_debug_data *old_data = NULL;
1935 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1937 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1938 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1939 if (!strcmp(old_data->key, key))
1940 return old_data->value;
1947 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1948 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1950 struct _tbm_surface_dump_buf_info {
1960 tbm_surface_info_s info;
1962 struct list_head link;
1965 struct _tbm_surface_dump_info {
1966 char *path; // copy???
1969 struct list_head *link;
1970 struct list_head surface_list; /* link of surface */
1973 static tbm_surface_dump_info *g_dump_info = NULL;
1974 static const char *dump_postfix[2] = {"png", "yuv"};
1975 static double scale_factor;
1978 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1979 void *data2, int size2, void *data3, int size3)
1982 unsigned int *blocks;
1984 if (_tbm_surface_check_file_is_symbolic_link(file))
1985 TBM_ERR("%s is symbolic link\n", file);
1987 fp = fopen(file, "w+");
1988 TBM_RETURN_IF_FAIL(fp != NULL);
1990 blocks = (unsigned int *)data1;
1991 fwrite(blocks, 1, size1, fp);
1994 blocks = (unsigned int *)data2;
1995 fwrite(blocks, 1, size2, fp);
1999 blocks = (unsigned int *)data3;
2000 fwrite(blocks, 1, size3, fp);
2007 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
2009 unsigned int *blocks = (unsigned int *)data;
2012 png_bytep *row_pointers;
2015 if (_tbm_surface_check_file_is_symbolic_link(file))
2016 TBM_ERR("%s is symbolic link\n", file);
2018 fp = fopen(file, "wb");
2019 TBM_RETURN_IF_FAIL(fp != NULL);
2021 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
2024 TBM_ERR("fail to create a png write structure.\n");
2029 png_infop pPngInfo = png_create_info_struct(pPngStruct);
2031 TBM_ERR("fail to create a png info structure.\n");
2032 png_destroy_write_struct(&pPngStruct, NULL);
2037 if (setjmp(png_jmpbuf(pPngStruct))) {
2038 /* if png has problem of writing the file, we get here */
2039 TBM_ERR("fail to write png file.\n");
2040 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2045 png_init_io(pPngStruct, fp);
2046 if (format == TBM_FORMAT_XRGB8888) {
2048 png_set_IHDR(pPngStruct,
2055 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2058 png_set_IHDR(pPngStruct,
2063 PNG_COLOR_TYPE_RGBA,
2065 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2068 png_set_bgr(pPngStruct);
2069 png_write_info(pPngStruct, pPngInfo);
2071 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
2072 if (!row_pointers) {
2073 TBM_ERR("fail to allocate the png row_pointers.\n");
2074 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2079 for (y = 0; y < height; ++y) {
2083 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
2085 TBM_ERR("fail to allocate the png row.\n");
2086 for (x = 0; x < y; x++)
2087 png_free(pPngStruct, row_pointers[x]);
2088 png_free(pPngStruct, row_pointers);
2089 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2093 row_pointers[y] = (png_bytep)row;
2095 for (x = 0; x < width; ++x) {
2096 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
2098 if (pixel_size == 3) { // XRGB8888
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 } else { // ARGB8888
2103 row[x * pixel_size] = (curBlock & 0xFF);
2104 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2105 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2106 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2111 png_write_image(pPngStruct, row_pointers);
2112 png_write_end(pPngStruct, pPngInfo);
2114 for (y = 0; y < height; y++)
2115 png_free(pPngStruct, row_pointers[y]);
2116 png_free(pPngStruct, row_pointers);
2118 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2124 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2126 TBM_RETURN_IF_FAIL(path != NULL);
2127 TBM_RETURN_IF_FAIL(w > 0);
2128 TBM_RETURN_IF_FAIL(h > 0);
2129 TBM_RETURN_IF_FAIL(count > 0);
2131 tbm_surface_dump_buf_info *buf_info = NULL;
2132 tbm_surface_h tbm_surface;
2133 tbm_surface_info_s info;
2138 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2142 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2143 TBM_RETURN_IF_FAIL(g_dump_info);
2145 LIST_INITHEAD(&g_dump_info->surface_list);
2146 g_dump_info->count = 0;
2147 g_dump_info->dump_max = count;
2149 /* get buffer size */
2150 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2151 if (tbm_surface == NULL) {
2152 TBM_ERR("tbm_surface_create fail\n");
2158 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2159 TBM_ERR("tbm_surface_get_info fail\n");
2160 tbm_surface_destroy(tbm_surface);
2165 buffer_size = info.size;
2166 tbm_surface_destroy(tbm_surface);
2168 /* create dump lists */
2169 for (i = 0; i < count; i++) {
2172 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2173 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2175 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2177 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2182 buf_info->index = i;
2184 buf_info->size = buffer_size;
2186 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2189 g_dump_info->path = path;
2190 g_dump_info->link = &g_dump_info->surface_list;
2194 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2199 /* free resources */
2200 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2201 tbm_surface_dump_buf_info *tmp;
2203 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2204 tbm_bo_unref(buf_info->bo);
2205 LIST_DEL(&buf_info->link);
2210 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2219 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2226 tbm_surface_internal_dump_start(path, w, h, count);
2227 scale_factor = scale;
2231 tbm_surface_internal_dump_end(void)
2233 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2234 tbm_bo_handle bo_handle;
2239 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2246 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2249 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2250 if (bo_handle.ptr == NULL) {
2251 tbm_bo_unref(buf_info->bo);
2252 LIST_DEL(&buf_info->link);
2257 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2258 TBM_INFO("Dump File.. %s generated.\n", file);
2260 if (buf_info->dirty) {
2261 void *ptr1 = NULL, *ptr2 = NULL;
2263 switch (buf_info->info.format) {
2264 case TBM_FORMAT_ARGB8888:
2265 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2266 buf_info->info.planes[0].stride >> 2,
2267 buf_info->info.height,
2268 buf_info->info.planes[0].stride,
2269 TBM_FORMAT_ARGB8888);
2271 case TBM_FORMAT_XRGB8888:
2272 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2273 buf_info->info.planes[0].stride >> 2,
2274 buf_info->info.height,
2275 buf_info->info.planes[0].stride,
2276 TBM_FORMAT_XRGB8888);
2278 case TBM_FORMAT_YVU420:
2279 case TBM_FORMAT_YUV420:
2280 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2281 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2282 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2283 buf_info->info.planes[0].stride * buf_info->info.height,
2285 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2287 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2289 case TBM_FORMAT_NV12:
2290 case TBM_FORMAT_NV21:
2291 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2292 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2293 buf_info->info.planes[0].stride * buf_info->info.height,
2295 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2298 case TBM_FORMAT_YUYV:
2299 case TBM_FORMAT_UYVY:
2300 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2301 buf_info->info.planes[0].stride * buf_info->info.height,
2305 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2308 } else if (buf_info->dirty_shm)
2309 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2310 buf_info->shm_stride >> 2,
2312 buf_info->shm_stride, 0);
2314 tbm_bo_unmap(buf_info->bo);
2315 tbm_bo_unref(buf_info->bo);
2316 LIST_DEL(&buf_info->link);
2323 TBM_INFO("Dump End..\n");
2326 static pixman_format_code_t
2327 _tbm_surface_internal_pixman_format_get(tbm_format format)
2330 case TBM_FORMAT_ARGB8888:
2331 return PIXMAN_a8r8g8b8;
2332 case TBM_FORMAT_XRGB8888:
2333 return PIXMAN_x8r8g8b8;
2342 * This function supports only if a buffer has below formats.
2343 * - TBM_FORMAT_ARGB8888
2344 * - TBM_FORMAT_XRGB8888
2346 static tbm_surface_error_e
2347 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2348 int format, int src_stride, int src_w, int src_h,
2349 int dst_stride, int dst_w, int dst_h)
2351 pixman_image_t *src_img = NULL, *dst_img = NULL;
2352 pixman_format_code_t pixman_format;
2353 pixman_transform_t t;
2354 struct pixman_f_transform ft;
2355 double scale_x, scale_y;
2357 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2358 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2360 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2361 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2364 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2365 (uint32_t*)src_ptr, src_stride);
2366 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2369 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2370 (uint32_t*)dst_ptr, dst_stride);
2371 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2373 pixman_f_transform_init_identity(&ft);
2375 scale_x = (double)src_w / dst_w;
2376 scale_y = (double)src_h / dst_h;
2378 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2379 pixman_f_transform_translate(&ft, NULL, 0, 0);
2380 pixman_transform_from_pixman_f_transform(&t, &ft);
2381 pixman_image_set_transform(src_img, &t);
2383 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2384 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2386 pixman_image_unref(src_img);
2387 pixman_image_unref(dst_img);
2389 return TBM_SURFACE_ERROR_NONE;
2393 pixman_image_unref(src_img);
2395 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2398 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2399 #define KEY_LEN 5 // "_XXXX"
2400 #define KEYS_LEN KEY_LEN * MAX_BOS
2402 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2404 char *keys, temp_key[KEY_LEN + 1];
2405 struct _tbm_surface *surf;
2409 _tbm_surface_mutex_lock();
2411 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2413 surf = (struct _tbm_surface *)surface;
2415 num_bos = surf->num_bos;
2416 if (num_bos > MAX_BOS)
2419 keys = calloc(KEYS_LEN + 1, sizeof(char));
2421 TBM_ERR("Failed to alloc memory");
2422 _tbm_surface_mutex_unlock();
2426 for (i = 0; i < num_bos; i++) {
2427 memset(temp_key, 0x00, KEY_LEN + 1);
2429 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2430 strncat(keys, temp_key, KEY_LEN + 1);
2433 _tbm_surface_mutex_unlock();
2438 static void _tbm_surface_internal_put_keys(char *keys)
2445 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2447 TBM_RETURN_IF_FAIL(surface != NULL);
2448 TBM_RETURN_IF_FAIL(type != NULL);
2450 tbm_surface_dump_buf_info *buf_info;
2451 struct list_head *next_link;
2452 tbm_surface_info_s info;
2453 tbm_bo_handle bo_handle;
2454 const char *postfix;
2455 const char *format = NULL;
2462 next_link = g_dump_info->link->next;
2463 TBM_RETURN_IF_FAIL(next_link != NULL);
2465 if (next_link == &g_dump_info->surface_list) {
2466 next_link = next_link->next;
2467 TBM_RETURN_IF_FAIL(next_link != NULL);
2470 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2471 TBM_RETURN_IF_FAIL(buf_info != NULL);
2473 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2474 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2476 if (scale_factor > 0.0) {
2479 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2480 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2481 _tbm_surface_internal_format_to_str(info.format));
2482 tbm_surface_unmap(surface);
2486 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2488 buf_info->info.width = info.width * scale_factor;
2489 buf_info->info.height = info.height * scale_factor;
2490 buf_info->info.format = info.format;
2491 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2492 if (!buf_info->info.bpp) {
2493 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2494 tbm_surface_unmap(surface);
2497 buf_info->info.num_planes = 1;
2498 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2499 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2501 if (buf_info->info.size > buf_info->size) {
2502 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2503 buf_info->info.size, buf_info->size);
2504 tbm_surface_unmap(surface);
2508 if (info.size > buf_info->size) {
2509 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2510 info.size, buf_info->size);
2511 tbm_surface_unmap(surface);
2515 /* make the file information */
2516 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2519 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2520 postfix = dump_postfix[0];
2521 format = _tbm_surface_internal_format_to_str(info.format);
2523 postfix = dump_postfix[1];
2525 keys = _tbm_surface_internal_get_keys(surface);
2527 TBM_ERR("fail to get keys");
2528 tbm_surface_unmap(surface);
2533 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2534 if (!bo_handle.ptr) {
2535 TBM_ERR("fail to map bo");
2536 _tbm_surface_internal_put_keys(keys);
2537 tbm_surface_unmap(surface);
2540 memset(bo_handle.ptr, 0x00, buf_info->size);
2542 switch (info.format) {
2543 case TBM_FORMAT_ARGB8888:
2544 case TBM_FORMAT_XRGB8888:
2545 snprintf(buf_info->name, sizeof(buf_info->name),
2546 "%10.3f_%03d%s_%p_%s-%s.%s",
2547 _tbm_surface_internal_get_time(),
2548 g_dump_info->count++, keys, surface, format, type, postfix);
2550 if (scale_factor > 0.0) {
2551 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2553 buf_info->info.format,
2554 info.planes[0].stride,
2555 info.width, info.height,
2556 buf_info->info.planes[0].stride,
2557 buf_info->info.width,
2558 buf_info->info.height);
2559 if (ret != TBM_SURFACE_ERROR_NONE) {
2560 TBM_ERR("fail to scale buffer");
2561 tbm_bo_unmap(buf_info->bo);
2562 _tbm_surface_internal_put_keys(keys);
2563 tbm_surface_unmap(surface);
2567 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2569 case TBM_FORMAT_YVU420:
2570 case TBM_FORMAT_YUV420:
2571 snprintf(buf_info->name, sizeof(buf_info->name),
2572 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2573 _tbm_surface_internal_get_time(),
2574 g_dump_info->count++, keys, type, info.planes[0].stride,
2575 info.height, FOURCC_STR(info.format), postfix);
2576 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2577 bo_handle.ptr += info.planes[0].stride * info.height;
2578 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2579 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2580 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2582 case TBM_FORMAT_NV12:
2583 case TBM_FORMAT_NV21:
2584 snprintf(buf_info->name, sizeof(buf_info->name),
2585 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2586 _tbm_surface_internal_get_time(),
2587 g_dump_info->count++, keys, type, info.planes[0].stride,
2588 info.height, FOURCC_STR(info.format), postfix);
2589 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2590 bo_handle.ptr += info.planes[0].stride * info.height;
2591 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2593 case TBM_FORMAT_YUYV:
2594 case TBM_FORMAT_UYVY:
2595 snprintf(buf_info->name, sizeof(buf_info->name),
2596 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2597 _tbm_surface_internal_get_time(),
2598 g_dump_info->count++, keys, type, info.planes[0].stride,
2599 info.height, FOURCC_STR(info.format), postfix);
2600 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2603 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2604 tbm_bo_unmap(buf_info->bo);
2605 _tbm_surface_internal_put_keys(keys);
2606 tbm_surface_unmap(surface);
2610 tbm_bo_unmap(buf_info->bo);
2612 _tbm_surface_internal_put_keys(keys);
2614 tbm_surface_unmap(surface);
2616 buf_info->dirty = 1;
2617 buf_info->dirty_shm = 0;
2619 if (g_dump_info->count == 1000)
2620 g_dump_info->count = 0;
2622 g_dump_info->link = next_link;
2624 TBM_INFO("Dump %s \n", buf_info->name);
2627 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2630 TBM_RETURN_IF_FAIL(ptr != NULL);
2631 TBM_RETURN_IF_FAIL(w > 0);
2632 TBM_RETURN_IF_FAIL(h > 0);
2633 TBM_RETURN_IF_FAIL(stride > 0);
2634 TBM_RETURN_IF_FAIL(type != NULL);
2636 tbm_surface_dump_buf_info *buf_info;
2637 struct list_head *next_link;
2638 tbm_bo_handle bo_handle;
2639 int ret, size, dw = 0, dh = 0, dstride = 0;
2644 next_link = g_dump_info->link->next;
2645 TBM_RETURN_IF_FAIL(next_link != NULL);
2647 if (next_link == &g_dump_info->surface_list) {
2648 next_link = next_link->next;
2649 TBM_RETURN_IF_FAIL(next_link != NULL);
2652 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2653 TBM_RETURN_IF_FAIL(buf_info != NULL);
2655 if (scale_factor > 0.0) {
2658 dw = w * scale_factor;
2659 dh = h * scale_factor;
2661 size = dstride * dh;
2665 if (size > buf_info->size) {
2666 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2667 size, buf_info->size);
2672 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2673 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2675 memset(bo_handle.ptr, 0x00, buf_info->size);
2676 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2678 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2679 _tbm_surface_internal_get_time(),
2680 g_dump_info->count++, type, dump_postfix[0]);
2681 if (scale_factor > 0.0) {
2682 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2683 TBM_FORMAT_ARGB8888, stride,
2684 w, h, dstride, dw, dh);
2685 if (ret != TBM_SURFACE_ERROR_NONE) {
2686 TBM_ERR("fail to scale buffer");
2687 tbm_bo_unmap(buf_info->bo);
2690 buf_info->shm_stride = dstride;
2691 buf_info->shm_h = dh;
2693 memcpy(bo_handle.ptr, ptr, size);
2694 buf_info->shm_stride = stride;
2695 buf_info->shm_h = h;
2698 tbm_bo_unmap(buf_info->bo);
2700 buf_info->dirty = 0;
2701 buf_info->dirty_shm = 1;
2703 if (g_dump_info->count == 1000)
2704 g_dump_info->count = 0;
2706 g_dump_info->link = next_link;
2708 TBM_INFO("Dump %s \n", buf_info->name);
2712 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2714 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2715 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2716 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2718 tbm_surface_info_s info;
2719 const char *postfix;
2723 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2724 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2726 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2727 postfix = dump_postfix[0];
2729 postfix = dump_postfix[1];
2731 if (strcmp(postfix, type)) {
2732 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2733 tbm_surface_unmap(surface);
2737 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2739 if (!access(file, 0)) {
2740 TBM_ERR("can't capture buffer, exist file %s", file);
2741 tbm_surface_unmap(surface);
2745 switch (info.format) {
2746 case TBM_FORMAT_ARGB8888:
2747 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2750 info.planes[0].stride,
2751 TBM_FORMAT_ARGB8888);
2753 case TBM_FORMAT_XRGB8888:
2754 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2757 info.planes[0].stride,
2758 TBM_FORMAT_XRGB8888);
2760 case TBM_FORMAT_YVU420:
2761 case TBM_FORMAT_YUV420:
2762 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2763 info.planes[0].stride * info.height,
2765 info.planes[1].stride * (info.height >> 1),
2767 info.planes[2].stride * (info.height >> 1));
2769 case TBM_FORMAT_NV12:
2770 case TBM_FORMAT_NV21:
2771 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2772 info.planes[0].stride * info.height,
2774 info.planes[1].stride * (info.height >> 1),
2777 case TBM_FORMAT_YUYV:
2778 case TBM_FORMAT_UYVY:
2779 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2780 info.planes[0].stride * info.height,
2784 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2785 tbm_surface_unmap(surface);
2789 tbm_surface_unmap(surface);
2791 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2797 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2798 const char *path, const char *name, const char *type)
2800 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2801 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2802 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2803 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2804 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2805 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2809 if (strcmp(dump_postfix[0], type)) {
2810 TBM_ERR("Not supported type:%s'", type);
2814 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2816 if (!access(file, 0)) {
2817 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2821 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2823 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2829 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2831 struct _tbm_surface *surf;
2833 _tbm_surface_mutex_lock();
2834 _tbm_set_last_result(TBM_ERROR_NONE);
2836 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2837 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2838 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2840 surf = (struct _tbm_surface *)surface;
2844 surf->damage.width = width;
2845 surf->damage.height = height;
2847 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2848 surface, x, y, width, height);
2850 _tbm_surface_mutex_unlock();
2856 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2858 struct _tbm_surface *surf;
2860 _tbm_surface_mutex_lock();
2861 _tbm_set_last_result(TBM_ERROR_NONE);
2863 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2865 surf = (struct _tbm_surface *)surface;
2867 if (x) *x = surf->damage.x;
2868 if (y) *y = surf->damage.y;
2869 if (width) *width = surf->damage.width;
2870 if (height) *height = surf->damage.height;
2872 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2873 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2875 _tbm_surface_mutex_unlock();
2881 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2883 struct _tbm_surface *surf;
2884 tbm_surface_destroy_func_info *func_info = NULL;
2886 _tbm_surface_mutex_lock();
2887 _tbm_set_last_result(TBM_ERROR_NONE);
2889 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2890 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2892 surf = (struct _tbm_surface *)surface;
2893 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2894 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2895 TBM_ERR("can't add twice");
2896 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2897 _tbm_surface_mutex_unlock();
2902 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2903 if (func_info == NULL) {
2904 TBM_ERR("alloc failed");
2905 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2906 _tbm_surface_mutex_unlock();
2910 func_info->destroy_func = func;
2911 func_info->user_data = user_data;
2913 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2915 _tbm_surface_mutex_unlock();
2921 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2923 struct _tbm_surface *surf;
2924 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
2926 _tbm_surface_mutex_lock();
2927 _tbm_set_last_result(TBM_ERROR_NONE);
2929 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
2930 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
2932 surf = (struct _tbm_surface *)surface;
2933 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
2934 if (func_info->destroy_func != func || func_info->user_data != user_data)
2937 LIST_DEL(&func_info->item_link);
2940 _tbm_surface_mutex_unlock();
2945 _tbm_surface_mutex_unlock();
2948 tbm_surface_buffer_data *
2949 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
2951 tbm_surface_buffer_data *buffer_data = NULL;
2952 struct _tbm_surface *surf;
2953 struct _tbm_bufmgr *bufmgr;
2955 _tbm_surface_mutex_lock();
2957 surf = (struct _tbm_surface *)surface;
2958 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
2960 bufmgr = surf->bufmgr;
2961 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
2963 // this function supports when it comes to be use_hal.
2964 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
2967 buffer_data = (tbm_surface_buffer_data *)hal_tbm_surface_export((hal_tbm_surface *)surf->hal_surface,
2968 (hal_tbm_error *)error);
2969 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
2971 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
2974 *error = TBM_ERROR_NONE;
2976 _tbm_set_last_result(TBM_ERROR_NONE);
2977 _tbm_surface_mutex_unlock();
2983 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
2985 struct _tbm_surface *surf;
2986 struct _tbm_bufmgr *bufmgr;
2988 _tbm_surface_mutex_lock();
2990 bufmgr = g_surface_bufmgr;
2991 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
2993 // this function supports when it comes to be use_hal.
2994 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
2996 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
2997 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
2998 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
2999 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3002 surf = _tbm_surface_internal_hal_tbm_import_surface(bufmgr,
3003 (int)surface_info->width,
3004 (int)surface_info->height,
3005 (int)surface_info->format,
3008 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
3010 LIST_INITHEAD(&surf->user_data_list);
3011 LIST_INITHEAD(&surf->debug_data_list);
3012 LIST_INITHEAD(&surf->destroy_funcs);
3014 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
3016 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
3019 *error = TBM_ERROR_NONE;
3021 _tbm_set_last_result(TBM_ERROR_NONE);
3022 _tbm_surface_mutex_unlock();
3024 return (tbm_surface_h)surf;