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);
639 } else if (bufmgr->backend_module_data) {
640 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
641 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
645 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
646 if (error != TBM_ERROR_NONE) {
647 /* LCOV_EXCL_START */
648 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
650 /* LCOV_EXCL_START */
654 if (!bufmgr->backend->surface_supported_format) {
655 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
659 ret = bufmgr->backend->surface_supported_format(formats, num);
661 /* LCOV_EXCL_START */
662 TBM_ERR("Fail to surface_supported_format.\n");
663 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
665 /* LCOV_EXCL_START */
669 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
671 if (bufmgr_initialized) {
672 LIST_DELINIT(&g_surface_bufmgr->surf_list);
673 _deinit_surface_bufmgr();
676 _tbm_surface_mutex_unlock();
680 /* LCOV_EXCL_START */
682 if (bufmgr_initialized) {
683 LIST_DELINIT(&g_surface_bufmgr->surf_list);
684 _deinit_surface_bufmgr();
686 _tbm_surface_mutex_unlock();
688 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
695 tbm_surface_internal_get_num_planes(tbm_format format)
699 _tbm_surface_mutex_lock();
700 _tbm_set_last_result(TBM_ERROR_NONE);
702 num_planes = _tbm_surface_internal_get_num_planes(format);
704 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
705 _tbm_surface_mutex_unlock();
709 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
711 _tbm_surface_mutex_unlock();
717 tbm_surface_internal_get_bpp(tbm_format format)
721 _tbm_surface_mutex_lock();
722 _tbm_set_last_result(TBM_ERROR_NONE);
724 bpp = _tbm_surface_internal_get_bpp(format);
726 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
727 _tbm_surface_mutex_unlock();
731 _tbm_surface_mutex_unlock();
733 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
739 tbm_surface_internal_create_with_flags(int width, int height,
740 int format, int flags)
742 struct _tbm_bufmgr *bufmgr;
743 struct _tbm_surface *surf = NULL;
747 uint32_t bo_size = 0;
750 bool bufmgr_initialized = false;
753 _tbm_surface_mutex_lock();
754 _tbm_set_last_result(TBM_ERROR_NONE);
756 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
757 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
759 if (!g_surface_bufmgr) {
760 _init_surface_bufmgr();
761 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
762 bufmgr_initialized = true;
765 bufmgr = g_surface_bufmgr;
766 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
767 TBM_ERR("The bufmgr is invalid\n");
768 goto check_valid_fail;
771 surf = calloc(1, sizeof(struct _tbm_surface));
773 /* LCOV_EXCL_START */
774 TBM_ERR("fail to alloc surf\n");
775 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
776 goto alloc_surf_fail;
780 surf->magic = TBM_SURFACE_MAGIC;
781 surf->bufmgr = bufmgr;
782 surf->info.width = width;
783 surf->info.height = height;
784 surf->info.format = format;
785 surf->info.bpp = _tbm_surface_internal_get_bpp(format);
786 if (!surf->info.bpp) {
787 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
790 surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
791 if (!surf->info.num_planes) {
792 TBM_ERR("fail to get num_planes. error(%s)\n", tbm_error_str(tbm_get_last_error()));
793 goto num_planes_fail;
797 /* get size, stride and offset bo_idx */
798 for (i = 0; i < surf->info.num_planes; i++) {
799 if (!_tbm_surface_internal_query_plane_data(surf, i, &size,
800 &offset, &stride, &bo_idx)) {
801 TBM_ERR("fail to query plane data\n");
802 goto query_plane_data_fail;
805 surf->info.planes[i].size = size;
806 surf->info.planes[i].offset = offset;
807 surf->info.planes[i].stride = stride;
808 surf->planes_bo_idx[i] = bo_idx;
813 for (i = 0; i < surf->info.num_planes; i++) {
814 surf->info.size += surf->info.planes[i].size;
816 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
817 surf->num_bos = surf->planes_bo_idx[i] + 1;
822 for (i = 0; i < surf->num_bos; i++) {
824 for (j = 0; j < surf->info.num_planes; j++) {
825 if (surf->planes_bo_idx[j] == i)
826 bo_size += surf->info.planes[j].size;
829 if (bufmgr->use_hal_tbm) {
830 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, flags, &error);
831 if (error == TBM_ERROR_NOT_SUPPORTED) {
832 if (flags & TBM_BO_TILED) {
833 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, &error);
834 if (error == TBM_ERROR_NOT_SUPPORTED) {
835 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
836 } else if (error != TBM_ERROR_NONE) {
837 TBM_ERR("fail to alloc bo idx:%d\n", i);
841 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
845 TBM_ERR("fail to alloc bo idx:%d\n", i);
848 } else if (error != TBM_ERROR_NONE) {
849 TBM_ERR("fail to alloc bo idx:%d\n", i);
852 } else if (bufmgr->backend_module_data) {
853 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
854 /* LCOV_EXCL_START */
855 surf->bos[i] = tbm_bo_alloc_with_format(bufmgr, format, i, width, height, flags, &error);
857 TBM_ERR("fail to tbm_bo_alloc_with_format idx:%d\n", i);
861 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
862 /* LCOV_EXCL_START */
863 surf->bos[i] = tbm_bo_alloc_with_tiled_format(bufmgr, width, height, surf->info.bpp/8, format, flags, i, &error);
865 TBM_ERR("fail to tbm_bo_alloc_with_tiled_format idx:%d\n", i);
870 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
872 TBM_ERR("fail to alloc bo idx:%d\n", i);
877 if (bufmgr->backend->surface_bo_alloc) {
878 /* LCOV_EXCL_START */
879 surf->bos[i] = tbm_bo_alloc_with_surface(bufmgr, width, height, format, flags, i);
881 TBM_ERR("fail to tbm_bo_alloc_with_surface idx:%d\n", i);
886 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
888 TBM_ERR("fail to alloc bo idx:%d\n", i);
894 _tbm_bo_set_surface(surf->bos[i], surf);
897 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
898 _tbm_surface_internal_format_to_str(format), flags, surf);
900 LIST_INITHEAD(&surf->user_data_list);
901 LIST_INITHEAD(&surf->debug_data_list);
903 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
905 _tbm_surface_mutex_unlock();
909 /* LCOV_EXCL_START */
911 for (j = 0; j < i; j++) {
913 tbm_bo_unref(surf->bos[j]);
915 query_plane_data_fail:
921 if (bufmgr_initialized && bufmgr) {
922 LIST_DELINIT(&bufmgr->surf_list);
923 _deinit_surface_bufmgr();
925 _tbm_surface_mutex_unlock();
927 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
929 _tbm_surface_internal_format_to_str(format), flags);
936 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
937 tbm_bo *bos, int num)
939 struct _tbm_bufmgr *bufmgr;
940 struct _tbm_surface *surf = NULL;
942 bool bufmgr_initialized = false;
944 _tbm_surface_mutex_lock();
945 _tbm_set_last_result(TBM_ERROR_NONE);
947 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
948 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
949 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
950 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
951 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
953 if (!g_surface_bufmgr) {
954 _init_surface_bufmgr();
955 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
956 bufmgr_initialized = true;
959 bufmgr = g_surface_bufmgr;
960 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
961 TBM_ERR("fail to validate the Bufmgr.\n");
962 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
963 goto check_valid_fail;
966 surf = calloc(1, sizeof(struct _tbm_surface));
968 /* LCOV_EXCL_START */
969 TBM_ERR("fail to allocate struct _tbm_surface.\n");
970 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
971 goto alloc_surf_fail;
975 surf->magic = TBM_SURFACE_MAGIC;
976 surf->bufmgr = bufmgr;
977 surf->info.width = info->width;
978 surf->info.height = info->height;
979 surf->info.format = info->format;
981 surf->info.bpp = info->bpp;
983 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
984 if (!surf->info.bpp) {
985 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
989 surf->info.num_planes = info->num_planes;
992 /* get size, stride and offset */
993 for (i = 0; i < info->num_planes; i++) {
994 surf->info.planes[i].offset = info->planes[i].offset;
995 surf->info.planes[i].stride = info->planes[i].stride;
997 if (info->planes[i].size > 0)
998 surf->info.planes[i].size = info->planes[i].size;
1000 uint32_t size = 0, offset = 0, stride = 0;
1003 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1004 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1005 goto plane_data_fail;
1007 surf->info.planes[i].size = size;
1011 surf->planes_bo_idx[i] = 0;
1013 surf->planes_bo_idx[i] = i;
1016 if (info->size > 0) {
1017 surf->info.size = info->size;
1019 surf->info.size = 0;
1020 for (i = 0; i < info->num_planes; i++)
1021 surf->info.size += surf->info.planes[i].size;
1024 surf->flags = TBM_BO_DEFAULT;
1026 /* create only one bo */
1027 surf->num_bos = num;
1028 for (i = 0; i < num; i++) {
1029 if (bos[i] == NULL) {
1030 TBM_ERR("bos[%d] is null.\n", i);
1031 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1035 surf->bos[i] = tbm_bo_ref(bos[i]);
1036 _tbm_bo_set_surface(bos[i], surf);
1039 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1040 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1042 LIST_INITHEAD(&surf->user_data_list);
1043 LIST_INITHEAD(&surf->debug_data_list);
1045 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1047 _tbm_surface_mutex_unlock();
1051 /* LCOV_EXCL_START */
1055 for (i = 0; i < num; i++) {
1057 tbm_bo_unref(surf->bos[i]);
1062 if (bufmgr_initialized && bufmgr) {
1063 LIST_DELINIT(&bufmgr->surf_list);
1064 _deinit_surface_bufmgr();
1066 _tbm_surface_mutex_unlock();
1068 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1069 info->width, info->height,
1070 _tbm_surface_internal_format_to_str(info->format), num);
1071 /* LCOV_EXCL_STOP */
1077 tbm_surface_internal_destroy(tbm_surface_h surface)
1079 _tbm_surface_mutex_lock();
1080 _tbm_set_last_result(TBM_ERROR_NONE);
1082 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1086 if (surface->refcnt > 0) {
1087 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1088 _tbm_surface_mutex_unlock();
1092 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1094 if (surface->refcnt == 0)
1095 _tbm_surface_internal_destroy(surface);
1097 _tbm_surface_mutex_unlock();
1101 tbm_surface_internal_ref(tbm_surface_h surface)
1103 _tbm_surface_mutex_lock();
1104 _tbm_set_last_result(TBM_ERROR_NONE);
1106 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1110 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1112 _tbm_surface_mutex_unlock();
1116 tbm_surface_internal_unref(tbm_surface_h surface)
1118 _tbm_surface_mutex_lock();
1119 _tbm_set_last_result(TBM_ERROR_NONE);
1121 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1125 if (surface->refcnt > 0) {
1126 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1127 _tbm_surface_mutex_unlock();
1131 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1133 if (surface->refcnt == 0)
1134 _tbm_surface_internal_destroy(surface);
1136 _tbm_surface_mutex_unlock();
1140 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1142 struct _tbm_surface *surf;
1145 _tbm_surface_mutex_lock();
1146 _tbm_set_last_result(TBM_ERROR_NONE);
1148 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1150 surf = (struct _tbm_surface *)surface;
1151 num = surf->num_bos;
1154 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1156 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1158 _tbm_surface_mutex_unlock();
1164 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1166 struct _tbm_surface *surf;
1169 _tbm_surface_mutex_lock();
1170 _tbm_set_last_result(TBM_ERROR_NONE);
1172 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1173 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1175 surf = (struct _tbm_surface *)surface;
1176 bo = surf->bos[bo_idx];
1178 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1180 _tbm_surface_mutex_unlock();
1186 tbm_surface_internal_get_size(tbm_surface_h surface)
1188 struct _tbm_surface *surf;
1191 _tbm_surface_mutex_lock();
1192 _tbm_set_last_result(TBM_ERROR_NONE);
1194 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1196 surf = (struct _tbm_surface *)surface;
1197 size = surf->info.size;
1199 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1201 _tbm_surface_mutex_unlock();
1207 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1208 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1210 struct _tbm_surface *surf;
1212 _tbm_surface_mutex_lock();
1213 _tbm_set_last_result(TBM_ERROR_NONE);
1215 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1216 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1218 surf = (struct _tbm_surface *)surface;
1220 if (plane_idx >= surf->info.num_planes) {
1221 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1222 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1223 _tbm_surface_mutex_unlock();
1228 *size = surf->info.planes[plane_idx].size;
1231 *offset = surf->info.planes[plane_idx].offset;
1234 *pitch = surf->info.planes[plane_idx].stride;
1236 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1237 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1238 surf->info.planes[plane_idx].stride);
1240 _tbm_surface_mutex_unlock();
1246 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1247 tbm_surface_info_s *info, int map)
1249 struct _tbm_surface *surf;
1250 tbm_bo_handle bo_handles[4];
1253 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1256 _tbm_surface_mutex_lock();
1257 _tbm_set_last_result(TBM_ERROR_NONE);
1259 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1261 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1263 surf = (struct _tbm_surface *)surface;
1265 memset(info, 0x00, sizeof(tbm_surface_info_s));
1266 info->width = surf->info.width;
1267 info->height = surf->info.height;
1268 info->format = surf->info.format;
1269 info->bpp = surf->info.bpp;
1270 info->size = surf->info.size;
1271 info->num_planes = surf->info.num_planes;
1273 for (i = 0; i < surf->info.num_planes; i++) {
1274 info->planes[i].size = surf->info.planes[i].size;
1275 info->planes[i].offset = surf->info.planes[i].offset;
1276 info->planes[i].stride = surf->info.planes[i].stride;
1277 planes_bo_idx[i] = surf->planes_bo_idx[i];
1280 for (i = 0; i < surf->num_bos; i++)
1281 bos[i] = surf->bos[i];
1283 num_bos = surf->num_bos;
1286 _tbm_surface_mutex_unlock();
1287 for (i = 0; i < num_bos; i++) {
1288 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1289 if (bo_handles[i].ptr == NULL) {
1290 for (j = 0; j < i; j++)
1291 tbm_bo_unmap(bos[j]);
1293 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1297 _tbm_surface_mutex_lock();
1299 for (i = 0; i < num_bos; i++) {
1300 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1301 if (bo_handles[i].ptr == NULL) {
1302 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1303 _tbm_surface_mutex_unlock();
1309 for (i = 0; i < info->num_planes; i++) {
1310 if (bo_handles[planes_bo_idx[i]].ptr)
1311 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1314 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1316 _tbm_surface_mutex_unlock();
1322 tbm_surface_internal_unmap(tbm_surface_h surface)
1324 struct _tbm_surface *surf;
1327 _tbm_surface_mutex_lock();
1328 _tbm_set_last_result(TBM_ERROR_NONE);
1330 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1332 surf = (struct _tbm_surface *)surface;
1334 for (i = 0; i < surf->num_bos; i++)
1335 tbm_bo_unmap(surf->bos[i]);
1337 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1339 _tbm_surface_mutex_unlock();
1343 tbm_surface_internal_get_width(tbm_surface_h surface)
1345 struct _tbm_surface *surf;
1348 _tbm_surface_mutex_lock();
1349 _tbm_set_last_result(TBM_ERROR_NONE);
1351 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1353 surf = (struct _tbm_surface *)surface;
1354 width = surf->info.width;
1356 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1358 _tbm_surface_mutex_unlock();
1364 tbm_surface_internal_get_height(tbm_surface_h surface)
1366 struct _tbm_surface *surf;
1367 unsigned int height;
1369 _tbm_surface_mutex_lock();
1370 _tbm_set_last_result(TBM_ERROR_NONE);
1372 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1374 surf = (struct _tbm_surface *)surface;
1375 height = surf->info.height;
1377 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1379 _tbm_surface_mutex_unlock();
1386 tbm_surface_internal_get_format(tbm_surface_h surface)
1388 struct _tbm_surface *surf;
1391 _tbm_surface_mutex_lock();
1392 _tbm_set_last_result(TBM_ERROR_NONE);
1394 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1396 surf = (struct _tbm_surface *)surface;
1397 format = surf->info.format;
1399 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1401 _tbm_surface_mutex_unlock();
1407 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1409 struct _tbm_surface *surf;
1412 _tbm_surface_mutex_lock();
1413 _tbm_set_last_result(TBM_ERROR_NONE);
1415 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1416 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1418 surf = (struct _tbm_surface *)surface;
1419 bo_idx = surf->planes_bo_idx[plane_idx];
1421 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1423 _tbm_surface_mutex_unlock();
1429 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1430 tbm_data_free data_free_func)
1432 tbm_user_data *data;
1434 _tbm_surface_mutex_lock();
1435 _tbm_set_last_result(TBM_ERROR_NONE);
1437 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1439 /* check if the data according to the key exist if so, return false. */
1440 data = user_data_lookup(&surface->user_data_list, key);
1442 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1443 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1444 _tbm_surface_mutex_unlock();
1448 data = user_data_create(key, data_free_func);
1450 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1451 _tbm_surface_mutex_unlock();
1455 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1457 LIST_ADD(&data->item_link, &surface->user_data_list);
1459 _tbm_surface_mutex_unlock();
1465 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1468 tbm_user_data *old_data;
1470 _tbm_surface_mutex_lock();
1471 _tbm_set_last_result(TBM_ERROR_NONE);
1473 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1475 old_data = user_data_lookup(&surface->user_data_list, key);
1477 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1478 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1479 _tbm_surface_mutex_unlock();
1483 if (old_data->data && old_data->free_func)
1484 old_data->free_func(old_data->data);
1486 old_data->data = data;
1488 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1490 _tbm_surface_mutex_unlock();
1496 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1499 tbm_user_data *old_data;
1501 _tbm_surface_mutex_lock();
1502 _tbm_set_last_result(TBM_ERROR_NONE);
1504 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1507 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1508 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1509 _tbm_surface_mutex_unlock();
1514 old_data = user_data_lookup(&surface->user_data_list, key);
1516 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1517 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1518 _tbm_surface_mutex_unlock();
1522 *data = old_data->data;
1524 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1526 _tbm_surface_mutex_unlock();
1532 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1535 tbm_user_data *old_data = (void *)0;
1537 _tbm_surface_mutex_lock();
1538 _tbm_set_last_result(TBM_ERROR_NONE);
1540 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1542 old_data = user_data_lookup(&surface->user_data_list, key);
1544 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1545 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1546 _tbm_surface_mutex_unlock();
1550 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1552 user_data_delete(old_data);
1554 _tbm_surface_mutex_unlock();
1559 /* LCOV_EXCL_START */
1561 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1563 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1565 return surface->debug_pid;
1569 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1571 _tbm_surface_mutex_lock();
1572 _tbm_set_last_result(TBM_ERROR_NONE);
1574 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1576 surface->debug_pid = pid;
1578 _tbm_surface_mutex_unlock();
1581 static tbm_surface_debug_data *
1582 _tbm_surface_internal_debug_data_create(char *key, char *value)
1584 tbm_surface_debug_data *debug_data = NULL;
1586 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1588 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1589 TBM_ERR("fail to allocate the debug_data.");
1593 if (key) debug_data->key = strdup(key);
1594 if (value) debug_data->value = strdup(value);
1600 _tbm_surface_internal_debug_data_value_update(tbm_surface_debug_data *debug_data, char *value)
1602 if (!debug_data->value && !value)
1605 if (debug_data->value && value && !strncmp(debug_data->value, value, strlen(debug_data->value)))
1608 if (debug_data->value)
1609 free(debug_data->value);
1612 debug_data->value = strdup(value);
1614 debug_data->value = NULL;
1617 static tbm_surface_debug_data *
1618 _tbm_surface_internal_debug_data_find(struct list_head *list, char *key)
1620 tbm_surface_debug_data *debug_data = NULL;
1622 if (LIST_IS_EMPTY(list))
1625 LIST_FOR_EACH_ENTRY(debug_data, list, item_link) {
1626 if (!strncmp(debug_data->key, key, strlen(debug_data->key)))
1634 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1636 tbm_surface_debug_data *debug_data = NULL;
1637 tbm_bufmgr bufmgr = NULL;
1639 _tbm_surface_mutex_lock();
1640 _tbm_set_last_result(TBM_ERROR_NONE);
1642 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1643 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1645 bufmgr = surface->bufmgr;
1647 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1649 debug_data = _tbm_surface_internal_debug_data_find(&surface->debug_data_list, key);
1651 _tbm_surface_internal_debug_data_value_update(debug_data, value);
1653 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1655 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1656 _tbm_surface_mutex_unlock();
1660 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1663 /* add new debug key to list */
1664 debug_data = _tbm_surface_internal_debug_data_find(&bufmgr->debug_key_list, key);
1666 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1668 LIST_ADDTAIL(&debug_data->item_link, &bufmgr->debug_key_list);
1671 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1673 _tbm_surface_mutex_unlock();
1679 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1681 tbm_surface_debug_data *old_data = NULL;
1683 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1685 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1686 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1687 if (!strcmp(old_data->key, key))
1688 return old_data->value;
1695 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1696 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1698 struct _tbm_surface_dump_buf_info {
1708 tbm_surface_info_s info;
1710 struct list_head link;
1713 struct _tbm_surface_dump_info {
1714 char *path; // copy???
1717 struct list_head *link;
1718 struct list_head surface_list; /* link of surface */
1721 static tbm_surface_dump_info *g_dump_info = NULL;
1722 static const char *dump_postfix[2] = {"png", "yuv"};
1723 static double scale_factor;
1726 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1727 void *data2, int size2, void *data3, int size3)
1730 unsigned int *blocks;
1732 if (_tbm_surface_check_file_is_symbolic_link(file))
1733 TBM_ERR("%s is symbolic link\n", file);
1735 fp = fopen(file, "w+");
1736 TBM_RETURN_IF_FAIL(fp != NULL);
1738 blocks = (unsigned int *)data1;
1739 fwrite(blocks, 1, size1, fp);
1742 blocks = (unsigned int *)data2;
1743 fwrite(blocks, 1, size2, fp);
1747 blocks = (unsigned int *)data3;
1748 fwrite(blocks, 1, size3, fp);
1755 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int stride, int format)
1757 unsigned int *blocks = (unsigned int *)data;
1760 png_bytep *row_pointers;
1763 if (_tbm_surface_check_file_is_symbolic_link(file))
1764 TBM_ERR("%s is symbolic link\n", file);
1766 fp = fopen(file, "wb");
1767 TBM_RETURN_IF_FAIL(fp != NULL);
1769 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1772 TBM_ERR("fail to create a png write structure.\n");
1777 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1779 TBM_ERR("fail to create a png info structure.\n");
1780 png_destroy_write_struct(&pPngStruct, NULL);
1785 if (setjmp(png_jmpbuf(pPngStruct))) {
1786 /* if png has problem of writing the file, we get here */
1787 TBM_ERR("fail to write png file.\n");
1788 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1793 png_init_io(pPngStruct, fp);
1794 if (format == TBM_FORMAT_XRGB8888) {
1796 png_set_IHDR(pPngStruct,
1803 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1806 png_set_IHDR(pPngStruct,
1811 PNG_COLOR_TYPE_RGBA,
1813 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1816 png_set_bgr(pPngStruct);
1817 png_write_info(pPngStruct, pPngInfo);
1819 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1820 if (!row_pointers) {
1821 TBM_ERR("fail to allocate the png row_pointers.\n");
1822 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1827 for (y = 0; y < height; ++y) {
1831 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1833 TBM_ERR("fail to allocate the png row.\n");
1834 for (x = 0; x < y; x++)
1835 png_free(pPngStruct, row_pointers[x]);
1836 png_free(pPngStruct, row_pointers);
1837 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1841 row_pointers[y] = (png_bytep)row;
1843 for (x = 0; x < width; ++x) {
1844 unsigned int curBlock = blocks[(y * (stride >> 2)) + x];
1846 if (pixel_size == 3) { // XRGB8888
1847 row[x * pixel_size] = (curBlock & 0xFF);
1848 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1849 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1850 } else { // ARGB8888
1851 row[x * pixel_size] = (curBlock & 0xFF);
1852 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1853 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1854 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1859 png_write_image(pPngStruct, row_pointers);
1860 png_write_end(pPngStruct, pPngInfo);
1862 for (y = 0; y < height; y++)
1863 png_free(pPngStruct, row_pointers[y]);
1864 png_free(pPngStruct, row_pointers);
1866 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1872 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1874 TBM_RETURN_IF_FAIL(path != NULL);
1875 TBM_RETURN_IF_FAIL(w > 0);
1876 TBM_RETURN_IF_FAIL(h > 0);
1877 TBM_RETURN_IF_FAIL(count > 0);
1879 tbm_surface_dump_buf_info *buf_info = NULL;
1880 tbm_surface_h tbm_surface;
1881 tbm_surface_info_s info;
1886 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1890 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1891 TBM_RETURN_IF_FAIL(g_dump_info);
1893 LIST_INITHEAD(&g_dump_info->surface_list);
1894 g_dump_info->count = 0;
1895 g_dump_info->dump_max = count;
1897 /* get buffer size */
1898 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1899 if (tbm_surface == NULL) {
1900 TBM_ERR("tbm_surface_create fail\n");
1906 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1907 TBM_ERR("tbm_surface_get_info fail\n");
1908 tbm_surface_destroy(tbm_surface);
1913 buffer_size = info.size;
1914 tbm_surface_destroy(tbm_surface);
1916 /* create dump lists */
1917 for (i = 0; i < count; i++) {
1920 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1921 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1923 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1925 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1930 buf_info->index = i;
1932 buf_info->size = buffer_size;
1934 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1937 g_dump_info->path = path;
1938 g_dump_info->link = &g_dump_info->surface_list;
1942 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1947 /* free resources */
1948 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1949 tbm_surface_dump_buf_info *tmp;
1951 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1952 tbm_bo_unref(buf_info->bo);
1953 LIST_DEL(&buf_info->link);
1958 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1967 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
1974 tbm_surface_internal_dump_start(path, w, h, count);
1975 scale_factor = scale;
1979 tbm_surface_internal_dump_end(void)
1981 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1982 tbm_bo_handle bo_handle;
1987 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1994 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1997 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1998 if (bo_handle.ptr == NULL) {
1999 tbm_bo_unref(buf_info->bo);
2000 LIST_DEL(&buf_info->link);
2005 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2006 TBM_INFO("Dump File.. %s generated.\n", file);
2008 if (buf_info->dirty) {
2009 void *ptr1 = NULL, *ptr2 = NULL;
2011 switch (buf_info->info.format) {
2012 case TBM_FORMAT_ARGB8888:
2013 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2014 buf_info->info.planes[0].stride >> 2,
2015 buf_info->info.height,
2016 buf_info->info.planes[0].stride,
2017 TBM_FORMAT_ARGB8888);
2019 case TBM_FORMAT_XRGB8888:
2020 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2021 buf_info->info.planes[0].stride >> 2,
2022 buf_info->info.height,
2023 buf_info->info.planes[0].stride,
2024 TBM_FORMAT_XRGB8888);
2026 case TBM_FORMAT_YVU420:
2027 case TBM_FORMAT_YUV420:
2028 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2029 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2030 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2031 buf_info->info.planes[0].stride * buf_info->info.height,
2033 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2035 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2037 case TBM_FORMAT_NV12:
2038 case TBM_FORMAT_NV21:
2039 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2040 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2041 buf_info->info.planes[0].stride * buf_info->info.height,
2043 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2046 case TBM_FORMAT_YUYV:
2047 case TBM_FORMAT_UYVY:
2048 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2049 buf_info->info.planes[0].stride * buf_info->info.height,
2053 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2056 } else if (buf_info->dirty_shm)
2057 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2058 buf_info->shm_stride >> 2,
2060 buf_info->shm_stride, 0);
2062 tbm_bo_unmap(buf_info->bo);
2063 tbm_bo_unref(buf_info->bo);
2064 LIST_DEL(&buf_info->link);
2071 TBM_INFO("Dump End..\n");
2074 static pixman_format_code_t
2075 _tbm_surface_internal_pixman_format_get(tbm_format format)
2078 case TBM_FORMAT_ARGB8888:
2079 return PIXMAN_a8r8g8b8;
2080 case TBM_FORMAT_XRGB8888:
2081 return PIXMAN_x8r8g8b8;
2090 * This function supports only if a buffer has below formats.
2091 * - TBM_FORMAT_ARGB8888
2092 * - TBM_FORMAT_XRGB8888
2094 static tbm_surface_error_e
2095 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2096 int format, int src_stride, int src_w, int src_h,
2097 int dst_stride, int dst_w, int dst_h)
2099 pixman_image_t *src_img = NULL, *dst_img = NULL;
2100 pixman_format_code_t pixman_format;
2101 pixman_transform_t t;
2102 struct pixman_f_transform ft;
2103 double scale_x, scale_y;
2105 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2106 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2108 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2109 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2112 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2113 (uint32_t*)src_ptr, src_stride);
2114 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2117 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2118 (uint32_t*)dst_ptr, dst_stride);
2119 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2121 pixman_f_transform_init_identity(&ft);
2123 scale_x = (double)src_w / dst_w;
2124 scale_y = (double)src_h / dst_h;
2126 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2127 pixman_f_transform_translate(&ft, NULL, 0, 0);
2128 pixman_transform_from_pixman_f_transform(&t, &ft);
2129 pixman_image_set_transform(src_img, &t);
2131 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2132 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2134 pixman_image_unref(src_img);
2135 pixman_image_unref(dst_img);
2137 return TBM_SURFACE_ERROR_NONE;
2141 pixman_image_unref(src_img);
2143 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2146 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2147 #define KEY_LEN 5 // "_XXXX"
2148 #define KEYS_LEN KEY_LEN * MAX_BOS
2150 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2152 char *keys, temp_key[KEY_LEN + 1];
2153 struct _tbm_surface *surf;
2157 _tbm_surface_mutex_lock();
2159 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2161 surf = (struct _tbm_surface *)surface;
2163 num_bos = surf->num_bos;
2164 if (num_bos > MAX_BOS)
2167 keys = calloc(KEYS_LEN + 1, sizeof(char));
2169 TBM_ERR("Failed to alloc memory");
2170 _tbm_surface_mutex_unlock();
2174 for (i = 0; i < num_bos; i++) {
2175 memset(temp_key, 0x00, KEY_LEN + 1);
2177 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2178 strncat(keys, temp_key, KEY_LEN + 1);
2181 _tbm_surface_mutex_unlock();
2186 static void _tbm_surface_internal_put_keys(char *keys)
2193 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2195 TBM_RETURN_IF_FAIL(surface != NULL);
2196 TBM_RETURN_IF_FAIL(type != NULL);
2198 tbm_surface_dump_buf_info *buf_info;
2199 struct list_head *next_link;
2200 tbm_surface_info_s info;
2201 tbm_bo_handle bo_handle;
2202 const char *postfix;
2203 const char *format = NULL;
2210 next_link = g_dump_info->link->next;
2211 TBM_RETURN_IF_FAIL(next_link != NULL);
2213 if (next_link == &g_dump_info->surface_list) {
2214 next_link = next_link->next;
2215 TBM_RETURN_IF_FAIL(next_link != NULL);
2218 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2219 TBM_RETURN_IF_FAIL(buf_info != NULL);
2221 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2222 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2224 if (scale_factor > 0.0) {
2227 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2228 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2229 _tbm_surface_internal_format_to_str(info.format));
2230 tbm_surface_unmap(surface);
2234 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2236 buf_info->info.width = info.width * scale_factor;
2237 buf_info->info.height = info.height * scale_factor;
2238 buf_info->info.format = info.format;
2239 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2240 if (!buf_info->info.bpp) {
2241 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2242 tbm_surface_unmap(surface);
2245 buf_info->info.num_planes = 1;
2246 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2247 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2249 if (buf_info->info.size > buf_info->size) {
2250 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2251 buf_info->info.size, buf_info->size);
2252 tbm_surface_unmap(surface);
2256 if (info.size > buf_info->size) {
2257 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2258 info.size, buf_info->size);
2259 tbm_surface_unmap(surface);
2263 /* make the file information */
2264 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2267 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2268 postfix = dump_postfix[0];
2269 format = _tbm_surface_internal_format_to_str(info.format);
2271 postfix = dump_postfix[1];
2273 keys = _tbm_surface_internal_get_keys(surface);
2275 TBM_ERR("fail to get keys");
2276 tbm_surface_unmap(surface);
2281 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2282 if (!bo_handle.ptr) {
2283 TBM_ERR("fail to map bo");
2284 _tbm_surface_internal_put_keys(keys);
2285 tbm_surface_unmap(surface);
2288 memset(bo_handle.ptr, 0x00, buf_info->size);
2290 switch (info.format) {
2291 case TBM_FORMAT_ARGB8888:
2292 case TBM_FORMAT_XRGB8888:
2293 snprintf(buf_info->name, sizeof(buf_info->name),
2294 "%10.3f_%03d%s_%p_%s-%s.%s",
2295 _tbm_surface_internal_get_time(),
2296 g_dump_info->count++, keys, surface, format, type, postfix);
2298 if (scale_factor > 0.0) {
2299 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2301 buf_info->info.format,
2302 info.planes[0].stride,
2303 info.width, info.height,
2304 buf_info->info.planes[0].stride,
2305 buf_info->info.width,
2306 buf_info->info.height);
2307 if (ret != TBM_SURFACE_ERROR_NONE) {
2308 TBM_ERR("fail to scale buffer");
2309 tbm_bo_unmap(buf_info->bo);
2310 _tbm_surface_internal_put_keys(keys);
2311 tbm_surface_unmap(surface);
2315 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2317 case TBM_FORMAT_YVU420:
2318 case TBM_FORMAT_YUV420:
2319 snprintf(buf_info->name, sizeof(buf_info->name),
2320 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2321 _tbm_surface_internal_get_time(),
2322 g_dump_info->count++, keys, type, info.planes[0].stride,
2323 info.height, FOURCC_STR(info.format), postfix);
2324 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2325 bo_handle.ptr += info.planes[0].stride * info.height;
2326 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2327 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2328 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2330 case TBM_FORMAT_NV12:
2331 case TBM_FORMAT_NV21:
2332 snprintf(buf_info->name, sizeof(buf_info->name),
2333 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2334 _tbm_surface_internal_get_time(),
2335 g_dump_info->count++, keys, type, info.planes[0].stride,
2336 info.height, FOURCC_STR(info.format), postfix);
2337 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2338 bo_handle.ptr += info.planes[0].stride * info.height;
2339 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2341 case TBM_FORMAT_YUYV:
2342 case TBM_FORMAT_UYVY:
2343 snprintf(buf_info->name, sizeof(buf_info->name),
2344 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2345 _tbm_surface_internal_get_time(),
2346 g_dump_info->count++, keys, type, info.planes[0].stride,
2347 info.height, FOURCC_STR(info.format), postfix);
2348 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2351 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2352 tbm_bo_unmap(buf_info->bo);
2353 _tbm_surface_internal_put_keys(keys);
2354 tbm_surface_unmap(surface);
2358 tbm_bo_unmap(buf_info->bo);
2360 _tbm_surface_internal_put_keys(keys);
2362 tbm_surface_unmap(surface);
2364 buf_info->dirty = 1;
2365 buf_info->dirty_shm = 0;
2367 if (g_dump_info->count == 1000)
2368 g_dump_info->count = 0;
2370 g_dump_info->link = next_link;
2372 TBM_INFO("Dump %s \n", buf_info->name);
2375 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2378 TBM_RETURN_IF_FAIL(ptr != NULL);
2379 TBM_RETURN_IF_FAIL(w > 0);
2380 TBM_RETURN_IF_FAIL(h > 0);
2381 TBM_RETURN_IF_FAIL(stride > 0);
2382 TBM_RETURN_IF_FAIL(type != NULL);
2384 tbm_surface_dump_buf_info *buf_info;
2385 struct list_head *next_link;
2386 tbm_bo_handle bo_handle;
2387 int ret, size, dw = 0, dh = 0, dstride = 0;
2392 next_link = g_dump_info->link->next;
2393 TBM_RETURN_IF_FAIL(next_link != NULL);
2395 if (next_link == &g_dump_info->surface_list) {
2396 next_link = next_link->next;
2397 TBM_RETURN_IF_FAIL(next_link != NULL);
2400 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2401 TBM_RETURN_IF_FAIL(buf_info != NULL);
2403 if (scale_factor > 0.0) {
2406 dw = w * scale_factor;
2407 dh = h * scale_factor;
2409 size = dstride * dh;
2413 if (size > buf_info->size) {
2414 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2415 size, buf_info->size);
2420 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2421 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2423 memset(bo_handle.ptr, 0x00, buf_info->size);
2424 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2426 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2427 _tbm_surface_internal_get_time(),
2428 g_dump_info->count++, type, dump_postfix[0]);
2429 if (scale_factor > 0.0) {
2430 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2431 TBM_FORMAT_ARGB8888, stride,
2432 w, h, dstride, dw, dh);
2433 if (ret != TBM_SURFACE_ERROR_NONE) {
2434 TBM_ERR("fail to scale buffer");
2435 tbm_bo_unmap(buf_info->bo);
2438 buf_info->shm_stride = dstride;
2439 buf_info->shm_h = dh;
2441 memcpy(bo_handle.ptr, ptr, size);
2442 buf_info->shm_stride = stride;
2443 buf_info->shm_h = h;
2446 tbm_bo_unmap(buf_info->bo);
2448 buf_info->dirty = 0;
2449 buf_info->dirty_shm = 1;
2451 if (g_dump_info->count == 1000)
2452 g_dump_info->count = 0;
2454 g_dump_info->link = next_link;
2456 TBM_INFO("Dump %s \n", buf_info->name);
2460 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2462 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2463 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2464 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2466 tbm_surface_info_s info;
2467 const char *postfix;
2471 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2472 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2474 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2475 postfix = dump_postfix[0];
2477 postfix = dump_postfix[1];
2479 if (strcmp(postfix, type)) {
2480 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2481 tbm_surface_unmap(surface);
2485 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2487 if (!access(file, 0)) {
2488 TBM_ERR("can't capture buffer, exist file %s", file);
2489 tbm_surface_unmap(surface);
2493 switch (info.format) {
2494 case TBM_FORMAT_ARGB8888:
2495 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2498 info.planes[0].stride,
2499 TBM_FORMAT_ARGB8888);
2501 case TBM_FORMAT_XRGB8888:
2502 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2505 info.planes[0].stride,
2506 TBM_FORMAT_XRGB8888);
2508 case TBM_FORMAT_YVU420:
2509 case TBM_FORMAT_YUV420:
2510 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2511 info.planes[0].stride * info.height,
2513 info.planes[1].stride * (info.height >> 1),
2515 info.planes[2].stride * (info.height >> 1));
2517 case TBM_FORMAT_NV12:
2518 case TBM_FORMAT_NV21:
2519 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2520 info.planes[0].stride * info.height,
2522 info.planes[1].stride * (info.height >> 1),
2525 case TBM_FORMAT_YUYV:
2526 case TBM_FORMAT_UYVY:
2527 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2528 info.planes[0].stride * info.height,
2532 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2533 tbm_surface_unmap(surface);
2537 tbm_surface_unmap(surface);
2539 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2545 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2546 const char *path, const char *name, const char *type)
2548 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2549 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2550 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2551 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2552 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2553 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2557 if (strcmp(dump_postfix[0], type)) {
2558 TBM_ERR("Not supported type:%s'", type);
2562 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2564 if (!access(file, 0)) {
2565 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2569 _tbm_surface_internal_dump_file_png(file, ptr, w, h, stride, 0);
2571 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2577 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2579 struct _tbm_surface *surf;
2581 _tbm_surface_mutex_lock();
2582 _tbm_set_last_result(TBM_ERROR_NONE);
2584 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2585 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2586 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2588 surf = (struct _tbm_surface *)surface;
2592 surf->damage.width = width;
2593 surf->damage.height = height;
2595 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2596 surface, x, y, width, height);
2598 _tbm_surface_mutex_unlock();
2604 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2606 struct _tbm_surface *surf;
2608 _tbm_surface_mutex_lock();
2609 _tbm_set_last_result(TBM_ERROR_NONE);
2611 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2613 surf = (struct _tbm_surface *)surface;
2615 if (x) *x = surf->damage.x;
2616 if (y) *y = surf->damage.y;
2617 if (width) *width = surf->damage.width;
2618 if (height) *height = surf->damage.height;
2620 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2621 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2623 _tbm_surface_mutex_unlock();