From d0e00c63d5f02aabc0a22ba952a64806fcab41ac Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 29 Feb 2016 16:31:41 +0900 Subject: [PATCH 01/16] enhance log Change-Id: Ica6faba6cf7144d6efd5991f7e08a436e85784bc --- src/tdm_display.c | 9 +++++++++ src/tdm_pp.c | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/tdm_display.c b/src/tdm_display.c index 36879f3..479f805 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -1042,6 +1042,15 @@ tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) return TDM_ERROR_NONE; } + TDM_INFO("layer info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)", + info->src_config.size.h, info->src_config.size.v, + info->src_config.pos.x, info->src_config.pos.y, + info->src_config.pos.w, info->src_config.pos.h, + FOURCC_STR(info->src_config.format), + info->dst_pos.x, info->dst_pos.y, + info->dst_pos.w, info->dst_pos.h, + info->transform); + ret = func_layer->layer_set_info(private_layer->layer_backend, info); pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 49430d8..3962bbe 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -176,6 +176,17 @@ tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info) return TDM_ERROR_NONE; } + TDM_INFO("pp info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%dx%d %d,%d %dx%d %c%c%c%c) trans(%d) sync(%d) flags(%x)", + info->src_config.size.h, info->src_config.size.v, + info->src_config.pos.x, info->src_config.pos.y, + info->src_config.pos.w, info->src_config.pos.h, + FOURCC_STR(info->src_config.format), + info->dst_config.size.h, info->dst_config.size.v, + info->dst_config.pos.x, info->dst_config.pos.y, + info->dst_config.pos.w, info->dst_config.pos.h, + FOURCC_STR(info->dst_config.format), + info->transform, info->sync, info->flags); + ret = func_pp->pp_set_info(private_pp->pp_backend, info); pthread_mutex_unlock(&private_display->lock); -- 2.7.4 From 0354da5856188a9fd6e394ad4ac6794ba312eda1 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 2 Mar 2016 09:45:37 +0900 Subject: [PATCH 02/16] fix dependency error for build-break Change-Id: Iffbda4fde6879f2fa258bf8f8821a76cceb592d9 --- configure.ac | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 3da1d84..c4b1a40 100644 --- a/configure.ac +++ b/configure.ac @@ -23,6 +23,16 @@ LT_INIT([disable-static]) # Enable quiet compiles on automake 1.11. m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +PKG_CHECK_MODULES(TTRACE, + [ttrace], + [have_ttrace="yes"], [have_ttrace="no"]) +if test "x$have_ttrace" = "xyes"; then + PKG_CHECK_MODULES(TDM, libtbm pthread-stubs libpng ttrace) + AC_DEFINE(HAVE_TTRACE, 1, [ttrace available]) +else + PKG_CHECK_MODULES(TDM, libtbm pthread-stubs libpng) +fi + PKG_CHECK_MODULES(TDM, libtbm pthread-stubs libpng) AC_SUBST(TDM_CFLAGS) AC_SUBST(TDM_LIBS) @@ -34,13 +44,6 @@ AC_ARG_WITH(tdm-module-path, AS_HELP_STRING([--with-tdm-module-path=PATH], [tdm [ TDM_MODULE_PATH="${DEFAULT_TDM_MODULE_PATH}" ]) AC_DEFINE_UNQUOTED(TDM_MODULE_PATH, "${TDM_MODULE_PATH}", [Directory for the modules of tdm]) -PKG_CHECK_MODULES(TTRACE, - [ttrace], - [have_ttrace="yes"], [have_ttrace="no"]) -if test "x$have_ttrace" = "xyes"; then - AC_DEFINE(HAVE_TTRACE, 1, [ttrace available]) -fi - # For enumerating devices in test case AC_SUBST(WARN_CFLAGS) AC_OUTPUT([ -- 2.7.4 From ff966f3f14a879b9dde736549ea662233b22f7ec Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 9 Mar 2016 13:27:31 +0900 Subject: [PATCH 03/16] enhance log for buffer debugging Change-Id: I0b5cda4cf5cb00e4ef3d000a8a16844db3b36e17 --- include/tdm_log.h | 1 + src/tdm.c | 7 +++++++ src/tdm_buffer.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tdm_capture.c | 25 ++++++++++++++++++++++ src/tdm_pp.c | 23 ++++++++++++++++++++ src/tdm_private.h | 11 ++++++++++ 6 files changed, 130 insertions(+) diff --git a/include/tdm_log.h b/include/tdm_log.h index 1952e2a..451bbf8 100644 --- a/include/tdm_log.h +++ b/include/tdm_log.h @@ -52,6 +52,7 @@ extern "C" { * @endcode */ extern int tdm_debug; +extern int tdm_debug_buffer; //#define TDM_CONFIG_DLOG #ifdef TDM_CONFIG_DLOG diff --git a/src/tdm.c b/src/tdm.c index 05f72c5..2933a23 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -500,6 +500,7 @@ tdm_display_update(tdm_display *dpy) #define DEFAULT_MODULE "libtdm-default"SUFFIX_MODULE int tdm_debug; +int tdm_debug_buffer; static tdm_private_display *g_private_display; static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER; @@ -736,6 +737,10 @@ tdm_display_init(tdm_error *error) if (debug && (strstr(debug, "1"))) tdm_debug = 1; + debug = getenv("TDM_DEBUG_BUFFER"); + if (debug && (strstr(debug, "1"))) + tdm_debug_buffer = 1; + private_display = calloc(1, sizeof(tdm_private_display)); if (!private_display) { ret = TDM_ERROR_OUT_OF_MEMORY; @@ -784,6 +789,7 @@ failed_mutex_init: free(private_display); failed_alloc: tdm_debug = 0; + tdm_debug_buffer = 0; if (error) *error = ret; pthread_mutex_unlock(&gLock); @@ -820,6 +826,7 @@ tdm_display_deinit(tdm_display *dpy) free(private_display); g_private_display = NULL; tdm_debug = 0; + tdm_debug_buffer = 0; pthread_mutex_unlock(&gLock); } diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 1385e18..33838df 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -60,6 +60,8 @@ typedef struct _tdm_buffer_info { struct list_head release_funcs; struct list_head destroy_funcs; + + struct list_head link; } tdm_buffer_info; static void @@ -84,6 +86,8 @@ _tdm_buffer_destroy_info(void *user_data) free(func_info); } + LIST_DEL(&buf_info->link); + free(buf_info); } @@ -106,6 +110,7 @@ _tdm_buffer_get_info(tbm_surface_h buffer) LIST_INITHEAD(&buf_info->release_funcs); LIST_INITHEAD(&buf_info->destroy_funcs); + LIST_INITHEAD(&buf_info->link); tbm_bo_add_user_data(bo, TDM_BUFFER_KEY, _tdm_buffer_destroy_info); tbm_bo_set_user_data(bo, TDM_BUFFER_KEY, buf_info); @@ -248,3 +253,61 @@ tdm_buffer_remove_destroy_handler(tbm_surface_h buffer, return; } } + +INTERN void +tdm_buffer_add_list(struct list_head *list, tbm_surface_h buffer) +{ + tdm_buffer_info *buf_info; + + TDM_RETURN_IF_FAIL(list != NULL); + TDM_RETURN_IF_FAIL(buffer != NULL); + + buf_info = _tdm_buffer_get_info(buffer); + TDM_RETURN_IF_FAIL(buf_info != NULL); + + if (buf_info->link.prev != buf_info->link.next) { + TDM_ERR("%p already added other list\n", buffer); + return; + } + + LIST_ADD(&buf_info->link, list); +} + +INTERN void +tdm_buffer_remove_list(struct list_head *list, tbm_surface_h buffer) +{ + tdm_buffer_info *buf_info, *b = NULL, *bb = NULL; + + TDM_RETURN_IF_FAIL(list != NULL); + + if (!buffer) + return; + + buf_info = _tdm_buffer_get_info(buffer); + TDM_RETURN_IF_FAIL(buf_info != NULL); + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, list, link) { + if (b == buf_info) { + LIST_DEL(&buf_info->link); + return; + } + } +} + +INTERN void +tdm_buffer_dump_list(struct list_head *list, char *str, int len) +{ + tdm_buffer_info *buf_info = NULL; + + TDM_RETURN_IF_FAIL(list != NULL); + + LIST_FOR_EACH_ENTRY(buf_info, list, link) { + if (len > 0) { + int l = snprintf(str, len, " %p", buf_info->buffer); + str += l; + len -= l; + } + else + break; + } +} diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 1bcbd1a..6c3fed6 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -68,6 +68,11 @@ _tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, lock_after_cb_done = 1; } + if (tdm_debug_buffer) + TDM_INFO("done: %p", buffer); + + tdm_buffer_remove_list(&private_capture->buffer_list, buffer); + tdm_buffer_unref_backend(buffer); if (lock_after_cb_done) @@ -126,6 +131,8 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, private_capture->private_layer = NULL; private_capture->capture_backend = capture_backend; + LIST_INITHEAD(&private_capture->buffer_list); + if (error) *error = TDM_ERROR_NONE; @@ -172,6 +179,8 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, private_capture->private_layer = private_layer; private_capture->capture_backend = capture_backend; + LIST_INITHEAD(&private_capture->buffer_list); + if (error) *error = TDM_ERROR_NONE; @@ -191,6 +200,13 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) func_capture = &private_capture->private_display->func_capture; func_capture->capture_destroy(private_capture->capture_backend); + if (!LIST_IS_EMPTY(&private_capture->buffer_list)) { + char str[256] = {0,}; + tdm_buffer_dump_list(&private_capture->buffer_list, str, 256); + if (strlen(str) > 0) + TDM_WRN("not finished: %s buffers", str); + } + free(private_capture); } @@ -248,6 +264,15 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer) tdm_buffer_ref_backend(buffer); ret = func_capture->capture_attach(private_capture->capture_backend, buffer); + if (ret == TDM_ERROR_NONE) + tdm_buffer_add_list(&private_capture->buffer_list, buffer); + + if (tdm_debug_buffer) { + char str[256] = {0,}; + tdm_buffer_dump_list(&private_capture->buffer_list, str, 256); + TDM_INFO("attached: %s", str); + } + pthread_mutex_unlock(&private_display->lock); return ret; diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 3962bbe..8294466 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -68,6 +68,11 @@ _tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, lock_after_cb_done = 1; } + if (tdm_debug_buffer) + TDM_INFO("done: %p", src); + + tdm_buffer_remove_list(&private_pp->buffer_list, src); + tdm_buffer_unref_backend(src); tdm_buffer_unref_backend(dst); @@ -123,6 +128,8 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) private_pp->private_display = private_display; private_pp->pp_backend = pp_backend; + LIST_INITHEAD(&private_pp->buffer_list); + if (error) *error = TDM_ERROR_NONE; @@ -143,6 +150,13 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) func_pp->pp_destroy(private_pp->pp_backend); + if (!LIST_IS_EMPTY(&private_pp->buffer_list)) { + char str[256] = {0,}; + tdm_buffer_dump_list(&private_pp->buffer_list, str, 256); + if (strlen(str) > 0) + TDM_WRN("not finished: %s buffers", str); + } + free(private_pp); } @@ -213,6 +227,15 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) tdm_buffer_ref_backend(dst); ret = func_pp->pp_attach(private_pp->pp_backend, src, dst); + if (ret == TDM_ERROR_NONE) + tdm_buffer_add_list(&private_pp->buffer_list, src); + + if (tdm_debug_buffer) { + char str[256] = {0,}; + tdm_buffer_dump_list(&private_pp->buffer_list, str, 256); + TDM_INFO("attached: %s", str); + } + pthread_mutex_unlock(&private_display->lock); return ret; diff --git a/src/tdm_private.h b/src/tdm_private.h index accb10f..9ac18ba 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -236,6 +236,8 @@ struct _tdm_private_pp { tdm_private_display *private_display; tdm_pp *pp_backend; + + struct list_head buffer_list; }; struct _tdm_private_capture { @@ -248,6 +250,8 @@ struct _tdm_private_capture { tdm_private_layer *private_layer; tdm_capture *capture_backend; + + struct list_head buffer_list; }; struct _tdm_private_vblank_handler { @@ -280,6 +284,13 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, void tdm_capture_destroy_internal(tdm_private_capture *private_capture); +void +tdm_buffer_add_list(struct list_head *list, tbm_surface_h buffer); +void +tdm_buffer_remove_list(struct list_head *list, tbm_surface_h buffer); +void +tdm_buffer_dump_list(struct list_head *list, char *str, int len); + #ifdef __cplusplus } #endif -- 2.7.4 From f5780960cf3931094a9b5b9a6efa99ffc5f1eaa6 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 9 Mar 2016 16:39:26 +0900 Subject: [PATCH 04/16] keep buffer_list in buf_info Change-Id: Ie987de6779a3ed63204d009cc4d68ffd6f4953a0 --- src/tdm_buffer.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 33838df..9b591f8 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -61,6 +61,7 @@ typedef struct _tdm_buffer_info { struct list_head release_funcs; struct list_head destroy_funcs; + struct list_head *list; struct list_head link; } tdm_buffer_info; @@ -86,7 +87,8 @@ _tdm_buffer_destroy_info(void *user_data) free(func_info); } - LIST_DEL(&buf_info->link); + if (buf_info->list) + LIST_DEL(&buf_info->link); free(buf_info); } @@ -265,33 +267,32 @@ tdm_buffer_add_list(struct list_head *list, tbm_surface_h buffer) buf_info = _tdm_buffer_get_info(buffer); TDM_RETURN_IF_FAIL(buf_info != NULL); - if (buf_info->link.prev != buf_info->link.next) { + if (buf_info->list) { TDM_ERR("%p already added other list\n", buffer); return; } + buf_info->list = list; LIST_ADD(&buf_info->link, list); } INTERN void tdm_buffer_remove_list(struct list_head *list, tbm_surface_h buffer) { - tdm_buffer_info *buf_info, *b = NULL, *bb = NULL; + tdm_buffer_info *buf_info; TDM_RETURN_IF_FAIL(list != NULL); - - if (!buffer) - return; + TDM_RETURN_IF_FAIL(buffer != NULL); buf_info = _tdm_buffer_get_info(buffer); TDM_RETURN_IF_FAIL(buf_info != NULL); - LIST_FOR_EACH_ENTRY_SAFE(b, bb, list, link) { - if (b == buf_info) { - LIST_DEL(&buf_info->link); - return; - } + if (buf_info->list != list) { + TDM_WRN("%p is not in %p list", buffer, list); + return; } + + LIST_DEL(&buf_info->link); } INTERN void -- 2.7.4 From d965db51a5ab55f3ac1d320677c32313274336dd Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 10 Mar 2016 22:37:51 +0900 Subject: [PATCH 05/16] fix TDM buffer management - enhance logs - use pending_list to rollback if commit is failed - increase buffer ref_count if commit is successed Change-Id: I6823202d9c1764c99d14378a1f37d55e47672c08 --- src/tdm_buffer.c | 99 +++++++++++++++++--------------------------- src/tdm_capture.c | 71 ++++++++++++++++++++++++-------- src/tdm_display.c | 95 ++++++++++++++++++++++++++++++------------ src/tdm_pp.c | 120 +++++++++++++++++++++++++++++++++++++++++++----------- src/tdm_private.h | 31 +++++++++++--- 5 files changed, 282 insertions(+), 134 deletions(-) diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 9b591f8..7ab6c21 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -52,27 +52,17 @@ typedef struct _tdm_buffer_func_info { struct list_head link; } tdm_buffer_func_info; -typedef struct _tdm_buffer_info { - tbm_surface_h buffer; - - /* ref_count for backend */ - int backend_ref_count; - - struct list_head release_funcs; - struct list_head destroy_funcs; - - struct list_head *list; - struct list_head link; -} tdm_buffer_info; - static void _tdm_buffer_destroy_info(void *user_data) { tdm_buffer_info *buf_info = (tdm_buffer_info *)user_data; tdm_buffer_func_info *func_info = NULL, *next = NULL; - if (buf_info->backend_ref_count > 0) + if (buf_info->backend_ref_count > 0) { TDM_NEVER_GET_HERE(); + if (tdm_debug_buffer) + TDM_INFO("%p", buf_info->buffer); + } LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) { LIST_DEL(&func_info->link); @@ -87,14 +77,14 @@ _tdm_buffer_destroy_info(void *user_data) free(func_info); } - if (buf_info->list) - LIST_DEL(&buf_info->link); + if (tdm_debug_buffer) + TDM_INFO("%p destroyed", buf_info->buffer); free(buf_info); } -static tdm_buffer_info * -_tdm_buffer_get_info(tbm_surface_h buffer) +tdm_buffer_info * +tdm_buffer_get_info(tbm_surface_h buffer) { tdm_buffer_info *buf_info = NULL; tbm_bo bo; @@ -116,6 +106,9 @@ _tdm_buffer_get_info(tbm_surface_h buffer) tbm_bo_add_user_data(bo, TDM_BUFFER_KEY, _tdm_buffer_destroy_info); tbm_bo_set_user_data(bo, TDM_BUFFER_KEY, buf_info); + + if (tdm_debug_buffer) + TDM_INFO("%p created", buf_info->buffer); } return buf_info; @@ -131,7 +124,7 @@ tdm_buffer_add_release_handler(tbm_surface_h buffer, TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); - buf_info = _tdm_buffer_get_info(buffer); + buf_info = tdm_buffer_get_info(buffer); TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY); func_info = calloc(1, sizeof(tdm_buffer_func_info)); @@ -155,7 +148,7 @@ tdm_buffer_remove_release_handler(tbm_surface_h buffer, TDM_RETURN_IF_FAIL(buffer != NULL); TDM_RETURN_IF_FAIL(func != NULL); - buf_info = _tdm_buffer_get_info(buffer); + buf_info = tdm_buffer_get_info(buffer); TDM_RETURN_IF_FAIL(buf_info != NULL); LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) { @@ -177,10 +170,11 @@ tdm_buffer_ref_backend(tbm_surface_h buffer) TDM_RETURN_VAL_IF_FAIL(buffer != NULL, NULL); - buf_info = _tdm_buffer_get_info(buffer); + buf_info = tdm_buffer_get_info(buffer); TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, NULL); buf_info->backend_ref_count++; + tbm_surface_internal_ref(buffer); return buffer; } @@ -193,19 +187,22 @@ tdm_buffer_unref_backend(tbm_surface_h buffer) TDM_RETURN_IF_FAIL(buffer != NULL); - buf_info = _tdm_buffer_get_info(buffer); + buf_info = tdm_buffer_get_info(buffer); TDM_RETURN_IF_FAIL(buf_info != NULL); buf_info->backend_ref_count--; - - if (buf_info->backend_ref_count > 0) + if (buf_info->backend_ref_count > 0) { + tbm_surface_internal_unref(buffer); return; + } LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) { tbm_surface_internal_ref(buffer); func_info->release_func(buffer, func_info->user_data); tbm_surface_internal_unref(buffer); } + + tbm_surface_internal_unref(buffer); } EXTERN tdm_error @@ -218,7 +215,7 @@ tdm_buffer_add_destroy_handler(tbm_surface_h buffer, TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); - buf_info = _tdm_buffer_get_info(buffer); + buf_info = tdm_buffer_get_info(buffer); TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY); func_info = calloc(1, sizeof(tdm_buffer_func_info)); @@ -242,7 +239,7 @@ tdm_buffer_remove_destroy_handler(tbm_surface_h buffer, TDM_RETURN_IF_FAIL(buffer != NULL); TDM_RETURN_IF_FAIL(func != NULL); - buf_info = _tdm_buffer_get_info(buffer); + buf_info = tdm_buffer_get_info(buffer); TDM_RETURN_IF_FAIL(buf_info != NULL); LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) { @@ -256,59 +253,37 @@ tdm_buffer_remove_destroy_handler(tbm_surface_h buffer, } } -INTERN void -tdm_buffer_add_list(struct list_head *list, tbm_surface_h buffer) +INTERN tbm_surface_h +tdm_buffer_list_get_first_entry(struct list_head *list) { - tdm_buffer_info *buf_info; - - TDM_RETURN_IF_FAIL(list != NULL); - TDM_RETURN_IF_FAIL(buffer != NULL); - - buf_info = _tdm_buffer_get_info(buffer); - TDM_RETURN_IF_FAIL(buf_info != NULL); - - if (buf_info->list) { - TDM_ERR("%p already added other list\n", buffer); - return; - } - - buf_info->list = list; - LIST_ADD(&buf_info->link, list); -} - -INTERN void -tdm_buffer_remove_list(struct list_head *list, tbm_surface_h buffer) -{ - tdm_buffer_info *buf_info; - - TDM_RETURN_IF_FAIL(list != NULL); - TDM_RETURN_IF_FAIL(buffer != NULL); + tdm_buffer_info *buf_info = NULL; - buf_info = _tdm_buffer_get_info(buffer); - TDM_RETURN_IF_FAIL(buf_info != NULL); + TDM_RETURN_VAL_IF_FAIL(list != NULL, NULL); - if (buf_info->list != list) { - TDM_WRN("%p is not in %p list", buffer, list); - return; - } + buf_info = container_of((list)->next, buf_info, link); - LIST_DEL(&buf_info->link); + return buf_info->buffer; } INTERN void -tdm_buffer_dump_list(struct list_head *list, char *str, int len) +tdm_buffer_list_dump(struct list_head *list) { tdm_buffer_info *buf_info = NULL; + char str[256], *p; + int len = sizeof (str); TDM_RETURN_IF_FAIL(list != NULL); + p = str; LIST_FOR_EACH_ENTRY(buf_info, list, link) { if (len > 0) { - int l = snprintf(str, len, " %p", buf_info->buffer); - str += l; + int l = snprintf(p, len, " %p", buf_info->buffer); + p += l; len -= l; } else break; } + + TDM_INFO("\t %s", str); } diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 6c3fed6..14ebc3d 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -57,9 +57,21 @@ _tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, { tdm_private_capture *private_capture = user_data; tdm_private_display *private_display = private_capture->private_display; + tdm_buffer_info *buf_info; + tbm_surface_h first_entry; int lock_after_cb_done = 0; int ret; + if (tdm_debug_buffer) + TDM_INFO("capture(%p) done: %p", private_capture, buffer); + + first_entry = tdm_buffer_list_get_first_entry(&private_capture->buffer_list); + if (first_entry != buffer) + TDM_ERR("%p is skipped", first_entry); + + if ((buf_info = tdm_buffer_get_info(buffer))) + LIST_DEL(&buf_info->link); + ret = pthread_mutex_trylock(&private_display->lock); if (ret == 0) pthread_mutex_unlock(&private_display->lock); @@ -68,11 +80,6 @@ _tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, lock_after_cb_done = 1; } - if (tdm_debug_buffer) - TDM_INFO("done: %p", buffer); - - tdm_buffer_remove_list(&private_capture->buffer_list, buffer); - tdm_buffer_unref_backend(buffer); if (lock_after_cb_done) @@ -117,7 +124,7 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, ret = func_capture->capture_set_done_handler(capture_backend, _tdm_caputre_cb_done, private_capture); if (ret != TDM_ERROR_NONE) { - TDM_ERR("set capture_done_handler failed"); + TDM_ERR("capture(%p) set capture_done_handler failed", private_capture); func_capture->capture_destroy(capture_backend); if (error) *error = ret; @@ -131,6 +138,7 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, private_capture->private_layer = NULL; private_capture->capture_backend = capture_backend; + LIST_INITHEAD(&private_capture->pending_buffer_list); LIST_INITHEAD(&private_capture->buffer_list); if (error) @@ -179,6 +187,7 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, private_capture->private_layer = private_layer; private_capture->capture_backend = capture_backend; + LIST_INITHEAD(&private_capture->pending_buffer_list); LIST_INITHEAD(&private_capture->buffer_list); if (error) @@ -191,6 +200,7 @@ INTERN void tdm_capture_destroy_internal(tdm_private_capture *private_capture) { tdm_func_capture *func_capture; + tdm_buffer_info *b = NULL, *bb = NULL; if (!private_capture) return; @@ -200,11 +210,20 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) func_capture = &private_capture->private_display->func_capture; func_capture->capture_destroy(private_capture->capture_backend); + if (!LIST_IS_EMPTY(&private_capture->pending_buffer_list)) { + TDM_ERR("capture(%p) not finished:", private_capture); + tdm_buffer_list_dump(&private_capture->pending_buffer_list); + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->pending_buffer_list, link) + LIST_DEL(&b->link); + } + if (!LIST_IS_EMPTY(&private_capture->buffer_list)) { - char str[256] = {0,}; - tdm_buffer_dump_list(&private_capture->buffer_list, str, 256); - if (strlen(str) > 0) - TDM_WRN("not finished: %s buffers", str); + TDM_ERR("capture(%p) not finished:", private_capture); + tdm_buffer_list_dump(&private_capture->buffer_list); + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->buffer_list, link) + LIST_DEL(&b->link); } free(private_capture); @@ -241,6 +260,7 @@ tdm_capture_set_info(tdm_capture *capture, tdm_info_capture *info) } ret = func_capture->capture_set_info(private_capture->capture_backend, info); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); pthread_mutex_unlock(&private_display->lock); @@ -261,16 +281,19 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer) return TDM_ERROR_NONE; } - tdm_buffer_ref_backend(buffer); ret = func_capture->capture_attach(private_capture->capture_backend, buffer); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - if (ret == TDM_ERROR_NONE) - tdm_buffer_add_list(&private_capture->buffer_list, buffer); + if (ret == TDM_ERROR_NONE) { + tdm_buffer_info *buf_info; - if (tdm_debug_buffer) { - char str[256] = {0,}; - tdm_buffer_dump_list(&private_capture->buffer_list, str, 256); - TDM_INFO("attached: %s", str); + if ((buf_info = tdm_buffer_get_info(buffer))) + LIST_ADDTAIL(&buf_info->link, &private_capture->pending_buffer_list); + + if (tdm_debug_buffer) { + TDM_INFO("capture(%p) attached:", private_capture); + tdm_buffer_list_dump(&private_capture->buffer_list); + } } pthread_mutex_unlock(&private_display->lock); @@ -281,6 +304,8 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer) EXTERN tdm_error tdm_capture_commit(tdm_capture *capture) { + tdm_buffer_info *b = NULL, *bb = NULL; + CAPTURE_FUNC_ENTRY(); pthread_mutex_lock(&private_display->lock); @@ -291,6 +316,18 @@ tdm_capture_commit(tdm_capture *capture) } ret = func_capture->capture_commit(private_capture->capture_backend); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); + + if (ret == TDM_ERROR_NONE) { + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->pending_buffer_list, link) { + LIST_DEL(&b->link); + tdm_buffer_ref_backend(b->buffer); + LIST_ADDTAIL(&b->link, &private_capture->buffer_list); + } + } else { + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->pending_buffer_list, link) + LIST_DEL(&b->link); + } pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_display.c b/src/tdm_display.c index 479f805..7f4857a 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -676,6 +676,11 @@ _tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, private_layer->showing_buffer = private_layer->waiting_buffer; private_layer->waiting_buffer = NULL; + + if (tdm_debug_buffer) + TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)", + private_layer, private_layer->waiting_buffer, + private_layer->showing_buffer); } if (commit_handler->func) { @@ -763,9 +768,7 @@ _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, ret = func_output->output_commit(private_output->output_backend, sync, commit_handler); - if (ret != TDM_ERROR_NONE) { - return ret; - } + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); if (!private_output->regist_commit_cb) { private_output->regist_commit_cb = 1; @@ -1042,8 +1045,8 @@ tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) return TDM_ERROR_NONE; } - TDM_INFO("layer info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)", - info->src_config.size.h, info->src_config.size.v, + TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)", + private_layer, info->src_config.size.h, info->src_config.size.v, info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h, FOURCC_STR(info->src_config.format), @@ -1052,6 +1055,7 @@ tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) info->transform); ret = func_layer->layer_set_info(private_layer->layer_backend, info); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); pthread_mutex_unlock(&private_display->lock); @@ -1086,6 +1090,7 @@ EXTERN tdm_error tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) { tdm_func_layer *func_layer; + LAYER_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER); @@ -1101,15 +1106,24 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) return TDM_ERROR_NONE; } - if (private_layer->waiting_buffer) { - pthread_mutex_unlock(&private_display->lock); - tdm_buffer_unref_backend(private_layer->waiting_buffer); - pthread_mutex_lock(&private_display->lock); - } + ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer); + if (ret == TDM_ERROR_NONE) { + /* FIXME: should save to pending_buffer first. And after committing + * successfully, need to move to waiting_buffer. + */ + if (private_layer->waiting_buffer) { + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->waiting_buffer); + pthread_mutex_lock(&private_display->lock); + } - ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer); + private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer); + if (tdm_debug_buffer) + TDM_INFO("layer(%p) waiting_buffer(%p)", + private_layer, private_layer->waiting_buffer); + } pthread_mutex_unlock(&private_display->lock); @@ -1131,6 +1145,10 @@ tdm_layer_unset_buffer(tdm_layer *layer) tdm_buffer_unref_backend(private_layer->waiting_buffer); pthread_mutex_lock(&private_display->lock); private_layer->waiting_buffer = NULL; + + if (tdm_debug_buffer) + TDM_INFO("layer(%p) waiting_buffer(%p)", + private_layer, private_layer->waiting_buffer); } if (private_layer->showing_buffer) { @@ -1138,6 +1156,10 @@ tdm_layer_unset_buffer(tdm_layer *layer) tdm_buffer_unref_backend(private_layer->showing_buffer); pthread_mutex_lock(&private_display->lock); private_layer->showing_buffer = NULL; + + if (tdm_debug_buffer) + TDM_INFO("layer(%p) showing_buffer(%p)", + private_layer, private_layer->showing_buffer); } private_layer->usable = 1; @@ -1148,6 +1170,7 @@ tdm_layer_unset_buffer(tdm_layer *layer) } ret = func_layer->layer_unset_buffer(private_layer->layer_backend); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); pthread_mutex_unlock(&private_display->lock); @@ -1174,26 +1197,34 @@ _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data) if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire( private_layer->buffer_queue, &surface) || surface == NULL) { - TDM_ERR("tbm_surface_queue_acquire() failed surface:%p", surface); + TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p", + private_layer, surface); pthread_mutex_unlock(&private_display->lock); return; } - if (private_layer->waiting_buffer) { - pthread_mutex_unlock(&private_display->lock); - tdm_buffer_unref_backend(private_layer->waiting_buffer); - tbm_surface_queue_release(private_layer->buffer_queue, - private_layer->waiting_buffer); - pthread_mutex_lock(&private_display->lock); - } + ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - private_layer->waiting_buffer = tdm_buffer_ref_backend(surface); + if (ret == TDM_ERROR_NONE) { + if (private_layer->waiting_buffer) { + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->waiting_buffer); + tbm_surface_queue_release(private_layer->buffer_queue, + private_layer->waiting_buffer); + pthread_mutex_lock(&private_display->lock); + } + + private_layer->waiting_buffer = tdm_buffer_ref_backend(surface); - func_layer->layer_set_buffer(private_layer->layer_backend, surface); + if (tdm_debug_buffer) + TDM_INFO("layer(%p) waiting_buffer(%p)", + private_layer, private_layer->waiting_buffer); - ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL); - if (ret != TDM_ERROR_NONE) - TDM_ERR("_tdm_output_commit() is fail"); + ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL); + if (ret != TDM_ERROR_NONE) + TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer); + } pthread_mutex_unlock(&private_display->lock); } @@ -1252,6 +1283,10 @@ tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue) private_layer->waiting_buffer); private_layer->waiting_buffer = NULL; pthread_mutex_lock(&private_display->lock); + + if (tdm_debug_buffer) + TDM_INFO("layer(%p) waiting_buffer(%p)", + private_layer, private_layer->waiting_buffer); } private_layer->buffer_queue = buffer_queue; @@ -1283,6 +1318,10 @@ tdm_layer_unset_buffer_queue(tdm_layer *layer) private_layer->waiting_buffer); private_layer->waiting_buffer = NULL; pthread_mutex_lock(&private_display->lock); + + if (tdm_debug_buffer) + TDM_INFO("layer(%p) waiting_buffer(%p)", + private_layer, private_layer->waiting_buffer); } if (private_layer->showing_buffer) { @@ -1292,6 +1331,10 @@ tdm_layer_unset_buffer_queue(tdm_layer *layer) private_layer->showing_buffer); pthread_mutex_lock(&private_display->lock); private_layer->showing_buffer = NULL; + + if (tdm_debug_buffer) + TDM_INFO("layer(%p) showing_buffer(%p)", + private_layer, private_layer->showing_buffer); } tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue, NULL, NULL); @@ -1338,7 +1381,7 @@ tdm_layer_set_video_pos(tdm_layer *layer, int zpos) func_layer = &private_display->func_layer; if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) { - TDM_ERR("layer is not video layer"); + TDM_ERR("layer(%p) is not video layer", private_layer); pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_INVALID_PARAMETER; } diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 8294466..8f43860 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -57,9 +57,28 @@ _tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, { tdm_private_pp *private_pp = user_data; tdm_private_display *private_display = private_pp->private_display; + tdm_buffer_info *buf_info; + tbm_surface_h first_entry; int lock_after_cb_done = 0; int ret; + if (tdm_debug_buffer) + TDM_INFO("pp(%p) done: src(%p) dst(%p)", private_pp, src, dst); + + first_entry = tdm_buffer_list_get_first_entry(&private_pp->src_buffer_list); + if (first_entry != src) + TDM_ERR("src(%p) is skipped", first_entry); + + first_entry = tdm_buffer_list_get_first_entry(&private_pp->dst_buffer_list); + if (first_entry != dst) + TDM_ERR("dst(%p) is skipped", first_entry); + + if ((buf_info = tdm_buffer_get_info(src))) + LIST_DEL(&buf_info->link); + + if ((buf_info = tdm_buffer_get_info(dst))) + LIST_DEL(&buf_info->link); + ret = pthread_mutex_trylock(&private_display->lock); if (ret == 0) pthread_mutex_unlock(&private_display->lock); @@ -68,11 +87,6 @@ _tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, lock_after_cb_done = 1; } - if (tdm_debug_buffer) - TDM_INFO("done: %p", src); - - tdm_buffer_remove_list(&private_pp->buffer_list, src); - tdm_buffer_unref_backend(src); tdm_buffer_unref_backend(dst); @@ -117,7 +131,7 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) ret = func_pp->pp_set_done_handler(pp_backend, _tdm_pp_cb_done, private_pp); if (ret != TDM_ERROR_NONE) { - TDM_ERR("set pp_done_handler failed"); + TDM_ERR("spp(%p) et pp_done_handler failed", private_pp); func_pp->pp_destroy(pp_backend); if (error) *error = ret; @@ -128,7 +142,10 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) private_pp->private_display = private_display; private_pp->pp_backend = pp_backend; - LIST_INITHEAD(&private_pp->buffer_list); + LIST_INITHEAD(&private_pp->src_pending_buffer_list); + LIST_INITHEAD(&private_pp->dst_pending_buffer_list); + LIST_INITHEAD(&private_pp->src_buffer_list); + LIST_INITHEAD(&private_pp->dst_buffer_list); if (error) *error = TDM_ERROR_NONE; @@ -139,22 +156,50 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) INTERN void tdm_pp_destroy_internal(tdm_private_pp *private_pp) { + tdm_private_display *private_display; tdm_func_pp *func_pp; + tdm_buffer_info *b = NULL, *bb = NULL; if (!private_pp) return; - func_pp = &private_pp->private_display->func_pp; + private_display = private_pp->private_display; + func_pp = &private_display->func_pp; LIST_DEL(&private_pp->link); func_pp->pp_destroy(private_pp->pp_backend); - if (!LIST_IS_EMPTY(&private_pp->buffer_list)) { - char str[256] = {0,}; - tdm_buffer_dump_list(&private_pp->buffer_list, str, 256); - if (strlen(str) > 0) - TDM_WRN("not finished: %s buffers", str); + if (!LIST_IS_EMPTY(&private_pp->src_pending_buffer_list)) { + TDM_ERR("pp(%p) not finished:", private_pp); + tdm_buffer_list_dump(&private_pp->src_pending_buffer_list); + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_pending_buffer_list, link) + LIST_DEL(&b->link); + } + + if (!LIST_IS_EMPTY(&private_pp->dst_pending_buffer_list)) { + TDM_ERR("pp(%p) not finished:", private_pp); + tdm_buffer_list_dump(&private_pp->dst_pending_buffer_list); + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_pending_buffer_list, link) + LIST_DEL(&b->link); + } + + if (!LIST_IS_EMPTY(&private_pp->src_buffer_list)) { + TDM_ERR("pp(%p) not finished:", private_pp); + tdm_buffer_list_dump(&private_pp->src_buffer_list); + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_buffer_list, link) + LIST_DEL(&b->link); + } + + if (!LIST_IS_EMPTY(&private_pp->dst_buffer_list)) { + TDM_ERR("pp(%p) not finished:", private_pp); + tdm_buffer_list_dump(&private_pp->dst_buffer_list); + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_buffer_list, link) + LIST_DEL(&b->link); } free(private_pp); @@ -190,8 +235,8 @@ tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info) return TDM_ERROR_NONE; } - TDM_INFO("pp info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%dx%d %d,%d %dx%d %c%c%c%c) trans(%d) sync(%d) flags(%x)", - info->src_config.size.h, info->src_config.size.v, + TDM_INFO("pp(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%dx%d %d,%d %dx%d %c%c%c%c) trans(%d) sync(%d) flags(%x)", + private_pp, info->src_config.size.h, info->src_config.size.v, info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h, FOURCC_STR(info->src_config.format), @@ -202,6 +247,7 @@ tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info) info->transform, info->sync, info->flags); ret = func_pp->pp_set_info(private_pp->pp_backend, info); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); pthread_mutex_unlock(&private_display->lock); @@ -223,17 +269,23 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) return TDM_ERROR_NONE; } - tdm_buffer_ref_backend(src); - tdm_buffer_ref_backend(dst); ret = func_pp->pp_attach(private_pp->pp_backend, src, dst); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); + + if (ret == TDM_ERROR_NONE) { + tdm_buffer_info *buf_info; - if (ret == TDM_ERROR_NONE) - tdm_buffer_add_list(&private_pp->buffer_list, src); + if ((buf_info = tdm_buffer_get_info(src))) + LIST_ADDTAIL(&buf_info->link, &private_pp->src_pending_buffer_list); - if (tdm_debug_buffer) { - char str[256] = {0,}; - tdm_buffer_dump_list(&private_pp->buffer_list, str, 256); - TDM_INFO("attached: %s", str); + if ((buf_info = tdm_buffer_get_info(dst))) + LIST_ADDTAIL(&buf_info->link, &private_pp->dst_pending_buffer_list); + + if (tdm_debug_buffer) { + TDM_INFO("pp(%p) attached:", private_pp); + tdm_buffer_list_dump(&private_pp->src_pending_buffer_list); + tdm_buffer_list_dump(&private_pp->dst_pending_buffer_list); + } } pthread_mutex_unlock(&private_display->lock); @@ -244,6 +296,8 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) EXTERN tdm_error tdm_pp_commit(tdm_pp *pp) { + tdm_buffer_info *b = NULL, *bb = NULL; + PP_FUNC_ENTRY(); pthread_mutex_lock(&private_display->lock); @@ -254,6 +308,26 @@ tdm_pp_commit(tdm_pp *pp) } ret = func_pp->pp_commit(private_pp->pp_backend); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); + + if (ret == TDM_ERROR_NONE) { + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_pending_buffer_list, link) { + LIST_DEL(&b->link); + tdm_buffer_ref_backend(b->buffer); + LIST_ADDTAIL(&b->link, &private_pp->src_buffer_list); + } + + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_pending_buffer_list, link) { + LIST_DEL(&b->link); + tdm_buffer_ref_backend(b->buffer); + LIST_ADDTAIL(&b->link, &private_pp->dst_buffer_list); + } + } else { + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_pending_buffer_list, link) + LIST_DEL(&b->link); + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_pending_buffer_list, link) + LIST_DEL(&b->link); + } pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_private.h b/src/tdm_private.h index 9ac18ba..fb0f7ad 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -221,6 +221,7 @@ struct _tdm_private_layer { tdm_caps_layer caps; tdm_layer *layer_backend; + tbm_surface_h pending_buffer; tbm_surface_h waiting_buffer; tbm_surface_h showing_buffer; tbm_surface_queue_h buffer_queue; @@ -237,7 +238,10 @@ struct _tdm_private_pp { tdm_pp *pp_backend; - struct list_head buffer_list; + struct list_head src_pending_buffer_list; + struct list_head dst_pending_buffer_list; + struct list_head src_buffer_list; + struct list_head dst_buffer_list; }; struct _tdm_private_capture { @@ -251,6 +255,7 @@ struct _tdm_private_capture { tdm_capture *capture_backend; + struct list_head pending_buffer_list; struct list_head buffer_list; }; @@ -270,6 +275,19 @@ struct _tdm_private_commit_handler { void *user_data; }; +typedef struct _tdm_buffer_info { + tbm_surface_h buffer; + + /* ref_count for backend */ + int backend_ref_count; + + struct list_head release_funcs; + struct list_head destroy_funcs; + + struct list_head *list; + struct list_head link; +} tdm_buffer_info; + tdm_private_pp * tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error); void @@ -284,12 +302,13 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, void tdm_capture_destroy_internal(tdm_private_capture *private_capture); +/* utility buffer functions for private */ +tdm_buffer_info* +tdm_buffer_get_info(tbm_surface_h buffer); +tbm_surface_h +tdm_buffer_list_get_first_entry(struct list_head *list); void -tdm_buffer_add_list(struct list_head *list, tbm_surface_h buffer); -void -tdm_buffer_remove_list(struct list_head *list, tbm_surface_h buffer); -void -tdm_buffer_dump_list(struct list_head *list, char *str, int len); +tdm_buffer_list_dump(struct list_head *list); #ifdef __cplusplus } -- 2.7.4 From 64f82c3d1812f47bf5d04fcb3ea6e801b6098b2c Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 11 Mar 2016 13:34:12 +0900 Subject: [PATCH 06/16] install the license file Change-Id: I3e4c22abba4ad716e9c4d14cfc1ad1a0e15ead42 --- packaging/libtdm.spec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 43d4969..b06652b 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -23,6 +23,8 @@ Requires: pkgconfig(libtbm) %description devel This supports frontend & backend library header and so +%global TZ_SYS_RO_SHARE %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share} + %prep %setup -q cp %{SOURCE1001} . @@ -34,16 +36,21 @@ cp %{SOURCE1001} . make %{?_smp_mflags} %install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{TZ_SYS_RO_SHARE}/license +cp -af COPYING %{buildroot}/%{TZ_SYS_RO_SHARE}/license/%{name} %make_install +%remove_docs + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %files %manifest %{name}.manifest -%license COPYING %defattr(-,root,root,-) +%{TZ_SYS_RO_SHARE}/license/%{name} %{_libdir}/libtdm.so.* %files devel -- 2.7.4 From 66f7ca417b5fbe400b43d52cd8dd21b063c1be1c Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Mon, 14 Mar 2016 18:02:56 +0900 Subject: [PATCH 07/16] change deprecated APIs Change-Id: I82daf13d77b949e9bffb8db14df39f1efcda981d --- src/tdm_display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tdm_display.c b/src/tdm_display.c index 7f4857a..cbcf675 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -1290,10 +1290,10 @@ tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue) } private_layer->buffer_queue = buffer_queue; - tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue, + tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer); - tbm_surface_queue_set_destroy_cb(private_layer->buffer_queue, + tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer); pthread_mutex_unlock(&private_display->lock); @@ -1337,8 +1337,8 @@ tdm_layer_unset_buffer_queue(tdm_layer *layer) private_layer, private_layer->showing_buffer); } - tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue, NULL, NULL); - tbm_surface_queue_set_destroy_cb(private_layer->buffer_queue, NULL, NULL); + tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer); + tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer); private_layer->buffer_queue = NULL; private_layer->usable = 1; -- 2.7.4 From a95dc0ec22ee09e86f1164b1c861087007dadb85 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 16 Mar 2016 17:12:33 +0900 Subject: [PATCH 08/16] map/unmap for dump Change-Id: Ib91a52e7c3dbb95db719da201efe8a0d34a3d999 --- src/tdm_helper.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index dd57986..d4a0937 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -110,13 +110,14 @@ EXTERN void tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) { tbm_surface_info_s info; - int len; + int len, ret; const char *prefix; TDM_RETURN_IF_FAIL(buffer != NULL); TDM_RETURN_IF_FAIL(file != NULL); - tbm_surface_get_info(buffer, &info); + ret = tbm_surface_map(buffer, TBM_DEVICE_CPU, &info); + TDM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE); len = strnlen(file, 1024); if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) @@ -126,6 +127,7 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) if (strncmp(file + (len - 3), prefix, 3)) { TDM_ERR("can't dump to '%s' file", file + (len - 3)); + tbm_surface_unmap(buffer); return; } @@ -163,8 +165,11 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) break; default: TDM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR (info.format)); + tbm_surface_unmap(buffer); return; } + tbm_surface_unmap(buffer); + TDM_INFO("dump %s", file); } -- 2.7.4 From 152309540993deec16594de71fa7bac777d29e67 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 16 Mar 2016 19:06:18 +0900 Subject: [PATCH 09/16] return error if a buffer is attached twice We have to handle attaching a buffer twice as error. Display server should attach a buffer after finishing a previous converting. Change-Id: I98ee0a585af19f3a3009133f99a2c27b4e51b438 --- src/tdm_capture.c | 29 +++++++++++++++++++++++++++++ src/tdm_pp.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 14ebc3d..133de4b 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -51,6 +51,29 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. private_display = private_capture->private_display; \ func_capture = &private_display->func_capture +static tdm_error +_tdm_capture_check_if_exist(tdm_private_capture *private_capture, + tbm_surface_h buffer) +{ + tdm_buffer_info *buf_info = NULL; + + LIST_FOR_EACH_ENTRY(buf_info, &private_capture->buffer_list, link) { + if (buf_info->buffer == buffer) { + TDM_ERR("%p attached twice", buffer); + return TDM_ERROR_BAD_REQUEST; + } + } + + LIST_FOR_EACH_ENTRY(buf_info, &private_capture->pending_buffer_list, link) { + if (buf_info->buffer == buffer) { + TDM_ERR("%p attached twice", buffer); + return TDM_ERROR_BAD_REQUEST; + } + } + + return TDM_ERROR_NONE; +} + static void _tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *user_data) @@ -281,6 +304,12 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer) return TDM_ERROR_NONE; } + ret = _tdm_capture_check_if_exist(private_capture, buffer); + if (ret != TDM_ERROR_NONE) { + pthread_mutex_unlock(&private_display->lock); + return ret; + } + ret = func_capture->capture_attach(private_capture->capture_backend, buffer); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 8f43860..ad6f8a5 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -51,6 +51,43 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. private_display = private_pp->private_display; \ func_pp = &private_display->func_pp +static tdm_error +_tdm_pp_check_if_exist(tdm_private_pp *private_pp, + tbm_surface_h src, tbm_surface_h dst) +{ + tdm_buffer_info *buf_info = NULL; + + LIST_FOR_EACH_ENTRY(buf_info, &private_pp->src_buffer_list, link) { + if (buf_info->buffer == src) { + TDM_ERR("%p attached twice", src); + return TDM_ERROR_BAD_REQUEST; + } + } + + LIST_FOR_EACH_ENTRY(buf_info, &private_pp->src_pending_buffer_list, link) { + if (buf_info->buffer == src) { + TDM_ERR("%p attached twice", src); + return TDM_ERROR_BAD_REQUEST; + } + } + + LIST_FOR_EACH_ENTRY(buf_info, &private_pp->dst_buffer_list, link) { + if (buf_info->buffer == dst) { + TDM_ERR("%p attached twice", dst); + return TDM_ERROR_BAD_REQUEST; + } + } + + LIST_FOR_EACH_ENTRY(buf_info, &private_pp->dst_pending_buffer_list, link) { + if (buf_info->buffer == dst) { + TDM_ERR("%p attached twice", dst); + return TDM_ERROR_BAD_REQUEST; + } + } + + return TDM_ERROR_NONE; +} + static void _tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, void *user_data) @@ -269,6 +306,12 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) return TDM_ERROR_NONE; } + ret = _tdm_pp_check_if_exist(private_pp, src, dst); + if (ret != TDM_ERROR_NONE) { + pthread_mutex_unlock(&private_display->lock); + return ret; + } + ret = func_pp->pp_attach(private_pp->pp_backend, src, dst); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); -- 2.7.4 From 5c7c66a5a6ee83d0c8ed09cbe6159e2e4fb9d14e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 17 Mar 2016 09:04:22 +0900 Subject: [PATCH 10/16] fix syntax error Change-Id: I5fdb2e30bb3e0d1c664cfa14d881f067f5c3f04e --- src/tdm_helper.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index d4a0937..7c47b6e 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -140,26 +140,26 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) case TBM_FORMAT_YVU420: case TBM_FORMAT_YUV420: _tdm_helper_dump_raw(file, - info.planes[0].ptr + info.planes[0].offset, + info.planes[0].ptr, info.planes[0].stride * info.height, - info.planes[1].ptr + info.planes[1].offset, + info.planes[1].ptr, info.planes[1].stride * (info.height >> 1), - info.planes[2].ptr + info.planes[2].offset, + info.planes[2].ptr, info.planes[2].stride * (info.height >> 1)); break; case TBM_FORMAT_NV12: case TBM_FORMAT_NV21: _tdm_helper_dump_raw(file, - info.planes[0].ptr + info.planes[0].offset, + info.planes[0].ptr, info.planes[0].stride * info.height, - info.planes[1].ptr + info.planes[1].offset, + info.planes[1].ptr, info.planes[1].stride * (info.height >> 1), NULL, 0); break; case TBM_FORMAT_YUYV: case TBM_FORMAT_UYVY: _tdm_helper_dump_raw(file, - info.planes[0].ptr + info.planes[0].offset, + info.planes[0].ptr, info.planes[0].stride * info.height, NULL, 0, NULL, 0); break; -- 2.7.4 From 1291e14b597459fc5eb7f6ec19ab09e0a3837b50 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 17 Mar 2016 12:03:06 +0900 Subject: [PATCH 11/16] unref buffer when destroyed Change-Id: I71ed02cfe70569c25b175142c0420387e70825c1 --- src/tdm_capture.c | 13 +++++++++++-- src/tdm_pp.c | 24 ++++++++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 133de4b..a68739d 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -222,6 +222,7 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, INTERN void tdm_capture_destroy_internal(tdm_private_capture *private_capture) { + tdm_private_display *private_display = private_capture->private_display; tdm_func_capture *func_capture; tdm_buffer_info *b = NULL, *bb = NULL; @@ -237,16 +238,24 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) TDM_ERR("capture(%p) not finished:", private_capture); tdm_buffer_list_dump(&private_capture->pending_buffer_list); - LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->pending_buffer_list, link) + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->pending_buffer_list, link) { LIST_DEL(&b->link); + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(b->buffer); + pthread_mutex_lock(&private_display->lock); + } } if (!LIST_IS_EMPTY(&private_capture->buffer_list)) { TDM_ERR("capture(%p) not finished:", private_capture); tdm_buffer_list_dump(&private_capture->buffer_list); - LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->buffer_list, link) + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_capture->buffer_list, link) { LIST_DEL(&b->link); + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(b->buffer); + pthread_mutex_lock(&private_display->lock); + } } free(private_capture); diff --git a/src/tdm_pp.c b/src/tdm_pp.c index ad6f8a5..cd88f49 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -211,32 +211,48 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) TDM_ERR("pp(%p) not finished:", private_pp); tdm_buffer_list_dump(&private_pp->src_pending_buffer_list); - LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_pending_buffer_list, link) + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_pending_buffer_list, link) { LIST_DEL(&b->link); + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(b->buffer); + pthread_mutex_lock(&private_display->lock); + } } if (!LIST_IS_EMPTY(&private_pp->dst_pending_buffer_list)) { TDM_ERR("pp(%p) not finished:", private_pp); tdm_buffer_list_dump(&private_pp->dst_pending_buffer_list); - LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_pending_buffer_list, link) + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_pending_buffer_list, link) { LIST_DEL(&b->link); + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(b->buffer); + pthread_mutex_lock(&private_display->lock); + } } if (!LIST_IS_EMPTY(&private_pp->src_buffer_list)) { TDM_ERR("pp(%p) not finished:", private_pp); tdm_buffer_list_dump(&private_pp->src_buffer_list); - LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_buffer_list, link) + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->src_buffer_list, link) { LIST_DEL(&b->link); + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(b->buffer); + pthread_mutex_lock(&private_display->lock); + } } if (!LIST_IS_EMPTY(&private_pp->dst_buffer_list)) { TDM_ERR("pp(%p) not finished:", private_pp); tdm_buffer_list_dump(&private_pp->dst_buffer_list); - LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_buffer_list, link) + LIST_FOR_EACH_ENTRY_SAFE(b, bb, &private_pp->dst_buffer_list, link) { LIST_DEL(&b->link); + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(b->buffer); + pthread_mutex_lock(&private_display->lock); + } } free(private_pp); -- 2.7.4 From dd2dbae510435c393ca931ada29f5fdf3dc55f23 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 17 Mar 2016 13:03:52 +0900 Subject: [PATCH 12/16] fix syntax error Change-Id: If368fcb353e920ecb0f362c52c38c75dead52751 --- src/tdm_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 7ab6c21..9de916f 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -83,7 +83,7 @@ _tdm_buffer_destroy_info(void *user_data) free(buf_info); } -tdm_buffer_info * +INTERN tdm_buffer_info * tdm_buffer_get_info(tbm_surface_h buffer) { tdm_buffer_info *buf_info = NULL; -- 2.7.4 From 4494265fbbd8ec7a7bc811c88eb0e5f91a38e4e1 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 17 Mar 2016 13:58:22 +0900 Subject: [PATCH 13/16] fix doxygen document Change-Id: I588b867d55069ed8199bd24894d85fd51e850e7c --- doc/tdm_doc.h | 28 +++++++++++++++++++--------- include/tdm_backend.h | 14 +++++++------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/doc/tdm_doc.h b/doc/tdm_doc.h index 9652b58..7d4c856 100644 --- a/doc/tdm_doc.h +++ b/doc/tdm_doc.h @@ -39,8 +39,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /** * @mainpage TDM * @author Boram Park, boram1288.park@samsung.com - * @date Dec 30, 2015 - * @version 1.0.0 + * @date Mar 17, 2016 + * @version 1.1.0 * @par Introduction * TDM stands for Tizen Display Manager. It's the display HAL layer for tizen * display server. It offers the frontend APIs(@ref tdm.h) for a frontend user @@ -69,20 +69,24 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * A backend module @b SHOULD define the global data symbol of which name is * @b "tdm_backend_module_data". TDM will read this symbol, @b "tdm_backend_module_data", * at the initial time and call init() function of #tdm_backend_module. - * A backend module at least @b SHOULD register the #tdm_func_display functions - * to a display object with #tdm_backend_register_func_display() function in initial time.\n + * A backend module at least @b SHOULD register the #tdm_func_display, + * #tdm_func_output, #tdm_func_layer functions to a display object via + * #tdm_backend_register_func_display(), #tdm_backend_register_func_output(), + * #tdm_backend_register_func_layer() functions in initial time.\n * @code #include - static tdm_func_display drm_func_display = - { + static tdm_func_display drm_func_display = { drm_display_get_capabilitiy, ... - drm_display_get_outputs, - ... + }; + + static tdm_func_output drm_func_output = { drm_output_get_capability, - drm_output_get_layers, ... + }; + + static tdm_func_layer drm_func_layer = { drm_layer_get_capability, ... }; @@ -98,6 +102,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ret = tdm_backend_register_func_display(dpy, &drm_func_display); if (ret != TDM_ERROR_NONE) goto failed; + ret = tdm_backend_register_func_output(dpy, &drm_func_output); + if (ret != TDM_ERROR_NONE) + goto failed; + ret = tdm_backend_register_func_layer(dpy, &drm_func_layer); + if (ret != TDM_ERROR_NONE) + goto failed; ... return (tdm_backend_data*)drm_data; } diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 775efcc..bc9d195 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -72,7 +72,7 @@ typedef struct _tdm_caps_display { /** * @brief The capabilities structure of a output object - * @see The output_get_capability() function of #tdm_func_display + * @see The output_get_capability() function of #tdm_func_output */ typedef struct _tdm_caps_output { char maker[TDM_NAME_LEN]; /**< The output maker */ @@ -103,7 +103,7 @@ typedef struct _tdm_caps_output { /** * @brief The capabilities structure of a layer object - * @see The layer_get_capability() function of #tdm_func_display + * @see The layer_get_capability() function of #tdm_func_layer */ typedef struct _tdm_caps_layer { tdm_layer_capability capabilities; /**< The capabilities of layer */ @@ -113,7 +113,7 @@ typedef struct _tdm_caps_layer { * GRAPHIC layers are non-changeable. The zpos of GRAPHIC layers starts * from 0. If there are 4 GRAPHIC layers, The zpos SHOULD be 0, 1, 2, 3.\n * But the zpos of VIDEO layer is changeable by layer_set_video_pos() function - * of #tdm_func_display. And The zpos of VIDEO layers is less than GRAPHIC + * of #tdm_func_layer. And The zpos of VIDEO layers is less than GRAPHIC * layers or more than GRAPHIC layers. * ie, ..., -2, -1, 4, 5, ... (if 0 <= GRAPHIC layer's zpos < 4). * The zpos of VIDEO layers is @b relative. It doesn't need to start @@ -521,7 +521,7 @@ typedef struct _tdm_func_layer { * @param[in] layer A layer object * @param[in] info The geometry information * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @see output_commit() function of #tdm_func_display + * @see output_commit() function of #tdm_func_output * @remark * A backend module would apply the geometry information when the output object * of a layer object is committed. @@ -541,7 +541,7 @@ typedef struct _tdm_func_layer { * @param[in] layer A layer object * @param[in] buffer A TDM buffer * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @see output_commit() function of #tdm_func_display + * @see output_commit() function of #tdm_func_output * @remark * A backend module would apply a TDM buffer when the output object * of a layer object is committed. @@ -689,8 +689,8 @@ typedef struct _tdm_func_capture { /** * @brief Destroy a capture object * @param[in] capture A capture object - * @see output_create_capture() function of #tdm_func_display - * @see layer_create_capture() function of #tdm_func_display + * @see output_create_capture() function of #tdm_func_output + * @see layer_create_capture() function of #tdm_func_layer */ void (*capture_destroy)(tdm_capture *capture); -- 2.7.4 From cc661633abc411e95f6abce78174c22dc57e61ef Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 6 Apr 2016 14:24:18 +0900 Subject: [PATCH 14/16] add TDM_LAYER_CAPABILITY_RESERVED_MEMORY Change-Id: I0a67874a6ff3345d83d02b9c325a58e3d4543cd2 --- include/tdm_types.h | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 include/tdm_types.h diff --git a/include/tdm_types.h b/include/tdm_types.h old mode 100644 new mode 100755 index 744e8f0..af69324 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -166,6 +166,7 @@ typedef enum { TDM_LAYER_CAPABILITY_SCALE = (1 << 8), /**< if a layer has scale capability */ TDM_LAYER_CAPABILITY_TRANSFORM = (1 << 9), /**< if a layer has transform capability */ TDM_LAYER_CAPABILITY_SCANOUT = (1 << 10), /**< if a layer allows a scanout buffer only */ + TDM_LAYER_CAPABILITY_RESEVED_MEMORY = (1 << 11), /**< if a layer allows a reserved buffer only */ } tdm_layer_capability; /** -- 2.7.4 From 47d129b17e0e94e997bd4c438c531a8f4f560bda Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 22 Mar 2016 21:55:45 +0900 Subject: [PATCH 15/16] Revert "add display_buffer_get_fd to TDM backend interface" This reverts commit 748a516c6f3f754be4ff0e32d21a0985839cbea1. Conflicts: include/tdm_backend.h src/tdm.c src/tdm_private.h Change-Id: Ida5296ea6fcc210cabb62361d416afca3cfbc691 --- include/tdm_backend.h | 10 ---------- src/tdm.c | 36 ------------------------------------ src/tdm_private.h | 2 -- 3 files changed, 48 deletions(-) diff --git a/include/tdm_backend.h b/include/tdm_backend.h index bc9d195..f240d41 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -288,16 +288,6 @@ typedef struct _tdm_func_display { tdm_error (*display_get_fd)(tdm_backend_data *bdata, int *fd); /** - * @brief Get the file descriptor for the memory-management framework of a backend module - * @param[in] bdata The backend module data - * @param[out] fd The fd of a backend module - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @see display_handle_events() function of #tdm_func_display - * This buffer fd will be passed to tbm_bufmgr_init. - */ - tdm_error (*display_get_buffer_fd)(tdm_backend_data *bdata, int *fd); - - /** * @brief Handle the events which happens on the fd of a backend module * @param[in] bdata The backend module data * @return #TDM_ERROR_NONE if success. Otherwise, error value. diff --git a/src/tdm.c b/src/tdm.c index 2933a23..a7451f1 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -451,33 +451,6 @@ failed_update: return ret; } -static tdm_error -_tdm_display_init_bufmgr(tdm_private_display *private_display) -{ - tdm_func_display *func_display = &private_display->func_display; - int buffer_fd = -1; - tdm_error ret; - - if (func_display->display_get_buffer_fd) { - ret = func_display->display_get_buffer_fd(private_display->bdata, &buffer_fd); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed to get buffer fd"); - return ret; - } - } - - private_display->bufmgr = tbm_bufmgr_init(buffer_fd); - if (!private_display->bufmgr) { - TDM_ERR("failed to init TBM bufmgr: fd(%d)", buffer_fd); - return TDM_ERROR_OUT_OF_MEMORY; - } - - TDM_INFO("init TBM bufmgr: fd(%d)", buffer_fd); - - return TDM_ERROR_NONE; -} - - EXTERN tdm_error tdm_display_update(tdm_display *dpy) { @@ -764,12 +737,6 @@ tdm_display_init(tdm_error *error) if (ret != TDM_ERROR_NONE) goto failed_update; - TDM_TRACE_BEGIN(Bufmgr_Init); - ret = _tdm_display_init_bufmgr(private_display); - TDM_TRACE_END(); - if (ret != TDM_ERROR_NONE) - goto failed_update; - private_display->init_count = 1; g_private_display = private_display; @@ -814,9 +781,6 @@ tdm_display_deinit(tdm_display *dpy) pthread_mutex_lock(&private_display->lock); - if (private_display->bufmgr) - tbm_bufmgr_deinit(private_display->bufmgr); - _tdm_display_destroy_private_display(private_display); _tdm_display_unload_module(private_display); diff --git a/src/tdm_private.h b/src/tdm_private.h index fb0f7ad..c1a34d0 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -187,8 +187,6 @@ struct _tdm_private_display { struct list_head pp_list; void **outputs_ptr; - - tbm_bufmgr bufmgr; }; struct _tdm_private_output { -- 2.7.4 From ff74e83997de9c11096c6c54074f0e64bfaede0c Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 21 Mar 2016 09:28:20 +0900 Subject: [PATCH 16/16] add tdm_helper_get_fd & tdm_helper_set_fd Change-Id: I07027116cf37fd312eda56c49b271b2f36575c8f --- include/tdm_helper.h | 27 ++++++++++++++++++++++++++ src/tdm.c | 3 +++ src/tdm_helper.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/include/tdm_helper.h b/include/tdm_helper.h index 86b6620..c329669 100644 --- a/include/tdm_helper.h +++ b/include/tdm_helper.h @@ -68,6 +68,33 @@ extern "C" { void tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file); +/** + * @brief Get a fd from the given enviroment variable. + * @details + * This function will dup the fd of the given enviroment variable. The Caller + * @b SHOULD close the fd. + * \n + * In DRM system, a drm-master-fd @b SHOULD be shared between TDM backend and + * TBM backend in display server side by using "TDM_DRM_MASTER_FD" + * and "TBM_DRM_MASTER_FD". + * @param[in] env The given enviroment variable + * @return fd if success. Otherwise, -1. + * @see #tdm_helper_set_fd() + */ +int tdm_helper_get_fd(const char *env); + +/** + * @brief Set the given fd to the give enviroment variable. + * @details + * In DRM system, a drm-master-fd @b SHOULD be shared between TDM backend and + * TBM backend in display server side by using "TDM_DRM_MASTER_FD" + * and "TBM_DRM_MASTER_FD". + * @param[in] env The given enviroment variable + * @param[in] fd The given fd + * @see #tdm_helper_get_fd() + */ +void tdm_helper_set_fd(const char *env, int fd); + #ifdef __cplusplus } #endif diff --git a/src/tdm.c b/src/tdm.c index a7451f1..1a02ef1 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -40,6 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tdm.h" #include "tdm_backend.h" #include "tdm_private.h" +#include "tdm_helper.h" static tdm_private_layer * _tdm_display_find_private_layer(tdm_private_output *private_output, @@ -784,6 +785,8 @@ tdm_display_deinit(tdm_display *dpy) _tdm_display_destroy_private_display(private_display); _tdm_display_unload_module(private_display); + tdm_helper_set_fd("TDM_DRM_MASTER_FD", -1); + pthread_mutex_unlock(&private_display->lock); pthread_mutex_destroy(&private_display->lock); diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 7c47b6e..311ea6e 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -173,3 +173,56 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) TDM_INFO("dump %s", file); } + +EXTERN int +tdm_helper_get_fd(const char *env) +{ + const char *value; + int fd, newfd, flags, ret; + + value = (const char*)getenv(env); + if (!value) + return -1; + + ret = sscanf(value, "%d", &fd); + if (ret < 0) { + TDM_ERR("sscanf failed: %m"); + return -1; + } + + flags = fcntl(fd, F_GETFD); + if (flags == -1) { + TDM_ERR("fcntl failed: %m"); + return -1; + } + + newfd = dup(fd); + if (newfd < 0) { + TDM_ERR("dup failed: %m"); + return -1; + } + + TDM_INFO("%s: fd(%d) newfd(%d)", env, fd, newfd); + + fcntl(newfd, F_SETFD, flags | FD_CLOEXEC); + + return newfd; +} + +EXTERN void +tdm_helper_set_fd(const char *env, int fd) +{ + char buf[32]; + int ret; + + snprintf(buf, sizeof(buf), "%d", fd); + + ret = setenv(env, (const char*)buf, 1); + if (ret) { + TDM_ERR("setenv failed: %m"); + return; + } + + if (fd >= 0) + TDM_INFO("%s: fd(%d)", env, fd); +} -- 2.7.4