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