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();
864 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
866 TBM_ERR("fail to alloc bo idx:%d\n", i);
871 if (bufmgr->backend->surface_bo_alloc) {
872 /* LCOV_EXCL_START */
873 bo = calloc(1, sizeof(struct _tbm_bo));
875 TBM_ERR("fail to alloc bo struct\n");
876 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
880 bo->bufmgr = surf->bufmgr;
882 _tbm_bufmgr_mutex_lock();
884 bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
886 TBM_ERR("fail to alloc bo priv\n");
887 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
889 _tbm_bufmgr_mutex_unlock();
896 LIST_INITHEAD(&bo->user_data_list);
898 LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
900 _tbm_bufmgr_mutex_unlock();
905 surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
907 TBM_ERR("fail to alloc bo idx:%d\n", i);
913 _tbm_bo_set_surface(surf->bos[i], surf);
916 TBM_TRACE_SURFACE_INTERNAL("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
917 _tbm_surface_internal_format_to_str(format), flags, surf);
919 LIST_INITHEAD(&surf->user_data_list);
920 LIST_INITHEAD(&surf->debug_data_list);
922 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
924 _tbm_surface_mutex_unlock();
928 /* LCOV_EXCL_START */
930 for (j = 0; j < i; j++) {
932 tbm_bo_unref(surf->bos[j]);
934 query_plane_data_fail:
940 if (bufmgr_initialized && bufmgr) {
941 LIST_DELINIT(&bufmgr->surf_list);
942 _deinit_surface_bufmgr();
944 _tbm_surface_mutex_unlock();
946 TBM_ERR("error: width(%d) height(%d) format(%s) flags(%d)\n",
948 _tbm_surface_internal_format_to_str(format), flags);
955 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
956 tbm_bo *bos, int num)
958 struct _tbm_bufmgr *bufmgr;
959 struct _tbm_surface *surf = NULL;
961 bool bufmgr_initialized = false;
963 _tbm_surface_mutex_lock();
964 _tbm_set_last_result(TBM_ERROR_NONE);
966 TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
967 TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
968 TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
969 TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
970 TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
972 if (!g_surface_bufmgr) {
973 _init_surface_bufmgr();
974 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
975 bufmgr_initialized = true;
978 bufmgr = g_surface_bufmgr;
979 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
980 TBM_ERR("fail to validate the Bufmgr.\n");
981 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
982 goto check_valid_fail;
985 surf = calloc(1, sizeof(struct _tbm_surface));
987 /* LCOV_EXCL_START */
988 TBM_ERR("fail to allocate struct _tbm_surface.\n");
989 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
990 goto alloc_surf_fail;
994 surf->bufmgr = bufmgr;
995 surf->info.width = info->width;
996 surf->info.height = info->height;
997 surf->info.format = info->format;
999 surf->info.bpp = info->bpp;
1001 surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
1002 if (!surf->info.bpp) {
1003 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1007 surf->info.num_planes = info->num_planes;
1010 /* get size, stride and offset */
1011 for (i = 0; i < info->num_planes; i++) {
1012 surf->info.planes[i].offset = info->planes[i].offset;
1013 surf->info.planes[i].stride = info->planes[i].stride;
1015 if (info->planes[i].size > 0)
1016 surf->info.planes[i].size = info->planes[i].size;
1018 uint32_t size = 0, offset = 0, stride = 0;
1021 if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
1022 TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
1023 goto plane_data_fail;
1025 surf->info.planes[i].size = size;
1029 surf->planes_bo_idx[i] = 0;
1031 surf->planes_bo_idx[i] = i;
1034 if (info->size > 0) {
1035 surf->info.size = info->size;
1037 surf->info.size = 0;
1038 for (i = 0; i < info->num_planes; i++)
1039 surf->info.size += surf->info.planes[i].size;
1042 surf->flags = TBM_BO_DEFAULT;
1044 /* create only one bo */
1045 surf->num_bos = num;
1046 for (i = 0; i < num; i++) {
1047 if (bos[i] == NULL) {
1048 TBM_ERR("bos[%d] is null.\n", i);
1049 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1053 surf->bos[i] = tbm_bo_ref(bos[i]);
1054 _tbm_bo_set_surface(bos[i], surf);
1057 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u) height(%u) format(%s) bo_num(%d)\n", surf,
1058 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
1060 LIST_INITHEAD(&surf->user_data_list);
1061 LIST_INITHEAD(&surf->debug_data_list);
1063 LIST_ADD(&surf->item_link, &bufmgr->surf_list);
1065 _tbm_surface_mutex_unlock();
1069 /* LCOV_EXCL_START */
1073 for (i = 0; i < num; i++) {
1075 tbm_bo_unref(surf->bos[i]);
1080 if (bufmgr_initialized && bufmgr) {
1081 LIST_DELINIT(&bufmgr->surf_list);
1082 _deinit_surface_bufmgr();
1084 _tbm_surface_mutex_unlock();
1086 TBM_ERR("error: width(%u) height(%u) format(%s) bo_num(%d)\n",
1087 info->width, info->height,
1088 _tbm_surface_internal_format_to_str(info->format), num);
1089 /* LCOV_EXCL_STOP */
1095 tbm_surface_internal_destroy(tbm_surface_h surface)
1097 _tbm_surface_mutex_lock();
1098 _tbm_set_last_result(TBM_ERROR_NONE);
1100 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1104 if (surface->refcnt > 0) {
1105 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1106 _tbm_surface_mutex_unlock();
1110 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1112 if (surface->refcnt == 0)
1113 _tbm_surface_internal_destroy(surface);
1115 _tbm_surface_mutex_unlock();
1119 tbm_surface_internal_ref(tbm_surface_h surface)
1121 _tbm_surface_mutex_lock();
1122 _tbm_set_last_result(TBM_ERROR_NONE);
1124 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1128 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1130 _tbm_surface_mutex_unlock();
1134 tbm_surface_internal_unref(tbm_surface_h surface)
1136 _tbm_surface_mutex_lock();
1137 _tbm_set_last_result(TBM_ERROR_NONE);
1139 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1143 if (surface->refcnt > 0) {
1144 TBM_TRACE_SURFACE_INTERNAL("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
1145 _tbm_surface_mutex_unlock();
1149 TBM_TRACE_SURFACE_INTERNAL("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
1151 if (surface->refcnt == 0)
1152 _tbm_surface_internal_destroy(surface);
1154 _tbm_surface_mutex_unlock();
1158 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
1160 struct _tbm_surface *surf;
1163 _tbm_surface_mutex_lock();
1164 _tbm_set_last_result(TBM_ERROR_NONE);
1166 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1168 surf = (struct _tbm_surface *)surface;
1169 num = surf->num_bos;
1172 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1174 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
1176 _tbm_surface_mutex_unlock();
1182 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
1184 struct _tbm_surface *surf;
1187 _tbm_surface_mutex_lock();
1188 _tbm_set_last_result(TBM_ERROR_NONE);
1190 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
1191 TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
1193 surf = (struct _tbm_surface *)surface;
1194 bo = surf->bos[bo_idx];
1196 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
1198 _tbm_surface_mutex_unlock();
1204 tbm_surface_internal_get_size(tbm_surface_h surface)
1206 struct _tbm_surface *surf;
1209 _tbm_surface_mutex_lock();
1210 _tbm_set_last_result(TBM_ERROR_NONE);
1212 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1214 surf = (struct _tbm_surface *)surface;
1215 size = surf->info.size;
1217 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) size(%u)\n", surface, size);
1219 _tbm_surface_mutex_unlock();
1225 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
1226 uint32_t *size, uint32_t *offset, uint32_t *pitch)
1228 struct _tbm_surface *surf;
1230 _tbm_surface_mutex_lock();
1231 _tbm_set_last_result(TBM_ERROR_NONE);
1233 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1234 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1236 surf = (struct _tbm_surface *)surface;
1238 if (plane_idx >= surf->info.num_planes) {
1239 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
1240 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1241 _tbm_surface_mutex_unlock();
1246 *size = surf->info.planes[plane_idx].size;
1249 *offset = surf->info.planes[plane_idx].offset;
1252 *pitch = surf->info.planes[plane_idx].stride;
1254 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) size(%u) offset(%u) pitch(%u)\n", surface, plane_idx,
1255 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1256 surf->info.planes[plane_idx].stride);
1258 _tbm_surface_mutex_unlock();
1264 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1265 tbm_surface_info_s *info, int map)
1267 struct _tbm_surface *surf;
1268 tbm_bo_handle bo_handles[4];
1271 int planes_bo_idx[TBM_SURF_PLANE_MAX];
1274 _tbm_surface_mutex_lock();
1275 _tbm_set_last_result(TBM_ERROR_NONE);
1277 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1279 memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1281 surf = (struct _tbm_surface *)surface;
1283 memset(info, 0x00, sizeof(tbm_surface_info_s));
1284 info->width = surf->info.width;
1285 info->height = surf->info.height;
1286 info->format = surf->info.format;
1287 info->bpp = surf->info.bpp;
1288 info->size = surf->info.size;
1289 info->num_planes = surf->info.num_planes;
1291 for (i = 0; i < surf->info.num_planes; i++) {
1292 info->planes[i].size = surf->info.planes[i].size;
1293 info->planes[i].offset = surf->info.planes[i].offset;
1294 info->planes[i].stride = surf->info.planes[i].stride;
1295 planes_bo_idx[i] = surf->planes_bo_idx[i];
1298 for (i = 0; i < surf->num_bos; i++)
1299 bos[i] = surf->bos[i];
1301 num_bos = surf->num_bos;
1304 _tbm_surface_mutex_unlock();
1305 for (i = 0; i < num_bos; i++) {
1306 bo_handles[i] = tbm_bo_map(bos[i], TBM_DEVICE_CPU, opt);
1307 if (bo_handles[i].ptr == NULL) {
1308 for (j = 0; j < i; j++)
1309 tbm_bo_unmap(bos[j]);
1311 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1315 _tbm_surface_mutex_lock();
1317 for (i = 0; i < num_bos; i++) {
1318 bo_handles[i] = tbm_bo_get_handle(bos[i], TBM_DEVICE_CPU);
1319 if (bo_handles[i].ptr == NULL) {
1320 TBM_ERR("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1321 _tbm_surface_mutex_unlock();
1327 for (i = 0; i < info->num_planes; i++) {
1328 if (bo_handles[planes_bo_idx[i]].ptr)
1329 info->planes[i].ptr = bo_handles[planes_bo_idx[i]].ptr + info->planes[i].offset;
1332 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1334 _tbm_surface_mutex_unlock();
1340 tbm_surface_internal_unmap(tbm_surface_h surface)
1342 struct _tbm_surface *surf;
1345 _tbm_surface_mutex_lock();
1346 _tbm_set_last_result(TBM_ERROR_NONE);
1348 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1350 surf = (struct _tbm_surface *)surface;
1352 for (i = 0; i < surf->num_bos; i++)
1353 tbm_bo_unmap(surf->bos[i]);
1355 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
1357 _tbm_surface_mutex_unlock();
1361 tbm_surface_internal_get_width(tbm_surface_h surface)
1363 struct _tbm_surface *surf;
1366 _tbm_surface_mutex_lock();
1367 _tbm_set_last_result(TBM_ERROR_NONE);
1369 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1371 surf = (struct _tbm_surface *)surface;
1372 width = surf->info.width;
1374 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) width(%u)\n", surface, width);
1376 _tbm_surface_mutex_unlock();
1382 tbm_surface_internal_get_height(tbm_surface_h surface)
1384 struct _tbm_surface *surf;
1385 unsigned int height;
1387 _tbm_surface_mutex_lock();
1388 _tbm_set_last_result(TBM_ERROR_NONE);
1390 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1392 surf = (struct _tbm_surface *)surface;
1393 height = surf->info.height;
1395 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) height(%u)\n", surface, height);
1397 _tbm_surface_mutex_unlock();
1404 tbm_surface_internal_get_format(tbm_surface_h surface)
1406 struct _tbm_surface *surf;
1409 _tbm_surface_mutex_lock();
1410 _tbm_set_last_result(TBM_ERROR_NONE);
1412 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1414 surf = (struct _tbm_surface *)surface;
1415 format = surf->info.format;
1417 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1419 _tbm_surface_mutex_unlock();
1425 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1427 struct _tbm_surface *surf;
1430 _tbm_surface_mutex_lock();
1431 _tbm_set_last_result(TBM_ERROR_NONE);
1433 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1434 TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1436 surf = (struct _tbm_surface *)surface;
1437 bo_idx = surf->planes_bo_idx[plane_idx];
1439 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1441 _tbm_surface_mutex_unlock();
1447 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1448 tbm_data_free data_free_func)
1450 tbm_user_data *data;
1452 _tbm_surface_mutex_lock();
1453 _tbm_set_last_result(TBM_ERROR_NONE);
1455 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1457 /* check if the data according to the key exist if so, return false. */
1458 data = user_data_lookup(&surface->user_data_list, key);
1460 TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1461 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1462 _tbm_surface_mutex_unlock();
1466 data = user_data_create(key, data_free_func);
1468 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1469 _tbm_surface_mutex_unlock();
1473 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1475 LIST_ADD(&data->item_link, &surface->user_data_list);
1477 _tbm_surface_mutex_unlock();
1483 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1486 tbm_user_data *old_data;
1488 _tbm_surface_mutex_lock();
1489 _tbm_set_last_result(TBM_ERROR_NONE);
1491 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1493 old_data = user_data_lookup(&surface->user_data_list, key);
1495 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1496 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1497 _tbm_surface_mutex_unlock();
1501 if (old_data->data && old_data->free_func)
1502 old_data->free_func(old_data->data);
1504 old_data->data = data;
1506 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1508 _tbm_surface_mutex_unlock();
1514 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1517 tbm_user_data *old_data;
1519 _tbm_surface_mutex_lock();
1520 _tbm_set_last_result(TBM_ERROR_NONE);
1522 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1525 TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
1526 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1527 _tbm_surface_mutex_unlock();
1532 old_data = user_data_lookup(&surface->user_data_list, key);
1534 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1535 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1536 _tbm_surface_mutex_unlock();
1540 *data = old_data->data;
1542 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1544 _tbm_surface_mutex_unlock();
1550 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1553 tbm_user_data *old_data = (void *)0;
1555 _tbm_surface_mutex_lock();
1556 _tbm_set_last_result(TBM_ERROR_NONE);
1558 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1560 old_data = user_data_lookup(&surface->user_data_list, key);
1562 TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
1563 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1564 _tbm_surface_mutex_unlock();
1568 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1570 user_data_delete(old_data);
1572 _tbm_surface_mutex_unlock();
1577 /* LCOV_EXCL_START */
1579 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1581 TBM_RETURN_VAL_IF_FAIL(surface, 0);
1583 return surface->debug_pid;
1587 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1589 _tbm_surface_mutex_lock();
1590 _tbm_set_last_result(TBM_ERROR_NONE);
1592 TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
1594 surface->debug_pid = pid;
1596 _tbm_surface_mutex_unlock();
1599 static tbm_surface_debug_data *
1600 _tbm_surface_internal_debug_data_create(char *key, char *value)
1602 tbm_surface_debug_data *debug_data = NULL;
1604 debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1606 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1607 TBM_ERR("fail to allocate the debug_data.");
1611 if (key) debug_data->key = strdup(key);
1612 if (value) debug_data->value = strdup(value);
1618 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1620 tbm_surface_debug_data *debug_data = NULL;
1621 tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1622 tbm_bufmgr bufmgr = NULL;
1624 _tbm_surface_mutex_lock();
1625 _tbm_set_last_result(TBM_ERROR_NONE);
1627 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
1628 TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1630 bufmgr = surface->bufmgr;
1632 TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1634 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1635 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1637 if (!strcmp(old_data->key, key)) {
1638 if (old_data->value && value && !strncmp(old_data->value, value, strlen(old_data->value))) {
1639 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) Already exist key(%s) and value(%s)!\n", surface, key, value);
1640 goto add_debug_key_list;
1643 if (old_data->value)
1644 free(old_data->value);
1647 old_data->value = strdup(value);
1649 old_data->value = NULL;
1651 goto add_debug_key_list;
1657 debug_data = _tbm_surface_internal_debug_data_create(key, value);
1659 TBM_ERR("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1660 _tbm_surface_mutex_unlock();
1664 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1666 LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1669 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1670 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1671 if (!strcmp(old_data->key, key)) {
1672 _tbm_surface_mutex_unlock();
1678 debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1679 LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1681 _tbm_surface_mutex_unlock();
1687 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1689 tbm_surface_debug_data *old_data = NULL;
1691 TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1693 if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1694 LIST_FOR_EACH_ENTRY(old_data, &surface->debug_data_list, item_link) {
1695 if (!strcmp(old_data->key, key))
1696 return old_data->value;
1703 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1704 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1706 struct _tbm_surface_dump_buf_info {
1716 tbm_surface_info_s info;
1718 struct list_head link;
1721 struct _tbm_surface_dump_info {
1722 char *path; // copy???
1725 struct list_head *link;
1726 struct list_head surface_list; /* link of surface */
1729 static tbm_surface_dump_info *g_dump_info = NULL;
1730 static const char *dump_postfix[2] = {"png", "yuv"};
1731 static double scale_factor;
1734 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1,
1735 void *data2, int size2, void *data3, int size3)
1738 unsigned int *blocks;
1740 if (_tbm_surface_check_file_is_symbolic_link(file))
1741 TBM_ERR("%s is symbolic link\n", file);
1743 fp = fopen(file, "w+");
1744 TBM_RETURN_IF_FAIL(fp != NULL);
1746 blocks = (unsigned int *)data1;
1747 fwrite(blocks, 1, size1, fp);
1750 blocks = (unsigned int *)data2;
1751 fwrite(blocks, 1, size2, fp);
1755 blocks = (unsigned int *)data3;
1756 fwrite(blocks, 1, size3, fp);
1763 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width, int height, int format)
1765 unsigned int *blocks = (unsigned int *)data;
1768 png_bytep *row_pointers;
1771 if (_tbm_surface_check_file_is_symbolic_link(file))
1772 TBM_ERR("%s is symbolic link\n", file);
1774 fp = fopen(file, "wb");
1775 TBM_RETURN_IF_FAIL(fp != NULL);
1777 png_structp pPngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1780 TBM_ERR("fail to create a png write structure.\n");
1785 png_infop pPngInfo = png_create_info_struct(pPngStruct);
1787 TBM_ERR("fail to create a png info structure.\n");
1788 png_destroy_write_struct(&pPngStruct, NULL);
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 * width + 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, TBM_FORMAT_ARGB8888);
2017 case TBM_FORMAT_XRGB8888:
2018 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2019 buf_info->info.planes[0].stride >> 2,
2020 buf_info->info.height, TBM_FORMAT_XRGB8888);
2022 case TBM_FORMAT_YVU420:
2023 case TBM_FORMAT_YUV420:
2024 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2025 ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
2026 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2027 buf_info->info.planes[0].stride * buf_info->info.height,
2029 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2031 buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
2033 case TBM_FORMAT_NV12:
2034 case TBM_FORMAT_NV21:
2035 ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
2036 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2037 buf_info->info.planes[0].stride * buf_info->info.height,
2039 buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
2042 case TBM_FORMAT_YUYV:
2043 case TBM_FORMAT_UYVY:
2044 _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
2045 buf_info->info.planes[0].stride * buf_info->info.height,
2049 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
2052 } else if (buf_info->dirty_shm)
2053 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
2054 buf_info->shm_stride >> 2,
2055 buf_info->shm_h, 0);
2057 tbm_bo_unmap(buf_info->bo);
2058 tbm_bo_unref(buf_info->bo);
2059 LIST_DEL(&buf_info->link);
2066 TBM_INFO("Dump End..\n");
2069 static pixman_format_code_t
2070 _tbm_surface_internal_pixman_format_get(tbm_format format)
2073 case TBM_FORMAT_ARGB8888:
2074 return PIXMAN_a8r8g8b8;
2075 case TBM_FORMAT_XRGB8888:
2076 return PIXMAN_x8r8g8b8;
2085 * This function supports only if a buffer has below formats.
2086 * - TBM_FORMAT_ARGB8888
2087 * - TBM_FORMAT_XRGB8888
2089 static tbm_surface_error_e
2090 _tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr,
2091 int format, int src_stride, int src_w, int src_h,
2092 int dst_stride, int dst_w, int dst_h)
2094 pixman_image_t *src_img = NULL, *dst_img = NULL;
2095 pixman_format_code_t pixman_format;
2096 pixman_transform_t t;
2097 struct pixman_f_transform ft;
2098 double scale_x, scale_y;
2100 TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2101 TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION);
2103 pixman_format = _tbm_surface_internal_pixman_format_get(format);
2104 TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION);
2107 src_img = pixman_image_create_bits(pixman_format, src_w, src_h,
2108 (uint32_t*)src_ptr, src_stride);
2109 TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert);
2112 dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h,
2113 (uint32_t*)dst_ptr, dst_stride);
2114 TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert);
2116 pixman_f_transform_init_identity(&ft);
2118 scale_x = (double)src_w / dst_w;
2119 scale_y = (double)src_h / dst_h;
2121 pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
2122 pixman_f_transform_translate(&ft, NULL, 0, 0);
2123 pixman_transform_from_pixman_f_transform(&t, &ft);
2124 pixman_image_set_transform(src_img, &t);
2126 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img,
2127 0, 0, 0, 0, 0, 0, dst_w, dst_h);
2129 pixman_image_unref(src_img);
2130 pixman_image_unref(dst_img);
2132 return TBM_SURFACE_ERROR_NONE;
2136 pixman_image_unref(src_img);
2138 return TBM_SURFACE_ERROR_INVALID_OPERATION;
2141 #define MAX_BOS 4 // This value is came from bos[4] in struct _tbm_surface
2142 #define KEY_LEN 5 // "_XXXX"
2143 #define KEYS_LEN KEY_LEN * MAX_BOS
2145 static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
2147 char *keys, temp_key[KEY_LEN + 1];
2148 struct _tbm_surface *surf;
2152 _tbm_surface_mutex_lock();
2154 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
2156 surf = (struct _tbm_surface *)surface;
2158 num_bos = surf->num_bos;
2159 if (num_bos > MAX_BOS)
2162 keys = calloc(KEYS_LEN + 1, sizeof(char));
2164 TBM_ERR("Failed to alloc memory");
2165 _tbm_surface_mutex_unlock();
2169 for (i = 0; i < num_bos; i++) {
2170 memset(temp_key, 0x00, KEY_LEN + 1);
2172 snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
2173 strncat(keys, temp_key, KEY_LEN);
2176 _tbm_surface_mutex_unlock();
2181 static void _tbm_surface_internal_put_keys(char *keys)
2188 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
2190 TBM_RETURN_IF_FAIL(surface != NULL);
2191 TBM_RETURN_IF_FAIL(type != NULL);
2193 tbm_surface_dump_buf_info *buf_info;
2194 struct list_head *next_link;
2195 tbm_surface_info_s info;
2196 tbm_bo_handle bo_handle;
2197 const char *postfix;
2198 const char *format = NULL;
2205 next_link = g_dump_info->link->next;
2206 TBM_RETURN_IF_FAIL(next_link != NULL);
2208 if (next_link == &g_dump_info->surface_list) {
2209 next_link = next_link->next;
2210 TBM_RETURN_IF_FAIL(next_link != NULL);
2213 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2214 TBM_RETURN_IF_FAIL(buf_info != NULL);
2216 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2217 TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
2219 if (scale_factor > 0.0) {
2222 if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) {
2223 TBM_WRN("Dump with scale skip. unsupported format(%s)\n",
2224 _tbm_surface_internal_format_to_str(info.format));
2225 tbm_surface_unmap(surface);
2229 memset(&buf_info->info, 0, sizeof(tbm_surface_info_s));
2231 buf_info->info.width = info.width * scale_factor;
2232 buf_info->info.height = info.height * scale_factor;
2233 buf_info->info.format = info.format;
2234 buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
2235 if (!buf_info->info.bpp) {
2236 TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
2237 tbm_surface_unmap(surface);
2240 buf_info->info.num_planes = 1;
2241 buf_info->info.planes[0].stride = buf_info->info.width * bpp;
2242 buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
2244 if (buf_info->info.size > buf_info->size) {
2245 TBM_WRN("Dump with scale skip. surface over created buffer size(%u, %d)\n",
2246 buf_info->info.size, buf_info->size);
2247 tbm_surface_unmap(surface);
2251 if (info.size > buf_info->size) {
2252 TBM_WRN("Dump skip. surface over created buffer size(%u, %d)\n",
2253 info.size, buf_info->size);
2254 tbm_surface_unmap(surface);
2258 /* make the file information */
2259 memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
2262 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) {
2263 postfix = dump_postfix[0];
2264 format = _tbm_surface_internal_format_to_str(info.format);
2266 postfix = dump_postfix[1];
2268 keys = _tbm_surface_internal_get_keys(surface);
2270 TBM_ERR("fail to get keys");
2271 tbm_surface_unmap(surface);
2276 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2277 if (!bo_handle.ptr) {
2278 TBM_ERR("fail to map bo");
2279 _tbm_surface_internal_put_keys(keys);
2280 tbm_surface_unmap(surface);
2283 memset(bo_handle.ptr, 0x00, buf_info->size);
2285 switch (info.format) {
2286 case TBM_FORMAT_ARGB8888:
2287 case TBM_FORMAT_XRGB8888:
2288 snprintf(buf_info->name, sizeof(buf_info->name),
2289 "%10.3f_%03d%s_%p_%s-%s.%s",
2290 _tbm_surface_internal_get_time(),
2291 g_dump_info->count++, keys, surface, format, type, postfix);
2293 if (scale_factor > 0.0) {
2294 ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr,
2296 buf_info->info.format,
2297 info.planes[0].stride,
2298 info.width, info.height,
2299 buf_info->info.planes[0].stride,
2300 buf_info->info.width,
2301 buf_info->info.height);
2302 if (ret != TBM_SURFACE_ERROR_NONE) {
2303 TBM_ERR("fail to scale buffer");
2304 tbm_bo_unmap(buf_info->bo);
2305 _tbm_surface_internal_put_keys(keys);
2306 tbm_surface_unmap(surface);
2310 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
2312 case TBM_FORMAT_YVU420:
2313 case TBM_FORMAT_YUV420:
2314 snprintf(buf_info->name, sizeof(buf_info->name),
2315 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2316 _tbm_surface_internal_get_time(),
2317 g_dump_info->count++, keys, type, info.planes[0].stride,
2318 info.height, FOURCC_STR(info.format), postfix);
2319 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2320 bo_handle.ptr += info.planes[0].stride * info.height;
2321 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2322 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
2323 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
2325 case TBM_FORMAT_NV12:
2326 case TBM_FORMAT_NV21:
2327 snprintf(buf_info->name, sizeof(buf_info->name),
2328 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2329 _tbm_surface_internal_get_time(),
2330 g_dump_info->count++, keys, type, info.planes[0].stride,
2331 info.height, FOURCC_STR(info.format), postfix);
2332 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2333 bo_handle.ptr += info.planes[0].stride * info.height;
2334 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
2336 case TBM_FORMAT_YUYV:
2337 case TBM_FORMAT_UYVY:
2338 snprintf(buf_info->name, sizeof(buf_info->name),
2339 "%10.3f_%03d%s-%s_%dx%d_%c%c%c%c.%s",
2340 _tbm_surface_internal_get_time(),
2341 g_dump_info->count++, keys, type, info.planes[0].stride,
2342 info.height, FOURCC_STR(info.format), postfix);
2343 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
2346 TBM_ERR("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
2347 tbm_bo_unmap(buf_info->bo);
2348 _tbm_surface_internal_put_keys(keys);
2349 tbm_surface_unmap(surface);
2353 tbm_bo_unmap(buf_info->bo);
2355 _tbm_surface_internal_put_keys(keys);
2357 tbm_surface_unmap(surface);
2359 buf_info->dirty = 1;
2360 buf_info->dirty_shm = 0;
2362 if (g_dump_info->count == 1000)
2363 g_dump_info->count = 0;
2365 g_dump_info->link = next_link;
2367 TBM_INFO("Dump %s \n", buf_info->name);
2370 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride,
2373 TBM_RETURN_IF_FAIL(ptr != NULL);
2374 TBM_RETURN_IF_FAIL(w > 0);
2375 TBM_RETURN_IF_FAIL(h > 0);
2376 TBM_RETURN_IF_FAIL(stride > 0);
2377 TBM_RETURN_IF_FAIL(type != NULL);
2379 tbm_surface_dump_buf_info *buf_info;
2380 struct list_head *next_link;
2381 tbm_bo_handle bo_handle;
2382 int ret, size, dw = 0, dh = 0, dstride = 0;
2387 next_link = g_dump_info->link->next;
2388 TBM_RETURN_IF_FAIL(next_link != NULL);
2390 if (next_link == &g_dump_info->surface_list) {
2391 next_link = next_link->next;
2392 TBM_RETURN_IF_FAIL(next_link != NULL);
2395 buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
2396 TBM_RETURN_IF_FAIL(buf_info != NULL);
2398 if (scale_factor > 0.0) {
2401 dw = w * scale_factor;
2402 dh = h * scale_factor;
2404 size = dstride * dh;
2408 if (size > buf_info->size) {
2409 TBM_WRN("Dump skip. shm buffer over created buffer size(%d, %d)\n",
2410 size, buf_info->size);
2415 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
2416 TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
2418 memset(bo_handle.ptr, 0x00, buf_info->size);
2419 memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
2421 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
2422 _tbm_surface_internal_get_time(),
2423 g_dump_info->count++, type, dump_postfix[0]);
2424 if (scale_factor > 0.0) {
2425 ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr,
2426 TBM_FORMAT_ARGB8888, stride,
2427 w, h, dstride, dw, dh);
2428 if (ret != TBM_SURFACE_ERROR_NONE) {
2429 TBM_ERR("fail to scale buffer");
2430 tbm_bo_unmap(buf_info->bo);
2433 buf_info->shm_stride = dstride;
2434 buf_info->shm_h = dh;
2436 memcpy(bo_handle.ptr, ptr, size);
2437 buf_info->shm_stride = stride;
2438 buf_info->shm_h = h;
2441 tbm_bo_unmap(buf_info->bo);
2443 buf_info->dirty = 0;
2444 buf_info->dirty_shm = 1;
2446 if (g_dump_info->count == 1000)
2447 g_dump_info->count = 0;
2449 g_dump_info->link = next_link;
2451 TBM_INFO("Dump %s \n", buf_info->name);
2455 tbm_surface_internal_capture_buffer(tbm_surface_h surface, const char *path, const char *name, const char *type)
2457 TBM_RETURN_VAL_IF_FAIL(surface != NULL, 0);
2458 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2459 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2461 tbm_surface_info_s info;
2462 const char *postfix;
2466 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
2467 TBM_RETURN_VAL_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE, 0);
2469 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
2470 postfix = dump_postfix[0];
2472 postfix = dump_postfix[1];
2474 if (strcmp(postfix, type)) {
2475 TBM_ERR("not support type(%s) %c%c%c%c buffer", type, FOURCC_STR(info.format));
2476 tbm_surface_unmap(surface);
2480 snprintf(file, sizeof(file), "%s/%s.%s", path , name, postfix);
2482 if (!access(file, 0)) {
2483 TBM_ERR("can't capture buffer, exist file %s", file);
2484 tbm_surface_unmap(surface);
2488 switch (info.format) {
2489 case TBM_FORMAT_ARGB8888:
2490 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2491 info.planes[0].stride >> 2,
2492 info.height, TBM_FORMAT_ARGB8888);
2494 case TBM_FORMAT_XRGB8888:
2495 _tbm_surface_internal_dump_file_png(file, info.planes[0].ptr,
2496 info.planes[0].stride >> 2,
2497 info.height, TBM_FORMAT_XRGB8888);
2499 case TBM_FORMAT_YVU420:
2500 case TBM_FORMAT_YUV420:
2501 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2502 info.planes[0].stride * info.height,
2504 info.planes[1].stride * (info.height >> 1),
2506 info.planes[2].stride * (info.height >> 1));
2508 case TBM_FORMAT_NV12:
2509 case TBM_FORMAT_NV21:
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),
2516 case TBM_FORMAT_YUYV:
2517 case TBM_FORMAT_UYVY:
2518 _tbm_surface_internal_dump_file_raw(file, info.planes[0].ptr,
2519 info.planes[0].stride * info.height,
2523 TBM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR(info.format));
2524 tbm_surface_unmap(surface);
2528 tbm_surface_unmap(surface);
2530 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2536 tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
2537 const char *path, const char *name, const char *type)
2539 TBM_RETURN_VAL_IF_FAIL(ptr != NULL, 0);
2540 TBM_RETURN_VAL_IF_FAIL(w > 0, 0);
2541 TBM_RETURN_VAL_IF_FAIL(h > 0, 0);
2542 TBM_RETURN_VAL_IF_FAIL(stride > 0, 0);
2543 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
2544 TBM_RETURN_VAL_IF_FAIL(name != NULL, 0);
2548 if (strcmp(dump_postfix[0], type)) {
2549 TBM_ERR("Not supported type:%s'", type);
2553 snprintf(file, sizeof(file), "%s/%s.%s", path , name, dump_postfix[0]);
2555 if (!access(file, 0)) {
2556 TBM_ERR("can't capture buffer, exist file %sTBM_FORMAT_XRGB8888", file);
2560 _tbm_surface_internal_dump_file_png(file, ptr, w, h, 0);
2562 TBM_TRACE_SURFACE_INTERNAL("Capture %s \n", file);
2568 tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
2570 struct _tbm_surface *surf;
2572 _tbm_surface_mutex_lock();
2573 _tbm_set_last_result(TBM_ERROR_NONE);
2575 TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
2576 TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
2577 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2579 surf = (struct _tbm_surface *)surface;
2583 surf->damage.width = width;
2584 surf->damage.height = height;
2586 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2587 surface, x, y, width, height);
2589 _tbm_surface_mutex_unlock();
2595 tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
2597 struct _tbm_surface *surf;
2599 _tbm_surface_mutex_lock();
2600 _tbm_set_last_result(TBM_ERROR_NONE);
2602 TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
2604 surf = (struct _tbm_surface *)surface;
2606 if (x) *x = surf->damage.x;
2607 if (y) *y = surf->damage.y;
2608 if (width) *width = surf->damage.width;
2609 if (height) *height = surf->damage.height;
2611 TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
2612 surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
2614 _tbm_surface_mutex_unlock();