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;
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 if (bufmgr->use_hal_tbm) {
332 error = (tbm_error_e)hal_tbm_bufmgr_get_plane_data(bufmgr->hal_bufmgr, (hal_tbm_format)surf->info.format,
333 plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
334 /* LCOV_EXCL_START */
335 if (error == TBM_ERROR_NOT_SUPPORTED) {
336 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
338 } else if (error != TBM_ERROR_NONE) {
339 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
340 _tbm_set_last_result(error);
345 } else if (bufmgr->backend_module_data) {
346 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
347 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
351 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
352 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
353 if (error != TBM_ERROR_NONE) {
354 /* LCOV_EXCL_START */
355 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
356 _tbm_set_last_result(error);
362 if (!bufmgr->backend->surface_get_plane_data) {
363 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
367 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
368 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
370 /* LCOV_EXCL_START */
371 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
372 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
382 _tbm_surface_internal_destroy(tbm_surface_h surface)
385 tbm_bufmgr bufmgr = surface->bufmgr;
386 tbm_user_data *old_data = NULL, *tmp = NULL;
387 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
388 tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL;
390 if (!LIST_IS_EMPTY(&surface->destroy_funcs)) {
391 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
392 func_info->destroy_func(surface, func_info->user_data);
394 TBM_DBG("free destroy_funcs %p\n", surface);
395 LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) {
396 LIST_DEL(&func_info->item_link);
401 /* destory the user_data_list */
402 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
403 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
404 TBM_DBG("free user_data\n");
405 user_data_delete(old_data);
409 for (i = 0; i < surface->num_bos; i++) {
410 surface->bos[i]->surface = NULL;
412 tbm_bo_unref(surface->bos[i]);
413 surface->bos[i] = NULL;
416 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
417 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
418 _tbm_surface_internal_debug_data_delete(debug_old_data);
421 LIST_DEL(&surface->item_link);
424 if (surface->hal_surface) {
425 hal_tbm_surface_free(surface->hal_surface);
426 surface->hal_surface = NULL;
432 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
433 LIST_DELINIT(&bufmgr->surf_list);
435 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
436 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
437 _tbm_surface_internal_debug_data_delete(debug_old_data);
441 _deinit_surface_bufmgr();
445 /* LCOV_EXCL_START */
447 _tbm_surface_check_file_is_symbolic_link(const char* path)
454 if (stat(path, &sb) != 0)
457 if (S_ISLNK(sb.st_mode))
465 _tbm_surface_internal_get_num_planes(tbm_format format)
471 case TBM_FORMAT_RGB332:
472 case TBM_FORMAT_BGR233:
473 case TBM_FORMAT_XRGB4444:
474 case TBM_FORMAT_XBGR4444:
475 case TBM_FORMAT_RGBX4444:
476 case TBM_FORMAT_BGRX4444:
477 case TBM_FORMAT_ARGB4444:
478 case TBM_FORMAT_ABGR4444:
479 case TBM_FORMAT_RGBA4444:
480 case TBM_FORMAT_BGRA4444:
481 case TBM_FORMAT_XRGB1555:
482 case TBM_FORMAT_XBGR1555:
483 case TBM_FORMAT_RGBX5551:
484 case TBM_FORMAT_BGRX5551:
485 case TBM_FORMAT_ARGB1555:
486 case TBM_FORMAT_ABGR1555:
487 case TBM_FORMAT_RGBA5551:
488 case TBM_FORMAT_BGRA5551:
489 case TBM_FORMAT_RGB565:
490 case TBM_FORMAT_BGR565:
491 case TBM_FORMAT_RGB888:
492 case TBM_FORMAT_BGR888:
493 case TBM_FORMAT_XRGB8888:
494 case TBM_FORMAT_XBGR8888:
495 case TBM_FORMAT_RGBX8888:
496 case TBM_FORMAT_BGRX8888:
497 case TBM_FORMAT_ARGB8888:
498 case TBM_FORMAT_ABGR8888:
499 case TBM_FORMAT_RGBA8888:
500 case TBM_FORMAT_BGRA8888:
501 case TBM_FORMAT_XRGB2101010:
502 case TBM_FORMAT_XBGR2101010:
503 case TBM_FORMAT_RGBX1010102:
504 case TBM_FORMAT_BGRX1010102:
505 case TBM_FORMAT_ARGB2101010:
506 case TBM_FORMAT_ABGR2101010:
507 case TBM_FORMAT_RGBA1010102:
508 case TBM_FORMAT_BGRA1010102:
509 case TBM_FORMAT_YUYV:
510 case TBM_FORMAT_YVYU:
511 case TBM_FORMAT_UYVY:
512 case TBM_FORMAT_VYUY:
513 case TBM_FORMAT_AYUV:
516 case TBM_FORMAT_NV12:
517 case TBM_FORMAT_NV12MT:
518 case TBM_FORMAT_NV21:
519 case TBM_FORMAT_NV16:
520 case TBM_FORMAT_NV61:
523 case TBM_FORMAT_YUV410:
524 case TBM_FORMAT_YVU410:
525 case TBM_FORMAT_YUV411:
526 case TBM_FORMAT_YVU411:
527 case TBM_FORMAT_YUV420:
528 case TBM_FORMAT_YVU420:
529 case TBM_FORMAT_YUV422:
530 case TBM_FORMAT_YVU422:
531 case TBM_FORMAT_YUV444:
532 case TBM_FORMAT_YVU444:
537 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
545 _tbm_surface_internal_get_bpp(tbm_format format)
552 case TBM_FORMAT_RGB332:
553 case TBM_FORMAT_BGR233:
556 case TBM_FORMAT_XRGB4444:
557 case TBM_FORMAT_XBGR4444:
558 case TBM_FORMAT_RGBX4444:
559 case TBM_FORMAT_BGRX4444:
560 case TBM_FORMAT_ARGB4444:
561 case TBM_FORMAT_ABGR4444:
562 case TBM_FORMAT_RGBA4444:
563 case TBM_FORMAT_BGRA4444:
564 case TBM_FORMAT_XRGB1555:
565 case TBM_FORMAT_XBGR1555:
566 case TBM_FORMAT_RGBX5551:
567 case TBM_FORMAT_BGRX5551:
568 case TBM_FORMAT_ARGB1555:
569 case TBM_FORMAT_ABGR1555:
570 case TBM_FORMAT_RGBA5551:
571 case TBM_FORMAT_BGRA5551:
572 case TBM_FORMAT_RGB565:
573 case TBM_FORMAT_BGR565:
576 case TBM_FORMAT_RGB888:
577 case TBM_FORMAT_BGR888:
580 case TBM_FORMAT_XRGB8888:
581 case TBM_FORMAT_XBGR8888:
582 case TBM_FORMAT_RGBX8888:
583 case TBM_FORMAT_BGRX8888:
584 case TBM_FORMAT_ARGB8888:
585 case TBM_FORMAT_ABGR8888:
586 case TBM_FORMAT_RGBA8888:
587 case TBM_FORMAT_BGRA8888:
588 case TBM_FORMAT_XRGB2101010:
589 case TBM_FORMAT_XBGR2101010:
590 case TBM_FORMAT_RGBX1010102:
591 case TBM_FORMAT_BGRX1010102:
592 case TBM_FORMAT_ARGB2101010:
593 case TBM_FORMAT_ABGR2101010:
594 case TBM_FORMAT_RGBA1010102:
595 case TBM_FORMAT_BGRA1010102:
596 case TBM_FORMAT_YUYV:
597 case TBM_FORMAT_YVYU:
598 case TBM_FORMAT_UYVY:
599 case TBM_FORMAT_VYUY:
600 case TBM_FORMAT_AYUV:
603 case TBM_FORMAT_NV12:
604 case TBM_FORMAT_NV12MT:
605 case TBM_FORMAT_NV21:
608 case TBM_FORMAT_NV16:
609 case TBM_FORMAT_NV61:
612 case TBM_FORMAT_YUV410:
613 case TBM_FORMAT_YVU410:
616 case TBM_FORMAT_YUV411:
617 case TBM_FORMAT_YVU411:
618 case TBM_FORMAT_YUV420:
619 case TBM_FORMAT_YVU420:
622 case TBM_FORMAT_YUV422:
623 case TBM_FORMAT_YVU422:
626 case TBM_FORMAT_YUV444:
627 case TBM_FORMAT_YVU444:
631 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
638 static struct _tbm_surface *
639 _tbm_surface_internal_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
641 struct _tbm_surface *surf = NULL;
642 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
645 surf = calloc(1, sizeof(struct _tbm_surface));
647 /* LCOV_EXCL_START */
648 TBM_ERR("fail to alloc surf\n");
649 *error = TBM_ERROR_OUT_OF_MEMORY;
650 goto alloc_surf_fail;
654 surf->magic = TBM_SURFACE_MAGIC;
655 surf->bufmgr = bufmgr;
656 surf->info.width = width;
657 surf->info.height = height;
658 surf->info.format = format;
659 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
660 if (!surf->info.bpp) {
661 TBM_ERR("fail to get bpp from format(%d), error(%s)\n", format, tbm_error_str(*error));
662 *error = tbm_get_last_error();
666 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
667 if (!surf->info.num_planes) {
668 TBM_ERR("fail to get num_planes from format(%d), error(%s)\n", format, tbm_error_str(*error));
669 *error = tbm_get_last_error();
670 goto num_planes_fail;
674 /* get size, stride and offset bo_idx */
675 for (i = 0; i < surf->info.num_planes; i++) {
676 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
677 TBM_ERR("fail to query plane data\n");
678 *error = tbm_get_last_error();
679 goto query_plane_data_fail;
682 surf->info.planes[i].size = size;
683 surf->info.planes[i].offset = offset;
684 surf->info.planes[i].stride = stride;
685 surf->planes_bo_idx[i] = bo_idx;
690 for (i = 0; i < surf->info.num_planes; i++) {
691 surf->info.size += surf->info.planes[i].size;
693 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
694 surf->num_bos = surf->planes_bo_idx[i] + 1;
699 for (i = 0; i < surf->num_bos; i++) {
701 for (j = 0; j < surf->info.num_planes; j++) {
702 if (surf->planes_bo_idx[j] == i)
703 bo_size += surf->info.planes[j].size;
706 if (bufmgr->use_hal_tbm) {
707 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
708 if (*error == TBM_ERROR_NOT_SUPPORTED) {
709 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
711 TBM_ERR("fail to alloc bo idx:%d\n", i);
712 *error = tbm_get_last_error();
716 } else if (bufmgr->backend_module_data) {
717 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
718 /* LCOV_EXCL_START */
719 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
721 TBM_ERR("fail to tbm_bo_alloc_with_format idx:%d\n", i);
722 *error = tbm_get_last_error();
726 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
727 /* LCOV_EXCL_START */
728 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, error);
730 TBM_ERR("fail to tbm_bo_alloc_with_tiled_format idx:%d\n", i);
731 *error = tbm_get_last_error();
736 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
738 TBM_ERR("fail to alloc bo idx:%d\n", i);
739 *error = tbm_get_last_error();
744 if (bufmgr->backend->surface_bo_alloc) {
745 /* LCOV_EXCL_START */
746 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
748 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
749 *error = tbm_get_last_error();
754 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
756 TBM_ERR("fail to alloc bo idx:%d\n", i);
757 *error = tbm_get_last_error();
763 _tbm_bo_set_surface(surf->bos[i], surf);
766 *error = TBM_ERROR_NONE;
771 for (j = 0; j < i; j++) {
773 tbm_bo_unref(surf->bos[j]);
775 query_plane_data_fail:
784 static struct _tbm_surface *
785 _tbm_surface_internal_hal_tbm_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
787 struct _tbm_surface *surf = NULL;
788 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
790 hal_tbm_surface *hal_surface = NULL;
791 hal_tbm_bo **hal_bos = NULL;
794 surf = calloc(1, sizeof(struct _tbm_surface));
796 /* LCOV_EXCL_START */
797 TBM_ERR("fail to alloc surf");
798 *error = TBM_ERROR_OUT_OF_MEMORY;
799 goto alloc_surf_fail;
804 surf->magic = TBM_SURFACE_MAGIC;
805 surf->bufmgr = bufmgr;
806 surf->info.width = width;
807 surf->info.height = height;
808 surf->info.format = format;
809 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
810 if (!surf->info.bpp) {
811 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
812 *error = tbm_get_last_error();
817 // get number of planes
818 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
819 if (!surf->info.num_planes) {
820 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
821 *error = tbm_get_last_error();
822 goto num_planes_fail;
825 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);
828 surf->hal_surface = hal_surface;
830 // set infomation of planes
831 for (i = 0; i < surf->info.num_planes; i++) {
832 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
833 if (*error != TBM_ERROR_NONE) {
834 goto query_plane_data_fail;
836 surf->info.planes[i].size = size;
837 surf->info.planes[i].offset = offset;
838 surf->info.planes[i].stride = stride;
839 surf->planes_bo_idx[i] = bo_idx;
842 // set infomation of bos
843 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
845 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
848 surf->num_bos = num_bos;
850 for (i = 0; i < surf->info.num_planes; i++) {
851 surf->info.size += surf->info.planes[i].size;
853 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
854 surf->num_bos = surf->planes_bo_idx[i] + 1;
857 for (i = 0; i < num_bos; i++) {
858 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
860 TBM_ERR("fail to alloc bo idx:%d", i);
861 *error = tbm_get_last_error();
865 _tbm_bo_set_surface(surf->bos[i], surf);
868 // set infomation of planes
869 for (i = 0; i < surf->info.num_planes; i++) {
870 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
871 TBM_ERR("fail to query plane data");
872 *error = tbm_get_last_error();
873 goto query_plane_data_fail;
875 surf->info.planes[i].size = size;
876 surf->info.planes[i].offset = offset;
877 surf->info.planes[i].stride = stride;
878 surf->planes_bo_idx[i] = bo_idx;
881 // count number of bos
883 for (i = 0; i < surf->info.num_planes; i++) {
884 surf->info.size += surf->info.planes[i].size;
886 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
887 surf->num_bos = surf->planes_bo_idx[i] + 1;
890 // set infomation of bos
891 for (i = 0; i < surf->num_bos; i++) {
893 for (j = 0; j < surf->info.num_planes; j++) {
894 if (surf->planes_bo_idx[j] == i)
895 bo_size += surf->info.planes[j].size;
898 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp / 8, flags, error);
899 if (*error == TBM_ERROR_NOT_SUPPORTED) {
900 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
902 TBM_ERR("fail to alloc bo idx:%d", i);
903 *error = tbm_get_last_error();
908 _tbm_bo_set_surface(surf->bos[i], surf);
912 *error = TBM_ERROR_NONE;
918 query_plane_data_fail:
920 hal_tbm_surface_free(hal_surface);
922 for (j = 0; j < i; j++) {
924 tbm_bo_unref(surf->bos[j]);
936 static struct _tbm_surface *
937 _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)
939 struct _tbm_surface *surf = NULL;
940 uint32_t size = 0, offset = 0, stride = 0;
942 hal_tbm_surface *hal_surface = NULL;
943 hal_tbm_bo **hal_bos = NULL;
947 surf = calloc(1, sizeof(struct _tbm_surface));
949 /* LCOV_EXCL_START */
950 TBM_ERR("fail to alloc surf");
951 *error = TBM_ERROR_OUT_OF_MEMORY;
952 goto alloc_surf_fail;
957 surf->magic = TBM_SURFACE_MAGIC;
958 surf->bufmgr = bufmgr;
959 surf->info.width = width;
960 surf->info.height = height;
961 surf->info.format = format;
962 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
963 if (!surf->info.bpp) {
964 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
965 *error = tbm_get_last_error();
969 // get number of planes
970 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
971 if (!surf->info.num_planes) {
972 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
973 *error = tbm_get_last_error();
974 goto num_planes_fail;
978 hal_surface = hal_tbm_bufmgr_import_surface(bufmgr->hal_bufmgr,
981 (hal_tbm_format)format,
982 (hal_tbm_surface_buffer_data *)buffer_data,
983 (hal_tbm_error *)error);
985 TBM_ERR("hal_tbm_bufmgr_import_surface failed.(width:%d height:%d format:%d error:%s)",
986 width, height, format, tbm_error_str(*error));
987 goto import_surface_fail;
989 surf->hal_surface = hal_surface;
991 // set infomation of planes
992 for (i = 0; i < surf->info.num_planes; i++) {
993 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
994 if (*error != TBM_ERROR_NONE) {
995 goto query_plane_data_fail;
997 surf->info.planes[i].size = size;
998 surf->info.planes[i].offset = offset;
999 surf->info.planes[i].stride = stride;
1000 surf->planes_bo_idx[i] = bo_idx;
1003 // set infomation of bos
1004 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
1006 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
1009 surf->num_bos = num_bos;
1011 for (i = 0; i < surf->info.num_planes; i++) {
1012 surf->info.size += surf->info.planes[i].size;
1014 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
1015 surf->num_bos = surf->planes_bo_idx[i] + 1;
1018 // get memory_types(bo flags)
1019 flags = (int)hal_tbm_bo_get_memory_types(hal_bos[0], (hal_tbm_error *)error);
1020 if (*error != TBM_ERROR_NONE) {
1021 TBM_ERR("hal_tbm_bo_get_memory_types failed.");
1022 goto get_memory_types_fail;
1024 surf->flags = flags;
1026 for (i = 0; i < num_bos; i++) {
1027 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
1028 if (!surf->bos[i]) {
1029 TBM_ERR("fail to alloc bo idx:%d", i);
1030 *error = tbm_get_last_error();
1034 _tbm_bo_set_surface(surf->bos[i], surf);
1037 *error = TBM_ERROR_NONE;
1042 get_memory_types_fail:
1044 query_plane_data_fail:
1046 hal_tbm_surface_free(hal_surface);
1048 for (j = 0; j < i; j++) {
1050 tbm_bo_unref(surf->bos[j]);
1053 import_surface_fail:
1064 tbm_surface_internal_is_valid(tbm_surface_h surface)
1068 _tbm_surface_mutex_lock();
1069 _tbm_set_last_result(TBM_ERROR_NONE);
1071 /* Return silently if surface is null. */
1073 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1074 _tbm_surface_mutex_unlock();
1078 ret = _tbm_surface_internal_is_valid(surface);
1080 _tbm_surface_mutex_unlock();
1086 tbm_surface_internal_query_supported_formats(uint32_t **formats,
1089 struct _tbm_bufmgr *bufmgr;
1091 bool bufmgr_initialized = false;
1094 _tbm_surface_mutex_lock();
1095 _tbm_set_last_result(TBM_ERROR_NONE);
1097 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
1098 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
1100 if (!g_surface_bufmgr) {
1101 _init_surface_bufmgr();
1102 if (!g_surface_bufmgr) {
1103 TBM_ERR("fail bufmgr initialization\n");
1104 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1107 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1108 bufmgr_initialized = true;
1111 bufmgr = g_surface_bufmgr;
1113 if (bufmgr->use_hal_tbm) {
1114 error = (tbm_error_e)hal_tbm_bufmgr_get_supported_formats(bufmgr->hal_bufmgr, formats, num);
1115 /* LCOV_EXCL_START */
1116 if (error == TBM_ERROR_NOT_SUPPORTED) {
1117 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1119 } else if (error != TBM_ERROR_NONE) {
1120 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1123 /* LCOV_EXCL_STOP */
1125 } else if (bufmgr->backend_module_data) {
1126 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
1127 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1131 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
1132 if (error != TBM_ERROR_NONE) {
1133 /* LCOV_EXCL_START */
1134 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
1136 /* LCOV_EXCL_START */
1140 if (!bufmgr->backend->surface_supported_format) {
1141 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1145 ret = bufmgr->backend->surface_supported_format(formats, num);
1147 /* LCOV_EXCL_START */
1148 TBM_ERR("Fail to surface_supported_format.\n");
1149 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1151 /* LCOV_EXCL_START */
1155 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
1157 if (bufmgr_initialized) {
1158 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1159 _deinit_surface_bufmgr();
1162 _tbm_surface_mutex_unlock();
1166 /* LCOV_EXCL_START */
1168 if (bufmgr_initialized) {
1169 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1170 _deinit_surface_bufmgr();
1172 _tbm_surface_mutex_unlock();
1174 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
1177 /* LCOV_EXCL_STOP */
1181 tbm_surface_internal_get_num_planes(tbm_format format)
1185 _tbm_surface_mutex_lock();
1186 _tbm_set_last_result(TBM_ERROR_NONE);
1188 num_planes = _tbm_surface_internal_get_num_planes(format);
1190 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1191 _tbm_surface_mutex_unlock();
1195 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
1197 _tbm_surface_mutex_unlock();
1203 tbm_surface_internal_get_bpp(tbm_format format)
1207 _tbm_surface_mutex_lock();
1208 _tbm_set_last_result(TBM_ERROR_NONE);
1210 bpp = _tbm_surface_internal_get_bpp(format);
1212 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1213 _tbm_surface_mutex_unlock();
1217 _tbm_surface_mutex_unlock();
1219 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
1225 tbm_surface_internal_create_with_flags(int width, int height,
1226 int format, int flags)
1228 struct _tbm_bufmgr *bufmgr;
1229 struct _tbm_surface *surf = NULL;
1230 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
1231 bool bufmgr_initialized = false;
1233 _tbm_surface_mutex_lock();
1234 _tbm_set_last_result(TBM_ERROR_NONE);
1236 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
1237 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
1239 if (!g_surface_bufmgr) {
1240 _init_surface_bufmgr();
1241 if (!g_surface_bufmgr) {
1242 TBM_ERR("fail bufmgr initialization\n");
1243 error = TBM_ERROR_INVALID_OPERATION;
1244 goto check_valid_fail;
1246 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1247 bufmgr_initialized = true;
1250 bufmgr = g_surface_bufmgr;
1251 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1252 TBM_ERR("The bufmgr is invalid\n");
1253 error = TBM_ERROR_INVALID_PARAMETER;
1254 goto check_valid_fail;
1257 if (bufmgr->use_hal_tbm) {
1258 surf = _tbm_surface_internal_hal_tbm_create_surface(bufmgr, width, height, format, flags, &error);
1260 TBM_ERR("_tbm_surface_internal_hal_tbm_create_surface failed.");
1261 goto surface_alloc_fail;
1264 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1266 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1267 goto surface_alloc_fail;
1271 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1272 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1274 LIST_INITHEAD(&surf->user_data_list);
1275 LIST_INITHEAD(&surf->debug_data_list);
1276 LIST_INITHEAD(&surf->destroy_funcs);
1278 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1280 _tbm_set_last_result(error);
1281 _tbm_surface_mutex_unlock();
1285 /* LCOV_EXCL_START */
1289 if (bufmgr_initialized && bufmgr) {
1290 LIST_DELINIT(&bufmgr->surf_list);
1291 _deinit_surface_bufmgr();
1294 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1295 width, height, _tbm_surface_internal_format_to_str(format), flags);
1297 _tbm_set_last_result(error);
1298 _tbm_surface_mutex_unlock();
1300 /* LCOV_EXCL_STOP */
1306 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1307 tbm_bo *bos, int num)
1309 struct _tbm_bufmgr *bufmgr;
1310 struct _tbm_surface *surf = NULL;
1312 bool bufmgr_initialized = false;
1314 _tbm_surface_mutex_lock();
1315 _tbm_set_last_result(TBM_ERROR_NONE);
1317 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1318 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1319 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1320 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1321 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1323 if (!g_surface_bufmgr) {
1324 _init_surface_bufmgr();
1325 if (!g_surface_bufmgr) {
1326 TBM_ERR("fail bufmgr initialization\n");
1327 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1328 goto check_valid_fail;
1330 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1331 bufmgr_initialized = true;
1334 bufmgr = g_surface_bufmgr;
1335 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1336 TBM_ERR("fail to validate the Bufmgr.\n");
1337 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1338 goto check_valid_fail;
1341 surf = calloc(1, sizeof(struct _tbm_surface));
1343 /* LCOV_EXCL_START */
1344 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1345 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1346 goto alloc_surf_fail;
1347 /* LCOV_EXCL_STOP */
1350 surf->magic = TBM_SURFACE_MAGIC;
1351 surf->bufmgr = bufmgr;
1352 surf->info.width = info->width;
1353 surf->info.height = info->height;
1354 surf->info.format = info->format;
1356 surf->info.bpp = info->bpp;
1358 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1359 if (!surf->info.bpp) {
1360 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1364 surf->info.num_planes = info->num_planes;
1367 /* get size, stride and offset */
1368 for (i = 0; i < info->num_planes; i++) {
1369 surf->info.planes[i].offset = info->planes[i].offset;
1370 surf->info.planes[i].stride = info->planes[i].stride;
1372 if (info->planes[i].size > 0)
1373 surf->info.planes[i].size = info->planes[i].size;
1375 uint32_t size = 0, offset = 0, stride = 0;
1378 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1379 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1380 goto plane_data_fail;
1382 surf->info.planes[i].size = size;
1386 surf->planes_bo_idx[i] = 0;
1388 surf->planes_bo_idx[i] = i;
1391 if (info->size > 0) {
1392 surf->info.size = info->size;
1394 surf->info.size = 0;
1395 for (i = 0; i < info->num_planes; i++)
1396 surf->info.size += surf->info.planes[i].size;
1399 surf->flags = TBM_BO_DEFAULT;
1401 /* create only one bo */
1402 surf->num_bos = num;
1403 for (i = 0; i < num; i++) {
1404 if (bos[i] == NULL) {
1405 TBM_ERR("bos[%d] is null.\n", i);
1406 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1410 surf->bos[i] = tbm_bo_ref(bos[i]);
1411 _tbm_bo_set_surface(bos[i], surf);
1414 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1415 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1417 LIST_INITHEAD(&surf->user_data_list);
1418 LIST_INITHEAD(&surf->debug_data_list);
1419 LIST_INITHEAD(&surf->destroy_funcs);
1421 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1423 _tbm_surface_mutex_unlock();
1427 /* LCOV_EXCL_START */
1431 for (i = 0; i < num; i++) {
1433 tbm_bo_unref(surf->bos[i]);
1438 if (bufmgr_initialized && bufmgr) {
1439 LIST_DELINIT(&bufmgr->surf_list);
1440 _deinit_surface_bufmgr();
1442 _tbm_surface_mutex_unlock();
1444 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1445 info->width, info->height,
1446 _tbm_surface_internal_format_to_str(info->format), num);
1447 /* LCOV_EXCL_STOP */
1453 tbm_surface_internal_destroy(tbm_surface_h surface)
1455 _tbm_surface_mutex_lock();
1456 _tbm_set_last_result(TBM_ERROR_NONE);
1458 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1462 if (surface->refcnt > 0) {
1463 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1464 _tbm_surface_mutex_unlock();
1468 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1470 if (surface->refcnt == 0)
1471 _tbm_surface_internal_destroy(surface);
1472 else // if (surface->refcnt < 0)
1473 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1475 _tbm_surface_mutex_unlock();
1479 tbm_surface_internal_ref(tbm_surface_h surface)
1481 _tbm_surface_mutex_lock();
1482 _tbm_set_last_result(TBM_ERROR_NONE);
1484 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1488 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1490 _tbm_surface_mutex_unlock();
1494 tbm_surface_internal_unref(tbm_surface_h surface)
1496 _tbm_surface_mutex_lock();
1497 _tbm_set_last_result(TBM_ERROR_NONE);
1499 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1503 if (surface->refcnt > 0) {
1504 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1505 _tbm_surface_mutex_unlock();
1509 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1511 if (surface->refcnt == 0)
1512 _tbm_surface_internal_destroy(surface);
1514 _tbm_surface_mutex_unlock();
1518 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1520 struct _tbm_surface *surf;
1523 _tbm_surface_mutex_lock();
1524 _tbm_set_last_result(TBM_ERROR_NONE);
1526 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1528 surf = (struct _tbm_surface *)surface;
1529 num = surf->num_bos;
1532 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1534 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1536 _tbm_surface_mutex_unlock();
1542 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1544 struct _tbm_surface *surf;
1547 _tbm_surface_mutex_lock();
1548 _tbm_set_last_result(TBM_ERROR_NONE);
1550 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1551 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1553 surf = (struct _tbm_surface *)surface;
1554 bo = surf->bos[bo_idx];
1556 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1558 _tbm_surface_mutex_unlock();
1564 tbm_surface_internal_get_size(tbm_surface_h surface)
1566 struct _tbm_surface *surf;
1569 _tbm_surface_mutex_lock();
1570 _tbm_set_last_result(TBM_ERROR_NONE);
1572 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1574 surf = (struct _tbm_surface *)surface;
1575 size = surf->info.size;
1577 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1579 _tbm_surface_mutex_unlock();
1585 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1586 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1588 struct _tbm_surface *surf;
1590 _tbm_surface_mutex_lock();
1591 _tbm_set_last_result(TBM_ERROR_NONE);
1593 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1594 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1596 surf = (struct _tbm_surface *)surface;
1598 if (plane_idx >= surf->info.num_planes) {
1599 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1600 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1601 _tbm_surface_mutex_unlock();
1606 *size = surf->info.planes[plane_idx].size;
1609 *offset = surf->info.planes[plane_idx].offset;
1612 *pitch = surf->info.planes[plane_idx].stride;
1614 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1615 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1616 surf->info.planes[plane_idx].stride);
1618 _tbm_surface_mutex_unlock();
1624 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1625 tbm_surface_info_s *info, int map)
1627 struct _tbm_surface *surf;
1628 tbm_bo_handle bo_handles[4];
1631 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1634 _tbm_surface_mutex_lock();
1635 _tbm_set_last_result(TBM_ERROR_NONE);
1637 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1639 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1641 surf = (struct _tbm_surface *)surface;
1643 memset(info, 0x00, sizeof(tbm_surface_info_s));
1644 info->width = surf->info.width;
1645 info->height = surf->info.height;
1646 info->format = surf->info.format;
1647 info->bpp = surf->info.bpp;
1648 info->size = surf->info.size;
1649 info->num_planes = surf->info.num_planes;
1651 for (i = 0; i < surf->info.num_planes; i++) {
1652 info->planes[i].size = surf->info.planes[i].size;
1653 info->planes[i].offset = surf->info.planes[i].offset;
1654 info->planes[i].stride = surf->info.planes[i].stride;
1655 planes_bo_idx[i] = surf->planes_bo_idx[i];
1658 for (i = 0; i < surf->num_bos; i++)
1659 bos[i] = surf->bos[i];
1661 num_bos = surf->num_bos;
1664 _tbm_surface_mutex_unlock();
1665 for (i = 0; i < num_bos; i++) {
1666 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1667 if (bo_handles[i].ptr == NULL) {
1668 for (j = 0; j < i; j++)
1669 tbm_bo_unmap(bos[j]);
1671 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1675 _tbm_surface_mutex_lock();
1677 for (i = 0; i < num_bos; i++) {
1678 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1679 if (bo_handles[i].ptr == NULL) {
1680 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1681 _tbm_surface_mutex_unlock();
1687 for (i = 0; i < info->num_planes; i++) {
1688 if (bo_handles[planes_bo_idx[i]].ptr)
1689 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1692 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1694 _tbm_surface_mutex_unlock();
1700 tbm_surface_internal_unmap(tbm_surface_h surface)
1702 struct _tbm_surface *surf;
1705 _tbm_surface_mutex_lock();
1706 _tbm_set_last_result(TBM_ERROR_NONE);
1708 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1710 surf = (struct _tbm_surface *)surface;
1712 for (i = 0; i < surf->num_bos; i++)
1713 tbm_bo_unmap(surf->bos[i]);
1715 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1717 _tbm_surface_mutex_unlock();
1721 tbm_surface_internal_get_width(tbm_surface_h surface)
1723 struct _tbm_surface *surf;
1726 _tbm_surface_mutex_lock();
1727 _tbm_set_last_result(TBM_ERROR_NONE);
1729 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1731 surf = (struct _tbm_surface *)surface;
1732 width = surf->info.width;
1734 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1736 _tbm_surface_mutex_unlock();
1742 tbm_surface_internal_get_height(tbm_surface_h surface)
1744 struct _tbm_surface *surf;
1745 unsigned int height;
1747 _tbm_surface_mutex_lock();
1748 _tbm_set_last_result(TBM_ERROR_NONE);
1750 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1752 surf = (struct _tbm_surface *)surface;
1753 height = surf->info.height;
1755 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1757 _tbm_surface_mutex_unlock();
1764 tbm_surface_internal_get_format(tbm_surface_h surface)
1766 struct _tbm_surface *surf;
1769 _tbm_surface_mutex_lock();
1770 _tbm_set_last_result(TBM_ERROR_NONE);
1772 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1774 surf = (struct _tbm_surface *)surface;
1775 format = surf->info.format;
1777 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1779 _tbm_surface_mutex_unlock();
1785 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1787 struct _tbm_surface *surf;
1790 _tbm_surface_mutex_lock();
1791 _tbm_set_last_result(TBM_ERROR_NONE);
1793 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1794 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1796 surf = (struct _tbm_surface *)surface;
1797 bo_idx = surf->planes_bo_idx[plane_idx];
1799 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1801 _tbm_surface_mutex_unlock();
1807 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1808 tbm_data_free data_free_func)
1810 tbm_user_data *data;
1812 _tbm_surface_mutex_lock();
1813 _tbm_set_last_result(TBM_ERROR_NONE);
1815 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1817 /* check if the data according to the key exist if so, return false. */
1818 data = user_data_lookup(&surface->user_data_list, key);
1820 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1821 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1822 _tbm_surface_mutex_unlock();
1826 data = user_data_create(key, data_free_func);
1828 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1829 _tbm_surface_mutex_unlock();
1833 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1835 LIST_ADD(&data->item_link, &surface->user_data_list);
1837 _tbm_surface_mutex_unlock();
1843 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1846 tbm_user_data *old_data;
1848 _tbm_surface_mutex_lock();
1849 _tbm_set_last_result(TBM_ERROR_NONE);
1851 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1853 old_data = user_data_lookup(&surface->user_data_list, key);
1855 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1856 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1857 _tbm_surface_mutex_unlock();
1861 if (old_data->data && old_data->free_func)
1862 old_data->free_func(old_data->data);
1864 old_data->data = data;
1866 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1868 _tbm_surface_mutex_unlock();
1874 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1877 tbm_user_data *old_data;
1879 _tbm_surface_mutex_lock();
1880 _tbm_set_last_result(TBM_ERROR_NONE);
1882 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1885 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1886 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1887 _tbm_surface_mutex_unlock();
1892 old_data = user_data_lookup(&surface->user_data_list, key);
1894 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1895 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1896 _tbm_surface_mutex_unlock();
1900 *data = old_data->data;
1902 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1904 _tbm_surface_mutex_unlock();
1910 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1913 tbm_user_data *old_data = (void *)0;
1915 _tbm_surface_mutex_lock();
1916 _tbm_set_last_result(TBM_ERROR_NONE);
1918 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1920 old_data = user_data_lookup(&surface->user_data_list, key);
1922 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1923 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1924 _tbm_surface_mutex_unlock();
1928 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1930 user_data_delete(old_data);
1932 _tbm_surface_mutex_unlock();
1937 /* LCOV_EXCL_START */
1939 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1941 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1943 return surface->debug_pid;
1947 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1949 _tbm_surface_mutex_lock();
1950 _tbm_set_last_result(TBM_ERROR_NONE);
1952 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1954 surface->debug_pid = pid;
1956 _tbm_surface_mutex_unlock();
1959 static tbm_surface_debug_data *
1960 _tbm_surface_internal_debug_data_create(char *key, char *value)
1962 tbm_surface_debug_data *debug_data = NULL;
1964 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1966 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1967 TBM_ERR("fail to allocate the debug_data.");
1971 if (key) debug_data->key = strdup(key);
1972 if (value) debug_data->value = strdup(value);
1978 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1980 if (!debug_data->value && !value)
1983 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1986 if (debug_data->value)
1987 free(debug_data->value);
1990 debug_data->value = strdup(value);
1992 debug_data->value = NULL;
1995 static tbm_surface_debug_data *
1996 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1998 tbm_surface_debug_data *debug_data = NULL;
2000 if (LIST_IS_EMPTY(list))
2003 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
2004 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
2012 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
2014 tbm_surface_debug_data *debug_data = NULL;
2015 tbm_bufmgr bufmgr = NULL;
2017 _tbm_surface_mutex_lock();
2018 _tbm_set_last_result(TBM_ERROR_NONE);
2020 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2021 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
2023 bufmgr = surface->bufmgr;
2025 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
2027 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
2029 _tbm_surface_internal_debug_data_value_update(debug_data, value);
2031 debug_data = _tbm_surface_internal_debug_data_create(key, value);
2033 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
2034 _tbm_surface_mutex_unlock();
2038 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
2041 /* add new debug key to list */
2042 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
2044 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
2046 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
2049 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
2051 _tbm_surface_mutex_unlock();
2057 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
2059 tbm_surface_debug_data *old_data = NULL;
2061 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
2063 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
2064 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
2065 if (!strcmp(old_data->key, key))
2066 return old_data->value;
2073 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
2074 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
2076 struct _tbm_surface_dump_buf_info {
2086 tbm_surface_info_s info;
2088 struct list_head link;
2091 struct _tbm_surface_dump_info {
2092 char *path; // copy???
2095 struct list_head *link;
2096 struct list_head surface_list; /* link of surface */
2099 static tbm_surface_dump_info *g_dump_info = NULL;
2100 static const char *dump_postfix[2] = {"png", "yuv"};
2101 static double scale_factor;
2104 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
2105 void *data2, int size2, void *data3, int size3)
2108 unsigned int *blocks;
2110 if (_tbm_surface_check_file_is_symbolic_link(file))
2111 TBM_ERR("%s is symbolic link\n", file);
2113 fp = fopen(file, "w+");
2114 TBM_RETURN_IF_FAIL(fp != NULL);
2116 blocks = (unsigned int *)data1;
2117 fwrite(blocks, 1, size1, fp);
2120 blocks = (unsigned int *)data2;
2121 fwrite(blocks, 1, size2, fp);
2125 blocks = (unsigned int *)data3;
2126 fwrite(blocks, 1, size3, fp);
2133 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
2135 unsigned int *blocks = (unsigned int *)data;
2138 png_bytep *row_pointers;
2141 if (_tbm_surface_check_file_is_symbolic_link(file))
2142 TBM_ERR("%s is symbolic link\n", file);
2144 fp = fopen(file, "wb");
2145 TBM_RETURN_IF_FAIL(fp != NULL);
2147 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
2150 TBM_ERR("fail to create a png write structure.\n");
2155 png_infop pPngInfo = png_create_info_struct(pPngStruct);
2157 TBM_ERR("fail to create a png info structure.\n");
2158 png_destroy_write_struct(&pPngStruct, NULL);
2163 if (setjmp(png_jmpbuf(pPngStruct))) {
2164 /* if png has problem of writing the file, we get here */
2165 TBM_ERR("fail to write png file.\n");
2166 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2171 png_init_io(pPngStruct, fp);
2172 if (format == TBM_FORMAT_XRGB8888) {
2174 png_set_IHDR(pPngStruct,
2181 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2184 png_set_IHDR(pPngStruct,
2189 PNG_COLOR_TYPE_RGBA,
2191 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2194 png_set_bgr(pPngStruct);
2195 png_write_info(pPngStruct, pPngInfo);
2197 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
2198 if (!row_pointers) {
2199 TBM_ERR("fail to allocate the png row_pointers.\n");
2200 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2205 for (y = 0; y < height; ++y) {
2209 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
2211 TBM_ERR("fail to allocate the png row.\n");
2212 for (x = 0; x < y; x++)
2213 png_free(pPngStruct, row_pointers[x]);
2214 png_free(pPngStruct, row_pointers);
2215 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2219 row_pointers[y] = (png_bytep)row;
2221 for (x = 0; x < width; ++x) {
2222 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
2224 if (pixel_size == 3) { // XRGB8888
2225 row[x * pixel_size] = (curBlock & 0xFF);
2226 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2227 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2228 } else { // ARGB8888
2229 row[x * pixel_size] = (curBlock & 0xFF);
2230 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2231 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2232 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2237 png_write_image(pPngStruct, row_pointers);
2238 png_write_end(pPngStruct, pPngInfo);
2240 for (y = 0; y < height; y++)
2241 png_free(pPngStruct, row_pointers[y]);
2242 png_free(pPngStruct, row_pointers);
2244 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2250 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2252 TBM_RETURN_IF_FAIL(path != NULL);
2253 TBM_RETURN_IF_FAIL(w > 0);
2254 TBM_RETURN_IF_FAIL(h > 0);
2255 TBM_RETURN_IF_FAIL(count > 0);
2257 tbm_surface_dump_buf_info *buf_info = NULL;
2258 tbm_surface_h tbm_surface;
2259 tbm_surface_info_s info;
2264 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2268 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2269 TBM_RETURN_IF_FAIL(g_dump_info);
2271 LIST_INITHEAD(&g_dump_info->surface_list);
2272 g_dump_info->count = 0;
2273 g_dump_info->dump_max = count;
2275 /* get buffer size */
2276 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2277 if (tbm_surface == NULL) {
2278 TBM_ERR("tbm_surface_create fail\n");
2284 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2285 TBM_ERR("tbm_surface_get_info fail\n");
2286 tbm_surface_destroy(tbm_surface);
2291 buffer_size = info.size;
2292 tbm_surface_destroy(tbm_surface);
2294 /* create dump lists */
2295 for (i = 0; i < count; i++) {
2298 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2299 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2301 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2303 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2308 buf_info->index = i;
2310 buf_info->size = buffer_size;
2312 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2315 g_dump_info->path = path;
2316 g_dump_info->link = &g_dump_info->surface_list;
2320 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2325 /* free resources */
2326 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2327 tbm_surface_dump_buf_info *tmp;
2329 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2330 tbm_bo_unref(buf_info->bo);
2331 LIST_DEL(&buf_info->link);
2336 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2345 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2352 tbm_surface_internal_dump_start(path, w, h, count);
2353 scale_factor = scale;
2357 tbm_surface_internal_dump_end(void)
2359 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2360 tbm_bo_handle bo_handle;
2365 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2372 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2375 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2376 if (bo_handle.ptr == NULL) {
2377 tbm_bo_unref(buf_info->bo);
2378 LIST_DEL(&buf_info->link);
2383 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2384 TBM_INFO("Dump File.. %s generated.\n", file);
2386 if (buf_info->dirty) {
2387 void *ptr1 = NULL, *ptr2 = NULL;
2389 switch (buf_info->info.format) {
2390 case TBM_FORMAT_ARGB8888:
2391 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2392 buf_info->info.planes[0].stride >> 2,
2393 buf_info->info.height,
2394 buf_info->info.planes[0].stride,
2395 TBM_FORMAT_ARGB8888);
2397 case TBM_FORMAT_XRGB8888:
2398 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2399 buf_info->info.planes[0].stride >> 2,
2400 buf_info->info.height,
2401 buf_info->info.planes[0].stride,
2402 TBM_FORMAT_XRGB8888);
2404 case TBM_FORMAT_YVU420:
2405 case TBM_FORMAT_YUV420:
2406 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2407 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2408 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2409 buf_info->info.planes[0].stride * buf_info->info.height,
2411 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2413 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2415 case TBM_FORMAT_NV12:
2416 case TBM_FORMAT_NV21:
2417 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2418 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2419 buf_info->info.planes[0].stride * buf_info->info.height,
2421 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2424 case TBM_FORMAT_YUYV:
2425 case TBM_FORMAT_UYVY:
2426 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2427 buf_info->info.planes[0].stride * buf_info->info.height,
2431 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2434 } else if (buf_info->dirty_shm)
2435 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2436 buf_info->shm_stride >> 2,
2438 buf_info->shm_stride, 0);
2440 tbm_bo_unmap(buf_info->bo);
2441 tbm_bo_unref(buf_info->bo);
2442 LIST_DEL(&buf_info->link);
2449 TBM_INFO("Dump End..\n");
2452 static pixman_format_code_t
2453 _tbm_surface_internal_pixman_format_get(tbm_format format)
2456 case TBM_FORMAT_ARGB8888:
2457 return PIXMAN_a8r8g8b8;
2458 case TBM_FORMAT_XRGB8888:
2459 return PIXMAN_x8r8g8b8;
2468 * This function supports only if a buffer has below formats.
2469 * - TBM_FORMAT_ARGB8888
2470 * - TBM_FORMAT_XRGB8888
2472 static tbm_surface_error_e
2473 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2474 int format, int src_stride, int src_w, int src_h,
2475 int dst_stride, int dst_w, int dst_h)
2477 pixman_image_t *src_img = NULL, *dst_img = NULL;
2478 pixman_format_code_t pixman_format;
2479 pixman_transform_t t;
2480 struct pixman_f_transform ft;
2481 double scale_x, scale_y;
2483 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2484 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2486 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2487 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2490 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2491 (uint32_t*)src_ptr, src_stride);
2492 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2495 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2496 (uint32_t*)dst_ptr, dst_stride);
2497 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2499 pixman_f_transform_init_identity(&ft);
2501 scale_x = (double)src_w / dst_w;
2502 scale_y = (double)src_h / dst_h;
2504 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2505 pixman_f_transform_translate(&ft, NULL, 0, 0);
2506 pixman_transform_from_pixman_f_transform(&t, &ft);
2507 pixman_image_set_transform(src_img, &t);
2509 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2510 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2512 pixman_image_unref(src_img);
2513 pixman_image_unref(dst_img);
2515 return TBM_SURFACE_ERROR_NONE;
2519 pixman_image_unref(src_img);
2521 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2524 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2525 #define KEY_LEN 5 // "_XXXX"
2526 #define KEYS_LEN KEY_LEN * MAX_BOS
2528 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2530 char *keys, temp_key[KEY_LEN + 1];
2531 struct _tbm_surface *surf;
2535 _tbm_surface_mutex_lock();
2537 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2539 surf = (struct _tbm_surface *)surface;
2541 num_bos = surf->num_bos;
2542 if (num_bos > MAX_BOS)
2545 keys = calloc(KEYS_LEN + 1, sizeof(char));
2547 TBM_ERR("Failed to alloc memory");
2548 _tbm_surface_mutex_unlock();
2552 for (i = 0; i < num_bos; i++) {
2553 memset(temp_key, 0x00, KEY_LEN + 1);
2555 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2556 strncat(keys, temp_key, KEY_LEN + 1);
2559 _tbm_surface_mutex_unlock();
2564 static void _tbm_surface_internal_put_keys(char *keys)
2571 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2573 TBM_RETURN_IF_FAIL(surface != NULL);
2574 TBM_RETURN_IF_FAIL(type != NULL);
2576 tbm_surface_dump_buf_info *buf_info;
2577 struct list_head *next_link;
2578 tbm_surface_info_s info;
2579 tbm_bo_handle bo_handle;
2580 const char *postfix;
2581 const char *format = NULL;
2588 next_link = g_dump_info->link->next;
2589 TBM_RETURN_IF_FAIL(next_link != NULL);
2591 if (next_link == &g_dump_info->surface_list) {
2592 next_link = next_link->next;
2593 TBM_RETURN_IF_FAIL(next_link != NULL);
2596 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2597 TBM_RETURN_IF_FAIL(buf_info != NULL);
2599 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2600 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2602 if (scale_factor > 0.0) {
2605 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2606 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2607 _tbm_surface_internal_format_to_str(info.format));
2608 tbm_surface_unmap(surface);
2612 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2614 buf_info->info.width = info.width * scale_factor;
2615 buf_info->info.height = info.height * scale_factor;
2616 buf_info->info.format = info.format;
2617 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2618 if (!buf_info->info.bpp) {
2619 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2620 tbm_surface_unmap(surface);
2623 buf_info->info.num_planes = 1;
2624 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2625 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2627 if (buf_info->info.size > buf_info->size) {
2628 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2629 buf_info->info.size, buf_info->size);
2630 tbm_surface_unmap(surface);
2634 if (info.size > buf_info->size) {
2635 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2636 info.size, buf_info->size);
2637 tbm_surface_unmap(surface);
2641 /* make the file information */
2642 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2645 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2646 postfix = dump_postfix[0];
2647 format = _tbm_surface_internal_format_to_str(info.format);
2649 postfix = dump_postfix[1];
2651 keys = _tbm_surface_internal_get_keys(surface);
2653 TBM_ERR("fail to get keys");
2654 tbm_surface_unmap(surface);
2659 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2660 if (!bo_handle.ptr) {
2661 TBM_ERR("fail to map bo");
2662 _tbm_surface_internal_put_keys(keys);
2663 tbm_surface_unmap(surface);
2666 memset(bo_handle.ptr, 0x00, buf_info->size);
2668 switch (info.format) {
2669 case TBM_FORMAT_ARGB8888:
2670 case TBM_FORMAT_XRGB8888:
2671 snprintf(buf_info->name, sizeof(buf_info->name),
2672 "%10.3f_%03d%s_%p_%s-%s.%s",
2673 _tbm_surface_internal_get_time(),
2674 g_dump_info->count++, keys, surface, format, type, postfix);
2676 if (scale_factor > 0.0) {
2677 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2679 buf_info->info.format,
2680 info.planes[0].stride,
2681 info.width, info.height,
2682 buf_info->info.planes[0].stride,
2683 buf_info->info.width,
2684 buf_info->info.height);
2685 if (ret != TBM_SURFACE_ERROR_NONE) {
2686 TBM_ERR("fail to scale buffer");
2687 tbm_bo_unmap(buf_info->bo);
2688 _tbm_surface_internal_put_keys(keys);
2689 tbm_surface_unmap(surface);
2693 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2695 case TBM_FORMAT_YVU420:
2696 case TBM_FORMAT_YUV420:
2697 snprintf(buf_info->name, sizeof(buf_info->name),
2698 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2699 _tbm_surface_internal_get_time(),
2700 g_dump_info->count++, keys, type, info.planes[0].stride,
2701 info.height, FOURCC_STR(info.format), postfix);
2702 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2703 bo_handle.ptr += info.planes[0].stride * info.height;
2704 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2705 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2706 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2708 case TBM_FORMAT_NV12:
2709 case TBM_FORMAT_NV21:
2710 snprintf(buf_info->name, sizeof(buf_info->name),
2711 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2712 _tbm_surface_internal_get_time(),
2713 g_dump_info->count++, keys, type, info.planes[0].stride,
2714 info.height, FOURCC_STR(info.format), postfix);
2715 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2716 bo_handle.ptr += info.planes[0].stride * info.height;
2717 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2719 case TBM_FORMAT_YUYV:
2720 case TBM_FORMAT_UYVY:
2721 snprintf(buf_info->name, sizeof(buf_info->name),
2722 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2723 _tbm_surface_internal_get_time(),
2724 g_dump_info->count++, keys, type, info.planes[0].stride,
2725 info.height, FOURCC_STR(info.format), postfix);
2726 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2729 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2730 tbm_bo_unmap(buf_info->bo);
2731 _tbm_surface_internal_put_keys(keys);
2732 tbm_surface_unmap(surface);
2736 tbm_bo_unmap(buf_info->bo);
2738 _tbm_surface_internal_put_keys(keys);
2740 tbm_surface_unmap(surface);
2742 buf_info->dirty = 1;
2743 buf_info->dirty_shm = 0;
2745 if (g_dump_info->count == 1000)
2746 g_dump_info->count = 0;
2748 g_dump_info->link = next_link;
2750 TBM_INFO("Dump %s \n", buf_info->name);
2753 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2756 TBM_RETURN_IF_FAIL(ptr != NULL);
2757 TBM_RETURN_IF_FAIL(w > 0);
2758 TBM_RETURN_IF_FAIL(h > 0);
2759 TBM_RETURN_IF_FAIL(stride > 0);
2760 TBM_RETURN_IF_FAIL(type != NULL);
2762 tbm_surface_dump_buf_info *buf_info;
2763 struct list_head *next_link;
2764 tbm_bo_handle bo_handle;
2765 int ret, size, dw = 0, dh = 0, dstride = 0;
2770 next_link = g_dump_info->link->next;
2771 TBM_RETURN_IF_FAIL(next_link != NULL);
2773 if (next_link == &g_dump_info->surface_list) {
2774 next_link = next_link->next;
2775 TBM_RETURN_IF_FAIL(next_link != NULL);
2778 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2779 TBM_RETURN_IF_FAIL(buf_info != NULL);
2781 if (scale_factor > 0.0) {
2784 dw = w * scale_factor;
2785 dh = h * scale_factor;
2787 size = dstride * dh;
2791 if (size > buf_info->size) {
2792 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2793 size, buf_info->size);
2798 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2799 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2801 memset(bo_handle.ptr, 0x00, buf_info->size);
2802 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2804 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2805 _tbm_surface_internal_get_time(),
2806 g_dump_info->count++, type, dump_postfix[0]);
2807 if (scale_factor > 0.0) {
2808 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2809 TBM_FORMAT_ARGB8888, stride,
2810 w, h, dstride, dw, dh);
2811 if (ret != TBM_SURFACE_ERROR_NONE) {
2812 TBM_ERR("fail to scale buffer");
2813 tbm_bo_unmap(buf_info->bo);
2816 buf_info->shm_stride = dstride;
2817 buf_info->shm_h = dh;
2819 memcpy(bo_handle.ptr, ptr, size);
2820 buf_info->shm_stride = stride;
2821 buf_info->shm_h = h;
2824 tbm_bo_unmap(buf_info->bo);
2826 buf_info->dirty = 0;
2827 buf_info->dirty_shm = 1;
2829 if (g_dump_info->count == 1000)
2830 g_dump_info->count = 0;
2832 g_dump_info->link = next_link;
2834 TBM_INFO("Dump %s \n", buf_info->name);
2838 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2840 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2841 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2842 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2844 tbm_surface_info_s info;
2845 const char *postfix;
2849 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2850 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2852 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2853 postfix = dump_postfix[0];
2855 postfix = dump_postfix[1];
2857 if (strcmp(postfix, type)) {
2858 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2859 tbm_surface_unmap(surface);
2863 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2865 if (!access(file, 0)) {
2866 TBM_ERR("can't capture buffer, exist file %s", file);
2867 tbm_surface_unmap(surface);
2871 switch (info.format) {
2872 case TBM_FORMAT_ARGB8888:
2873 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2876 info.planes[0].stride,
2877 TBM_FORMAT_ARGB8888);
2879 case TBM_FORMAT_XRGB8888:
2880 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2883 info.planes[0].stride,
2884 TBM_FORMAT_XRGB8888);
2886 case TBM_FORMAT_YVU420:
2887 case TBM_FORMAT_YUV420:
2888 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2889 info.planes[0].stride * info.height,
2891 info.planes[1].stride * (info.height >> 1),
2893 info.planes[2].stride * (info.height >> 1));
2895 case TBM_FORMAT_NV12:
2896 case TBM_FORMAT_NV21:
2897 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2898 info.planes[0].stride * info.height,
2900 info.planes[1].stride * (info.height >> 1),
2903 case TBM_FORMAT_YUYV:
2904 case TBM_FORMAT_UYVY:
2905 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2906 info.planes[0].stride * info.height,
2910 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2911 tbm_surface_unmap(surface);
2915 tbm_surface_unmap(surface);
2917 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2923 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2924 const char *path, const char *name, const char *type)
2926 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2927 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2928 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2929 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2930 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2931 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2935 if (strcmp(dump_postfix[0], type)) {
2936 TBM_ERR("Not supported type:%s'", type);
2940 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2942 if (!access(file, 0)) {
2943 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2947 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2949 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2955 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2957 struct _tbm_surface *surf;
2959 _tbm_surface_mutex_lock();
2960 _tbm_set_last_result(TBM_ERROR_NONE);
2962 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2963 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2964 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2966 surf = (struct _tbm_surface *)surface;
2970 surf->damage.width = width;
2971 surf->damage.height = height;
2973 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2974 surface, x, y, width, height);
2976 _tbm_surface_mutex_unlock();
2982 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2984 struct _tbm_surface *surf;
2986 _tbm_surface_mutex_lock();
2987 _tbm_set_last_result(TBM_ERROR_NONE);
2989 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2991 surf = (struct _tbm_surface *)surface;
2993 if (x) *x = surf->damage.x;
2994 if (y) *y = surf->damage.y;
2995 if (width) *width = surf->damage.width;
2996 if (height) *height = surf->damage.height;
2998 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2999 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
3001 _tbm_surface_mutex_unlock();
3007 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
3009 struct _tbm_surface *surf;
3010 tbm_surface_destroy_func_info *func_info = NULL;
3012 _tbm_surface_mutex_lock();
3013 _tbm_set_last_result(TBM_ERROR_NONE);
3015 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
3016 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
3018 surf = (struct _tbm_surface *)surface;
3019 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
3020 if (func_info->destroy_func == func && func_info->user_data == user_data) {
3021 TBM_ERR("can't add twice");
3022 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
3023 _tbm_surface_mutex_unlock();
3028 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
3029 if (func_info == NULL) {
3030 TBM_ERR("alloc failed");
3031 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
3032 _tbm_surface_mutex_unlock();
3036 func_info->destroy_func = func;
3037 func_info->user_data = user_data;
3039 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
3041 _tbm_surface_mutex_unlock();
3047 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
3049 struct _tbm_surface *surf;
3050 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
3052 _tbm_surface_mutex_lock();
3053 _tbm_set_last_result(TBM_ERROR_NONE);
3055 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
3056 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
3058 surf = (struct _tbm_surface *)surface;
3059 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
3060 if (func_info->destroy_func != func || func_info->user_data != user_data)
3063 LIST_DEL(&func_info->item_link);
3066 _tbm_surface_mutex_unlock();
3071 _tbm_surface_mutex_unlock();
3074 tbm_surface_buffer_data *
3075 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
3077 tbm_surface_buffer_data *buffer_data = NULL;
3078 struct _tbm_surface *surf;
3079 struct _tbm_bufmgr *bufmgr;
3081 _tbm_surface_mutex_lock();
3083 surf = (struct _tbm_surface *)surface;
3084 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3086 bufmgr = surf->bufmgr;
3087 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3089 // this function supports when it comes to be use_hal.
3090 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
3093 buffer_data = (tbm_surface_buffer_data *)hal_tbm_surface_export((hal_tbm_surface *)surf->hal_surface,
3094 (hal_tbm_error *)error);
3095 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
3097 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
3100 *error = TBM_ERROR_NONE;
3102 _tbm_set_last_result(TBM_ERROR_NONE);
3103 _tbm_surface_mutex_unlock();
3109 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
3111 struct _tbm_surface *surf;
3112 struct _tbm_bufmgr *bufmgr;
3114 _tbm_surface_mutex_lock();
3116 bufmgr = g_surface_bufmgr;
3117 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3119 // this function supports when it comes to be use_hal.
3120 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
3122 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3123 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3124 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3125 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3128 surf = _tbm_surface_internal_hal_tbm_import_surface(bufmgr,
3129 (int)surface_info->width,
3130 (int)surface_info->height,
3131 (int)surface_info->format,
3134 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
3136 LIST_INITHEAD(&surf->user_data_list);
3137 LIST_INITHEAD(&surf->debug_data_list);
3138 LIST_INITHEAD(&surf->destroy_funcs);
3140 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
3142 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
3145 *error = TBM_ERROR_NONE;
3147 _tbm_set_last_result(TBM_ERROR_NONE);
3148 _tbm_surface_mutex_unlock();
3150 return (tbm_surface_h)surf;