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_VAL_IF_FAIL(cond, val) {\
62 TBM_ERR("'%s' failed.\n", #cond);\
63 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
64 _tbm_surface_mutex_unlock();\
71 _tbm_surface_internal_get_time(void)
76 clock_gettime(CLOCK_MONOTONIC, &tp);
77 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
83 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
85 LIST_DEL(&debug_data->item_link);
87 if (debug_data->key) free(debug_data->key);
88 if (debug_data->value) free(debug_data->value);
93 _tbm_surface_internal_format_to_str(tbm_format format)
97 return "TBM_FORMAT_C8";
98 case TBM_FORMAT_RGB332:
99 return "TBM_FORMAT_RGB332";
100 case TBM_FORMAT_BGR233:
101 return "TBM_FORMAT_BGR233";
102 case TBM_FORMAT_XRGB4444:
103 return "TBM_FORMAT_XRGB4444";
104 case TBM_FORMAT_XBGR4444:
105 return "TBM_FORMAT_XBGR4444";
106 case TBM_FORMAT_RGBX4444:
107 return "TBM_FORMAT_RGBX4444";
108 case TBM_FORMAT_BGRX4444:
109 return "TBM_FORMAT_BGRX4444";
110 case TBM_FORMAT_ARGB4444:
111 return "TBM_FORMAT_ARGB4444";
112 case TBM_FORMAT_ABGR4444:
113 return "TBM_FORMAT_ABGR4444";
114 case TBM_FORMAT_RGBA4444:
115 return "TBM_FORMAT_RGBA4444";
116 case TBM_FORMAT_BGRA4444:
117 return "TBM_FORMAT_BGRA4444";
118 case TBM_FORMAT_XRGB1555:
119 return "TBM_FORMAT_XRGB1555";
120 case TBM_FORMAT_XBGR1555:
121 return "TBM_FORMAT_XBGR1555";
122 case TBM_FORMAT_RGBX5551:
123 return "TBM_FORMAT_RGBX5551";
124 case TBM_FORMAT_BGRX5551:
125 return "TBM_FORMAT_BGRX5551";
126 case TBM_FORMAT_ARGB1555:
127 return "TBM_FORMAT_ARGB1555";
128 case TBM_FORMAT_ABGR1555:
129 return "TBM_FORMAT_ABGR1555";
130 case TBM_FORMAT_RGBA5551:
131 return "TBM_FORMAT_RGBA5551";
132 case TBM_FORMAT_BGRA5551:
133 return "TBM_FORMAT_BGRA5551";
134 case TBM_FORMAT_RGB565:
135 return "TBM_FORMAT_RGB565";
136 case TBM_FORMAT_BGR565:
137 return "TBM_FORMAT_BGR565";
138 case TBM_FORMAT_RGB888:
139 return "TBM_FORMAT_RGB888";
140 case TBM_FORMAT_BGR888:
141 return "TBM_FORMAT_BGR888";
142 case TBM_FORMAT_XRGB8888:
143 return "TBM_FORMAT_XRGB8888";
144 case TBM_FORMAT_XBGR8888:
145 return "TBM_FORMAT_XBGR8888";
146 case TBM_FORMAT_RGBX8888:
147 return "TBM_FORMAT_RGBX8888";
148 case TBM_FORMAT_BGRX8888:
149 return "TBM_FORMAT_BGRX8888";
150 case TBM_FORMAT_ARGB8888:
151 return "TBM_FORMAT_ARGB8888";
152 case TBM_FORMAT_ABGR8888:
153 return "TBM_FORMAT_ABGR8888";
154 case TBM_FORMAT_RGBA8888:
155 return "TBM_FORMAT_RGBA8888";
156 case TBM_FORMAT_BGRA8888:
157 return "TBM_FORMAT_BGRA8888";
158 case TBM_FORMAT_XRGB2101010:
159 return "TBM_FORMAT_XRGB2101010";
160 case TBM_FORMAT_XBGR2101010:
161 return "TBM_FORMAT_XBGR2101010";
162 case TBM_FORMAT_RGBX1010102:
163 return "TBM_FORMAT_RGBX1010102";
164 case TBM_FORMAT_BGRX1010102:
165 return "TBM_FORMAT_BGRX1010102";
166 case TBM_FORMAT_ARGB2101010:
167 return "TBM_FORMAT_ARGB2101010";
168 case TBM_FORMAT_ABGR2101010:
169 return "TBM_FORMAT_ABGR2101010";
170 case TBM_FORMAT_RGBA1010102:
171 return "TBM_FORMAT_RGBA1010102";
172 case TBM_FORMAT_BGRA1010102:
173 return "TBM_FORMAT_BGRA1010102";
174 case TBM_FORMAT_YUYV:
175 return "TBM_FORMAT_YUYV";
176 case TBM_FORMAT_YVYU:
177 return "TBM_FORMAT_YVYU";
178 case TBM_FORMAT_UYVY:
179 return "TBM_FORMAT_UYVY";
180 case TBM_FORMAT_VYUY:
181 return "TBM_FORMAT_VYUY";
182 case TBM_FORMAT_AYUV:
183 return "TBM_FORMAT_AYUV";
184 case TBM_FORMAT_NV12:
185 return "TBM_FORMAT_NV12";
186 case TBM_FORMAT_NV21:
187 return "TBM_FORMAT_NV21";
188 case TBM_FORMAT_NV16:
189 return "TBM_FORMAT_NV16";
190 case TBM_FORMAT_NV61:
191 return "TBM_FORMAT_NV61";
192 case TBM_FORMAT_YUV410:
193 return "TBM_FORMAT_YUV410";
194 case TBM_FORMAT_YVU410:
195 return "TBM_FORMAT_YVU410";
196 case TBM_FORMAT_YUV411:
197 return "TBM_FORMAT_YUV411";
198 case TBM_FORMAT_YVU411:
199 return "TBM_FORMAT_YVU411";
200 case TBM_FORMAT_YUV420:
201 return "TBM_FORMAT_YUV420";
202 case TBM_FORMAT_YVU420:
203 return "TBM_FORMAT_YVU420";
204 case TBM_FORMAT_YUV422:
205 return "TBM_FORMAT_YUV422";
206 case TBM_FORMAT_YVU422:
207 return "TBM_FORMAT_YVU422";
208 case TBM_FORMAT_YUV444:
209 return "TBM_FORMAT_YUV444";
210 case TBM_FORMAT_YVU444:
211 return "TBM_FORMAT_YVU444";
212 case TBM_FORMAT_NV12MT:
213 return "TBM_FORMAT_NV12MT";
220 _tbm_surface_mutex_lock(void)
222 pthread_mutex_lock(&tbm_surface_lock);
226 _tbm_surface_mutex_unlock(void)
228 pthread_mutex_unlock(&tbm_surface_lock);
232 _init_surface_bufmgr(void)
234 g_surface_bufmgr = tbm_bufmgr_init(-1);
238 _deinit_surface_bufmgr(void)
240 if (!g_surface_bufmgr)
243 tbm_bufmgr_deinit(g_surface_bufmgr);
244 g_surface_bufmgr = NULL;
249 _tbm_surface_internal_magic_check(tbm_surface_h surface)
251 if (surface->magic != TBM_SURFACE_MAGIC)
258 _tbm_surface_internal_is_valid(tbm_surface_h surface)
261 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
262 TBM_ERR("error: No valid tbm_surface is NULL\n");
266 if (!_tbm_surface_internal_magic_check(surface)) {
267 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
268 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
276 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
277 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
279 TBM_RETURN_VAL_IF_FAIL(surface, 0);
280 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
282 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
283 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
287 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
288 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
289 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
290 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
292 if (bufmgr->use_hal_tbm) {
293 error = (tbm_error_e)hal_tbm_bufmgr_get_plane_data(bufmgr->hal_bufmgr, (hal_tbm_format)surf->info.format,
294 plane_idx, surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
295 /* LCOV_EXCL_START */
296 if (error == TBM_ERROR_NOT_SUPPORTED) {
297 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
299 } else if (error != TBM_ERROR_NONE) {
300 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
301 _tbm_set_last_result(error);
306 } else if (bufmgr->backend_module_data) {
307 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
308 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
312 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
313 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
314 if (error != TBM_ERROR_NONE) {
315 /* LCOV_EXCL_START */
316 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
317 _tbm_set_last_result(error);
323 if (!bufmgr->backend->surface_get_plane_data) {
324 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
328 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
329 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
331 /* LCOV_EXCL_START */
332 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
333 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
343 _tbm_surface_internal_destroy(tbm_surface_h surface)
346 tbm_bufmgr bufmgr = surface->bufmgr;
347 tbm_user_data *old_data = NULL, *tmp = NULL;
348 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
350 /* destory the user_data_list */
351 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
352 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
353 TBM_DBG("free user_data\n");
354 user_data_delete(old_data);
358 for (i = 0; i < surface->num_bos; i++) {
359 surface->bos[i]->surface = NULL;
361 tbm_bo_unref(surface->bos[i]);
362 surface->bos[i] = NULL;
365 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
366 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
367 _tbm_surface_internal_debug_data_delete(debug_old_data);
370 LIST_DEL(&surface->item_link);
376 if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
377 LIST_DELINIT(&bufmgr->surf_list);
379 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
380 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
381 _tbm_surface_internal_debug_data_delete(debug_old_data);
385 _deinit_surface_bufmgr();
389 /* LCOV_EXCL_START */
391 _tbm_surface_check_file_is_symbolic_link(const char* path)
398 if (stat(path, &sb) != 0)
401 if (S_ISLNK(sb.st_mode))
409 _tbm_surface_internal_get_num_planes(tbm_format format)
415 case TBM_FORMAT_RGB332:
416 case TBM_FORMAT_BGR233:
417 case TBM_FORMAT_XRGB4444:
418 case TBM_FORMAT_XBGR4444:
419 case TBM_FORMAT_RGBX4444:
420 case TBM_FORMAT_BGRX4444:
421 case TBM_FORMAT_ARGB4444:
422 case TBM_FORMAT_ABGR4444:
423 case TBM_FORMAT_RGBA4444:
424 case TBM_FORMAT_BGRA4444:
425 case TBM_FORMAT_XRGB1555:
426 case TBM_FORMAT_XBGR1555:
427 case TBM_FORMAT_RGBX5551:
428 case TBM_FORMAT_BGRX5551:
429 case TBM_FORMAT_ARGB1555:
430 case TBM_FORMAT_ABGR1555:
431 case TBM_FORMAT_RGBA5551:
432 case TBM_FORMAT_BGRA5551:
433 case TBM_FORMAT_RGB565:
434 case TBM_FORMAT_BGR565:
435 case TBM_FORMAT_RGB888:
436 case TBM_FORMAT_BGR888:
437 case TBM_FORMAT_XRGB8888:
438 case TBM_FORMAT_XBGR8888:
439 case TBM_FORMAT_RGBX8888:
440 case TBM_FORMAT_BGRX8888:
441 case TBM_FORMAT_ARGB8888:
442 case TBM_FORMAT_ABGR8888:
443 case TBM_FORMAT_RGBA8888:
444 case TBM_FORMAT_BGRA8888:
445 case TBM_FORMAT_XRGB2101010:
446 case TBM_FORMAT_XBGR2101010:
447 case TBM_FORMAT_RGBX1010102:
448 case TBM_FORMAT_BGRX1010102:
449 case TBM_FORMAT_ARGB2101010:
450 case TBM_FORMAT_ABGR2101010:
451 case TBM_FORMAT_RGBA1010102:
452 case TBM_FORMAT_BGRA1010102:
453 case TBM_FORMAT_YUYV:
454 case TBM_FORMAT_YVYU:
455 case TBM_FORMAT_UYVY:
456 case TBM_FORMAT_VYUY:
457 case TBM_FORMAT_AYUV:
460 case TBM_FORMAT_NV12:
461 case TBM_FORMAT_NV12MT:
462 case TBM_FORMAT_NV21:
463 case TBM_FORMAT_NV16:
464 case TBM_FORMAT_NV61:
467 case TBM_FORMAT_YUV410:
468 case TBM_FORMAT_YVU410:
469 case TBM_FORMAT_YUV411:
470 case TBM_FORMAT_YVU411:
471 case TBM_FORMAT_YUV420:
472 case TBM_FORMAT_YVU420:
473 case TBM_FORMAT_YUV422:
474 case TBM_FORMAT_YVU422:
475 case TBM_FORMAT_YUV444:
476 case TBM_FORMAT_YVU444:
481 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
489 _tbm_surface_internal_get_bpp(tbm_format format)
496 case TBM_FORMAT_RGB332:
497 case TBM_FORMAT_BGR233:
500 case TBM_FORMAT_XRGB4444:
501 case TBM_FORMAT_XBGR4444:
502 case TBM_FORMAT_RGBX4444:
503 case TBM_FORMAT_BGRX4444:
504 case TBM_FORMAT_ARGB4444:
505 case TBM_FORMAT_ABGR4444:
506 case TBM_FORMAT_RGBA4444:
507 case TBM_FORMAT_BGRA4444:
508 case TBM_FORMAT_XRGB1555:
509 case TBM_FORMAT_XBGR1555:
510 case TBM_FORMAT_RGBX5551:
511 case TBM_FORMAT_BGRX5551:
512 case TBM_FORMAT_ARGB1555:
513 case TBM_FORMAT_ABGR1555:
514 case TBM_FORMAT_RGBA5551:
515 case TBM_FORMAT_BGRA5551:
516 case TBM_FORMAT_RGB565:
517 case TBM_FORMAT_BGR565:
520 case TBM_FORMAT_RGB888:
521 case TBM_FORMAT_BGR888:
524 case TBM_FORMAT_XRGB8888:
525 case TBM_FORMAT_XBGR8888:
526 case TBM_FORMAT_RGBX8888:
527 case TBM_FORMAT_BGRX8888:
528 case TBM_FORMAT_ARGB8888:
529 case TBM_FORMAT_ABGR8888:
530 case TBM_FORMAT_RGBA8888:
531 case TBM_FORMAT_BGRA8888:
532 case TBM_FORMAT_XRGB2101010:
533 case TBM_FORMAT_XBGR2101010:
534 case TBM_FORMAT_RGBX1010102:
535 case TBM_FORMAT_BGRX1010102:
536 case TBM_FORMAT_ARGB2101010:
537 case TBM_FORMAT_ABGR2101010:
538 case TBM_FORMAT_RGBA1010102:
539 case TBM_FORMAT_BGRA1010102:
540 case TBM_FORMAT_YUYV:
541 case TBM_FORMAT_YVYU:
542 case TBM_FORMAT_UYVY:
543 case TBM_FORMAT_VYUY:
544 case TBM_FORMAT_AYUV:
547 case TBM_FORMAT_NV12:
548 case TBM_FORMAT_NV12MT:
549 case TBM_FORMAT_NV21:
552 case TBM_FORMAT_NV16:
553 case TBM_FORMAT_NV61:
556 case TBM_FORMAT_YUV410:
557 case TBM_FORMAT_YVU410:
560 case TBM_FORMAT_YUV411:
561 case TBM_FORMAT_YVU411:
562 case TBM_FORMAT_YUV420:
563 case TBM_FORMAT_YVU420:
566 case TBM_FORMAT_YUV422:
567 case TBM_FORMAT_YVU422:
570 case TBM_FORMAT_YUV444:
571 case TBM_FORMAT_YVU444:
575 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
583 tbm_surface_internal_is_valid(tbm_surface_h surface)
587 _tbm_surface_mutex_lock();
588 _tbm_set_last_result(TBM_ERROR_NONE);
590 /* Return silently if surface is null. */
592 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
593 _tbm_surface_mutex_unlock();
597 ret = _tbm_surface_internal_is_valid(surface);
599 _tbm_surface_mutex_unlock();
605 tbm_surface_internal_query_supported_formats(uint32_t **formats,
608 struct _tbm_bufmgr *bufmgr;
610 bool bufmgr_initialized = false;
613 _tbm_surface_mutex_lock();
614 _tbm_set_last_result(TBM_ERROR_NONE);
616 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
617 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
619 if (!g_surface_bufmgr) {
620 _init_surface_bufmgr();
621 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
622 bufmgr_initialized = true;
625 bufmgr = g_surface_bufmgr;
627 if (bufmgr->use_hal_tbm) {
628 error = (tbm_error_e)hal_tbm_bufmgr_get_supported_formats(bufmgr->hal_bufmgr, formats, num);
629 /* LCOV_EXCL_START */
630 if (error == TBM_ERROR_NOT_SUPPORTED) {
631 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
633 } else if (error != TBM_ERROR_NONE) {
634 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
638 } else if (bufmgr->backend_module_data) {
639 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
640 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
644 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
645 if (error != TBM_ERROR_NONE) {
646 /* LCOV_EXCL_START */
647 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
649 /* LCOV_EXCL_START */
653 if (!bufmgr->backend->surface_supported_format) {
654 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
658 ret = bufmgr->backend->surface_supported_format(formats, num);
660 /* LCOV_EXCL_START */
661 TBM_ERR("Fail to surface_supported_format.\n");
662 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
664 /* LCOV_EXCL_START */
668 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
670 if (bufmgr_initialized) {
671 LIST_DELINIT(&g_surface_bufmgr->surf_list);
672 _deinit_surface_bufmgr();
675 _tbm_surface_mutex_unlock();
679 /* LCOV_EXCL_START */
681 if (bufmgr_initialized) {
682 LIST_DELINIT(&g_surface_bufmgr->surf_list);
683 _deinit_surface_bufmgr();
685 _tbm_surface_mutex_unlock();
687 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
694 tbm_surface_internal_get_num_planes(tbm_format format)
698 _tbm_surface_mutex_lock();
699 _tbm_set_last_result(TBM_ERROR_NONE);
701 num_planes = _tbm_surface_internal_get_num_planes(format);
703 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
704 _tbm_surface_mutex_unlock();
708 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
710 _tbm_surface_mutex_unlock();
716 tbm_surface_internal_get_bpp(tbm_format format)
720 _tbm_surface_mutex_lock();
721 _tbm_set_last_result(TBM_ERROR_NONE);
723 bpp = _tbm_surface_internal_get_bpp(format);
725 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
726 _tbm_surface_mutex_unlock();
730 _tbm_surface_mutex_unlock();
732 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
738 tbm_surface_internal_create_with_flags(int width, int height,
739 int format, int flags)
741 struct _tbm_bufmgr *bufmgr;
742 struct _tbm_surface *surf = NULL;
746 uint32_t bo_size = 0;
749 bool bufmgr_initialized = false;
752 _tbm_surface_mutex_lock();
753 _tbm_set_last_result(TBM_ERROR_NONE);
755 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
756 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
758 if (!g_surface_bufmgr) {
759 _init_surface_bufmgr();
760 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
761 bufmgr_initialized = true;
764 bufmgr = g_surface_bufmgr;
765 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
766 TBM_ERR("The bufmgr is invalid\n");
767 goto check_valid_fail;
770 surf = calloc(1, sizeof(struct _tbm_surface));
772 /* LCOV_EXCL_START */
773 TBM_ERR("fail to alloc surf\n");
774 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
775 goto alloc_surf_fail;
779 surf->magic = TBM_SURFACE_MAGIC;
780 surf->bufmgr = bufmgr;
781 surf->info.width = width;
782 surf->info.height = height;
783 surf->info.format = format;
784 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
785 if (!surf->info.bpp) {
786 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
789 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
790 if (!surf->info.num_planes) {
791 TBM_ERR("fail to get num_planes. error(%s)\n", tbm_error_str(tbm_get_last_error()));
792 goto num_planes_fail;
796 /* get size, stride and offset bo_idx */
797 for (i = 0; i < surf->info.num_planes; i++) {
798 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
799 &offset, &stride, &bo_idx)) {
800 TBM_ERR("fail to query plane data\n");
801 goto query_plane_data_fail;
804 surf->info.planes[i].size = size;
805 surf->info.planes[i].offset = offset;
806 surf->info.planes[i].stride = stride;
807 surf->planes_bo_idx[i] = bo_idx;
812 for (i = 0; i < surf->info.num_planes; i++) {
813 surf->info.size += surf->info.planes[i].size;
815 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
816 surf->num_bos = surf->planes_bo_idx[i] + 1;
821 for (i = 0; i < surf->num_bos; i++) {
823 for (j = 0; j < surf->info.num_planes; j++) {
824 if (surf->planes_bo_idx[j] == i)
825 bo_size += surf->info.planes[j].size;
828 if (bufmgr->use_hal_tbm) {
829 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, flags, &error);
830 if (error == TBM_ERROR_NOT_SUPPORTED) {
831 if (flags & TBM_BO_TILED) {
832 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, &error);
833 if (error == TBM_ERROR_NOT_SUPPORTED) {
834 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
835 } else if (error != TBM_ERROR_NONE) {
836 TBM_ERR("fail to alloc bo idx:%d\n", i);
840 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
844 TBM_ERR("fail to alloc bo idx:%d\n", i);
847 } else if (error != TBM_ERROR_NONE) {
848 TBM_ERR("fail to alloc bo idx:%d\n", i);
851 } else if (bufmgr->backend_module_data) {
852 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
853 /* LCOV_EXCL_START */
854 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, flags, &error);
856 TBM_ERR("fail to tbm_bo_alloc_with_format idx:%d\n", i);
860 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
861 /* LCOV_EXCL_START */
862 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, &error);
864 TBM_ERR("fail to tbm_bo_alloc_with_tiled_format idx:%d\n", i);
869 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
871 TBM_ERR("fail to alloc bo idx:%d\n", i);
876 if (bufmgr->backend->surface_bo_alloc) {
877 /* LCOV_EXCL_START */
878 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
880 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
885 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
887 TBM_ERR("fail to alloc bo idx:%d\n", i);
893 _tbm_bo_set_surface(surf->bos[i], surf);
896 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
897 _tbm_surface_internal_format_to_str(format), flags, surf);
899 LIST_INITHEAD(&surf->user_data_list);
900 LIST_INITHEAD(&surf->debug_data_list);
902 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
904 _tbm_surface_mutex_unlock();
908 /* LCOV_EXCL_START */
910 for (j = 0; j < i; j++) {
912 tbm_bo_unref(surf->bos[j]);
914 query_plane_data_fail:
920 if (bufmgr_initialized && bufmgr) {
921 LIST_DELINIT(&bufmgr->surf_list);
922 _deinit_surface_bufmgr();
924 _tbm_surface_mutex_unlock();
926 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
928 _tbm_surface_internal_format_to_str(format), flags);
935 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
936 tbm_bo *bos, int num)
938 struct _tbm_bufmgr *bufmgr;
939 struct _tbm_surface *surf = NULL;
941 bool bufmgr_initialized = false;
943 _tbm_surface_mutex_lock();
944 _tbm_set_last_result(TBM_ERROR_NONE);
946 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
947 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
948 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
949 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
950 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
952 if (!g_surface_bufmgr) {
953 _init_surface_bufmgr();
954 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
955 bufmgr_initialized = true;
958 bufmgr = g_surface_bufmgr;
959 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
960 TBM_ERR("fail to validate the Bufmgr.\n");
961 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
962 goto check_valid_fail;
965 surf = calloc(1, sizeof(struct _tbm_surface));
967 /* LCOV_EXCL_START */
968 TBM_ERR("fail to allocate struct _tbm_surface.\n");
969 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
970 goto alloc_surf_fail;
974 surf->magic = TBM_SURFACE_MAGIC;
975 surf->bufmgr = bufmgr;
976 surf->info.width = info->width;
977 surf->info.height = info->height;
978 surf->info.format = info->format;
980 surf->info.bpp = info->bpp;
982 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
983 if (!surf->info.bpp) {
984 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
988 surf->info.num_planes = info->num_planes;
991 /* get size, stride and offset */
992 for (i = 0; i < info->num_planes; i++) {
993 surf->info.planes[i].offset = info->planes[i].offset;
994 surf->info.planes[i].stride = info->planes[i].stride;
996 if (info->planes[i].size > 0)
997 surf->info.planes[i].size = info->planes[i].size;
999 uint32_t size = 0, offset = 0, stride = 0;
1002 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1003 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1004 goto plane_data_fail;
1006 surf->info.planes[i].size = size;
1010 surf->planes_bo_idx[i] = 0;
1012 surf->planes_bo_idx[i] = i;
1015 if (info->size > 0) {
1016 surf->info.size = info->size;
1018 surf->info.size = 0;
1019 for (i = 0; i < info->num_planes; i++)
1020 surf->info.size += surf->info.planes[i].size;
1023 surf->flags = TBM_BO_DEFAULT;
1025 /* create only one bo */
1026 surf->num_bos = num;
1027 for (i = 0; i < num; i++) {
1028 if (bos[i] == NULL) {
1029 TBM_ERR("bos[%d] is null.\n", i);
1030 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1034 surf->bos[i] = tbm_bo_ref(bos[i]);
1035 _tbm_bo_set_surface(bos[i], surf);
1038 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1039 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1041 LIST_INITHEAD(&surf->user_data_list);
1042 LIST_INITHEAD(&surf->debug_data_list);
1044 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1046 _tbm_surface_mutex_unlock();
1050 /* LCOV_EXCL_START */
1054 for (i = 0; i < num; i++) {
1056 tbm_bo_unref(surf->bos[i]);
1061 if (bufmgr_initialized && bufmgr) {
1062 LIST_DELINIT(&bufmgr->surf_list);
1063 _deinit_surface_bufmgr();
1065 _tbm_surface_mutex_unlock();
1067 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1068 info->width, info->height,
1069 _tbm_surface_internal_format_to_str(info->format), num);
1070 /* LCOV_EXCL_STOP */
1076 tbm_surface_internal_destroy(tbm_surface_h surface)
1078 _tbm_surface_mutex_lock();
1079 _tbm_set_last_result(TBM_ERROR_NONE);
1081 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1085 if (surface->refcnt > 0) {
1086 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1087 _tbm_surface_mutex_unlock();
1091 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1093 if (surface->refcnt == 0)
1094 _tbm_surface_internal_destroy(surface);
1096 _tbm_surface_mutex_unlock();
1100 tbm_surface_internal_ref(tbm_surface_h surface)
1102 _tbm_surface_mutex_lock();
1103 _tbm_set_last_result(TBM_ERROR_NONE);
1105 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1109 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1111 _tbm_surface_mutex_unlock();
1115 tbm_surface_internal_unref(tbm_surface_h surface)
1117 _tbm_surface_mutex_lock();
1118 _tbm_set_last_result(TBM_ERROR_NONE);
1120 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1124 if (surface->refcnt > 0) {
1125 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1126 _tbm_surface_mutex_unlock();
1130 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1132 if (surface->refcnt == 0)
1133 _tbm_surface_internal_destroy(surface);
1135 _tbm_surface_mutex_unlock();
1139 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1141 struct _tbm_surface *surf;
1144 _tbm_surface_mutex_lock();
1145 _tbm_set_last_result(TBM_ERROR_NONE);
1147 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1149 surf = (struct _tbm_surface *)surface;
1150 num = surf->num_bos;
1153 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1155 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1157 _tbm_surface_mutex_unlock();
1163 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1165 struct _tbm_surface *surf;
1168 _tbm_surface_mutex_lock();
1169 _tbm_set_last_result(TBM_ERROR_NONE);
1171 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1172 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1174 surf = (struct _tbm_surface *)surface;
1175 bo = surf->bos[bo_idx];
1177 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1179 _tbm_surface_mutex_unlock();
1185 tbm_surface_internal_get_size(tbm_surface_h surface)
1187 struct _tbm_surface *surf;
1190 _tbm_surface_mutex_lock();
1191 _tbm_set_last_result(TBM_ERROR_NONE);
1193 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1195 surf = (struct _tbm_surface *)surface;
1196 size = surf->info.size;
1198 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1200 _tbm_surface_mutex_unlock();
1206 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1207 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1209 struct _tbm_surface *surf;
1211 _tbm_surface_mutex_lock();
1212 _tbm_set_last_result(TBM_ERROR_NONE);
1214 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1215 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1217 surf = (struct _tbm_surface *)surface;
1219 if (plane_idx >= surf->info.num_planes) {
1220 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1221 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1222 _tbm_surface_mutex_unlock();
1227 *size = surf->info.planes[plane_idx].size;
1230 *offset = surf->info.planes[plane_idx].offset;
1233 *pitch = surf->info.planes[plane_idx].stride;
1235 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1236 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1237 surf->info.planes[plane_idx].stride);
1239 _tbm_surface_mutex_unlock();
1245 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1246 tbm_surface_info_s *info, int map)
1248 struct _tbm_surface *surf;
1249 tbm_bo_handle bo_handles[4];
1252 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1255 _tbm_surface_mutex_lock();
1256 _tbm_set_last_result(TBM_ERROR_NONE);
1258 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1260 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1262 surf = (struct _tbm_surface *)surface;
1264 memset(info, 0x00, sizeof(tbm_surface_info_s));
1265 info->width = surf->info.width;
1266 info->height = surf->info.height;
1267 info->format = surf->info.format;
1268 info->bpp = surf->info.bpp;
1269 info->size = surf->info.size;
1270 info->num_planes = surf->info.num_planes;
1272 for (i = 0; i < surf->info.num_planes; i++) {
1273 info->planes[i].size = surf->info.planes[i].size;
1274 info->planes[i].offset = surf->info.planes[i].offset;
1275 info->planes[i].stride = surf->info.planes[i].stride;
1276 planes_bo_idx[i] = surf->planes_bo_idx[i];
1279 for (i = 0; i < surf->num_bos; i++)
1280 bos[i] = surf->bos[i];
1282 num_bos = surf->num_bos;
1285 _tbm_surface_mutex_unlock();
1286 for (i = 0; i < num_bos; i++) {
1287 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1288 if (bo_handles[i].ptr == NULL) {
1289 for (j = 0; j < i; j++)
1290 tbm_bo_unmap(bos[j]);
1292 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1296 _tbm_surface_mutex_lock();
1298 for (i = 0; i < num_bos; i++) {
1299 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1300 if (bo_handles[i].ptr == NULL) {
1301 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1302 _tbm_surface_mutex_unlock();
1308 for (i = 0; i < info->num_planes; i++) {
1309 if (bo_handles[planes_bo_idx[i]].ptr)
1310 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1313 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1315 _tbm_surface_mutex_unlock();
1321 tbm_surface_internal_unmap(tbm_surface_h surface)
1323 struct _tbm_surface *surf;
1326 _tbm_surface_mutex_lock();
1327 _tbm_set_last_result(TBM_ERROR_NONE);
1329 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1331 surf = (struct _tbm_surface *)surface;
1333 for (i = 0; i < surf->num_bos; i++)
1334 tbm_bo_unmap(surf->bos[i]);
1336 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1338 _tbm_surface_mutex_unlock();
1342 tbm_surface_internal_get_width(tbm_surface_h surface)
1344 struct _tbm_surface *surf;
1347 _tbm_surface_mutex_lock();
1348 _tbm_set_last_result(TBM_ERROR_NONE);
1350 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1352 surf = (struct _tbm_surface *)surface;
1353 width = surf->info.width;
1355 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1357 _tbm_surface_mutex_unlock();
1363 tbm_surface_internal_get_height(tbm_surface_h surface)
1365 struct _tbm_surface *surf;
1366 unsigned int height;
1368 _tbm_surface_mutex_lock();
1369 _tbm_set_last_result(TBM_ERROR_NONE);
1371 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1373 surf = (struct _tbm_surface *)surface;
1374 height = surf->info.height;
1376 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1378 _tbm_surface_mutex_unlock();
1385 tbm_surface_internal_get_format(tbm_surface_h surface)
1387 struct _tbm_surface *surf;
1390 _tbm_surface_mutex_lock();
1391 _tbm_set_last_result(TBM_ERROR_NONE);
1393 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1395 surf = (struct _tbm_surface *)surface;
1396 format = surf->info.format;
1398 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1400 _tbm_surface_mutex_unlock();
1406 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1408 struct _tbm_surface *surf;
1411 _tbm_surface_mutex_lock();
1412 _tbm_set_last_result(TBM_ERROR_NONE);
1414 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1415 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1417 surf = (struct _tbm_surface *)surface;
1418 bo_idx = surf->planes_bo_idx[plane_idx];
1420 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1422 _tbm_surface_mutex_unlock();
1428 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1429 tbm_data_free data_free_func)
1431 tbm_user_data *data;
1433 _tbm_surface_mutex_lock();
1434 _tbm_set_last_result(TBM_ERROR_NONE);
1436 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1438 /* check if the data according to the key exist if so, return false. */
1439 data = user_data_lookup(&surface->user_data_list, key);
1441 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1442 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1443 _tbm_surface_mutex_unlock();
1447 data = user_data_create(key, data_free_func);
1449 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1450 _tbm_surface_mutex_unlock();
1454 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1456 LIST_ADD(&data->item_link, &surface->user_data_list);
1458 _tbm_surface_mutex_unlock();
1464 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1467 tbm_user_data *old_data;
1469 _tbm_surface_mutex_lock();
1470 _tbm_set_last_result(TBM_ERROR_NONE);
1472 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1474 old_data = user_data_lookup(&surface->user_data_list, key);
1476 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1477 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1478 _tbm_surface_mutex_unlock();
1482 if (old_data->data && old_data->free_func)
1483 old_data->free_func(old_data->data);
1485 old_data->data = data;
1487 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1489 _tbm_surface_mutex_unlock();
1495 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1498 tbm_user_data *old_data;
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), 0);
1506 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1507 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1508 _tbm_surface_mutex_unlock();
1513 old_data = user_data_lookup(&surface->user_data_list, key);
1515 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1516 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1517 _tbm_surface_mutex_unlock();
1521 *data = old_data->data;
1523 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1525 _tbm_surface_mutex_unlock();
1531 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1534 tbm_user_data *old_data = (void *)0;
1536 _tbm_surface_mutex_lock();
1537 _tbm_set_last_result(TBM_ERROR_NONE);
1539 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1541 old_data = user_data_lookup(&surface->user_data_list, key);
1543 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1544 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1545 _tbm_surface_mutex_unlock();
1549 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1551 user_data_delete(old_data);
1553 _tbm_surface_mutex_unlock();
1558 /* LCOV_EXCL_START */
1560 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1562 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1564 return surface->debug_pid;
1568 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1570 _tbm_surface_mutex_lock();
1571 _tbm_set_last_result(TBM_ERROR_NONE);
1573 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1575 surface->debug_pid = pid;
1577 _tbm_surface_mutex_unlock();
1580 static tbm_surface_debug_data *
1581 _tbm_surface_internal_debug_data_create(char *key, char *value)
1583 tbm_surface_debug_data *debug_data = NULL;
1585 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1587 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1588 TBM_ERR("fail to allocate the debug_data.");
1592 if (key) debug_data->key = strdup(key);
1593 if (value) debug_data->value = strdup(value);
1599 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1601 if (!debug_data->value && !value)
1604 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1607 if (debug_data->value)
1608 free(debug_data->value);
1611 debug_data->value = strdup(value);
1613 debug_data->value = NULL;
1616 static tbm_surface_debug_data *
1617 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1619 tbm_surface_debug_data *debug_data = NULL;
1621 if (LIST_IS_EMPTY(list))
1624 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1625 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1633 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1635 tbm_surface_debug_data *debug_data = NULL;
1636 tbm_bufmgr bufmgr = NULL;
1638 _tbm_surface_mutex_lock();
1639 _tbm_set_last_result(TBM_ERROR_NONE);
1641 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1642 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1644 bufmgr = surface->bufmgr;
1646 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1648 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1650 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1652 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1654 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1655 _tbm_surface_mutex_unlock();
1659 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1662 /* add new debug key to list */
1663 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1665 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1667 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1670 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1672 _tbm_surface_mutex_unlock();
1678 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1680 tbm_surface_debug_data *old_data = NULL;
1682 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1684 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1685 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1686 if (!strcmp(old_data->key, key))
1687 return old_data->value;
1694 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1695 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1697 struct _tbm_surface_dump_buf_info {
1707 tbm_surface_info_s info;
1709 struct list_head link;
1712 struct _tbm_surface_dump_info {
1713 char *path; // copy???
1716 struct list_head *link;
1717 struct list_head surface_list; /* link of surface */
1720 static tbm_surface_dump_info *g_dump_info = NULL;
1721 static const char *dump_postfix[2] = {"png", "yuv"};
1722 static double scale_factor;
1725 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1726 void *data2, int size2, void *data3, int size3)
1729 unsigned int *blocks;
1731 if (_tbm_surface_check_file_is_symbolic_link(file))
1732 TBM_ERR("%s is symbolic link\n", file);
1734 fp = fopen(file, "w+");
1735 TBM_RETURN_IF_FAIL(fp != NULL);
1737 blocks = (unsigned int *)data1;
1738 fwrite(blocks, 1, size1, fp);
1741 blocks = (unsigned int *)data2;
1742 fwrite(blocks, 1, size2, fp);
1746 blocks = (unsigned int *)data3;
1747 fwrite(blocks, 1, size3, fp);
1754 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1756 unsigned int *blocks = (unsigned int *)data;
1759 png_bytep *row_pointers;
1762 if (_tbm_surface_check_file_is_symbolic_link(file))
1763 TBM_ERR("%s is symbolic link\n", file);
1765 fp = fopen(file, "wb");
1766 TBM_RETURN_IF_FAIL(fp != NULL);
1768 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1771 TBM_ERR("fail to create a png write structure.\n");
1776 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1778 TBM_ERR("fail to create a png info structure.\n");
1779 png_destroy_write_struct(&pPngStruct, NULL);
1784 if (setjmp(png_jmpbuf(pPngStruct))) {
1785 /* if png has problem of writing the file, we get here */
1786 TBM_ERR("fail to write png file.\n");
1787 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1792 png_init_io(pPngStruct, fp);
1793 if (format == TBM_FORMAT_XRGB8888) {
1795 png_set_IHDR(pPngStruct,
1802 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1805 png_set_IHDR(pPngStruct,
1810 PNG_COLOR_TYPE_RGBA,
1812 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1815 png_set_bgr(pPngStruct);
1816 png_write_info(pPngStruct, pPngInfo);
1818 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1819 if (!row_pointers) {
1820 TBM_ERR("fail to allocate the png row_pointers.\n");
1821 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1826 for (y = 0; y < height; ++y) {
1830 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1832 TBM_ERR("fail to allocate the png row.\n");
1833 for (x = 0; x < y; x++)
1834 png_free(pPngStruct, row_pointers[x]);
1835 png_free(pPngStruct, row_pointers);
1836 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1840 row_pointers[y] = (png_bytep)row;
1842 for (x = 0; x < width; ++x) {
1843 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1845 if (pixel_size == 3) { // XRGB8888
1846 row[x * pixel_size] = (curBlock & 0xFF);
1847 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1848 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1849 } else { // ARGB8888
1850 row[x * pixel_size] = (curBlock & 0xFF);
1851 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1852 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1853 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1858 png_write_image(pPngStruct, row_pointers);
1859 png_write_end(pPngStruct, pPngInfo);
1861 for (y = 0; y < height; y++)
1862 png_free(pPngStruct, row_pointers[y]);
1863 png_free(pPngStruct, row_pointers);
1865 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1871 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1873 TBM_RETURN_IF_FAIL(path != NULL);
1874 TBM_RETURN_IF_FAIL(w > 0);
1875 TBM_RETURN_IF_FAIL(h > 0);
1876 TBM_RETURN_IF_FAIL(count > 0);
1878 tbm_surface_dump_buf_info *buf_info = NULL;
1879 tbm_surface_h tbm_surface;
1880 tbm_surface_info_s info;
1885 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1889 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1890 TBM_RETURN_IF_FAIL(g_dump_info);
1892 LIST_INITHEAD(&g_dump_info->surface_list);
1893 g_dump_info->count = 0;
1894 g_dump_info->dump_max = count;
1896 /* get buffer size */
1897 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1898 if (tbm_surface == NULL) {
1899 TBM_ERR("tbm_surface_create fail\n");
1905 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1906 TBM_ERR("tbm_surface_get_info fail\n");
1907 tbm_surface_destroy(tbm_surface);
1912 buffer_size = info.size;
1913 tbm_surface_destroy(tbm_surface);
1915 /* create dump lists */
1916 for (i = 0; i < count; i++) {
1919 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1920 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1922 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1924 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1929 buf_info->index = i;
1931 buf_info->size = buffer_size;
1933 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1936 g_dump_info->path = path;
1937 g_dump_info->link = &g_dump_info->surface_list;
1941 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1946 /* free resources */
1947 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1948 tbm_surface_dump_buf_info *tmp;
1950 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1951 tbm_bo_unref(buf_info->bo);
1952 LIST_DEL(&buf_info->link);
1957 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1966 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1973 tbm_surface_internal_dump_start(path, w, h, count);
1974 scale_factor = scale;
1978 tbm_surface_internal_dump_end(void)
1980 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1981 tbm_bo_handle bo_handle;
1986 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1993 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1996 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1997 if (bo_handle.ptr == NULL) {
1998 tbm_bo_unref(buf_info->bo);
1999 LIST_DEL(&buf_info->link);
2004 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2005 TBM_INFO("Dump File.. %s generated.\n", file);
2007 if (buf_info->dirty) {
2008 void *ptr1 = NULL, *ptr2 = NULL;
2010 switch (buf_info->info.format) {
2011 case TBM_FORMAT_ARGB8888:
2012 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2013 buf_info->info.planes[0].stride >> 2,
2014 buf_info->info.height,
2015 buf_info->info.planes[0].stride,
2016 TBM_FORMAT_ARGB8888);
2018 case TBM_FORMAT_XRGB8888:
2019 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2020 buf_info->info.planes[0].stride >> 2,
2021 buf_info->info.height,
2022 buf_info->info.planes[0].stride,
2023 TBM_FORMAT_XRGB8888);
2025 case TBM_FORMAT_YVU420:
2026 case TBM_FORMAT_YUV420:
2027 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2028 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2029 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2030 buf_info->info.planes[0].stride * buf_info->info.height,
2032 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2034 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2036 case TBM_FORMAT_NV12:
2037 case TBM_FORMAT_NV21:
2038 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2039 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2040 buf_info->info.planes[0].stride * buf_info->info.height,
2042 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2045 case TBM_FORMAT_YUYV:
2046 case TBM_FORMAT_UYVY:
2047 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2048 buf_info->info.planes[0].stride * buf_info->info.height,
2052 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2055 } else if (buf_info->dirty_shm)
2056 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2057 buf_info->shm_stride >> 2,
2059 buf_info->shm_stride, 0);
2061 tbm_bo_unmap(buf_info->bo);
2062 tbm_bo_unref(buf_info->bo);
2063 LIST_DEL(&buf_info->link);
2070 TBM_INFO("Dump End..\n");
2073 static pixman_format_code_t
2074 _tbm_surface_internal_pixman_format_get(tbm_format format)
2077 case TBM_FORMAT_ARGB8888:
2078 return PIXMAN_a8r8g8b8;
2079 case TBM_FORMAT_XRGB8888:
2080 return PIXMAN_x8r8g8b8;
2089 * This function supports only if a buffer has below formats.
2090 * - TBM_FORMAT_ARGB8888
2091 * - TBM_FORMAT_XRGB8888
2093 static tbm_surface_error_e
2094 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2095 int format, int src_stride, int src_w, int src_h,
2096 int dst_stride, int dst_w, int dst_h)
2098 pixman_image_t *src_img = NULL, *dst_img = NULL;
2099 pixman_format_code_t pixman_format;
2100 pixman_transform_t t;
2101 struct pixman_f_transform ft;
2102 double scale_x, scale_y;
2104 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2105 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2107 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2108 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2111 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2112 (uint32_t*)src_ptr, src_stride);
2113 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2116 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2117 (uint32_t*)dst_ptr, dst_stride);
2118 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2120 pixman_f_transform_init_identity(&ft);
2122 scale_x = (double)src_w / dst_w;
2123 scale_y = (double)src_h / dst_h;
2125 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2126 pixman_f_transform_translate(&ft, NULL, 0, 0);
2127 pixman_transform_from_pixman_f_transform(&t, &ft);
2128 pixman_image_set_transform(src_img, &t);
2130 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2131 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2133 pixman_image_unref(src_img);
2134 pixman_image_unref(dst_img);
2136 return TBM_SURFACE_ERROR_NONE;
2140 pixman_image_unref(src_img);
2142 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2145 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2146 #define KEY_LEN 5 // "_XXXX"
2147 #define KEYS_LEN KEY_LEN * MAX_BOS
2149 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2151 char *keys, temp_key[KEY_LEN + 1];
2152 struct _tbm_surface *surf;
2156 _tbm_surface_mutex_lock();
2158 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2160 surf = (struct _tbm_surface *)surface;
2162 num_bos = surf->num_bos;
2163 if (num_bos > MAX_BOS)
2166 keys = calloc(KEYS_LEN + 1, sizeof(char));
2168 TBM_ERR("Failed to alloc memory");
2169 _tbm_surface_mutex_unlock();
2173 for (i = 0; i < num_bos; i++) {
2174 memset(temp_key, 0x00, KEY_LEN + 1);
2176 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2177 strncat(keys, temp_key, KEY_LEN + 1);
2180 _tbm_surface_mutex_unlock();
2185 static void _tbm_surface_internal_put_keys(char *keys)
2192 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2194 TBM_RETURN_IF_FAIL(surface != NULL);
2195 TBM_RETURN_IF_FAIL(type != NULL);
2197 tbm_surface_dump_buf_info *buf_info;
2198 struct list_head *next_link;
2199 tbm_surface_info_s info;
2200 tbm_bo_handle bo_handle;
2201 const char *postfix;
2202 const char *format = NULL;
2209 next_link = g_dump_info->link->next;
2210 TBM_RETURN_IF_FAIL(next_link != NULL);
2212 if (next_link == &g_dump_info->surface_list) {
2213 next_link = next_link->next;
2214 TBM_RETURN_IF_FAIL(next_link != NULL);
2217 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2218 TBM_RETURN_IF_FAIL(buf_info != NULL);
2220 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2221 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2223 if (scale_factor > 0.0) {
2226 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2227 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2228 _tbm_surface_internal_format_to_str(info.format));
2229 tbm_surface_unmap(surface);
2233 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2235 buf_info->info.width = info.width * scale_factor;
2236 buf_info->info.height = info.height * scale_factor;
2237 buf_info->info.format = info.format;
2238 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2239 if (!buf_info->info.bpp) {
2240 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2241 tbm_surface_unmap(surface);
2244 buf_info->info.num_planes = 1;
2245 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2246 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2248 if (buf_info->info.size > buf_info->size) {
2249 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2250 buf_info->info.size, buf_info->size);
2251 tbm_surface_unmap(surface);
2255 if (info.size > buf_info->size) {
2256 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2257 info.size, buf_info->size);
2258 tbm_surface_unmap(surface);
2262 /* make the file information */
2263 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2266 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2267 postfix = dump_postfix[0];
2268 format = _tbm_surface_internal_format_to_str(info.format);
2270 postfix = dump_postfix[1];
2272 keys = _tbm_surface_internal_get_keys(surface);
2274 TBM_ERR("fail to get keys");
2275 tbm_surface_unmap(surface);
2280 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2281 if (!bo_handle.ptr) {
2282 TBM_ERR("fail to map bo");
2283 _tbm_surface_internal_put_keys(keys);
2284 tbm_surface_unmap(surface);
2287 memset(bo_handle.ptr, 0x00, buf_info->size);
2289 switch (info.format) {
2290 case TBM_FORMAT_ARGB8888:
2291 case TBM_FORMAT_XRGB8888:
2292 snprintf(buf_info->name, sizeof(buf_info->name),
2293 "%10.3f_%03d%s_%p_%s-%s.%s",
2294 _tbm_surface_internal_get_time(),
2295 g_dump_info->count++, keys, surface, format, type, postfix);
2297 if (scale_factor > 0.0) {
2298 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2300 buf_info->info.format,
2301 info.planes[0].stride,
2302 info.width, info.height,
2303 buf_info->info.planes[0].stride,
2304 buf_info->info.width,
2305 buf_info->info.height);
2306 if (ret != TBM_SURFACE_ERROR_NONE) {
2307 TBM_ERR("fail to scale buffer");
2308 tbm_bo_unmap(buf_info->bo);
2309 _tbm_surface_internal_put_keys(keys);
2310 tbm_surface_unmap(surface);
2314 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2316 case TBM_FORMAT_YVU420:
2317 case TBM_FORMAT_YUV420:
2318 snprintf(buf_info->name, sizeof(buf_info->name),
2319 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2320 _tbm_surface_internal_get_time(),
2321 g_dump_info->count++, keys, type, info.planes[0].stride,
2322 info.height, FOURCC_STR(info.format), postfix);
2323 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2324 bo_handle.ptr += info.planes[0].stride * info.height;
2325 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2326 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2327 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2329 case TBM_FORMAT_NV12:
2330 case TBM_FORMAT_NV21:
2331 snprintf(buf_info->name, sizeof(buf_info->name),
2332 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2333 _tbm_surface_internal_get_time(),
2334 g_dump_info->count++, keys, type, info.planes[0].stride,
2335 info.height, FOURCC_STR(info.format), postfix);
2336 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2337 bo_handle.ptr += info.planes[0].stride * info.height;
2338 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2340 case TBM_FORMAT_YUYV:
2341 case TBM_FORMAT_UYVY:
2342 snprintf(buf_info->name, sizeof(buf_info->name),
2343 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2344 _tbm_surface_internal_get_time(),
2345 g_dump_info->count++, keys, type, info.planes[0].stride,
2346 info.height, FOURCC_STR(info.format), postfix);
2347 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2350 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2351 tbm_bo_unmap(buf_info->bo);
2352 _tbm_surface_internal_put_keys(keys);
2353 tbm_surface_unmap(surface);
2357 tbm_bo_unmap(buf_info->bo);
2359 _tbm_surface_internal_put_keys(keys);
2361 tbm_surface_unmap(surface);
2363 buf_info->dirty = 1;
2364 buf_info->dirty_shm = 0;
2366 if (g_dump_info->count == 1000)
2367 g_dump_info->count = 0;
2369 g_dump_info->link = next_link;
2371 TBM_INFO("Dump %s \n", buf_info->name);
2374 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2377 TBM_RETURN_IF_FAIL(ptr != NULL);
2378 TBM_RETURN_IF_FAIL(w > 0);
2379 TBM_RETURN_IF_FAIL(h > 0);
2380 TBM_RETURN_IF_FAIL(stride > 0);
2381 TBM_RETURN_IF_FAIL(type != NULL);
2383 tbm_surface_dump_buf_info *buf_info;
2384 struct list_head *next_link;
2385 tbm_bo_handle bo_handle;
2386 int ret, size, dw = 0, dh = 0, dstride = 0;
2391 next_link = g_dump_info->link->next;
2392 TBM_RETURN_IF_FAIL(next_link != NULL);
2394 if (next_link == &g_dump_info->surface_list) {
2395 next_link = next_link->next;
2396 TBM_RETURN_IF_FAIL(next_link != NULL);
2399 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2400 TBM_RETURN_IF_FAIL(buf_info != NULL);
2402 if (scale_factor > 0.0) {
2405 dw = w * scale_factor;
2406 dh = h * scale_factor;
2408 size = dstride * dh;
2412 if (size > buf_info->size) {
2413 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2414 size, buf_info->size);
2419 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2420 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2422 memset(bo_handle.ptr, 0x00, buf_info->size);
2423 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2425 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2426 _tbm_surface_internal_get_time(),
2427 g_dump_info->count++, type, dump_postfix[0]);
2428 if (scale_factor > 0.0) {
2429 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2430 TBM_FORMAT_ARGB8888, stride,
2431 w, h, dstride, dw, dh);
2432 if (ret != TBM_SURFACE_ERROR_NONE) {
2433 TBM_ERR("fail to scale buffer");
2434 tbm_bo_unmap(buf_info->bo);
2437 buf_info->shm_stride = dstride;
2438 buf_info->shm_h = dh;
2440 memcpy(bo_handle.ptr, ptr, size);
2441 buf_info->shm_stride = stride;
2442 buf_info->shm_h = h;
2445 tbm_bo_unmap(buf_info->bo);
2447 buf_info->dirty = 0;
2448 buf_info->dirty_shm = 1;
2450 if (g_dump_info->count == 1000)
2451 g_dump_info->count = 0;
2453 g_dump_info->link = next_link;
2455 TBM_INFO("Dump %s \n", buf_info->name);
2459 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2461 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2462 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2463 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2465 tbm_surface_info_s info;
2466 const char *postfix;
2470 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2471 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2473 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2474 postfix = dump_postfix[0];
2476 postfix = dump_postfix[1];
2478 if (strcmp(postfix, type)) {
2479 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2480 tbm_surface_unmap(surface);
2484 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2486 if (!access(file, 0)) {
2487 TBM_ERR("can't capture buffer, exist file %s", file);
2488 tbm_surface_unmap(surface);
2492 switch (info.format) {
2493 case TBM_FORMAT_ARGB8888:
2494 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2497 info.planes[0].stride,
2498 TBM_FORMAT_ARGB8888);
2500 case TBM_FORMAT_XRGB8888:
2501 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2504 info.planes[0].stride,
2505 TBM_FORMAT_XRGB8888);
2507 case TBM_FORMAT_YVU420:
2508 case TBM_FORMAT_YUV420:
2509 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2510 info.planes[0].stride * info.height,
2512 info.planes[1].stride * (info.height >> 1),
2514 info.planes[2].stride * (info.height >> 1));
2516 case TBM_FORMAT_NV12:
2517 case TBM_FORMAT_NV21:
2518 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2519 info.planes[0].stride * info.height,
2521 info.planes[1].stride * (info.height >> 1),
2524 case TBM_FORMAT_YUYV:
2525 case TBM_FORMAT_UYVY:
2526 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2527 info.planes[0].stride * info.height,
2531 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2532 tbm_surface_unmap(surface);
2536 tbm_surface_unmap(surface);
2538 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2544 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2545 const char *path, const char *name, const char *type)
2547 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2548 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2549 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2550 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2551 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2552 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2556 if (strcmp(dump_postfix[0], type)) {
2557 TBM_ERR("Not supported type:%s'", type);
2561 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2563 if (!access(file, 0)) {
2564 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2568 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2570 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2576 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2578 struct _tbm_surface *surf;
2580 _tbm_surface_mutex_lock();
2581 _tbm_set_last_result(TBM_ERROR_NONE);
2583 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2584 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2585 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2587 surf = (struct _tbm_surface *)surface;
2591 surf->damage.width = width;
2592 surf->damage.height = height;
2594 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2595 surface, x, y, width, height);
2597 _tbm_surface_mutex_unlock();
2603 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2605 struct _tbm_surface *surf;
2607 _tbm_surface_mutex_lock();
2608 _tbm_set_last_result(TBM_ERROR_NONE);
2610 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2612 surf = (struct _tbm_surface *)surface;
2614 if (x) *x = surf->damage.x;
2615 if (y) *y = surf->damage.y;
2616 if (width) *width = surf->damage.width;
2617 if (height) *height = surf->damage.height;
2619 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2620 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2622 _tbm_surface_mutex_unlock();