tbm_bo: remove tbm_bo_alloc_with_tiled_format
[platform/core/uifw/libtbm.git] / src / tbm_bo.c
1 /**************************************************************************
2
3 libtbm
4
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #include "config.h"
33 #include "tbm_bufmgr.h"
34 #include "tbm_bufmgr_int.h"
35 #include "list.h"
36
37 #define TBM_BO_MAGIC 0xBF011234
38
39 /* check condition */
40 #define TBM_BO_RETURN_IF_FAIL(cond) {\
41         if (!(cond)) {\
42                 TBM_ERR("'%s' failed.\n", #cond);\
43                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
44                 _tbm_bufmgr_mutex_unlock();\
45                 return;\
46         } \
47 }
48
49 #define TBM_BO_RETURN_VAL_IF_FAIL(cond, val) {\
50         if (!(cond)) {\
51                 TBM_ERR("'%s' failed.\n", #cond);\
52                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
53                 _tbm_bufmgr_mutex_unlock();\
54                 return val;\
55         } \
56 }
57
58 static char *
59 _tbm_flag_to_str(int f)
60 {
61         static char str[255];
62
63         if (f == TBM_BO_DEFAULT)
64                  snprintf(str, 255, "DEFAULT");
65         else {
66                 int c = 0;
67
68                 if (f & TBM_BO_SCANOUT)
69                         c += snprintf(&str[c], 255-c, "SCANOUT");
70
71                 if (f & TBM_BO_NONCACHABLE) {
72                         if (c >= 0 && c < 255)
73                                 c += snprintf(&str[c], 255-c, ", ");
74
75                         if (c >= 0 && c < 255)
76                                 c += snprintf(&str[c], 255-c, "NONCACHABLE,");
77                 }
78
79                 if (f & TBM_BO_WC) {
80                         if (c >= 0 && c < 255)
81                                 c += snprintf(&str[c], 255-c, ", ");
82
83                         if (c >= 0 && c < 255)
84                                 c += snprintf(&str[c], 255-c, "WC");
85                 }
86         }
87
88         return str;
89 }
90
91 static void
92 _tbm_util_check_bo_cnt(tbm_bufmgr bufmgr)
93 {
94         static int last_chk_bo_cnt = 0;
95
96         if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
97                 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
98                 TBM_DBG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
99                 tbm_bufmgr_debug_show(bufmgr);
100                 last_chk_bo_cnt = bufmgr->bo_cnt;
101         }
102 }
103 /* LCOV_EXCL_STOP */
104
105 tbm_user_data *
106 user_data_lookup(struct list_head *user_data_list, unsigned long key)
107 {
108         tbm_user_data *old_data = NULL;
109
110         if (LIST_IS_EMPTY(user_data_list))
111                 return NULL;
112
113         LIST_FOR_EACH_ENTRY(old_data, user_data_list, item_link) {
114                 if (old_data->key == key)
115                         return old_data;
116         }
117
118         return NULL;
119 }
120
121 tbm_user_data *
122 user_data_create(unsigned long key, tbm_data_free data_free_func)
123 {
124         tbm_user_data *user_data;
125
126         user_data = calloc(1, sizeof(tbm_user_data));
127         if (!user_data) {
128                 /* LCOV_EXCL_START */
129                 TBM_ERR("fail to allocate an user_date\n");
130                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
131                 return NULL;
132                 /* LCOV_EXCL_STOP */
133         }
134
135         user_data->key = key;
136         user_data->free_func = data_free_func;
137
138         return user_data;
139 }
140
141 void
142 user_data_delete(tbm_user_data *user_data)
143 {
144         if (user_data->data && user_data->free_func)
145                 user_data->free_func(user_data->data);
146
147         LIST_DEL(&user_data->item_link);
148
149         free(user_data);
150 }
151
152 static int
153 _bo_lock(tbm_bo bo, int device, int opt)
154 {
155         int ret = 1;
156         tbm_error_e error;
157
158         if (bo->bufmgr->use_hal_tbm) {
159                 error = (tbm_error_e)hal_tbm_bo_lock((hal_tbm_bo *)bo->bo_data, device, opt);
160                 if (error == TBM_ERROR_NOT_SUPPORTED) {
161                         _tbm_set_last_result(TBM_ERROR_NONE);
162                 } else {
163                         if (error != TBM_ERROR_NONE) {
164                                 TBM_WRN("fail to lock");
165                                 _tbm_set_last_result(error);
166                                 ret = 0;
167                         }
168                 }
169         } else if (bo->bufmgr->backend_module_data) {
170                 if (bo->bufmgr->bo_func->bo_lock) {
171                         error = bo->bufmgr->bo_func->bo_lock(bo->bo_data, device, opt);
172                         if (error != TBM_ERROR_NONE) {
173                                 TBM_WRN("fail to lock");
174                                 _tbm_set_last_result(error);
175                                 ret = 0;
176                         }
177                 }
178         } else {
179                 if (bo->bufmgr->backend->bo_lock) {
180                         ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
181                         if (!ret)
182                                 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
183                 }
184         }
185
186         return ret;
187 }
188
189 static void
190 _bo_unlock(tbm_bo bo)
191 {
192         tbm_error_e error;
193
194         if (bo->bufmgr->use_hal_tbm) {
195                 error = (tbm_error_e)hal_tbm_bo_unlock((hal_tbm_bo *)bo->bo_data);
196                 if (error == TBM_ERROR_NOT_SUPPORTED) {
197                         _tbm_set_last_result(TBM_ERROR_NONE);
198                 } else {
199                         if (error != TBM_ERROR_NONE) {
200                                 TBM_WRN("fail to lock");
201                                 _tbm_set_last_result(error);
202                         }
203                 }
204         } else if (bo->bufmgr->backend_module_data) {
205                 if (bo->bufmgr->bo_func->bo_unlock) {
206                         error = bo->bufmgr->bo_func->bo_unlock(bo->bo_data);
207                         if (error != TBM_ERROR_NONE) {
208                                 TBM_WRN("fail to unlock");
209                                 _tbm_set_last_result(error);
210                         }
211                 }
212         } else {
213                 if (bo->bufmgr->backend->bo_unlock)
214                         bo->bufmgr->backend->bo_unlock(bo);
215         }
216 }
217
218 static int
219 _tbm_bo_lock(tbm_bo bo, int device, int opt)
220 {
221         int old, ret;
222
223         if (!bo)
224                 return 0;
225
226         /* do not try to lock the bo */
227         if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
228                 return 1;
229
230         if (bo->lock_cnt < 0) {
231                 TBM_ERR("error bo:%p LOCK_CNT=%d\n",
232                         bo, bo->lock_cnt);
233                 return 0;
234         }
235
236         old = bo->lock_cnt;
237
238         switch (bo->bufmgr->bo_lock_type) {
239         case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
240                 if (bo->lock_cnt == 0) {
241                         _tbm_bufmgr_mutex_unlock();
242                         ret = _bo_lock(bo, device, opt);
243                         _tbm_bufmgr_mutex_lock();
244                         if (ret)
245                                 bo->lock_cnt++;
246                 } else
247                         ret = 1;
248                 break;
249         case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
250                 _tbm_bufmgr_mutex_unlock();
251                 ret = _bo_lock(bo, device, opt);
252                 _tbm_bufmgr_mutex_lock();
253                 if (ret)
254                         bo->lock_cnt++;
255                 break;
256         default:
257                 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
258                                 bo, bo->bufmgr->bo_lock_type);
259                 ret = 0;
260                 break;
261         }
262
263         TBM_DBG(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
264
265         return ret;
266 }
267
268 static void
269 _tbm_bo_unlock(tbm_bo bo)
270 {
271         int old;
272
273         /* do not try to unlock the bo */
274         if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
275                 return;
276
277         old = bo->lock_cnt;
278
279         switch (bo->bufmgr->bo_lock_type) {
280         case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
281                 if (bo->lock_cnt > 0) {
282                         bo->lock_cnt--;
283                         if (bo->lock_cnt == 0)
284                                 _bo_unlock(bo);
285                 }
286                 break;
287         case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
288                 if (bo->lock_cnt > 0) {
289                         bo->lock_cnt--;
290                         _bo_unlock(bo);
291                 }
292                 break;
293         default:
294                 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
295                                 bo, bo->bufmgr->bo_lock_type);
296                 break;
297         }
298
299         if (bo->lock_cnt < 0)
300                 bo->lock_cnt = 0;
301
302         TBM_DBG(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
303 }
304
305 static int
306 _tbm_bo_magic_check(tbm_bo bo)
307 {
308         if (bo->magic != TBM_BO_MAGIC)
309                 return 0;
310
311         return 1;
312 }
313
314 static int
315 _tbm_bo_is_valid(tbm_bo bo)
316 {
317         if (!bo) {
318                 TBM_ERR("error: bo is NULL.\n");
319                 return 0;
320         }
321
322         if (!_tbm_bo_magic_check(bo)) {
323                 TBM_ERR("error: No valid bo(%p).\n", bo);
324                 return 0;
325         }
326
327         return 1;
328 }
329
330 static void
331 _tbm_bo_init(tbm_bufmgr bufmgr, tbm_bo bo, int flags)
332 {
333         bo->bufmgr = bufmgr;
334         bo->flags = flags;
335         bo->magic = TBM_BO_MAGIC;
336         bo->ref_cnt = 1;
337
338         LIST_INITHEAD(&bo->user_data_list);
339
340         bufmgr->bo_cnt++;
341         LIST_ADD(&bo->item_link, &bufmgr->bo_list);
342 }
343
344 static void
345 _tbm_bo_deinit(tbm_bo bo)
346 {
347         bo->magic = 0;
348
349         bo->bufmgr->bo_cnt--;
350         LIST_DEL(&bo->item_link);
351 }
352
353 tbm_bo
354 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
355 {
356         tbm_bo bo;
357         tbm_backend_bo_data *bo_data;
358         tbm_error_e error;
359
360         _tbm_bufmgr_mutex_lock();
361         _tbm_set_last_result(TBM_ERROR_NONE);
362
363         TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
364         TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
365
366         bo = calloc(1, sizeof(struct _tbm_bo));
367         if (!bo) {
368                 /* LCOV_EXCL_START */
369                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
370                 _tbm_bufmgr_mutex_unlock();
371                 return NULL;
372                 /* LCOV_EXCL_STOP */
373         }
374
375         _tbm_util_check_bo_cnt(bufmgr);
376
377         bo_data = tbm_module_bufmgr_bo_alloc(bufmgr->module, bo, size, flags, &error);
378         if (!bo_data || error != TBM_ERROR_NONE) {
379                 /* LCOV_EXCL_START */
380                 TBM_ERR("tbm_module_bufmgr_bo_alloc failed. error:%d", error);
381                 _tbm_set_last_result(error);
382                 goto alloc_fail;
383                 /* LCOV_EXCL_STOP */
384         }
385         bo->bo_data = bo_data;
386         bo->priv = (void *)bo_data; // TODO: this will be DEPRECATED.
387
388         _tbm_bo_init(bufmgr, bo, flags);
389
390         TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
391                         _tbm_flag_to_str(bo->flags));
392
393         _tbm_bufmgr_mutex_unlock();
394
395         return bo;
396
397 alloc_fail:
398         TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n", size, _tbm_flag_to_str(flags));
399         free(bo);
400         _tbm_bufmgr_mutex_unlock();
401         return NULL;
402 }
403
404 /* LCOV_EXCL_START */
405 tbm_bo
406 tbm_bo_alloc_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
407                                                 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
408 {
409         tbm_bo bo = NULL;
410
411         _tbm_bufmgr_mutex_lock();
412         _tbm_set_last_result(TBM_ERROR_NONE);
413
414         TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
415
416         bo = calloc(1, sizeof(struct _tbm_bo));
417         if (!bo) {
418                 /* LCOV_EXCL_START */
419                 TBM_ERR("error: fail to tbm_bo_alloc_with_format fmt(%s) idx(%d) w(%d) h(%d) mem_types(%s)\n",
420                                 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
421                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
422                 /* LCOV_EXCL_STOP */
423                 goto fail;
424         }
425
426         _tbm_util_check_bo_cnt(bufmgr);
427
428         bo->bo_data = tbm_module_bufmgr_bo_alloc_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
429         if (!bo->bo_data) {
430                 /* LCOV_EXCL_START */
431                 TBM_ERR("tbm_module_bufmgr_bo_alloc_with_format failed. fmt:%d idx:%d wxh:%dx%d mem_types:%s\n",
432                                 format, bo_idx, width, height, _tbm_flag_to_str(flags));
433                 _tbm_set_last_result(*error);
434                 /* LCOV_EXCL_STOP */
435                 goto fail;
436         }
437
438         _tbm_bo_init(bufmgr, bo, flags);
439
440         _tbm_bufmgr_mutex_unlock();
441
442         return bo;
443
444 fail:
445         if (bo)
446                 free(bo);
447         _tbm_bufmgr_mutex_unlock();
448
449         return NULL;
450 }
451
452 tbm_bo
453 tbm_bo_alloc_with_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, int bo_idx)
454 {
455         tbm_bo bo;
456         void *bo_priv;
457
458         _tbm_bufmgr_mutex_lock();
459         _tbm_set_last_result(TBM_ERROR_NONE);
460
461         TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
462
463         bo = calloc(1, sizeof(struct _tbm_bo));
464         if (!bo) {
465                 TBM_ERR("error: fail to tbm_bo_alloc_with_surface fmt(%s) idx(%d) w(%d) h(%d) flags(%s)\n",
466                                 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
467                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
468                 _tbm_bufmgr_mutex_unlock();
469                 return NULL;
470         }
471
472         _tbm_util_check_bo_cnt(bufmgr);
473
474         if (!bufmgr->backend->surface_bo_alloc) {
475                 TBM_ERR("error: not supported tbm_bo_alloc_with_surface\n");
476                 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
477                 free(bo);
478                 _tbm_bufmgr_mutex_unlock();
479                 return NULL;
480         }
481
482         bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, bo_idx);
483         if (!bo_priv) {
484                 TBM_ERR("error: fail to tbm_bo_alloc_with_surface fmt(%s) idx(%d) w(%d) h(%d) flags(%s)\n",
485                                 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
486                 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
487                 free(bo);
488                 _tbm_bufmgr_mutex_unlock();
489                 return NULL;
490         }
491
492         bo->priv = bo_priv;
493         _tbm_bo_init(bufmgr, bo, flags);
494
495         _tbm_bufmgr_mutex_unlock();
496
497         return bo;
498 }
499
500 tbm_bo
501 tbm_bo_alloc_with_bo_data(tbm_bufmgr bufmgr, tbm_backend_bo_data *bo_data, int flags)
502 {
503         tbm_bo bo, bo2 = NULL;
504
505         _tbm_bufmgr_mutex_lock();
506         _tbm_set_last_result(TBM_ERROR_NONE);
507
508         TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
509         TBM_BO_RETURN_VAL_IF_FAIL(bo_data, NULL);
510
511         // return an existed bo if the bo is already created with the same bo_data.
512         if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
513                 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
514                         if (bo2->bo_data == bo_data) {
515                                 TBM_ERR("find bo(%p) ref(%d) flag(%s) in list\n",
516                                                 bo2, bo2->ref_cnt, _tbm_flag_to_str(bo2->flags));
517                                 bo2->ref_cnt++;
518                                 _tbm_bufmgr_mutex_unlock();
519                                 return bo2;
520                         }
521                 }
522         }
523
524         bo = calloc(1, sizeof(struct _tbm_bo));
525         if (!bo) {
526                 /* LCOV_EXCL_START */
527                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
528                 _tbm_bufmgr_mutex_unlock();
529                 return NULL;
530                 /* LCOV_EXCL_STOP */
531         }
532
533         _tbm_util_check_bo_cnt(bufmgr);
534
535         bo->get_from_hal_surface = 1;
536         bo->bo_data = bo_data;
537
538         _tbm_bo_init(bufmgr, bo, flags);
539
540         TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)\n", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
541
542         _tbm_bufmgr_mutex_unlock();
543
544         return bo;
545 }
546
547 /* LCOV_EXCL_STOP */
548
549 tbm_bo
550 tbm_bo_ref(tbm_bo bo)
551 {
552         _tbm_bufmgr_mutex_lock();
553         _tbm_set_last_result(TBM_ERROR_NONE);
554
555         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
556
557         bo->ref_cnt++;
558
559         TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
560
561         _tbm_bufmgr_mutex_unlock();
562
563         return bo;
564 }
565
566 void
567 tbm_bo_unref(tbm_bo bo)
568 {
569         _tbm_bufmgr_mutex_lock();
570         _tbm_set_last_result(TBM_ERROR_NONE);
571
572         TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
573
574         TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
575
576         if (bo->ref_cnt <= 0) {
577                 _tbm_bufmgr_mutex_unlock();
578                 return;
579         }
580
581         bo->ref_cnt--;
582         if (bo->ref_cnt == 0)
583                 _tbm_bo_free(bo);
584
585         _tbm_bufmgr_mutex_unlock();
586 }
587
588 tbm_bo_handle
589 tbm_bo_map(tbm_bo bo, int device, int opt)
590 {
591         tbm_bo_handle bo_handle;
592         tbm_error_e error;
593
594         _tbm_bufmgr_mutex_lock();
595         _tbm_set_last_result(TBM_ERROR_NONE);
596
597         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
598
599         if (!_tbm_bo_lock(bo, device, opt)) {
600                 TBM_ERR("error: fail to lock bo:%p)\n", bo);
601                 _tbm_bufmgr_mutex_unlock();
602                 return (tbm_bo_handle) NULL;
603         }
604
605         if (bo->bufmgr->use_hal_tbm) {
606                 hal_tbm_bo_handle hbo_handle;
607                 hbo_handle = hal_tbm_bo_map((hal_tbm_bo *)bo->bo_data, device, opt, (hal_tbm_error *)&error);
608                 if (hbo_handle.ptr == NULL) {
609                         /* LCOV_EXCL_START */
610                         _tbm_set_last_result(error);
611                         TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
612                         goto bo_map_fail;
613                         /* LCOV_EXCL_STOP */
614                 }
615                 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
616         } else if (bo->bufmgr->backend_module_data) {
617                 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
618                 if (bo_handle.ptr == NULL) {
619                         /* LCOV_EXCL_START */
620                         _tbm_set_last_result(error);
621                         TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
622                         goto bo_map_fail;
623                         /* LCOV_EXCL_STOP */
624                 }
625         } else {
626                 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
627                 if (bo_handle.ptr == NULL) {
628                         /* LCOV_EXCL_START */
629                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
630                         TBM_ERR("error: fail to map bo:%p\n", bo);
631                         goto bo_map_fail;
632                         /* LCOV_EXCL_STOP */
633                 }
634         }
635
636         /* increase the map_count */
637         bo->map_cnt++;
638
639         TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
640
641         _tbm_bufmgr_mutex_unlock();
642
643         return bo_handle;
644
645 bo_map_fail:
646         _tbm_bo_unlock(bo);
647         _tbm_bufmgr_mutex_unlock();
648         return (tbm_bo_handle) NULL;
649 }
650
651 int
652 tbm_bo_unmap(tbm_bo bo)
653 {
654         int ret = 1;
655         tbm_error_e error;
656
657         _tbm_bufmgr_mutex_lock();
658         _tbm_set_last_result(TBM_ERROR_NONE);
659
660         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
661         TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
662
663         if (bo->bufmgr->use_hal_tbm) {
664                 error = (hal_tbm_error)hal_tbm_bo_unmap((hal_tbm_bo *)bo->bo_data);
665                 if (error != TBM_ERROR_NONE) {
666                         /* LCOV_EXCL_START */
667                         TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
668                         _tbm_set_last_result(error);
669                         ret = 0;
670                         goto done;
671                         /* LCOV_EXCL_STOP */
672                 }
673         } else if (bo->bufmgr->backend_module_data) {
674                 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
675                 if (error != TBM_ERROR_NONE) {
676                         /* LCOV_EXCL_START */
677                         TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
678                         _tbm_set_last_result(error);
679                         ret = 0;
680                         goto done;
681                         /* LCOV_EXCL_STOP */
682                 }
683         } else {
684                 ret = bo->bufmgr->backend->bo_unmap(bo);
685                 if (!ret) {
686                         /* LCOV_EXCL_START */
687                         TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
688                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
689                         goto done;
690                         /* LCOV_EXCL_STOP */
691                 }
692         }
693
694         /* decrease the map_count */
695         bo->map_cnt--;
696
697         TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
698
699         _tbm_bo_unlock(bo);
700
701 done:
702         _tbm_bufmgr_mutex_unlock();
703
704         return ret;
705 }
706
707 tbm_bo_handle
708 tbm_bo_get_handle(tbm_bo bo, int device)
709 {
710         tbm_bo_handle bo_handle;
711         tbm_error_e error;
712
713         _tbm_bufmgr_mutex_lock();
714         _tbm_set_last_result(TBM_ERROR_NONE);
715
716         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
717
718         if (bo->bufmgr->use_hal_tbm) {
719                 hal_tbm_bo_handle hbo_handle;
720                 hbo_handle = hal_tbm_bo_get_handle((hal_tbm_bo *)bo->bo_data, device, (hal_tbm_error *)&error);
721                 if (hbo_handle.ptr == NULL) {
722                         /* LCOV_EXCL_START */
723                         TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
724                         _tbm_set_last_result(error);
725                         goto bo_handle_fail;
726                         /* LCOV_EXCL_STOP */
727                 }
728                 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
729         } else if (bo->bufmgr->backend_module_data) {
730                 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
731                 if (bo_handle.ptr == NULL) {
732                         /* LCOV_EXCL_START */
733                         TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
734                         _tbm_set_last_result(error);
735                         goto bo_handle_fail;
736                         /* LCOV_EXCL_STOP */
737                 }
738         } else {
739                 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
740                 if (bo_handle.ptr == NULL) {
741                         /* LCOV_EXCL_START */
742                         TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
743                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
744                         goto bo_handle_fail;
745                         /* LCOV_EXCL_STOP */
746                 }
747         }
748
749         TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
750
751         _tbm_bufmgr_mutex_unlock();
752
753         return bo_handle;
754
755 bo_handle_fail:
756         _tbm_bufmgr_mutex_unlock();
757         return (tbm_bo_handle) NULL;
758 }
759
760 tbm_key
761 tbm_bo_export(tbm_bo bo)
762 {
763         tbm_key ret;
764         tbm_error_e error;
765
766         _tbm_bufmgr_mutex_lock();
767         _tbm_set_last_result(TBM_ERROR_NONE);
768
769         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
770
771         if (bo->bufmgr->use_hal_tbm) {
772                 ret = (hal_tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
773                 if (!ret) {
774                         /* LCOV_EXCL_START */
775                         TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
776                         _tbm_set_last_result(error);
777                         goto done;
778                         /* LCOV_EXCL_STOP */
779                 }
780         } else if (bo->bufmgr->backend_module_data) {
781                 if (!bo->bufmgr->bo_func->bo_export_key) {
782                         /* LCOV_EXCL_START */
783                         _tbm_bufmgr_mutex_unlock();
784                         _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
785                         return 0;
786                         /* LCOV_EXCL_STOP */
787                 }
788
789                 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
790                 if (!ret) {
791                         /* LCOV_EXCL_START */
792                         TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
793                         _tbm_set_last_result(error);
794                         goto done;
795                         /* LCOV_EXCL_STOP */
796                 }
797         } else {
798                 if (!bo->bufmgr->backend->bo_export) {
799                         /* LCOV_EXCL_START */
800                         _tbm_bufmgr_mutex_unlock();
801                         _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
802                         return 0;
803                         /* LCOV_EXCL_STOP */
804                 }
805
806                 ret = bo->bufmgr->backend->bo_export(bo);
807                 if (!ret) {
808                         /* LCOV_EXCL_START */
809                         TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
810                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
811                         goto done;
812                         /* LCOV_EXCL_STOP */
813                 }
814         }
815
816         TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
817
818 done:
819         _tbm_bufmgr_mutex_unlock();
820
821         return ret;
822 }
823
824 tbm_fd
825 tbm_bo_export_fd(tbm_bo bo)
826 {
827         tbm_fd ret;
828         tbm_error_e error;
829
830         _tbm_bufmgr_mutex_lock();
831         _tbm_set_last_result(TBM_ERROR_NONE);
832
833         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
834
835         if (bo->bufmgr->use_hal_tbm) {
836                 ret = (hal_tbm_fd)hal_tbm_bo_export_fd((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
837                 if (ret < 0) {
838                         /* LCOV_EXCL_START */
839                         TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
840                         _tbm_set_last_result(error);
841                         goto done;
842                         /* LCOV_EXCL_STOP */
843                 }
844         } else if (bo->bufmgr->backend_module_data) {
845                 if (!bo->bufmgr->bo_func->bo_export_fd) {
846                         /* LCOV_EXCL_START */
847                         _tbm_bufmgr_mutex_unlock();
848                         _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
849                         return -1;
850                         /* LCOV_EXCL_STOP */
851                 }
852
853                 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
854                 if (ret < 0) {
855                         /* LCOV_EXCL_START */
856                         TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
857                         _tbm_set_last_result(error);
858                         goto done;
859                         /* LCOV_EXCL_STOP */
860                 }
861         } else {
862                 if (!bo->bufmgr->backend->bo_export_fd) {
863                         /* LCOV_EXCL_START */
864                         _tbm_bufmgr_mutex_unlock();
865                         _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
866                         return -1;
867                         /* LCOV_EXCL_STOP */
868                 }
869
870                 ret = bo->bufmgr->backend->bo_export_fd(bo);
871                 if (ret < 0) {
872                         /* LCOV_EXCL_START */
873                         TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
874                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
875                         goto done;
876                         /* LCOV_EXCL_STOP */
877                 }
878         }
879
880         TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
881
882 done:
883         _tbm_bufmgr_mutex_unlock();
884
885         return ret;
886 }
887
888 tbm_bo
889 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
890 {
891         tbm_bo bo;
892         tbm_bo bo2 = NULL;
893         void *bo_priv;
894         tbm_error_e error;
895         tbm_backend_bo_data *bo_data;
896         int flags;
897
898         _tbm_bufmgr_mutex_lock();
899         _tbm_set_last_result(TBM_ERROR_NONE);
900
901         TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
902
903         if (!bufmgr->use_hal_tbm) {
904                 if (bufmgr->backend_module_data) {
905                         if (!bufmgr->bufmgr_func->bufmgr_import_key) {
906                                 /* LCOV_EXCL_START */
907                                 _tbm_bufmgr_mutex_unlock();
908                                 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
909                                 return NULL;
910                                 /* LCOV_EXCL_STOP */
911                         }
912                 } else {
913                         if (!bufmgr->backend->bo_import) {
914                                 /* LCOV_EXCL_START */
915                                 _tbm_bufmgr_mutex_unlock();
916                                 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
917                                 return NULL;
918                                 /* LCOV_EXCL_STOP */
919                         }
920                 }
921         }
922
923         _tbm_util_check_bo_cnt(bufmgr);
924
925         bo = calloc(1, sizeof(struct _tbm_bo));
926         if (!bo) {
927                 /* LCOV_EXCL_START */
928                 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
929                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
930                 _tbm_bufmgr_mutex_unlock();
931                 return NULL;
932                 /* LCOV_EXCL_STOP */
933         }
934
935         if (bufmgr->use_hal_tbm) {
936                 bo_data = (tbm_backend_bo_data *)hal_tbm_bufmgr_import_key(bufmgr->hal_bufmgr, key, (hal_tbm_error *)&error);
937                 /* LCOV_EXCL_START */
938                 if (!bo_data) {
939                         TBM_ERR("error: fail to import of tbm_bo by key(%d). error(%d)\n", key, error);
940                         _tbm_set_last_result(error);
941                         goto import_fail;
942                 }
943                 /* LCOV_EXCL_STOP */
944                 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
945                         LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
946                                 if (bo2->bo_data == bo_data) {
947                                         TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
948                                                         bo2, bo2->ref_cnt, key,
949                                                         _tbm_flag_to_str(bo2->flags));
950                                         bo2->ref_cnt++;
951                                         free(bo);
952                                         _tbm_bufmgr_mutex_unlock();
953                                         return bo2;
954                                 }
955                         }
956                 }
957                 bo->bo_data = bo_data;
958         } else if (bufmgr->backend_module_data) {
959                 bo_data = bufmgr->bufmgr_func->bufmgr_import_key(bufmgr->bufmgr_data, key, &error);
960                 if (!bo_data) {
961                         /* LCOV_EXCL_START */
962                         TBM_ERR("error: fail to import of tbm_bo by key(%d). error(%d)\n", key, error);
963                         _tbm_set_last_result(error);
964                         goto import_fail;
965                         /* LCOV_EXCL_STOP */
966                 }
967
968                 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
969                         LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
970                                 if (bo2->bo_data == bo_data) {
971                                         TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
972                                                         bo2, bo2->ref_cnt, key,
973                                                         _tbm_flag_to_str(bo2->flags));
974                                         bo2->ref_cnt++;
975                                         free(bo);
976                                         _tbm_bufmgr_mutex_unlock();
977                                         return bo2;
978                                 }
979                         }
980                 }
981                 bo->bo_data = bo_data;
982         } else {
983                 bo_priv = bufmgr->backend->bo_import(bo, key);
984                 if (!bo_priv) {
985                         /* LCOV_EXCL_START */
986                         TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
987                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
988                         goto import_fail;
989                         /* LCOV_EXCL_STOP */
990                 }
991
992                 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
993                         LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
994                                 if (bo2->priv == bo_priv) {
995                                         TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
996                                                         bo2, bo2->ref_cnt, key,
997                                                         _tbm_flag_to_str(bo2->flags));
998                                         bo2->ref_cnt++;
999                                         free(bo);
1000                                         _tbm_bufmgr_mutex_unlock();
1001                                         return bo2;
1002                                 }
1003                         }
1004                 }
1005                 bo->priv = bo_priv;
1006         }
1007
1008         if (bufmgr->use_hal_tbm) {
1009                 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
1010                 if (error != TBM_ERROR_NONE) {
1011                         TBM_ERR("fail to get the bo flags(memory_types)");
1012                         _tbm_set_last_result(error);
1013                         flags = TBM_BO_DEFAULT;
1014                 }
1015         } else if (bufmgr->backend_module_data) {
1016                 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
1017                 if (error != TBM_ERROR_NONE) {
1018                         TBM_ERR("fail to get the bo flags(memory_types)");
1019                         _tbm_set_last_result(error);
1020                         flags = TBM_BO_DEFAULT;
1021                 }
1022         } else {
1023                 if (bufmgr->backend->bo_get_flags)
1024                         flags = bufmgr->backend->bo_get_flags(bo);
1025                 else
1026                         flags = TBM_BO_DEFAULT;
1027         }
1028
1029         _tbm_bo_init(bufmgr, bo, flags);
1030
1031         TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
1032                           bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
1033
1034         _tbm_bufmgr_mutex_unlock();
1035
1036         return bo;
1037
1038 import_fail:
1039         free(bo);
1040         _tbm_bufmgr_mutex_unlock();
1041         return NULL;
1042 }
1043
1044 tbm_bo
1045 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1046 {
1047         tbm_bo bo;
1048         tbm_bo bo2 = NULL;
1049         void *bo_priv;
1050         tbm_backend_bo_data *bo_data;
1051         tbm_error_e error;
1052         int flags;
1053
1054         _tbm_bufmgr_mutex_lock();
1055         _tbm_set_last_result(TBM_ERROR_NONE);
1056
1057         TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1058
1059         if (!bufmgr->use_hal_tbm) {
1060                 if (bufmgr->backend_module_data) {
1061                         if (!bufmgr->bufmgr_func->bufmgr_import_fd) {
1062                                 /* LCOV_EXCL_START */
1063                                 _tbm_bufmgr_mutex_unlock();
1064                                 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1065                                 return NULL;
1066                                 /* LCOV_EXCL_STOP */
1067                         }
1068                 } else {
1069                         if (!bufmgr->backend->bo_import_fd) {
1070                                 /* LCOV_EXCL_START */
1071                                 _tbm_bufmgr_mutex_unlock();
1072                                 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1073                                 return NULL;
1074                                 /* LCOV_EXCL_STOP */
1075                         }
1076                 }
1077         }
1078
1079         _tbm_util_check_bo_cnt(bufmgr);
1080
1081         bo = calloc(1, sizeof(struct _tbm_bo));
1082         if (!bo) {
1083                 /* LCOV_EXCL_START */
1084                 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1085                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1086                 _tbm_bufmgr_mutex_unlock();
1087                 return NULL;
1088                 /* LCOV_EXCL_STOP */
1089         }
1090
1091         if (bufmgr->use_hal_tbm) {
1092                 bo_data = (tbm_backend_bo_data *)hal_tbm_bufmgr_import_fd(bufmgr->hal_bufmgr, (hal_tbm_fd)fd, (hal_tbm_error *)&error);
1093                 /* LCOV_EXCL_START */
1094                 if (!bo_data) {
1095                         TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d). error(%d)\n", fd, error);
1096                         _tbm_set_last_result(error);
1097                         goto import_fail;
1098                 }
1099                 /* LCOV_EXCL_STOP */
1100
1101                 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1102                         LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1103                                 if (bo2->bo_data == bo_data) {
1104                                         TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1105                                                         bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1106                                         bo2->ref_cnt++;
1107                                         free(bo);
1108                                         _tbm_bufmgr_mutex_unlock();
1109                                         return bo2;
1110                                 }
1111                         }
1112                 }
1113                 bo->bo_data = bo_data;
1114         } else if (bufmgr->backend_module_data) {
1115                 bo_data = bufmgr->bufmgr_func->bufmgr_import_fd(bufmgr->bufmgr_data, fd, &error);
1116                 if (!bo_data) {
1117                         /* LCOV_EXCL_START */
1118                         TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d). error(%d)\n", fd, error);
1119                         _tbm_set_last_result(error);
1120                         goto import_fail;
1121                         /* LCOV_EXCL_STOP */
1122                 }
1123
1124                 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1125                         LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1126                                 if (bo2->bo_data == bo_data) {
1127                                         TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1128                                                         bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1129                                         bo2->ref_cnt++;
1130                                         free(bo);
1131                                         _tbm_bufmgr_mutex_unlock();
1132                                         return bo2;
1133                                 }
1134                         }
1135                 }
1136                 bo->bo_data = bo_data;
1137         } else {
1138                 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
1139                 if (!bo_priv) {
1140                         /* LCOV_EXCL_START */
1141                         TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1142                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1143                         goto import_fail;
1144                         /* LCOV_EXCL_STOP */
1145                 }
1146
1147                 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1148                         LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1149                                 if (bo2->priv == bo_priv) {
1150                                         TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1151                                                         bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1152                                         bo2->ref_cnt++;
1153                                         free(bo);
1154                                         _tbm_bufmgr_mutex_unlock();
1155                                         return bo2;
1156                                 }
1157                         }
1158                 }
1159                 bo->priv = bo_priv;
1160         }
1161
1162         if (bufmgr->use_hal_tbm) {
1163                 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
1164                 if (error != TBM_ERROR_NONE) {
1165                         TBM_ERR("fail to get the bo flags(memory_types)");
1166                         _tbm_set_last_result(error);
1167                         flags = TBM_BO_DEFAULT;
1168                 }
1169         } else if (bufmgr->backend_module_data) {
1170                 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
1171                 if (error != TBM_ERROR_NONE) {
1172                         TBM_ERR("fail to get the bo flags(memory_types)");
1173                         _tbm_set_last_result(error);
1174                         flags = TBM_BO_DEFAULT;
1175                 }
1176         } else {
1177                 if (bufmgr->backend->bo_get_flags)
1178                         flags = bufmgr->backend->bo_get_flags(bo);
1179                 else
1180                         flags = TBM_BO_DEFAULT;
1181         }
1182
1183         _tbm_bo_init(bufmgr, bo, flags);
1184
1185         TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
1186                         bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1187
1188         _tbm_bufmgr_mutex_unlock();
1189
1190         return bo;
1191
1192 import_fail:
1193         free(bo);
1194         _tbm_bufmgr_mutex_unlock();
1195         return NULL;
1196 }
1197
1198 int
1199 tbm_bo_size(tbm_bo bo)
1200 {
1201         int size;
1202         tbm_error_e error;
1203
1204         _tbm_bufmgr_mutex_lock();
1205         _tbm_set_last_result(TBM_ERROR_NONE);
1206
1207         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1208
1209         if (bo->bufmgr->use_hal_tbm) {
1210                 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
1211                 if (error != TBM_ERROR_NONE) {
1212                         TBM_ERR("fail to get the size of the bo_data(%d).", error);
1213                         _tbm_set_last_result(TBM_ERROR_NONE);
1214                 }
1215         } else if (bo->bufmgr->backend_module_data) {
1216                 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
1217                 if (error != TBM_ERROR_NONE) {
1218                         TBM_ERR("fail to get the size of the bo_data(%d).", error);
1219                         _tbm_set_last_result(TBM_ERROR_NONE);
1220                 }
1221         } else
1222                 size = bo->bufmgr->backend->bo_size(bo);
1223
1224         TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
1225
1226         _tbm_bufmgr_mutex_unlock();
1227
1228         return size;
1229 }
1230
1231 int
1232 tbm_bo_locked(tbm_bo bo)
1233 {
1234         _tbm_bufmgr_mutex_lock();
1235         _tbm_set_last_result(TBM_ERROR_NONE);
1236
1237         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1238
1239         if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
1240                 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1241                 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1242                 _tbm_bufmgr_mutex_unlock();
1243                 return 0;
1244         }
1245
1246         if (bo->lock_cnt > 0) {
1247                 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1248                 _tbm_bufmgr_mutex_unlock();
1249                 return 1;
1250         }
1251
1252         TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1253         _tbm_bufmgr_mutex_unlock();
1254
1255         return 0;
1256 }
1257
1258 int
1259 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1260 {
1261         tbm_error_e error1, error2;
1262         int size1 = -1, size2 = -2;
1263         void *temp;
1264
1265         _tbm_bufmgr_mutex_lock();
1266         _tbm_set_last_result(TBM_ERROR_NONE);
1267
1268         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1269         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1270
1271         TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1272
1273         if (bo1->bufmgr->use_hal_tbm) {
1274                 size1 = hal_tbm_bo_get_size((hal_tbm_bo *)bo1->bo_data, (hal_tbm_error *)&error1);
1275                 if (error1 != TBM_ERROR_NONE) {
1276                         TBM_ERR("fail to get the size of bo1.(%d)", error1);
1277                         _tbm_set_last_result(error1);
1278                         goto fail;
1279                 }
1280                 size2 = hal_tbm_bo_get_size((hal_tbm_bo *)bo2->bo_data, (hal_tbm_error *)&error2);
1281                 if (error2 != TBM_ERROR_NONE) {
1282                         TBM_ERR("fail to get the size of bo1.(%d)", error2);
1283                         _tbm_set_last_result(error2);
1284                         goto fail;
1285                 }
1286         } else if (bo1->bufmgr->backend_module_data) {
1287                 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1288                 if (error1 != TBM_ERROR_NONE) {
1289                         TBM_ERR("fail to get the size of bo1.(%d)", error1);
1290                         _tbm_set_last_result(error1);
1291                         goto fail;
1292                 }
1293                 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1294                 if (error2 != TBM_ERROR_NONE) {
1295                         TBM_ERR("fail to get the size of bo2.(%d)", error2);
1296                         _tbm_set_last_result(error2);
1297                         goto fail;
1298                 }
1299         } else {
1300                 size1 = bo1->bufmgr->backend->bo_size(bo1);
1301                 size2 = bo2->bufmgr->backend->bo_size(bo2);
1302         }
1303
1304         if (size1 != size2) {
1305                 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1306                 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1307                 goto fail;
1308         }
1309
1310         TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1311
1312         temp = bo1->priv;
1313         bo1->priv = bo2->priv;
1314         bo2->priv = temp;
1315
1316         _tbm_bufmgr_mutex_unlock();
1317
1318         return 1;
1319
1320 fail:
1321         TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1322         _tbm_bufmgr_mutex_unlock();
1323
1324         return 0;
1325 }
1326
1327 int
1328 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1329                      tbm_data_free data_free_func)
1330 {
1331         tbm_user_data *data;
1332
1333         _tbm_bufmgr_mutex_lock();
1334         _tbm_set_last_result(TBM_ERROR_NONE);
1335
1336         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1337
1338         /* check if the data according to the key exist if so, return false. */
1339         data = user_data_lookup(&bo->user_data_list, key);
1340         if (data) {
1341                 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1342                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1343                 _tbm_bufmgr_mutex_unlock();
1344                 return 0;
1345         }
1346
1347         data = user_data_create(key, data_free_func);
1348         if (!data) {
1349                 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1350                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1351                 _tbm_bufmgr_mutex_unlock();
1352                 return 0;
1353         }
1354
1355         TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1356
1357         LIST_ADD(&data->item_link, &bo->user_data_list);
1358
1359         _tbm_bufmgr_mutex_unlock();
1360
1361         return 1;
1362 }
1363
1364 int
1365 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1366 {
1367         tbm_user_data *old_data;
1368
1369         _tbm_bufmgr_mutex_lock();
1370         _tbm_set_last_result(TBM_ERROR_NONE);
1371
1372         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1373
1374         if (LIST_IS_EMPTY(&bo->user_data_list)) {
1375                 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1376                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1377                 _tbm_bufmgr_mutex_unlock();
1378                 return 0;
1379         }
1380
1381         old_data = user_data_lookup(&bo->user_data_list, key);
1382         if (!old_data) {
1383                 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1384                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1385                 _tbm_bufmgr_mutex_unlock();
1386                 return 0;
1387         }
1388
1389         TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1390
1391         user_data_delete(old_data);
1392
1393         _tbm_bufmgr_mutex_unlock();
1394
1395         return 1;
1396 }
1397
1398 int
1399 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1400 {
1401         tbm_user_data *old_data;
1402
1403         _tbm_bufmgr_mutex_lock();
1404         _tbm_set_last_result(TBM_ERROR_NONE);
1405
1406         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1407
1408         if (LIST_IS_EMPTY(&bo->user_data_list)) {
1409                 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1410                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1411                 _tbm_bufmgr_mutex_unlock();
1412                 return 0;
1413         }
1414
1415         old_data = user_data_lookup(&bo->user_data_list, key);
1416         if (!old_data) {
1417                 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1418                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1419                 _tbm_bufmgr_mutex_unlock();
1420                 return 0;
1421         }
1422
1423         if (old_data->data && old_data->free_func)
1424                 old_data->free_func(old_data->data);
1425         old_data->data = data;
1426
1427         TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1428
1429         _tbm_bufmgr_mutex_unlock();
1430
1431         return 1;
1432 }
1433
1434 int
1435 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1436 {
1437         tbm_user_data *old_data;
1438
1439         _tbm_bufmgr_mutex_lock();
1440         _tbm_set_last_result(TBM_ERROR_NONE);
1441
1442         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1443
1444         if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1445                 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1446                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1447                 _tbm_bufmgr_mutex_unlock();
1448                 return 0;
1449         }
1450
1451         old_data = user_data_lookup(&bo->user_data_list, key);
1452         if (!old_data) {
1453                 *data = NULL;
1454                 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1455                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1456                 _tbm_bufmgr_mutex_unlock();
1457                 return 0;
1458         }
1459
1460         *data = old_data->data;
1461
1462         TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1463
1464         _tbm_bufmgr_mutex_unlock();
1465
1466         return 1;
1467 }
1468
1469 int
1470 tbm_bo_get_flags(tbm_bo bo)
1471 {
1472         int flags;
1473
1474         _tbm_bufmgr_mutex_lock();
1475
1476         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1477
1478         flags = bo->flags;
1479
1480         TBM_TRACE_BO("bo(%p)\n", bo);
1481
1482         _tbm_bufmgr_mutex_unlock();
1483
1484         return flags;
1485 }
1486
1487 /* LCOV_EXCL_START */
1488 /* internal function */
1489 int
1490 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1491 {
1492         _tbm_bufmgr_mutex_lock();
1493
1494         TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1495
1496         bo->surface = surface;
1497
1498         _tbm_bufmgr_mutex_unlock();
1499
1500         return 1;
1501 }
1502
1503 void
1504 _tbm_bo_free(tbm_bo bo)
1505 {
1506         /* destory the user_data_list */
1507         if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1508                 tbm_user_data *old_data = NULL, *tmp;
1509
1510                 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1511                                 &bo->user_data_list, item_link) {
1512                         TBM_DBG("free user_data\n");
1513                         user_data_delete(old_data);
1514                 }
1515         }
1516
1517         while (bo->lock_cnt > 0) {
1518                 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1519                 _bo_unlock(bo);
1520                 bo->lock_cnt--;
1521         }
1522
1523         /* call the bo_free */
1524         if (bo->bufmgr->use_hal_tbm) {
1525                 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1526                 if (!bo->get_from_hal_surface) {
1527                         bo->get_from_hal_surface = 0;
1528
1529                         hal_tbm_bo_free(bo->bo_data);
1530                         bo->bo_data = NULL;
1531                 }
1532         } else if (bo->bufmgr->backend_module_data) {
1533                 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1534                 bo->bo_data = NULL;
1535         } else {
1536                 bo->bufmgr->backend->bo_free(bo);
1537                 bo->priv = NULL;
1538         }
1539
1540         _tbm_bo_deinit(bo);
1541
1542         free(bo);
1543 }
1544 /* LCOV_EXCL_STOP */