add tbm_surface_internal_set_debug_data function for debugging
[platform/core/uifw/libtbm.git] / src / tbm_surface_internal.c
1 /**************************************************************************
2
3 libtbm
4
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
6
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>
9
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:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
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.
29
30 **************************************************************************/
31
32 #include "config.h"
33 #include <stdio.h>
34 #include <time.h>
35 #include <sys/time.h>
36 #include "tbm_bufmgr.h"
37 #include "tbm_bufmgr_int.h"
38 #include "tbm_surface_internal.h"
39 #include "list.h"
40 #include <png.h>
41
42 #define C(b, m)              (((b) >> (m)) & 0xFF)
43 #define B(c, s)              ((((unsigned int)(c)) & 0xff) << (s))
44 #define FOURCC(a, b, c, d)     (B(d, 24) | B(c, 16) | B(b, 8) | B(a, 0))
45 #define FOURCC_STR(id)      C(id, 0), C(id, 8), C(id, 16), C(id, 24)
46 #define FOURCC_ID(str)      FOURCC(((char*)str)[0], ((char*)str)[1], ((char*)str)[2], ((char*)str)[3])
47
48 static tbm_bufmgr g_surface_bufmgr;
49 static pthread_mutex_t tbm_surface_lock;
50
51 /* LCOV_EXCL_START */
52 #define USE_REALTIME 1
53
54 static double
55 _tbm_surface_internal_get_time(void)
56 {
57         struct timespec tp;
58         unsigned int time;
59
60 #if USE_REALTIME
61         clock_gettime(CLOCK_REALTIME, &tp);
62 #else /* USE_MONOTONIC */
63         clock_gettime(CLOCK_MONOTONIC, &tp);
64 #endif
65         time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
66
67         return time / 1000.0;
68 }
69
70 static void
71 _tbm_surface_internal_debug_data_delete(tbm_surface_debug_data *debug_data)
72 {
73         LIST_DEL(&debug_data->item_link);
74
75         if (debug_data->key) free(debug_data->key);
76         if (debug_data->value) free(debug_data->value);
77         free(debug_data);
78 }
79
80 char *
81 _tbm_surface_internal_format_to_str(tbm_format format)
82 {
83         switch (format) {
84         case TBM_FORMAT_C8:
85                 return "TBM_FORMAT_C8";
86         case TBM_FORMAT_RGB332:
87                 return "TBM_FORMAT_RGB332";
88         case TBM_FORMAT_BGR233:
89                 return "TBM_FORMAT_BGR233";
90         case TBM_FORMAT_XRGB4444:
91                 return "TBM_FORMAT_XRGB4444";
92         case TBM_FORMAT_XBGR4444:
93                 return "TBM_FORMAT_XBGR4444";
94         case TBM_FORMAT_RGBX4444:
95                 return "TBM_FORMAT_RGBX4444";
96         case TBM_FORMAT_BGRX4444:
97                 return "TBM_FORMAT_BGRX4444";
98         case TBM_FORMAT_ARGB4444:
99                 return "TBM_FORMAT_ARGB4444";
100         case TBM_FORMAT_ABGR4444:
101                 return "TBM_FORMAT_ABGR4444";
102         case TBM_FORMAT_RGBA4444:
103                 return "TBM_FORMAT_RGBA4444";
104         case TBM_FORMAT_BGRA4444:
105                 return "TBM_FORMAT_BGRA4444";
106         case TBM_FORMAT_XRGB1555:
107                 return "TBM_FORMAT_XRGB1555";
108         case TBM_FORMAT_XBGR1555:
109                 return "TBM_FORMAT_XBGR1555";
110         case TBM_FORMAT_RGBX5551:
111                 return "TBM_FORMAT_RGBX5551";
112         case TBM_FORMAT_BGRX5551:
113                 return "TBM_FORMAT_BGRX5551";
114         case TBM_FORMAT_ARGB1555:
115                 return "TBM_FORMAT_ARGB1555";
116         case TBM_FORMAT_ABGR1555:
117                 return "TBM_FORMAT_ABGR1555";
118         case TBM_FORMAT_RGBA5551:
119                 return "TBM_FORMAT_RGBA5551";
120         case TBM_FORMAT_BGRA5551:
121                 return "TBM_FORMAT_BGRA5551";
122         case TBM_FORMAT_RGB565:
123                 return "TBM_FORMAT_RGB565";
124         case TBM_FORMAT_BGR565:
125                 return "TBM_FORMAT_BGR565";
126         case TBM_FORMAT_RGB888:
127                 return "TBM_FORMAT_RGB888";
128         case TBM_FORMAT_BGR888:
129                 return "TBM_FORMAT_BGR888";
130         case TBM_FORMAT_XRGB8888:
131                 return "TBM_FORMAT_XRGB8888";
132         case TBM_FORMAT_XBGR8888:
133                 return "TBM_FORMAT_XBGR8888";
134         case TBM_FORMAT_RGBX8888:
135                 return "TBM_FORMAT_RGBX8888";
136         case TBM_FORMAT_BGRX8888:
137                 return "TBM_FORMAT_BGRX8888";
138         case TBM_FORMAT_ARGB8888:
139                 return "TBM_FORMAT_ARGB8888";
140         case TBM_FORMAT_ABGR8888:
141                 return "TBM_FORMAT_ABGR8888";
142         case TBM_FORMAT_RGBA8888:
143                 return "TBM_FORMAT_RGBA8888";
144         case TBM_FORMAT_BGRA8888:
145                 return "TBM_FORMAT_BGRA8888";
146         case TBM_FORMAT_XRGB2101010:
147                 return "TBM_FORMAT_XRGB2101010";
148         case TBM_FORMAT_XBGR2101010:
149                 return "TBM_FORMAT_XBGR2101010";
150         case TBM_FORMAT_RGBX1010102:
151                 return "TBM_FORMAT_RGBX1010102";
152         case TBM_FORMAT_BGRX1010102:
153                 return "TBM_FORMAT_BGRX1010102";
154         case TBM_FORMAT_ARGB2101010:
155                 return "TBM_FORMAT_ARGB2101010";
156         case TBM_FORMAT_ABGR2101010:
157                 return "TBM_FORMAT_ABGR2101010";
158         case TBM_FORMAT_RGBA1010102:
159                 return "TBM_FORMAT_RGBA1010102";
160         case TBM_FORMAT_BGRA1010102:
161                 return "TBM_FORMAT_BGRA1010102";
162         case TBM_FORMAT_YUYV:
163                 return "TBM_FORMAT_YUYV";
164         case TBM_FORMAT_YVYU:
165                 return "TBM_FORMAT_YVYU";
166         case TBM_FORMAT_UYVY:
167                 return "TBM_FORMAT_UYVY";
168         case TBM_FORMAT_VYUY:
169                 return "TBM_FORMAT_VYUY";
170         case TBM_FORMAT_AYUV:
171                 return "TBM_FORMAT_AYUV";
172         case TBM_FORMAT_NV12:
173                 return "TBM_FORMAT_NV12";
174         case TBM_FORMAT_NV21:
175                 return "TBM_FORMAT_NV21";
176         case TBM_FORMAT_NV16:
177                 return "TBM_FORMAT_NV16";
178         case TBM_FORMAT_NV61:
179                 return "TBM_FORMAT_NV61";
180         case TBM_FORMAT_YUV410:
181                 return "TBM_FORMAT_YUV410";
182         case TBM_FORMAT_YVU410:
183                 return "TBM_FORMAT_YVU410";
184         case TBM_FORMAT_YUV411:
185                 return "TBM_FORMAT_YUV411";
186         case TBM_FORMAT_YVU411:
187                 return "TBM_FORMAT_YVU411";
188         case TBM_FORMAT_YUV420:
189                 return "TBM_FORMAT_YUV420";
190         case TBM_FORMAT_YVU420:
191                 return "TBM_FORMAT_YVU420";
192         case TBM_FORMAT_YUV422:
193                 return "TBM_FORMAT_YUV422";
194         case TBM_FORMAT_YVU422:
195                 return "TBM_FORMAT_YVU422";
196         case TBM_FORMAT_YUV444:
197                 return "TBM_FORMAT_YUV444";
198         case TBM_FORMAT_YVU444:
199                 return "TBM_FORMAT_YVU444";
200         case TBM_FORMAT_NV12MT:
201                 return "TBM_FORMAT_NV12MT";
202         default:
203                 return "unknwon";
204         }
205 }
206 /* LCOV_EXCL_STOP */
207
208 static bool
209 _tbm_surface_mutex_init(void)
210 {
211         static bool tbm_surface_mutex_init = false;
212
213         if (tbm_surface_mutex_init)
214                 return true;
215
216         if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
217                 TBM_LOG_E("fail: tbm_surface mutex init\n");
218                 return false;
219         }
220
221         tbm_surface_mutex_init = true;
222
223         return true;
224 }
225
226 void
227 _tbm_surface_mutex_lock(void)
228 {
229         if (!_tbm_surface_mutex_init())
230                 return;
231
232         pthread_mutex_lock(&tbm_surface_lock);
233 }
234
235 void
236 _tbm_surface_mutex_unlock(void)
237 {
238         pthread_mutex_unlock(&tbm_surface_lock);
239 }
240
241 static void
242 _init_surface_bufmgr(void)
243 {
244         g_surface_bufmgr = tbm_bufmgr_init(-1);
245 }
246
247 static void
248 _deinit_surface_bufmgr(void)
249 {
250         if (!g_surface_bufmgr)
251                 return;
252
253         tbm_bufmgr_deinit(g_surface_bufmgr);
254         g_surface_bufmgr = NULL;
255 }
256
257 static int
258 _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
259                                        int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
260 {
261         TBM_RETURN_VAL_IF_FAIL(surface, 0);
262         TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
263
264         struct _tbm_surface *surf = (struct _tbm_surface *)surface;
265         struct _tbm_bufmgr *mgr = surf->bufmgr;
266         int ret = 0;
267
268         TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
269         TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
270         TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
271         TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
272
273         if (!mgr->backend->surface_get_plane_data)
274                 return 0;
275
276         ret = mgr->backend->surface_get_plane_data(surf->info.width,
277                         surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
278         if (!ret)
279                 return 0;
280
281         return 1;
282 }
283
284 static void
285 _tbm_surface_internal_destroy(tbm_surface_h surface)
286 {
287         int i;
288         tbm_bufmgr bufmgr = surface->bufmgr;
289         tbm_user_data *old_data = NULL, *tmp = NULL;
290         tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL;
291
292         /* destory the user_data_list */
293         if (!LIST_IS_EMPTY(&surface->user_data_list)) {
294                 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
295                         DBG("free user_data\n");
296                         user_data_delete(old_data);
297                 }
298         }
299
300         for (i = 0; i < surface->num_bos; i++) {
301                 surface->bos[i]->surface = NULL;
302
303                 tbm_bo_unref(surface->bos[i]);
304                 surface->bos[i] = NULL;
305         }
306
307         if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
308                 LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &surface->debug_data_list, item_link)
309                         _tbm_surface_internal_debug_data_delete(debug_old_data);
310         }
311
312         LIST_DEL(&surface->item_link);
313
314         free(surface);
315         surface = NULL;
316
317         if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
318                 LIST_DELINIT(&bufmgr->surf_list);
319
320                 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
321                         LIST_FOR_EACH_ENTRY_SAFE(debug_old_data, debug_tmp, &bufmgr->debug_key_list, item_link) {
322                                 _tbm_surface_internal_debug_data_delete(debug_old_data);
323                         }
324                 }
325
326                 _deinit_surface_bufmgr();
327         }
328 }
329
330 static int
331 _tbm_surface_get_max_size(int * w, int * h)
332 {
333         int count = 0;
334         tbm_surface_h surface = NULL, tmp = NULL;
335         tbm_surface_info_s info;
336
337         *w = 0;
338         *h = 0;
339
340         if (g_surface_bufmgr == NULL)
341                 return count;
342
343         if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
344                 LIST_FOR_EACH_ENTRY_SAFE(surface, tmp, &g_surface_bufmgr->surf_list, item_link) {
345                         if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
346                                 count++;
347                                 if (*w < info.width) *w = info.width;
348                                 if (*h < info.height) *h = info.height;
349                         }
350                 }
351         }
352
353         return count;
354 }
355
356 int
357 tbm_surface_internal_is_valid(tbm_surface_h surface)
358 {
359         tbm_surface_h old_data = NULL, tmp = NULL;
360
361         if (surface == NULL || g_surface_bufmgr == NULL) {
362                 TBM_TRACE("error: tbm_surface(%p)\n", surface);
363                 return 0;
364         }
365
366         if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
367                 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &g_surface_bufmgr->surf_list, item_link) {
368                         if (old_data == surface) {
369                                 TBM_TRACE("tbm_surface(%p)\n", surface);
370                                 return 1;
371                         }
372                 }
373         }
374         TBM_TRACE("error: tbm_surface(%p)\n", surface);
375         return 0;
376 }
377
378 int
379 tbm_surface_internal_query_supported_formats(uint32_t **formats,
380                 uint32_t *num)
381 {
382         struct _tbm_bufmgr *mgr;
383         int ret = 0;
384
385         _tbm_surface_mutex_lock();
386
387         if (!g_surface_bufmgr) {
388                 _init_surface_bufmgr();
389                 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
390         }
391
392         mgr = g_surface_bufmgr;
393
394         if (!mgr->backend->surface_supported_format) {
395                 TBM_TRACE("error: tbm_bufmgr(%p)\n", g_surface_bufmgr);
396                 _tbm_surface_mutex_unlock();
397                 return 0;
398         }
399
400         ret = mgr->backend->surface_supported_format(formats, num);
401
402         TBM_TRACE("tbm_bufmgr(%p) format num(%d)\n", g_surface_bufmgr, *num);
403
404         _tbm_surface_mutex_unlock();
405
406         return ret;
407 }
408
409 int
410 tbm_surface_internal_get_num_planes(tbm_format format)
411 {
412         int num_planes = 0;
413
414         switch (format) {
415         case TBM_FORMAT_C8:
416         case TBM_FORMAT_RGB332:
417         case TBM_FORMAT_BGR233:
418         case TBM_FORMAT_XRGB4444:
419         case TBM_FORMAT_XBGR4444:
420         case TBM_FORMAT_RGBX4444:
421         case TBM_FORMAT_BGRX4444:
422         case TBM_FORMAT_ARGB4444:
423         case TBM_FORMAT_ABGR4444:
424         case TBM_FORMAT_RGBA4444:
425         case TBM_FORMAT_BGRA4444:
426         case TBM_FORMAT_XRGB1555:
427         case TBM_FORMAT_XBGR1555:
428         case TBM_FORMAT_RGBX5551:
429         case TBM_FORMAT_BGRX5551:
430         case TBM_FORMAT_ARGB1555:
431         case TBM_FORMAT_ABGR1555:
432         case TBM_FORMAT_RGBA5551:
433         case TBM_FORMAT_BGRA5551:
434         case TBM_FORMAT_RGB565:
435         case TBM_FORMAT_BGR565:
436         case TBM_FORMAT_RGB888:
437         case TBM_FORMAT_BGR888:
438         case TBM_FORMAT_XRGB8888:
439         case TBM_FORMAT_XBGR8888:
440         case TBM_FORMAT_RGBX8888:
441         case TBM_FORMAT_BGRX8888:
442         case TBM_FORMAT_ARGB8888:
443         case TBM_FORMAT_ABGR8888:
444         case TBM_FORMAT_RGBA8888:
445         case TBM_FORMAT_BGRA8888:
446         case TBM_FORMAT_XRGB2101010:
447         case TBM_FORMAT_XBGR2101010:
448         case TBM_FORMAT_RGBX1010102:
449         case TBM_FORMAT_BGRX1010102:
450         case TBM_FORMAT_ARGB2101010:
451         case TBM_FORMAT_ABGR2101010:
452         case TBM_FORMAT_RGBA1010102:
453         case TBM_FORMAT_BGRA1010102:
454         case TBM_FORMAT_YUYV:
455         case TBM_FORMAT_YVYU:
456         case TBM_FORMAT_UYVY:
457         case TBM_FORMAT_VYUY:
458         case TBM_FORMAT_AYUV:
459                 num_planes = 1;
460                 break;
461         case TBM_FORMAT_NV12:
462         case TBM_FORMAT_NV12MT:
463         case TBM_FORMAT_NV21:
464         case TBM_FORMAT_NV16:
465         case TBM_FORMAT_NV61:
466                 num_planes = 2;
467                 break;
468         case TBM_FORMAT_YUV410:
469         case TBM_FORMAT_YVU410:
470         case TBM_FORMAT_YUV411:
471         case TBM_FORMAT_YVU411:
472         case TBM_FORMAT_YUV420:
473         case TBM_FORMAT_YVU420:
474         case TBM_FORMAT_YUV422:
475         case TBM_FORMAT_YVU422:
476         case TBM_FORMAT_YUV444:
477         case TBM_FORMAT_YVU444:
478                 num_planes = 3;
479                 break;
480
481         default:
482                 break;
483         }
484
485         TBM_TRACE("tbm_format(%s) num_planes(%d)\n", _tbm_surface_internal_format_to_str(format), num_planes);
486
487         return num_planes;
488 }
489
490 int
491 tbm_surface_internal_get_bpp(tbm_format format)
492 {
493
494         int bpp = 0;
495
496         switch (format) {
497         case TBM_FORMAT_C8:
498         case TBM_FORMAT_RGB332:
499         case TBM_FORMAT_BGR233:
500                 bpp = 8;
501                 break;
502         case TBM_FORMAT_XRGB4444:
503         case TBM_FORMAT_XBGR4444:
504         case TBM_FORMAT_RGBX4444:
505         case TBM_FORMAT_BGRX4444:
506         case TBM_FORMAT_ARGB4444:
507         case TBM_FORMAT_ABGR4444:
508         case TBM_FORMAT_RGBA4444:
509         case TBM_FORMAT_BGRA4444:
510         case TBM_FORMAT_XRGB1555:
511         case TBM_FORMAT_XBGR1555:
512         case TBM_FORMAT_RGBX5551:
513         case TBM_FORMAT_BGRX5551:
514         case TBM_FORMAT_ARGB1555:
515         case TBM_FORMAT_ABGR1555:
516         case TBM_FORMAT_RGBA5551:
517         case TBM_FORMAT_BGRA5551:
518         case TBM_FORMAT_RGB565:
519         case TBM_FORMAT_BGR565:
520                 bpp = 16;
521                 break;
522         case TBM_FORMAT_RGB888:
523         case TBM_FORMAT_BGR888:
524                 bpp = 24;
525                 break;
526         case TBM_FORMAT_XRGB8888:
527         case TBM_FORMAT_XBGR8888:
528         case TBM_FORMAT_RGBX8888:
529         case TBM_FORMAT_BGRX8888:
530         case TBM_FORMAT_ARGB8888:
531         case TBM_FORMAT_ABGR8888:
532         case TBM_FORMAT_RGBA8888:
533         case TBM_FORMAT_BGRA8888:
534         case TBM_FORMAT_XRGB2101010:
535         case TBM_FORMAT_XBGR2101010:
536         case TBM_FORMAT_RGBX1010102:
537         case TBM_FORMAT_BGRX1010102:
538         case TBM_FORMAT_ARGB2101010:
539         case TBM_FORMAT_ABGR2101010:
540         case TBM_FORMAT_RGBA1010102:
541         case TBM_FORMAT_BGRA1010102:
542         case TBM_FORMAT_YUYV:
543         case TBM_FORMAT_YVYU:
544         case TBM_FORMAT_UYVY:
545         case TBM_FORMAT_VYUY:
546         case TBM_FORMAT_AYUV:
547                 bpp = 32;
548                 break;
549         case TBM_FORMAT_NV12:
550         case TBM_FORMAT_NV12MT:
551         case TBM_FORMAT_NV21:
552                 bpp = 12;
553                 break;
554         case TBM_FORMAT_NV16:
555         case TBM_FORMAT_NV61:
556                 bpp = 16;
557                 break;
558         case TBM_FORMAT_YUV410:
559         case TBM_FORMAT_YVU410:
560                 bpp = 9;
561                 break;
562         case TBM_FORMAT_YUV411:
563         case TBM_FORMAT_YVU411:
564         case TBM_FORMAT_YUV420:
565         case TBM_FORMAT_YVU420:
566                 bpp = 12;
567                 break;
568         case TBM_FORMAT_YUV422:
569         case TBM_FORMAT_YVU422:
570                 bpp = 16;
571                 break;
572         case TBM_FORMAT_YUV444:
573         case TBM_FORMAT_YVU444:
574                 bpp = 24;
575                 break;
576         default:
577                 break;
578         }
579
580         TBM_TRACE("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
581
582         return bpp;
583 }
584
585 tbm_surface_h
586 tbm_surface_internal_create_with_flags(int width, int height,
587                                        int format, int flags)
588 {
589         TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
590         TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
591
592         struct _tbm_bufmgr *mgr;
593         struct _tbm_surface *surf = NULL;
594         uint32_t size = 0;
595         uint32_t offset = 0;
596         uint32_t stride = 0;
597         uint32_t bo_size = 0;
598         int bo_idx;
599         int i, j;
600
601         _tbm_surface_mutex_lock();
602
603         if (!g_surface_bufmgr) {
604                 _init_surface_bufmgr();
605                 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
606         }
607
608         mgr = g_surface_bufmgr;
609         if (!TBM_BUFMGR_IS_VALID(mgr)) {
610                 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
611                                 width, height, _tbm_surface_internal_format_to_str(format), flags);
612                 _tbm_surface_mutex_unlock();
613                 return NULL;
614         }
615         surf = calloc(1, sizeof(struct _tbm_surface));
616         if (!surf) {
617                 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
618                                 width, height, _tbm_surface_internal_format_to_str(format), flags);
619                 _tbm_surface_mutex_unlock();
620                 return NULL;
621         }
622
623         surf->bufmgr = mgr;
624         surf->info.width = width;
625         surf->info.height = height;
626         surf->info.format = format;
627         surf->info.bpp = tbm_surface_internal_get_bpp(format);
628         surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
629         surf->refcnt = 1;
630
631         /* get size, stride and offset bo_idx */
632         for (i = 0; i < surf->info.num_planes; i++) {
633                 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride,
634                                                        &bo_idx);
635                 surf->info.planes[i].size = size;
636                 surf->info.planes[i].offset = offset;
637                 surf->info.planes[i].stride = stride;
638                 surf->planes_bo_idx[i] = bo_idx;
639         }
640
641         surf->num_bos = 1;
642
643         for (i = 0; i < surf->info.num_planes; i++) {
644                 surf->info.size += surf->info.planes[i].size;
645
646                 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
647                         surf->num_bos = surf->planes_bo_idx[i] + 1;
648         }
649
650         surf->flags = flags;
651
652         for (i = 0; i < surf->num_bos; i++) {
653                 bo_size = 0;
654                 for (j = 0; j < surf->info.num_planes; j++) {
655                         if (surf->planes_bo_idx[j] == i)
656                                 bo_size += surf->info.planes[j].size;
657                 }
658
659                 if (mgr->backend->surface_bo_alloc) {
660                         /* LCOV_EXCL_START */
661                         tbm_bo bo = NULL;
662                         void *bo_priv = NULL;
663
664                         bo = calloc(1, sizeof(struct _tbm_bo));
665                         if (!bo) {
666                                 TBM_LOG_E("fail to alloc bo struct\n");
667                                 goto alloc_fail;
668                         }
669
670                         bo->bufmgr = surf->bufmgr;
671
672                         pthread_mutex_lock(&surf->bufmgr->lock);
673
674                         bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
675                         if (!bo_priv) {
676                                 TBM_LOG_E("fail to alloc bo priv\n");
677                                 free(bo);
678                                 pthread_mutex_unlock(&surf->bufmgr->lock);
679                                 goto alloc_fail;
680                         }
681
682                         bo->ref_cnt = 1;
683                         bo->flags = flags;
684                         bo->priv = bo_priv;
685
686                         LIST_INITHEAD(&bo->user_data_list);
687
688                         LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
689
690                         pthread_mutex_unlock(&surf->bufmgr->lock);
691
692                         surf->bos[i] = bo;
693                         /* LCOV_EXCL_STOP */
694                 } else {
695                         surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
696                 }
697
698                 if (!surf->bos[i]) {
699                         TBM_LOG_E("fail to alloc bo idx:%d\n", i);
700                         goto alloc_fail;
701                 }
702
703                 _tbm_bo_set_surface(surf->bos[i], surf);
704
705         }
706
707         TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
708                         _tbm_surface_internal_format_to_str(format), flags, surf);
709
710         LIST_INITHEAD(&surf->user_data_list);
711         LIST_INITHEAD(&surf->debug_data_list);
712
713         LIST_ADD(&surf->item_link, &mgr->surf_list);
714
715         _tbm_surface_mutex_unlock();
716
717         return surf;
718
719 alloc_fail:
720
721         TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
722                         width, height, _tbm_surface_internal_format_to_str(format), flags);
723
724         for (j = 0; j < i; j++) {
725                 if (surf->bos[j])
726                         tbm_bo_unref(surf->bos[j]);
727         }
728
729         free(surf);
730         surf = NULL;
731
732         if (LIST_IS_EMPTY(&mgr->surf_list)) {
733                 LIST_DELINIT(&mgr->surf_list);
734                 _deinit_surface_bufmgr();
735         }
736
737         _tbm_surface_mutex_unlock();
738         return NULL;
739 }
740
741 tbm_surface_h
742 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
743                                      tbm_bo *bos, int num)
744 {
745         TBM_RETURN_VAL_IF_FAIL(bos, NULL);
746         TBM_RETURN_VAL_IF_FAIL(info, NULL);
747         TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
748
749         struct _tbm_bufmgr *mgr;
750         struct _tbm_surface *surf = NULL;
751         int i;
752
753         _tbm_surface_mutex_lock();
754
755         if (!g_surface_bufmgr) {
756                 _init_surface_bufmgr();
757                 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
758         }
759
760         mgr = g_surface_bufmgr;
761         if (!TBM_BUFMGR_IS_VALID(mgr)) {
762                 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
763                                 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
764                 _tbm_surface_mutex_unlock();
765                 return NULL;
766         }
767
768         surf = calloc(1, sizeof(struct _tbm_surface));
769         if (!surf) {
770                 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
771                                 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
772                 _tbm_surface_mutex_unlock();
773                 return NULL;
774         }
775
776         surf->bufmgr = mgr;
777         surf->info.width = info->width;
778         surf->info.height = info->height;
779         surf->info.format = info->format;
780         surf->info.bpp = info->bpp;
781         surf->info.num_planes = info->num_planes;
782         surf->refcnt = 1;
783
784         /* get size, stride and offset */
785         for (i = 0; i < info->num_planes; i++) {
786                 surf->info.planes[i].offset = info->planes[i].offset;
787                 surf->info.planes[i].stride = info->planes[i].stride;
788
789                 if (info->planes[i].size > 0)
790                         surf->info.planes[i].size = info->planes[i].size;
791                 else
792                         surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
793
794                 if (num == 1)
795                         surf->planes_bo_idx[i] = 0;
796                 else
797                         surf->planes_bo_idx[i] = i;
798         }
799
800         if (info->size > 0) {
801                 surf->info.size = info->size;
802         } else {
803                 surf->info.size = 0;
804                 for (i = 0; i < info->num_planes; i++)
805                         surf->info.size += surf->info.planes[i].size;
806         }
807
808         surf->flags = TBM_BO_DEFAULT;
809
810         /* create only one bo */
811         surf->num_bos = num;
812         for (i = 0; i < num; i++) {
813                 if (bos[i] == NULL)
814                         goto bail1;
815
816                 surf->bos[i] = tbm_bo_ref(bos[i]);
817                 _tbm_bo_set_surface(bos[i], surf);
818         }
819
820         TBM_TRACE("tbm_surface(%p) width(%d) height(%d) format(%s) bo_num(%d)\n", surf,
821                         info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
822
823         LIST_INITHEAD(&surf->user_data_list);
824         LIST_INITHEAD(&surf->debug_data_list);
825
826         LIST_ADD(&surf->item_link, &mgr->surf_list);
827
828         _tbm_surface_mutex_unlock();
829
830         return surf;
831 bail1:
832         TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
833                                 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
834         for (i = 0; i < num; i++) {
835                 if (surf->bos[i]) {
836                         tbm_bo_unref(surf->bos[i]);
837                         surf->bos[i] = NULL;
838                 }
839         }
840
841         free(surf);
842         surf = NULL;
843
844         if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
845                 LIST_DELINIT(&g_surface_bufmgr->surf_list);
846                 _deinit_surface_bufmgr();
847         }
848
849         _tbm_surface_mutex_unlock();
850
851         return NULL;
852 }
853
854 void
855 tbm_surface_internal_destroy(tbm_surface_h surface)
856 {
857         if (!tbm_surface_internal_is_valid(surface))
858                 return;
859
860         _tbm_surface_mutex_lock();
861
862         surface->refcnt--;
863
864         if (surface->refcnt > 0) {
865                 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
866                 _tbm_surface_mutex_unlock();
867                 return;
868         }
869
870         TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
871
872         if (surface->refcnt == 0)
873                 _tbm_surface_internal_destroy(surface);
874
875         _tbm_surface_mutex_unlock();
876 }
877
878 void
879 tbm_surface_internal_ref(tbm_surface_h surface)
880 {
881         TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
882
883         _tbm_surface_mutex_lock();
884
885         surface->refcnt++;
886
887         TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
888
889         _tbm_surface_mutex_unlock();
890 }
891
892 void
893 tbm_surface_internal_unref(tbm_surface_h surface)
894 {
895         TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
896
897         _tbm_surface_mutex_lock();
898
899         surface->refcnt--;
900
901         if (surface->refcnt > 0) {
902                 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
903                 _tbm_surface_mutex_unlock();
904                 return;
905         }
906
907         TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
908
909         if (surface->refcnt == 0)
910                 _tbm_surface_internal_destroy(surface);
911
912         _tbm_surface_mutex_unlock();
913 }
914
915 int
916 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
917 {
918         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
919
920         struct _tbm_surface *surf;
921         int num;
922
923         _tbm_surface_mutex_lock();
924
925         surf = (struct _tbm_surface *)surface;
926         num = surf->num_bos;
927
928         TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
929
930         _tbm_surface_mutex_unlock();
931
932         return num;
933 }
934
935 tbm_bo
936 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
937 {
938         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
939         TBM_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
940
941         struct _tbm_surface *surf;
942         tbm_bo bo;
943
944         _tbm_surface_mutex_lock();
945
946         surf = (struct _tbm_surface *)surface;
947         bo = surf->bos[bo_idx];
948
949         TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
950
951         _tbm_surface_mutex_unlock();
952
953         return bo;
954 }
955
956 int
957 tbm_surface_internal_get_size(tbm_surface_h surface)
958 {
959         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
960
961         struct _tbm_surface *surf;
962         unsigned int size;
963
964         _tbm_surface_mutex_lock();
965
966         surf = (struct _tbm_surface *)surface;
967         size = surf->info.size;
968
969         TBM_TRACE("tbm_surface(%p) size(%d)\n", surface, size);
970
971         _tbm_surface_mutex_unlock();
972
973         return size;
974 }
975
976 int
977 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
978                                     uint32_t *size, uint32_t *offset, uint32_t *pitch)
979 {
980         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
981         TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
982
983         struct _tbm_surface *surf;
984
985         _tbm_surface_mutex_lock();
986
987         surf = (struct _tbm_surface *)surface;
988
989         if (plane_idx >= surf->info.num_planes) {
990                 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
991                 _tbm_surface_mutex_unlock();
992                 return 0;
993         }
994
995         if (size)
996                 *size = surf->info.planes[plane_idx].size;
997
998         if (offset)
999                 *offset = surf->info.planes[plane_idx].offset;
1000
1001         if (pitch)
1002                 *pitch = surf->info.planes[plane_idx].stride;
1003
1004         TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%d) offset(%d) pitch(%d)\n", surface, plane_idx,
1005                                 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
1006                                 surf->info.planes[plane_idx].stride);
1007
1008         _tbm_surface_mutex_unlock();
1009
1010         return 1;
1011 }
1012
1013 int
1014 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1015                               tbm_surface_info_s *info, int map)
1016 {
1017         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1018
1019         struct _tbm_surface *surf;
1020         tbm_bo_handle bo_handles[4];
1021         int i, j;
1022
1023         _tbm_surface_mutex_lock();
1024
1025         memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1026
1027         surf = (struct _tbm_surface *)surface;
1028
1029         memset(info, 0x00, sizeof(tbm_surface_info_s));
1030         info->width = surf->info.width;
1031         info->height = surf->info.height;
1032         info->format = surf->info.format;
1033         info->bpp = surf->info.bpp;
1034         info->size = surf->info.size;
1035         info->num_planes = surf->info.num_planes;
1036
1037         if (map == 1) {
1038                 for (i = 0; i < surf->num_bos; i++) {
1039                         bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1040                         if (bo_handles[i].ptr == NULL) {
1041                                 for (j = 0; j < i; j++)
1042                                         tbm_bo_unmap(surf->bos[j]);
1043
1044                                 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1045                                 _tbm_surface_mutex_unlock();
1046                                 return 0;
1047                         }
1048                 }
1049         } else {
1050                 for (i = 0; i < surf->num_bos; i++)
1051                         bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1052         }
1053
1054         for (i = 0; i < surf->info.num_planes; i++) {
1055                 info->planes[i].size = surf->info.planes[i].size;
1056                 info->planes[i].offset = surf->info.planes[i].offset;
1057                 info->planes[i].stride = surf->info.planes[i].stride;
1058
1059                 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1060                         info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1061                                               surf->info.planes[i].offset;
1062         }
1063
1064         TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1065
1066         _tbm_surface_mutex_unlock();
1067
1068         return 1;
1069 }
1070
1071 void
1072 tbm_surface_internal_unmap(tbm_surface_h surface)
1073 {
1074         TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1075
1076         struct _tbm_surface *surf;
1077         int i;
1078
1079         _tbm_surface_mutex_lock();
1080
1081         surf = (struct _tbm_surface *)surface;
1082
1083         for (i = 0; i < surf->num_bos; i++)
1084                 tbm_bo_unmap(surf->bos[i]);
1085
1086         TBM_TRACE("tbm_surface(%p)\n", surface);
1087
1088         _tbm_surface_mutex_unlock();
1089 }
1090
1091 unsigned int
1092 tbm_surface_internal_get_width(tbm_surface_h surface)
1093 {
1094         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1095
1096         struct _tbm_surface *surf;
1097         unsigned int width;
1098
1099         _tbm_surface_mutex_lock();
1100
1101         surf = (struct _tbm_surface *)surface;
1102         width = surf->info.width;
1103
1104         TBM_TRACE("tbm_surface(%p) width(%d)\n", surface, width);
1105
1106         _tbm_surface_mutex_unlock();
1107
1108         return width;
1109 }
1110
1111 unsigned int
1112 tbm_surface_internal_get_height(tbm_surface_h surface)
1113 {
1114         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1115
1116         struct _tbm_surface *surf;
1117         unsigned int height;
1118
1119         _tbm_surface_mutex_lock();
1120
1121         surf = (struct _tbm_surface *)surface;
1122         height = surf->info.height;
1123
1124         TBM_TRACE("tbm_surface(%p) height(%d)\n", surface, height);
1125
1126         _tbm_surface_mutex_unlock();
1127
1128         return height;
1129
1130 }
1131
1132 tbm_format
1133 tbm_surface_internal_get_format(tbm_surface_h surface)
1134 {
1135         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1136
1137         struct _tbm_surface *surf;
1138         tbm_format format;
1139
1140         _tbm_surface_mutex_lock();
1141
1142         surf = (struct _tbm_surface *)surface;
1143         format = surf->info.format;
1144
1145         TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1146
1147         _tbm_surface_mutex_unlock();
1148
1149         return format;
1150 }
1151
1152 int
1153 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1154 {
1155         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1156         TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1157         struct _tbm_surface *surf;
1158         int bo_idx;
1159
1160         _tbm_surface_mutex_lock();
1161
1162         surf = (struct _tbm_surface *)surface;
1163         bo_idx = surf->planes_bo_idx[plane_idx];
1164
1165         TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1166
1167         _tbm_surface_mutex_unlock();
1168
1169         return bo_idx;
1170 }
1171
1172 int
1173 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1174                                    tbm_data_free data_free_func)
1175 {
1176         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1177
1178         tbm_user_data *data;
1179
1180         /* check if the data according to the key exist if so, return false. */
1181         data = user_data_lookup(&surface->user_data_list, key);
1182         if (data) {
1183                 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1184                 return 0;
1185         }
1186
1187         data = user_data_create(key, data_free_func);
1188         if (!data) {
1189                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1190                 return 0;
1191         }
1192
1193         TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1194
1195         LIST_ADD(&data->item_link, &surface->user_data_list);
1196
1197         return 1;
1198 }
1199
1200 int
1201 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1202                                    void *data)
1203 {
1204         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1205
1206         tbm_user_data *old_data;
1207
1208         if (LIST_IS_EMPTY(&surface->user_data_list)) {
1209                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1210                 return 0;
1211         }
1212
1213         old_data = user_data_lookup(&surface->user_data_list, key);
1214         if (!old_data) {
1215                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1216                 return 0;
1217         }
1218
1219         if (old_data->data && old_data->free_func)
1220                 old_data->free_func(old_data->data);
1221
1222         old_data->data = data;
1223
1224         TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1225
1226         return 1;
1227 }
1228
1229 int
1230 tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
1231                                    void **data)
1232 {
1233         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1234
1235         tbm_user_data *old_data;
1236
1237         if (!data || LIST_IS_EMPTY(&surface->user_data_list)) {
1238                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1239                 return 0;
1240         }
1241
1242         old_data = user_data_lookup(&surface->user_data_list, key);
1243         if (!old_data) {
1244                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1245                 *data = NULL;
1246                 return 0;
1247         }
1248
1249         *data = old_data->data;
1250
1251         TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1252
1253         return 1;
1254 }
1255
1256 int
1257 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1258                                       unsigned long key)
1259 {
1260         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1261
1262         tbm_user_data *old_data = (void *)0;
1263
1264         if (LIST_IS_EMPTY(&surface->user_data_list)) {
1265                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1266                 return 0;
1267         }
1268
1269         old_data = user_data_lookup(&surface->user_data_list, key);
1270         if (!old_data) {
1271                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1272                 return 0;
1273         }
1274
1275         TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1276
1277         user_data_delete(old_data);
1278
1279         return 1;
1280 }
1281
1282 /* LCOV_EXCL_START */
1283 unsigned int
1284 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1285 {
1286         TBM_RETURN_VAL_IF_FAIL(surface, 0);
1287
1288         return surface->debug_pid;
1289 }
1290
1291 void
1292 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1293 {
1294         TBM_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1295
1296         surface->debug_pid = pid;
1297 }
1298
1299 static tbm_surface_debug_data *
1300 _tbm_surface_internal_debug_data_create(char *key, char *value)
1301 {
1302         tbm_surface_debug_data *debug_data = NULL;
1303
1304         debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1305         if (!debug_data)
1306                 return NULL;
1307
1308         if (key) debug_data->key = strdup(key);
1309         if (value) debug_data->value = strdup(value);
1310
1311         return debug_data;
1312 }
1313
1314 int
1315 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1316 {
1317         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1318         TBM_RETURN_VAL_IF_FAIL(key, 0);
1319
1320         tbm_surface_debug_data *debug_data = NULL;
1321         tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1322         tbm_bufmgr bufmgr = surface->bufmgr;
1323
1324         TBM_RETURN_VAL_IF_FAIL(bufmgr, 0);
1325
1326         if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1327                 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1328                         if (!strcmp(old_data->key ,key)) {
1329                                 if (value)
1330                                         old_data->value = strdup(value);
1331                                 else
1332                                         old_data->value = NULL;
1333                         }
1334                 }
1335         }
1336
1337         debug_data = _tbm_surface_internal_debug_data_create(key, value);
1338         if (!debug_data) {
1339                 TBM_TRACE("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1340                 return 0;
1341         }
1342
1343         TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1344
1345         LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1346
1347         if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1348                 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1349                         if (!strcmp(old_data->key ,key)) {
1350                                 return 1;
1351                         }
1352                 }
1353         }
1354
1355         debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1356         LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1357
1358         return 1;
1359 }
1360
1361 char *
1362 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1363 {
1364         TBM_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
1365
1366         tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1367
1368         if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1369                 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1370                         if (!strcmp(old_data->key, key)) {
1371                                 return old_data->value;
1372                         }
1373                 }
1374         }
1375
1376         return NULL;
1377 }
1378
1379 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1380 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1381
1382 struct _tbm_surface_dump_buf_info {
1383         int index;
1384         tbm_bo bo;
1385         int size;
1386         int dirty;
1387         int dirty_shm;
1388         int shm_stride;
1389         int shm_h;
1390         char name[1024];
1391
1392         tbm_surface_info_s info;
1393
1394         struct list_head link;
1395 };
1396
1397 struct _tbm_surface_dump_info {
1398         char *path;  // copy???
1399         int dump_max;
1400         int count;
1401         struct list_head *link;
1402         struct list_head surface_list; /* link of surface */
1403 };
1404
1405 static tbm_surface_dump_info *g_dump_info = NULL;
1406 static const char *dump_postfix[2] = {"png", "yuv"};
1407
1408 static void
1409 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1410                 int size2, void *data3, int size3)
1411 {
1412         unsigned int *blocks;
1413         FILE *fp = fopen(file, "w+");
1414         TBM_RETURN_IF_FAIL(fp != NULL);
1415
1416         blocks = (unsigned int *)data1;
1417         fwrite(blocks, 1, size1, fp);
1418
1419         if (size2 > 0) {
1420                 blocks = (unsigned int *)data2;
1421                 fwrite(blocks, 1, size2, fp);
1422         }
1423
1424         if (size3 > 0) {
1425                 blocks = (unsigned int *)data3;
1426                 fwrite(blocks, 1, size3, fp);
1427         }
1428
1429         fclose(fp);
1430 }
1431
1432 static void
1433 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1434                 int height)
1435 {
1436         FILE *fp = fopen(file, "wb");
1437         TBM_RETURN_IF_FAIL(fp != NULL);
1438         int depth = 8;
1439
1440         png_structp pPngStruct =
1441                 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1442         if (!pPngStruct) {
1443                 fclose(fp);
1444                 return;
1445         }
1446
1447         png_infop pPngInfo = png_create_info_struct(pPngStruct);
1448         if (!pPngInfo) {
1449                 png_destroy_write_struct(&pPngStruct, NULL);
1450                 fclose(fp);
1451                 return;
1452         }
1453
1454         png_init_io(pPngStruct, fp);
1455         png_set_IHDR(pPngStruct,
1456                         pPngInfo,
1457                         width,
1458                         height,
1459                         depth,
1460                         PNG_COLOR_TYPE_RGBA,
1461                         PNG_INTERLACE_NONE,
1462                         PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1463
1464         png_set_bgr(pPngStruct);
1465         png_write_info(pPngStruct, pPngInfo);
1466
1467         const int pixel_size = 4;       // RGBA
1468         png_bytep *row_pointers =
1469                         png_malloc(pPngStruct, height * sizeof(png_byte *));
1470
1471         unsigned int *blocks = (unsigned int *)data;
1472         int y = 0;
1473         int x = 0;
1474
1475         for (; y < height; ++y) {
1476                 png_bytep row =
1477                         png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1478                 row_pointers[y] = (png_bytep)row;
1479                 for (x = 0; x < width; ++x) {
1480                         unsigned int curBlock = blocks[y * width + x];
1481                         row[x * pixel_size] = (curBlock & 0xFF);
1482                         row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1483                         row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1484                         row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1485                 }
1486         }
1487
1488         png_write_image(pPngStruct, row_pointers);
1489         png_write_end(pPngStruct, pPngInfo);
1490
1491         for (y = 0; y < height; y++)
1492                 png_free(pPngStruct, row_pointers[y]);
1493         png_free(pPngStruct, row_pointers);
1494
1495         png_destroy_write_struct(&pPngStruct, &pPngInfo);
1496
1497         fclose(fp);
1498 }
1499
1500 void
1501 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1502 {
1503         TBM_RETURN_IF_FAIL(path != NULL);
1504         TBM_RETURN_IF_FAIL(w > 0);
1505         TBM_RETURN_IF_FAIL(h > 0);
1506         TBM_RETURN_IF_FAIL(count > 0);
1507
1508         tbm_surface_dump_buf_info *buf_info = NULL;
1509         tbm_surface_dump_buf_info *tmp;
1510         tbm_bo bo = NULL;
1511         int i;
1512         int buffer_size;
1513         tbm_surface_h tbm_surface;
1514         tbm_surface_info_s info;
1515         tbm_surface_error_e err;
1516
1517         /* check running */
1518         if (g_dump_info) {
1519                 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1520                 return;
1521         }
1522
1523         g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1524         TBM_RETURN_IF_FAIL(g_dump_info);
1525
1526         LIST_INITHEAD(&g_dump_info->surface_list);
1527         g_dump_info->count = 0;
1528         g_dump_info->dump_max = count;
1529
1530         /* get buffer size */
1531         tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1532         if (tbm_surface == NULL) {
1533                 TBM_LOG_E("tbm_surface_create fail\n");
1534                 free(g_dump_info);
1535                 g_dump_info = NULL;
1536                 return;
1537         }
1538         err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
1539         if (err != TBM_SURFACE_ERROR_NONE) {
1540                 TBM_LOG_E("tbm_surface_map fail\n");
1541                 tbm_surface_destroy(tbm_surface);
1542                 free(g_dump_info);
1543                 g_dump_info = NULL;
1544                 return;
1545         }
1546         buffer_size = info.planes[0].stride * h;
1547         tbm_surface_unmap(tbm_surface);
1548         tbm_surface_destroy(tbm_surface);
1549
1550         /* create dump lists */
1551         for (i = 0; i < count; i++)     {
1552                 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1553                 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1554                 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1555                 if (bo == NULL) {
1556                         free(buf_info);
1557                         goto fail;
1558                 }
1559
1560                 buf_info->index = i;
1561                 buf_info->bo = bo;
1562                 buf_info->size = buffer_size;
1563
1564                 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1565         }
1566
1567         g_dump_info->path = path;
1568         g_dump_info->link = &g_dump_info->surface_list;
1569
1570         TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1571
1572         return;
1573 fail:
1574         /* free resources */
1575         if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1576                 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1577                         tbm_bo_unref(buf_info->bo);
1578                         free(buf_info);
1579                 }
1580         }
1581
1582         TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1583
1584         free(g_dump_info);
1585         g_dump_info = NULL;
1586
1587         return;
1588 }
1589
1590 void
1591 tbm_surface_internal_dump_end(void)
1592 {
1593         tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1594         tbm_bo_handle bo_handle;
1595
1596         if (!g_dump_info)
1597                 return;
1598
1599         /* make files */
1600         if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1601                 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1602                         char file[2048];
1603
1604                         if (buf_info->dirty) {
1605                                 void *ptr1 = NULL;
1606                                 void *ptr2 = NULL;
1607
1608                                 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1609                                 if (bo_handle.ptr == NULL)
1610                                         continue;
1611
1612                                 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1613                                 TBM_LOG_I("Dump File.. %s generated.\n", file);
1614
1615                                 switch (buf_info->info.format) {
1616                                 case TBM_FORMAT_ARGB8888:
1617                                 case TBM_FORMAT_XRGB8888:
1618                                         _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1619                                                                         buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1620                                         break;
1621                                 case TBM_FORMAT_YVU420:
1622                                 case TBM_FORMAT_YUV420:
1623                                         ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1624                                         ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1625                                         _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1626                                                                         buf_info->info.planes[0].stride * buf_info->info.height,
1627                                                                         ptr1,
1628                                                                         buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1629                                                                         ptr2,
1630                                                                         buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1631                                         break;
1632                                 case TBM_FORMAT_NV12:
1633                                 case TBM_FORMAT_NV21:
1634                                         ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1635                                         _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1636                                                                         buf_info->info.planes[0].stride * buf_info->info.height,
1637                                                                         ptr1,
1638                                                                         buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1639                                                                         NULL, 0);
1640                                         break;
1641                                 case TBM_FORMAT_YUYV:
1642                                 case TBM_FORMAT_UYVY:
1643                                         _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1644                                                                         buf_info->info.planes[0].stride * buf_info->info.height,
1645                                                                         NULL, 0, NULL, 0);
1646                                         break;
1647                                 default:
1648                                         TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1649                                         tbm_bo_unmap(buf_info->bo);
1650                                         return;
1651                                 }
1652
1653                                 tbm_bo_unmap(buf_info->bo);
1654                         } else if (buf_info->dirty_shm) {
1655                                 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1656                                 if (bo_handle.ptr == NULL)
1657                                         continue;
1658
1659                                 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1660                                 TBM_LOG_I("Dump File.. %s generated.\n", file);
1661
1662                                 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1663                                                                 buf_info->shm_stride >> 2, buf_info->shm_h);
1664
1665                                 tbm_bo_unmap(buf_info->bo);
1666                         }
1667                 }
1668         }
1669
1670         /* free resources */
1671         if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1672                 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1673                         tbm_bo_unref(buf_info->bo);
1674                         free(buf_info);
1675                 }
1676         }
1677
1678         free(g_dump_info);
1679         g_dump_info = NULL;
1680
1681         TBM_LOG_I("Dump End..\n");
1682 }
1683
1684 void
1685 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1686 {
1687         TBM_RETURN_IF_FAIL(surface != NULL);
1688         TBM_RETURN_IF_FAIL(type != NULL);
1689
1690         tbm_surface_dump_buf_info *buf_info;
1691         tbm_surface_info_s info;
1692         struct list_head *next_link;
1693         tbm_bo_handle bo_handle;
1694         int ret;
1695         const char *postfix;
1696
1697         if (!g_dump_info)
1698                 return;
1699
1700         next_link = g_dump_info->link->next;
1701         TBM_RETURN_IF_FAIL(next_link != NULL);
1702
1703         if (next_link == &g_dump_info->surface_list) {
1704                 next_link = next_link->next;
1705                 TBM_RETURN_IF_FAIL(next_link != NULL);
1706         }
1707
1708         buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1709         TBM_RETURN_IF_FAIL(buf_info != NULL);
1710
1711         ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1712         TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1713
1714         if (info.size > buf_info->size) {
1715                 TBM_LOG_W("Dump skip. surface over created buffer size(%d, %d)\n", info.size, buf_info->size);
1716                 tbm_surface_unmap(surface);
1717                 return;
1718         }
1719
1720         if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1721                 postfix = dump_postfix[0];
1722         else
1723                 postfix = dump_postfix[1];
1724
1725         /* make the file information */
1726         memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1727
1728         /* dump */
1729         bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1730         TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1731         memset(bo_handle.ptr, 0x00, buf_info->size);
1732
1733         switch (info.format) {
1734         case TBM_FORMAT_ARGB8888:
1735         case TBM_FORMAT_XRGB8888:
1736                 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d_%p-%s.%s",
1737                                  _tbm_surface_internal_get_time(),
1738                                  g_dump_info->count++, surface, type, postfix);
1739                 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1740                 break;
1741         case TBM_FORMAT_YVU420:
1742         case TBM_FORMAT_YUV420:
1743                 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1744                                  _tbm_surface_internal_get_time(),
1745                                  g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1746                 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1747                 bo_handle.ptr += info.planes[0].stride * info.height;
1748                 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1749                 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1750                 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1751                 break;
1752         case TBM_FORMAT_NV12:
1753         case TBM_FORMAT_NV21:
1754                 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1755                                  _tbm_surface_internal_get_time(),
1756                                  g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1757                 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1758                 bo_handle.ptr += info.planes[0].stride * info.height;
1759                 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1760                 break;
1761         case TBM_FORMAT_YUYV:
1762         case TBM_FORMAT_UYVY:
1763                 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1764                                  _tbm_surface_internal_get_time(),
1765                                  g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1766                 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1767                 break;
1768         default:
1769                 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1770                 tbm_bo_unmap(buf_info->bo);
1771                 return;
1772         }
1773
1774         tbm_bo_unmap(buf_info->bo);
1775
1776         tbm_surface_unmap(surface);
1777
1778         buf_info->dirty = 1;
1779         buf_info->dirty_shm = 0;
1780
1781         if (g_dump_info->count == 1000)
1782                 g_dump_info->count = 0;
1783
1784         g_dump_info->link = next_link;
1785
1786         TBM_LOG_I("Dump %s \n", buf_info->name);
1787 }
1788
1789 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int  stride, const char *type)
1790 {
1791         TBM_RETURN_IF_FAIL(ptr != NULL);
1792         TBM_RETURN_IF_FAIL(w > 0);
1793         TBM_RETURN_IF_FAIL(h > 0);
1794         TBM_RETURN_IF_FAIL(stride > 0);
1795         TBM_RETURN_IF_FAIL(type != NULL);
1796
1797         tbm_surface_dump_buf_info *buf_info;
1798         struct list_head *next_link;
1799         tbm_bo_handle bo_handle;
1800
1801         if (!g_dump_info)
1802                 return;
1803
1804         next_link = g_dump_info->link->next;
1805         TBM_RETURN_IF_FAIL(next_link != NULL);
1806
1807         if (next_link == &g_dump_info->surface_list) {
1808                 next_link = next_link->next;
1809                 TBM_RETURN_IF_FAIL(next_link != NULL);
1810         }
1811
1812         buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1813         TBM_RETURN_IF_FAIL(buf_info != NULL);
1814
1815         if (stride * h > buf_info->size) {
1816                 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", stride * h, buf_info->size);
1817                 return;
1818         }
1819
1820         /* dump */
1821         bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1822         TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1823         memset(bo_handle.ptr, 0x00, buf_info->size);
1824         memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1825
1826         snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1827                          _tbm_surface_internal_get_time(),
1828                          g_dump_info->count++, type, dump_postfix[0]);
1829         memcpy(bo_handle.ptr, ptr, stride * h);
1830
1831         tbm_bo_unmap(buf_info->bo);
1832
1833         buf_info->dirty = 0;
1834         buf_info->dirty_shm = 1;
1835         buf_info->shm_stride = stride;
1836         buf_info->shm_h = h;
1837
1838         if (g_dump_info->count == 1000)
1839                 g_dump_info->count = 0;
1840
1841         g_dump_info->link = next_link;
1842
1843         TBM_LOG_I("Dump %s \n", buf_info->name);
1844 }
1845
1846 void tbm_surface_internal_dump_all(char *path)
1847 {
1848         TBM_RETURN_IF_FAIL(path != NULL);
1849         int w = 0, h = 0, count = 0;
1850         tbm_surface_h surface = NULL, tmp = NULL;
1851
1852         count = _tbm_surface_get_max_size(&w, &h);
1853         if (count == 0) {
1854                 TBM_LOG_I("No tbm_surface.\n");
1855                 return;
1856         }
1857
1858         tbm_surface_internal_dump_start(path, w, h, count);
1859
1860         LIST_FOR_EACH_ENTRY_SAFE(surface, tmp, &g_surface_bufmgr->surf_list, item_link) {
1861                 tbm_surface_internal_dump_buffer(surface, "dump_all");
1862         }
1863
1864         tbm_surface_internal_dump_end();
1865 }
1866 /*LCOV_EXCL_STOP*/