1 /**************************************************************************
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
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>
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:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
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.
30 **************************************************************************/
34 #include "tbm_bufmgr.h"
35 #include "tbm_bufmgr_int.h"
36 #include "tbm_drm_helper.h"
39 #include <sys/resource.h>
46 static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
47 static pthread_mutex_t tbm_bufmgr_lock = PTHREAD_MUTEX_INITIALIZER;
48 static double scale_factor = 0;
49 void _tbm_bufmgr_mutex_unlock(void);
50 static char *_tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, tbm_error_e *error);
52 //#define TBM_BUFMGR_INIT_TIME
54 #define MAX_SIZE_N(dest) (sizeof(dest) - strlen(dest) - 1)
57 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
59 TBM_ERR("'%s' failed.", #cond);\
60 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
61 _tbm_bufmgr_mutex_unlock();\
66 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
68 TBM_ERR("'%s' failed.", #cond);\
69 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
70 _tbm_bufmgr_mutex_unlock();\
75 #define TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(cond, val, error, error_type) {\
77 TBM_ERR("'%s' failed.", #cond);\
79 _tbm_bufmgr_mutex_unlock();\
87 _tbm_bufmgr_check_bo_cnt(tbm_bufmgr bufmgr)
89 static int last_chk_bo_cnt = 0;
91 tbm_error_e error = TBM_ERROR_NONE;
93 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
94 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
95 TBM_DBG("============TBM BO CNT DEBUG: bo_cnt=%d", bufmgr->bo_cnt);
96 str = _tbm_bufmgr_debug_tbm_info_get(bufmgr, &error);
102 last_chk_bo_cnt = bufmgr->bo_cnt;
107 _tbm_bufmgr_initialize_bo(tbm_bufmgr bufmgr, tbm_bo bo, int flags)
111 bo->magic = TBM_BO_MAGIC;
114 LIST_INITHEAD(&bo->user_data_list);
117 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
121 _tbm_bufmgr_mutex_lock(void)
123 pthread_mutex_lock(&tbm_bufmgr_lock);
127 _tbm_bufmgr_mutex_unlock(void)
129 pthread_mutex_unlock(&tbm_bufmgr_lock);
133 _tbm_util_get_max_surface_size(int *w, int *h)
135 tbm_surface_info_s info;
136 tbm_surface_h surface = NULL;
142 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
145 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
146 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
150 if (*h < info.height)
159 _tbm_util_get_appname_brief(char *brief)
163 char temp[255] = {0,};
164 char *saveptr = NULL;
166 token = strtok_r(brief, delim, &saveptr);
168 while (token != NULL) {
169 memset(temp, 0x00, 255 * sizeof(char));
170 strncpy(temp, token, 254 * sizeof(char));
171 token = strtok_r(NULL, delim, &saveptr);
174 snprintf(brief, sizeof(temp), "%s", temp);
178 _tbm_util_get_appname_from_pid(unsigned int pid, char *str)
180 char fn_cmdline[255] = {0, }, cmdline[255];
184 if (pid <= 0) return;
186 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%d/cmdline", pid);
188 fp = fopen(fn_cmdline, "r");
190 TBM_ERR("cannot file open %s", fn_cmdline);
194 if (!fgets(cmdline, 255, fp)) {
195 TBM_ERR("fail to get appname for pid(%d)", pid);
202 len = strlen(cmdline);
204 memset(cmdline, 0x00, 255);
208 snprintf(str, sizeof(cmdline), "%s", cmdline);
214 _tbm_bufmgr_init(int fd, int server)
216 tbm_error_e error = TBM_ERROR_NONE;
218 #ifdef TBM_BUFMGR_INIT_TIME
219 struct timeval start_tv, end_tv;
223 #ifdef TBM_BUFMGR_INIT_TIME
224 /* get the start tv */
225 gettimeofday(&start_tv, NULL);
228 /* LCOV_EXCL_START */
230 env = getenv("TBM_TRACE");
232 trace_mask = atoi(env);
233 TBM_DBG("TBM_TRACE=%s", env);
238 pthread_mutex_lock(&gLock);
240 _tbm_set_last_result(TBM_ERROR_NONE);
243 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.");
244 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).");
248 /* initialize buffer manager */
250 gBufMgr->ref_count++;
251 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
252 pthread_mutex_unlock(&gLock);
256 TBM_DBG("bufmgr init");
258 /* allocate bufmgr */
259 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
261 TBM_ERR("error: fail to alloc bufmgr fd(%d)", fd);
262 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
263 pthread_mutex_unlock(&gLock);
269 /* set the display_server flag before loading the backend module */
271 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.", gBufMgr);
272 gBufMgr->display_server = 1;
275 /* load bufmgr priv from env */
276 gBufMgr->module = tbm_module_load(gBufMgr->fd);
277 if (!gBufMgr->module) {
278 TBM_ERR("error : Fail to load bufmgr backend");
279 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
282 pthread_mutex_unlock(&gLock);
287 /* check the essential capabilities of tbm_module */
288 gBufMgr->capabilities = tbm_module_get_capabilities(gBufMgr->module, &error);
289 if (gBufMgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
290 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
291 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
292 tbm_module_unload(gBufMgr->module);
293 _tbm_set_last_result(error);
296 pthread_mutex_unlock(&gLock);
300 if (!(gBufMgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
301 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
302 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
303 tbm_module_unload(gBufMgr->module);
304 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
307 pthread_mutex_unlock(&gLock);
313 gBufMgr->ref_count = 1;
315 TBM_INFO("create tizen bufmgr:%p ref_count:%d",
316 gBufMgr, gBufMgr->ref_count);
318 /* setup the bo_lock_type */
319 env = getenv("BUFMGR_LOCK_TYPE");
320 if (env && !strcmp(env, "always"))
321 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
322 else if (env && !strcmp(env, "none"))
323 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
324 else if (env && !strcmp(env, "once"))
325 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
327 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
329 TBM_DBG("BUFMGR_LOCK_TYPE=%s", env ? env : "default:once");
331 /* intialize bo_list */
332 LIST_INITHEAD(&gBufMgr->bo_list);
334 /* intialize surf_list */
335 LIST_INITHEAD(&gBufMgr->surf_list);
337 /* intialize surf_queue_list */
338 LIST_INITHEAD(&gBufMgr->surf_queue_list);
340 /* intialize debug_key_list */
341 LIST_INITHEAD(&gBufMgr->debug_key_list);
343 #ifdef TBM_BUFMGR_INIT_TIME
345 gettimeofday(&end_tv, NULL);
346 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)));
349 pthread_mutex_unlock(&gLock);
355 tbm_bufmgr_init(int fd)
359 bufmgr = _tbm_bufmgr_init(fd, 0);
365 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
367 pthread_mutex_lock(&gLock);
368 _tbm_bufmgr_mutex_lock();
369 _tbm_set_last_result(TBM_ERROR_NONE);
371 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
372 TBM_ERR("TBM_BUFMGR_IS_VALID failed.");
373 _tbm_bufmgr_mutex_unlock();
374 pthread_mutex_unlock(&gLock);
379 TBM_ERR("gBufmgr already destroy: bufmgr:%p", bufmgr);
380 _tbm_bufmgr_mutex_unlock();
381 pthread_mutex_unlock(&gLock);
386 if (bufmgr->ref_count > 0) {
387 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)", bufmgr->ref_count, bufmgr);
388 _tbm_bufmgr_mutex_unlock();
389 pthread_mutex_unlock(&gLock);
393 /* destroy bo_list */
394 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
395 tbm_bo bo = NULL, tmp;
397 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
398 TBM_ERR("Un-freed bo(%p, ref:%d)", bo, bo->ref_cnt);
401 LIST_DELINIT(&bufmgr->bo_list);
404 /* destroy surf_list */
405 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
406 tbm_surface_h surf = NULL, tmp;
408 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
409 TBM_ERR("Un-freed surf(%p, ref:%d)", surf, surf->refcnt);
410 tbm_surface_destroy(surf);
412 LIST_DELINIT(&bufmgr->surf_list);
415 tbm_module_unload(bufmgr->module);
420 TBM_INFO("destroy tbm_bufmgr(%p)", bufmgr);
425 _tbm_bufmgr_mutex_unlock();
426 pthread_mutex_unlock(&gLock);
430 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
432 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
434 _tbm_bufmgr_mutex_lock();
435 _tbm_set_last_result(TBM_ERROR_NONE);
437 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
438 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
440 capabilities = bufmgr->capabilities;
442 _tbm_bufmgr_mutex_unlock();
447 /* LCOV_EXCL_START */
449 _tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, tbm_error_e *error)
451 char app_name[255] = {0,}, title[512] = {0,};
452 tbm_surface_debug_data *debug_old_data = NULL;
459 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
460 TBM_ERR("invalid bufmgr");
461 *error = TBM_ERROR_INVALID_PARAMETER;
467 TBM_ERR("Fail to allocate the string.");
468 *error = TBM_ERROR_OUT_OF_MEMORY;
472 TBM_SNRPRINTF(str, len, c, "\n");
473 pid = syscall(SYS_getpid);
474 _tbm_util_get_appname_from_pid(pid, app_name);
475 _tbm_util_get_appname_brief(app_name);
476 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
479 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
481 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
482 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
483 strncat(title, " ", MAX_SIZE_N(title));
484 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
488 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
489 TBM_SNRPRINTF(str, len, c, "%s\n", title);
491 /* show the tbm_surface information in surf_list */
492 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
493 tbm_surface_h surf = NULL;
496 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
497 char data[512] = {0,};
499 unsigned int t_pid = 0;
502 t_pid = _tbm_surface_internal_get_debug_pid(surf);
504 /* if pid is null, set the self_pid */
505 surf_pid = syscall(SYS_getpid);;
507 surf_pid = (long)t_pid;
509 memset(app_name, 0x0, 255 * sizeof(char));
510 if (geteuid() == 0) {
511 _tbm_util_get_appname_from_pid(surf_pid, app_name);
512 _tbm_util_get_appname_brief(app_name);
514 snprintf(app_name, sizeof(app_name), "%ld", surf_pid);
517 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
524 surf->info.size / 1024,
528 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
531 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
532 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
535 strncat(data, " ", MAX_SIZE_N(title));
537 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
539 strncat(data, value, MAX_SIZE_N(title));
541 strncat(data, "none", MAX_SIZE_N(title));
544 TBM_SNRPRINTF(str, len, c, "%s\n", data);
546 for (i = 0; i < surf->num_bos; i++) {
547 size = tbm_bo_data_get_size(surf->bos[i]->bo_data, error);
548 if (*error != TBM_ERROR_NONE)
549 TBM_WRN("fail to get the size of bo.");
550 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
552 surf->bos[i]->ref_cnt,
557 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
558 TBM_SNRPRINTF(str, len, c, "\n");
560 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
561 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
563 /* show the tbm_bo information in bo_list */
564 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
569 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
570 size = tbm_bo_data_get_size(bo->bo_data, error);
571 if (*error != TBM_ERROR_NONE)
572 TBM_WRN("fail to get the size of bo.");
573 key = tbm_bo_data_export_key(bo->bo_data, error);
574 if (*error != TBM_ERROR_NONE)
575 TBM_WRN("fail to get the tdm_key of bo.");
576 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
588 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
589 TBM_SNRPRINTF(str, len, c, "\n");
591 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
597 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
600 tbm_error_e error = TBM_ERROR_NONE;
602 pthread_mutex_lock(&gLock);
603 _tbm_set_last_result(TBM_ERROR_NONE);
605 str = _tbm_bufmgr_debug_tbm_info_get(bufmgr, &error);
607 TBM_ERR("tbm_bufmgr_internal_debug_tbm_info_get failed.");
608 _tbm_set_last_result(error);
609 pthread_mutex_unlock(&gLock);
613 _tbm_set_last_result(error);
614 pthread_mutex_unlock(&gLock);
620 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
623 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
631 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
633 _tbm_bufmgr_mutex_lock();
634 _tbm_set_last_result(TBM_ERROR_NONE);
636 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
637 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
640 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
644 _tbm_bufmgr_mutex_unlock();
648 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
650 _tbm_bufmgr_mutex_lock();
651 _tbm_set_last_result(TBM_ERROR_NONE);
653 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
654 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
659 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
660 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
661 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
662 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
663 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
664 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
665 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
666 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
667 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
668 } else if (set == 0) {
671 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
672 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
673 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
674 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
675 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
676 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
677 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
678 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
679 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
681 TBM_WRN("set value is wrong.(set=%d)", set);
684 _tbm_bufmgr_mutex_unlock();
688 tbm_bufmgr_debug_dump_set_scale(double scale)
690 pthread_mutex_lock(&gLock);
691 _tbm_set_last_result(TBM_ERROR_NONE);
692 scale_factor = scale;
693 pthread_mutex_unlock(&gLock);
697 tbm_bufmgr_debug_get_ref_count(void)
701 pthread_mutex_lock(&gLock);
703 _tbm_set_last_result(TBM_ERROR_NONE);
705 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
707 pthread_mutex_unlock(&gLock);
713 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
715 pthread_mutex_lock(&gLock);
716 _tbm_set_last_result(TBM_ERROR_NONE);
719 TBM_DBG("count=%d onoff=%d\n", count, onoff);
721 tbm_surface_internal_dump_end();
726 TBM_ERR("path is null");
727 pthread_mutex_unlock(&gLock);
730 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
732 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
733 TBM_ERR("Fail to get tbm_surface size.\n");
734 pthread_mutex_unlock(&gLock);
738 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
744 pthread_mutex_unlock(&gLock);
750 tbm_bufmgr_debug_dump_all(char *path)
753 tbm_surface_h surface = NULL;
755 pthread_mutex_lock(&gLock);
756 _tbm_set_last_result(TBM_ERROR_NONE);
759 TBM_ERR("path is null.\n");
760 pthread_mutex_unlock(&gLock);
764 TBM_DBG("path=%s\n", path);
766 count = _tbm_util_get_max_surface_size(&w, &h);
768 TBM_ERR("No tbm_surface.\n");
769 pthread_mutex_unlock(&gLock);
773 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
776 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
777 tbm_surface_internal_dump_buffer(surface, "dump_all");
779 tbm_surface_internal_dump_end();
781 pthread_mutex_unlock(&gLock);
786 /* internal function */
788 _tbm_bufmgr_get_bufmgr(void)
794 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
798 _tbm_bufmgr_mutex_lock();
799 _tbm_set_last_result(TBM_ERROR_NONE);
801 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
803 error = tbm_module_bind_native_display(bufmgr->module, native_display);
804 if (error != TBM_ERROR_NONE) {
805 _tbm_set_last_result(error);
806 _tbm_bufmgr_mutex_unlock();
808 if (error == TBM_ERROR_NOT_SUPPORTED) {
809 TBM_WRN("Not supported, so skip: tbm_bufmgr(%p) native_display(%p)", bufmgr, native_display);
816 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
818 _tbm_bufmgr_mutex_unlock();
824 tbm_bufmgr_server_init(void)
828 bufmgr = _tbm_bufmgr_init(-1, 1);
834 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
836 pthread_mutex_lock(&gLock);
837 _tbm_bufmgr_mutex_lock();
839 _tbm_set_last_result(TBM_ERROR_NONE);
841 TBM_GOTO_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), failed);
842 TBM_GOTO_VAL_IF_FAIL(bufmgr == gBufMgr, failed);
844 gBufMgr->bo_lock_type = bo_lock_type;
846 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
848 _tbm_bufmgr_mutex_unlock();
849 pthread_mutex_unlock(&gLock);
854 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
855 _tbm_bufmgr_mutex_unlock();
856 pthread_mutex_unlock(&gLock);
862 int tbm_bufmgr_get_fd_limit(void)
866 if (getrlimit(RLIMIT_NOFILE, &lim))
869 return (int)lim.rlim_cur;
872 tbm_bufmgr tbm_bufmgr_get(void)
879 tbm_bufmgr_internal_find_bo(tbm_bufmgr bufmgr, tbm_bo bo)
883 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
884 TBM_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
886 if (LIST_IS_EMPTY(&bufmgr->bo_list))
889 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
890 if (tbm_module_compare_bo_data(bufmgr->module, bo2->bo_data, bo->bo_data))
898 tbm_bufmgr_internal_alloc_bo(tbm_bufmgr bufmgr, int size, int flags)
900 tbm_error_e error = TBM_ERROR_NONE;
903 _tbm_bufmgr_mutex_lock();
905 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
906 TBM_BUFMGR_RETURN_VAL_IF_FAIL(size > 0, NULL);
908 _tbm_bufmgr_check_bo_cnt(bufmgr);
910 bo = calloc(1, sizeof(struct _tbm_bo));
912 TBM_ERR("memory allocationc failed.");
913 error = TBM_ERROR_OUT_OF_MEMORY;
917 bo->bo_data = tbm_module_alloc_bo_data(bufmgr->module, bo, size, flags, &error);
919 TBM_ERR("tbm_module_alloc_bo_data failed. size:%d flags:%s error:%d", size, _tbm_flag_to_str(flags), error);
921 _tbm_set_last_result(error);
922 _tbm_bufmgr_mutex_unlock();
926 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
928 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)", bo, size, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
930 _tbm_set_last_result(TBM_ERROR_NONE);
931 _tbm_bufmgr_mutex_unlock();
936 _tbm_set_last_result(error);
937 _tbm_bufmgr_mutex_unlock();
943 tbm_bufmgr_internal_alloc_bo_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
944 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
948 _tbm_bufmgr_mutex_lock();
950 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
952 _tbm_bufmgr_check_bo_cnt(bufmgr);
954 bo = calloc(1, sizeof(struct _tbm_bo));
956 TBM_ERR("memory allocationc failed.");
957 *error = TBM_ERROR_OUT_OF_MEMORY;
961 bo->bo_data = tbm_module_alloc_bo_data_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
967 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
969 _tbm_bufmgr_mutex_unlock();
974 _tbm_bufmgr_mutex_unlock();
980 tbm_bufmgr_internal_alloc_bo_with_bo_data(tbm_bufmgr bufmgr, tbm_bo_data *bo_data, int flags, tbm_error_e *error)
982 tbm_bo bo, bo2 = NULL;
984 _tbm_bufmgr_mutex_lock();
986 *error = TBM_ERROR_NONE;
988 TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
989 TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
991 _tbm_bufmgr_check_bo_cnt(bufmgr);
993 bo = calloc(1, sizeof(struct _tbm_bo));
995 TBM_ERR("memory allocationc failed.");
996 *error = TBM_ERROR_OUT_OF_MEMORY;
997 _tbm_bufmgr_mutex_unlock();
1000 bo->bo_data = bo_data;
1001 bo->get_from_surface_data = 1;
1003 // return an existed bo if the bo is already created with the same bo_data.
1004 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1009 _tbm_bufmgr_mutex_unlock();
1013 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1015 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
1017 _tbm_bufmgr_mutex_unlock();
1023 tbm_bufmgr_internal_import_bo_with_key(tbm_bufmgr bufmgr, unsigned int key)
1025 tbm_error_e error = TBM_ERROR_NONE;
1029 _tbm_bufmgr_mutex_lock();
1031 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1033 _tbm_bufmgr_check_bo_cnt(bufmgr);
1035 bo = calloc(1, sizeof(struct _tbm_bo));
1037 TBM_ERR("memory allocationc failed.");
1041 bo->bo_data = tbm_module_import_bo_data_with_key(bufmgr->module, bo, key, &error);
1043 TBM_ERR("tbm_module_import_bo_data_with_key failed. tbm_key:%d", key);
1048 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1049 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1051 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
1052 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
1056 _tbm_set_last_result(TBM_ERROR_NONE);
1057 _tbm_bufmgr_mutex_unlock();
1061 flags = tbm_bo_data_get_memory_types(bo->bo_data, &error);
1062 if (error != TBM_ERROR_NONE) {
1063 TBM_WRN("tbm_bo_data_get_memory_types filed. use the default flags:TBM_BO_DEFAULT.");
1064 flags = TBM_BO_DEFAULT;
1065 error = TBM_ERROR_NONE;
1068 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1070 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list",
1071 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
1073 _tbm_set_last_result(TBM_ERROR_NONE);
1074 _tbm_bufmgr_mutex_unlock();
1079 _tbm_set_last_result(error);
1080 _tbm_bufmgr_mutex_unlock();
1086 tbm_bufmgr_internal_import_bo_with_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1088 tbm_error_e error = TBM_ERROR_NONE;
1092 _tbm_bufmgr_mutex_lock();
1094 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1096 _tbm_bufmgr_check_bo_cnt(bufmgr);
1098 bo = calloc(1, sizeof(struct _tbm_bo));
1100 TBM_ERR("memory allocationc failed.");
1104 bo->bo_data = tbm_module_import_bo_data_with_fd(bufmgr->module, bo, fd, &error);
1106 TBM_ERR("tbm_module_import_bo_data_with_fd failed. tbm_fd:%d", fd);
1111 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1112 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1114 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
1115 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1119 _tbm_set_last_result(TBM_ERROR_NONE);
1120 _tbm_bufmgr_mutex_unlock();
1124 flags = tbm_bo_data_get_memory_types(bo->bo_data, &error);
1125 if (error != TBM_ERROR_NONE) {
1126 TBM_WRN("tbm_bo_data_get_memory_types filed. use the default flags:TBM_BO_DEFAULT.");
1127 flags = TBM_BO_DEFAULT;
1128 error = TBM_ERROR_NONE;
1131 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)",
1132 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1134 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1136 _tbm_set_last_result(TBM_ERROR_NONE);
1137 _tbm_bufmgr_mutex_unlock();
1142 _tbm_set_last_result(error);
1143 _tbm_bufmgr_mutex_unlock();
1149 tbm_bufmgr_internal_support_capabilites(tbm_bufmgr bufmgr, int capabilities)
1151 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1152 TBM_BUFMGR_RETURN_VAL_IF_FAIL(capabilities > 0, 0);
1154 _tbm_bufmgr_mutex_lock();
1156 // check if the bufmgr does not support capabilities at the same time.
1157 if (!(bufmgr->capabilities & capabilities)) {
1158 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1159 _tbm_bufmgr_mutex_unlock();
1163 _tbm_set_last_result(TBM_ERROR_NONE);
1164 _tbm_bufmgr_mutex_unlock();
1169 /* LCOV_EXCL_STOP */