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 TBM_ERR("NOT SUPPORTED. idx:%d", i);
729 *error = TBM_ERROR_NOT_SUPPORTED;
733 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
735 TBM_ERR("fail to alloc bo idx:%d\n", i);
736 *error = tbm_get_last_error();
741 if (bufmgr->backend->surface_bo_alloc) {
742 /* LCOV_EXCL_START */
743 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
745 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
746 *error = tbm_get_last_error();
751 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
753 TBM_ERR("fail to alloc bo idx:%d\n", i);
754 *error = tbm_get_last_error();
760 _tbm_bo_set_surface(surf->bos[i], surf);
763 *error = TBM_ERROR_NONE;
768 for (j = 0; j < i; j++) {
770 tbm_bo_unref(surf->bos[j]);
772 query_plane_data_fail:
781 static struct _tbm_surface *
782 _tbm_surface_internal_hal_tbm_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
784 struct _tbm_surface *surf = NULL;
785 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
787 hal_tbm_surface *hal_surface = NULL;
788 hal_tbm_bo **hal_bos = NULL;
791 surf = calloc(1, sizeof(struct _tbm_surface));
793 /* LCOV_EXCL_START */
794 TBM_ERR("fail to alloc surf");
795 *error = TBM_ERROR_OUT_OF_MEMORY;
796 goto alloc_surf_fail;
801 surf->magic = TBM_SURFACE_MAGIC;
802 surf->bufmgr = bufmgr;
803 surf->info.width = width;
804 surf->info.height = height;
805 surf->info.format = format;
806 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
807 if (!surf->info.bpp) {
808 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
809 *error = tbm_get_last_error();
814 // get number of planes
815 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
816 if (!surf->info.num_planes) {
817 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
818 *error = tbm_get_last_error();
819 goto num_planes_fail;
822 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);
825 surf->hal_surface = hal_surface;
827 // set infomation of planes
828 for (i = 0; i < surf->info.num_planes; i++) {
829 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
830 if (*error != TBM_ERROR_NONE) {
831 goto query_plane_data_fail;
833 surf->info.planes[i].size = size;
834 surf->info.planes[i].offset = offset;
835 surf->info.planes[i].stride = stride;
836 surf->planes_bo_idx[i] = bo_idx;
839 // set infomation of bos
840 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
842 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
845 surf->num_bos = num_bos;
847 for (i = 0; i < surf->info.num_planes; i++) {
848 surf->info.size += surf->info.planes[i].size;
850 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
851 surf->num_bos = surf->planes_bo_idx[i] + 1;
854 for (i = 0; i < num_bos; i++) {
855 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
857 TBM_ERR("fail to alloc bo idx:%d", i);
858 *error = tbm_get_last_error();
862 _tbm_bo_set_surface(surf->bos[i], surf);
865 // set infomation of planes
866 for (i = 0; i < surf->info.num_planes; i++) {
867 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
868 TBM_ERR("fail to query plane data");
869 *error = tbm_get_last_error();
870 goto query_plane_data_fail;
872 surf->info.planes[i].size = size;
873 surf->info.planes[i].offset = offset;
874 surf->info.planes[i].stride = stride;
875 surf->planes_bo_idx[i] = bo_idx;
878 // count number of bos
880 for (i = 0; i < surf->info.num_planes; i++) {
881 surf->info.size += surf->info.planes[i].size;
883 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
884 surf->num_bos = surf->planes_bo_idx[i] + 1;
887 // set infomation of bos
888 for (i = 0; i < surf->num_bos; i++) {
890 for (j = 0; j < surf->info.num_planes; j++) {
891 if (surf->planes_bo_idx[j] == i)
892 bo_size += surf->info.planes[j].size;
895 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp / 8, flags, error);
896 if (*error == TBM_ERROR_NOT_SUPPORTED) {
897 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
899 TBM_ERR("fail to alloc bo idx:%d", i);
900 *error = tbm_get_last_error();
905 _tbm_bo_set_surface(surf->bos[i], surf);
909 *error = TBM_ERROR_NONE;
915 query_plane_data_fail:
917 hal_tbm_surface_free(hal_surface);
919 for (j = 0; j < i; j++) {
921 tbm_bo_unref(surf->bos[j]);
933 static struct _tbm_surface *
934 _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)
936 struct _tbm_surface *surf = NULL;
937 uint32_t size = 0, offset = 0, stride = 0;
939 hal_tbm_surface *hal_surface = NULL;
940 hal_tbm_bo **hal_bos = NULL;
944 surf = calloc(1, sizeof(struct _tbm_surface));
946 /* LCOV_EXCL_START */
947 TBM_ERR("fail to alloc surf");
948 *error = TBM_ERROR_OUT_OF_MEMORY;
949 goto alloc_surf_fail;
954 surf->magic = TBM_SURFACE_MAGIC;
955 surf->bufmgr = bufmgr;
956 surf->info.width = width;
957 surf->info.height = height;
958 surf->info.format = format;
959 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
960 if (!surf->info.bpp) {
961 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
962 *error = tbm_get_last_error();
966 // get number of planes
967 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
968 if (!surf->info.num_planes) {
969 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
970 *error = tbm_get_last_error();
971 goto num_planes_fail;
975 hal_surface = hal_tbm_bufmgr_import_surface(bufmgr->hal_bufmgr,
978 (hal_tbm_format)format,
979 (hal_tbm_surface_buffer_data *)buffer_data,
980 (hal_tbm_error *)error);
982 TBM_ERR("hal_tbm_bufmgr_import_surface failed.(width:%d height:%d format:%d error:%s)",
983 width, height, format, tbm_error_str(*error));
984 goto import_surface_fail;
986 surf->hal_surface = hal_surface;
988 // set infomation of planes
989 for (i = 0; i < surf->info.num_planes; i++) {
990 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
991 if (*error != TBM_ERROR_NONE) {
992 goto query_plane_data_fail;
994 surf->info.planes[i].size = size;
995 surf->info.planes[i].offset = offset;
996 surf->info.planes[i].stride = stride;
997 surf->planes_bo_idx[i] = bo_idx;
1000 // set infomation of bos
1001 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
1003 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
1006 surf->num_bos = num_bos;
1008 for (i = 0; i < surf->info.num_planes; i++) {
1009 surf->info.size += surf->info.planes[i].size;
1011 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
1012 surf->num_bos = surf->planes_bo_idx[i] + 1;
1015 // get memory_types(bo flags)
1016 flags = (int)hal_tbm_bo_get_memory_types(hal_bos[0], (hal_tbm_error *)error);
1017 if (*error != TBM_ERROR_NONE) {
1018 TBM_ERR("hal_tbm_bo_get_memory_types failed.");
1019 goto get_memory_types_fail;
1021 surf->flags = flags;
1023 for (i = 0; i < num_bos; i++) {
1024 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
1025 if (!surf->bos[i]) {
1026 TBM_ERR("fail to alloc bo idx:%d", i);
1027 *error = tbm_get_last_error();
1031 _tbm_bo_set_surface(surf->bos[i], surf);
1034 *error = TBM_ERROR_NONE;
1039 get_memory_types_fail:
1041 query_plane_data_fail:
1043 hal_tbm_surface_free(hal_surface);
1045 for (j = 0; j < i; j++) {
1047 tbm_bo_unref(surf->bos[j]);
1050 import_surface_fail:
1061 tbm_surface_internal_is_valid(tbm_surface_h surface)
1065 _tbm_surface_mutex_lock();
1066 _tbm_set_last_result(TBM_ERROR_NONE);
1068 /* Return silently if surface is null. */
1070 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1071 _tbm_surface_mutex_unlock();
1075 ret = _tbm_surface_internal_is_valid(surface);
1077 _tbm_surface_mutex_unlock();
1083 tbm_surface_internal_query_supported_formats(uint32_t **formats,
1086 struct _tbm_bufmgr *bufmgr;
1088 bool bufmgr_initialized = false;
1091 _tbm_surface_mutex_lock();
1092 _tbm_set_last_result(TBM_ERROR_NONE);
1094 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
1095 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
1097 if (!g_surface_bufmgr) {
1098 _init_surface_bufmgr();
1099 if (!g_surface_bufmgr) {
1100 TBM_ERR("fail bufmgr initialization\n");
1101 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1104 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1105 bufmgr_initialized = true;
1108 bufmgr = g_surface_bufmgr;
1110 if (bufmgr->use_hal_tbm) {
1111 error = (tbm_error_e)hal_tbm_bufmgr_get_supported_formats(bufmgr->hal_bufmgr, formats, num);
1112 /* LCOV_EXCL_START */
1113 if (error == TBM_ERROR_NOT_SUPPORTED) {
1114 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1116 } else if (error != TBM_ERROR_NONE) {
1117 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1120 /* LCOV_EXCL_STOP */
1122 } else if (bufmgr->backend_module_data) {
1123 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
1124 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1128 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
1129 if (error != TBM_ERROR_NONE) {
1130 /* LCOV_EXCL_START */
1131 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
1133 /* LCOV_EXCL_START */
1137 if (!bufmgr->backend->surface_supported_format) {
1138 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1142 ret = bufmgr->backend->surface_supported_format(formats, num);
1144 /* LCOV_EXCL_START */
1145 TBM_ERR("Fail to surface_supported_format.\n");
1146 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1148 /* LCOV_EXCL_START */
1152 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
1154 if (bufmgr_initialized) {
1155 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1156 _deinit_surface_bufmgr();
1159 _tbm_surface_mutex_unlock();
1163 /* LCOV_EXCL_START */
1165 if (bufmgr_initialized) {
1166 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1167 _deinit_surface_bufmgr();
1169 _tbm_surface_mutex_unlock();
1171 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
1174 /* LCOV_EXCL_STOP */
1178 tbm_surface_internal_get_num_planes(tbm_format format)
1182 _tbm_surface_mutex_lock();
1183 _tbm_set_last_result(TBM_ERROR_NONE);
1185 num_planes = _tbm_surface_internal_get_num_planes(format);
1187 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1188 _tbm_surface_mutex_unlock();
1192 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
1194 _tbm_surface_mutex_unlock();
1200 tbm_surface_internal_get_bpp(tbm_format format)
1204 _tbm_surface_mutex_lock();
1205 _tbm_set_last_result(TBM_ERROR_NONE);
1207 bpp = _tbm_surface_internal_get_bpp(format);
1209 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1210 _tbm_surface_mutex_unlock();
1214 _tbm_surface_mutex_unlock();
1216 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
1222 tbm_surface_internal_create_with_flags(int width, int height,
1223 int format, int flags)
1225 struct _tbm_bufmgr *bufmgr;
1226 struct _tbm_surface *surf = NULL;
1227 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
1228 bool bufmgr_initialized = false;
1230 _tbm_surface_mutex_lock();
1231 _tbm_set_last_result(TBM_ERROR_NONE);
1233 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
1234 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
1236 if (!g_surface_bufmgr) {
1237 _init_surface_bufmgr();
1238 if (!g_surface_bufmgr) {
1239 TBM_ERR("fail bufmgr initialization\n");
1240 error = TBM_ERROR_INVALID_OPERATION;
1241 goto check_valid_fail;
1243 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1244 bufmgr_initialized = true;
1247 bufmgr = g_surface_bufmgr;
1248 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1249 TBM_ERR("The bufmgr is invalid\n");
1250 error = TBM_ERROR_INVALID_PARAMETER;
1251 goto check_valid_fail;
1254 if (bufmgr->use_hal_tbm) {
1255 surf = _tbm_surface_internal_hal_tbm_create_surface(bufmgr, width, height, format, flags, &error);
1257 TBM_ERR("_tbm_surface_internal_hal_tbm_create_surface failed.");
1258 goto surface_alloc_fail;
1261 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1263 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1264 goto surface_alloc_fail;
1268 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1269 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1271 LIST_INITHEAD(&surf->user_data_list);
1272 LIST_INITHEAD(&surf->debug_data_list);
1273 LIST_INITHEAD(&surf->destroy_funcs);
1275 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1277 _tbm_set_last_result(error);
1278 _tbm_surface_mutex_unlock();
1282 /* LCOV_EXCL_START */
1286 if (bufmgr_initialized && bufmgr) {
1287 LIST_DELINIT(&bufmgr->surf_list);
1288 _deinit_surface_bufmgr();
1291 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1292 width, height, _tbm_surface_internal_format_to_str(format), flags);
1294 _tbm_set_last_result(error);
1295 _tbm_surface_mutex_unlock();
1297 /* LCOV_EXCL_STOP */
1303 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1304 tbm_bo *bos, int num)
1306 struct _tbm_bufmgr *bufmgr;
1307 struct _tbm_surface *surf = NULL;
1309 bool bufmgr_initialized = false;
1311 _tbm_surface_mutex_lock();
1312 _tbm_set_last_result(TBM_ERROR_NONE);
1314 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1315 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1316 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1317 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1318 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1320 if (!g_surface_bufmgr) {
1321 _init_surface_bufmgr();
1322 if (!g_surface_bufmgr) {
1323 TBM_ERR("fail bufmgr initialization\n");
1324 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1325 goto check_valid_fail;
1327 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1328 bufmgr_initialized = true;
1331 bufmgr = g_surface_bufmgr;
1332 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1333 TBM_ERR("fail to validate the Bufmgr.\n");
1334 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1335 goto check_valid_fail;
1338 surf = calloc(1, sizeof(struct _tbm_surface));
1340 /* LCOV_EXCL_START */
1341 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1342 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1343 goto alloc_surf_fail;
1344 /* LCOV_EXCL_STOP */
1347 surf->magic = TBM_SURFACE_MAGIC;
1348 surf->bufmgr = bufmgr;
1349 surf->info.width = info->width;
1350 surf->info.height = info->height;
1351 surf->info.format = info->format;
1353 surf->info.bpp = info->bpp;
1355 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1356 if (!surf->info.bpp) {
1357 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1361 surf->info.num_planes = info->num_planes;
1364 /* get size, stride and offset */
1365 for (i = 0; i < info->num_planes; i++) {
1366 surf->info.planes[i].offset = info->planes[i].offset;
1367 surf->info.planes[i].stride = info->planes[i].stride;
1369 if (info->planes[i].size > 0)
1370 surf->info.planes[i].size = info->planes[i].size;
1372 uint32_t size = 0, offset = 0, stride = 0;
1375 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1376 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1377 goto plane_data_fail;
1379 surf->info.planes[i].size = size;
1383 surf->planes_bo_idx[i] = 0;
1385 surf->planes_bo_idx[i] = i;
1388 if (info->size > 0) {
1389 surf->info.size = info->size;
1391 surf->info.size = 0;
1392 for (i = 0; i < info->num_planes; i++)
1393 surf->info.size += surf->info.planes[i].size;
1396 surf->flags = TBM_BO_DEFAULT;
1398 /* create only one bo */
1399 surf->num_bos = num;
1400 for (i = 0; i < num; i++) {
1401 if (bos[i] == NULL) {
1402 TBM_ERR("bos[%d] is null.\n", i);
1403 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1407 surf->bos[i] = tbm_bo_ref(bos[i]);
1408 _tbm_bo_set_surface(bos[i], surf);
1411 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1412 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1414 LIST_INITHEAD(&surf->user_data_list);
1415 LIST_INITHEAD(&surf->debug_data_list);
1416 LIST_INITHEAD(&surf->destroy_funcs);
1418 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1420 _tbm_surface_mutex_unlock();
1424 /* LCOV_EXCL_START */
1428 for (i = 0; i < num; i++) {
1430 tbm_bo_unref(surf->bos[i]);
1435 if (bufmgr_initialized && bufmgr) {
1436 LIST_DELINIT(&bufmgr->surf_list);
1437 _deinit_surface_bufmgr();
1439 _tbm_surface_mutex_unlock();
1441 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1442 info->width, info->height,
1443 _tbm_surface_internal_format_to_str(info->format), num);
1444 /* LCOV_EXCL_STOP */
1450 tbm_surface_internal_destroy(tbm_surface_h surface)
1452 _tbm_surface_mutex_lock();
1453 _tbm_set_last_result(TBM_ERROR_NONE);
1455 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1459 if (surface->refcnt > 0) {
1460 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1461 _tbm_surface_mutex_unlock();
1465 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1467 if (surface->refcnt == 0)
1468 _tbm_surface_internal_destroy(surface);
1469 else // if (surface->refcnt < 0)
1470 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1472 _tbm_surface_mutex_unlock();
1476 tbm_surface_internal_ref(tbm_surface_h surface)
1478 _tbm_surface_mutex_lock();
1479 _tbm_set_last_result(TBM_ERROR_NONE);
1481 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1485 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1487 _tbm_surface_mutex_unlock();
1491 tbm_surface_internal_unref(tbm_surface_h surface)
1493 _tbm_surface_mutex_lock();
1494 _tbm_set_last_result(TBM_ERROR_NONE);
1496 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1500 if (surface->refcnt > 0) {
1501 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1502 _tbm_surface_mutex_unlock();
1506 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1508 if (surface->refcnt == 0)
1509 _tbm_surface_internal_destroy(surface);
1511 _tbm_surface_mutex_unlock();
1515 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1517 struct _tbm_surface *surf;
1520 _tbm_surface_mutex_lock();
1521 _tbm_set_last_result(TBM_ERROR_NONE);
1523 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1525 surf = (struct _tbm_surface *)surface;
1526 num = surf->num_bos;
1529 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1531 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1533 _tbm_surface_mutex_unlock();
1539 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1541 struct _tbm_surface *surf;
1544 _tbm_surface_mutex_lock();
1545 _tbm_set_last_result(TBM_ERROR_NONE);
1547 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1548 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1550 surf = (struct _tbm_surface *)surface;
1551 bo = surf->bos[bo_idx];
1553 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1555 _tbm_surface_mutex_unlock();
1561 tbm_surface_internal_get_size(tbm_surface_h surface)
1563 struct _tbm_surface *surf;
1566 _tbm_surface_mutex_lock();
1567 _tbm_set_last_result(TBM_ERROR_NONE);
1569 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1571 surf = (struct _tbm_surface *)surface;
1572 size = surf->info.size;
1574 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1576 _tbm_surface_mutex_unlock();
1582 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1583 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1585 struct _tbm_surface *surf;
1587 _tbm_surface_mutex_lock();
1588 _tbm_set_last_result(TBM_ERROR_NONE);
1590 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1591 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1593 surf = (struct _tbm_surface *)surface;
1595 if (plane_idx >= surf->info.num_planes) {
1596 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1597 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1598 _tbm_surface_mutex_unlock();
1603 *size = surf->info.planes[plane_idx].size;
1606 *offset = surf->info.planes[plane_idx].offset;
1609 *pitch = surf->info.planes[plane_idx].stride;
1611 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1612 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1613 surf->info.planes[plane_idx].stride);
1615 _tbm_surface_mutex_unlock();
1621 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1622 tbm_surface_info_s *info, int map)
1624 struct _tbm_surface *surf;
1625 tbm_bo_handle bo_handles[4];
1628 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1631 _tbm_surface_mutex_lock();
1632 _tbm_set_last_result(TBM_ERROR_NONE);
1634 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1636 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1638 surf = (struct _tbm_surface *)surface;
1640 memset(info, 0x00, sizeof(tbm_surface_info_s));
1641 info->width = surf->info.width;
1642 info->height = surf->info.height;
1643 info->format = surf->info.format;
1644 info->bpp = surf->info.bpp;
1645 info->size = surf->info.size;
1646 info->num_planes = surf->info.num_planes;
1648 for (i = 0; i < surf->info.num_planes; i++) {
1649 info->planes[i].size = surf->info.planes[i].size;
1650 info->planes[i].offset = surf->info.planes[i].offset;
1651 info->planes[i].stride = surf->info.planes[i].stride;
1652 planes_bo_idx[i] = surf->planes_bo_idx[i];
1655 for (i = 0; i < surf->num_bos; i++)
1656 bos[i] = surf->bos[i];
1658 num_bos = surf->num_bos;
1661 _tbm_surface_mutex_unlock();
1662 for (i = 0; i < num_bos; i++) {
1663 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1664 if (bo_handles[i].ptr == NULL) {
1665 for (j = 0; j < i; j++)
1666 tbm_bo_unmap(bos[j]);
1668 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1672 _tbm_surface_mutex_lock();
1674 for (i = 0; i < num_bos; i++) {
1675 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1676 if (bo_handles[i].ptr == NULL) {
1677 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1678 _tbm_surface_mutex_unlock();
1684 for (i = 0; i < info->num_planes; i++) {
1685 if (bo_handles[planes_bo_idx[i]].ptr)
1686 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1689 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1691 _tbm_surface_mutex_unlock();
1697 tbm_surface_internal_unmap(tbm_surface_h surface)
1699 struct _tbm_surface *surf;
1702 _tbm_surface_mutex_lock();
1703 _tbm_set_last_result(TBM_ERROR_NONE);
1705 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1707 surf = (struct _tbm_surface *)surface;
1709 for (i = 0; i < surf->num_bos; i++)
1710 tbm_bo_unmap(surf->bos[i]);
1712 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1714 _tbm_surface_mutex_unlock();
1718 tbm_surface_internal_get_width(tbm_surface_h surface)
1720 struct _tbm_surface *surf;
1723 _tbm_surface_mutex_lock();
1724 _tbm_set_last_result(TBM_ERROR_NONE);
1726 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1728 surf = (struct _tbm_surface *)surface;
1729 width = surf->info.width;
1731 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1733 _tbm_surface_mutex_unlock();
1739 tbm_surface_internal_get_height(tbm_surface_h surface)
1741 struct _tbm_surface *surf;
1742 unsigned int height;
1744 _tbm_surface_mutex_lock();
1745 _tbm_set_last_result(TBM_ERROR_NONE);
1747 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1749 surf = (struct _tbm_surface *)surface;
1750 height = surf->info.height;
1752 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1754 _tbm_surface_mutex_unlock();
1761 tbm_surface_internal_get_format(tbm_surface_h surface)
1763 struct _tbm_surface *surf;
1766 _tbm_surface_mutex_lock();
1767 _tbm_set_last_result(TBM_ERROR_NONE);
1769 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1771 surf = (struct _tbm_surface *)surface;
1772 format = surf->info.format;
1774 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1776 _tbm_surface_mutex_unlock();
1782 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1784 struct _tbm_surface *surf;
1787 _tbm_surface_mutex_lock();
1788 _tbm_set_last_result(TBM_ERROR_NONE);
1790 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1791 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1793 surf = (struct _tbm_surface *)surface;
1794 bo_idx = surf->planes_bo_idx[plane_idx];
1796 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1798 _tbm_surface_mutex_unlock();
1804 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1805 tbm_data_free data_free_func)
1807 tbm_user_data *data;
1809 _tbm_surface_mutex_lock();
1810 _tbm_set_last_result(TBM_ERROR_NONE);
1812 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1814 /* check if the data according to the key exist if so, return false. */
1815 data = user_data_lookup(&surface->user_data_list, key);
1817 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1818 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1819 _tbm_surface_mutex_unlock();
1823 data = user_data_create(key, data_free_func);
1825 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1826 _tbm_surface_mutex_unlock();
1830 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1832 LIST_ADD(&data->item_link, &surface->user_data_list);
1834 _tbm_surface_mutex_unlock();
1840 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1843 tbm_user_data *old_data;
1845 _tbm_surface_mutex_lock();
1846 _tbm_set_last_result(TBM_ERROR_NONE);
1848 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1850 old_data = user_data_lookup(&surface->user_data_list, key);
1852 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1853 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1854 _tbm_surface_mutex_unlock();
1858 if (old_data->data && old_data->free_func)
1859 old_data->free_func(old_data->data);
1861 old_data->data = data;
1863 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1865 _tbm_surface_mutex_unlock();
1871 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1874 tbm_user_data *old_data;
1876 _tbm_surface_mutex_lock();
1877 _tbm_set_last_result(TBM_ERROR_NONE);
1879 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1882 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1883 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1884 _tbm_surface_mutex_unlock();
1889 old_data = user_data_lookup(&surface->user_data_list, key);
1891 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1892 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1893 _tbm_surface_mutex_unlock();
1897 *data = old_data->data;
1899 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1901 _tbm_surface_mutex_unlock();
1907 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1910 tbm_user_data *old_data = (void *)0;
1912 _tbm_surface_mutex_lock();
1913 _tbm_set_last_result(TBM_ERROR_NONE);
1915 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1917 old_data = user_data_lookup(&surface->user_data_list, key);
1919 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1920 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1921 _tbm_surface_mutex_unlock();
1925 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1927 user_data_delete(old_data);
1929 _tbm_surface_mutex_unlock();
1934 /* LCOV_EXCL_START */
1936 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1938 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1940 return surface->debug_pid;
1944 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1946 _tbm_surface_mutex_lock();
1947 _tbm_set_last_result(TBM_ERROR_NONE);
1949 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1951 surface->debug_pid = pid;
1953 _tbm_surface_mutex_unlock();
1956 static tbm_surface_debug_data *
1957 _tbm_surface_internal_debug_data_create(char *key, char *value)
1959 tbm_surface_debug_data *debug_data = NULL;
1961 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1963 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1964 TBM_ERR("fail to allocate the debug_data.");
1968 if (key) debug_data->key = strdup(key);
1969 if (value) debug_data->value = strdup(value);
1975 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1977 if (!debug_data->value && !value)
1980 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1983 if (debug_data->value)
1984 free(debug_data->value);
1987 debug_data->value = strdup(value);
1989 debug_data->value = NULL;
1992 static tbm_surface_debug_data *
1993 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1995 tbm_surface_debug_data *debug_data = NULL;
1997 if (LIST_IS_EMPTY(list))
2000 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
2001 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
2009 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
2011 tbm_surface_debug_data *debug_data = NULL;
2012 tbm_bufmgr bufmgr = NULL;
2014 _tbm_surface_mutex_lock();
2015 _tbm_set_last_result(TBM_ERROR_NONE);
2017 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2018 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
2020 bufmgr = surface->bufmgr;
2022 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
2024 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
2026 _tbm_surface_internal_debug_data_value_update(debug_data, value);
2028 debug_data = _tbm_surface_internal_debug_data_create(key, value);
2030 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
2031 _tbm_surface_mutex_unlock();
2035 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
2038 /* add new debug key to list */
2039 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
2041 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
2043 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
2046 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
2048 _tbm_surface_mutex_unlock();
2054 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
2056 tbm_surface_debug_data *old_data = NULL;
2058 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
2060 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
2061 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
2062 if (!strcmp(old_data->key, key))
2063 return old_data->value;
2070 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
2071 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
2073 struct _tbm_surface_dump_buf_info {
2083 tbm_surface_info_s info;
2085 struct list_head link;
2088 struct _tbm_surface_dump_info {
2089 char *path; // copy???
2092 struct list_head *link;
2093 struct list_head surface_list; /* link of surface */
2096 static tbm_surface_dump_info *g_dump_info = NULL;
2097 static const char *dump_postfix[2] = {"png", "yuv"};
2098 static double scale_factor;
2101 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
2102 void *data2, int size2, void *data3, int size3)
2105 unsigned int *blocks;
2107 if (_tbm_surface_check_file_is_symbolic_link(file))
2108 TBM_ERR("%s is symbolic link\n", file);
2110 fp = fopen(file, "w+");
2111 TBM_RETURN_IF_FAIL(fp != NULL);
2113 blocks = (unsigned int *)data1;
2114 fwrite(blocks, 1, size1, fp);
2117 blocks = (unsigned int *)data2;
2118 fwrite(blocks, 1, size2, fp);
2122 blocks = (unsigned int *)data3;
2123 fwrite(blocks, 1, size3, fp);
2130 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
2132 unsigned int *blocks = (unsigned int *)data;
2135 png_bytep *row_pointers;
2138 if (_tbm_surface_check_file_is_symbolic_link(file))
2139 TBM_ERR("%s is symbolic link\n", file);
2141 fp = fopen(file, "wb");
2142 TBM_RETURN_IF_FAIL(fp != NULL);
2144 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
2147 TBM_ERR("fail to create a png write structure.\n");
2152 png_infop pPngInfo = png_create_info_struct(pPngStruct);
2154 TBM_ERR("fail to create a png info structure.\n");
2155 png_destroy_write_struct(&pPngStruct, NULL);
2160 if (setjmp(png_jmpbuf(pPngStruct))) {
2161 /* if png has problem of writing the file, we get here */
2162 TBM_ERR("fail to write png file.\n");
2163 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2168 png_init_io(pPngStruct, fp);
2169 if (format == TBM_FORMAT_XRGB8888) {
2171 png_set_IHDR(pPngStruct,
2178 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2181 png_set_IHDR(pPngStruct,
2186 PNG_COLOR_TYPE_RGBA,
2188 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2191 png_set_bgr(pPngStruct);
2192 png_write_info(pPngStruct, pPngInfo);
2194 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
2195 if (!row_pointers) {
2196 TBM_ERR("fail to allocate the png row_pointers.\n");
2197 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2202 for (y = 0; y < height; ++y) {
2206 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
2208 TBM_ERR("fail to allocate the png row.\n");
2209 for (x = 0; x < y; x++)
2210 png_free(pPngStruct, row_pointers[x]);
2211 png_free(pPngStruct, row_pointers);
2212 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2216 row_pointers[y] = (png_bytep)row;
2218 for (x = 0; x < width; ++x) {
2219 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
2221 if (pixel_size == 3) { // XRGB8888
2222 row[x * pixel_size] = (curBlock & 0xFF);
2223 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2224 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2225 } else { // ARGB8888
2226 row[x * pixel_size] = (curBlock & 0xFF);
2227 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2228 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2229 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2234 png_write_image(pPngStruct, row_pointers);
2235 png_write_end(pPngStruct, pPngInfo);
2237 for (y = 0; y < height; y++)
2238 png_free(pPngStruct, row_pointers[y]);
2239 png_free(pPngStruct, row_pointers);
2241 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2247 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2249 TBM_RETURN_IF_FAIL(path != NULL);
2250 TBM_RETURN_IF_FAIL(w > 0);
2251 TBM_RETURN_IF_FAIL(h > 0);
2252 TBM_RETURN_IF_FAIL(count > 0);
2254 tbm_surface_dump_buf_info *buf_info = NULL;
2255 tbm_surface_h tbm_surface;
2256 tbm_surface_info_s info;
2261 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2265 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2266 TBM_RETURN_IF_FAIL(g_dump_info);
2268 LIST_INITHEAD(&g_dump_info->surface_list);
2269 g_dump_info->count = 0;
2270 g_dump_info->dump_max = count;
2272 /* get buffer size */
2273 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2274 if (tbm_surface == NULL) {
2275 TBM_ERR("tbm_surface_create fail\n");
2281 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2282 TBM_ERR("tbm_surface_get_info fail\n");
2283 tbm_surface_destroy(tbm_surface);
2288 buffer_size = info.size;
2289 tbm_surface_destroy(tbm_surface);
2291 /* create dump lists */
2292 for (i = 0; i < count; i++) {
2295 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2296 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2298 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2300 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2305 buf_info->index = i;
2307 buf_info->size = buffer_size;
2309 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2312 g_dump_info->path = path;
2313 g_dump_info->link = &g_dump_info->surface_list;
2317 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2322 /* free resources */
2323 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2324 tbm_surface_dump_buf_info *tmp;
2326 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2327 tbm_bo_unref(buf_info->bo);
2328 LIST_DEL(&buf_info->link);
2333 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2342 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2349 tbm_surface_internal_dump_start(path, w, h, count);
2350 scale_factor = scale;
2354 tbm_surface_internal_dump_end(void)
2356 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2357 tbm_bo_handle bo_handle;
2362 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2369 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2372 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2373 if (bo_handle.ptr == NULL) {
2374 tbm_bo_unref(buf_info->bo);
2375 LIST_DEL(&buf_info->link);
2380 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2381 TBM_INFO("Dump File.. %s generated.\n", file);
2383 if (buf_info->dirty) {
2384 void *ptr1 = NULL, *ptr2 = NULL;
2386 switch (buf_info->info.format) {
2387 case TBM_FORMAT_ARGB8888:
2388 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2389 buf_info->info.planes[0].stride >> 2,
2390 buf_info->info.height,
2391 buf_info->info.planes[0].stride,
2392 TBM_FORMAT_ARGB8888);
2394 case TBM_FORMAT_XRGB8888:
2395 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2396 buf_info->info.planes[0].stride >> 2,
2397 buf_info->info.height,
2398 buf_info->info.planes[0].stride,
2399 TBM_FORMAT_XRGB8888);
2401 case TBM_FORMAT_YVU420:
2402 case TBM_FORMAT_YUV420:
2403 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2404 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2405 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2406 buf_info->info.planes[0].stride * buf_info->info.height,
2408 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2410 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2412 case TBM_FORMAT_NV12:
2413 case TBM_FORMAT_NV21:
2414 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2415 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2416 buf_info->info.planes[0].stride * buf_info->info.height,
2418 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2421 case TBM_FORMAT_YUYV:
2422 case TBM_FORMAT_UYVY:
2423 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2424 buf_info->info.planes[0].stride * buf_info->info.height,
2428 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2431 } else if (buf_info->dirty_shm)
2432 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2433 buf_info->shm_stride >> 2,
2435 buf_info->shm_stride, 0);
2437 tbm_bo_unmap(buf_info->bo);
2438 tbm_bo_unref(buf_info->bo);
2439 LIST_DEL(&buf_info->link);
2446 TBM_INFO("Dump End..\n");
2449 static pixman_format_code_t
2450 _tbm_surface_internal_pixman_format_get(tbm_format format)
2453 case TBM_FORMAT_ARGB8888:
2454 return PIXMAN_a8r8g8b8;
2455 case TBM_FORMAT_XRGB8888:
2456 return PIXMAN_x8r8g8b8;
2465 * This function supports only if a buffer has below formats.
2466 * - TBM_FORMAT_ARGB8888
2467 * - TBM_FORMAT_XRGB8888
2469 static tbm_surface_error_e
2470 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2471 int format, int src_stride, int src_w, int src_h,
2472 int dst_stride, int dst_w, int dst_h)
2474 pixman_image_t *src_img = NULL, *dst_img = NULL;
2475 pixman_format_code_t pixman_format;
2476 pixman_transform_t t;
2477 struct pixman_f_transform ft;
2478 double scale_x, scale_y;
2480 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2481 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2483 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2484 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2487 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2488 (uint32_t*)src_ptr, src_stride);
2489 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2492 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2493 (uint32_t*)dst_ptr, dst_stride);
2494 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2496 pixman_f_transform_init_identity(&ft);
2498 scale_x = (double)src_w / dst_w;
2499 scale_y = (double)src_h / dst_h;
2501 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2502 pixman_f_transform_translate(&ft, NULL, 0, 0);
2503 pixman_transform_from_pixman_f_transform(&t, &ft);
2504 pixman_image_set_transform(src_img, &t);
2506 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2507 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2509 pixman_image_unref(src_img);
2510 pixman_image_unref(dst_img);
2512 return TBM_SURFACE_ERROR_NONE;
2516 pixman_image_unref(src_img);
2518 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2521 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2522 #define KEY_LEN 5 // "_XXXX"
2523 #define KEYS_LEN KEY_LEN * MAX_BOS
2525 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2527 char *keys, temp_key[KEY_LEN + 1];
2528 struct _tbm_surface *surf;
2532 _tbm_surface_mutex_lock();
2534 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2536 surf = (struct _tbm_surface *)surface;
2538 num_bos = surf->num_bos;
2539 if (num_bos > MAX_BOS)
2542 keys = calloc(KEYS_LEN + 1, sizeof(char));
2544 TBM_ERR("Failed to alloc memory");
2545 _tbm_surface_mutex_unlock();
2549 for (i = 0; i < num_bos; i++) {
2550 memset(temp_key, 0x00, KEY_LEN + 1);
2552 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2553 strncat(keys, temp_key, KEY_LEN + 1);
2556 _tbm_surface_mutex_unlock();
2561 static void _tbm_surface_internal_put_keys(char *keys)
2568 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2570 TBM_RETURN_IF_FAIL(surface != NULL);
2571 TBM_RETURN_IF_FAIL(type != NULL);
2573 tbm_surface_dump_buf_info *buf_info;
2574 struct list_head *next_link;
2575 tbm_surface_info_s info;
2576 tbm_bo_handle bo_handle;
2577 const char *postfix;
2578 const char *format = NULL;
2585 next_link = g_dump_info->link->next;
2586 TBM_RETURN_IF_FAIL(next_link != NULL);
2588 if (next_link == &g_dump_info->surface_list) {
2589 next_link = next_link->next;
2590 TBM_RETURN_IF_FAIL(next_link != NULL);
2593 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2594 TBM_RETURN_IF_FAIL(buf_info != NULL);
2596 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2597 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2599 if (scale_factor > 0.0) {
2602 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2603 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2604 _tbm_surface_internal_format_to_str(info.format));
2605 tbm_surface_unmap(surface);
2609 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2611 buf_info->info.width = info.width * scale_factor;
2612 buf_info->info.height = info.height * scale_factor;
2613 buf_info->info.format = info.format;
2614 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2615 if (!buf_info->info.bpp) {
2616 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2617 tbm_surface_unmap(surface);
2620 buf_info->info.num_planes = 1;
2621 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2622 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2624 if (buf_info->info.size > buf_info->size) {
2625 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2626 buf_info->info.size, buf_info->size);
2627 tbm_surface_unmap(surface);
2631 if (info.size > buf_info->size) {
2632 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2633 info.size, buf_info->size);
2634 tbm_surface_unmap(surface);
2638 /* make the file information */
2639 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2642 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2643 postfix = dump_postfix[0];
2644 format = _tbm_surface_internal_format_to_str(info.format);
2646 postfix = dump_postfix[1];
2648 keys = _tbm_surface_internal_get_keys(surface);
2650 TBM_ERR("fail to get keys");
2651 tbm_surface_unmap(surface);
2656 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2657 if (!bo_handle.ptr) {
2658 TBM_ERR("fail to map bo");
2659 _tbm_surface_internal_put_keys(keys);
2660 tbm_surface_unmap(surface);
2663 memset(bo_handle.ptr, 0x00, buf_info->size);
2665 switch (info.format) {
2666 case TBM_FORMAT_ARGB8888:
2667 case TBM_FORMAT_XRGB8888:
2668 snprintf(buf_info->name, sizeof(buf_info->name),
2669 "%10.3f_%03d%s_%p_%s-%s.%s",
2670 _tbm_surface_internal_get_time(),
2671 g_dump_info->count++, keys, surface, format, type, postfix);
2673 if (scale_factor > 0.0) {
2674 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2676 buf_info->info.format,
2677 info.planes[0].stride,
2678 info.width, info.height,
2679 buf_info->info.planes[0].stride,
2680 buf_info->info.width,
2681 buf_info->info.height);
2682 if (ret != TBM_SURFACE_ERROR_NONE) {
2683 TBM_ERR("fail to scale buffer");
2684 tbm_bo_unmap(buf_info->bo);
2685 _tbm_surface_internal_put_keys(keys);
2686 tbm_surface_unmap(surface);
2690 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2692 case TBM_FORMAT_YVU420:
2693 case TBM_FORMAT_YUV420:
2694 snprintf(buf_info->name, sizeof(buf_info->name),
2695 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2696 _tbm_surface_internal_get_time(),
2697 g_dump_info->count++, keys, type, info.planes[0].stride,
2698 info.height, FOURCC_STR(info.format), postfix);
2699 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2700 bo_handle.ptr += info.planes[0].stride * info.height;
2701 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2702 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2703 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2705 case TBM_FORMAT_NV12:
2706 case TBM_FORMAT_NV21:
2707 snprintf(buf_info->name, sizeof(buf_info->name),
2708 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2709 _tbm_surface_internal_get_time(),
2710 g_dump_info->count++, keys, type, info.planes[0].stride,
2711 info.height, FOURCC_STR(info.format), postfix);
2712 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2713 bo_handle.ptr += info.planes[0].stride * info.height;
2714 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2716 case TBM_FORMAT_YUYV:
2717 case TBM_FORMAT_UYVY:
2718 snprintf(buf_info->name, sizeof(buf_info->name),
2719 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2720 _tbm_surface_internal_get_time(),
2721 g_dump_info->count++, keys, type, info.planes[0].stride,
2722 info.height, FOURCC_STR(info.format), postfix);
2723 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2726 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2727 tbm_bo_unmap(buf_info->bo);
2728 _tbm_surface_internal_put_keys(keys);
2729 tbm_surface_unmap(surface);
2733 tbm_bo_unmap(buf_info->bo);
2735 _tbm_surface_internal_put_keys(keys);
2737 tbm_surface_unmap(surface);
2739 buf_info->dirty = 1;
2740 buf_info->dirty_shm = 0;
2742 if (g_dump_info->count == 1000)
2743 g_dump_info->count = 0;
2745 g_dump_info->link = next_link;
2747 TBM_INFO("Dump %s \n", buf_info->name);
2750 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2753 TBM_RETURN_IF_FAIL(ptr != NULL);
2754 TBM_RETURN_IF_FAIL(w > 0);
2755 TBM_RETURN_IF_FAIL(h > 0);
2756 TBM_RETURN_IF_FAIL(stride > 0);
2757 TBM_RETURN_IF_FAIL(type != NULL);
2759 tbm_surface_dump_buf_info *buf_info;
2760 struct list_head *next_link;
2761 tbm_bo_handle bo_handle;
2762 int ret, size, dw = 0, dh = 0, dstride = 0;
2767 next_link = g_dump_info->link->next;
2768 TBM_RETURN_IF_FAIL(next_link != NULL);
2770 if (next_link == &g_dump_info->surface_list) {
2771 next_link = next_link->next;
2772 TBM_RETURN_IF_FAIL(next_link != NULL);
2775 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2776 TBM_RETURN_IF_FAIL(buf_info != NULL);
2778 if (scale_factor > 0.0) {
2781 dw = w * scale_factor;
2782 dh = h * scale_factor;
2784 size = dstride * dh;
2788 if (size > buf_info->size) {
2789 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2790 size, buf_info->size);
2795 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2796 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2798 memset(bo_handle.ptr, 0x00, buf_info->size);
2799 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2801 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2802 _tbm_surface_internal_get_time(),
2803 g_dump_info->count++, type, dump_postfix[0]);
2804 if (scale_factor > 0.0) {
2805 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2806 TBM_FORMAT_ARGB8888, stride,
2807 w, h, dstride, dw, dh);
2808 if (ret != TBM_SURFACE_ERROR_NONE) {
2809 TBM_ERR("fail to scale buffer");
2810 tbm_bo_unmap(buf_info->bo);
2813 buf_info->shm_stride = dstride;
2814 buf_info->shm_h = dh;
2816 memcpy(bo_handle.ptr, ptr, size);
2817 buf_info->shm_stride = stride;
2818 buf_info->shm_h = h;
2821 tbm_bo_unmap(buf_info->bo);
2823 buf_info->dirty = 0;
2824 buf_info->dirty_shm = 1;
2826 if (g_dump_info->count == 1000)
2827 g_dump_info->count = 0;
2829 g_dump_info->link = next_link;
2831 TBM_INFO("Dump %s \n", buf_info->name);
2835 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2837 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2838 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2839 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2841 tbm_surface_info_s info;
2842 const char *postfix;
2846 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2847 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2849 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2850 postfix = dump_postfix[0];
2852 postfix = dump_postfix[1];
2854 if (strcmp(postfix, type)) {
2855 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2856 tbm_surface_unmap(surface);
2860 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2862 if (!access(file, 0)) {
2863 TBM_ERR("can't capture buffer, exist file %s", file);
2864 tbm_surface_unmap(surface);
2868 switch (info.format) {
2869 case TBM_FORMAT_ARGB8888:
2870 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2873 info.planes[0].stride,
2874 TBM_FORMAT_ARGB8888);
2876 case TBM_FORMAT_XRGB8888:
2877 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2880 info.planes[0].stride,
2881 TBM_FORMAT_XRGB8888);
2883 case TBM_FORMAT_YVU420:
2884 case TBM_FORMAT_YUV420:
2885 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2886 info.planes[0].stride * info.height,
2888 info.planes[1].stride * (info.height >> 1),
2890 info.planes[2].stride * (info.height >> 1));
2892 case TBM_FORMAT_NV12:
2893 case TBM_FORMAT_NV21:
2894 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2895 info.planes[0].stride * info.height,
2897 info.planes[1].stride * (info.height >> 1),
2900 case TBM_FORMAT_YUYV:
2901 case TBM_FORMAT_UYVY:
2902 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2903 info.planes[0].stride * info.height,
2907 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2908 tbm_surface_unmap(surface);
2912 tbm_surface_unmap(surface);
2914 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2920 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2921 const char *path, const char *name, const char *type)
2923 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2924 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2925 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2926 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2927 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2928 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2932 if (strcmp(dump_postfix[0], type)) {
2933 TBM_ERR("Not supported type:%s'", type);
2937 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2939 if (!access(file, 0)) {
2940 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2944 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2946 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2952 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2954 struct _tbm_surface *surf;
2956 _tbm_surface_mutex_lock();
2957 _tbm_set_last_result(TBM_ERROR_NONE);
2959 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2960 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2961 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2963 surf = (struct _tbm_surface *)surface;
2967 surf->damage.width = width;
2968 surf->damage.height = height;
2970 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2971 surface, x, y, width, height);
2973 _tbm_surface_mutex_unlock();
2979 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2981 struct _tbm_surface *surf;
2983 _tbm_surface_mutex_lock();
2984 _tbm_set_last_result(TBM_ERROR_NONE);
2986 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2988 surf = (struct _tbm_surface *)surface;
2990 if (x) *x = surf->damage.x;
2991 if (y) *y = surf->damage.y;
2992 if (width) *width = surf->damage.width;
2993 if (height) *height = surf->damage.height;
2995 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2996 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2998 _tbm_surface_mutex_unlock();
3004 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
3006 struct _tbm_surface *surf;
3007 tbm_surface_destroy_func_info *func_info = NULL;
3009 _tbm_surface_mutex_lock();
3010 _tbm_set_last_result(TBM_ERROR_NONE);
3012 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
3013 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
3015 surf = (struct _tbm_surface *)surface;
3016 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
3017 if (func_info->destroy_func == func && func_info->user_data == user_data) {
3018 TBM_ERR("can't add twice");
3019 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
3020 _tbm_surface_mutex_unlock();
3025 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
3026 if (func_info == NULL) {
3027 TBM_ERR("alloc failed");
3028 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
3029 _tbm_surface_mutex_unlock();
3033 func_info->destroy_func = func;
3034 func_info->user_data = user_data;
3036 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
3038 _tbm_surface_mutex_unlock();
3044 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
3046 struct _tbm_surface *surf;
3047 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
3049 _tbm_surface_mutex_lock();
3050 _tbm_set_last_result(TBM_ERROR_NONE);
3052 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
3053 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
3055 surf = (struct _tbm_surface *)surface;
3056 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
3057 if (func_info->destroy_func != func || func_info->user_data != user_data)
3060 LIST_DEL(&func_info->item_link);
3063 _tbm_surface_mutex_unlock();
3068 _tbm_surface_mutex_unlock();
3071 tbm_surface_buffer_data *
3072 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
3074 tbm_surface_buffer_data *buffer_data = NULL;
3075 struct _tbm_surface *surf;
3076 struct _tbm_bufmgr *bufmgr;
3078 _tbm_surface_mutex_lock();
3080 surf = (struct _tbm_surface *)surface;
3081 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3083 bufmgr = surf->bufmgr;
3084 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3086 // this function supports when it comes to be use_hal.
3087 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
3090 buffer_data = (tbm_surface_buffer_data *)hal_tbm_surface_export((hal_tbm_surface *)surf->hal_surface,
3091 (hal_tbm_error *)error);
3092 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
3094 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
3097 *error = TBM_ERROR_NONE;
3099 _tbm_set_last_result(TBM_ERROR_NONE);
3100 _tbm_surface_mutex_unlock();
3106 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
3108 struct _tbm_surface *surf;
3109 struct _tbm_bufmgr *bufmgr;
3111 _tbm_surface_mutex_lock();
3113 bufmgr = g_surface_bufmgr;
3114 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3116 // this function supports when it comes to be use_hal.
3117 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
3119 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3120 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3121 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3122 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3125 surf = _tbm_surface_internal_hal_tbm_import_surface(bufmgr,
3126 (int)surface_info->width,
3127 (int)surface_info->height,
3128 (int)surface_info->format,
3131 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
3133 LIST_INITHEAD(&surf->user_data_list);
3134 LIST_INITHEAD(&surf->debug_data_list);
3135 LIST_INITHEAD(&surf->destroy_funcs);
3137 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
3139 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
3142 *error = TBM_ERROR_NONE;
3144 _tbm_set_last_result(TBM_ERROR_NONE);
3145 _tbm_surface_mutex_unlock();
3147 return (tbm_surface_h)surf;