include config.h in all c file and fixed dlog level
[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, tmp = 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_SAFE(old_data, tmp, &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
589         _tbm_surface_mutex_lock();
590
591         if (!g_surface_bufmgr) {
592                 _init_surface_bufmgr();
593                 LIST_INITHEAD(&g_surface_bufmgr->surf_list);
594         }
595
596         mgr = g_surface_bufmgr;
597         if (!TBM_BUFMGR_IS_VALID(mgr)) {
598                 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
599                                 width, height, _tbm_surface_internal_format_to_str(format), flags);
600                 _tbm_surface_mutex_unlock();
601                 return NULL;
602         }
603         surf = calloc(1, sizeof(struct _tbm_surface));
604         if (!surf) {
605                 TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
606                                 width, height, _tbm_surface_internal_format_to_str(format), flags);
607                 _tbm_surface_mutex_unlock();
608                 return NULL;
609         }
610
611         surf->bufmgr = mgr;
612         surf->info.width = width;
613         surf->info.height = height;
614         surf->info.format = format;
615         surf->info.bpp = tbm_surface_internal_get_bpp(format);
616         surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
617         surf->refcnt = 1;
618
619         /* get size, stride and offset bo_idx */
620         for (i = 0; i < surf->info.num_planes; i++) {
621                 _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride,
622                                                        &bo_idx);
623                 surf->info.planes[i].size = size;
624                 surf->info.planes[i].offset = offset;
625                 surf->info.planes[i].stride = stride;
626                 surf->planes_bo_idx[i] = bo_idx;
627         }
628
629         surf->num_bos = 1;
630
631         for (i = 0; i < surf->info.num_planes; i++) {
632                 surf->info.size += surf->info.planes[i].size;
633
634                 if (surf->num_bos < surf->planes_bo_idx[i] + 1)
635                         surf->num_bos = surf->planes_bo_idx[i] + 1;
636         }
637
638         surf->flags = flags;
639
640         for (i = 0; i < surf->num_bos; i++) {
641                 bo_size = 0;
642                 for (j = 0; j < surf->info.num_planes; j++) {
643                         if (surf->planes_bo_idx[j] == i)
644                                 bo_size += surf->info.planes[j].size;
645                 }
646
647                 if (mgr->backend->surface_bo_alloc) {
648                         /* LCOV_EXCL_START */
649                         tbm_bo bo = NULL;
650                         void *bo_priv = NULL;
651
652                         bo = calloc(1, sizeof(struct _tbm_bo));
653                         if (!bo) {
654                                 TBM_LOG_E("fail to alloc bo struct\n");
655                                 goto alloc_fail;
656                         }
657
658                         bo->bufmgr = surf->bufmgr;
659
660                         pthread_mutex_lock(&surf->bufmgr->lock);
661
662                         bo_priv = mgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
663                         if (!bo_priv) {
664                                 TBM_LOG_E("fail to alloc bo priv\n");
665                                 free(bo);
666                                 pthread_mutex_unlock(&surf->bufmgr->lock);
667                                 goto alloc_fail;
668                         }
669
670                         bo->ref_cnt = 1;
671                         bo->flags = flags;
672                         bo->priv = bo_priv;
673
674                         LIST_INITHEAD(&bo->user_data_list);
675
676                         LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
677
678                         pthread_mutex_unlock(&surf->bufmgr->lock);
679
680                         surf->bos[i] = bo;
681                         /* LCOV_EXCL_STOP */
682                 } else {
683                         surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
684                 }
685
686                 if (!surf->bos[i]) {
687                         TBM_LOG_E("fail to alloc bo idx:%d\n", i);
688                         goto alloc_fail;
689                 }
690
691                 _tbm_bo_set_surface(surf->bos[i], surf);
692
693         }
694
695         TBM_TRACE("width(%d) height(%d) format(%s) flags(%d) tbm_surface(%p)\n", width, height,
696                         _tbm_surface_internal_format_to_str(format), flags, surf);
697
698         LIST_INITHEAD(&surf->user_data_list);
699         LIST_INITHEAD(&surf->debug_data_list);
700
701         LIST_ADD(&surf->item_link, &mgr->surf_list);
702
703         _tbm_surface_mutex_unlock();
704
705         return surf;
706
707 alloc_fail:
708
709         TBM_TRACE("error: width(%d) height(%d) format(%s) flags(%d)\n",
710                         width, height, _tbm_surface_internal_format_to_str(format), flags);
711
712         for (j = 0; j < i; j++) {
713                 if (surf->bos[j])
714                         tbm_bo_unref(surf->bos[j]);
715         }
716
717         free(surf);
718         surf = NULL;
719
720         if (LIST_IS_EMPTY(&mgr->surf_list)) {
721                 LIST_DELINIT(&mgr->surf_list);
722                 _deinit_surface_bufmgr();
723         }
724
725         _tbm_surface_mutex_unlock();
726         return NULL;
727 }
728
729 tbm_surface_h
730 tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
731                                      tbm_bo *bos, int num)
732 {
733         TBM_RETURN_VAL_IF_FAIL(bos, NULL);
734         TBM_RETURN_VAL_IF_FAIL(info, NULL);
735         TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
736
737         struct _tbm_bufmgr *mgr;
738         struct _tbm_surface *surf = NULL;
739         int i;
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         }
747
748         mgr = g_surface_bufmgr;
749         if (!TBM_BUFMGR_IS_VALID(mgr)) {
750                 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
751                                 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
752                 _tbm_surface_mutex_unlock();
753                 return NULL;
754         }
755
756         surf = calloc(1, sizeof(struct _tbm_surface));
757         if (!surf) {
758                 TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
759                                 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
760                 _tbm_surface_mutex_unlock();
761                 return NULL;
762         }
763
764         surf->bufmgr = mgr;
765         surf->info.width = info->width;
766         surf->info.height = info->height;
767         surf->info.format = info->format;
768         surf->info.bpp = info->bpp;
769         surf->info.num_planes = info->num_planes;
770         surf->refcnt = 1;
771
772         /* get size, stride and offset */
773         for (i = 0; i < info->num_planes; i++) {
774                 surf->info.planes[i].offset = info->planes[i].offset;
775                 surf->info.planes[i].stride = info->planes[i].stride;
776
777                 if (info->planes[i].size > 0)
778                         surf->info.planes[i].size = info->planes[i].size;
779                 else
780                         surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
781
782                 if (num == 1)
783                         surf->planes_bo_idx[i] = 0;
784                 else
785                         surf->planes_bo_idx[i] = i;
786         }
787
788         if (info->size > 0) {
789                 surf->info.size = info->size;
790         } else {
791                 surf->info.size = 0;
792                 for (i = 0; i < info->num_planes; i++)
793                         surf->info.size += surf->info.planes[i].size;
794         }
795
796         surf->flags = TBM_BO_DEFAULT;
797
798         /* create only one bo */
799         surf->num_bos = num;
800         for (i = 0; i < num; i++) {
801                 if (bos[i] == NULL)
802                         goto bail1;
803
804                 surf->bos[i] = tbm_bo_ref(bos[i]);
805                 _tbm_bo_set_surface(bos[i], surf);
806         }
807
808         TBM_TRACE("tbm_surface(%p) width(%d) height(%d) format(%s) bo_num(%d)\n", surf,
809                         info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
810
811         LIST_INITHEAD(&surf->user_data_list);
812         LIST_INITHEAD(&surf->debug_data_list);
813
814         LIST_ADD(&surf->item_link, &mgr->surf_list);
815
816         _tbm_surface_mutex_unlock();
817
818         return surf;
819 bail1:
820         TBM_TRACE("error: width(%d) height(%d) format(%s) bo_num(%d)\n",
821                                 info->width, info->height, _tbm_surface_internal_format_to_str(info->format), num);
822         for (i = 0; i < num; i++) {
823                 if (surf->bos[i]) {
824                         tbm_bo_unref(surf->bos[i]);
825                         surf->bos[i] = NULL;
826                 }
827         }
828
829         free(surf);
830         surf = NULL;
831
832         if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
833                 LIST_DELINIT(&g_surface_bufmgr->surf_list);
834                 _deinit_surface_bufmgr();
835         }
836
837         _tbm_surface_mutex_unlock();
838
839         return NULL;
840 }
841
842 void
843 tbm_surface_internal_destroy(tbm_surface_h surface)
844 {
845         _tbm_surface_mutex_lock();
846
847         TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
848
849         surface->refcnt--;
850
851         if (surface->refcnt > 0) {
852                 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
853                 _tbm_surface_mutex_unlock();
854                 return;
855         }
856
857         TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
858
859         if (surface->refcnt == 0)
860                 _tbm_surface_internal_destroy(surface);
861
862         _tbm_surface_mutex_unlock();
863 }
864
865 void
866 tbm_surface_internal_ref(tbm_surface_h surface)
867 {
868         _tbm_surface_mutex_lock();
869
870         TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
871
872         surface->refcnt++;
873
874         TBM_TRACE("tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
875
876         _tbm_surface_mutex_unlock();
877 }
878
879 void
880 tbm_surface_internal_unref(tbm_surface_h surface)
881 {
882         _tbm_surface_mutex_lock();
883
884         TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
885
886         surface->refcnt--;
887
888         if (surface->refcnt > 0) {
889                 TBM_TRACE("reduce a refcnt(%d) of tbm_surface(%p)\n", surface->refcnt, surface);
890                 _tbm_surface_mutex_unlock();
891                 return;
892         }
893
894         TBM_TRACE("destroy tbm_surface(%p) refcnt(%d)\n", surface, surface->refcnt);
895
896         if (surface->refcnt == 0)
897                 _tbm_surface_internal_destroy(surface);
898
899         _tbm_surface_mutex_unlock();
900 }
901
902 int
903 tbm_surface_internal_get_num_bos(tbm_surface_h surface)
904 {
905         struct _tbm_surface *surf;
906         int num;
907
908         _tbm_surface_mutex_lock();
909
910         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
911
912         surf = (struct _tbm_surface *)surface;
913         num = surf->num_bos;
914
915         TBM_TRACE("tbm_surface(%p) num_bos(%d)\n", surface, num);
916
917         _tbm_surface_mutex_unlock();
918
919         return num;
920 }
921
922 tbm_bo
923 tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
924 {
925         struct _tbm_surface *surf;
926         tbm_bo bo;
927
928         _tbm_surface_mutex_lock();
929
930         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), NULL);
931         TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
932
933         surf = (struct _tbm_surface *)surface;
934         bo = surf->bos[bo_idx];
935
936         TBM_TRACE("tbm_surface(%p) bo_idx(%d) tbm_bo(%p)\n", surface, bo_idx, bo);
937
938         _tbm_surface_mutex_unlock();
939
940         return bo;
941 }
942
943 int
944 tbm_surface_internal_get_size(tbm_surface_h surface)
945 {
946         struct _tbm_surface *surf;
947         unsigned int size;
948
949         _tbm_surface_mutex_lock();
950
951         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
952
953         surf = (struct _tbm_surface *)surface;
954         size = surf->info.size;
955
956         TBM_TRACE("tbm_surface(%p) size(%d)\n", surface, size);
957
958         _tbm_surface_mutex_unlock();
959
960         return size;
961 }
962
963 int
964 tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
965                                     uint32_t *size, uint32_t *offset, uint32_t *pitch)
966 {
967         struct _tbm_surface *surf;
968
969         _tbm_surface_mutex_lock();
970
971         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
972         TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
973
974         surf = (struct _tbm_surface *)surface;
975
976         if (plane_idx >= surf->info.num_planes) {
977                 TBM_TRACE("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
978                 _tbm_surface_mutex_unlock();
979                 return 0;
980         }
981
982         if (size)
983                 *size = surf->info.planes[plane_idx].size;
984
985         if (offset)
986                 *offset = surf->info.planes[plane_idx].offset;
987
988         if (pitch)
989                 *pitch = surf->info.planes[plane_idx].stride;
990
991         TBM_TRACE("tbm_surface(%p) plane_idx(%d) size(%d) offset(%d) pitch(%d)\n", surface, plane_idx,
992                                 surf->info.planes[plane_idx].size, surf->info.planes[plane_idx].offset,
993                                 surf->info.planes[plane_idx].stride);
994
995         _tbm_surface_mutex_unlock();
996
997         return 1;
998 }
999
1000 int
1001 tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
1002                               tbm_surface_info_s *info, int map)
1003 {
1004         struct _tbm_surface *surf;
1005         tbm_bo_handle bo_handles[4];
1006         int i, j;
1007
1008         _tbm_surface_mutex_lock();
1009
1010         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1011
1012         memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
1013
1014         surf = (struct _tbm_surface *)surface;
1015
1016         memset(info, 0x00, sizeof(tbm_surface_info_s));
1017         info->width = surf->info.width;
1018         info->height = surf->info.height;
1019         info->format = surf->info.format;
1020         info->bpp = surf->info.bpp;
1021         info->size = surf->info.size;
1022         info->num_planes = surf->info.num_planes;
1023
1024         if (map == 1) {
1025                 for (i = 0; i < surf->num_bos; i++) {
1026                         bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
1027                         if (bo_handles[i].ptr == NULL) {
1028                                 for (j = 0; j < i; j++)
1029                                         tbm_bo_unmap(surf->bos[j]);
1030
1031                                 TBM_TRACE("error: tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1032                                 _tbm_surface_mutex_unlock();
1033                                 return 0;
1034                         }
1035                 }
1036         } else {
1037                 for (i = 0; i < surf->num_bos; i++)
1038                         bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
1039         }
1040
1041         for (i = 0; i < surf->info.num_planes; i++) {
1042                 info->planes[i].size = surf->info.planes[i].size;
1043                 info->planes[i].offset = surf->info.planes[i].offset;
1044                 info->planes[i].stride = surf->info.planes[i].stride;
1045
1046                 if (bo_handles[surf->planes_bo_idx[i]].ptr)
1047                         info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr +
1048                                               surf->info.planes[i].offset;
1049         }
1050
1051         TBM_TRACE("tbm_surface(%p) opt(%d) map(%d)\n", surface, opt, map);
1052
1053         _tbm_surface_mutex_unlock();
1054
1055         return 1;
1056 }
1057
1058 void
1059 tbm_surface_internal_unmap(tbm_surface_h surface)
1060 {
1061         struct _tbm_surface *surf;
1062         int i;
1063
1064         _tbm_surface_mutex_lock();
1065
1066         TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1067
1068         surf = (struct _tbm_surface *)surface;
1069
1070         for (i = 0; i < surf->num_bos; i++)
1071                 tbm_bo_unmap(surf->bos[i]);
1072
1073         TBM_TRACE("tbm_surface(%p)\n", surface);
1074
1075         _tbm_surface_mutex_unlock();
1076 }
1077
1078 unsigned int
1079 tbm_surface_internal_get_width(tbm_surface_h surface)
1080 {
1081         struct _tbm_surface *surf;
1082         unsigned int width;
1083
1084         _tbm_surface_mutex_lock();
1085
1086         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1087
1088         surf = (struct _tbm_surface *)surface;
1089         width = surf->info.width;
1090
1091         TBM_TRACE("tbm_surface(%p) width(%d)\n", surface, width);
1092
1093         _tbm_surface_mutex_unlock();
1094
1095         return width;
1096 }
1097
1098 unsigned int
1099 tbm_surface_internal_get_height(tbm_surface_h surface)
1100 {
1101         struct _tbm_surface *surf;
1102         unsigned int height;
1103
1104         _tbm_surface_mutex_lock();
1105
1106         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1107
1108         surf = (struct _tbm_surface *)surface;
1109         height = surf->info.height;
1110
1111         TBM_TRACE("tbm_surface(%p) height(%d)\n", surface, height);
1112
1113         _tbm_surface_mutex_unlock();
1114
1115         return height;
1116
1117 }
1118
1119 tbm_format
1120 tbm_surface_internal_get_format(tbm_surface_h surface)
1121 {
1122         struct _tbm_surface *surf;
1123         tbm_format format;
1124
1125         _tbm_surface_mutex_lock();
1126
1127         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1128
1129         surf = (struct _tbm_surface *)surface;
1130         format = surf->info.format;
1131
1132         TBM_TRACE("tbm_surface(%p) format(%s)\n", surface, _tbm_surface_internal_format_to_str(format));
1133
1134         _tbm_surface_mutex_unlock();
1135
1136         return format;
1137 }
1138
1139 int
1140 tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
1141 {
1142         struct _tbm_surface *surf;
1143         int bo_idx;
1144
1145         _tbm_surface_mutex_lock();
1146
1147         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1148         TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
1149
1150         surf = (struct _tbm_surface *)surface;
1151         bo_idx = surf->planes_bo_idx[plane_idx];
1152
1153         TBM_TRACE("tbm_surface(%p) plane_idx(%d) bo_idx(%d)\n", surface, plane_idx, bo_idx);
1154
1155         _tbm_surface_mutex_unlock();
1156
1157         return bo_idx;
1158 }
1159
1160 int
1161 tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
1162                                    tbm_data_free data_free_func)
1163 {
1164         tbm_user_data *data;
1165
1166         _tbm_surface_mutex_lock();
1167
1168         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1169
1170         /* check if the data according to the key exist if so, return false. */
1171         data = user_data_lookup(&surface->user_data_list, key);
1172         if (data) {
1173                 TBM_TRACE("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
1174                 _tbm_surface_mutex_unlock();
1175                 return 0;
1176         }
1177
1178         data = user_data_create(key, data_free_func);
1179         if (!data) {
1180                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1181                 _tbm_surface_mutex_unlock();
1182                 return 0;
1183         }
1184
1185         TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, data);
1186
1187         LIST_ADD(&data->item_link, &surface->user_data_list);
1188
1189         _tbm_surface_mutex_unlock();
1190
1191         return 1;
1192 }
1193
1194 int
1195 tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
1196                                    void *data)
1197 {
1198         tbm_user_data *old_data;
1199
1200         _tbm_surface_mutex_lock();
1201
1202         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1203
1204         if (LIST_IS_EMPTY(&surface->user_data_list)) {
1205                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1206                 _tbm_surface_mutex_unlock();
1207                 return 0;
1208         }
1209
1210         old_data = user_data_lookup(&surface->user_data_list, key);
1211         if (!old_data) {
1212                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1213                 _tbm_surface_mutex_unlock();
1214                 return 0;
1215         }
1216
1217         if (old_data->data && old_data->free_func)
1218                 old_data->free_func(old_data->data);
1219
1220         old_data->data = data;
1221
1222         TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1223
1224         _tbm_surface_mutex_unlock();
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_user_data *old_data;
1234
1235         _tbm_surface_mutex_lock();
1236
1237         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1238
1239         if (!data || LIST_IS_EMPTY(&surface->user_data_list)) {
1240                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1241                 _tbm_surface_mutex_unlock();
1242                 return 0;
1243         }
1244
1245         old_data = user_data_lookup(&surface->user_data_list, key);
1246         if (!old_data) {
1247                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1248                 *data = NULL;
1249                 _tbm_surface_mutex_unlock();
1250                 return 0;
1251         }
1252
1253         *data = old_data->data;
1254
1255         TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1256
1257         _tbm_surface_mutex_unlock();
1258
1259         return 1;
1260 }
1261
1262 int
1263 tbm_surface_internal_delete_user_data(tbm_surface_h surface,
1264                                       unsigned long key)
1265 {
1266         tbm_user_data *old_data = (void *)0;
1267
1268         _tbm_surface_mutex_lock();
1269
1270         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1271
1272         if (LIST_IS_EMPTY(&surface->user_data_list)) {
1273                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1274                 _tbm_surface_mutex_unlock();
1275                 return 0;
1276         }
1277
1278         old_data = user_data_lookup(&surface->user_data_list, key);
1279         if (!old_data) {
1280                 TBM_TRACE("error: tbm_surface(%p) key(%lu)\n", surface, key);
1281                 _tbm_surface_mutex_unlock();
1282                 return 0;
1283         }
1284
1285         TBM_TRACE("tbm_surface(%p) key(%lu) data(%p)\n", surface, key, old_data->data);
1286
1287         user_data_delete(old_data);
1288
1289         _tbm_surface_mutex_unlock();
1290
1291         return 1;
1292 }
1293
1294 /* LCOV_EXCL_START */
1295 unsigned int
1296 _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
1297 {
1298         TBM_RETURN_VAL_IF_FAIL(surface, 0);
1299
1300         return surface->debug_pid;
1301 }
1302
1303 void
1304 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
1305 {
1306         _tbm_surface_mutex_lock();
1307
1308         TBM_SURFACE_RETURN_IF_FAIL(tbm_surface_internal_is_valid(surface));
1309
1310         surface->debug_pid = pid;
1311
1312         _tbm_surface_mutex_unlock();
1313 }
1314
1315 static tbm_surface_debug_data *
1316 _tbm_surface_internal_debug_data_create(char *key, char *value)
1317 {
1318         tbm_surface_debug_data *debug_data = NULL;
1319
1320         debug_data = calloc(1, sizeof(tbm_surface_debug_data));
1321         if (!debug_data)
1322                 return NULL;
1323
1324         if (key) debug_data->key = strdup(key);
1325         if (value) debug_data->value = strdup(value);
1326
1327         return debug_data;
1328 }
1329
1330 int
1331 tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *value)
1332 {
1333         tbm_surface_debug_data *debug_data = NULL;
1334         tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1335         tbm_bufmgr bufmgr = NULL;
1336
1337         _tbm_surface_mutex_lock();
1338
1339         TBM_SURFACE_RETURN_VAL_IF_FAIL(tbm_surface_internal_is_valid(surface), 0);
1340         TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
1341
1342         bufmgr = surface->bufmgr;
1343
1344         TBM_SURFACE_RETURN_VAL_IF_FAIL(bufmgr, 0);
1345
1346         if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1347                 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1348                         if (!strcmp(old_data->key, key)) {
1349                                 if (value)
1350                                         old_data->value = strdup(value);
1351                                 else
1352                                         old_data->value = NULL;
1353                         }
1354                 }
1355         }
1356
1357         debug_data = _tbm_surface_internal_debug_data_create(key, value);
1358         if (!debug_data) {
1359                 TBM_TRACE("error: tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1360                 _tbm_surface_mutex_unlock();
1361                 return 0;
1362         }
1363
1364         TBM_TRACE("tbm_surface(%p) key(%s) value(%s)\n", surface, key, value);
1365
1366         LIST_ADD(&debug_data->item_link, &surface->debug_data_list);
1367
1368         if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1369                 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bufmgr->debug_key_list, item_link) {
1370                         if (!strcmp(old_data->key, key)) {
1371                                 _tbm_surface_mutex_unlock();
1372                                 return 1;
1373                         }
1374                 }
1375         }
1376
1377         debug_data = _tbm_surface_internal_debug_data_create(key, NULL);
1378         LIST_ADD(&debug_data->item_link, &bufmgr->debug_key_list);
1379
1380         _tbm_surface_mutex_unlock();
1381
1382         return 1;
1383 }
1384
1385 char *
1386 _tbm_surface_internal_get_debug_data(tbm_surface_h surface, char *key)
1387 {
1388         tbm_surface_debug_data *old_data = NULL, *tmp = NULL;
1389
1390         _tbm_surface_mutex_lock();
1391
1392         TBM_SURFACE_RETURN_VAL_IF_FAIL(surface, NULL);
1393
1394         if (!LIST_IS_EMPTY(&surface->debug_data_list)) {
1395                 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->debug_data_list, item_link) {
1396                         if (!strcmp(old_data->key, key)) {
1397                                 _tbm_surface_mutex_unlock();
1398                                 return old_data->value;
1399                         }
1400                 }
1401         }
1402
1403         _tbm_surface_mutex_unlock();
1404
1405         return NULL;
1406 }
1407
1408 typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
1409 typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
1410
1411 struct _tbm_surface_dump_buf_info {
1412         int index;
1413         tbm_bo bo;
1414         int size;
1415         int dirty;
1416         int dirty_shm;
1417         int shm_stride;
1418         int shm_h;
1419         char name[1024];
1420
1421         tbm_surface_info_s info;
1422
1423         struct list_head link;
1424 };
1425
1426 struct _tbm_surface_dump_info {
1427         char *path;  // copy???
1428         int dump_max;
1429         int count;
1430         struct list_head *link;
1431         struct list_head surface_list; /* link of surface */
1432 };
1433
1434 static tbm_surface_dump_info *g_dump_info = NULL;
1435 static const char *dump_postfix[2] = {"png", "yuv"};
1436
1437 static void
1438 _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
1439                 int size2, void *data3, int size3)
1440 {
1441         unsigned int *blocks;
1442         FILE *fp = fopen(file, "w+");
1443         TBM_RETURN_IF_FAIL(fp != NULL);
1444
1445         blocks = (unsigned int *)data1;
1446         fwrite(blocks, 1, size1, fp);
1447
1448         if (size2 > 0) {
1449                 blocks = (unsigned int *)data2;
1450                 fwrite(blocks, 1, size2, fp);
1451         }
1452
1453         if (size3 > 0) {
1454                 blocks = (unsigned int *)data3;
1455                 fwrite(blocks, 1, size3, fp);
1456         }
1457
1458         fclose(fp);
1459 }
1460
1461 static void
1462 _tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
1463                 int height)
1464 {
1465         FILE *fp = fopen(file, "wb");
1466         TBM_RETURN_IF_FAIL(fp != NULL);
1467         int depth = 8;
1468
1469         png_structp pPngStruct =
1470                 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1471         if (!pPngStruct) {
1472                 fclose(fp);
1473                 return;
1474         }
1475
1476         png_infop pPngInfo = png_create_info_struct(pPngStruct);
1477         if (!pPngInfo) {
1478                 png_destroy_write_struct(&pPngStruct, NULL);
1479                 fclose(fp);
1480                 return;
1481         }
1482
1483         png_init_io(pPngStruct, fp);
1484         png_set_IHDR(pPngStruct,
1485                         pPngInfo,
1486                         width,
1487                         height,
1488                         depth,
1489                         PNG_COLOR_TYPE_RGBA,
1490                         PNG_INTERLACE_NONE,
1491                         PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1492
1493         png_set_bgr(pPngStruct);
1494         png_write_info(pPngStruct, pPngInfo);
1495
1496         const int pixel_size = 4;       // RGBA
1497         png_bytep *row_pointers =
1498                         png_malloc(pPngStruct, height * sizeof(png_byte *));
1499
1500         unsigned int *blocks = (unsigned int *)data;
1501         int y = 0;
1502         int x = 0;
1503
1504         for (; y < height; ++y) {
1505                 png_bytep row =
1506                         png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
1507                 row_pointers[y] = (png_bytep)row;
1508                 for (x = 0; x < width; ++x) {
1509                         unsigned int curBlock = blocks[y * width + x];
1510                         row[x * pixel_size] = (curBlock & 0xFF);
1511                         row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
1512                         row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
1513                         row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
1514                 }
1515         }
1516
1517         png_write_image(pPngStruct, row_pointers);
1518         png_write_end(pPngStruct, pPngInfo);
1519
1520         for (y = 0; y < height; y++)
1521                 png_free(pPngStruct, row_pointers[y]);
1522         png_free(pPngStruct, row_pointers);
1523
1524         png_destroy_write_struct(&pPngStruct, &pPngInfo);
1525
1526         fclose(fp);
1527 }
1528
1529 void
1530 tbm_surface_internal_dump_start(char *path, int w, int h, int count)
1531 {
1532         TBM_RETURN_IF_FAIL(path != NULL);
1533         TBM_RETURN_IF_FAIL(w > 0);
1534         TBM_RETURN_IF_FAIL(h > 0);
1535         TBM_RETURN_IF_FAIL(count > 0);
1536
1537         tbm_surface_dump_buf_info *buf_info = NULL;
1538         tbm_surface_dump_buf_info *tmp;
1539         tbm_bo bo = NULL;
1540         int i;
1541         int buffer_size;
1542         tbm_surface_h tbm_surface;
1543         tbm_surface_info_s info;
1544         tbm_surface_error_e err;
1545
1546         /* check running */
1547         if (g_dump_info) {
1548                 TBM_LOG_W("waring already running the tbm_surface_internal_dump.\n");
1549                 return;
1550         }
1551
1552         g_dump_info = calloc(1, sizeof(struct _tbm_surface_dump_info));
1553         TBM_RETURN_IF_FAIL(g_dump_info);
1554
1555         LIST_INITHEAD(&g_dump_info->surface_list);
1556         g_dump_info->count = 0;
1557         g_dump_info->dump_max = count;
1558
1559         /* get buffer size */
1560         tbm_surface = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
1561         if (tbm_surface == NULL) {
1562                 TBM_LOG_E("tbm_surface_create fail\n");
1563                 free(g_dump_info);
1564                 g_dump_info = NULL;
1565                 return;
1566         }
1567         err = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
1568         if (err != TBM_SURFACE_ERROR_NONE) {
1569                 TBM_LOG_E("tbm_surface_map fail\n");
1570                 tbm_surface_destroy(tbm_surface);
1571                 free(g_dump_info);
1572                 g_dump_info = NULL;
1573                 return;
1574         }
1575         buffer_size = info.planes[0].stride * h;
1576         tbm_surface_unmap(tbm_surface);
1577         tbm_surface_destroy(tbm_surface);
1578
1579         /* create dump lists */
1580         for (i = 0; i < count; i++)     {
1581                 buf_info = calloc(1, sizeof(tbm_surface_dump_buf_info));
1582                 TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
1583                 bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
1584                 if (bo == NULL) {
1585                         free(buf_info);
1586                         goto fail;
1587                 }
1588
1589                 buf_info->index = i;
1590                 buf_info->bo = bo;
1591                 buf_info->size = buffer_size;
1592
1593                 LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
1594         }
1595
1596         g_dump_info->path = path;
1597         g_dump_info->link = &g_dump_info->surface_list;
1598
1599         TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count);
1600
1601         return;
1602 fail:
1603         /* free resources */
1604         if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1605                 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1606                         tbm_bo_unref(buf_info->bo);
1607                         free(buf_info);
1608                 }
1609         }
1610
1611         TBM_LOG_E("Dump Start fail.. path:%s\n", g_dump_info->path);
1612
1613         free(g_dump_info);
1614         g_dump_info = NULL;
1615
1616         return;
1617 }
1618
1619 void
1620 tbm_surface_internal_dump_end(void)
1621 {
1622         tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL;
1623         tbm_bo_handle bo_handle;
1624
1625         if (!g_dump_info)
1626                 return;
1627
1628         /* make files */
1629         if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1630                 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1631                         char file[2048];
1632
1633                         if (buf_info->dirty) {
1634                                 void *ptr1 = NULL;
1635                                 void *ptr2 = NULL;
1636
1637                                 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1638                                 if (bo_handle.ptr == NULL)
1639                                         continue;
1640
1641                                 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1642                                 TBM_LOG_I("Dump File.. %s generated.\n", file);
1643
1644                                 switch (buf_info->info.format) {
1645                                 case TBM_FORMAT_ARGB8888:
1646                                 case TBM_FORMAT_XRGB8888:
1647                                         _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1648                                                                         buf_info->info.planes[0].stride >> 2, buf_info->info.height);
1649                                         break;
1650                                 case TBM_FORMAT_YVU420:
1651                                 case TBM_FORMAT_YUV420:
1652                                         ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1653                                         ptr2 = ptr1 + buf_info->info.planes[1].stride * (buf_info->info.height >> 1);
1654                                         _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1655                                                                         buf_info->info.planes[0].stride * buf_info->info.height,
1656                                                                         ptr1,
1657                                                                         buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1658                                                                         ptr2,
1659                                                                         buf_info->info.planes[2].stride * (buf_info->info.height >> 1));
1660                                         break;
1661                                 case TBM_FORMAT_NV12:
1662                                 case TBM_FORMAT_NV21:
1663                                         ptr1 = bo_handle.ptr + buf_info->info.planes[0].stride * buf_info->info.height;
1664                                         _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1665                                                                         buf_info->info.planes[0].stride * buf_info->info.height,
1666                                                                         ptr1,
1667                                                                         buf_info->info.planes[1].stride * (buf_info->info.height >> 1),
1668                                                                         NULL, 0);
1669                                         break;
1670                                 case TBM_FORMAT_YUYV:
1671                                 case TBM_FORMAT_UYVY:
1672                                         _tbm_surface_internal_dump_file_raw(file, bo_handle.ptr,
1673                                                                         buf_info->info.planes[0].stride * buf_info->info.height,
1674                                                                         NULL, 0, NULL, 0);
1675                                         break;
1676                                 default:
1677                                         TBM_LOG_E("can't dump %c%c%c%c buffer", FOURCC_STR(buf_info->info.format));
1678                                         tbm_bo_unmap(buf_info->bo);
1679                                         return;
1680                                 }
1681
1682                                 tbm_bo_unmap(buf_info->bo);
1683                         } else if (buf_info->dirty_shm) {
1684                                 bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
1685                                 if (bo_handle.ptr == NULL)
1686                                         continue;
1687
1688                                 snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
1689                                 TBM_LOG_I("Dump File.. %s generated.\n", file);
1690
1691                                 _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
1692                                                                 buf_info->shm_stride >> 2, buf_info->shm_h);
1693
1694                                 tbm_bo_unmap(buf_info->bo);
1695                         }
1696                 }
1697         }
1698
1699         /* free resources */
1700         if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
1701                 LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
1702                         tbm_bo_unref(buf_info->bo);
1703                         free(buf_info);
1704                 }
1705         }
1706
1707         free(g_dump_info);
1708         g_dump_info = NULL;
1709
1710         TBM_LOG_I("Dump End..\n");
1711 }
1712
1713 void
1714 tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
1715 {
1716         TBM_RETURN_IF_FAIL(surface != NULL);
1717         TBM_RETURN_IF_FAIL(type != NULL);
1718
1719         tbm_surface_dump_buf_info *buf_info;
1720         tbm_surface_info_s info;
1721         struct list_head *next_link;
1722         tbm_bo_handle bo_handle;
1723         int ret;
1724         const char *postfix;
1725
1726         if (!g_dump_info)
1727                 return;
1728
1729         next_link = g_dump_info->link->next;
1730         TBM_RETURN_IF_FAIL(next_link != NULL);
1731
1732         if (next_link == &g_dump_info->surface_list) {
1733                 next_link = next_link->next;
1734                 TBM_RETURN_IF_FAIL(next_link != NULL);
1735         }
1736
1737         buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1738         TBM_RETURN_IF_FAIL(buf_info != NULL);
1739
1740         ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1741         TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE);
1742
1743         if (info.size > buf_info->size) {
1744                 TBM_LOG_W("Dump skip. surface over created buffer size(%d, %d)\n", info.size, buf_info->size);
1745                 tbm_surface_unmap(surface);
1746                 return;
1747         }
1748
1749         if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1750                 postfix = dump_postfix[0];
1751         else
1752                 postfix = dump_postfix[1];
1753
1754         /* make the file information */
1755         memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s));
1756
1757         /* dump */
1758         bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1759         TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1760         memset(bo_handle.ptr, 0x00, buf_info->size);
1761
1762         switch (info.format) {
1763         case TBM_FORMAT_ARGB8888:
1764         case TBM_FORMAT_XRGB8888:
1765                 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d_%p-%s.%s",
1766                                  _tbm_surface_internal_get_time(),
1767                                  g_dump_info->count++, surface, type, postfix);
1768                 memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
1769                 break;
1770         case TBM_FORMAT_YVU420:
1771         case TBM_FORMAT_YUV420:
1772                 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1773                                  _tbm_surface_internal_get_time(),
1774                                  g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1775                 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1776                 bo_handle.ptr += info.planes[0].stride * info.height;
1777                 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1778                 bo_handle.ptr += info.planes[1].stride * (info.height >> 1);
1779                 memcpy(bo_handle.ptr, info.planes[2].ptr, info.planes[2].stride * (info.height >> 1));
1780                 break;
1781         case TBM_FORMAT_NV12:
1782         case TBM_FORMAT_NV21:
1783                 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1784                                  _tbm_surface_internal_get_time(),
1785                                  g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1786                 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1787                 bo_handle.ptr += info.planes[0].stride * info.height;
1788                 memcpy(bo_handle.ptr, info.planes[1].ptr, info.planes[1].stride * (info.height >> 1));
1789                 break;
1790         case TBM_FORMAT_YUYV:
1791         case TBM_FORMAT_UYVY:
1792                 snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s_%dx%d_%c%c%c%c.%s",
1793                                  _tbm_surface_internal_get_time(),
1794                                  g_dump_info->count++, type, info.planes[0].stride, info.height, FOURCC_STR(info.format), postfix);
1795                 memcpy(bo_handle.ptr, info.planes[0].ptr, info.planes[0].stride * info.height);
1796                 break;
1797         default:
1798                 TBM_LOG_E("can't copy %c%c%c%c buffer", FOURCC_STR(info.format));
1799                 tbm_bo_unmap(buf_info->bo);
1800                 return;
1801         }
1802
1803         tbm_bo_unmap(buf_info->bo);
1804
1805         tbm_surface_unmap(surface);
1806
1807         buf_info->dirty = 1;
1808         buf_info->dirty_shm = 0;
1809
1810         if (g_dump_info->count == 1000)
1811                 g_dump_info->count = 0;
1812
1813         g_dump_info->link = next_link;
1814
1815         TBM_LOG_I("Dump %s \n", buf_info->name);
1816 }
1817
1818 void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int  stride, const char *type)
1819 {
1820         TBM_RETURN_IF_FAIL(ptr != NULL);
1821         TBM_RETURN_IF_FAIL(w > 0);
1822         TBM_RETURN_IF_FAIL(h > 0);
1823         TBM_RETURN_IF_FAIL(stride > 0);
1824         TBM_RETURN_IF_FAIL(type != NULL);
1825
1826         tbm_surface_dump_buf_info *buf_info;
1827         struct list_head *next_link;
1828         tbm_bo_handle bo_handle;
1829
1830         if (!g_dump_info)
1831                 return;
1832
1833         next_link = g_dump_info->link->next;
1834         TBM_RETURN_IF_FAIL(next_link != NULL);
1835
1836         if (next_link == &g_dump_info->surface_list) {
1837                 next_link = next_link->next;
1838                 TBM_RETURN_IF_FAIL(next_link != NULL);
1839         }
1840
1841         buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
1842         TBM_RETURN_IF_FAIL(buf_info != NULL);
1843
1844         if (stride * h > buf_info->size) {
1845                 TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", stride * h, buf_info->size);
1846                 return;
1847         }
1848
1849         /* dump */
1850         bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1851         TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
1852         memset(bo_handle.ptr, 0x00, buf_info->size);
1853         memset(&buf_info->info, 0x00, sizeof(tbm_surface_info_s));
1854
1855         snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s",
1856                          _tbm_surface_internal_get_time(),
1857                          g_dump_info->count++, type, dump_postfix[0]);
1858         memcpy(bo_handle.ptr, ptr, stride * h);
1859
1860         tbm_bo_unmap(buf_info->bo);
1861
1862         buf_info->dirty = 0;
1863         buf_info->dirty_shm = 1;
1864         buf_info->shm_stride = stride;
1865         buf_info->shm_h = h;
1866
1867         if (g_dump_info->count == 1000)
1868                 g_dump_info->count = 0;
1869
1870         g_dump_info->link = next_link;
1871
1872         TBM_LOG_I("Dump %s \n", buf_info->name);
1873 }
1874 /*LCOV_EXCL_STOP*/