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