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 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp/8, flags, error);
708 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
710 TBM_ERR("fail to alloc bo idx:%d\n", i);
711 *error = tbm_get_last_error();
716 _tbm_bo_set_surface(surf->bos[i], surf);
719 *error = TBM_ERROR_NONE;
724 for (j = 0; j < i; j++) {
726 tbm_bo_unref(surf->bos[j]);
728 query_plane_data_fail:
737 static struct _tbm_surface *
738 _tbm_surface_internal_hal_tbm_create_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, tbm_error_e *error)
740 struct _tbm_surface *surf = NULL;
741 uint32_t size = 0, offset = 0, stride = 0, bo_size = 0;
743 hal_tbm_surface *hal_surface = NULL;
744 hal_tbm_bo **hal_bos = NULL;
747 surf = calloc(1, sizeof(struct _tbm_surface));
749 /* LCOV_EXCL_START */
750 TBM_ERR("fail to alloc surf");
751 *error = TBM_ERROR_OUT_OF_MEMORY;
752 goto alloc_surf_fail;
757 surf->magic = TBM_SURFACE_MAGIC;
758 surf->bufmgr = bufmgr;
759 surf->info.width = width;
760 surf->info.height = height;
761 surf->info.format = format;
762 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
763 if (!surf->info.bpp) {
764 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
765 *error = tbm_get_last_error();
770 // get number of planes
771 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
772 if (!surf->info.num_planes) {
773 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
774 *error = tbm_get_last_error();
775 goto num_planes_fail;
778 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);
781 surf->hal_surface = hal_surface;
783 // set infomation of planes
784 for (i = 0; i < surf->info.num_planes; i++) {
785 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
786 if (*error != TBM_ERROR_NONE) {
787 goto query_plane_data_fail;
789 surf->info.planes[i].size = size;
790 surf->info.planes[i].offset = offset;
791 surf->info.planes[i].stride = stride;
792 surf->planes_bo_idx[i] = bo_idx;
795 // set infomation of bos
796 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
798 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
801 surf->num_bos = num_bos;
803 for (i = 0; i < surf->info.num_planes; i++) {
804 surf->info.size += surf->info.planes[i].size;
806 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
807 surf->num_bos = surf->planes_bo_idx[i] + 1;
810 for (i = 0; i < num_bos; i++) {
811 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
813 TBM_ERR("fail to alloc bo idx:%d", i);
814 *error = tbm_get_last_error();
818 _tbm_bo_set_surface(surf->bos[i], surf);
821 // set infomation of planes
822 for (i = 0; i < surf->info.num_planes; i++) {
823 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
824 TBM_ERR("fail to query plane data");
825 *error = tbm_get_last_error();
826 goto query_plane_data_fail;
828 surf->info.planes[i].size = size;
829 surf->info.planes[i].offset = offset;
830 surf->info.planes[i].stride = stride;
831 surf->planes_bo_idx[i] = bo_idx;
834 // count number of bos
836 for (i = 0; i < surf->info.num_planes; i++) {
837 surf->info.size += surf->info.planes[i].size;
839 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
840 surf->num_bos = surf->planes_bo_idx[i] + 1;
843 // set infomation of bos
844 for (i = 0; i < surf->num_bos; i++) {
846 for (j = 0; j < surf->info.num_planes; j++) {
847 if (surf->planes_bo_idx[j] == i)
848 bo_size += surf->info.planes[j].size;
851 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, surf->info.bpp / 8, flags, error);
852 if (*error == TBM_ERROR_NOT_SUPPORTED) {
853 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
855 TBM_ERR("fail to alloc bo idx:%d", i);
856 *error = tbm_get_last_error();
861 _tbm_bo_set_surface(surf->bos[i], surf);
865 *error = TBM_ERROR_NONE;
871 query_plane_data_fail:
873 hal_tbm_surface_free(hal_surface);
875 for (j = 0; j < i; j++) {
877 tbm_bo_unref(surf->bos[j]);
889 static struct _tbm_surface *
890 _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)
892 struct _tbm_surface *surf = NULL;
893 uint32_t size = 0, offset = 0, stride = 0;
895 hal_tbm_surface *hal_surface = NULL;
896 hal_tbm_bo **hal_bos = NULL;
900 surf = calloc(1, sizeof(struct _tbm_surface));
902 /* LCOV_EXCL_START */
903 TBM_ERR("fail to alloc surf");
904 *error = TBM_ERROR_OUT_OF_MEMORY;
905 goto alloc_surf_fail;
910 surf->magic = TBM_SURFACE_MAGIC;
911 surf->bufmgr = bufmgr;
912 surf->info.width = width;
913 surf->info.height = height;
914 surf->info.format = format;
915 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
916 if (!surf->info.bpp) {
917 TBM_ERR("fail to get bpp from format(%d), error(%s)", format, tbm_error_str(*error));
918 *error = tbm_get_last_error();
922 // get number of planes
923 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
924 if (!surf->info.num_planes) {
925 TBM_ERR("fail to get num_planes from format(%d), error(%s)", format, tbm_error_str(*error));
926 *error = tbm_get_last_error();
927 goto num_planes_fail;
931 hal_surface = hal_tbm_bufmgr_import_surface(bufmgr->hal_bufmgr,
934 (hal_tbm_format)format,
935 (hal_tbm_surface_buffer_data *)buffer_data,
936 (hal_tbm_error *)error);
938 TBM_ERR("hal_tbm_bufmgr_import_surface failed.(width:%d height:%d format:%d error:%s)",
939 width, height, format, tbm_error_str(*error));
940 goto import_surface_fail;
942 surf->hal_surface = hal_surface;
944 // set infomation of planes
945 for (i = 0; i < surf->info.num_planes; i++) {
946 *error = (tbm_error_e)hal_tbm_surface_get_plane_data(hal_surface, i, &size, &offset, &stride, &bo_idx);
947 if (*error != TBM_ERROR_NONE) {
948 goto query_plane_data_fail;
950 surf->info.planes[i].size = size;
951 surf->info.planes[i].offset = offset;
952 surf->info.planes[i].stride = stride;
953 surf->planes_bo_idx[i] = bo_idx;
956 // set infomation of bos
957 hal_bos = hal_tbm_surface_get_bos(hal_surface, &num_bos, (hal_tbm_error *)error);
959 TBM_ERR("fail to get bos, error(%s)", tbm_error_str(*error));
962 surf->num_bos = num_bos;
964 for (i = 0; i < surf->info.num_planes; i++) {
965 surf->info.size += surf->info.planes[i].size;
967 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
968 surf->num_bos = surf->planes_bo_idx[i] + 1;
971 // get memory_types(bo flags)
972 flags = (int)hal_tbm_bo_get_memory_types(hal_bos[0], (hal_tbm_error *)error);
973 if (*error != TBM_ERROR_NONE) {
974 TBM_ERR("hal_tbm_bo_get_memory_types failed.");
975 goto get_memory_types_fail;
979 for (i = 0; i < num_bos; i++) {
980 surf->bos[i] = tbm_bo_alloc_with_bo_data(bufmgr, (tbm_backend_bo_data *)hal_bos[i], flags);
982 TBM_ERR("fail to alloc bo idx:%d", i);
983 *error = tbm_get_last_error();
987 _tbm_bo_set_surface(surf->bos[i], surf);
990 *error = TBM_ERROR_NONE;
995 get_memory_types_fail:
997 query_plane_data_fail:
999 hal_tbm_surface_free(hal_surface);
1001 for (j = 0; j < i; j++) {
1003 tbm_bo_unref(surf->bos[j]);
1006 import_surface_fail:
1017 tbm_surface_internal_is_valid(tbm_surface_h surface)
1021 _tbm_surface_mutex_lock();
1022 _tbm_set_last_result(TBM_ERROR_NONE);
1024 /* Return silently if surface is null. */
1026 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1027 _tbm_surface_mutex_unlock();
1031 ret = _tbm_surface_internal_is_valid(surface);
1033 _tbm_surface_mutex_unlock();
1039 tbm_surface_internal_query_supported_formats(uint32_t **formats,
1042 struct _tbm_bufmgr *bufmgr;
1044 bool bufmgr_initialized = false;
1047 _tbm_surface_mutex_lock();
1048 _tbm_set_last_result(TBM_ERROR_NONE);
1050 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
1051 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
1053 if (!g_surface_bufmgr) {
1054 _init_surface_bufmgr();
1055 if (!g_surface_bufmgr) {
1056 TBM_ERR("fail bufmgr initialization\n");
1057 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1060 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1061 bufmgr_initialized = true;
1064 bufmgr = g_surface_bufmgr;
1066 if (bufmgr->use_hal_tbm) {
1067 error = (tbm_error_e)hal_tbm_bufmgr_get_supported_formats(bufmgr->hal_bufmgr, formats, num);
1068 /* LCOV_EXCL_START */
1069 if (error == TBM_ERROR_NOT_SUPPORTED) {
1070 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1072 } else if (error != TBM_ERROR_NONE) {
1073 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1076 /* LCOV_EXCL_STOP */
1078 } else if (bufmgr->backend_module_data) {
1079 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
1080 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1084 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
1085 if (error != TBM_ERROR_NONE) {
1086 /* LCOV_EXCL_START */
1087 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
1089 /* LCOV_EXCL_START */
1093 if (!bufmgr->backend->surface_supported_format) {
1094 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1098 ret = bufmgr->backend->surface_supported_format(formats, num);
1100 /* LCOV_EXCL_START */
1101 TBM_ERR("Fail to surface_supported_format.\n");
1102 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1104 /* LCOV_EXCL_START */
1108 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
1110 if (bufmgr_initialized) {
1111 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1112 _deinit_surface_bufmgr();
1115 _tbm_surface_mutex_unlock();
1119 /* LCOV_EXCL_START */
1121 if (bufmgr_initialized) {
1122 LIST_DELINIT(&g_surface_bufmgr->surf_list);
1123 _deinit_surface_bufmgr();
1125 _tbm_surface_mutex_unlock();
1127 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
1130 /* LCOV_EXCL_STOP */
1134 tbm_surface_internal_get_num_planes(tbm_format format)
1138 _tbm_surface_mutex_lock();
1139 _tbm_set_last_result(TBM_ERROR_NONE);
1141 num_planes = _tbm_surface_internal_get_num_planes(format);
1143 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1144 _tbm_surface_mutex_unlock();
1148 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
1150 _tbm_surface_mutex_unlock();
1156 tbm_surface_internal_get_bpp(tbm_format format)
1160 _tbm_surface_mutex_lock();
1161 _tbm_set_last_result(TBM_ERROR_NONE);
1163 bpp = _tbm_surface_internal_get_bpp(format);
1165 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
1166 _tbm_surface_mutex_unlock();
1170 _tbm_surface_mutex_unlock();
1172 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
1178 tbm_surface_internal_create_with_flags(int width, int height,
1179 int format, int flags)
1181 struct _tbm_bufmgr *bufmgr;
1182 struct _tbm_surface *surf = NULL;
1183 tbm_error_e error = TBM_ERROR_INVALID_OPERATION;
1184 bool bufmgr_initialized = false;
1186 _tbm_surface_mutex_lock();
1187 _tbm_set_last_result(TBM_ERROR_NONE);
1189 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
1190 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
1192 if (!g_surface_bufmgr) {
1193 _init_surface_bufmgr();
1194 if (!g_surface_bufmgr) {
1195 TBM_ERR("fail bufmgr initialization\n");
1196 error = TBM_ERROR_INVALID_OPERATION;
1197 goto check_valid_fail;
1199 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1200 bufmgr_initialized = true;
1203 bufmgr = g_surface_bufmgr;
1204 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1205 TBM_ERR("The bufmgr is invalid\n");
1206 error = TBM_ERROR_INVALID_PARAMETER;
1207 goto check_valid_fail;
1210 if (bufmgr->use_hal_tbm) {
1211 surf = _tbm_surface_internal_hal_tbm_create_surface(bufmgr, width, height, format, flags, &error);
1213 TBM_ERR("_tbm_surface_internal_hal_tbm_create_surface failed.");
1214 goto surface_alloc_fail;
1217 surf = _tbm_surface_internal_create_surface(bufmgr, width, height, format, flags, &error);
1219 TBM_ERR("_tbm_surface_internal_create_surface failed.");
1220 goto surface_alloc_fail;
1224 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n",
1225 width, height, _tbm_surface_internal_format_to_str(format), flags, surf);
1227 LIST_INITHEAD(&surf->user_data_list);
1228 LIST_INITHEAD(&surf->debug_data_list);
1229 LIST_INITHEAD(&surf->destroy_funcs);
1231 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1233 _tbm_set_last_result(error);
1234 _tbm_surface_mutex_unlock();
1238 /* LCOV_EXCL_START */
1242 if (bufmgr_initialized && bufmgr) {
1243 LIST_DELINIT(&bufmgr->surf_list);
1244 _deinit_surface_bufmgr();
1247 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
1248 width, height, _tbm_surface_internal_format_to_str(format), flags);
1250 _tbm_set_last_result(error);
1251 _tbm_surface_mutex_unlock();
1253 /* LCOV_EXCL_STOP */
1259 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
1260 tbm_bo *bos, int num)
1262 struct _tbm_bufmgr *bufmgr;
1263 struct _tbm_surface *surf = NULL;
1265 bool bufmgr_initialized = false;
1267 _tbm_surface_mutex_lock();
1268 _tbm_set_last_result(TBM_ERROR_NONE);
1270 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
1271 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1272 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1273 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1274 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1276 if (!g_surface_bufmgr) {
1277 _init_surface_bufmgr();
1278 if (!g_surface_bufmgr) {
1279 TBM_ERR("fail bufmgr initialization\n");
1280 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1281 goto check_valid_fail;
1283 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1284 bufmgr_initialized = true;
1287 bufmgr = g_surface_bufmgr;
1288 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1289 TBM_ERR("fail to validate the Bufmgr.\n");
1290 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1291 goto check_valid_fail;
1294 surf = calloc(1, sizeof(struct _tbm_surface));
1296 /* LCOV_EXCL_START */
1297 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1298 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1299 goto alloc_surf_fail;
1300 /* LCOV_EXCL_STOP */
1303 surf->magic = TBM_SURFACE_MAGIC;
1304 surf->bufmgr = bufmgr;
1305 surf->info.width = info->width;
1306 surf->info.height = info->height;
1307 surf->info.format = info->format;
1309 surf->info.bpp = info->bpp;
1311 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1312 if (!surf->info.bpp) {
1313 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1317 surf->info.num_planes = info->num_planes;
1320 /* get size, stride and offset */
1321 for (i = 0; i < info->num_planes; i++) {
1322 surf->info.planes[i].offset = info->planes[i].offset;
1323 surf->info.planes[i].stride = info->planes[i].stride;
1325 if (info->planes[i].size > 0)
1326 surf->info.planes[i].size = info->planes[i].size;
1328 uint32_t size = 0, offset = 0, stride = 0;
1331 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1332 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1333 goto plane_data_fail;
1335 surf->info.planes[i].size = size;
1339 surf->planes_bo_idx[i] = 0;
1341 surf->planes_bo_idx[i] = i;
1344 if (info->size > 0) {
1345 surf->info.size = info->size;
1347 surf->info.size = 0;
1348 for (i = 0; i < info->num_planes; i++)
1349 surf->info.size += surf->info.planes[i].size;
1352 surf->flags = TBM_BO_DEFAULT;
1354 /* create only one bo */
1355 surf->num_bos = num;
1356 for (i = 0; i < num; i++) {
1357 if (bos[i] == NULL) {
1358 TBM_ERR("bos[%d] is null.\n", i);
1359 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1363 surf->bos[i] = tbm_bo_ref(bos[i]);
1364 _tbm_bo_set_surface(bos[i], surf);
1367 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1368 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1370 LIST_INITHEAD(&surf->user_data_list);
1371 LIST_INITHEAD(&surf->debug_data_list);
1372 LIST_INITHEAD(&surf->destroy_funcs);
1374 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1376 _tbm_surface_mutex_unlock();
1380 /* LCOV_EXCL_START */
1384 for (i = 0; i < num; i++) {
1386 tbm_bo_unref(surf->bos[i]);
1391 if (bufmgr_initialized && bufmgr) {
1392 LIST_DELINIT(&bufmgr->surf_list);
1393 _deinit_surface_bufmgr();
1395 _tbm_surface_mutex_unlock();
1397 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1398 info->width, info->height,
1399 _tbm_surface_internal_format_to_str(info->format), num);
1400 /* LCOV_EXCL_STOP */
1406 tbm_surface_internal_destroy(tbm_surface_h surface)
1408 _tbm_surface_mutex_lock();
1409 _tbm_set_last_result(TBM_ERROR_NONE);
1411 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1415 if (surface->refcnt > 0) {
1416 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1417 _tbm_surface_mutex_unlock();
1421 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1423 if (surface->refcnt == 0)
1424 _tbm_surface_internal_destroy(surface);
1425 else // if (surface->refcnt < 0)
1426 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1428 _tbm_surface_mutex_unlock();
1432 tbm_surface_internal_ref(tbm_surface_h surface)
1434 _tbm_surface_mutex_lock();
1435 _tbm_set_last_result(TBM_ERROR_NONE);
1437 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1441 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1443 _tbm_surface_mutex_unlock();
1447 tbm_surface_internal_unref(tbm_surface_h surface)
1449 _tbm_surface_mutex_lock();
1450 _tbm_set_last_result(TBM_ERROR_NONE);
1452 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1456 if (surface->refcnt > 0) {
1457 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1458 _tbm_surface_mutex_unlock();
1462 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1464 if (surface->refcnt == 0)
1465 _tbm_surface_internal_destroy(surface);
1467 _tbm_surface_mutex_unlock();
1471 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1473 struct _tbm_surface *surf;
1476 _tbm_surface_mutex_lock();
1477 _tbm_set_last_result(TBM_ERROR_NONE);
1479 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1481 surf = (struct _tbm_surface *)surface;
1482 num = surf->num_bos;
1485 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1487 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1489 _tbm_surface_mutex_unlock();
1495 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1497 struct _tbm_surface *surf;
1500 _tbm_surface_mutex_lock();
1501 _tbm_set_last_result(TBM_ERROR_NONE);
1503 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1504 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1506 surf = (struct _tbm_surface *)surface;
1507 bo = surf->bos[bo_idx];
1509 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1511 _tbm_surface_mutex_unlock();
1517 tbm_surface_internal_get_size(tbm_surface_h surface)
1519 struct _tbm_surface *surf;
1522 _tbm_surface_mutex_lock();
1523 _tbm_set_last_result(TBM_ERROR_NONE);
1525 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1527 surf = (struct _tbm_surface *)surface;
1528 size = surf->info.size;
1530 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1532 _tbm_surface_mutex_unlock();
1538 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1539 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1541 struct _tbm_surface *surf;
1543 _tbm_surface_mutex_lock();
1544 _tbm_set_last_result(TBM_ERROR_NONE);
1546 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1547 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1549 surf = (struct _tbm_surface *)surface;
1551 if (plane_idx >= surf->info.num_planes) {
1552 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1553 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1554 _tbm_surface_mutex_unlock();
1559 *size = surf->info.planes[plane_idx].size;
1562 *offset = surf->info.planes[plane_idx].offset;
1565 *pitch = surf->info.planes[plane_idx].stride;
1567 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1568 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1569 surf->info.planes[plane_idx].stride);
1571 _tbm_surface_mutex_unlock();
1577 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1578 tbm_surface_info_s *info, int map)
1580 struct _tbm_surface *surf;
1581 tbm_bo_handle bo_handles[4];
1584 int planes_bo_idx[TBM_SURF_PLANE_MAX];
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);
1592 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1594 surf = (struct _tbm_surface *)surface;
1596 memset(info, 0x00, sizeof(tbm_surface_info_s));
1597 info->width = surf->info.width;
1598 info->height = surf->info.height;
1599 info->format = surf->info.format;
1600 info->bpp = surf->info.bpp;
1601 info->size = surf->info.size;
1602 info->num_planes = surf->info.num_planes;
1604 for (i = 0; i < surf->info.num_planes; i++) {
1605 info->planes[i].size = surf->info.planes[i].size;
1606 info->planes[i].offset = surf->info.planes[i].offset;
1607 info->planes[i].stride = surf->info.planes[i].stride;
1608 planes_bo_idx[i] = surf->planes_bo_idx[i];
1611 for (i = 0; i < surf->num_bos; i++)
1612 bos[i] = surf->bos[i];
1614 num_bos = surf->num_bos;
1617 _tbm_surface_mutex_unlock();
1618 for (i = 0; i < num_bos; i++) {
1619 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1620 if (bo_handles[i].ptr == NULL) {
1621 for (j = 0; j < i; j++)
1622 tbm_bo_unmap(bos[j]);
1624 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1628 _tbm_surface_mutex_lock();
1630 for (i = 0; i < num_bos; i++) {
1631 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1632 if (bo_handles[i].ptr == NULL) {
1633 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1634 _tbm_surface_mutex_unlock();
1640 for (i = 0; i < info->num_planes; i++) {
1641 if (bo_handles[planes_bo_idx[i]].ptr)
1642 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1645 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1647 _tbm_surface_mutex_unlock();
1653 tbm_surface_internal_unmap(tbm_surface_h surface)
1655 struct _tbm_surface *surf;
1658 _tbm_surface_mutex_lock();
1659 _tbm_set_last_result(TBM_ERROR_NONE);
1661 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1663 surf = (struct _tbm_surface *)surface;
1665 for (i = 0; i < surf->num_bos; i++)
1666 tbm_bo_unmap(surf->bos[i]);
1668 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1670 _tbm_surface_mutex_unlock();
1674 tbm_surface_internal_get_width(tbm_surface_h surface)
1676 struct _tbm_surface *surf;
1679 _tbm_surface_mutex_lock();
1680 _tbm_set_last_result(TBM_ERROR_NONE);
1682 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1684 surf = (struct _tbm_surface *)surface;
1685 width = surf->info.width;
1687 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1689 _tbm_surface_mutex_unlock();
1695 tbm_surface_internal_get_height(tbm_surface_h surface)
1697 struct _tbm_surface *surf;
1698 unsigned int height;
1700 _tbm_surface_mutex_lock();
1701 _tbm_set_last_result(TBM_ERROR_NONE);
1703 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1705 surf = (struct _tbm_surface *)surface;
1706 height = surf->info.height;
1708 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1710 _tbm_surface_mutex_unlock();
1717 tbm_surface_internal_get_format(tbm_surface_h surface)
1719 struct _tbm_surface *surf;
1722 _tbm_surface_mutex_lock();
1723 _tbm_set_last_result(TBM_ERROR_NONE);
1725 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1727 surf = (struct _tbm_surface *)surface;
1728 format = surf->info.format;
1730 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1732 _tbm_surface_mutex_unlock();
1738 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1740 struct _tbm_surface *surf;
1743 _tbm_surface_mutex_lock();
1744 _tbm_set_last_result(TBM_ERROR_NONE);
1746 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1747 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1749 surf = (struct _tbm_surface *)surface;
1750 bo_idx = surf->planes_bo_idx[plane_idx];
1752 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1754 _tbm_surface_mutex_unlock();
1760 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1761 tbm_data_free data_free_func)
1763 tbm_user_data *data;
1765 _tbm_surface_mutex_lock();
1766 _tbm_set_last_result(TBM_ERROR_NONE);
1768 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1770 /* check if the data according to the key exist if so, return false. */
1771 data = user_data_lookup(&surface->user_data_list, key);
1773 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1774 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1775 _tbm_surface_mutex_unlock();
1779 data = user_data_create(key, data_free_func);
1781 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1782 _tbm_surface_mutex_unlock();
1786 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1788 LIST_ADD(&data->item_link, &surface->user_data_list);
1790 _tbm_surface_mutex_unlock();
1796 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1799 tbm_user_data *old_data;
1801 _tbm_surface_mutex_lock();
1802 _tbm_set_last_result(TBM_ERROR_NONE);
1804 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1806 old_data = user_data_lookup(&surface->user_data_list, key);
1808 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1809 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1810 _tbm_surface_mutex_unlock();
1814 if (old_data->data && old_data->free_func)
1815 old_data->free_func(old_data->data);
1817 old_data->data = data;
1819 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1821 _tbm_surface_mutex_unlock();
1827 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1830 tbm_user_data *old_data;
1832 _tbm_surface_mutex_lock();
1833 _tbm_set_last_result(TBM_ERROR_NONE);
1835 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1838 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1839 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1840 _tbm_surface_mutex_unlock();
1845 old_data = user_data_lookup(&surface->user_data_list, key);
1847 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1848 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1849 _tbm_surface_mutex_unlock();
1853 *data = old_data->data;
1855 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1857 _tbm_surface_mutex_unlock();
1863 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1866 tbm_user_data *old_data = (void *)0;
1868 _tbm_surface_mutex_lock();
1869 _tbm_set_last_result(TBM_ERROR_NONE);
1871 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1873 old_data = user_data_lookup(&surface->user_data_list, key);
1875 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1876 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1877 _tbm_surface_mutex_unlock();
1881 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1883 user_data_delete(old_data);
1885 _tbm_surface_mutex_unlock();
1890 /* LCOV_EXCL_START */
1892 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1894 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1896 return surface->debug_pid;
1900 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1902 _tbm_surface_mutex_lock();
1903 _tbm_set_last_result(TBM_ERROR_NONE);
1905 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1907 surface->debug_pid = pid;
1909 _tbm_surface_mutex_unlock();
1912 static tbm_surface_debug_data *
1913 _tbm_surface_internal_debug_data_create(char *key, char *value)
1915 tbm_surface_debug_data *debug_data = NULL;
1917 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1919 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1920 TBM_ERR("fail to allocate the debug_data.");
1924 if (key) debug_data->key = strdup(key);
1925 if (value) debug_data->value = strdup(value);
1931 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1933 if (!debug_data->value && !value)
1936 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1939 if (debug_data->value)
1940 free(debug_data->value);
1943 debug_data->value = strdup(value);
1945 debug_data->value = NULL;
1948 static tbm_surface_debug_data *
1949 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1951 tbm_surface_debug_data *debug_data = NULL;
1953 if (LIST_IS_EMPTY(list))
1956 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1957 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1965 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1967 tbm_surface_debug_data *debug_data = NULL;
1968 tbm_bufmgr bufmgr = NULL;
1970 _tbm_surface_mutex_lock();
1971 _tbm_set_last_result(TBM_ERROR_NONE);
1973 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1974 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1976 bufmgr = surface->bufmgr;
1978 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1980 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1982 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1984 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1986 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1987 _tbm_surface_mutex_unlock();
1991 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1994 /* add new debug key to list */
1995 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1997 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1999 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
2002 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
2004 _tbm_surface_mutex_unlock();
2010 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
2012 tbm_surface_debug_data *old_data = NULL;
2014 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
2016 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
2017 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
2018 if (!strcmp(old_data->key, key))
2019 return old_data->value;
2026 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
2027 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
2029 struct _tbm_surface_dump_buf_info {
2039 tbm_surface_info_s info;
2041 struct list_head link;
2044 struct _tbm_surface_dump_info {
2045 char *path; // copy???
2048 struct list_head *link;
2049 struct list_head surface_list; /* link of surface */
2052 static tbm_surface_dump_info *g_dump_info = NULL;
2053 static const char *dump_postfix[2] = {"png", "yuv"};
2054 static double scale_factor;
2057 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
2058 void *data2, int size2, void *data3, int size3)
2061 unsigned int *blocks;
2063 if (_tbm_surface_check_file_is_symbolic_link(file))
2064 TBM_ERR("%s is symbolic link\n", file);
2066 fp = fopen(file, "w+");
2067 TBM_RETURN_IF_FAIL(fp != NULL);
2069 blocks = (unsigned int *)data1;
2070 fwrite(blocks, 1, size1, fp);
2073 blocks = (unsigned int *)data2;
2074 fwrite(blocks, 1, size2, fp);
2078 blocks = (unsigned int *)data3;
2079 fwrite(blocks, 1, size3, fp);
2086 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
2088 unsigned int *blocks = (unsigned int *)data;
2091 png_bytep *row_pointers;
2094 if (_tbm_surface_check_file_is_symbolic_link(file))
2095 TBM_ERR("%s is symbolic link\n", file);
2097 fp = fopen(file, "wb");
2098 TBM_RETURN_IF_FAIL(fp != NULL);
2100 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
2103 TBM_ERR("fail to create a png write structure.\n");
2108 png_infop pPngInfo = png_create_info_struct(pPngStruct);
2110 TBM_ERR("fail to create a png info structure.\n");
2111 png_destroy_write_struct(&pPngStruct, NULL);
2116 if (setjmp(png_jmpbuf(pPngStruct))) {
2117 /* if png has problem of writing the file, we get here */
2118 TBM_ERR("fail to write png file.\n");
2119 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2124 png_init_io(pPngStruct, fp);
2125 if (format == TBM_FORMAT_XRGB8888) {
2127 png_set_IHDR(pPngStruct,
2134 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2137 png_set_IHDR(pPngStruct,
2142 PNG_COLOR_TYPE_RGBA,
2144 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2147 png_set_bgr(pPngStruct);
2148 png_write_info(pPngStruct, pPngInfo);
2150 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
2151 if (!row_pointers) {
2152 TBM_ERR("fail to allocate the png row_pointers.\n");
2153 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2158 for (y = 0; y < height; ++y) {
2162 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
2164 TBM_ERR("fail to allocate the png row.\n");
2165 for (x = 0; x < y; x++)
2166 png_free(pPngStruct, row_pointers[x]);
2167 png_free(pPngStruct, row_pointers);
2168 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2172 row_pointers[y] = (png_bytep)row;
2174 for (x = 0; x < width; ++x) {
2175 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
2177 if (pixel_size == 3) { // XRGB8888
2178 row[x * pixel_size] = (curBlock & 0xFF);
2179 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2180 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2181 } else { // ARGB8888
2182 row[x * pixel_size] = (curBlock & 0xFF);
2183 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
2184 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
2185 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
2190 png_write_image(pPngStruct, row_pointers);
2191 png_write_end(pPngStruct, pPngInfo);
2193 for (y = 0; y < height; y++)
2194 png_free(pPngStruct, row_pointers[y]);
2195 png_free(pPngStruct, row_pointers);
2197 png_destroy_write_struct(&pPngStruct, &pPngInfo);
2203 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
2205 TBM_RETURN_IF_FAIL(path != NULL);
2206 TBM_RETURN_IF_FAIL(w > 0);
2207 TBM_RETURN_IF_FAIL(h > 0);
2208 TBM_RETURN_IF_FAIL(count > 0);
2210 tbm_surface_dump_buf_info *buf_info = NULL;
2211 tbm_surface_h tbm_surface;
2212 tbm_surface_info_s info;
2217 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
2221 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
2222 TBM_RETURN_IF_FAIL(g_dump_info);
2224 LIST_INITHEAD(&g_dump_info->surface_list);
2225 g_dump_info->count = 0;
2226 g_dump_info->dump_max = count;
2228 /* get buffer size */
2229 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
2230 if (tbm_surface == NULL) {
2231 TBM_ERR("tbm_surface_create fail\n");
2237 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
2238 TBM_ERR("tbm_surface_get_info fail\n");
2239 tbm_surface_destroy(tbm_surface);
2244 buffer_size = info.size;
2245 tbm_surface_destroy(tbm_surface);
2247 /* create dump lists */
2248 for (i = 0; i < count; i++) {
2251 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
2252 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
2254 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
2256 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
2261 buf_info->index = i;
2263 buf_info->size = buffer_size;
2265 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
2268 g_dump_info->path = path;
2269 g_dump_info->link = &g_dump_info->surface_list;
2273 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
2278 /* free resources */
2279 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2280 tbm_surface_dump_buf_info *tmp;
2282 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2283 tbm_bo_unref(buf_info->bo);
2284 LIST_DEL(&buf_info->link);
2289 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
2298 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2305 tbm_surface_internal_dump_start(path, w, h, count);
2306 scale_factor = scale;
2310 tbm_surface_internal_dump_end(void)
2312 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2313 tbm_bo_handle bo_handle;
2318 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2325 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2328 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2329 if (bo_handle.ptr == NULL) {
2330 tbm_bo_unref(buf_info->bo);
2331 LIST_DEL(&buf_info->link);
2336 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2337 TBM_INFO("Dump File.. %s generated.\n", file);
2339 if (buf_info->dirty) {
2340 void *ptr1 = NULL, *ptr2 = NULL;
2342 switch (buf_info->info.format) {
2343 case TBM_FORMAT_ARGB8888:
2344 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2345 buf_info->info.planes[0].stride >> 2,
2346 buf_info->info.height,
2347 buf_info->info.planes[0].stride,
2348 TBM_FORMAT_ARGB8888);
2350 case TBM_FORMAT_XRGB8888:
2351 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2352 buf_info->info.planes[0].stride >> 2,
2353 buf_info->info.height,
2354 buf_info->info.planes[0].stride,
2355 TBM_FORMAT_XRGB8888);
2357 case TBM_FORMAT_YVU420:
2358 case TBM_FORMAT_YUV420:
2359 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2360 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2361 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2362 buf_info->info.planes[0].stride * buf_info->info.height,
2364 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2366 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2368 case TBM_FORMAT_NV12:
2369 case TBM_FORMAT_NV21:
2370 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2371 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2372 buf_info->info.planes[0].stride * buf_info->info.height,
2374 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2377 case TBM_FORMAT_YUYV:
2378 case TBM_FORMAT_UYVY:
2379 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2380 buf_info->info.planes[0].stride * buf_info->info.height,
2384 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2387 } else if (buf_info->dirty_shm)
2388 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2389 buf_info->shm_stride >> 2,
2391 buf_info->shm_stride, 0);
2393 tbm_bo_unmap(buf_info->bo);
2394 tbm_bo_unref(buf_info->bo);
2395 LIST_DEL(&buf_info->link);
2402 TBM_INFO("Dump End..\n");
2405 static pixman_format_code_t
2406 _tbm_surface_internal_pixman_format_get(tbm_format format)
2409 case TBM_FORMAT_ARGB8888:
2410 return PIXMAN_a8r8g8b8;
2411 case TBM_FORMAT_XRGB8888:
2412 return PIXMAN_x8r8g8b8;
2421 * This function supports only if a buffer has below formats.
2422 * - TBM_FORMAT_ARGB8888
2423 * - TBM_FORMAT_XRGB8888
2425 static tbm_surface_error_e
2426 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2427 int format, int src_stride, int src_w, int src_h,
2428 int dst_stride, int dst_w, int dst_h)
2430 pixman_image_t *src_img = NULL, *dst_img = NULL;
2431 pixman_format_code_t pixman_format;
2432 pixman_transform_t t;
2433 struct pixman_f_transform ft;
2434 double scale_x, scale_y;
2436 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2437 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2439 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2440 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2443 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2444 (uint32_t*)src_ptr, src_stride);
2445 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2448 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2449 (uint32_t*)dst_ptr, dst_stride);
2450 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2452 pixman_f_transform_init_identity(&ft);
2454 scale_x = (double)src_w / dst_w;
2455 scale_y = (double)src_h / dst_h;
2457 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2458 pixman_f_transform_translate(&ft, NULL, 0, 0);
2459 pixman_transform_from_pixman_f_transform(&t, &ft);
2460 pixman_image_set_transform(src_img, &t);
2462 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2463 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2465 pixman_image_unref(src_img);
2466 pixman_image_unref(dst_img);
2468 return TBM_SURFACE_ERROR_NONE;
2472 pixman_image_unref(src_img);
2474 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2477 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2478 #define KEY_LEN 5 // "_XXXX"
2479 #define KEYS_LEN KEY_LEN * MAX_BOS
2481 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2483 char *keys, temp_key[KEY_LEN + 1];
2484 struct _tbm_surface *surf;
2488 _tbm_surface_mutex_lock();
2490 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2492 surf = (struct _tbm_surface *)surface;
2494 num_bos = surf->num_bos;
2495 if (num_bos > MAX_BOS)
2498 keys = calloc(KEYS_LEN + 1, sizeof(char));
2500 TBM_ERR("Failed to alloc memory");
2501 _tbm_surface_mutex_unlock();
2505 for (i = 0; i < num_bos; i++) {
2506 memset(temp_key, 0x00, KEY_LEN + 1);
2508 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2509 strncat(keys, temp_key, KEY_LEN + 1);
2512 _tbm_surface_mutex_unlock();
2517 static void _tbm_surface_internal_put_keys(char *keys)
2524 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2526 TBM_RETURN_IF_FAIL(surface != NULL);
2527 TBM_RETURN_IF_FAIL(type != NULL);
2529 tbm_surface_dump_buf_info *buf_info;
2530 struct list_head *next_link;
2531 tbm_surface_info_s info;
2532 tbm_bo_handle bo_handle;
2533 const char *postfix;
2534 const char *format = NULL;
2541 next_link = g_dump_info->link->next;
2542 TBM_RETURN_IF_FAIL(next_link != NULL);
2544 if (next_link == &g_dump_info->surface_list) {
2545 next_link = next_link->next;
2546 TBM_RETURN_IF_FAIL(next_link != NULL);
2549 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2550 TBM_RETURN_IF_FAIL(buf_info != NULL);
2552 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2553 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2555 if (scale_factor > 0.0) {
2558 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2559 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2560 _tbm_surface_internal_format_to_str(info.format));
2561 tbm_surface_unmap(surface);
2565 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2567 buf_info->info.width = info.width * scale_factor;
2568 buf_info->info.height = info.height * scale_factor;
2569 buf_info->info.format = info.format;
2570 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2571 if (!buf_info->info.bpp) {
2572 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2573 tbm_surface_unmap(surface);
2576 buf_info->info.num_planes = 1;
2577 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2578 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2580 if (buf_info->info.size > buf_info->size) {
2581 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2582 buf_info->info.size, buf_info->size);
2583 tbm_surface_unmap(surface);
2587 if (info.size > buf_info->size) {
2588 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2589 info.size, buf_info->size);
2590 tbm_surface_unmap(surface);
2594 /* make the file information */
2595 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2598 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2599 postfix = dump_postfix[0];
2600 format = _tbm_surface_internal_format_to_str(info.format);
2602 postfix = dump_postfix[1];
2604 keys = _tbm_surface_internal_get_keys(surface);
2606 TBM_ERR("fail to get keys");
2607 tbm_surface_unmap(surface);
2612 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2613 if (!bo_handle.ptr) {
2614 TBM_ERR("fail to map bo");
2615 _tbm_surface_internal_put_keys(keys);
2616 tbm_surface_unmap(surface);
2619 memset(bo_handle.ptr, 0x00, buf_info->size);
2621 switch (info.format) {
2622 case TBM_FORMAT_ARGB8888:
2623 case TBM_FORMAT_XRGB8888:
2624 snprintf(buf_info->name, sizeof(buf_info->name),
2625 "%10.3f_%03d%s_%p_%s-%s.%s",
2626 _tbm_surface_internal_get_time(),
2627 g_dump_info->count++, keys, surface, format, type, postfix);
2629 if (scale_factor > 0.0) {
2630 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2632 buf_info->info.format,
2633 info.planes[0].stride,
2634 info.width, info.height,
2635 buf_info->info.planes[0].stride,
2636 buf_info->info.width,
2637 buf_info->info.height);
2638 if (ret != TBM_SURFACE_ERROR_NONE) {
2639 TBM_ERR("fail to scale buffer");
2640 tbm_bo_unmap(buf_info->bo);
2641 _tbm_surface_internal_put_keys(keys);
2642 tbm_surface_unmap(surface);
2646 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2648 case TBM_FORMAT_YVU420:
2649 case TBM_FORMAT_YUV420:
2650 snprintf(buf_info->name, sizeof(buf_info->name),
2651 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2652 _tbm_surface_internal_get_time(),
2653 g_dump_info->count++, keys, type, info.planes[0].stride,
2654 info.height, FOURCC_STR(info.format), postfix);
2655 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2656 bo_handle.ptr += info.planes[0].stride * info.height;
2657 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2658 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2659 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2661 case TBM_FORMAT_NV12:
2662 case TBM_FORMAT_NV21:
2663 snprintf(buf_info->name, sizeof(buf_info->name),
2664 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2665 _tbm_surface_internal_get_time(),
2666 g_dump_info->count++, keys, type, info.planes[0].stride,
2667 info.height, FOURCC_STR(info.format), postfix);
2668 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2669 bo_handle.ptr += info.planes[0].stride * info.height;
2670 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2672 case TBM_FORMAT_YUYV:
2673 case TBM_FORMAT_UYVY:
2674 snprintf(buf_info->name, sizeof(buf_info->name),
2675 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2676 _tbm_surface_internal_get_time(),
2677 g_dump_info->count++, keys, type, info.planes[0].stride,
2678 info.height, FOURCC_STR(info.format), postfix);
2679 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2682 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2683 tbm_bo_unmap(buf_info->bo);
2684 _tbm_surface_internal_put_keys(keys);
2685 tbm_surface_unmap(surface);
2689 tbm_bo_unmap(buf_info->bo);
2691 _tbm_surface_internal_put_keys(keys);
2693 tbm_surface_unmap(surface);
2695 buf_info->dirty = 1;
2696 buf_info->dirty_shm = 0;
2698 if (g_dump_info->count == 1000)
2699 g_dump_info->count = 0;
2701 g_dump_info->link = next_link;
2703 TBM_INFO("Dump %s \n", buf_info->name);
2706 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2709 TBM_RETURN_IF_FAIL(ptr != NULL);
2710 TBM_RETURN_IF_FAIL(w > 0);
2711 TBM_RETURN_IF_FAIL(h > 0);
2712 TBM_RETURN_IF_FAIL(stride > 0);
2713 TBM_RETURN_IF_FAIL(type != NULL);
2715 tbm_surface_dump_buf_info *buf_info;
2716 struct list_head *next_link;
2717 tbm_bo_handle bo_handle;
2718 int ret, size, dw = 0, dh = 0, dstride = 0;
2723 next_link = g_dump_info->link->next;
2724 TBM_RETURN_IF_FAIL(next_link != NULL);
2726 if (next_link == &g_dump_info->surface_list) {
2727 next_link = next_link->next;
2728 TBM_RETURN_IF_FAIL(next_link != NULL);
2731 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2732 TBM_RETURN_IF_FAIL(buf_info != NULL);
2734 if (scale_factor > 0.0) {
2737 dw = w * scale_factor;
2738 dh = h * scale_factor;
2740 size = dstride * dh;
2744 if (size > buf_info->size) {
2745 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2746 size, buf_info->size);
2751 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2752 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2754 memset(bo_handle.ptr, 0x00, buf_info->size);
2755 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2757 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2758 _tbm_surface_internal_get_time(),
2759 g_dump_info->count++, type, dump_postfix[0]);
2760 if (scale_factor > 0.0) {
2761 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2762 TBM_FORMAT_ARGB8888, stride,
2763 w, h, dstride, dw, dh);
2764 if (ret != TBM_SURFACE_ERROR_NONE) {
2765 TBM_ERR("fail to scale buffer");
2766 tbm_bo_unmap(buf_info->bo);
2769 buf_info->shm_stride = dstride;
2770 buf_info->shm_h = dh;
2772 memcpy(bo_handle.ptr, ptr, size);
2773 buf_info->shm_stride = stride;
2774 buf_info->shm_h = h;
2777 tbm_bo_unmap(buf_info->bo);
2779 buf_info->dirty = 0;
2780 buf_info->dirty_shm = 1;
2782 if (g_dump_info->count == 1000)
2783 g_dump_info->count = 0;
2785 g_dump_info->link = next_link;
2787 TBM_INFO("Dump %s \n", buf_info->name);
2791 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2793 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2794 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2795 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2797 tbm_surface_info_s info;
2798 const char *postfix;
2802 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2803 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2805 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2806 postfix = dump_postfix[0];
2808 postfix = dump_postfix[1];
2810 if (strcmp(postfix, type)) {
2811 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2812 tbm_surface_unmap(surface);
2816 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2818 if (!access(file, 0)) {
2819 TBM_ERR("can't capture buffer, exist file %s", file);
2820 tbm_surface_unmap(surface);
2824 switch (info.format) {
2825 case TBM_FORMAT_ARGB8888:
2826 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2829 info.planes[0].stride,
2830 TBM_FORMAT_ARGB8888);
2832 case TBM_FORMAT_XRGB8888:
2833 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2836 info.planes[0].stride,
2837 TBM_FORMAT_XRGB8888);
2839 case TBM_FORMAT_YVU420:
2840 case TBM_FORMAT_YUV420:
2841 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2842 info.planes[0].stride * info.height,
2844 info.planes[1].stride * (info.height >> 1),
2846 info.planes[2].stride * (info.height >> 1));
2848 case TBM_FORMAT_NV12:
2849 case TBM_FORMAT_NV21:
2850 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2851 info.planes[0].stride * info.height,
2853 info.planes[1].stride * (info.height >> 1),
2856 case TBM_FORMAT_YUYV:
2857 case TBM_FORMAT_UYVY:
2858 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2859 info.planes[0].stride * info.height,
2863 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2864 tbm_surface_unmap(surface);
2868 tbm_surface_unmap(surface);
2870 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2876 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2877 const char *path, const char *name, const char *type)
2879 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2880 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2881 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2882 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2883 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2884 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2888 if (strcmp(dump_postfix[0], type)) {
2889 TBM_ERR("Not supported type:%s'", type);
2893 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2895 if (!access(file, 0)) {
2896 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2900 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2902 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2908 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2910 struct _tbm_surface *surf;
2912 _tbm_surface_mutex_lock();
2913 _tbm_set_last_result(TBM_ERROR_NONE);
2915 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2916 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2917 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2919 surf = (struct _tbm_surface *)surface;
2923 surf->damage.width = width;
2924 surf->damage.height = height;
2926 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2927 surface, x, y, width, height);
2929 _tbm_surface_mutex_unlock();
2935 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2937 struct _tbm_surface *surf;
2939 _tbm_surface_mutex_lock();
2940 _tbm_set_last_result(TBM_ERROR_NONE);
2942 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2944 surf = (struct _tbm_surface *)surface;
2946 if (x) *x = surf->damage.x;
2947 if (y) *y = surf->damage.y;
2948 if (width) *width = surf->damage.width;
2949 if (height) *height = surf->damage.height;
2951 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2952 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2954 _tbm_surface_mutex_unlock();
2960 tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
2962 struct _tbm_surface *surf;
2963 tbm_surface_destroy_func_info *func_info = NULL;
2965 _tbm_surface_mutex_lock();
2966 _tbm_set_last_result(TBM_ERROR_NONE);
2968 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2969 TBM_SURFACE_RETURN_VAL_IF_FAIL(func != NULL, 0);
2971 surf = (struct _tbm_surface *)surface;
2972 LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
2973 if (func_info->destroy_func == func && func_info->user_data == user_data) {
2974 TBM_ERR("can't add twice");
2975 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
2976 _tbm_surface_mutex_unlock();
2981 func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
2982 if (func_info == NULL) {
2983 TBM_ERR("alloc failed");
2984 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2985 _tbm_surface_mutex_unlock();
2989 func_info->destroy_func = func;
2990 func_info->user_data = user_data;
2992 LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
2994 _tbm_surface_mutex_unlock();
3000 tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
3002 struct _tbm_surface *surf;
3003 tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
3005 _tbm_surface_mutex_lock();
3006 _tbm_set_last_result(TBM_ERROR_NONE);
3008 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
3009 TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
3011 surf = (struct _tbm_surface *)surface;
3012 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
3013 if (func_info->destroy_func != func || func_info->user_data != user_data)
3016 LIST_DEL(&func_info->item_link);
3019 _tbm_surface_mutex_unlock();
3024 _tbm_surface_mutex_unlock();
3027 tbm_surface_buffer_data *
3028 tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
3030 tbm_surface_buffer_data *buffer_data = NULL;
3031 struct _tbm_surface *surf;
3032 struct _tbm_bufmgr *bufmgr;
3034 _tbm_surface_mutex_lock();
3036 surf = (struct _tbm_surface *)surface;
3037 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3039 bufmgr = surf->bufmgr;
3040 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3042 // this function supports when it comes to be use_hal.
3043 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
3046 buffer_data = (tbm_surface_buffer_data *)hal_tbm_surface_export((hal_tbm_surface *)surf->hal_surface,
3047 (hal_tbm_error *)error);
3048 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
3050 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
3053 *error = TBM_ERROR_NONE;
3055 _tbm_set_last_result(TBM_ERROR_NONE);
3056 _tbm_surface_mutex_unlock();
3062 tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
3064 struct _tbm_surface *surf;
3065 struct _tbm_bufmgr *bufmgr;
3067 _tbm_surface_mutex_lock();
3069 bufmgr = g_surface_bufmgr;
3070 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3072 // this function supports when it comes to be use_hal.
3073 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
3075 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3076 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3077 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3078 TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
3081 surf = _tbm_surface_internal_hal_tbm_import_surface(bufmgr,
3082 (int)surface_info->width,
3083 (int)surface_info->height,
3084 (int)surface_info->format,
3087 TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
3089 LIST_INITHEAD(&surf->user_data_list);
3090 LIST_INITHEAD(&surf->debug_data_list);
3091 LIST_INITHEAD(&surf->destroy_funcs);
3093 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
3095 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
3098 *error = TBM_ERROR_NONE;
3100 _tbm_set_last_result(TBM_ERROR_NONE);
3101 _tbm_surface_mutex_unlock();
3103 return (tbm_surface_h)surf;