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 static tbm_bufmgr g_surface_bufmgr;
45 static pthread_mutex_t tbm_surface_lock;
46 void _tbm_surface_mutex_unlock(void);
48 #define C(b, m) (((b) >> (m)) & 0xFF)
49 #define B(c, s) ((((unsigned int)(c)) & 0xff) << (s))
50 #define FOURCC(a, b, c, d) (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
51 #define FOURCC_STR(id) C(id, 0), C(id, 8), C(id, 16), C(id, 24)
52 #define FOURCC_ID(str) FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
55 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
57 TBM_ERR("'%s' failed.\n", #cond);\
58 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
59 _tbm_surface_mutex_unlock();\
64 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
66 TBM_ERR("'%s' failed.\n", #cond);\
67 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
68 _tbm_surface_mutex_unlock();\
75 _tbm_surface_internal_get_time(void)
80 clock_gettime(CLOCK_MONOTONIC, &tp);
81 time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
87 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
89 LIST_DEL(&debug_data->item_link);
91 if (debug_data->key) free(debug_data->key);
92 if (debug_data->value) free(debug_data->value);
97 _tbm_surface_internal_format_to_str(tbm_format format)
101 return "TBM_FORMAT_C8";
102 case TBM_FORMAT_RGB332:
103 return "TBM_FORMAT_RGB332";
104 case TBM_FORMAT_BGR233:
105 return "TBM_FORMAT_BGR233";
106 case TBM_FORMAT_XRGB4444:
107 return "TBM_FORMAT_XRGB4444";
108 case TBM_FORMAT_XBGR4444:
109 return "TBM_FORMAT_XBGR4444";
110 case TBM_FORMAT_RGBX4444:
111 return "TBM_FORMAT_RGBX4444";
112 case TBM_FORMAT_BGRX4444:
113 return "TBM_FORMAT_BGRX4444";
114 case TBM_FORMAT_ARGB4444:
115 return "TBM_FORMAT_ARGB4444";
116 case TBM_FORMAT_ABGR4444:
117 return "TBM_FORMAT_ABGR4444";
118 case TBM_FORMAT_RGBA4444:
119 return "TBM_FORMAT_RGBA4444";
120 case TBM_FORMAT_BGRA4444:
121 return "TBM_FORMAT_BGRA4444";
122 case TBM_FORMAT_XRGB1555:
123 return "TBM_FORMAT_XRGB1555";
124 case TBM_FORMAT_XBGR1555:
125 return "TBM_FORMAT_XBGR1555";
126 case TBM_FORMAT_RGBX5551:
127 return "TBM_FORMAT_RGBX5551";
128 case TBM_FORMAT_BGRX5551:
129 return "TBM_FORMAT_BGRX5551";
130 case TBM_FORMAT_ARGB1555:
131 return "TBM_FORMAT_ARGB1555";
132 case TBM_FORMAT_ABGR1555:
133 return "TBM_FORMAT_ABGR1555";
134 case TBM_FORMAT_RGBA5551:
135 return "TBM_FORMAT_RGBA5551";
136 case TBM_FORMAT_BGRA5551:
137 return "TBM_FORMAT_BGRA5551";
138 case TBM_FORMAT_RGB565:
139 return "TBM_FORMAT_RGB565";
140 case TBM_FORMAT_BGR565:
141 return "TBM_FORMAT_BGR565";
142 case TBM_FORMAT_RGB888:
143 return "TBM_FORMAT_RGB888";
144 case TBM_FORMAT_BGR888:
145 return "TBM_FORMAT_BGR888";
146 case TBM_FORMAT_XRGB8888:
147 return "TBM_FORMAT_XRGB8888";
148 case TBM_FORMAT_XBGR8888:
149 return "TBM_FORMAT_XBGR8888";
150 case TBM_FORMAT_RGBX8888:
151 return "TBM_FORMAT_RGBX8888";
152 case TBM_FORMAT_BGRX8888:
153 return "TBM_FORMAT_BGRX8888";
154 case TBM_FORMAT_ARGB8888:
155 return "TBM_FORMAT_ARGB8888";
156 case TBM_FORMAT_ABGR8888:
157 return "TBM_FORMAT_ABGR8888";
158 case TBM_FORMAT_RGBA8888:
159 return "TBM_FORMAT_RGBA8888";
160 case TBM_FORMAT_BGRA8888:
161 return "TBM_FORMAT_BGRA8888";
162 case TBM_FORMAT_XRGB2101010:
163 return "TBM_FORMAT_XRGB2101010";
164 case TBM_FORMAT_XBGR2101010:
165 return "TBM_FORMAT_XBGR2101010";
166 case TBM_FORMAT_RGBX1010102:
167 return "TBM_FORMAT_RGBX1010102";
168 case TBM_FORMAT_BGRX1010102:
169 return "TBM_FORMAT_BGRX1010102";
170 case TBM_FORMAT_ARGB2101010:
171 return "TBM_FORMAT_ARGB2101010";
172 case TBM_FORMAT_ABGR2101010:
173 return "TBM_FORMAT_ABGR2101010";
174 case TBM_FORMAT_RGBA1010102:
175 return "TBM_FORMAT_RGBA1010102";
176 case TBM_FORMAT_BGRA1010102:
177 return "TBM_FORMAT_BGRA1010102";
178 case TBM_FORMAT_YUYV:
179 return "TBM_FORMAT_YUYV";
180 case TBM_FORMAT_YVYU:
181 return "TBM_FORMAT_YVYU";
182 case TBM_FORMAT_UYVY:
183 return "TBM_FORMAT_UYVY";
184 case TBM_FORMAT_VYUY:
185 return "TBM_FORMAT_VYUY";
186 case TBM_FORMAT_AYUV:
187 return "TBM_FORMAT_AYUV";
188 case TBM_FORMAT_NV12:
189 return "TBM_FORMAT_NV12";
190 case TBM_FORMAT_NV21:
191 return "TBM_FORMAT_NV21";
192 case TBM_FORMAT_NV16:
193 return "TBM_FORMAT_NV16";
194 case TBM_FORMAT_NV61:
195 return "TBM_FORMAT_NV61";
196 case TBM_FORMAT_YUV410:
197 return "TBM_FORMAT_YUV410";
198 case TBM_FORMAT_YVU410:
199 return "TBM_FORMAT_YVU410";
200 case TBM_FORMAT_YUV411:
201 return "TBM_FORMAT_YUV411";
202 case TBM_FORMAT_YVU411:
203 return "TBM_FORMAT_YVU411";
204 case TBM_FORMAT_YUV420:
205 return "TBM_FORMAT_YUV420";
206 case TBM_FORMAT_YVU420:
207 return "TBM_FORMAT_YVU420";
208 case TBM_FORMAT_YUV422:
209 return "TBM_FORMAT_YUV422";
210 case TBM_FORMAT_YVU422:
211 return "TBM_FORMAT_YVU422";
212 case TBM_FORMAT_YUV444:
213 return "TBM_FORMAT_YUV444";
214 case TBM_FORMAT_YVU444:
215 return "TBM_FORMAT_YVU444";
216 case TBM_FORMAT_NV12MT:
217 return "TBM_FORMAT_NV12MT";
224 _tbm_surface_mutex_init(void)
226 static bool tbm_surface_mutex_init = false;
228 if (tbm_surface_mutex_init)
231 if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
232 TBM_ERR("fail: pthread_mutex_init for tbm_surface_lock.\n");
236 tbm_surface_mutex_init = true;
242 _tbm_surface_mutex_lock(void)
244 if (!_tbm_surface_mutex_init()) {
245 TBM_ERR("fail: _tbm_surface_mutex_init.\n");
249 pthread_mutex_lock(&tbm_surface_lock);
253 _tbm_surface_mutex_unlock(void)
255 pthread_mutex_unlock(&tbm_surface_lock);
259 _init_surface_bufmgr(void)
261 g_surface_bufmgr = tbm_bufmgr_init(-1);
265 _deinit_surface_bufmgr(void)
267 if (!g_surface_bufmgr)
270 tbm_bufmgr_deinit(g_surface_bufmgr);
271 g_surface_bufmgr = NULL;
276 _tbm_surface_internal_is_valid(tbm_surface_h surface)
278 tbm_surface_h old_data = NULL;
280 TBM_RETURN_VAL_IF_FAIL(g_surface_bufmgr, 0);
281 TBM_RETURN_VAL_IF_FAIL(surface, 0);
283 if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
284 LIST_FOR_EACH_ENTRY(old_data, &g_surface_bufmgr->surf_list, item_link) {
285 if (old_data == surface) {
286 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
292 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
294 TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
300 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
301 int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
303 TBM_RETURN_VAL_IF_FAIL(surface, 0);
304 TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
306 struct _tbm_surface *surf = (struct _tbm_surface *)surface;
307 struct _tbm_bufmgr *bufmgr = surf->bufmgr;
311 TBM_RETURN_VAL_IF_FAIL(bufmgr != NULL, 0);
312 TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
313 TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
314 TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
316 if (bufmgr->backend_module_data) {
317 if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
318 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
322 error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
323 surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
324 if (error != TBM_ERROR_NONE) {
325 /* LCOV_EXCL_START */
326 TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
327 _tbm_set_last_result(error);
333 if (!bufmgr->backend->surface_get_plane_data) {
334 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
338 ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
339 surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
341 /* LCOV_EXCL_START */
342 TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
343 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
353 _tbm_surface_internal_destroy(tbm_surface_h surface)
356 tbm_bufmgr bufmgr = surface->bufmgr;
357 tbm_user_data *old_data = NULL, *tmp = NULL;
358 tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
360 /* destory the user_data_list */
361 if (!LIST_IS_EMPTY(&surface->user_data_list)) {
362 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
363 TBM_DBG("free user_data\n");
364 user_data_delete(old_data);
368 for (i = 0; i < surface->num_bos; i++) {
369 surface->bos[i]->surface = NULL;
371 tbm_bo_unref(surface->bos[i]);
372 surface->bos[i] = NULL;
375 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
376 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
377 _tbm_surface_internal_debug_data_delete(debug_old_data);
380 LIST_DEL(&surface->item_link);
385 if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
386 LIST_DELINIT(&bufmgr->surf_list);
388 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
389 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
390 _tbm_surface_internal_debug_data_delete(debug_old_data);
394 _deinit_surface_bufmgr();
398 /* LCOV_EXCL_START */
400 _tbm_surface_check_file_is_symbolic_link(const char* path)
407 if (stat(path, &sb) != 0)
410 if (S_ISLNK(sb.st_mode))
418 _tbm_surface_internal_get_num_planes(tbm_format format)
424 case TBM_FORMAT_RGB332:
425 case TBM_FORMAT_BGR233:
426 case TBM_FORMAT_XRGB4444:
427 case TBM_FORMAT_XBGR4444:
428 case TBM_FORMAT_RGBX4444:
429 case TBM_FORMAT_BGRX4444:
430 case TBM_FORMAT_ARGB4444:
431 case TBM_FORMAT_ABGR4444:
432 case TBM_FORMAT_RGBA4444:
433 case TBM_FORMAT_BGRA4444:
434 case TBM_FORMAT_XRGB1555:
435 case TBM_FORMAT_XBGR1555:
436 case TBM_FORMAT_RGBX5551:
437 case TBM_FORMAT_BGRX5551:
438 case TBM_FORMAT_ARGB1555:
439 case TBM_FORMAT_ABGR1555:
440 case TBM_FORMAT_RGBA5551:
441 case TBM_FORMAT_BGRA5551:
442 case TBM_FORMAT_RGB565:
443 case TBM_FORMAT_BGR565:
444 case TBM_FORMAT_RGB888:
445 case TBM_FORMAT_BGR888:
446 case TBM_FORMAT_XRGB8888:
447 case TBM_FORMAT_XBGR8888:
448 case TBM_FORMAT_RGBX8888:
449 case TBM_FORMAT_BGRX8888:
450 case TBM_FORMAT_ARGB8888:
451 case TBM_FORMAT_ABGR8888:
452 case TBM_FORMAT_RGBA8888:
453 case TBM_FORMAT_BGRA8888:
454 case TBM_FORMAT_XRGB2101010:
455 case TBM_FORMAT_XBGR2101010:
456 case TBM_FORMAT_RGBX1010102:
457 case TBM_FORMAT_BGRX1010102:
458 case TBM_FORMAT_ARGB2101010:
459 case TBM_FORMAT_ABGR2101010:
460 case TBM_FORMAT_RGBA1010102:
461 case TBM_FORMAT_BGRA1010102:
462 case TBM_FORMAT_YUYV:
463 case TBM_FORMAT_YVYU:
464 case TBM_FORMAT_UYVY:
465 case TBM_FORMAT_VYUY:
466 case TBM_FORMAT_AYUV:
469 case TBM_FORMAT_NV12:
470 case TBM_FORMAT_NV12MT:
471 case TBM_FORMAT_NV21:
472 case TBM_FORMAT_NV16:
473 case TBM_FORMAT_NV61:
476 case TBM_FORMAT_YUV410:
477 case TBM_FORMAT_YVU410:
478 case TBM_FORMAT_YUV411:
479 case TBM_FORMAT_YVU411:
480 case TBM_FORMAT_YUV420:
481 case TBM_FORMAT_YVU420:
482 case TBM_FORMAT_YUV422:
483 case TBM_FORMAT_YVU422:
484 case TBM_FORMAT_YUV444:
485 case TBM_FORMAT_YVU444:
490 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
498 _tbm_surface_internal_get_bpp(tbm_format format)
505 case TBM_FORMAT_RGB332:
506 case TBM_FORMAT_BGR233:
509 case TBM_FORMAT_XRGB4444:
510 case TBM_FORMAT_XBGR4444:
511 case TBM_FORMAT_RGBX4444:
512 case TBM_FORMAT_BGRX4444:
513 case TBM_FORMAT_ARGB4444:
514 case TBM_FORMAT_ABGR4444:
515 case TBM_FORMAT_RGBA4444:
516 case TBM_FORMAT_BGRA4444:
517 case TBM_FORMAT_XRGB1555:
518 case TBM_FORMAT_XBGR1555:
519 case TBM_FORMAT_RGBX5551:
520 case TBM_FORMAT_BGRX5551:
521 case TBM_FORMAT_ARGB1555:
522 case TBM_FORMAT_ABGR1555:
523 case TBM_FORMAT_RGBA5551:
524 case TBM_FORMAT_BGRA5551:
525 case TBM_FORMAT_RGB565:
526 case TBM_FORMAT_BGR565:
529 case TBM_FORMAT_RGB888:
530 case TBM_FORMAT_BGR888:
533 case TBM_FORMAT_XRGB8888:
534 case TBM_FORMAT_XBGR8888:
535 case TBM_FORMAT_RGBX8888:
536 case TBM_FORMAT_BGRX8888:
537 case TBM_FORMAT_ARGB8888:
538 case TBM_FORMAT_ABGR8888:
539 case TBM_FORMAT_RGBA8888:
540 case TBM_FORMAT_BGRA8888:
541 case TBM_FORMAT_XRGB2101010:
542 case TBM_FORMAT_XBGR2101010:
543 case TBM_FORMAT_RGBX1010102:
544 case TBM_FORMAT_BGRX1010102:
545 case TBM_FORMAT_ARGB2101010:
546 case TBM_FORMAT_ABGR2101010:
547 case TBM_FORMAT_RGBA1010102:
548 case TBM_FORMAT_BGRA1010102:
549 case TBM_FORMAT_YUYV:
550 case TBM_FORMAT_YVYU:
551 case TBM_FORMAT_UYVY:
552 case TBM_FORMAT_VYUY:
553 case TBM_FORMAT_AYUV:
556 case TBM_FORMAT_NV12:
557 case TBM_FORMAT_NV12MT:
558 case TBM_FORMAT_NV21:
561 case TBM_FORMAT_NV16:
562 case TBM_FORMAT_NV61:
565 case TBM_FORMAT_YUV410:
566 case TBM_FORMAT_YVU410:
569 case TBM_FORMAT_YUV411:
570 case TBM_FORMAT_YVU411:
571 case TBM_FORMAT_YUV420:
572 case TBM_FORMAT_YVU420:
575 case TBM_FORMAT_YUV422:
576 case TBM_FORMAT_YVU422:
579 case TBM_FORMAT_YUV444:
580 case TBM_FORMAT_YVU444:
584 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
592 tbm_surface_internal_is_valid(tbm_surface_h surface)
596 _tbm_surface_mutex_lock();
597 _tbm_set_last_result(TBM_ERROR_NONE);
599 /* Return silently if surface is null. */
601 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
602 _tbm_surface_mutex_unlock();
606 ret = _tbm_surface_internal_is_valid(surface);
608 _tbm_surface_mutex_unlock();
614 tbm_surface_internal_query_supported_formats(uint32_t **formats,
617 struct _tbm_bufmgr *bufmgr;
619 bool bufmgr_initialized = false;
622 _tbm_surface_mutex_lock();
623 _tbm_set_last_result(TBM_ERROR_NONE);
625 TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
626 TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
628 if (!g_surface_bufmgr) {
629 _init_surface_bufmgr();
630 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
631 bufmgr_initialized = true;
634 bufmgr = g_surface_bufmgr;
636 if (bufmgr->backend_module_data) {
637 if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
638 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
642 error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
643 if (error != TBM_ERROR_NONE) {
644 /* LCOV_EXCL_START */
645 TBM_ERR("Fail to surface_supported_format. error(%d)\n", error);
647 /* LCOV_EXCL_START */
651 if (!bufmgr->backend->surface_supported_format) {
652 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
656 ret = bufmgr->backend->surface_supported_format(formats, num);
658 /* LCOV_EXCL_START */
659 TBM_ERR("Fail to surface_supported_format.\n");
660 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
662 /* LCOV_EXCL_START */
666 TBM_TRACE_SURFACE_INTERNAL("tbm_bufmgr(%p) format num(%u)\n", g_surface_bufmgr, *num);
668 if (bufmgr_initialized) {
669 LIST_DELINIT(&g_surface_bufmgr->surf_list);
670 _deinit_surface_bufmgr();
673 _tbm_surface_mutex_unlock();
677 /* LCOV_EXCL_START */
679 if (bufmgr_initialized) {
680 LIST_DELINIT(&g_surface_bufmgr->surf_list);
681 _deinit_surface_bufmgr();
683 _tbm_surface_mutex_unlock();
685 TBM_ERR("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
692 tbm_surface_internal_get_num_planes(tbm_format format)
696 _tbm_surface_mutex_lock();
697 _tbm_set_last_result(TBM_ERROR_NONE);
699 num_planes = _tbm_surface_internal_get_num_planes(format);
701 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
702 _tbm_surface_mutex_unlock();
706 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
708 _tbm_surface_mutex_unlock();
714 tbm_surface_internal_get_bpp(tbm_format format)
718 _tbm_surface_mutex_lock();
719 _tbm_set_last_result(TBM_ERROR_NONE);
721 bpp = _tbm_surface_internal_get_bpp(format);
723 TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
724 _tbm_surface_mutex_unlock();
728 _tbm_surface_mutex_unlock();
730 TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
736 tbm_surface_internal_create_with_flags(int width, int height,
737 int format, int flags)
739 struct _tbm_bufmgr *bufmgr;
740 struct _tbm_surface *surf = NULL;
744 uint32_t bo_size = 0;
747 bool bufmgr_initialized = false;
749 void *bo_priv = NULL;
750 tbm_backend_bo_data *bo_data = NULL;
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->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->backend_module_data) {
829 if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
830 /* LCOV_EXCL_START */
831 bo = calloc(1, sizeof(struct _tbm_bo));
833 TBM_ERR("fail to alloc bo struct\n");
834 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
838 bo->bufmgr = surf->bufmgr;
840 _tbm_bufmgr_mutex_lock();
842 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format(bufmgr->bufmgr_data, format, i,
843 width, height, flags, &error);
845 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
846 _tbm_set_last_result(error);
848 _tbm_bufmgr_mutex_unlock();
851 bo->bo_data = bo_data;
855 LIST_INITHEAD(&bo->user_data_list);
857 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
859 _tbm_bufmgr_mutex_unlock();
863 } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
864 bo = calloc(1, sizeof(struct _tbm_bo));
866 TBM_ERR("fail to alloc bo struct\n");
867 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
871 bo->bufmgr = surf->bufmgr;
873 _tbm_bufmgr_mutex_lock();
875 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format(bufmgr->bufmgr_data, width, height, surf->info.bpp/8, format, flags, i, &error);
877 TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
878 _tbm_set_last_result(error);
880 _tbm_bufmgr_mutex_unlock();
883 bo->bo_data = bo_data;
887 LIST_INITHEAD(&bo->user_data_list);
889 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
891 _tbm_bufmgr_mutex_unlock();
896 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
898 TBM_ERR("fail to alloc bo idx:%d\n", i);
903 if (bufmgr->backend->surface_bo_alloc) {
904 /* LCOV_EXCL_START */
905 bo = calloc(1, sizeof(struct _tbm_bo));
907 TBM_ERR("fail to alloc bo struct\n");
908 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
912 bo->bufmgr = surf->bufmgr;
914 _tbm_bufmgr_mutex_lock();
916 bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
918 TBM_ERR("fail to alloc bo priv\n");
919 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
921 _tbm_bufmgr_mutex_unlock();
928 LIST_INITHEAD(&bo->user_data_list);
930 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
932 _tbm_bufmgr_mutex_unlock();
937 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
939 TBM_ERR("fail to alloc bo idx:%d\n", i);
945 _tbm_bo_set_surface(surf->bos[i], surf);
948 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
949 _tbm_surface_internal_format_to_str(format), flags, surf);
951 LIST_INITHEAD(&surf->user_data_list);
952 LIST_INITHEAD(&surf->debug_data_list);
954 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
956 _tbm_surface_mutex_unlock();
960 /* LCOV_EXCL_START */
962 for (j = 0; j < i; j++) {
964 tbm_bo_unref(surf->bos[j]);
966 query_plane_data_fail:
972 if (bufmgr_initialized && bufmgr) {
973 LIST_DELINIT(&bufmgr->surf_list);
974 _deinit_surface_bufmgr();
976 _tbm_surface_mutex_unlock();
978 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
980 _tbm_surface_internal_format_to_str(format), flags);
987 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
988 tbm_bo *bos, int num)
990 struct _tbm_bufmgr *bufmgr;
991 struct _tbm_surface *surf = NULL;
993 bool bufmgr_initialized = false;
995 _tbm_surface_mutex_lock();
996 _tbm_set_last_result(TBM_ERROR_NONE);
998 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
999 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
1000 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
1001 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
1002 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
1004 if (!g_surface_bufmgr) {
1005 _init_surface_bufmgr();
1006 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
1007 bufmgr_initialized = true;
1010 bufmgr = g_surface_bufmgr;
1011 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
1012 TBM_ERR("fail to validate the Bufmgr.\n");
1013 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1014 goto check_valid_fail;
1017 surf = calloc(1, sizeof(struct _tbm_surface));
1019 /* LCOV_EXCL_START */
1020 TBM_ERR("fail to allocate struct _tbm_surface.\n");
1021 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1022 goto alloc_surf_fail;
1023 /* LCOV_EXCL_STOP */
1026 surf->bufmgr = bufmgr;
1027 surf->info.width = info->width;
1028 surf->info.height = info->height;
1029 surf->info.format = info->format;
1031 surf->info.bpp = info->bpp;
1033 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1034 if (!surf->info.bpp) {
1035 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1039 surf->info.num_planes = info->num_planes;
1042 /* get size, stride and offset */
1043 for (i = 0; i < info->num_planes; i++) {
1044 surf->info.planes[i].offset = info->planes[i].offset;
1045 surf->info.planes[i].stride = info->planes[i].stride;
1047 if (info->planes[i].size > 0)
1048 surf->info.planes[i].size = info->planes[i].size;
1050 uint32_t size = 0, offset = 0, stride = 0;
1053 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1054 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1055 goto plane_data_fail;
1057 surf->info.planes[i].size = size;
1061 surf->planes_bo_idx[i] = 0;
1063 surf->planes_bo_idx[i] = i;
1066 if (info->size > 0) {
1067 surf->info.size = info->size;
1069 surf->info.size = 0;
1070 for (i = 0; i < info->num_planes; i++)
1071 surf->info.size += surf->info.planes[i].size;
1074 surf->flags = TBM_BO_DEFAULT;
1076 /* create only one bo */
1077 surf->num_bos = num;
1078 for (i = 0; i < num; i++) {
1079 if (bos[i] == NULL) {
1080 TBM_ERR("bos[%d] is null.\n", i);
1081 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1085 surf->bos[i] = tbm_bo_ref(bos[i]);
1086 _tbm_bo_set_surface(bos[i], surf);
1089 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1090 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1092 LIST_INITHEAD(&surf->user_data_list);
1093 LIST_INITHEAD(&surf->debug_data_list);
1095 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1097 _tbm_surface_mutex_unlock();
1101 /* LCOV_EXCL_START */
1105 for (i = 0; i < num; i++) {
1107 tbm_bo_unref(surf->bos[i]);
1112 if (bufmgr_initialized && bufmgr) {
1113 LIST_DELINIT(&bufmgr->surf_list);
1114 _deinit_surface_bufmgr();
1116 _tbm_surface_mutex_unlock();
1118 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1119 info->width, info->height,
1120 _tbm_surface_internal_format_to_str(info->format), num);
1121 /* LCOV_EXCL_STOP */
1127 tbm_surface_internal_destroy(tbm_surface_h surface)
1129 _tbm_surface_mutex_lock();
1130 _tbm_set_last_result(TBM_ERROR_NONE);
1132 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1136 if (surface->refcnt > 0) {
1137 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1138 _tbm_surface_mutex_unlock();
1142 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1144 if (surface->refcnt == 0)
1145 _tbm_surface_internal_destroy(surface);
1147 _tbm_surface_mutex_unlock();
1151 tbm_surface_internal_ref(tbm_surface_h surface)
1153 _tbm_surface_mutex_lock();
1154 _tbm_set_last_result(TBM_ERROR_NONE);
1156 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1160 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1162 _tbm_surface_mutex_unlock();
1166 tbm_surface_internal_unref(tbm_surface_h surface)
1168 _tbm_surface_mutex_lock();
1169 _tbm_set_last_result(TBM_ERROR_NONE);
1171 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1175 if (surface->refcnt > 0) {
1176 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1177 _tbm_surface_mutex_unlock();
1181 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1183 if (surface->refcnt == 0)
1184 _tbm_surface_internal_destroy(surface);
1186 _tbm_surface_mutex_unlock();
1190 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1192 struct _tbm_surface *surf;
1195 _tbm_surface_mutex_lock();
1196 _tbm_set_last_result(TBM_ERROR_NONE);
1198 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1200 surf = (struct _tbm_surface *)surface;
1201 num = surf->num_bos;
1204 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1206 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1208 _tbm_surface_mutex_unlock();
1214 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1216 struct _tbm_surface *surf;
1219 _tbm_surface_mutex_lock();
1220 _tbm_set_last_result(TBM_ERROR_NONE);
1222 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1223 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1225 surf = (struct _tbm_surface *)surface;
1226 bo = surf->bos[bo_idx];
1228 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1230 _tbm_surface_mutex_unlock();
1236 tbm_surface_internal_get_size(tbm_surface_h surface)
1238 struct _tbm_surface *surf;
1241 _tbm_surface_mutex_lock();
1242 _tbm_set_last_result(TBM_ERROR_NONE);
1244 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1246 surf = (struct _tbm_surface *)surface;
1247 size = surf->info.size;
1249 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1251 _tbm_surface_mutex_unlock();
1257 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1258 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1260 struct _tbm_surface *surf;
1262 _tbm_surface_mutex_lock();
1263 _tbm_set_last_result(TBM_ERROR_NONE);
1265 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1266 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1268 surf = (struct _tbm_surface *)surface;
1270 if (plane_idx >= surf->info.num_planes) {
1271 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1272 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1273 _tbm_surface_mutex_unlock();
1278 *size = surf->info.planes[plane_idx].size;
1281 *offset = surf->info.planes[plane_idx].offset;
1284 *pitch = surf->info.planes[plane_idx].stride;
1286 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1287 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1288 surf->info.planes[plane_idx].stride);
1290 _tbm_surface_mutex_unlock();
1296 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1297 tbm_surface_info_s *info, int map)
1299 struct _tbm_surface *surf;
1300 tbm_bo_handle bo_handles[4];
1303 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1306 _tbm_surface_mutex_lock();
1307 _tbm_set_last_result(TBM_ERROR_NONE);
1309 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1311 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1313 surf = (struct _tbm_surface *)surface;
1315 memset(info, 0x00, sizeof(tbm_surface_info_s));
1316 info->width = surf->info.width;
1317 info->height = surf->info.height;
1318 info->format = surf->info.format;
1319 info->bpp = surf->info.bpp;
1320 info->size = surf->info.size;
1321 info->num_planes = surf->info.num_planes;
1323 for (i = 0; i < surf->info.num_planes; i++) {
1324 info->planes[i].size = surf->info.planes[i].size;
1325 info->planes[i].offset = surf->info.planes[i].offset;
1326 info->planes[i].stride = surf->info.planes[i].stride;
1327 planes_bo_idx[i] = surf->planes_bo_idx[i];
1330 for (i = 0; i < surf->num_bos; i++)
1331 bos[i] = surf->bos[i];
1333 num_bos = surf->num_bos;
1336 _tbm_surface_mutex_unlock();
1337 for (i = 0; i < num_bos; i++) {
1338 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1339 if (bo_handles[i].ptr == NULL) {
1340 for (j = 0; j < i; j++)
1341 tbm_bo_unmap(bos[j]);
1343 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1347 _tbm_surface_mutex_lock();
1349 for (i = 0; i < num_bos; i++) {
1350 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1351 if (bo_handles[i].ptr == NULL) {
1352 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1353 _tbm_surface_mutex_unlock();
1359 for (i = 0; i < info->num_planes; i++) {
1360 if (bo_handles[planes_bo_idx[i]].ptr)
1361 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1364 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1366 _tbm_surface_mutex_unlock();
1372 tbm_surface_internal_unmap(tbm_surface_h surface)
1374 struct _tbm_surface *surf;
1377 _tbm_surface_mutex_lock();
1378 _tbm_set_last_result(TBM_ERROR_NONE);
1380 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1382 surf = (struct _tbm_surface *)surface;
1384 for (i = 0; i < surf->num_bos; i++)
1385 tbm_bo_unmap(surf->bos[i]);
1387 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1389 _tbm_surface_mutex_unlock();
1393 tbm_surface_internal_get_width(tbm_surface_h surface)
1395 struct _tbm_surface *surf;
1398 _tbm_surface_mutex_lock();
1399 _tbm_set_last_result(TBM_ERROR_NONE);
1401 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1403 surf = (struct _tbm_surface *)surface;
1404 width = surf->info.width;
1406 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1408 _tbm_surface_mutex_unlock();
1414 tbm_surface_internal_get_height(tbm_surface_h surface)
1416 struct _tbm_surface *surf;
1417 unsigned int height;
1419 _tbm_surface_mutex_lock();
1420 _tbm_set_last_result(TBM_ERROR_NONE);
1422 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1424 surf = (struct _tbm_surface *)surface;
1425 height = surf->info.height;
1427 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1429 _tbm_surface_mutex_unlock();
1436 tbm_surface_internal_get_format(tbm_surface_h surface)
1438 struct _tbm_surface *surf;
1441 _tbm_surface_mutex_lock();
1442 _tbm_set_last_result(TBM_ERROR_NONE);
1444 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1446 surf = (struct _tbm_surface *)surface;
1447 format = surf->info.format;
1449 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1451 _tbm_surface_mutex_unlock();
1457 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1459 struct _tbm_surface *surf;
1462 _tbm_surface_mutex_lock();
1463 _tbm_set_last_result(TBM_ERROR_NONE);
1465 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1466 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1468 surf = (struct _tbm_surface *)surface;
1469 bo_idx = surf->planes_bo_idx[plane_idx];
1471 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1473 _tbm_surface_mutex_unlock();
1479 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1480 tbm_data_free data_free_func)
1482 tbm_user_data *data;
1484 _tbm_surface_mutex_lock();
1485 _tbm_set_last_result(TBM_ERROR_NONE);
1487 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1489 /* check if the data according to the key exist if so, return false. */
1490 data = user_data_lookup(&surface->user_data_list, key);
1492 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1493 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1494 _tbm_surface_mutex_unlock();
1498 data = user_data_create(key, data_free_func);
1500 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1501 _tbm_surface_mutex_unlock();
1505 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1507 LIST_ADD(&data->item_link, &surface->user_data_list);
1509 _tbm_surface_mutex_unlock();
1515 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1518 tbm_user_data *old_data;
1520 _tbm_surface_mutex_lock();
1521 _tbm_set_last_result(TBM_ERROR_NONE);
1523 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1525 old_data = user_data_lookup(&surface->user_data_list, key);
1527 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1528 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1529 _tbm_surface_mutex_unlock();
1533 if (old_data->data && old_data->free_func)
1534 old_data->free_func(old_data->data);
1536 old_data->data = data;
1538 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1540 _tbm_surface_mutex_unlock();
1546 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1549 tbm_user_data *old_data;
1551 _tbm_surface_mutex_lock();
1552 _tbm_set_last_result(TBM_ERROR_NONE);
1554 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1557 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1558 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1559 _tbm_surface_mutex_unlock();
1564 old_data = user_data_lookup(&surface->user_data_list, key);
1566 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1567 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1568 _tbm_surface_mutex_unlock();
1572 *data = old_data->data;
1574 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1576 _tbm_surface_mutex_unlock();
1582 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1585 tbm_user_data *old_data = (void *)0;
1587 _tbm_surface_mutex_lock();
1588 _tbm_set_last_result(TBM_ERROR_NONE);
1590 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1592 old_data = user_data_lookup(&surface->user_data_list, key);
1594 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1595 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1596 _tbm_surface_mutex_unlock();
1600 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1602 user_data_delete(old_data);
1604 _tbm_surface_mutex_unlock();
1609 /* LCOV_EXCL_START */
1611 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1613 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1615 return surface->debug_pid;
1619 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1621 _tbm_surface_mutex_lock();
1622 _tbm_set_last_result(TBM_ERROR_NONE);
1624 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1626 surface->debug_pid = pid;
1628 _tbm_surface_mutex_unlock();
1631 static tbm_surface_debug_data *
1632 _tbm_surface_internal_debug_data_create(char *key, char *value)
1634 tbm_surface_debug_data *debug_data = NULL;
1636 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1638 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1639 TBM_ERR("fail to allocate the debug_data.");
1643 if (key) debug_data->key = strdup(key);
1644 if (value) debug_data->value = strdup(value);
1650 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1652 tbm_surface_debug_data *debug_data = NULL;
1653 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1654 tbm_bufmgr bufmgr = NULL;
1656 _tbm_surface_mutex_lock();
1657 _tbm_set_last_result(TBM_ERROR_NONE);
1659 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1660 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1662 bufmgr = surface->bufmgr;
1664 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1666 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1667 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1669 if (!strcmp(old_data->key, key)) {
1670 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1671 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1672 goto add_debug_key_list;
1675 if (old_data->value)
1676 free(old_data->value);
1679 old_data->value = strdup(value);
1681 old_data->value = NULL;
1683 goto add_debug_key_list;
1689 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1691 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1692 _tbm_surface_mutex_unlock();
1696 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1698 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1701 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1702 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1703 if (!strcmp(old_data->key, key)) {
1704 _tbm_surface_mutex_unlock();
1710 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1711 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1713 _tbm_surface_mutex_unlock();
1719 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1721 tbm_surface_debug_data *old_data = NULL;
1723 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1725 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1726 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1727 if (!strcmp(old_data->key, key))
1728 return old_data->value;
1735 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1736 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1738 struct _tbm_surface_dump_buf_info {
1748 tbm_surface_info_s info;
1750 struct list_head link;
1753 struct _tbm_surface_dump_info {
1754 char *path; // copy???
1757 struct list_head *link;
1758 struct list_head surface_list; /* link of surface */
1761 static tbm_surface_dump_info *g_dump_info = NULL;
1762 static const char *dump_postfix[2] = {"png", "yuv"};
1763 static double scale_factor;
1766 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1767 void *data2, int size2, void *data3, int size3)
1770 unsigned int *blocks;
1772 if (_tbm_surface_check_file_is_symbolic_link(file))
1773 TBM_ERR("%s is symbolic link\n", file);
1775 fp = fopen(file, "w+");
1776 TBM_RETURN_IF_FAIL(fp != NULL);
1778 blocks = (unsigned int *)data1;
1779 fwrite(blocks, 1, size1, fp);
1782 blocks = (unsigned int *)data2;
1783 fwrite(blocks, 1, size2, fp);
1787 blocks = (unsigned int *)data3;
1788 fwrite(blocks, 1, size3, fp);
1795 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1797 unsigned int *blocks = (unsigned int *)data;
1800 png_bytep *row_pointers;
1803 if (_tbm_surface_check_file_is_symbolic_link(file))
1804 TBM_ERR("%s is symbolic link\n", file);
1806 fp = fopen(file, "wb");
1807 TBM_RETURN_IF_FAIL(fp != NULL);
1809 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1812 TBM_ERR("fail to create a png write structure.\n");
1817 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1819 TBM_ERR("fail to create a png info structure.\n");
1820 png_destroy_write_struct(&pPngStruct, NULL);
1825 png_init_io(pPngStruct, fp);
1826 if (format == TBM_FORMAT_XRGB8888) {
1828 png_set_IHDR(pPngStruct,
1835 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1838 png_set_IHDR(pPngStruct,
1843 PNG_COLOR_TYPE_RGBA,
1845 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1848 png_set_bgr(pPngStruct);
1849 png_write_info(pPngStruct, pPngInfo);
1851 row_pointers = png_malloc(pPngStruct, height * sizeof(png_byte *));
1852 if (!row_pointers) {
1853 TBM_ERR("fail to allocate the png row_pointers.\n");
1854 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1859 for (y = 0; y < height; ++y) {
1863 row = png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1865 TBM_ERR("fail to allocate the png row.\n");
1866 for (x = 0; x < y; x++)
1867 png_free(pPngStruct, row_pointers[x]);
1868 png_free(pPngStruct, row_pointers);
1869 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1873 row_pointers[y] = (png_bytep)row;
1875 for (x = 0; x < width; ++x) {
1876 unsigned int curBlock = blocks[y * width + x];
1878 if (pixel_size == 3) { // XRGB8888
1879 row[x * pixel_size] = (curBlock & 0xFF);
1880 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1881 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1882 } else { // ARGB8888
1883 row[x * pixel_size] = (curBlock & 0xFF);
1884 row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1885 row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1886 row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1891 png_write_image(pPngStruct, row_pointers);
1892 png_write_end(pPngStruct, pPngInfo);
1894 for (y = 0; y < height; y++)
1895 png_free(pPngStruct, row_pointers[y]);
1896 png_free(pPngStruct, row_pointers);
1898 png_destroy_write_struct(&pPngStruct, &pPngInfo);
1904 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1906 TBM_RETURN_IF_FAIL(path != NULL);
1907 TBM_RETURN_IF_FAIL(w > 0);
1908 TBM_RETURN_IF_FAIL(h > 0);
1909 TBM_RETURN_IF_FAIL(count > 0);
1911 tbm_surface_dump_buf_info *buf_info = NULL;
1912 tbm_surface_h tbm_surface;
1913 tbm_surface_info_s info;
1918 TBM_WRN("waring already running the tbm_surface_internal_dump.\n");
1922 g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1923 TBM_RETURN_IF_FAIL(g_dump_info);
1925 LIST_INITHEAD(&g_dump_info->surface_list);
1926 g_dump_info->count = 0;
1927 g_dump_info->dump_max = count;
1929 /* get buffer size */
1930 tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1931 if (tbm_surface == NULL) {
1932 TBM_ERR("tbm_surface_create fail\n");
1938 if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &info)) {
1939 TBM_ERR("tbm_surface_get_info fail\n");
1940 tbm_surface_destroy(tbm_surface);
1945 buffer_size = info.size;
1946 tbm_surface_destroy(tbm_surface);
1948 /* create dump lists */
1949 for (i = 0; i < count; i++) {
1952 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1953 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1955 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1957 TBM_ERR("fail to allocate the tbm_bo[%d]\n", i);
1962 buf_info->index = i;
1964 buf_info->size = buffer_size;
1966 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1969 g_dump_info->path = path;
1970 g_dump_info->link = &g_dump_info->surface_list;
1974 TBM_INFO("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1979 /* free resources */
1980 if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1981 tbm_surface_dump_buf_info *tmp;
1983 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1984 tbm_bo_unref(buf_info->bo);
1985 LIST_DEL(&buf_info->link);
1990 TBM_ERR("Dump Start fail.. path:%s\n", g_dump_info->path);
1999 tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale)
2006 tbm_surface_internal_dump_start(path, w, h, count);
2007 scale_factor = scale;
2011 tbm_surface_internal_dump_end(void)
2013 tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
2014 tbm_bo_handle bo_handle;
2019 if (LIST_IS_EMPTY(&g_dump_info->surface_list)) {
2026 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
2029 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
2030 if (bo_handle.ptr == NULL) {
2031 tbm_bo_unref(buf_info->bo);
2032 LIST_DEL(&buf_info->link);
2037 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
2038 TBM_INFO("Dump File.. %s generated.\n", file);
2040 if (buf_info->dirty) {
2041 void *ptr1 = NULL, *ptr2 = NULL;
2043 switch (buf_info->info.format) {
2044 case TBM_FORMAT_ARGB8888:
2045 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2046 buf_info->info.planes[0].stride >> 2,
2047 buf_info->info.height, TBM_FORMAT_ARGB8888);
2049 case TBM_FORMAT_XRGB8888:
2050 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2051 buf_info->info.planes[0].stride >> 2,
2052 buf_info->info.height, TBM_FORMAT_XRGB8888);
2054 case TBM_FORMAT_YVU420:
2055 case TBM_FORMAT_YUV420:
2056 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2057 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2058 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2059 buf_info->info.planes[0].stride * buf_info->info.height,
2061 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2063 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2065 case TBM_FORMAT_NV12:
2066 case TBM_FORMAT_NV21:
2067 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2068 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2069 buf_info->info.planes[0].stride * buf_info->info.height,
2071 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2074 case TBM_FORMAT_YUYV:
2075 case TBM_FORMAT_UYVY:
2076 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2077 buf_info->info.planes[0].stride * buf_info->info.height,
2081 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2084 } else if (buf_info->dirty_shm)
2085 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2086 buf_info->shm_stride >> 2,
2087 buf_info->shm_h, 0);
2089 tbm_bo_unmap(buf_info->bo);
2090 tbm_bo_unref(buf_info->bo);
2091 LIST_DEL(&buf_info->link);
2098 TBM_INFO("Dump End..\n");
2101 static pixman_format_code_t
2102 _tbm_surface_internal_pixman_format_get(tbm_format format)
2105 case TBM_FORMAT_ARGB8888:
2106 return PIXMAN_a8r8g8b8;
2107 case TBM_FORMAT_XRGB8888:
2108 return PIXMAN_x8r8g8b8;
2117 * This function supports only if a buffer has below formats.
2118 * - TBM_FORMAT_ARGB8888
2119 * - TBM_FORMAT_XRGB8888
2121 static tbm_surface_error_e
2122 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2123 int format, int src_stride, int src_w, int src_h,
2124 int dst_stride, int dst_w, int dst_h)
2126 pixman_image_t *src_img = NULL, *dst_img = NULL;
2127 pixman_format_code_t pixman_format;
2128 pixman_transform_t t;
2129 struct pixman_f_transform ft;
2130 double scale_x, scale_y;
2132 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2133 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2135 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2136 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2139 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2140 (uint32_t*)src_ptr, src_stride);
2141 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2144 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2145 (uint32_t*)dst_ptr, dst_stride);
2146 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2148 pixman_f_transform_init_identity(&ft);
2150 scale_x = (double)src_w / dst_w;
2151 scale_y = (double)src_h / dst_h;
2153 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2154 pixman_f_transform_translate(&ft, NULL, 0, 0);
2155 pixman_transform_from_pixman_f_transform(&t, &ft);
2156 pixman_image_set_transform(src_img, &t);
2158 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2159 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2161 pixman_image_unref(src_img);
2162 pixman_image_unref(dst_img);
2164 return TBM_SURFACE_ERROR_NONE;
2168 pixman_image_unref(src_img);
2170 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2173 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2174 #define KEY_LEN 5 // "_XXXX"
2175 #define KEYS_LEN KEY_LEN * MAX_BOS
2177 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2179 char *keys, temp_key[KEY_LEN + 1];
2180 struct _tbm_surface *surf;
2184 _tbm_surface_mutex_lock();
2186 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2188 surf = (struct _tbm_surface *)surface;
2190 num_bos = surf->num_bos;
2191 if (num_bos > MAX_BOS)
2194 keys = calloc(KEYS_LEN + 1, sizeof(char));
2196 TBM_ERR("Failed to alloc memory");
2197 _tbm_surface_mutex_unlock();
2201 for (i = 0; i < num_bos; i++) {
2202 memset(temp_key, 0x00, KEY_LEN + 1);
2204 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2205 strncat(keys, temp_key, KEY_LEN);
2208 _tbm_surface_mutex_unlock();
2213 static void _tbm_surface_internal_put_keys(char *keys)
2220 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2222 TBM_RETURN_IF_FAIL(surface != NULL);
2223 TBM_RETURN_IF_FAIL(type != NULL);
2225 tbm_surface_dump_buf_info *buf_info;
2226 struct list_head *next_link;
2227 tbm_surface_info_s info;
2228 tbm_bo_handle bo_handle;
2229 const char *postfix;
2230 const char *format = NULL;
2237 next_link = g_dump_info->link->next;
2238 TBM_RETURN_IF_FAIL(next_link != NULL);
2240 if (next_link == &g_dump_info->surface_list) {
2241 next_link = next_link->next;
2242 TBM_RETURN_IF_FAIL(next_link != NULL);
2245 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2246 TBM_RETURN_IF_FAIL(buf_info != NULL);
2248 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2249 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2251 if (scale_factor > 0.0) {
2254 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2255 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2256 _tbm_surface_internal_format_to_str(info.format));
2257 tbm_surface_unmap(surface);
2261 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2263 buf_info->info.width = info.width * scale_factor;
2264 buf_info->info.height = info.height * scale_factor;
2265 buf_info->info.format = info.format;
2266 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2267 if (!buf_info->info.bpp) {
2268 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2269 tbm_surface_unmap(surface);
2272 buf_info->info.num_planes = 1;
2273 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2274 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2276 if (buf_info->info.size > buf_info->size) {
2277 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2278 buf_info->info.size, buf_info->size);
2279 tbm_surface_unmap(surface);
2283 if (info.size > buf_info->size) {
2284 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2285 info.size, buf_info->size);
2286 tbm_surface_unmap(surface);
2290 /* make the file information */
2291 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2294 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2295 postfix = dump_postfix[0];
2296 format = _tbm_surface_internal_format_to_str(info.format);
2298 postfix = dump_postfix[1];
2300 keys = _tbm_surface_internal_get_keys(surface);
2302 TBM_ERR("fail to get keys");
2303 tbm_surface_unmap(surface);
2308 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2309 if (!bo_handle.ptr) {
2310 TBM_ERR("fail to map bo");
2311 _tbm_surface_internal_put_keys(keys);
2312 tbm_surface_unmap(surface);
2315 memset(bo_handle.ptr, 0x00, buf_info->size);
2317 switch (info.format) {
2318 case TBM_FORMAT_ARGB8888:
2319 case TBM_FORMAT_XRGB8888:
2320 snprintf(buf_info->name, sizeof(buf_info->name),
2321 "%10.3f_%03d%s_%p_%s-%s.%s",
2322 _tbm_surface_internal_get_time(),
2323 g_dump_info->count++, keys, surface, format, type, postfix);
2325 if (scale_factor > 0.0) {
2326 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2328 buf_info->info.format,
2329 info.planes[0].stride,
2330 info.width, info.height,
2331 buf_info->info.planes[0].stride,
2332 buf_info->info.width,
2333 buf_info->info.height);
2334 if (ret != TBM_SURFACE_ERROR_NONE) {
2335 TBM_ERR("fail to scale buffer");
2336 tbm_bo_unmap(buf_info->bo);
2337 _tbm_surface_internal_put_keys(keys);
2338 tbm_surface_unmap(surface);
2342 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2344 case TBM_FORMAT_YVU420:
2345 case TBM_FORMAT_YUV420:
2346 snprintf(buf_info->name, sizeof(buf_info->name),
2347 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2348 _tbm_surface_internal_get_time(),
2349 g_dump_info->count++, keys, type, info.planes[0].stride,
2350 info.height, FOURCC_STR(info.format), postfix);
2351 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2352 bo_handle.ptr += info.planes[0].stride * info.height;
2353 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2354 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2355 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2357 case TBM_FORMAT_NV12:
2358 case TBM_FORMAT_NV21:
2359 snprintf(buf_info->name, sizeof(buf_info->name),
2360 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2361 _tbm_surface_internal_get_time(),
2362 g_dump_info->count++, keys, type, info.planes[0].stride,
2363 info.height, FOURCC_STR(info.format), postfix);
2364 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2365 bo_handle.ptr += info.planes[0].stride * info.height;
2366 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2368 case TBM_FORMAT_YUYV:
2369 case TBM_FORMAT_UYVY:
2370 snprintf(buf_info->name, sizeof(buf_info->name),
2371 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2372 _tbm_surface_internal_get_time(),
2373 g_dump_info->count++, keys, type, info.planes[0].stride,
2374 info.height, FOURCC_STR(info.format), postfix);
2375 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2378 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2379 tbm_bo_unmap(buf_info->bo);
2380 _tbm_surface_internal_put_keys(keys);
2381 tbm_surface_unmap(surface);
2385 tbm_bo_unmap(buf_info->bo);
2387 _tbm_surface_internal_put_keys(keys);
2389 tbm_surface_unmap(surface);
2391 buf_info->dirty = 1;
2392 buf_info->dirty_shm = 0;
2394 if (g_dump_info->count == 1000)
2395 g_dump_info->count = 0;
2397 g_dump_info->link = next_link;
2399 TBM_INFO("Dump %s \n", buf_info->name);
2402 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2405 TBM_RETURN_IF_FAIL(ptr != NULL);
2406 TBM_RETURN_IF_FAIL(w > 0);
2407 TBM_RETURN_IF_FAIL(h > 0);
2408 TBM_RETURN_IF_FAIL(stride > 0);
2409 TBM_RETURN_IF_FAIL(type != NULL);
2411 tbm_surface_dump_buf_info *buf_info;
2412 struct list_head *next_link;
2413 tbm_bo_handle bo_handle;
2414 int ret, size, dw = 0, dh = 0, dstride = 0;
2419 next_link = g_dump_info->link->next;
2420 TBM_RETURN_IF_FAIL(next_link != NULL);
2422 if (next_link == &g_dump_info->surface_list) {
2423 next_link = next_link->next;
2424 TBM_RETURN_IF_FAIL(next_link != NULL);
2427 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2428 TBM_RETURN_IF_FAIL(buf_info != NULL);
2430 if (scale_factor > 0.0) {
2433 dw = w * scale_factor;
2434 dh = h * scale_factor;
2436 size = dstride * dh;
2440 if (size > buf_info->size) {
2441 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2442 size, buf_info->size);
2447 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2448 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2450 memset(bo_handle.ptr, 0x00, buf_info->size);
2451 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2453 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2454 _tbm_surface_internal_get_time(),
2455 g_dump_info->count++, type, dump_postfix[0]);
2456 if (scale_factor > 0.0) {
2457 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2458 TBM_FORMAT_ARGB8888, stride,
2459 w, h, dstride, dw, dh);
2460 if (ret != TBM_SURFACE_ERROR_NONE) {
2461 TBM_ERR("fail to scale buffer");
2462 tbm_bo_unmap(buf_info->bo);
2465 buf_info->shm_stride = dstride;
2466 buf_info->shm_h = dh;
2468 memcpy(bo_handle.ptr, ptr, size);
2469 buf_info->shm_stride = stride;
2470 buf_info->shm_h = h;
2473 tbm_bo_unmap(buf_info->bo);
2475 buf_info->dirty = 0;
2476 buf_info->dirty_shm = 1;
2478 if (g_dump_info->count == 1000)
2479 g_dump_info->count = 0;
2481 g_dump_info->link = next_link;
2483 TBM_INFO("Dump %s \n", buf_info->name);
2487 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2489 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2490 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2491 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2493 tbm_surface_info_s info;
2494 const char *postfix;
2498 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2499 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2501 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2502 postfix = dump_postfix[0];
2504 postfix = dump_postfix[1];
2506 if (strcmp(postfix, type)) {
2507 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2508 tbm_surface_unmap(surface);
2512 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2514 if (!access(file, 0)) {
2515 TBM_ERR("can't capture buffer, exist file %s", file);
2516 tbm_surface_unmap(surface);
2520 switch (info.format) {
2521 case TBM_FORMAT_ARGB8888:
2522 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2523 info.planes[0].stride >> 2,
2524 info.height, TBM_FORMAT_ARGB8888);
2526 case TBM_FORMAT_XRGB8888:
2527 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2528 info.planes[0].stride >> 2,
2529 info.height, TBM_FORMAT_XRGB8888);
2531 case TBM_FORMAT_YVU420:
2532 case TBM_FORMAT_YUV420:
2533 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2534 info.planes[0].stride * info.height,
2536 info.planes[1].stride * (info.height >> 1),
2538 info.planes[2].stride * (info.height >> 1));
2540 case TBM_FORMAT_NV12:
2541 case TBM_FORMAT_NV21:
2542 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2543 info.planes[0].stride * info.height,
2545 info.planes[1].stride * (info.height >> 1),
2548 case TBM_FORMAT_YUYV:
2549 case TBM_FORMAT_UYVY:
2550 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2551 info.planes[0].stride * info.height,
2555 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2556 tbm_surface_unmap(surface);
2560 tbm_surface_unmap(surface);
2562 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2568 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2569 const char *path, const char *name, const char *type)
2571 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2572 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2573 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2574 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2575 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2576 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2580 if (strcmp(dump_postfix[0], type)) {
2581 TBM_ERR("Not supported type:%s'", type);
2585 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2587 if (!access(file, 0)) {
2588 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2592 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2594 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2600 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2602 struct _tbm_surface *surf;
2604 _tbm_surface_mutex_lock();
2605 _tbm_set_last_result(TBM_ERROR_NONE);
2607 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2608 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2609 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2611 surf = (struct _tbm_surface *)surface;
2615 surf->damage.width = width;
2616 surf->damage.height = height;
2618 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2619 surface, x, y, width, height);
2621 _tbm_surface_mutex_unlock();
2627 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2629 struct _tbm_surface *surf;
2631 _tbm_surface_mutex_lock();
2632 _tbm_set_last_result(TBM_ERROR_NONE);
2634 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2636 surf = (struct _tbm_surface *)surface;
2638 if (x) *x = surf->damage.x;
2639 if (y) *y = surf->damage.y;
2640 if (width) *width = surf->damage.width;
2641 if (height) *height = surf->damage.height;
2643 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2644 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2646 _tbm_surface_mutex_unlock();