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