tbm_bufmgr: use tbm_module_load/unload functions
[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 MAX_SIZE_N(dest)        (sizeof(dest) - strlen(dest) - 1)
59
60 /* check condition */
61 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
62         if (!(cond)) {\
63                 TBM_ERR("'%s' failed.\n", #cond);\
64                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
65                 _tbm_bufmgr_mutex_unlock();\
66                 return;\
67         } \
68 }
69
70 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
71         if (!(cond)) {\
72                 TBM_ERR("'%s' failed.\n", #cond);\
73                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
74                 _tbm_bufmgr_mutex_unlock();\
75                 return val;\
76         } \
77 }
78
79 /* LCOV_EXCL_START */
80
81 void
82 _tbm_bufmgr_mutex_lock(void)
83 {
84         pthread_mutex_lock(&tbm_bufmgr_lock);
85 }
86
87 void
88 _tbm_bufmgr_mutex_unlock(void)
89 {
90         pthread_mutex_unlock(&tbm_bufmgr_lock);
91 }
92
93 static int
94 _tbm_util_get_max_surface_size(int *w, int *h)
95 {
96         tbm_surface_info_s info;
97         tbm_surface_h surface = NULL;
98         int count = 0;
99
100         *w = 0;
101         *h = 0;
102
103         if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
104                 return count;
105
106         LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
107                 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
108                         count++;
109                         if (*w < info.width)
110                                 *w = info.width;
111                         if (*h < info.height)
112                                 *h = info.height;
113                 }
114         }
115
116         return count;
117 }
118
119 static void
120 _tbm_util_get_appname_brief(char *brief)
121 {
122         char delim[] = "/";
123         char *token = NULL;
124         char temp[255] = {0,};
125         char *saveptr = NULL;
126
127         token = strtok_r(brief, delim, &saveptr);
128
129         while (token != NULL) {
130                 memset(temp, 0x00, 255 * sizeof(char));
131                 strncpy(temp, token, 254 * sizeof(char));
132                 token = strtok_r(NULL, delim, &saveptr);
133         }
134
135         snprintf(brief, sizeof(temp), "%s", temp);
136 }
137
138 static void
139 _tbm_util_get_appname_from_pid(long pid, char *str)
140 {
141         char fn_cmdline[255] = {0, }, cmdline[255];
142         FILE *fp;
143         int len;
144
145         if (pid <= 0) return;
146
147         snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
148
149         fp = fopen(fn_cmdline, "r");
150         if (fp == 0) {
151                 TBM_ERR("cannot file open %s\n", fn_cmdline);
152                 return;
153         }
154
155         if (!fgets(cmdline, 255, fp)) {
156                 TBM_ERR("fail to get appname for pid(%ld)\n", pid);
157                 fclose(fp);
158                 return;
159         }
160
161         fclose(fp);
162
163         len = strlen(cmdline);
164         if (len < 1)
165                 memset(cmdline, 0x00, 255);
166         else
167                 cmdline[len] = 0;
168
169         snprintf(str, sizeof(cmdline), "%s", cmdline);
170 }
171
172 /* LCOV_EXCL_STOP */
173
174 static tbm_bufmgr
175 _tbm_bufmgr_init(int fd, int server)
176 {
177 #ifdef TBM_BUFMGR_INIT_TIME
178         struct timeval start_tv, end_tv;
179 #endif
180         char *env;
181
182 #ifdef TBM_BUFMGR_INIT_TIME
183         /* get the start tv */
184         gettimeofday(&start_tv, NULL);
185 #endif
186
187         bDlog = 1;
188
189         /* LCOV_EXCL_START */
190 #ifdef TRACE
191         env = getenv("TBM_TRACE");
192         if (env) {
193                 trace_mask = atoi(env);
194                 TBM_DBG("TBM_TRACE=%s\n", env);
195         } else
196                 trace_mask = 0;
197 #endif
198
199         pthread_mutex_lock(&gLock);
200
201         _tbm_set_last_result(TBM_ERROR_NONE);
202
203         if (fd >= 0) {
204                 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
205                 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
206         }
207
208
209         /* initialize buffer manager */
210         if (gBufMgr) {
211                 gBufMgr->ref_count++;
212                 TBM_DBG("reuse  tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
213                 pthread_mutex_unlock(&gLock);
214                 return gBufMgr;
215         }
216
217         TBM_DBG("bufmgr init\n");
218
219         /* allocate bufmgr */
220         gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
221         if (!gBufMgr) {
222                 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
223                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
224                 pthread_mutex_unlock(&gLock);
225                 return NULL;
226         }
227
228         gBufMgr->fd = fd;
229
230         /* set the display_server flag before loading the backend module */
231         if (server) {
232                 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
233                 gBufMgr->display_server = 1;
234         }
235
236         /* load bufmgr priv from env */
237         gBufMgr->module = tbm_module_load(gBufMgr, gBufMgr->fd);
238         if (!gBufMgr->module) {
239                 TBM_ERR("error : Fail to load bufmgr backend\n");
240                 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
241                 free(gBufMgr);
242                 gBufMgr = NULL;
243                 pthread_mutex_unlock(&gLock);
244                 return NULL;
245
246         }
247         /* LCOV_EXCL_STOP */
248
249         gBufMgr->ref_count = 1;
250
251         TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
252             gBufMgr, gBufMgr->ref_count);
253
254         /* setup the bo_lock_type */
255         env = getenv("BUFMGR_LOCK_TYPE");
256         if (env && !strcmp(env, "always"))
257                 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
258         else if (env && !strcmp(env, "none"))
259                 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
260         else if (env && !strcmp(env, "once"))
261                 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
262         else
263                 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
264
265         TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
266
267         /* intialize bo_list */
268         LIST_INITHEAD(&gBufMgr->bo_list);
269
270         /* intialize surf_list */
271         LIST_INITHEAD(&gBufMgr->surf_list);
272
273         /* intialize surf_queue_list */
274         LIST_INITHEAD(&gBufMgr->surf_queue_list);
275
276         /* intialize debug_key_list */
277         LIST_INITHEAD(&gBufMgr->debug_key_list);
278
279 #ifdef TBM_BUFMGR_INIT_TIME
280         /* get the end tv */
281         gettimeofday(&end_tv, NULL);
282         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)));
283 #endif
284
285         pthread_mutex_unlock(&gLock);
286
287         return gBufMgr;
288 }
289
290 tbm_bufmgr
291 tbm_bufmgr_init(int fd)
292 {
293         tbm_bufmgr bufmgr;
294
295         bufmgr = _tbm_bufmgr_init(fd, 0);
296
297         return bufmgr;
298 }
299
300 void
301 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
302 {
303         TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
304
305         _tbm_bufmgr_mutex_lock();
306         pthread_mutex_lock(&gLock);
307         _tbm_set_last_result(TBM_ERROR_NONE);
308
309         if (!gBufMgr) {
310                 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
311                 pthread_mutex_unlock(&gLock);
312                 _tbm_bufmgr_mutex_unlock();
313                 return;
314         }
315
316         bufmgr->ref_count--;
317         if (bufmgr->ref_count > 0) {
318                 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
319                 pthread_mutex_unlock(&gLock);
320                 _tbm_bufmgr_mutex_unlock();
321                 return;
322         }
323
324         /* destroy bo_list */
325         if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
326                 tbm_bo bo = NULL, tmp;
327
328                 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
329                         TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
330                         _tbm_bo_free(bo);
331                 }
332                 LIST_DELINIT(&bufmgr->bo_list);
333         }
334
335         /* destroy surf_list */
336         if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
337                 tbm_surface_h surf = NULL, tmp;
338
339                 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
340                         TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
341                         tbm_surface_destroy(surf);
342                 }
343                 LIST_DELINIT(&bufmgr->surf_list);
344         }
345
346         tbm_module_unload(bufmgr->module);
347
348         if (bufmgr->fd > 0)
349                 close(bufmgr->fd);
350
351         TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
352
353         free(bufmgr);
354         gBufMgr = NULL;
355
356         pthread_mutex_unlock(&gLock);
357         _tbm_bufmgr_mutex_unlock();
358 }
359
360 unsigned int
361 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
362 {
363         unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
364
365         _tbm_bufmgr_mutex_lock();
366         _tbm_set_last_result(TBM_ERROR_NONE);
367
368         TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
369         TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
370
371         capabilities = bufmgr->capabilities;
372
373         _tbm_bufmgr_mutex_unlock();
374
375         return capabilities;
376 }
377
378 /* LCOV_EXCL_START */
379 char *
380 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
381 {
382         char app_name[255] = {0,}, title[512] = {0,};
383         tbm_surface_debug_data *debug_old_data = NULL;
384         char *str;
385         int len = 1024*4;
386         int c = 0;
387         int size;
388         tbm_error_e error;
389         long pid = 0;
390
391         pthread_mutex_lock(&gLock);
392         _tbm_set_last_result(TBM_ERROR_NONE);
393
394         if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
395                 TBM_ERR("invalid bufmgr\n");
396                 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
397                 pthread_mutex_unlock(&gLock);
398                 return NULL;
399         }
400
401         str = malloc(len);
402         if (!str) {
403                 TBM_ERR("Fail to allocate the string.\n");
404                 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
405                 pthread_mutex_unlock(&gLock);
406                 return NULL;
407         }
408
409         TBM_SNRPRINTF(str, len, c, "\n");
410         pid = syscall(SYS_getpid);
411         _tbm_util_get_appname_from_pid(pid, app_name);
412         _tbm_util_get_appname_brief(app_name);
413         TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
414                   app_name, pid);
415
416         snprintf(title, 255, "%s", "no  surface     refcnt  width  height  bpp  size    n_b  n_p  flags    format    app_name              ");
417
418         if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
419                 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
420                         strncat(title, "  ", MAX_SIZE_N(title));
421                         strncat(title, debug_old_data->key, MAX_SIZE_N(title));
422                 }
423         }
424
425         TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
426         TBM_SNRPRINTF(str, len, c, "%s\n", title);
427
428         /* show the tbm_surface information in surf_list */
429         if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
430                 tbm_surface_h surf = NULL;
431                 int surf_cnt = 0;
432
433                 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
434                         char data[512] = {0,};
435                         unsigned int surf_pid = 0;
436                         int i;
437
438                         surf_pid = _tbm_surface_internal_get_debug_pid(surf);
439                         if (!surf_pid) {
440                                 /* if pid is null, set the self_pid */
441                                 surf_pid = syscall(SYS_getpid);;
442                         }
443
444                         memset(app_name, 0x0, 255 * sizeof(char));
445                         if (geteuid() == 0) {
446                                 _tbm_util_get_appname_from_pid(surf_pid, app_name);
447                                 _tbm_util_get_appname_brief(app_name);
448                         } else {
449                                 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
450                         }
451
452                         snprintf(data, 255, "%-3d %-11p   %-5d %-6u %-7u %-4u %-7u  %-3d  %-3d %-8d %-9s %-22s",
453                                   ++surf_cnt,
454                                   surf,
455                                   surf->refcnt,
456                                   surf->info.width,
457                                   surf->info.height,
458                                   surf->info.bpp,
459                                   surf->info.size / 1024,
460                                   surf->num_bos,
461                                   surf->num_planes,
462                                   surf->flags,
463                                   _tbm_surface_internal_format_to_str(surf->info.format) + 11,
464                                   app_name);
465
466                         if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
467                                 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
468                                         char *value;
469
470                                         strncat(data, "  ", MAX_SIZE_N(title));
471
472                                         value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
473                                         if (value)
474                                                 strncat(data, value, MAX_SIZE_N(title));
475                                         else
476                                                 strncat(data, "none", MAX_SIZE_N(title));
477                                 }
478                         }
479                         TBM_SNRPRINTF(str, len, c, "%s\n", data);
480
481                         for (i = 0; i < surf->num_bos; i++) {
482                                 if (bufmgr->use_hal_tbm) {
483                                         size = hal_tbm_bo_get_size((hal_tbm_bo *)surf->bos[i]->bo_data, (hal_tbm_error *)&error);
484                                         if (error != TBM_ERROR_NONE)
485                                                 TBM_WRN("fail to get the size of bo.");
486                                 } else if (bufmgr->backend_module_data) {
487                                         size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
488                                         if (error != TBM_ERROR_NONE)
489                                                 TBM_WRN("fail to get the size of bo.");
490                                 } else
491                                         size = bufmgr->backend->bo_size(surf->bos[i]);
492                                 TBM_SNRPRINTF(str, len, c, " bo:%-12p  %-26d%-10d\n",
493                                           surf->bos[i],
494                                           surf->bos[i]->ref_cnt,
495                                           size / 1024);
496                         }
497                 }
498         } else
499                 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
500         TBM_SNRPRINTF(str, len, c, "\n");
501
502         TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
503         TBM_SNRPRINTF(str, len, c, "no  bo          refcnt  size    lock_cnt  map_cnt  flags   surface     name\n");
504
505         /* show the tbm_bo information in bo_list */
506         if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
507                 int bo_cnt = 0;
508                 tbm_bo bo = NULL;
509                 tbm_key key = 0;
510
511                 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
512                         if (bo->bufmgr->use_hal_tbm) {
513                                 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
514                                 if (error != TBM_ERROR_NONE)
515                                         TBM_WRN("fail to get the size of bo.");
516                                 key = (tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
517                         } else if (bufmgr->backend_module_data) {
518                                 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
519                                 if (error != TBM_ERROR_NONE)
520                                         TBM_WRN("fail to get the size of bo.");
521                                 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
522                                 if (error != TBM_ERROR_NONE)
523                                         TBM_WRN("fail to get the tdm_key of bo.");
524                         } else {
525                                 size = bufmgr->backend->bo_size(bo);
526                                 key = bufmgr->backend->bo_export(bo);
527                         }
528                         TBM_SNRPRINTF(str, len, c, "%-3d %-11p   %-5d %-7d    %-6d    %-5u %-7d %-11p  %-4d\n",
529                                   ++bo_cnt,
530                                   bo,
531                                   bo->ref_cnt,
532                                   size / 1024,
533                                   bo->lock_cnt,
534                                   bo->map_cnt,
535                                   bo->flags,
536                                   bo->surface,
537                                   key);
538                 }
539         } else
540                 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
541         TBM_SNRPRINTF(str, len, c, "\n");
542
543         TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
544
545         pthread_mutex_unlock(&gLock);
546
547         return str;
548 }
549
550 void
551 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
552 {
553         char * str;
554         str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
555         if (str) {
556                 TBM_DBG("       %s", str);
557                 free(str);
558         }
559 }
560
561 void
562 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
563 {
564         _tbm_bufmgr_mutex_lock();
565         _tbm_set_last_result(TBM_ERROR_NONE);
566
567         TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
568         TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
569
570 #ifdef TRACE
571         TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
572         bTrace = onoff;
573 #endif
574
575         _tbm_bufmgr_mutex_unlock();
576 }
577
578 void
579 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
580 {
581         _tbm_bufmgr_mutex_lock();
582         _tbm_set_last_result(TBM_ERROR_NONE);
583
584         TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
585         TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
586
587         if (set == 1) {
588                 trace_mask |= mask;
589
590                 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
591                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
592                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_BO");
593                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
594                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
595                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
596                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE");
597                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
598                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
599         } else if (set == 0) {
600                 trace_mask &= ~mask;
601
602                 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
603                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
604                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_BO");
605                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
606                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
607                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
608                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE");
609                 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
610                         TBM_INFO("  TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
611         } else {
612                 TBM_WRN("set value is wrong.(set=%d)", set);
613         }
614
615         _tbm_bufmgr_mutex_unlock();
616 }
617
618 void
619 tbm_bufmgr_debug_dump_set_scale(double scale)
620 {
621         pthread_mutex_lock(&gLock);
622         _tbm_set_last_result(TBM_ERROR_NONE);
623         scale_factor = scale;
624         pthread_mutex_unlock(&gLock);
625 }
626
627 int
628 tbm_bufmgr_debug_get_ref_count(void)
629 {
630         int refcnt;
631
632         pthread_mutex_lock(&gLock);
633
634         _tbm_set_last_result(TBM_ERROR_NONE);
635
636         refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
637
638         pthread_mutex_unlock(&gLock);
639
640         return refcnt;
641 }
642
643 int
644 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
645 {
646         pthread_mutex_lock(&gLock);
647         _tbm_set_last_result(TBM_ERROR_NONE);
648
649         if (onoff == 0) {
650                 TBM_DBG("count=%d onoff=%d\n", count, onoff);
651                 b_dump_queue = 0;
652                 tbm_surface_internal_dump_end();
653         } else {
654                 int w, h;
655
656                 if (path == NULL) {
657                         TBM_ERR("path is null");
658                         pthread_mutex_unlock(&gLock);
659                         return 0;
660                 }
661                 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
662
663                 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
664                         TBM_ERR("Fail to get tbm_surface size.\n");
665                         pthread_mutex_unlock(&gLock);
666                         return 0;
667                 }
668
669                 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
670                 scale_factor = 0;
671
672                 b_dump_queue = 1;
673         }
674
675         pthread_mutex_unlock(&gLock);
676
677         return 1;
678 }
679
680 int
681 tbm_bufmgr_debug_dump_all(char *path)
682 {
683         int w, h, count = 0;
684         tbm_surface_h surface = NULL;
685
686         pthread_mutex_lock(&gLock);
687         _tbm_set_last_result(TBM_ERROR_NONE);
688
689         if (!path) {
690                 TBM_ERR("path is null.\n");
691                 pthread_mutex_unlock(&gLock);
692                 return 0;
693         }
694
695         TBM_DBG("path=%s\n", path);
696
697         count = _tbm_util_get_max_surface_size(&w, &h);
698         if (count == 0) {
699                 TBM_ERR("No tbm_surface.\n");
700                 pthread_mutex_unlock(&gLock);
701                 return 0;
702         }
703
704         tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
705         scale_factor = 0;
706
707         LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
708                 tbm_surface_internal_dump_buffer(surface, "dump_all");
709
710         tbm_surface_internal_dump_end();
711
712         pthread_mutex_unlock(&gLock);
713
714         return 1;
715 }
716
717 /* internal function */
718 tbm_bufmgr
719 _tbm_bufmgr_get_bufmgr(void)
720 {
721         return gBufMgr;
722 }
723
724 int
725 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
726 {
727         int ret;
728         tbm_error_e error;
729
730         _tbm_bufmgr_mutex_lock();
731         _tbm_set_last_result(TBM_ERROR_NONE);
732
733         TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
734
735         if (bufmgr->use_hal_tbm) {
736                 if (hal_tbm_backend_has_drm_device(bufmgr->hal_backend, &ret)) {
737                         int fd = tbm_drm_helper_get_fd(); // this must be the auth drm_fd.(master drm_fd);
738                         if (fd < -1) {
739                                 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
740                                 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
741                                 _tbm_bufmgr_mutex_unlock();
742                                 return 0;
743                         }
744
745                         // make the wayland server socket for sending the authenticated drm_fd to wayland clients.
746                         if (!tbm_drm_helper_wl_auth_server_init(native_display, fd, NULL, 0)) {
747                                 TBM_ERR("error: tbm_drm_helper_wl_auth_server_init failed\n", bufmgr, native_display);
748                                 close(fd);
749                                 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
750                                 _tbm_bufmgr_mutex_unlock();
751                                 return 0;
752                         }
753                         TBM_INFO("tbm creates a wayland socket for authentication of drm_fd.");
754
755                         bufmgr->auth_wl_socket_created = 1;
756                         bufmgr->auth_fd = fd;
757                 }
758         } else if (bufmgr->backend_module_data) {
759                 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
760                         TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
761                                         bufmgr, native_display);
762                         _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
763                         _tbm_bufmgr_mutex_unlock();
764                         return 1;
765                 }
766
767                 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
768                 if (error != TBM_ERROR_NONE) {
769                         TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
770                                         bufmgr, native_display, error);
771                         _tbm_set_last_result(error);
772                         _tbm_bufmgr_mutex_unlock();
773                         return 0;
774                 }
775                 ret = 1;
776         } else {
777                 if (!bufmgr->backend->bufmgr_bind_native_display) {
778                         TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
779                                         bufmgr, native_display);
780                         _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
781                         _tbm_bufmgr_mutex_unlock();
782                         return 1;
783                 }
784
785                 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
786                 if (!ret) {
787                         TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
788                                         bufmgr, native_display);
789                         _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
790                         _tbm_bufmgr_mutex_unlock();
791                         return 0;
792                 }
793         }
794
795         TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
796
797         _tbm_bufmgr_mutex_unlock();
798
799         return 1;
800 }
801
802 tbm_bufmgr
803 tbm_bufmgr_server_init(void)
804 {
805         tbm_bufmgr bufmgr;
806
807         bufmgr = _tbm_bufmgr_init(-1, 1);
808
809         return bufmgr;
810 }
811
812 int
813 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
814 {
815         _tbm_bufmgr_mutex_lock();
816         _tbm_set_last_result(TBM_ERROR_NONE);
817
818         TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
819         TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
820
821         pthread_mutex_lock(&gLock);
822         gBufMgr->bo_lock_type = bo_lock_type;
823         pthread_mutex_unlock(&gLock);
824
825         TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
826
827         _tbm_bufmgr_mutex_unlock();
828
829         return 1;
830 }
831
832
833 int tbm_bufmgr_get_fd_limit(void)
834 {
835         struct rlimit lim;
836
837         if (getrlimit(RLIMIT_NOFILE, &lim))
838                 return 1024;
839
840         return (int)lim.rlim_cur;
841 }
842
843 tbm_bufmgr tbm_bufmgr_get(void)
844 {
845         return gBufMgr;
846 }
847 /* LCOV_EXCL_STOP */