adapt hal-api-tbm
[platform/core/uifw/libtbm.git] / src / tbm_bufmgr.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
34 #include "tbm_bufmgr.h"
35 #include "tbm_bufmgr_int.h"
36 #include "tbm_bufmgr_backend.h"
37 #include "list.h"
38
39 #include <sys/resource.h>
40
41 int trace_mask = 0;
42
43 #ifdef HAVE_DLOG
44 int bDlog;
45 #endif
46
47 tbm_bufmgr gBufMgr;
48 int b_dump_queue;
49
50 static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
51 static pthread_mutex_t tbm_bufmgr_lock = PTHREAD_MUTEX_INITIALIZER;
52 static double scale_factor = 0;
53 void _tbm_bufmgr_mutex_unlock(void);
54
55 //#define TBM_BUFMGR_INIT_TIME
56
57 #define PREFIX_LIB    "libtbm_"
58 #define SUFFIX_LIB    ".so"
59 #define DEFAULT_LIB   PREFIX_LIB"default"SUFFIX_LIB
60
61 /* values to indicate unspecified fields in XF86ModReqInfo. */
62 #define MAJOR_UNSPEC      0xFF
63 #define MINOR_UNSPEC      0xFF
64 #define PATCH_UNSPEC      0xFFFF
65 #define ABI_VERS_UNSPEC   0xFFFFFFFF
66
67 #define MODULE_VERSION_NUMERIC(maj, min, patch) \
68                         ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
69 #define GET_MODULE_MAJOR_VERSION(vers)    (((vers) >> 24) & 0xFF)
70 #define GET_MODULE_MINOR_VERSION(vers)    (((vers) >> 16) & 0xFF)
71 #define GET_MODULE_PATCHLEVEL(vers)    ((vers) & 0xFFFF)
72
73 #define MAX_SIZE_N(dest)        (sizeof(dest) - strlen(dest) - 1)
74
75 /* check condition */
76 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
77         if (!(cond)) {\
78                 TBM_ERR("'%s' failed.\n", #cond);\
79                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
80                 _tbm_bufmgr_mutex_unlock();\
81                 return;\
82         } \
83 }
84
85 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
86         if (!(cond)) {\
87                 TBM_ERR("'%s' failed.\n", #cond);\
88                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
89                 _tbm_bufmgr_mutex_unlock();\
90                 return val;\
91         } \
92 }
93
94 /* LCOV_EXCL_START */
95
96 void
97 _tbm_bufmgr_mutex_lock(void)
98 {
99         pthread_mutex_lock(&tbm_bufmgr_lock);
100 }
101
102 void
103 _tbm_bufmgr_mutex_unlock(void)
104 {
105         pthread_mutex_unlock(&tbm_bufmgr_lock);
106 }
107
108 static int
109 _tbm_util_get_max_surface_size(int *w, int *h)
110 {
111         tbm_surface_info_s info;
112         tbm_surface_h surface = NULL;
113         int count = 0;
114
115         *w = 0;
116         *h = 0;
117
118         if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
119                 return count;
120
121         LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
122                 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
123                         count++;
124                         if (*w < info.width)
125                                 *w = info.width;
126                         if (*h < info.height)
127                                 *h = info.height;
128                 }
129         }
130
131         return count;
132 }
133
134 static void
135 _tbm_util_get_appname_brief(char *brief)
136 {
137         char delim[] = "/";
138         char *token = NULL;
139         char temp[255] = {0,};
140         char *saveptr = NULL;
141
142         token = strtok_r(brief, delim, &saveptr);
143
144         while (token != NULL) {
145                 memset(temp, 0x00, 255 * sizeof(char));
146                 strncpy(temp, token, 254 * sizeof(char));
147                 token = strtok_r(NULL, delim, &saveptr);
148         }
149
150         snprintf(brief, sizeof(temp), "%s", temp);
151 }
152
153 static void
154 _tbm_util_get_appname_from_pid(long pid, char *str)
155 {
156         char fn_cmdline[255] = {0, }, cmdline[255];
157         FILE *fp;
158         int len;
159
160         if (pid <= 0) return;
161
162         snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
163
164         fp = fopen(fn_cmdline, "r");
165         if (fp == 0) {
166                 TBM_ERR("cannot file open %s\n", fn_cmdline);
167                 return;
168         }
169
170         if (!fgets(cmdline, 255, fp)) {
171                 TBM_ERR("fail to get appname for pid(%ld)\n", pid);
172                 fclose(fp);
173                 return;
174         }
175
176         fclose(fp);
177
178         len = strlen(cmdline);
179         if (len < 1)
180                 memset(cmdline, 0x00, 255);
181         else
182                 cmdline[len] = 0;
183
184         snprintf(str, sizeof(cmdline), "%s", cmdline);
185 }
186
187 static int
188 _tbm_backend_load_hal_tbm(tbm_bufmgr bufmgr)
189 {
190         hal_tbm_backend *hal_backend = NULL;
191         hal_tbm_bufmgr_capability capability;
192         hal_tbm_bufmgr *hal_bufmgr;
193         hal_tbm_error ret = HAL_TBM_ERROR_NONE;
194
195         hal_backend = hal_tbm_get_backend(&ret);
196         if (hal_backend == NULL || ret != HAL_TBM_ERROR_NONE) {
197                 TBM_ERR("get backend fail");
198                 return 0;
199         }
200
201         hal_bufmgr = hal_tbm_backend_get_bufmgr(hal_backend, &ret);
202         if (hal_bufmgr == NULL || ret != HAL_TBM_ERROR_NONE) {
203                 TBM_ERR("get hal_bufmgr fail");
204                 goto get_backend_fail;
205         }
206
207         capability = hal_tbm_bufmgr_get_capabilities(hal_bufmgr, &ret);
208         if (ret != HAL_TBM_ERROR_NONE) {
209                 TBM_ERR("hal_tbm_bufmgr_get_capabilities fail.");
210                 goto get_backend_fail;
211         }
212
213         if (capability == HAL_TBM_BUFMGR_CAPABILITY_NONE) {
214                 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
215                 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
216                 goto get_backend_fail;
217         }
218         if (!(capability & HAL_TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
219                 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
220                 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
221                 goto get_backend_fail;
222         }
223         bufmgr->capabilities = capability;
224
225         bufmgr->hal_backend = hal_backend;
226         bufmgr->hal_bufmgr = hal_bufmgr;
227
228         bufmgr->use_hal_tbm = 1;
229
230         TBM_INFO("use hal tbm");
231
232         return 1;
233
234 get_backend_fail:
235         hal_tbm_put_backend(hal_backend);
236         return 0;
237 }
238
239 static int
240 _check_version(TBMModuleVersionInfo *data)
241 {
242         int backend_module_major, backend_module_minor;
243         int tbm_backend_major, tbm_backend_minor;
244
245         backend_module_major = GET_ABI_MAJOR(data->abiversion);
246         backend_module_minor = GET_ABI_MINOR(data->abiversion);
247
248         TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
249             data->modname ? data->modname : "UNKNOWN!",
250             data->vendor ? data->vendor : "UNKNOWN!", backend_module_major, backend_module_minor);
251
252         tbm_backend_major = GET_ABI_MAJOR(TBM_ABI_VERSION);
253         tbm_backend_minor = GET_ABI_MINOR(TBM_ABI_VERSION);
254
255         TBM_DBG("TBM ABI version %d.%d\n",
256             tbm_backend_major, tbm_backend_minor);
257
258         if (backend_module_major != tbm_backend_major) {
259                 TBM_ERR("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
260                         backend_module_major, tbm_backend_major);
261                 return 0;
262         } else if (backend_module_minor > tbm_backend_minor) {
263                 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
264                         backend_module_minor, tbm_backend_minor);
265                 return 0;
266         }
267
268         return 1;
269 }
270
271 static int
272 _tbm_backend_check_bufmgr_func(tbm_backend_bufmgr_func *bufmgr_func)
273 {
274         TBM_RETURN_VAL_IF_FAIL(bufmgr_func, 0); /* mandatory symbol */
275         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0); /* mandatory symbol */
276         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, 0); /* mandatory symbol */
277         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, 0); /* mandatory symbol */
278         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, 0); /* mandatory symbol */
279         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, 0); /* mandatory symbol */
280         if (!bufmgr_func->bufmgr_alloc_bo_with_format)
281                 TBM_DBG("No bufmgr_func->bufmgr_alloc_bo_with_format.");
282         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_import_fd, 0); /* mandatory symbol */
283         if (!bufmgr_func->bufmgr_import_key)
284                 TBM_DBG("No bufmgr_func->bo_export_key.");
285
286         return 1;
287 }
288
289 static int
290 _tbm_backend_check_bufmgr_bo(tbm_backend_bo_func *bo_func)
291 {
292         TBM_RETURN_VAL_IF_FAIL(bo_func, 0); /* mandatory symbol */
293         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_free, 0); /* mandatory symbol */
294         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_size, 0); /* mandatory symbol */
295         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_memory_types, 0); /* mandatory symbol */
296         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_handle, 0); /* mandatory symbol */
297         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_map, 0); /* mandatory symbol */
298         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, 0); /* mandatory symbol */
299         if (!bo_func->bo_lock)
300                 TBM_DBG("No bo_func->bo_lock.");
301         if (!bo_func->bo_unlock)
302                 TBM_DBG("No bo_func->bo_unlock.");
303         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_export_fd, 0); /* mandatory symbol */
304         if (!bo_func->bo_export_key)
305                 TBM_INFO("No bo_func->bo_export_key.");
306
307         return 1;
308 }
309
310 static int
311 _tbm_backend_load_module(tbm_bufmgr bufmgr, const char *file)
312 {
313         char path[PATH_MAX] = {0, };
314         void *module_data = NULL;
315         tbm_backend_module *backend_module_data = NULL;
316         tbm_backend_bufmgr_data *bufmgr_data = NULL;
317         int backend_module_major, backend_module_minor;
318         int tbm_backend_major, tbm_backend_minor;
319         tbm_error_e error;
320
321         snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
322
323         module_data = dlopen(path, RTLD_LAZY);
324         if (!module_data) {
325                 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
326                 return 0;
327         }
328
329         backend_module_data = dlsym(module_data, "tbm_backend_module_data");
330         if (!backend_module_data) {
331                 TBM_ERR("Error: module does not have data object.\n");
332                 goto err;
333         }
334
335         tbm_backend_major = GET_ABI_MAJOR(TBM_BACKEND_ABI_LATEST_VERSION);
336         tbm_backend_minor = GET_ABI_MINOR(TBM_BACKEND_ABI_LATEST_VERSION);
337         TBM_INFO("TBM Backend ABI version %d.%d\n", tbm_backend_major, tbm_backend_minor);
338
339         backend_module_major = GET_ABI_MAJOR(backend_module_data->abi_version);
340         backend_module_minor = GET_ABI_MINOR(backend_module_data->abi_version);
341
342         TBM_INFO("TBM module %s: vendor=\"%s\" Backend ABI version=%d.%d\n",
343             backend_module_data->name ? backend_module_data->name : "UNKNOWN!",
344             backend_module_data->vendor ? backend_module_data->vendor : "UNKNOWN!",
345                 backend_module_major, backend_module_minor);
346
347         if (backend_module_major > tbm_backend_major) {
348                 TBM_ERR("TBM module ABI major ver(%d) is newer than the TBM's ver(%d)\n",
349                         backend_module_major, tbm_backend_major);
350                 goto err;
351         } else if (backend_module_minor > tbm_backend_minor) {
352                 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
353                         backend_module_minor, tbm_backend_minor);
354                 goto err;
355         }
356
357         if (!backend_module_data->init) {
358                 TBM_ERR("Error: module does not supply init symbol.\n");
359                 goto err;
360         }
361
362         if (!backend_module_data->deinit)       {
363                 TBM_ERR("Error: module does not supply deinit symbol.\n");
364                 goto err;
365         }
366
367         bufmgr_data = backend_module_data->init(bufmgr, &error);
368         if (!bufmgr_data) {
369                 TBM_ERR("Fail to init module(%s)\n", file);
370                 goto err;
371         }
372
373         /* check the mandatory symbols of the backend module */
374         if (!_tbm_backend_check_bufmgr_func(bufmgr->bufmgr_func)) {
375                 TBM_ERR("Fail to check the bufmgr_func symboles.");
376                 goto err;
377         }
378
379         if (!_tbm_backend_check_bufmgr_bo(bufmgr->bo_func)) {
380                 TBM_ERR("Fail to check the bufmgr_bo symboles.");
381                 goto err;
382         }
383
384         /* get the capability */
385         bufmgr->capabilities = bufmgr->bufmgr_func->bufmgr_get_capabilities(bufmgr_data, &error);
386         if (bufmgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
387                 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
388                 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
389                 goto err;
390         }
391
392         if (!(bufmgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
393                 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
394                 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
395                 goto err;
396         }
397
398         bufmgr->module_data = module_data;
399         bufmgr->backend_module_data = backend_module_data;
400         bufmgr->bufmgr_data = bufmgr_data;
401
402         TBM_INFO("Success to load module(%s)\n", file);
403
404         return 1;
405
406 err:
407         if (bufmgr_data)
408                 bufmgr->backend_module_data->deinit(bufmgr_data);
409         if (module_data)
410                 dlclose(module_data);
411
412         return 0;
413 }
414
415 static int
416 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
417 {
418         char path[PATH_MAX] = {0, };
419         TBMModuleVersionInfo *vers;
420         TBMModuleData *initdata;
421         ModuleInitProc init;
422         void *module_data;
423
424         snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
425
426         module_data = dlopen(path, RTLD_LAZY);
427         if (!module_data) {
428                 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
429                 return 0;
430         }
431
432         initdata = dlsym(module_data, "tbmModuleData");
433         if (!initdata) {
434                 TBM_ERR("Error: module does not have data object.\n");
435                 goto err;
436         }
437
438         vers = initdata->vers;
439         if (!vers) {
440                 TBM_ERR("Error: module does not supply version information.\n");
441                 goto err;
442         }
443
444         init = initdata->init;
445         if (!init) {
446                 TBM_ERR("Error: module does not supply init symbol.\n");
447                 goto err;
448         }
449
450         if (!_check_version(vers)) {
451                 TBM_ERR("Fail to check version.\n");
452                 goto err;
453         }
454
455         if (!init(bufmgr, fd)) {
456                 TBM_ERR("Fail to init module(%s)\n", file);
457                 goto err;
458         }
459
460         if (!bufmgr->backend || !bufmgr->backend->priv) {
461                 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
462                 goto err;
463         }
464
465         bufmgr->module_data = module_data;
466
467         TBM_DBG("Success to load module(%s)\n", file);
468
469         return 1;
470
471 err:
472         dlclose(module_data);
473         return 0;
474 }
475
476 static int
477 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
478 {
479         struct dirent **namelist;
480         int ret = 0, n;
481
482         /* try to load the hal-tbm backend module */
483         ret = _tbm_backend_load_hal_tbm(bufmgr);
484         if (ret)
485                 return 1;
486
487         /* try to load the new backend module */
488         ret = _tbm_backend_load_module(bufmgr, DEFAULT_LIB);
489         if (ret)
490                 return 1;
491
492         /* try to load the old(deprecated) backend mdoule */
493         ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
494         if (ret)
495                 return 1;
496
497         /* load bufmgr priv from configured path */
498         n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
499         if (n < 0) {
500                 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
501                 return 0;
502         }
503
504         while (n--) {
505                 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
506                         const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
507
508                         if (p && !strcmp(p, SUFFIX_LIB)) {
509                                 ret = _tbm_backend_load_module(bufmgr, namelist[n]->d_name);
510                                 if (!ret)
511                                         ret = _tbm_bufmgr_load_module(bufmgr, fd,
512                                                                         namelist[n]->d_name);
513                         }
514                 }
515
516                 free(namelist[n]);
517         }
518
519         free(namelist);
520
521         return ret;
522 }
523 /* LCOV_EXCL_STOP */
524
525 static tbm_bufmgr
526 _tbm_bufmgr_init(int fd, int server)
527 {
528 #ifdef TBM_BUFMGR_INIT_TIME
529         struct timeval start_tv, end_tv;
530 #endif
531         char *env;
532
533 #ifdef TBM_BUFMGR_INIT_TIME
534         /* get the start tv */
535         gettimeofday(&start_tv, NULL);
536 #endif
537
538         bDlog = 1;
539
540         /* LCOV_EXCL_START */
541 #ifdef TRACE
542         env = getenv("TBM_TRACE");
543         if (env) {
544                 trace_mask = atoi(env);
545                 TBM_DBG("TBM_TRACE=%s\n", env);
546         } else
547                 trace_mask = 0;
548 #endif
549
550         pthread_mutex_lock(&gLock);
551
552         _tbm_set_last_result(TBM_ERROR_NONE);
553
554         if (fd >= 0) {
555                 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
556                 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
557         }
558
559
560         /* initialize buffer manager */
561         if (gBufMgr) {
562                 gBufMgr->ref_count++;
563                 TBM_DBG("reuse  tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
564                 pthread_mutex_unlock(&gLock);
565                 return gBufMgr;
566         }
567
568         TBM_DBG("bufmgr init\n");
569
570         /* allocate bufmgr */
571         gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
572         if (!gBufMgr) {
573                 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
574                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
575                 pthread_mutex_unlock(&gLock);
576                 return NULL;
577         }
578
579         gBufMgr->fd = fd;
580
581         /* set the display_server flag before loading the backend module */
582         if (server) {
583                 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
584                 gBufMgr->display_server = 1;
585         }
586
587         /* load bufmgr priv from env */
588         if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
589                 TBM_ERR("error : Fail to load bufmgr backend\n");
590                 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
591                 free(gBufMgr);
592                 gBufMgr = NULL;
593                 pthread_mutex_unlock(&gLock);
594                 return NULL;
595
596         }
597         /* LCOV_EXCL_STOP */
598
599         gBufMgr->ref_count = 1;
600
601         TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
602             gBufMgr, gBufMgr->ref_count);
603
604         /* setup the bo_lock_type */
605         env = getenv("BUFMGR_LOCK_TYPE");
606         if (env && !strcmp(env, "always"))
607                 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
608         else if (env && !strcmp(env, "none"))
609                 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
610         else if (env && !strcmp(env, "once"))
611                 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
612         else
613                 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
614
615         TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
616
617         /* intialize bo_list */
618         LIST_INITHEAD(&gBufMgr->bo_list);
619
620         /* intialize surf_list */
621         LIST_INITHEAD(&gBufMgr->surf_list);
622
623         /* intialize surf_queue_list */
624         LIST_INITHEAD(&gBufMgr->surf_queue_list);
625
626         /* intialize debug_key_list */
627         LIST_INITHEAD(&gBufMgr->debug_key_list);
628
629 #ifdef TBM_BUFMGR_INIT_TIME
630         /* get the end tv */
631         gettimeofday(&end_tv, NULL);
632         TBM_INFO("tbm_bufmgr_init time: %ld ms", ((end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000) - (start_tv.tv_sec * 1000 + start_tv.tv_usec / 1000)));
633 #endif
634
635         pthread_mutex_unlock(&gLock);
636
637         return gBufMgr;
638 }
639
640 tbm_bufmgr
641 tbm_bufmgr_init(int fd)
642 {
643         tbm_bufmgr bufmgr;
644
645         bufmgr = _tbm_bufmgr_init(fd, 0);
646
647         return bufmgr;
648 }
649
650 void
651 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
652 {
653         TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
654
655         _tbm_bufmgr_mutex_lock();
656         pthread_mutex_lock(&gLock);
657         _tbm_set_last_result(TBM_ERROR_NONE);
658
659         if (!gBufMgr) {
660                 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
661                 pthread_mutex_unlock(&gLock);
662                 _tbm_bufmgr_mutex_unlock();
663                 return;
664         }
665
666         bufmgr->ref_count--;
667         if (bufmgr->ref_count > 0) {
668                 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
669                 pthread_mutex_unlock(&gLock);
670                 _tbm_bufmgr_mutex_unlock();
671                 return;
672         }
673
674         /* destroy bo_list */
675         if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
676                 tbm_bo bo = NULL, tmp;
677
678                 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
679                         TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
680                         _tbm_bo_free(bo);
681                 }
682                 LIST_DELINIT(&bufmgr->bo_list);
683         }
684
685         /* destroy surf_list */
686         if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
687                 tbm_surface_h surf = NULL, tmp;
688
689                 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
690                         TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
691                         tbm_surface_destroy(surf);
692                 }
693                 LIST_DELINIT(&bufmgr->surf_list);
694         }
695
696         if (bufmgr->use_hal_tbm) {
697                 hal_tbm_put_backend(bufmgr->hal_backend);
698                 bufmgr->hal_backend = NULL;
699                 bufmgr->hal_bufmgr = NULL;
700                 bufmgr->use_hal_tbm = 0;
701         } else {
702                 if (bufmgr->backend_module_data) {
703                         /* deinit and backend destroys the backend func and data */
704                         bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
705                         bufmgr->bo_func = NULL;
706                         bufmgr->bufmgr_func = NULL;
707                         bufmgr->bufmgr_data = NULL;
708                         bufmgr->backend_module_data = NULL;
709                 } else {
710                         /* destroy bufmgr priv */
711                         bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
712                         bufmgr->backend->priv = NULL;
713                         tbm_backend_free(bufmgr->backend);
714                         bufmgr->backend = NULL;
715                 }
716
717                 dlclose(bufmgr->module_data);
718         }
719         if (bufmgr->fd > 0)
720                 close(bufmgr->fd);
721
722         TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
723
724         free(bufmgr);
725         gBufMgr = NULL;
726
727         pthread_mutex_unlock(&gLock);
728         _tbm_bufmgr_mutex_unlock();
729 }
730
731 unsigned int
732 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
733 {
734         unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
735
736         _tbm_bufmgr_mutex_lock();
737         _tbm_set_last_result(TBM_ERROR_NONE);
738
739         TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
740         TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
741
742         capabilities = bufmgr->capabilities;
743
744         _tbm_bufmgr_mutex_unlock();
745
746         return capabilities;
747 }
748
749 /* LCOV_EXCL_START */
750 char *
751 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
752 {
753         char app_name[255] = {0,}, title[512] = {0,};
754         tbm_surface_debug_data *debug_old_data = NULL;
755         char *str;
756         int len = 1024*4;
757         int c = 0;
758         int size;
759         tbm_error_e error;
760         long pid = 0;
761
762         pthread_mutex_lock(&gLock);
763         _tbm_set_last_result(TBM_ERROR_NONE);
764
765         if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
766                 TBM_ERR("invalid bufmgr\n");
767                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
768                 pthread_mutex_unlock(&gLock);
769                 return NULL;
770         }
771
772         str = malloc(len);
773         if (!str) {
774                 TBM_ERR("Fail to allocate the string.\n");
775                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
776                 pthread_mutex_unlock(&gLock);
777                 return NULL;
778         }
779
780         TBM_SNRPRINTF(str, len, c, "\n");
781         pid = syscall(SYS_getpid);
782         _tbm_util_get_appname_from_pid(pid, app_name);
783         _tbm_util_get_appname_brief(app_name);
784         TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
785                   app_name, pid);
786
787         snprintf(title, 255, "%s", "no  surface     refcnt  width  height  bpp  size    n_b  n_p  flags    format    app_name              ");
788
789         if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
790                 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
791                         strncat(title, "  ", MAX_SIZE_N(title));
792                         strncat(title, debug_old_data->key, MAX_SIZE_N(title));
793                 }
794         }
795
796         TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
797         TBM_SNRPRINTF(str, len, c, "%s\n", title);
798
799         /* show the tbm_surface information in surf_list */
800         if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
801                 tbm_surface_h surf = NULL;
802                 int surf_cnt = 0;
803
804                 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
805                         char data[512] = {0,};
806                         unsigned int surf_pid = 0;
807                         int i;
808
809                         surf_pid = _tbm_surface_internal_get_debug_pid(surf);
810                         if (!surf_pid) {
811                                 /* if pid is null, set the self_pid */
812                                 surf_pid = syscall(SYS_getpid);;
813                         }
814
815                         memset(app_name, 0x0, 255 * sizeof(char));
816                         if (geteuid() == 0) {
817                                 _tbm_util_get_appname_from_pid(surf_pid, app_name);
818                                 _tbm_util_get_appname_brief(app_name);
819                         } else {
820                                 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
821                         }
822
823                         snprintf(data, 255, "%-3d %-11p   %-5d %-6u %-7u %-4u %-7u  %-3d  %-3d %-8d %-9s %-22s",
824                                   ++surf_cnt,
825                                   surf,
826                                   surf->refcnt,
827                                   surf->info.width,
828                                   surf->info.height,
829                                   surf->info.bpp,
830                                   surf->info.size / 1024,
831                                   surf->num_bos,
832                                   surf->num_planes,
833                                   surf->flags,
834                                   _tbm_surface_internal_format_to_str(surf->info.format) + 11,
835                                   app_name);
836
837                         if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
838                                 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
839                                         char *value;
840
841                                         strncat(data, "  ", MAX_SIZE_N(title));
842
843                                         value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
844                                         if (value)
845                                                 strncat(data, value, MAX_SIZE_N(title));
846                                         else
847                                                 strncat(data, "none", MAX_SIZE_N(title));
848                                 }
849                         }
850                         TBM_SNRPRINTF(str, len, c, "%s\n", data);
851
852                         for (i = 0; i < surf->num_bos; i++) {
853                                 if (bufmgr->use_hal_tbm) {
854                                         size = hal_tbm_bo_get_size((hal_tbm_bo *)surf->bos[i]->bo_data, (hal_tbm_error *)&error);
855                                         if (error != TBM_ERROR_NONE)
856                                                 TBM_WRN("fail to get the size of bo.");
857                                 } else if (bufmgr->backend_module_data) {
858                                         size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
859                                         if (error != TBM_ERROR_NONE)
860                                                 TBM_WRN("fail to get the size of bo.");
861                                 } else
862                                         size = bufmgr->backend->bo_size(surf->bos[i]);
863                                 TBM_SNRPRINTF(str, len, c, " bo:%-12p  %-26d%-10d\n",
864                                           surf->bos[i],
865                                           surf->bos[i]->ref_cnt,
866                                           size / 1024);
867                         }
868                 }
869         } else
870                 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
871         TBM_SNRPRINTF(str, len, c, "\n");
872
873         TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
874         TBM_SNRPRINTF(str, len, c, "no  bo          refcnt  size    lock_cnt  map_cnt  flags   surface     name\n");
875
876         /* show the tbm_bo information in bo_list */
877         if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
878                 int bo_cnt = 0;
879                 tbm_bo bo = NULL;
880                 tbm_key key = 0;
881
882                 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
883                         if (bo->bufmgr->use_hal_tbm) {
884                                 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
885                                 if (error != TBM_ERROR_NONE)
886                                         TBM_WRN("fail to get the size of bo.");
887                                 key = (tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
888                         } else if (bufmgr->backend_module_data) {
889                                 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
890                                 if (error != TBM_ERROR_NONE)
891                                         TBM_WRN("fail to get the size of bo.");
892                                 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
893                                 if (error != TBM_ERROR_NONE)
894                                         TBM_WRN("fail to get the tdm_key of bo.");
895                         } else {
896                                 size = bufmgr->backend->bo_size(bo);
897                                 key = bufmgr->backend->bo_export(bo);
898                         }
899                         TBM_SNRPRINTF(str, len, c, "%-3d %-11p   %-5d %-7d    %-6d    %-5u %-7d %-11p  %-4d\n",
900                                   ++bo_cnt,
901                                   bo,
902                                   bo->ref_cnt,
903                                   size / 1024,
904                                   bo->lock_cnt,
905                                   bo->map_cnt,
906                                   bo->flags,
907                                   bo->surface,
908                                   key);
909                 }
910         } else
911                 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
912         TBM_SNRPRINTF(str, len, c, "\n");
913
914         TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
915
916         pthread_mutex_unlock(&gLock);
917
918         return str;
919 }
920
921 void
922 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
923 {
924         char * str;
925         str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
926         if (str) {
927                 TBM_DBG("       %s", str);
928                 free(str);
929         }
930 }
931
932 void
933 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
934 {
935         _tbm_bufmgr_mutex_lock();
936         _tbm_set_last_result(TBM_ERROR_NONE);
937
938         TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
939         TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
940
941 #ifdef TRACE
942         TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
943         bTrace = onoff;
944 #endif
945
946         _tbm_bufmgr_mutex_unlock();
947 }
948
949 void
950 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
951 {
952         _tbm_bufmgr_mutex_lock();
953         _tbm_set_last_result(TBM_ERROR_NONE);
954
955         TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
956         TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
957
958         if (set == 1) {
959                 trace_mask |= mask;
960
961                 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
962                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
963                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_BO");
964                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
965                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
966                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
967                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE");
968                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
969                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
970         } else if (set == 0) {
971                 trace_mask &= ~mask;
972
973                 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
974                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
975                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_BO");
976                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
977                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
978                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
979                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE");
980                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
981                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
982         } else {
983                 TBM_WRN("set value is wrong.(set=%d)", set);
984         }
985
986         _tbm_bufmgr_mutex_unlock();
987 }
988
989 void
990 tbm_bufmgr_debug_dump_set_scale(double scale)
991 {
992         pthread_mutex_lock(&gLock);
993         _tbm_set_last_result(TBM_ERROR_NONE);
994         scale_factor = scale;
995         pthread_mutex_unlock(&gLock);
996 }
997
998 int
999 tbm_bufmgr_debug_get_ref_count(void)
1000 {
1001         int refcnt;
1002
1003         pthread_mutex_lock(&gLock);
1004
1005         _tbm_set_last_result(TBM_ERROR_NONE);
1006
1007         refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
1008
1009         pthread_mutex_unlock(&gLock);
1010
1011         return refcnt;
1012 }
1013
1014 int
1015 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
1016 {
1017         pthread_mutex_lock(&gLock);
1018         _tbm_set_last_result(TBM_ERROR_NONE);
1019
1020         if (onoff == 0) {
1021                 TBM_DBG("count=%d onoff=%d\n", count, onoff);
1022                 b_dump_queue = 0;
1023                 tbm_surface_internal_dump_end();
1024         } else {
1025                 int w, h;
1026
1027                 if (path == NULL) {
1028                         TBM_ERR("path is null");
1029                         pthread_mutex_unlock(&gLock);
1030                         return 0;
1031                 }
1032                 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
1033
1034                 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
1035                         TBM_ERR("Fail to get tbm_surface size.\n");
1036                         pthread_mutex_unlock(&gLock);
1037                         return 0;
1038                 }
1039
1040                 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1041                 scale_factor = 0;
1042
1043                 b_dump_queue = 1;
1044         }
1045
1046         pthread_mutex_unlock(&gLock);
1047
1048         return 1;
1049 }
1050
1051 int
1052 tbm_bufmgr_debug_dump_all(char *path)
1053 {
1054         int w, h, count = 0;
1055         tbm_surface_h surface = NULL;
1056
1057         pthread_mutex_lock(&gLock);
1058         _tbm_set_last_result(TBM_ERROR_NONE);
1059
1060         if (!path) {
1061                 TBM_ERR("path is null.\n");
1062                 pthread_mutex_unlock(&gLock);
1063                 return 0;
1064         }
1065
1066         TBM_DBG("path=%s\n", path);
1067
1068         count = _tbm_util_get_max_surface_size(&w, &h);
1069         if (count == 0) {
1070                 TBM_ERR("No tbm_surface.\n");
1071                 pthread_mutex_unlock(&gLock);
1072                 return 0;
1073         }
1074
1075         tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1076         scale_factor = 0;
1077
1078         LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1079                 tbm_surface_internal_dump_buffer(surface, "dump_all");
1080
1081         tbm_surface_internal_dump_end();
1082
1083         pthread_mutex_unlock(&gLock);
1084
1085         return 1;
1086 }
1087
1088 /* internal function */
1089 tbm_bufmgr
1090 _tbm_bufmgr_get_bufmgr(void)
1091 {
1092         return gBufMgr;
1093 }
1094
1095 int
1096 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1097 {
1098         int ret;
1099         tbm_error_e error;
1100
1101         _tbm_bufmgr_mutex_lock();
1102         _tbm_set_last_result(TBM_ERROR_NONE);
1103
1104         TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1105
1106         if (bufmgr->use_hal_tbm) {
1107                 error = (tbm_error_e)hal_tbm_bufmgr_bind_native_display(bufmgr->hal_bufmgr, (hal_tbm_native_display *)native_display);
1108                 if (error == TBM_ERROR_NOT_SUPPORTED) {
1109                         TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1110                         _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1111                         _tbm_bufmgr_mutex_unlock();
1112                         return 1;
1113                 } else if (error != TBM_ERROR_NONE) {
1114                         TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1115                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1116                         _tbm_bufmgr_mutex_unlock();
1117                         return 0;
1118                 }
1119         } else if (bufmgr->backend_module_data) {
1120                 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1121                         TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1122                                         bufmgr, native_display);
1123                         _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1124                         _tbm_bufmgr_mutex_unlock();
1125                         return 1;
1126                 }
1127
1128                 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1129                 if (error != TBM_ERROR_NONE) {
1130                         TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1131                                         bufmgr, native_display, error);
1132                         _tbm_set_last_result(error);
1133                         _tbm_bufmgr_mutex_unlock();
1134                         return 0;
1135                 }
1136                 ret = 1;
1137         } else {
1138                 if (!bufmgr->backend->bufmgr_bind_native_display) {
1139                         TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1140                                         bufmgr, native_display);
1141                         _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1142                         _tbm_bufmgr_mutex_unlock();
1143                         return 1;
1144                 }
1145
1146                 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1147                 if (!ret) {
1148                         TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1149                                         bufmgr, native_display);
1150                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1151                         _tbm_bufmgr_mutex_unlock();
1152                         return 0;
1153                 }
1154         }
1155
1156         TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1157
1158         _tbm_bufmgr_mutex_unlock();
1159
1160         return 1;
1161 }
1162
1163 tbm_bufmgr
1164 tbm_bufmgr_server_init(void)
1165 {
1166         tbm_bufmgr bufmgr;
1167
1168         bufmgr = _tbm_bufmgr_init(-1, 1);
1169
1170         return bufmgr;
1171 }
1172
1173 int
1174 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1175 {
1176         _tbm_bufmgr_mutex_lock();
1177         _tbm_set_last_result(TBM_ERROR_NONE);
1178
1179         TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1180         TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1181
1182         pthread_mutex_lock(&gLock);
1183         gBufMgr->bo_lock_type = bo_lock_type;
1184         pthread_mutex_unlock(&gLock);
1185
1186         TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1187
1188         _tbm_bufmgr_mutex_unlock();
1189
1190         return 1;
1191 }
1192
1193
1194 int tbm_bufmgr_get_fd_limit(void)
1195 {
1196         struct rlimit lim;
1197
1198         if (getrlimit(RLIMIT_NOFILE, &lim))
1199                 return 1024;
1200
1201         return (int)lim.rlim_cur;
1202 }
1203
1204 tbm_bufmgr tbm_bufmgr_get(void)
1205 {
1206         return gBufMgr;
1207 }
1208 /* LCOV_EXCL_STOP */