From d7a3a75c32b83cc1859589e38ba5b1d0cb1a20ff Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 29 Jan 2018 09:54:16 +0900 Subject: [PATCH 01/16] output: using thread_cb Change-Id: I00fa06b60a2fa808df7a54d6739d1c4d8b3ae54e --- src/tdm.c | 54 +++--- src/tdm_macro.h | 3 +- src/tdm_output.c | 491 +++++++++++++++++++++--------------------------- src/tdm_private.h | 20 +- src/tdm_private_types.h | 34 +--- src/tdm_thread.c | 62 +----- 6 files changed, 263 insertions(+), 401 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 0213cb7..7fabc4a 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -61,9 +61,8 @@ _tdm_display_find_private_layer(tdm_private_output *private_output, return NULL; } -static tdm_private_output * -_tdm_display_find_private_output(tdm_private_display *private_display, - tdm_output *output_backend) +INTERN tdm_private_output * +tdm_display_find_private_output(tdm_private_display *private_display, tdm_output *output_backend) { tdm_private_output *private_output = NULL; @@ -75,7 +74,7 @@ _tdm_display_find_private_output(tdm_private_display *private_display, return NULL; } -INTERN tdm_private_output * +INTERN void * tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp) { tdm_private_output *private_output = NULL; @@ -135,8 +134,6 @@ _tdm_display_destroy_private_layer(tdm_private_layer *private_layer) { tdm_private_capture *c = NULL, *cc = NULL; - LIST_DEL(&private_layer->link); - tdm_layer_unset_buffer_internal(private_layer); LIST_FOR_EACH_ENTRY_SAFE(c, cc, &private_layer->capture_list, link) @@ -144,6 +141,11 @@ _tdm_display_destroy_private_layer(tdm_private_layer *private_layer) _tdm_display_destroy_caps_layer(&private_layer->caps); + /* when destroying layer, someone could check if layer is valid. So delete + * the layer's link at last. + */ + LIST_DEL(&private_layer->link); + free(private_layer); } @@ -154,13 +156,11 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) tdm_private_layer *l = NULL, *ll = NULL; tdm_private_hwc_window *hw = NULL, *hww = NULL; tdm_private_capture *c = NULL, *cc = NULL; - tdm_private_vblank_handler *v = NULL, *vv = NULL; + tdm_private_output_vblank_handler *v = NULL, *vv = NULL; tdm_private_output_commit_handler *om = NULL, *omm = NULL; tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL; tdm_private_output_change_handler *h = NULL, *hh = NULL; - LIST_DEL(&private_output->link); - free(private_output->layers_ptr); if (private_output->vblank_timeout_timer) @@ -186,13 +186,9 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) free(lm); } - LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) { - LIST_DEL(&h->link); - free(h); - } - - LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) { + LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list, link) { LIST_DEL(&h->link); + tdm_thread_cb_remove(h->private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, h); free(h); } @@ -221,12 +217,16 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) _tdm_display_destroy_caps_output(&private_output->caps); - if (private_output->dpms_changed_timer) - tdm_event_loop_source_remove(private_output->dpms_changed_timer); - + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_NEED_VALIDATE, NULL, + tdm_output_need_validate_handler_thread, NULL); tdm_event_loop_source_remove(private_output->need_validate.event_source); close(private_output->need_validate.event_fd); + /* when destroying output, vblank objects are also destroyed. vblank checks + * if output object is valid. So delete the output's link at last. + */ + LIST_DEL(&private_output->link); + private_output->stamp = 0; free(private_output); } @@ -401,7 +401,7 @@ tdm_display_update_output(tdm_private_display *private_display, int layer_count = 0, i; tdm_error ret; - private_output = _tdm_display_find_private_output(private_display, output_backend); + private_output = tdm_display_find_private_output(private_display, output_backend); if (!private_output) { private_output = calloc(1, sizeof(tdm_private_output)); TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_OUT_OF_MEMORY); @@ -425,8 +425,7 @@ tdm_display_update_output(tdm_private_display *private_display, LIST_INITHEAD(&private_output->output_commit_handler_list); LIST_INITHEAD(&private_output->layer_commit_handler_list); LIST_INITHEAD(&private_output->pending_commit_handler_list); - LIST_INITHEAD(&private_output->change_handler_list_main); - LIST_INITHEAD(&private_output->change_handler_list_sub); + LIST_INITHEAD(&private_output->change_handler_list); if (func_output->output_set_status_handler) { func_output->output_set_status_handler(private_output->output_backend, @@ -976,6 +975,10 @@ tdm_display_init(tdm_error *error) TDM_INFO("event loop init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; + ret = tdm_output_init(private_display); + if (ret != TDM_ERROR_NONE) + goto failed_load; + ret = tdm_pp_init(private_display); if (ret != TDM_ERROR_NONE) goto failed_load; @@ -1100,11 +1103,16 @@ tdm_display_deinit(tdm_display *dpy) */ _pthread_mutex_lock(&private_display->lock); tdm_event_loop_stop(private_display); + tdm_event_loop_deinit(private_display); + _pthread_mutex_unlock(&private_display->lock); + + /* when private_output is destroyed, all vblank resources of client and server + * are destroyed. Then we can call tdm_vblank_deinit. After destroying display, + * we can unload backend modulues. + */ _tdm_display_destroy_private_display(private_display); _tdm_display_unload_module(private_display); - _pthread_mutex_unlock(&private_display->lock); - tdm_event_loop_deinit(private_display); tdm_vblank_deinit(private_display); #ifdef INIT_BUFMGR diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 77538a3..98f25b4 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -236,8 +236,7 @@ static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_NONE, "none" }, { TDM_THREAD_CB_OUTPUT_COMMIT, "output-commit" }, { TDM_THREAD_CB_OUTPUT_VBLANK, "output-vblank" }, - { TDM_THREAD_CB_OUTPUT_STATUS, "output-status" }, - { TDM_THREAD_CB_OUTPUT_DPMS, "output-dpms" }, + { TDM_THREAD_CB_OUTPUT_CHANGE, "output-change" }, { TDM_THREAD_CB_PP_DONE, "pp-done" }, { TDM_THREAD_CB_CAPTURE_DONE, "capture-done" }, { TDM_THREAD_CB_VBLANK_SW, "vblank-sw" }, diff --git a/src/tdm_output.c b/src/tdm_output.c index 1edf7fc..accdfa3 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -64,7 +64,7 @@ static tdm_error _tdm_output_vblank_timeout_cb(void *user_data) { tdm_private_output *private_output = user_data; - tdm_private_vblank_handler *v = NULL; + tdm_private_output_vblank_handler *v = NULL; TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_OPERATION_FAILED); @@ -81,7 +81,7 @@ _tdm_output_vblank_timeout_cb(void *user_data) INTERN void tdm_output_vblank_print_wait_information(tdm_private_output *private_output, void *user_data) { - tdm_private_vblank_handler *v = NULL; + tdm_private_output_vblank_handler *v = NULL; TDM_RETURN_IF_FAIL(private_output != NULL); TDM_RETURN_IF_FAIL(user_data != NULL); @@ -135,6 +135,16 @@ _tdm_output_find_private_hwc_window(tdm_private_output *private_output, return NULL; } +INTERN tdm_error +tdm_output_init(tdm_private_display *private_display) +{ + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_COMMIT, tdm_display_find_output_stamp); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_VBLANK, tdm_display_find_output_stamp); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_CHANGE, tdm_display_find_output_stamp); + + return TDM_ERROR_NONE; +} + EXTERN tdm_error tdm_output_get_model_info(tdm_output *output, const char **maker, const char **model, const char **name) @@ -202,59 +212,80 @@ _tdm_output_update(tdm_output *output_backend, void *user_data) ret = tdm_display_update_output(private_display, output_backend, private_output->pipe); TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); } +/* LCOV_EXCL_STOP */ INTERN void -tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, - void *user_data) +tdm_output_thread_cb_change(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { - tdm_private_display *private_display; - tdm_private_output *private_output = user_data; - tdm_value value; + tdm_private_output *private_output = object; + tdm_thread_cb_output_change *output_change = (tdm_thread_cb_output_change *)cb_base; + tdm_private_output_change_handler *change_handler = user_data; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - TDM_RETURN_IF_FAIL(private_output); - - private_display = private_output->private_display; - if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) { - tdm_thread_cb_output_status output_status; - tdm_error ret; + assert(change_handler->owner_tid == syscall(SYS_gettid)); - TDM_INFO("output(%d) sub %s", private_output->pipe, tdm_status_str(status)); + _pthread_mutex_unlock(&private_display->lock); + change_handler->func(private_output, output_change->type, output_change->value, change_handler->user_data); + _pthread_mutex_lock(&private_display->lock); +} - _tdm_output_update(output_backend, user_data); +static tdm_error +_tdm_output_call_thread_cb_change(tdm_private_output *private_output, tdm_output_change_type type, tdm_value value) +{ + tdm_thread_cb_output_change output_change; + tdm_error ret; - output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS; - output_status.base.length = sizeof output_status; - output_status.output_stamp = private_output->stamp; - output_status.status = status; - output_status.user_data = user_data; + memset(&output_change, 0, sizeof output_change); + output_change.base.type = TDM_THREAD_CB_OUTPUT_CHANGE; + output_change.base.length = sizeof output_change; + output_change.base.object_stamp = private_output->stamp; + output_change.base.data = NULL; + output_change.base.sync = 1; + output_change.type = type; + output_change.value = value; - value.u32 = status; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_sub, - TDM_OUTPUT_CHANGE_CONNECTION, - value); + ret = tdm_thread_cb_call(private_output, &output_change.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); + return TDM_ERROR_NONE; +} - return; - } +INTERN void +tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, void *user_data) +{ + tdm_private_output *private_output = user_data; + tdm_value value; + tdm_error ret; TDM_INFO("output(%d) main %s", private_output->pipe, tdm_status_str(status)); - if (!tdm_thread_is_running()) - _tdm_output_update(output_backend, user_data); - private_output->caps.status = status; + _tdm_output_update(output_backend, user_data); value.u32 = status; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_main, - TDM_OUTPUT_CHANGE_CONNECTION, - value); + + ret = _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_CONNECTION, value); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + +INTERN void +tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data) +{ + tdm_private_output *private_output = user_data; + tdm_value value; + tdm_error ret; + + TDM_INFO("output(%d) %s", private_output->pipe, tdm_status_str(dpms)); + + private_output->current_dpms_value = dpms; + private_output->waiting_dpms_change = 0; + TDM_INFO("output(%d) dpms async '%s' done", private_output->pipe, tdm_dpms_str(dpms)); + + value.u32 = dpms; + + ret = _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } -/* LCOV_EXCL_STOP */ EXTERN tdm_error tdm_output_add_change_handler(tdm_output *output, @@ -277,15 +308,22 @@ tdm_output_add_change_handler(tdm_output *output, /* LCOV_EXCL_STOP */ } + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, change_handler); + if (ret != TDM_ERROR_NONE) { + /* LCOV_EXCL_START */ + TDM_ERR("tdm_thread_cb_add failed"); + free(change_handler); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OPERATION_FAILED; + /* LCOV_EXCL_STOP */ + } + change_handler->private_output = private_output; change_handler->func = func; change_handler->user_data = user_data; change_handler->owner_tid = syscall(SYS_gettid); - if (!tdm_thread_in_display_thread(change_handler->owner_tid)) - LIST_ADDTAIL(&change_handler->link, &private_output->change_handler_list_sub); - else - LIST_ADDTAIL(&change_handler->link, &private_output->change_handler_list_main); + LIST_ADDTAIL(&change_handler->link, &private_output->change_handler_list); _pthread_mutex_unlock(&private_display->lock); @@ -299,7 +337,7 @@ tdm_output_remove_change_handler(tdm_output *output, { tdm_private_display *private_display; tdm_private_output *private_output; - tdm_private_output_change_handler *h = NULL, *hh = NULL; + tdm_private_output_change_handler *change_handler = NULL, *hh = NULL; TDM_RETURN_IF_FAIL(tdm_output_is_valid(output)); TDM_RETURN_IF_FAIL(func != NULL); @@ -309,24 +347,14 @@ tdm_output_remove_change_handler(tdm_output *output, _pthread_mutex_lock(&private_display->lock); - LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) { - if (h->func != func || h->user_data != user_data) + LIST_FOR_EACH_ENTRY_SAFE(change_handler, hh, &private_output->change_handler_list, link) { + if (change_handler->func != func || change_handler->user_data != user_data) continue; - LIST_DEL(&h->link); - free(h); - - _pthread_mutex_unlock(&private_display->lock); - - return; - } - - LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) { - if (h->func != func || h->user_data != user_data) - continue; + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, change_handler); - LIST_DEL(&h->link); - free(h); + LIST_DEL(&change_handler->link); + free(change_handler); _pthread_mutex_unlock(&private_display->lock); @@ -644,50 +672,26 @@ tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) return ret; } -INTERN void -tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data) +static void +_tdm_output_thread_cb_vblank(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { - tdm_private_vblank_handler *vblank_handler = user_data; - tdm_private_vblank_handler *v = NULL, *vv = NULL; - tdm_private_output *private_output; - tdm_private_display *private_display; + tdm_thread_cb_output_vblank *output_vblank = (tdm_thread_cb_output_vblank *)cb_base; + tdm_private_output_vblank_handler *vblank_handler = output_vblank->base.data; + tdm_private_output_vblank_handler *v = NULL, *vv = NULL; + tdm_private_output *private_output = object; struct list_head clone_list; int interval, sync; pid_t tid = syscall(SYS_gettid); TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - TDM_RETURN_IF_FAIL(vblank_handler); - - private_output = vblank_handler->private_output; - private_display = private_output->private_display; - - if (vblank_handler->owner_tid != tid) { - tdm_thread_cb_output_vblank output_vblank; - tdm_error ret; - vblank_handler->sent_to_frontend = 1; - - output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK; - output_vblank.base.length = sizeof output_vblank; - output_vblank.output_stamp = vblank_handler->private_output->stamp; - output_vblank.sequence = sequence; - output_vblank.tv_sec = tv_sec; - output_vblank.tv_usec = tv_usec; - output_vblank.user_data = user_data; - - ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - return; - } + assert(vblank_handler->owner_tid == tid); vblank_handler->sent_to_frontend = 0; _tdm_output_vblank_timeout_update(private_output, 0); - if (vblank_handler->owner_tid != tid) - TDM_NEVER_GET_HERE(); + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_VBLANK, vblank_handler, _tdm_output_thread_cb_vblank, NULL); interval = vblank_handler->interval; sync = vblank_handler->sync; @@ -713,7 +717,11 @@ tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, LIST_DEL(&v->link); if (v->func) - v->func(v->private_output, sequence, tv_sec, tv_usec, v->user_data); + v->func(v->private_output, + output_vblank->sequence, + output_vblank->tv_sec, + output_vblank->tv_usec, + v->user_data); free(v); } @@ -723,13 +731,36 @@ tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, TDM_INFO("-----------------------------------------..."); } -INTERN void -tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data) +static void +_tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) { - tdm_private_output_commit_handler *output_commit_handler = user_data; - tdm_private_display *private_display; - tdm_private_output *private_output; + tdm_private_output_vblank_handler *vblank_handler = user_data; + tdm_thread_cb_output_vblank output_vblank; + tdm_error ret; + + memset(&output_vblank, 0, sizeof output_vblank); + output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK; + output_vblank.base.length = sizeof output_vblank; + output_vblank.base.object_stamp = vblank_handler->private_output->stamp; + output_vblank.base.data = vblank_handler; + output_vblank.base.sync = 0; + output_vblank.sequence = sequence; + output_vblank.tv_sec = tv_sec; + output_vblank.tv_usec = tv_usec; + + vblank_handler->sent_to_frontend = 1; + + ret = tdm_thread_cb_call(vblank_handler->private_output, &output_vblank.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + +static void +_tdm_output_thread_cb_commit(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) +{ + tdm_thread_cb_output_commit *output_commit = (tdm_thread_cb_output_commit *)cb_base; + tdm_private_output_commit_handler *output_commit_handler = output_commit->base.data; + tdm_private_output *private_output = object; tdm_private_layer *private_layer = NULL; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); @@ -737,26 +768,9 @@ tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, if (!output_commit_handler) return; - private_output = output_commit_handler->private_output; - private_display = private_output->private_display; - - if (output_commit_handler->owner_tid != syscall(SYS_gettid)) { - tdm_thread_cb_output_commit output_commit; - tdm_error ret; - - output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT; - output_commit.base.length = sizeof output_commit; - output_commit.output_stamp = private_output->stamp; - output_commit.sequence = sequence; - output_commit.tv_sec = tv_sec; - output_commit.tv_usec = tv_usec; - output_commit.user_data = user_data; + assert(output_commit_handler->owner_tid == syscall(SYS_gettid)); - ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - return; - } + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL); LIST_DEL(&output_commit_handler->link); @@ -775,8 +789,11 @@ tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, if (output_commit_handler->func) { _pthread_mutex_unlock(&private_display->lock); - output_commit_handler->func(private_output, sequence, - tv_sec, tv_usec, output_commit_handler->user_data); + output_commit_handler->func(private_output, + output_commit->sequence, + output_commit->tv_sec, + output_commit->tv_usec, + output_commit_handler->user_data); _pthread_mutex_lock(&private_display->lock); } @@ -786,23 +803,50 @@ tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, TDM_INFO("-----------------------------------------..."); } +static void +_tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + tdm_private_output_commit_handler *output_commit_handler = user_data; + tdm_private_output *private_output; + tdm_thread_cb_output_commit output_commit; + tdm_error ret; + + if (output_commit_handler) + private_output = output_commit_handler->private_output; + else + private_output = tdm_display_find_private_output(tdm_display_get(), output_backend); + + memset(&output_commit, 0, sizeof output_commit); + output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT; + output_commit.base.length = sizeof output_commit; + output_commit.base.object_stamp = private_output->stamp; + output_commit.base.data = output_commit_handler; + output_commit.base.sync = 0; + output_commit.sequence = sequence; + output_commit.tv_sec = tv_sec; + output_commit.tv_usec = tv_usec; + + ret = tdm_thread_cb_call(private_output, &output_commit.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + /* add_front: To distinguish between the user vblank handlers and the layer * commit vblank handlers. The layer commit handlers will be called * before calling the user vblank handlers. */ static tdm_error -_tdm_output_wait_vblank(tdm_output *output, int interval, int sync, +_tdm_output_wait_vblank(tdm_private_output *private_output, int interval, int sync, tdm_output_vblank_handler func, void *user_data, unsigned int add_front) { tdm_func_output *func_output; - tdm_private_vblank_handler *vblank_handler = NULL, *v = NULL; + tdm_private_output_vblank_handler *vblank_handler = NULL, *v = NULL; unsigned int skip_request = 0; pid_t tid = syscall(SYS_gettid); + tdm_error ret = TDM_ERROR_NONE; - OUTPUT_FUNC_ENTRY(); - - func_output = &private_display->func_output; + func_output = &private_output->private_display->func_output; /* interval SHOULD be at least 1 */ if (interval <= 0) @@ -818,10 +862,10 @@ _tdm_output_wait_vblank(tdm_output *output, int interval, int sync, if (!private_output->regist_vblank_cb) { private_output->regist_vblank_cb = 1; ret = func_output->output_set_vblank_handler(private_output->output_backend, - tdm_output_cb_vblank); + _tdm_output_cb_vblank); } - vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler)); + vblank_handler = calloc(1, sizeof(tdm_private_output_vblank_handler)); if (!vblank_handler) { /* LCOV_EXCL_START */ TDM_ERR("failed: alloc memory"); @@ -853,6 +897,12 @@ _tdm_output_wait_vblank(tdm_output *output, int interval, int sync, /* If there is the previous request, we can skip to call output_wait_vblank() */ if (!skip_request) { + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_VBLANK, vblank_handler, _tdm_output_thread_cb_vblank, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_thread_cb_add failed"); + goto wait_failed; + } + ret = func_output->output_wait_vblank(private_output->output_backend, interval, sync, vblank_handler); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed); @@ -868,6 +918,7 @@ _tdm_output_wait_vblank(tdm_output *output, int interval, int sync, wait_failed: /* LCOV_EXCL_START */ if (vblank_handler) { + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_VBLANK, vblank_handler, _tdm_output_thread_cb_vblank, NULL); LIST_DEL(&vblank_handler->link); free(vblank_handler); } @@ -890,7 +941,7 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, return TDM_ERROR_DPMS_OFF; } - ret = _tdm_output_wait_vblank(output, interval, sync, func, user_data, 0); + ret = _tdm_output_wait_vblank(private_output, interval, sync, func, user_data, 0); _pthread_mutex_unlock(&private_display->lock); @@ -913,7 +964,7 @@ tdm_output_wait_vblank_add_front(tdm_output *output, int interval, int sync, return TDM_ERROR_DPMS_OFF; } - ret = _tdm_output_wait_vblank(output, interval, sync, func, user_data, 1); + ret = _tdm_output_wait_vblank(private_output, interval, sync, func, user_data, 1); _pthread_mutex_unlock(&private_display->lock); @@ -925,7 +976,7 @@ INTERN void tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_handler func, void *user_data) { tdm_private_output *private_output = (tdm_private_output*)output; - tdm_private_vblank_handler *v = NULL; + tdm_private_output_vblank_handler *v = NULL; TDM_RETURN_IF_FAIL(private_output != NULL); TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); @@ -1013,8 +1064,7 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl if (func) { if (!private_output->regist_commit_cb) { private_output->regist_commit_cb = 1; - ret = func_output->output_set_commit_handler(private_output->output_backend, - tdm_output_cb_commit); + ret = func_output->output_set_commit_handler(private_output->output_backend, _tdm_output_cb_commit); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); } @@ -1026,6 +1076,13 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl /* LCOV_EXCL_STOP */ } + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_thread_cb_add failed"); + free(output_commit_handler); + return ret; + } + LIST_ADDTAIL(&output_commit_handler->link, &private_output->output_commit_handler_list); output_commit_handler->private_output = private_output; output_commit_handler->func = func; @@ -1068,6 +1125,7 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl commit_failed: /* LCOV_EXCL_START */ if (output_commit_handler) { + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL); LIST_DEL(&output_commit_handler->link); free(output_commit_handler); } @@ -1169,110 +1227,6 @@ tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode) return ret; } -static tdm_error -_tdm_output_dpms_changed_timeout(void *user_data) -{ - tdm_private_output *private_output = user_data; - tdm_value value; - - value.u32 = private_output->current_dpms_value; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_sub, - TDM_OUTPUT_CHANGE_DPMS, - value); - - return TDM_ERROR_NONE; -} - -static tdm_error -tdm_output_call_dpms_change_handler(tdm_output *output) -{ - tdm_private_output *private_output = (tdm_private_output*)output; - tdm_value value; - - /** Use timer to call the output change callback of the sub-thread. - * The output change callback of tdm_server and tdm_vblank was called - * in the main thread. And it made the multi thread issue. If we use - * the timer, we can call the sub-thread's output change callback in - * sub-thread. - */ - if (!private_output->dpms_changed_timer) { - private_output->dpms_changed_timer = - tdm_event_loop_add_timer_handler(private_output->private_display, - _tdm_output_dpms_changed_timeout, private_output, NULL); - if (!private_output->dpms_changed_timer) { - /* LCOV_EXCL_START */ - TDM_ERR("can't create dpms timer!!"); - return TDM_ERROR_OUT_OF_MEMORY; - /* LCOV_EXCL_STOP */ - } - } - - value.u32 = private_output->current_dpms_value; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_main, - TDM_OUTPUT_CHANGE_DPMS, - value); - - if (!LIST_IS_EMPTY(&private_output->change_handler_list_sub)) { - tdm_error ret = tdm_event_loop_source_timer_update(private_output->dpms_changed_timer, 1); - if (ret != TDM_ERROR_NONE) - TDM_NEVER_GET_HERE(); - } - - return TDM_ERROR_NONE; -} - -/* LCOV_EXCL_START */ -INTERN void -tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data) -{ - tdm_private_display *private_display; - tdm_private_output *private_output = user_data; - tdm_value value; - - TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - TDM_RETURN_IF_FAIL(private_output); - - private_display = private_output->private_display; - - if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) { - tdm_thread_cb_output_dpms output_dpms; - tdm_error ret; - - _tdm_output_update(output_backend, user_data); - - output_dpms.base.type = TDM_THREAD_CB_OUTPUT_DPMS; - output_dpms.base.length = sizeof output_dpms; - output_dpms.output_stamp = private_output->stamp; - output_dpms.dpms = dpms; - output_dpms.user_data = user_data; - - value.u32 = dpms; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_sub, - TDM_OUTPUT_CHANGE_DPMS, - value); - - ret = tdm_thread_send_cb(private_display->private_loop, &output_dpms.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - return; - } - - private_output->current_dpms_value = dpms; - private_output->waiting_dpms_change = 0; - - TDM_INFO("output(%d) dpms async '%s' done", private_output->pipe, tdm_dpms_str(dpms)); - - value.u32 = dpms; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_main, - TDM_OUTPUT_CHANGE_DPMS, - value); -} -/* LCOV_EXCL_STOP */ - EXTERN tdm_error tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) { @@ -1317,9 +1271,11 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) done: if (ret == TDM_ERROR_NONE) { if (private_output->current_dpms_value != dpms_value) { + tdm_value value; private_output->current_dpms_value = dpms_value; + value.u32 = dpms_value; + _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); TDM_INFO("output(%d) dpms '%s' done", private_output->pipe, tdm_dpms_str(dpms_value)); - tdm_output_call_dpms_change_handler(output); } } else { tdm_output_dpms temp = TDM_OUTPUT_DPMS_OFF; @@ -1452,11 +1408,13 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) /* checking with backend's value */ if (*dpms_value != private_output->current_dpms_value) { + tdm_value value; TDM_ERR("output(%d) dpms changed suddenly: %s -> %s", private_output->pipe, private_output->current_dpms_value, tdm_dpms_str(*dpms_value)); private_output->current_dpms_value = *dpms_value; - tdm_output_call_dpms_change_handler(output); + value.u32 = *dpms_value; + _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); } return ret; @@ -2017,42 +1975,6 @@ tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format return ret; } -INTERN void -tdm_output_call_change_handler_internal(tdm_private_output *private_output, - struct list_head *change_handler_list, - tdm_output_change_type type, - tdm_value value) -{ - tdm_private_display *private_display; - tdm_private_output_change_handler *change_handler = NULL; - - TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - TDM_RETURN_IF_FAIL(private_output); - - private_display = private_output->private_display; - if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) { - if (type & TDM_OUTPUT_CHANGE_CONNECTION) - TDM_INFO("output(%d) changed: %s (%d)", - private_output->pipe, tdm_status_str(value.u32), value.u32); - if (type & TDM_OUTPUT_CHANGE_DPMS) - TDM_INFO("output(%d) changed: dpms %s (%d)", - private_output->pipe, tdm_dpms_str(value.u32), value.u32); - } - - if (LIST_IS_EMPTY(change_handler_list)) - return; - - LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) { - if (change_handler->owner_tid != syscall(SYS_gettid)) - TDM_NEVER_GET_HERE(); - - _pthread_mutex_unlock(&private_display->lock); - change_handler->func(private_output, type, - value, change_handler->user_data); - _pthread_mutex_lock(&private_display->lock); - } -} - static int _is_hwc_output_still_existed(tdm_private_output *private_output) { @@ -2079,22 +2001,28 @@ exist: } /* gets called on behalf of the ecore-main-loop thread */ -INTERN tdm_error -tdm_output_cb_need_validate(tdm_private_output *private_output) +INTERN void +tdm_output_need_validate_handler_thread(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { - TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); + tdm_private_output *private_output = object; + + TDM_RETURN_IF_FAIL(private_output != NULL); + + _pthread_mutex_lock(&private_display->lock); /* as we get 'private_output' within an event, an output this 'private_output' * points to can be destroyed already */ - if (!_is_hwc_output_still_existed(private_output)) - return TDM_ERROR_NONE; + if (!_is_hwc_output_still_existed(private_output)) { + _pthread_mutex_unlock(&private_display->lock); + return; + } + + _pthread_mutex_unlock(&private_display->lock); TDM_INFO("tdm-backend asks for revalidation for the output:%p.", private_output); if (private_output->need_validate.hndl) private_output->need_validate.hndl((tdm_output*)private_output); - - return TDM_ERROR_NONE; } /* gets called on behalf of the tdm-thread */ @@ -2113,11 +2041,14 @@ _need_validate_handler(int fd, tdm_event_loop_mask mask, void *user_data) return TDM_ERROR_OPERATION_FAILED; } + memset(&ev, 0, sizeof ev); ev.base.type = TDM_THREAD_CB_NEED_VALIDATE; ev.base.length = sizeof ev; - ev.o = private_output; + ev.base.object_stamp = private_output->stamp; + ev.base.data = NULL; + ev.base.sync = 0; - ret = tdm_thread_send_cb(private_output->private_display->private_loop, &ev.base); + ret = tdm_thread_cb_call(private_output, &ev.base); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); TDM_INFO("tdm-thread: get a 'need to revalidate' event for the ouptut:%p.", private_output); diff --git a/src/tdm_private.h b/src/tdm_private.h index 44359f9..a35aea8 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -90,18 +90,18 @@ tdm_display_get(void); int tdm_display_check_module_abi(tdm_private_display *private_display, int abimaj, int abimin); -tdm_private_output * +void * tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp); +tdm_private_output * +tdm_display_find_private_output(tdm_private_display *private_display, tdm_output *output_backend); +tdm_error +tdm_output_init(tdm_private_display *private_display); int tdm_output_is_valid(tdm_output *output); void -tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data); -void -tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data); +tdm_output_thread_cb_change(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); void tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, void *user_data); @@ -123,6 +123,8 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value); tdm_error tdm_output_need_validate_event_init(tdm_output *output); +void +tdm_output_need_validate_handler_thread(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); tdm_error tdm_output_choose_commit_per_vblank_mode(tdm_private_output *private_output, int mode); @@ -161,12 +163,6 @@ tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned in void tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len); -void -tdm_output_call_change_handler_internal(tdm_private_output *private_output, - struct list_head *change_handler_list, - tdm_output_change_type type, - tdm_value value); - tdm_error tdm_pp_init(tdm_private_display *private_display); tdm_private_pp * diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 4f3da84..77393f1 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -105,9 +105,9 @@ typedef struct _tdm_private_capture tdm_private_capture; typedef struct _tdm_private_loop tdm_private_loop; typedef struct _tdm_private_server tdm_private_server; typedef struct _tdm_private_thread tdm_private_thread; -typedef struct _tdm_private_vblank_handler tdm_private_vblank_handler; typedef struct _tdm_private_output_change_handler tdm_private_output_change_handler; typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler; +typedef struct _tdm_private_output_vblank_handler tdm_private_output_vblank_handler; typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler; typedef struct _tdm_private_hwc_window_commit_handler tdm_private_hwc_window_commit_handler; typedef struct _tdm_private_output_hwc_target_buffer_window_commit_handler tdm_private_output_hwc_target_buffer_commit_handler; @@ -194,15 +194,10 @@ struct _tdm_private_output { tdm_event_loop_source *vblank_timeout_timer; - /* seperate list for multi-thread*/ - struct list_head change_handler_list_main; - struct list_head change_handler_list_sub; + struct list_head change_handler_list; void **layers_ptr; - /* TODO: temp solution for handling DPMS things in sub-htread */ - tdm_event_loop_source *dpms_changed_timer; - struct { /* look at the tdm_output_set_need_revalidate_handler() declaration for the details */ tdm_output_need_validate_handler hndl; @@ -344,7 +339,7 @@ struct _tdm_private_loop { tdm_private_thread *private_thread; }; -struct _tdm_private_vblank_handler { +struct _tdm_private_output_vblank_handler { struct list_head link; tdm_private_output *private_output; @@ -435,8 +430,7 @@ typedef enum { TDM_THREAD_CB_NONE, TDM_THREAD_CB_OUTPUT_COMMIT, TDM_THREAD_CB_OUTPUT_VBLANK, - TDM_THREAD_CB_OUTPUT_STATUS, - TDM_THREAD_CB_OUTPUT_DPMS, + TDM_THREAD_CB_OUTPUT_CHANGE, TDM_THREAD_CB_PP_DONE, TDM_THREAD_CB_CAPTURE_DONE, TDM_THREAD_CB_VBLANK_SW, @@ -448,8 +442,7 @@ typedef enum { typedef struct _tdm_thread_cb_base tdm_thread_cb_base; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_commit; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_vblank; -typedef struct _tdm_thread_cb_output_status tdm_thread_cb_output_status; -typedef struct _tdm_thread_cb_output_dpms tdm_thread_cb_output_dpms; +typedef struct _tdm_thread_cb_output_change tdm_thread_cb_output_change; typedef struct _tdm_thread_cb_pp_done tdm_thread_cb_pp_done; typedef struct _tdm_thread_cb_capture_done tdm_thread_cb_capture_done; typedef struct _tdm_thread_cb_vblank_sw tdm_thread_cb_vblank_sw; @@ -466,25 +459,15 @@ struct _tdm_thread_cb_base { struct _tdm_thread_cb_output_vblank { tdm_thread_cb_base base; - double output_stamp; unsigned int sequence; unsigned int tv_sec; unsigned int tv_usec; - void *user_data; }; -struct _tdm_thread_cb_output_status { +struct _tdm_thread_cb_output_change { tdm_thread_cb_base base; - double output_stamp; - tdm_output_conn_status status; - void *user_data; -}; - -struct _tdm_thread_cb_output_dpms { - tdm_thread_cb_base base; - double output_stamp; - tdm_output_dpms dpms; - void *user_data; + tdm_output_change_type type; + tdm_value value; }; struct _tdm_thread_cb_pp_done { @@ -509,7 +492,6 @@ struct _tdm_thread_cb_vblank_create { struct _tdm_thread_cb_need_validate { tdm_thread_cb_base base; - tdm_private_output *o; }; struct argument_details { diff --git a/src/tdm_thread.c b/src/tdm_thread.c index e9fec48..cf76c82 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -418,70 +418,16 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) if (tdm_debug_module & TDM_DEBUG_THREAD) TDM_INFO("type(%d), length(%d)", base->type, base->length); switch (base->type) { - case TDM_THREAD_CB_OUTPUT_COMMIT: { - tdm_thread_cb_output_commit *output_commit = (tdm_thread_cb_output_commit*)base; - tdm_output *output_backend = - tdm_display_find_output_stamp(private_loop->dpy, output_commit->output_stamp); - if (!output_backend) { - TDM_WRN("no output(%f)", output_commit->output_stamp); - break; - } - tdm_output_cb_commit(output_backend, output_commit->sequence, - output_commit->tv_sec, output_commit->tv_usec, - output_commit->user_data); - break; - } - case TDM_THREAD_CB_OUTPUT_VBLANK: { - tdm_thread_cb_output_vblank *output_vblank = (tdm_thread_cb_output_vblank*)base; - tdm_output *output_backend = - tdm_display_find_output_stamp(private_loop->dpy, output_vblank->output_stamp); - if (!output_backend) { - TDM_WRN("no output(%f)", output_vblank->output_stamp); - break; - } - tdm_output_cb_vblank(output_backend, output_vblank->sequence, - output_vblank->tv_sec, output_vblank->tv_usec, - output_vblank->user_data); - break; - } - case TDM_THREAD_CB_OUTPUT_STATUS: { - /* LCOV_EXCL_START */ - tdm_thread_cb_output_status *output_status = (tdm_thread_cb_output_status*)base; - tdm_output *output_backend = - tdm_display_find_output_stamp(private_loop->dpy, output_status->output_stamp); - if (!output_backend) { - TDM_WRN("no output(%f)", output_status->output_stamp); - break; - } - tdm_output_cb_status(output_backend, output_status->status, - output_status->user_data); - break; - /* LCOV_EXCL_STOP */ - } - case TDM_THREAD_CB_OUTPUT_DPMS: { - /* LCOV_EXCL_START */ - tdm_thread_cb_output_dpms *output_dpms = (tdm_thread_cb_output_dpms*)base; - tdm_output *output_backend = - tdm_display_find_output_stamp(private_loop->dpy, output_dpms->output_stamp); - if (!output_backend) { - TDM_WRN("no output(%f)", output_dpms->output_stamp); - break; - } - tdm_output_cb_dpms(output_backend, output_dpms->dpms, output_dpms->user_data); - break; - /* LCOV_EXCL_STOP */ - } + case TDM_THREAD_CB_OUTPUT_COMMIT: + case TDM_THREAD_CB_OUTPUT_VBLANK: + case TDM_THREAD_CB_OUTPUT_CHANGE: case TDM_THREAD_CB_PP_DONE: case TDM_THREAD_CB_CAPTURE_DONE: case TDM_THREAD_CB_VBLANK_SW: case TDM_THREAD_CB_VBLANK_CREATE: + case TDM_THREAD_CB_NEED_VALIDATE: tdm_thread_cb_call(NULL, base); break; - case TDM_THREAD_CB_NEED_VALIDATE: { - tdm_thread_cb_need_validate *ev = (tdm_thread_cb_need_validate*)base; - tdm_output_cb_need_validate(ev->o); - break; - } default: break; } -- 2.7.4 From ddaded5fa255c078568e7f92311c335151dc1b99 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 14:36:26 +0900 Subject: [PATCH 02/16] log: no need to use ifdef Change-Id: I2f1b03b99b6925511410d87b0649db1c19580ba5 --- common/tdm_log.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index b77e765..3ddcda1 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -184,10 +184,7 @@ tdm_log_print(int level, const char *fmt, ...) pthread_mutex_unlock(&log_lock); } -#ifdef TDM_CONFIG_ASSERT - if (level <= assert_level) - assert(0); -#endif + assert(level > assert_level); } EXTERN void -- 2.7.4 From 1b73cea10c215e7640a0a7a94da2fde7d7120760 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 14:36:52 +0900 Subject: [PATCH 03/16] thread: reset find_funcs table when init, deinit Change-Id: I20f572f7dd6014daf0ee02a656f188c3d89d5900 --- src/tdm_thread.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tdm_thread.c b/src/tdm_thread.c index cf76c82..30966b4 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -185,7 +185,7 @@ tdm_thread_init(tdm_private_loop *private_loop) { tdm_private_display *private_display; tdm_private_thread *private_thread; - int thread; + int thread, i; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); TDM_RETURN_VAL_IF_FAIL(private_loop->dpy, TDM_ERROR_OPERATION_FAILED); @@ -193,6 +193,9 @@ tdm_thread_init(tdm_private_loop *private_loop) private_display = private_loop->dpy; TDM_RETURN_VAL_IF_FAIL(private_display->private_loop, TDM_ERROR_OPERATION_FAILED); + for (i = 0; i < TDM_THREAD_CB_MAX; i++) + find_funcs[i] = NULL; + LIST_INITHEAD(&cb_list); if (private_loop->private_thread) @@ -267,6 +270,9 @@ tdm_thread_deinit(tdm_private_loop *private_loop) TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + for (i = 0; i < TDM_THREAD_CB_MAX; i++) + find_funcs[i] = NULL; + if (!private_loop->private_thread) return; @@ -305,9 +311,6 @@ tdm_thread_deinit(tdm_private_loop *private_loop) private_loop->private_thread = NULL; keep_private_thread = NULL; - for (i = 0; i < TDM_THREAD_CB_MAX; i++) - find_funcs[i] = NULL; - TDM_INFO("Finish a TDM event thread"); } -- 2.7.4 From 342aaf80ca0d017f1dad08e16d1460d8abfdb674 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 14:37:35 +0900 Subject: [PATCH 04/16] config: remove unuseful codes Change-Id: If5b99cb203fcb7e58fc3e9c40e45f64bd3d84a3a --- src/tdm_config.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tdm_config.c b/src/tdm_config.c index 4c66e07..703ae0a 100644 --- a/src/tdm_config.c +++ b/src/tdm_config.c @@ -254,8 +254,6 @@ tdm_config_set_int(const char *key, int value) ret = iniparser_set(g_dic, key, (const char*)temp); - _tdm_config_check_logs(); - pthread_mutex_unlock(&g_dic_lock); TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); @@ -282,8 +280,6 @@ tdm_config_set_string(const char *key, const char *value) ret = iniparser_set(g_dic, key, value); - _tdm_config_check_logs(); - pthread_mutex_unlock(&g_dic_lock); TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); -- 2.7.4 From d53c7f30fde17401402cdac430c936c4aa4c0110 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 14:39:28 +0900 Subject: [PATCH 05/16] should init event_loop before vblank when initing event_loop, thread's find_funcs table is also inited. This should be done before initing others. Change-Id: Iae6c0e44b3f00c0b6a5aa77bbdbee158ce74baa0 --- src/tdm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 7fabc4a..b0d1f40 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -963,10 +963,6 @@ tdm_display_init(tdm_error *error) TDM_DBG("prepare init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; - ret = tdm_vblank_init(private_display); - if (ret != TDM_ERROR_NONE) - goto failed_vblank; - ret = tdm_event_loop_init(private_display); if (ret != TDM_ERROR_NONE) goto failed_event; @@ -975,6 +971,10 @@ tdm_display_init(tdm_error *error) TDM_INFO("event loop init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; + ret = tdm_vblank_init(private_display); + if (ret != TDM_ERROR_NONE) + goto failed_vblank; + ret = tdm_output_init(private_display); if (ret != TDM_ERROR_NONE) goto failed_load; -- 2.7.4 From a03f1283751930597b6c9f2fe43bffef288d6ead Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 31 Jan 2018 12:04:51 +0900 Subject: [PATCH 06/16] support multi backend Change-Id: I6e6d24256e1eb84dd6180bac35b33c55b076b3bb --- 0001-save.patch | 31 ++++ include/tdm.h | 55 +++---- include/tdm_backend.h | 4 +- include/tdm_deprecated.h | 95 ++++++++++++ include/tdm_helper.h | 10 -- include/tdm_log.h | 9 ++ include/tdm_types.h | 5 + src/tdm.c | 391 +++++++++++++++++++++++++++-------------------- src/tdm_backend.c | 75 +++++---- src/tdm_capture.c | 61 +++++--- src/tdm_display.c | 160 +++++++++++++------ src/tdm_event_loop.c | 77 +++++----- src/tdm_helper.c | 123 ++++++++------- src/tdm_hwc_window.c | 83 ++++++---- src/tdm_layer.c | 52 ++++--- src/tdm_macro.h | 8 +- src/tdm_monitor_server.c | 2 - src/tdm_output.c | 137 +++++++++++------ src/tdm_pp.c | 47 +++--- src/tdm_private.h | 6 +- src/tdm_private_types.h | 48 ++++-- src/tdm_vblank.c | 2 +- 22 files changed, 950 insertions(+), 531 deletions(-) create mode 100644 0001-save.patch create mode 100644 include/tdm_deprecated.h diff --git a/0001-save.patch b/0001-save.patch new file mode 100644 index 0000000..25ad8f0 --- /dev/null +++ b/0001-save.patch @@ -0,0 +1,31 @@ +From 60fa1ef61f143eb5310588bba987bdfce5d33ad1 Mon Sep 17 00:00:00 2001 +From: Boram Park +Date: Wed, 21 Feb 2018 15:26:17 +0900 +Subject: [PATCH] save + +Change-Id: I5e33d25ad3678f4a77c5ec4396af2b1b45a32488 +--- + include/tdm.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/tdm.h b/include/tdm.h +index f4aa8d8..3cae42f 100644 +--- a/include/tdm.h ++++ b/include/tdm.h +@@ -222,10 +222,10 @@ tdm_backend_get_info(tdm_backend *backend, const char **name, + const char **vendor, int *major, int *minor); + + /** +- * @brief Get the capabilities of a output object. ++ * @brief Get a backend object of the given output. + * @param[in] output A output object +- * @param[out] capabilities The capabilities of a output object +- * @return #TDM_ERROR_NONE if success. Otherwise, error value. ++ * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. ++ * @return A backend object if success. Otherwise, NULL. + */ + tdm_backend * + tdm_output_get_backend(tdm_output *output, tdm_error *error); +-- +1.9.1 + diff --git a/include/tdm.h b/include/tdm.h index 7ee3edc..3cae42f 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -43,6 +43,7 @@ #include #include "tdm_types.h" +#include "tdm_deprecated.h" #ifdef __cplusplus extern "C" { @@ -75,17 +76,6 @@ void tdm_display_deinit(tdm_display *dpy); /** - * @brief Update a display object - * @details - * When new output is connected, a frontend user need to call this function. - * And a frontend user can the new output information with tdm_output_get_xxx functions. - * @param[in] dpy A display object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_display_update(tdm_display *dpy); - -/** * @brief Get the file descriptor * @details TDM handles the events of fd with #tdm_display_handle_events. * @param[in] dpy A display object @@ -106,18 +96,6 @@ tdm_error tdm_display_handle_events(tdm_display *dpy); /** - * @brief Get the information of the TDM backend module. - * @param[in] dpy A display object - * @param[out] name The name of the TDM backend module - * @param[out] vendor The vendor of the TDM backend module - * @param[out] version The version of the TDM backend module - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_display_get_backend_info(tdm_display *dpy, const char **name, - const char **vendor, int *major, int *minor); - -/** * @brief Get the capabilities of a display object. * @details A frontend user can get whether TDM supports pp/capture functionality with this function. * @param[in] dpy A display object @@ -201,16 +179,6 @@ tdm_display_get_capture_available_size(tdm_display *dpy, int *min_w, int *min_h, int *max_w, int *max_h, int *preferred_align); /** - * @brief Get the max layer counts which a display object can show on screen. - * @details -1 means that a TDM backend module doesn't define the value. - * @param[in] dpy A display object - * @param[out] count The max count of layers - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_display_get_max_layer_count(tdm_display *dpy, int *max_count); - -/** * @brief Get the output counts which a display object has. * @param[in] dpy A display object * @param[out] count The count of outputs @@ -242,6 +210,27 @@ tdm_pp * tdm_display_create_pp(tdm_display *dpy, tdm_error *error); /** + * @brief Get the information of the TDM backend module. + * @param[in] backend A backend object + * @param[out] name The name of the TDM backend module + * @param[out] vendor The vendor of the TDM backend module + * @param[out] version The version of the TDM backend module + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_backend_get_info(tdm_backend *backend, const char **name, + const char **vendor, int *major, int *minor); + +/** + * @brief Get a backend object of the given output. + * @param[in] output A output object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A backend object if success. Otherwise, NULL. + */ +tdm_backend * +tdm_output_get_backend(tdm_output *output, tdm_error *error); + +/** * @brief Get the capabilities of a output object. * @param[in] output A output object * @param[out] capabilities The capabilities of a output object diff --git a/include/tdm_backend.h b/include/tdm_backend.h index de6fb24..4e8aee3 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -103,8 +103,7 @@ typedef struct _tdm_caps_output { unsigned int type_id; /**< The connection type id */ unsigned int mode_count; /**< The count of available modes */ - tdm_output_mode - *modes; /**< The @b newly-allocated array of modes. will be freed in frontend. */ + tdm_output_mode *modes; /**< The @b newly-allocated array of modes. will be freed in frontend. */ unsigned int prop_count; /**< The count of available properties */ tdm_prop *props; /**< The @b newly-allocated array of properties. will be freed in frontend. */ @@ -477,7 +476,6 @@ typedef struct _tdm_func_output { /** * @brief Get the mode of a output object - * @deprecated * @param[in] output A output object * @param[out] mode A output mode * @return #TDM_ERROR_NONE if success. Otherwise, error value. diff --git a/include/tdm_deprecated.h b/include/tdm_deprecated.h new file mode 100644 index 0000000..06a3d24 --- /dev/null +++ b/include/tdm_deprecated.h @@ -0,0 +1,95 @@ +/************************************************************************** + * + * libtdm + * + * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Eunchul Kim , + * JinYoung Jeon , + * Taeheon Kim , + * YoungJun Cho , + * SooChan Lim , + * Boram Park + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * +**************************************************************************/ + +#ifndef _TDM_DEPRECATED_H_ +#define _TDM_DEPRECATED_H_ + +#include "tdm_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @deprecated + * @brief Update a display object + * @details + * When new output is connected, a frontend user need to call this function. + * And a frontend user can the new output information with tdm_output_get_xxx functions. + * @param[in] dpy A display object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_display_update(tdm_display *dpy); + +/** + * @deprecated + * @brief Get the information of the TDM backend module. + * @param[in] dpy A display object + * @param[out] name The name of the TDM backend module + * @param[out] vendor The vendor of the TDM backend module + * @param[out] version The version of the TDM backend module + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see #tdm_output_get_backend, #tdm_backend_get_info + */ +tdm_error +tdm_display_get_backend_info(tdm_display *dpy, const char **name, + const char **vendor, int *major, int *minor); + +/** + * @deprecated + * @brief Get the max layer counts which a display object can show on screen. + * @details -1 means that a TDM backend module doesn't define the value. + * @param[in] dpy A display object + * @param[out] count The max count of layers + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_display_get_max_layer_count(tdm_display *dpy, int *max_count); + +/** + * @deprecated use @c tdm_helper_output_commit_per_vblank_enabled instead + * @brief Get whether the commit-per-vblank functionality is enabled or not. + * @param[in] dpy A display object + * @return 1 if enabled. Otherwise, 0. + */ +int +tdm_helper_commit_per_vblank_enabled(tdm_display *dpy); + +#ifdef __cplusplus +} +#endif + +#endif /* _TDM_DEPRECATED_H_ */ diff --git a/include/tdm_helper.h b/include/tdm_helper.h index d5d8d6e..fa82602 100644 --- a/include/tdm_helper.h +++ b/include/tdm_helper.h @@ -229,16 +229,6 @@ void tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len); /** - * @brief Get whether the commit-per-vblank functionality is enabled or not. - * @param[in] dpy A display object - * @return 1 if enabled. Otherwise, 0. - * - * @deprecated use @c tdm_helper_output_commit_per_vblank_enabled instead - */ -int -tdm_helper_commit_per_vblank_enabled(tdm_display *dpy); - -/** * @brief Get whether the commit-per-vblank functionality is enabled or not for the output. * @param[in] output An output the functionality has to be checked for * @return -1 if error occurred, 1 if enabled, 0 if disabled. diff --git a/include/tdm_log.h b/include/tdm_log.h index 02e8b0c..880ffe8 100644 --- a/include/tdm_log.h +++ b/include/tdm_log.h @@ -116,6 +116,15 @@ extern unsigned int tdm_log_debug_level; } \ } while (0) +#define TDM_NEVER_GET_HERE() TDM_WRN("** NEVER GET HERE **") +#define TDM_DEPRECATED(str) \ + do { \ + if (str) \ + TDM_WRN("** DEPRECATED: %s **", str); \ + else \ + TDM_WRN("** DEPRECATED **"); \ + } while(0) + #ifdef __cplusplus } #endif diff --git a/include/tdm_types.h b/include/tdm_types.h index 055005f..d5e6b18 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -221,6 +221,11 @@ typedef enum { typedef void tdm_display; /** + * @brief The tdm backend object + */ +typedef void tdm_backend; + +/** * @brief The tdm output object */ typedef void tdm_output; diff --git a/src/tdm.c b/src/tdm.c index b0d1f40..d744875 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -64,11 +64,14 @@ _tdm_display_find_private_layer(tdm_private_output *private_output, INTERN tdm_private_output * tdm_display_find_private_output(tdm_private_display *private_display, tdm_output *output_backend) { + tdm_private_backend *private_backend = NULL; tdm_private_output *private_output = NULL; - LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) { - if (private_output->output_backend == output_backend) - return private_output; + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_backend->output_list, link) { + if (private_output->output_backend == output_backend) + return private_output; + } } return NULL; @@ -77,11 +80,14 @@ tdm_display_find_private_output(tdm_private_display *private_display, tdm_output INTERN void * tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp) { + tdm_private_backend *private_backend = NULL; tdm_private_output *private_output = NULL; - LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) { - if (private_output->stamp == stamp) - return private_output; + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_backend->output_list, link) { + if (private_output->stamp == stamp) + return private_output; + } } return NULL; @@ -234,46 +240,48 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) static void _tdm_display_destroy_private_display(tdm_private_display *private_display) { + tdm_private_backend *private_backend = NULL, *bb = NULL; tdm_private_output *o = NULL, *oo = NULL; tdm_private_pp *p = NULL, *pp = NULL; - free(private_display->outputs_ptr); - if (private_display->outputs) { - free(private_display->outputs); - private_display->outputs = NULL; - } + LIST_FOR_EACH_ENTRY_SAFE(private_backend, bb, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY_SAFE(p, pp, &private_backend->pp_list, link) { + tdm_pp_destroy_internal(p); + } - LIST_FOR_EACH_ENTRY_SAFE(p, pp, &private_display->pp_list, link) - tdm_pp_destroy_internal(p); + LIST_FOR_EACH_ENTRY_SAFE(o, oo, &private_backend->output_list, link) { + _tdm_display_destroy_private_output(o); + } - LIST_FOR_EACH_ENTRY_SAFE(o, oo, &private_display->output_list, link) - _tdm_display_destroy_private_output(o); + _tdm_display_destroy_caps_pp(&private_backend->caps_pp); + _tdm_display_destroy_caps_capture(&private_backend->caps_capture); - _tdm_display_destroy_caps_pp(&private_display->caps_pp); - _tdm_display_destroy_caps_capture(&private_display->caps_capture); + private_backend->capabilities = 0; + private_backend->caps_display.max_layer_count = 0; - private_display->capabilities = 0; - private_display->caps_display.max_layer_count = 0; + if (private_backend->outputs) { + free(private_backend->outputs); + private_backend->outputs = NULL; + } + } } static tdm_error -_tdm_display_update_caps_pp(tdm_private_display *private_display, - tdm_caps_pp *caps) +_tdm_display_update_caps_pp(tdm_private_backend *private_backend, tdm_caps_pp *caps) { - tdm_func_display *func_display = &private_display->func_display; + tdm_func_display *func_display; tdm_error ret; - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) - return TDM_ERROR_NONE; + func_display = &private_backend->func_display; if (!func_display->display_get_pp_capability) { - TDM_ERR("no display_get_pp_capability()"); + TDM_ERR("backend(%s) no display_get_pp_capability()", private_backend->module_data->name); return TDM_ERROR_BAD_MODULE; } - ret = func_display->display_get_pp_capability(private_display->bdata, caps); + ret = func_display->display_get_pp_capability(private_backend->bdata, caps); if (ret != TDM_ERROR_NONE) { - TDM_ERR("display_get_pp_capability() failed"); + TDM_ERR("backend(%s) display_get_pp_capability() failed", private_backend->module_data->name); return TDM_ERROR_BAD_MODULE; } @@ -281,23 +289,21 @@ _tdm_display_update_caps_pp(tdm_private_display *private_display, } static tdm_error -_tdm_display_update_caps_capture(tdm_private_display *private_display, - tdm_caps_capture *caps) +_tdm_display_update_caps_capture(tdm_private_backend *private_backend, tdm_caps_capture *caps) { - tdm_func_display *func_display = &private_display->func_display; + tdm_func_display *func_display; tdm_error ret; - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) - return TDM_ERROR_NONE; + func_display = &private_backend->func_display; if (!func_display->display_get_capture_capability) { - TDM_ERR("no display_get_capture_capability()"); + TDM_ERR("backend(%s) no display_get_capture_capability()", private_backend->module_data->name); return TDM_ERROR_BAD_MODULE; } - ret = func_display->display_get_capture_capability(private_display->bdata, caps); + ret = func_display->display_get_capture_capability(private_backend->bdata, caps); if (ret != TDM_ERROR_NONE) { - TDM_ERR("display_get_capture_capability() failed"); + TDM_ERR("backend(%s) display_get_capture_capability() failed", private_backend->module_data->name); return TDM_ERROR_BAD_MODULE; } @@ -305,20 +311,20 @@ _tdm_display_update_caps_capture(tdm_private_display *private_display, } static tdm_error -_tdm_display_update_caps_layer(tdm_private_display *private_display, +_tdm_display_update_caps_layer(tdm_private_backend *private_backend, tdm_layer *layer_backend, tdm_caps_layer *caps) { - tdm_func_layer *func_layer = &private_display->func_layer; + tdm_func_layer *func_layer = &private_backend->func_layer; tdm_error ret; if (!func_layer->layer_get_capability) { - TDM_ERR("no layer_get_capability()"); + TDM_ERR("backend(%s) no layer_get_capability()", private_backend->module_data->name); return TDM_ERROR_BAD_MODULE; } ret = func_layer->layer_get_capability(layer_backend, caps); if (ret != TDM_ERROR_NONE) { - TDM_ERR("layer_get_capability() failed"); + TDM_ERR("backend(%s) layer_get_capability() failed", private_backend->module_data->name); return TDM_ERROR_BAD_MODULE; } @@ -326,25 +332,26 @@ _tdm_display_update_caps_layer(tdm_private_display *private_display, } static tdm_error -_tdm_display_update_caps_output(tdm_private_display *private_display, int pipe, +_tdm_display_update_caps_output(tdm_private_backend *private_backend, int pipe, tdm_output *output_backend, tdm_caps_output *caps) { - tdm_func_output *func_output = &private_display->func_output; + tdm_func_output *func_output = &private_backend->func_output; char temp[TDM_NAME_LEN]; tdm_error ret; double stamp; if (!func_output->output_get_capability) { - TDM_ERR("no output_get_capability()"); + TDM_ERR("backend(%s) no output_get_capability()", private_backend->module_data->name); return TDM_ERROR_BAD_MODULE; } stamp = tdm_helper_get_time(); ret = func_output->output_get_capability(output_backend, caps); - TDM_DBG("backend output_get_capability() time: %.3f ms", (tdm_helper_get_time() - stamp) * 1000.0); + TDM_DBG("backend(%s) backend output_get_capability() time: %.3f ms", + private_backend->module_data->name, (tdm_helper_get_time() - stamp) * 1000.0); if (ret != TDM_ERROR_NONE) { - TDM_ERR("output_get_capability() failed"); + TDM_ERR("backend(%s) output_get_capability() failed", private_backend->module_data->name); return TDM_ERROR_BAD_MODULE; } @@ -356,8 +363,7 @@ _tdm_display_update_caps_output(tdm_private_display *private_display, int pipe, } static tdm_error -_tdm_display_update_layer(tdm_private_display *private_display, - tdm_private_output *private_output, +_tdm_display_update_layer(tdm_private_output *private_output, tdm_layer *layer_backend, int index) { tdm_private_layer *private_layer; @@ -370,7 +376,8 @@ _tdm_display_update_layer(tdm_private_display *private_display, LIST_ADDTAIL(&private_layer->link, &private_output->layer_list); private_layer->index = index; - private_layer->private_display = private_display; + private_layer->private_backend = private_output->private_backend; + private_layer->private_display = private_output->private_display; private_layer->private_output = private_output; private_layer->layer_backend = layer_backend; @@ -380,7 +387,7 @@ _tdm_display_update_layer(tdm_private_display *private_display, } else _tdm_display_destroy_caps_layer(&private_layer->caps); - ret = _tdm_display_update_caps_layer(private_display, layer_backend, + ret = _tdm_display_update_caps_layer(private_layer->private_backend, layer_backend, &private_layer->caps); if (ret != TDM_ERROR_NONE) goto failed_update; @@ -392,27 +399,28 @@ failed_update: } INTERN tdm_error -tdm_display_update_output(tdm_private_display *private_display, +tdm_display_update_output(tdm_private_backend *private_backend, tdm_output *output_backend, int pipe) { - tdm_func_output *func_output = &private_display->func_output; + tdm_func_output *func_output = &private_backend->func_output; tdm_private_output *private_output = NULL; tdm_layer **layers = NULL; int layer_count = 0, i; tdm_error ret; - private_output = tdm_display_find_private_output(private_display, output_backend); + private_output = tdm_display_find_private_output(private_backend->private_display, output_backend); if (!private_output) { private_output = calloc(1, sizeof(tdm_private_output)); TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_OUT_OF_MEMORY); private_output->stamp = tdm_helper_get_time(); - while (tdm_display_find_output_stamp(private_display, private_output->stamp)) + while (tdm_display_find_output_stamp(private_backend->private_display, private_output->stamp)) private_output->stamp++; - LIST_ADDTAIL(&private_output->link, &private_display->output_list); + LIST_ADDTAIL(&private_output->link, &private_backend->output_list); - private_output->private_display = private_display; + private_output->private_backend = private_backend; + private_output->private_display = private_backend->private_display; private_output->current_dpms_value = TDM_OUTPUT_DPMS_OFF; private_output->output_backend = output_backend; private_output->pipe = pipe; @@ -434,14 +442,14 @@ tdm_display_update_output(tdm_private_display *private_display, private_output->regist_change_cb = 1; } - ret = _tdm_display_update_caps_output(private_display, pipe, output_backend, + ret = _tdm_display_update_caps_output(private_backend, pipe, output_backend, &private_output->caps); if (ret != TDM_ERROR_NONE) return ret; } else { tdm_caps_output new_caps; - ret = _tdm_display_update_caps_output(private_display, pipe, output_backend, + ret = _tdm_display_update_caps_output(private_backend, pipe, output_backend, &new_caps); if (ret != TDM_ERROR_NONE) return ret; @@ -469,7 +477,7 @@ tdm_display_update_output(tdm_private_display *private_display, goto failed_update; for (i = 0; i < layer_count; i++) { - ret = _tdm_display_update_layer(private_display, private_output, layers[i], i); + ret = _tdm_display_update_layer(private_output, layers[i], i); if (ret != TDM_ERROR_NONE) goto failed_update; } @@ -499,9 +507,9 @@ _tdm_display_set_main_first(tdm_output **outputs, int index) } static tdm_output ** -_tdm_display_get_ordered_outputs(tdm_private_display *private_display, int *count) +_tdm_display_get_ordered_outputs(tdm_private_backend *private_backend, int *count) { - tdm_func_display *func_display = &private_display->func_display; + tdm_func_display *func_display = &private_backend->func_display; tdm_output **outputs = NULL; tdm_output **new_outputs = NULL; tdm_output *output_dsi = NULL; @@ -513,10 +521,12 @@ _tdm_display_get_ordered_outputs(tdm_private_display *private_display, int *coun tdm_error ret; /* don't change list order if not init time */ - if (private_display->outputs) - return private_display->outputs; + if (private_backend->outputs) { + TDM_ERR("can't change output order"); + return private_backend->outputs; + } - outputs = func_display->display_get_outputs(private_display->bdata, &output_count, &ret); + outputs = func_display->display_get_outputs(private_backend->bdata, &output_count, &ret); if (ret != TDM_ERROR_NONE) goto failed_get_outputs; @@ -525,13 +535,13 @@ _tdm_display_get_ordered_outputs(tdm_private_display *private_display, int *coun if (output_count == 0) goto failed_get_outputs; else if (output_count == 1) { - private_display->outputs = outputs; + private_backend->outputs = outputs; return outputs; } /* count connected outputs */ for (i = 0; i < output_count; i++) { - tdm_func_output *func_output = &private_display->func_output; + tdm_func_output *func_output = &private_backend->func_output; tdm_caps_output caps; memset(&caps, 0, sizeof(tdm_caps_output)); @@ -607,7 +617,7 @@ _tdm_display_get_ordered_outputs(tdm_private_display *private_display, int *coun new_outputs = outputs; } - private_display->outputs = new_outputs; + private_backend->outputs = new_outputs; return new_outputs; @@ -618,36 +628,39 @@ failed_get_outputs: } static tdm_error -_tdm_display_update_internal(tdm_private_display *private_display, - int only_display) +_tdm_display_update(tdm_private_display *private_display) { - tdm_output **outputs = NULL; - int output_count = 0, i; + tdm_private_backend *private_backend = NULL; tdm_error ret = TDM_ERROR_NONE; + int index = 0; - LIST_INITHEAD(&private_display->output_list); - LIST_INITHEAD(&private_display->pp_list); - LIST_INITHEAD(&private_display->capture_list); - - if (!only_display) { - ret = _tdm_display_update_caps_pp(private_display, &private_display->caps_pp); + if (private_display->pp_backend) { + ret = _tdm_display_update_caps_pp(private_display->pp_backend, + &private_display->pp_backend->caps_pp); if (ret != TDM_ERROR_NONE) goto failed_update; + } - ret = _tdm_display_update_caps_capture(private_display, - &private_display->caps_capture); + if (private_display->capture_backend) { + ret = _tdm_display_update_caps_capture(private_display->capture_backend, + &private_display->capture_backend->caps_capture); if (ret != TDM_ERROR_NONE) goto failed_update; } - outputs = _tdm_display_get_ordered_outputs(private_display, &output_count); - if (!outputs) - goto failed_update; + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + tdm_output **outputs; + int output_count = 0, i; - for (i = 0; i < output_count; i++) { - ret = tdm_display_update_output(private_display, outputs[i], i); - if (ret != TDM_ERROR_NONE) + outputs = _tdm_display_get_ordered_outputs(private_backend, &output_count); + if (!outputs) goto failed_update; + + for (i = 0; i < output_count; i++) { + ret = tdm_display_update_output(private_backend, outputs[i], index++); + if (ret != TDM_ERROR_NONE) + goto failed_update; + } } return TDM_ERROR_NONE; @@ -661,20 +674,12 @@ failed_update: EXTERN tdm_error tdm_display_update(tdm_display *dpy) { - tdm_private_display *private_display; - tdm_error ret; - TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(tdm_display_is_valid(dpy), TDM_ERROR_INVALID_PARAMETER); - private_display = dpy; - _pthread_mutex_lock(&private_display->lock); - - ret = _tdm_display_update_internal(private_display, 1); + TDM_DEPRECATED(NULL); - _pthread_mutex_unlock(&private_display->lock); - - return ret; + return TDM_ERROR_NONE; } #define SUFFIX_MODULE ".so" @@ -741,11 +746,11 @@ _tdm_display_check_module(tdm_backend_module *module) } static tdm_error -_tdm_display_check_backend_functions(tdm_private_display *private_display) +_tdm_display_check_backend_functions(tdm_private_backend *private_backend) { - tdm_func_display *func_display = &private_display->func_display; - tdm_func_output *func_output = &private_display->func_output; - tdm_func_layer *func_layer = &private_display->func_layer; + tdm_func_display *func_display = &private_backend->func_display; + tdm_func_output *func_output = &private_backend->func_output; + tdm_func_layer *func_layer = &private_backend->func_layer; tdm_error ret; /* below functions should be implemented in backend side */ @@ -756,14 +761,14 @@ _tdm_display_check_backend_functions(tdm_private_display *private_display) TDM_RETURN_VAL_IF_FAIL(func_output->output_get_layers, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_layer->layer_get_capability, TDM_ERROR_BAD_MODULE); - ret = func_display->display_get_capability(private_display->bdata, &private_display->caps_display); + ret = func_display->display_get_capability(private_backend->bdata, &private_backend->caps_display); if (ret != TDM_ERROR_NONE) { TDM_ERR("display_get_capability() failed"); return TDM_ERROR_BAD_MODULE; } - if (private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP) { - tdm_func_pp *func_pp = &private_display->func_pp; + if (private_backend->capabilities & TDM_DISPLAY_CAPABILITY_PP) { + tdm_func_pp *func_pp = &private_backend->func_pp; TDM_RETURN_VAL_IF_FAIL(func_display->display_get_pp_capability, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_display->display_create_pp, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_pp->pp_destroy, TDM_ERROR_BAD_MODULE); @@ -771,12 +776,12 @@ _tdm_display_check_backend_functions(tdm_private_display *private_display) TDM_RETURN_VAL_IF_FAIL(func_pp->pp_set_done_handler, TDM_ERROR_BAD_MODULE); } - if (private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE) { - tdm_func_capture *func_capture = &private_display->func_capture; + if (private_backend->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE) { + tdm_func_capture *func_capture = &private_backend->func_capture; TDM_RETURN_VAL_IF_FAIL(func_display->display_get_capture_capability, TDM_ERROR_BAD_MODULE); - if (private_display->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT) + if (private_backend->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT) TDM_RETURN_VAL_IF_FAIL(func_output->output_create_capture, TDM_ERROR_BAD_MODULE); - if (private_display->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_LAYER) + if (private_backend->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_LAYER) TDM_RETURN_VAL_IF_FAIL(func_layer->layer_create_capture, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_capture->capture_destroy, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_capture->capture_commit, TDM_ERROR_BAD_MODULE); @@ -791,8 +796,10 @@ _tdm_display_load_module_with_file(tdm_private_display *private_display, const char *file) { char path[TDM_PATH_LEN] = {0,}; + void *module = NULL; tdm_backend_module *module_data; - void *module; + tdm_backend_data *bdata = NULL; + tdm_private_backend *private_backend = NULL; tdm_error ret; double stamp; int size; @@ -803,6 +810,15 @@ _tdm_display_load_module_with_file(tdm_private_display *private_display, return TDM_ERROR_BAD_MODULE; }; + private_backend = calloc(1, sizeof *private_backend); + if (!private_backend) { + TDM_ERR("alloc failed: %m"); + ret = TDM_ERROR_OUT_OF_MEMORY; + goto failed_load; + } + + private_backend->private_display = private_display; + stamp = tdm_helper_get_time(); TDM_TRACE_BEGIN("TDM_Load_Backend"); @@ -810,9 +826,12 @@ _tdm_display_load_module_with_file(tdm_private_display *private_display, if (!module) { TDM_ERR("failed to load module: %s(%s)", dlerror(), file); TDM_TRACE_END(); - return TDM_ERROR_BAD_MODULE; + ret = TDM_ERROR_BAD_MODULE; + goto failed_load; } + private_backend->module = module; + module_data = dlsym(module, "tdm_backend_module_data"); if (!module_data) { TDM_ERR("'%s' doesn't have data object", file); @@ -822,47 +841,61 @@ _tdm_display_load_module_with_file(tdm_private_display *private_display, } TDM_TRACE_END(); - TDM_DBG("dlopen, dlsym time: %.3f ms", (tdm_helper_get_time() - stamp) * 1000.0); + private_backend->module_data = module_data; - private_display->module_data = module_data; - private_display->module = module; + TDM_DBG("dlopen, dlsym time: %.3f ms", (tdm_helper_get_time() - stamp) * 1000.0); /* check if version, init() and deinit() are valid or not */ ret = _tdm_display_check_module(module_data); - if (ret != TDM_ERROR_NONE) + if (ret != TDM_ERROR_NONE) { + TDM_ERR("backend(%s) load failed: check module error", module_data->name); goto failed_load; + } + + private_display->current_backend = private_backend; /* We don't care if backend_data is NULL or not. It's up to backend. */ TDM_TRACE_BEGIN("TDM_Init_Backend"); stamp = tdm_helper_get_time(); - private_display->bdata = module_data->init((tdm_display *)private_display, &ret); + bdata = module_data->init((tdm_display *)private_display, &ret); TDM_DBG("backend init() time: %.3f ms", (tdm_helper_get_time() - stamp) * 1000.0); TDM_TRACE_END(); + private_display->current_backend = NULL; + + private_backend->bdata = bdata; + if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed to init '%s' module", module_data->name); + TDM_ERR("backend(%s) load failed: init error", module_data->name); goto failed_load; } - ret = _tdm_display_check_backend_functions(private_display); + ret = _tdm_display_check_backend_functions(private_backend); if (ret != TDM_ERROR_NONE) { - module_data->deinit(private_display->bdata); - private_display->bdata = NULL; + TDM_ERR("backend(%s) load failed: check functions error", module_data->name); goto failed_load; } + LIST_INITHEAD(&private_backend->output_list); + LIST_INITHEAD(&private_backend->pp_list); + LIST_INITHEAD(&private_backend->capture_list); + + LIST_ADDTAIL(&private_backend->link, &private_display->backend_list); + TDM_INFO("Success to load '%s' module", module_data->name); return TDM_ERROR_NONE; failed_load: + if (bdata) + module_data->deinit(bdata); dlclose(module); - private_display->module_data = NULL; - private_display->module = NULL; + if (private_backend) + free(private_backend); return ret; } static tdm_error -_tdm_display_load_module(tdm_private_display *private_display) +_tdm_display_load_modules(tdm_private_display *private_display) { const char *module_names; tdm_error ret = 0; @@ -870,38 +903,51 @@ _tdm_display_load_module(tdm_private_display *private_display) char *arg; char *end; + LIST_INITHEAD(&private_display->backend_list); + module_names = tdm_config_get_string(TDM_CONFIG_KEY_GENERAL_BACKENDS, TDM_DEFAULT_MODULE); snprintf(temp, TDM_PATH_LEN, "%s", module_names); arg = strtok_r(temp, TDM_CONFIG_DELIM, &end); while (arg) { + TDM_INFO("loading a %s backend", arg); ret = _tdm_display_load_module_with_file(private_display, arg); if (ret == TDM_ERROR_NONE) - return TDM_ERROR_NONE; - + TDM_INFO("%s backend loading success", arg); + else + TDM_INFO("%s backend loading failed", arg); arg = strtok_r(NULL, TDM_CONFIG_DELIM, &end); } /* load bufmgr priv from dummy lib */ - ret = _tdm_display_load_module_with_file(private_display, TDM_DUMMY_MODULE); - if (ret == TDM_ERROR_NONE) - return TDM_ERROR_NONE; + if (LIST_IS_EMPTY(&private_display->backend_list)) { + TDM_WRN("No backend. loading a %s backend", TDM_DUMMY_MODULE); + ret = _tdm_display_load_module_with_file(private_display, TDM_DUMMY_MODULE); + if (ret == TDM_ERROR_NONE) + TDM_INFO("%s backend loading success", TDM_DUMMY_MODULE); + else + TDM_INFO("%s backend loading failed", TDM_DUMMY_MODULE); + } return ret; } static void -_tdm_display_unload_module(tdm_private_display *private_display) +_tdm_display_unload_modules(tdm_private_display *private_display) { - if (private_display->module_data) - private_display->module_data->deinit(private_display->bdata); - if (private_display->module) - dlclose(private_display->module); - - private_display->bdata = NULL; - private_display->module_data = NULL; - private_display->module = NULL; + tdm_private_backend *private_backend = NULL, *bb = NULL; + + LIST_FOR_EACH_ENTRY_SAFE(private_backend, bb, &private_display->backend_list, link) { + LIST_DEL(&private_backend->link); + + if (private_backend->module_data) + private_backend->module_data->deinit(private_backend->bdata); + if (private_backend->module) + dlclose(private_backend->module); + + free(private_backend); + } } /* LCOV_EXCL_STOP */ @@ -987,7 +1033,7 @@ tdm_display_init(tdm_error *error) if (ret != TDM_ERROR_NONE) goto failed_load; - ret = _tdm_display_load_module(private_display); + ret = _tdm_display_load_modules(private_display); if (ret != TDM_ERROR_NONE) goto failed_load; @@ -1014,7 +1060,7 @@ tdm_display_init(tdm_error *error) #endif TDM_TRACE_BEGIN("TDM_Update_Display"); - ret = _tdm_display_update_internal(private_display, 0); + ret = _tdm_display_update(private_display); TDM_TRACE_END(); if (ret != TDM_ERROR_NONE) goto failed_update; @@ -1028,10 +1074,13 @@ tdm_display_init(tdm_error *error) private_display->init_count = 1; g_private_display = private_display; + tdm_private_backend *b = NULL; tdm_private_output *o = NULL; - LIST_FOR_EACH_ENTRY(o, &private_display->output_list, link) { - if (o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) - tdm_output_need_validate_event_init(o); + LIST_FOR_EACH_ENTRY(b, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(o, &b->output_list, link) { + if (o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) + tdm_output_need_validate_event_init(o); + } } /* the COMMIT_PER_VBLANK functionality is ability of an output to support @@ -1039,13 +1088,17 @@ tdm_display_init(tdm_error *error) * this functionality can be turned off which means a default mode */ mode = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); if (mode > 0) { + tdm_private_backend *b = NULL; tdm_private_output *o = NULL; /* outputs which support hwc capability can work only * if commit_per_vblank mode is '0' (default mode) */ - LIST_FOR_EACH_ENTRY(o, &private_display->output_list, link) - if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) - tdm_output_choose_commit_per_vblank_mode(o, mode); + LIST_FOR_EACH_ENTRY(b, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(o, &b->output_list, link) { + if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) + tdm_output_choose_commit_per_vblank_mode(o, mode); + } + } } if (error) @@ -1060,7 +1113,7 @@ tdm_display_init(tdm_error *error) /* LCOV_EXCL_START */ failed_update: - _tdm_display_unload_module(private_display); + _tdm_display_unload_modules(private_display); failed_load: tdm_event_loop_stop(private_display); tdm_event_loop_deinit(private_display); @@ -1111,7 +1164,7 @@ tdm_display_deinit(tdm_display *dpy) * we can unload backend modulues. */ _tdm_display_destroy_private_display(private_display); - _tdm_display_unload_module(private_display); + _tdm_display_unload_modules(private_display); tdm_vblank_deinit(private_display); @@ -1155,19 +1208,26 @@ tdm_display_is_valid(tdm_display *dpy) INTERN int tdm_output_is_valid(tdm_output *output) { - tdm_private_output *o = NULL, *private_output = output; - if (output && g_private_display) - LIST_FOR_EACH_ENTRY(o, &g_private_display->output_list, link) - if (o == private_output) + tdm_private_backend *b = NULL; + tdm_private_output *o = NULL; + + if (!output || !g_private_display) + return 0; + + LIST_FOR_EACH_ENTRY(b, &g_private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(o, &b->output_list, link) + if (o == output) return 1; + } + return 0; } /* LCOV_EXCL_START */ INTERN int -tdm_display_check_module_abi(tdm_private_display *private_display, int abimaj, int abimin) +tdm_backend_check_module_abi(tdm_private_backend *private_backend, int abimaj, int abimin) { - tdm_backend_module *module = private_display->module_data; + tdm_backend_module *module = private_backend->module_data; if (TDM_BACKEND_GET_ABI_MAJOR(module->abi_version) < abimaj) return 0; @@ -1255,22 +1315,26 @@ tdm_display_enable_dump(tdm_private_display *private_display, const char *dump_s TDM_GOTO_IF_FAIL(path != NULL, done); if (!strncmp(arg, "current", 7)) { + tdm_private_backend *b = NULL; tdm_private_output *o = NULL; + if (!private_display) { TDM_WRN("no private_display"); goto done; } - LIST_FOR_EACH_ENTRY(o, &private_display->output_list, link) { - tdm_private_layer *l = NULL; - LIST_FOR_EACH_ENTRY(l, &o->layer_list, link) { - char str[TDM_PATH_LEN]; - if (l->usable || l->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO) - continue; - if (!l->showing_buffer) - continue; - snprintf(str, TDM_PATH_LEN, "layer_%d_%d", o->index, l->index); - tdm_helper_dump_buffer_str(l->showing_buffer->buffer, path, str); + LIST_FOR_EACH_ENTRY(b, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(o, &b->output_list, link) { + tdm_private_layer *l = NULL; + LIST_FOR_EACH_ENTRY(l, &o->layer_list, link) { + char str[TDM_PATH_LEN]; + if (l->usable || l->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO) + continue; + if (!l->showing_buffer) + continue; + snprintf(str, TDM_PATH_LEN, "layer_%d_%d", o->index, l->index); + tdm_helper_dump_buffer_str(l->showing_buffer->buffer, path, str); + } } } @@ -1328,16 +1392,19 @@ INTERN tdm_error tdm_display_enable_ttrace_vblank(tdm_display *dpy, tdm_output *output, int enable) { tdm_private_display *private_display = dpy; + tdm_private_backend *private_backend = NULL; tdm_private_output *private_output = NULL; const tdm_output_mode *mode = NULL; tdm_vblank *vblank = NULL; tdm_error ret = TDM_ERROR_NONE; if (!enable) { - LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) { - if (private_output->ttrace_vblank) - tdm_vblank_destroy(private_output->ttrace_vblank); - private_output->ttrace_vblank = NULL; + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_backend->output_list, link) { + if (private_output->ttrace_vblank) + tdm_vblank_destroy(private_output->ttrace_vblank); + private_output->ttrace_vblank = NULL; + } } return TDM_ERROR_NONE; } diff --git a/src/tdm_backend.c b/src/tdm_backend.c index e6463bc..ed57b34 100644 --- a/src/tdm_backend.c +++ b/src/tdm_backend.c @@ -73,12 +73,14 @@ tdm_backend_register_func_display(tdm_display *dpy, TDM_RETURN_VAL_IF_FAIL(func_display != NULL, TDM_ERROR_INVALID_PARAMETER); + assert(private_display->current_backend); + /* the ABI version of backend module should be more than 1.1 */ - module = private_display->module_data; + module = private_display->current_backend->module_data; if (_check_abi_version(module, 1, 1) < 0) return TDM_ERROR_BAD_MODULE; - private_display->func_display = *func_display; + private_display->current_backend->func_display = *func_display; return TDM_ERROR_NONE; } @@ -94,12 +96,14 @@ tdm_backend_register_func_output(tdm_display *dpy, tdm_func_output *func_output) TDM_RETURN_VAL_IF_FAIL(func_output != NULL, TDM_ERROR_INVALID_PARAMETER); + assert(private_display->current_backend); + /* the ABI version of backend module should be more than 1.1 */ - module = private_display->module_data; + module = private_display->current_backend->module_data; if (_check_abi_version(module, 1, 1) < 0) return TDM_ERROR_BAD_MODULE; - private_display->func_output = *func_output; + private_display->current_backend->func_output = *func_output; return TDM_ERROR_NONE; } @@ -115,12 +119,14 @@ tdm_backend_register_func_layer(tdm_display *dpy, tdm_func_layer *func_layer) TDM_RETURN_VAL_IF_FAIL(func_layer != NULL, TDM_ERROR_INVALID_PARAMETER); + assert(private_display->current_backend); + /* the ABI version of backend module should be more than 1.1 */ - module = private_display->module_data; + module = private_display->current_backend->module_data; if (_check_abi_version(module, 1, 1) < 0) return TDM_ERROR_BAD_MODULE; - private_display->func_layer = *func_layer; + private_display->current_backend->func_layer = *func_layer; return TDM_ERROR_NONE; } @@ -136,14 +142,16 @@ tdm_backend_register_func_hwc_window(tdm_display *dpy, tdm_func_hwc_window *func TDM_RETURN_VAL_IF_FAIL(func_hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); - module = private_display->module_data; + assert(private_display->current_backend); + + module = private_display->current_backend->module_data; /* FIX ME: Temporarily, we set the version of hwc window to 1.1 for the development. Originally the hwc window version is 2.0. */ if (_check_abi_version(module, 1, 1) < 0) return TDM_ERROR_BAD_MODULE; - private_display->func_hwc_window = *func_hwc_window; + private_display->current_backend->func_hwc_window = *func_hwc_window; return TDM_ERROR_NONE; } @@ -158,8 +166,15 @@ tdm_backend_register_func_pp(tdm_display *dpy, tdm_func_pp *func_pp) if (!func_pp) return TDM_ERROR_NONE; - private_display->capabilities |= TDM_DISPLAY_CAPABILITY_PP; - private_display->func_pp = *func_pp; + assert(private_display->current_backend); + + private_display->current_backend->capabilities |= TDM_DISPLAY_CAPABILITY_PP; + private_display->current_backend->func_pp = *func_pp; + + if (!private_display->pp_backend) + private_display->pp_backend = private_display->current_backend; + else + TDM_ERR("already has pp backend(%s)", private_display->pp_backend->module_data->name); return TDM_ERROR_NONE; } @@ -175,8 +190,16 @@ tdm_backend_register_func_capture(tdm_display *dpy, if (!func_capture) return TDM_ERROR_NONE; - private_display->capabilities |= TDM_DISPLAY_CAPABILITY_CAPTURE; - private_display->func_capture = *func_capture; + assert(private_display->current_backend); + + private_display->current_backend->capabilities |= TDM_DISPLAY_CAPABILITY_CAPTURE; + private_display->current_backend->func_capture = *func_capture; + + //TODO: remove later + if (!private_display->capture_backend) + private_display->capture_backend = private_display->current_backend; + else + TDM_ERR("already has capture backend(%s)", private_display->capture_backend->module_data->name); return TDM_ERROR_NONE; } @@ -186,24 +209,22 @@ static tdm_private_output* _look_for_frontend_hwc_output(tdm_output *backend_output) { tdm_private_output *frontend_output = NULL, *o = NULL; - tdm_private_display *dpy; - - dpy = tdm_display_init(NULL); - TDM_RETURN_VAL_IF_FAIL(dpy != NULL, NULL); - - LIST_FOR_EACH_ENTRY(o, &dpy->output_list, link) { - if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) - continue; - - if (o->output_backend == backend_output) { - frontend_output = o; - break; + tdm_private_display *private_display = tdm_display_get(); + tdm_private_backend *private_backend = NULL; + + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(o, &private_backend->output_list, link) { + if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) + continue; + + if (o->output_backend == backend_output) { + frontend_output = o; + return frontend_output; + } } } - tdm_display_deinit(dpy); - - return frontend_output; + return NULL; } EXTERN tdm_error diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 869e31f..b7b8631 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -42,12 +42,14 @@ #define CAPTURE_FUNC_ENTRY() \ tdm_func_capture *func_capture; \ tdm_private_display *private_display; \ + tdm_private_backend *private_backend; \ tdm_private_capture *private_capture; \ tdm_error ret = TDM_ERROR_NONE; \ TDM_RETURN_VAL_IF_FAIL(capture != NULL, TDM_ERROR_INVALID_PARAMETER); \ private_capture = (tdm_private_capture*)capture; \ private_display = private_capture->private_display; \ - func_capture = &private_display->func_capture + private_backend = private_capture->private_backend; \ + func_capture = &private_backend->func_capture static void _tdm_capture_print_list(struct list_head *list) @@ -174,13 +176,16 @@ _tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *u static void * _tdm_capture_find_object(tdm_private_display *private_display, double stamp) { + tdm_private_backend *private_backend = NULL; tdm_private_capture *private_capture = NULL; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); - LIST_FOR_EACH_ENTRY(private_capture, &private_display->capture_list, display_link) { - if (private_capture->stamp == stamp) - return private_capture; + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(private_capture, &private_backend->capture_list, display_link) { + if (private_capture->stamp == stamp) + return private_capture; + } } return NULL; @@ -199,26 +204,27 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, tdm_error *error) { tdm_private_display *private_display = private_output->private_display; - tdm_func_output *func_output = &private_display->func_output; - tdm_func_capture *func_capture = &private_display->func_capture; + tdm_private_backend *private_backend = private_output->private_backend; + tdm_func_output *func_output = &private_backend->func_output; + tdm_func_capture *func_capture = &private_backend->func_capture; tdm_private_capture *private_capture = NULL; tdm_capture *capture_backend = NULL; tdm_error ret = TDM_ERROR_NONE; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) { + if (!(private_backend->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) { /* LCOV_EXCL_START */ - TDM_ERR("no capture capability"); + TDM_ERR("backend(%s) no capture capability", private_backend->module_data->name); if (error) *error = TDM_ERROR_NO_CAPABILITY; return NULL; /* LCOV_EXCL_STOP */ } - if (!(private_display->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT)) { + if (!(private_backend->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT)) { /* LCOV_EXCL_START */ - TDM_ERR("no output capture capability"); + TDM_ERR("backend(%s) no output capture capability", private_backend->module_data->name); if (error) *error = TDM_ERROR_NO_CAPABILITY; return NULL; @@ -273,7 +279,9 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, private_capture->stamp++; LIST_ADD(&private_capture->link, &private_output->capture_list); - LIST_ADD(&private_capture->display_link, &private_display->capture_list); + LIST_ADD(&private_capture->display_link, &private_backend->capture_list); + + private_capture->private_backend = private_backend; private_capture->target = TDM_CAPTURE_TARGET_OUTPUT; private_capture->private_display = private_display; @@ -299,24 +307,25 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, tdm_error *error) { tdm_private_output *private_output = private_layer->private_output; + tdm_private_backend *private_backend = private_layer->private_backend; tdm_private_display *private_display = private_output->private_display; - tdm_func_layer *func_layer = &private_display->func_layer; - tdm_func_capture *func_capture = &private_display->func_capture; + tdm_func_layer *func_layer = &private_backend->func_layer; + tdm_func_capture *func_capture = &private_backend->func_capture; tdm_private_capture *private_capture = NULL; tdm_capture *capture_backend = NULL; tdm_error ret = TDM_ERROR_NONE; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) { - TDM_ERR("no capture capability"); + if (!(private_backend->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) { + TDM_ERR("backend(%s) no capture capability", private_backend->module_data->name); if (error) *error = TDM_ERROR_NO_CAPABILITY; return NULL; } - if (!(private_display->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_LAYER)) { - TDM_ERR("no layer capture capability"); + if (!(private_backend->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_LAYER)) { + TDM_ERR("backend(%s) no layer capture capability", private_backend->module_data->name); if (error) *error = TDM_ERROR_NO_CAPABILITY; return NULL; @@ -341,7 +350,9 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, private_capture->stamp++; LIST_ADD(&private_capture->link, &private_layer->capture_list); - LIST_ADD(&private_capture->display_link, &private_display->capture_list); + LIST_ADD(&private_capture->display_link, &private_backend->capture_list); + + private_capture->private_backend = private_backend; private_capture->target = TDM_CAPTURE_TARGET_LAYER; private_capture->private_display = private_display; @@ -366,6 +377,7 @@ INTERN void tdm_capture_destroy_internal(tdm_private_capture *private_capture) { tdm_private_display *private_display; + tdm_private_backend *private_backend; tdm_func_capture *func_capture; tdm_capture_private_buffer *b = NULL, *bb = NULL; struct list_head clone_list; @@ -382,7 +394,8 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) LIST_DEL(&private_capture->link); LIST_DEL(&private_capture->display_link); - func_capture = &private_capture->private_display->func_capture; + private_backend = private_capture->private_backend; + func_capture = &private_backend->func_capture; func_capture->capture_destroy(private_capture->capture_backend); if (!LIST_IS_EMPTY(&private_capture->pending_buffer_list)) { @@ -541,15 +554,15 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer) /* LCOV_EXCL_STOP */ } - if (tdm_display_check_module_abi(private_display, 1, 2) && - private_display->caps_capture.max_attach_count > 0) { + if (tdm_backend_check_module_abi(private_backend, 1, 2) && + private_backend->caps_capture.max_attach_count > 0) { /* LCOV_EXCL_START */ int length = LIST_LENGTH(&private_capture->pending_buffer_list) + LIST_LENGTH(&private_capture->buffer_list); - if (length >= private_display->caps_capture.max_attach_count) { + if (length >= private_backend->caps_capture.max_attach_count) { _pthread_mutex_unlock(&private_display->lock); - TDM_DBG("failed: too many attached!! max_attach_count(%d)", - private_display->caps_capture.max_attach_count); + TDM_DBG("failed: backend(%s) too many attached!! max_attach_count(%d)", + private_backend->module_data->name, private_backend->caps_capture.max_attach_count); return TDM_ERROR_BAD_REQUEST; } /* LCOV_EXCL_STOP */ diff --git a/src/tdm_display.c b/src/tdm_display.c index abf4374..a7e880e 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -55,17 +55,31 @@ TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(tdm_display_is_valid(dpy), TDM_ERROR_INVALID_PARAMETER, NULL); \ private_display = (tdm_private_display*)dpy; +#define BACKEND_FUNC_ENTRY() \ + tdm_private_backend *private_backend; \ + tdm_private_display *private_display; \ + tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ + TDM_RETURN_VAL_IF_FAIL(backend != NULL, TDM_ERROR_INVALID_PARAMETER); \ + private_backend = (tdm_private_backend*)backend; \ + private_display = private_backend->private_display; + EXTERN tdm_error tdm_display_get_capabilities(tdm_display *dpy, tdm_display_capability *capabilities) { + tdm_private_backend *private_backend = NULL; + DISPLAY_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER); _pthread_mutex_lock(&private_display->lock); - *capabilities = private_display->capabilities; + *capabilities = 0; + + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + *capabilities |= private_backend->capabilities; + } _pthread_mutex_unlock(&private_display->lock); @@ -76,13 +90,15 @@ EXTERN tdm_error tdm_display_get_pp_capabilities(tdm_display *dpy, tdm_pp_capability *capabilities) { + tdm_private_backend *pp_backend; + DISPLAY_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER); _pthread_mutex_lock(&private_display->lock); - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) { + if (!private_display->pp_backend) { /* LCOV_EXCL_START */ TDM_ERR("no pp capability"); _pthread_mutex_unlock(&private_display->lock); @@ -90,7 +106,9 @@ tdm_display_get_pp_capabilities(tdm_display *dpy, /* LCOV_EXCL_STOP */ } - *capabilities = private_display->caps_pp.capabilities; + pp_backend = private_display->pp_backend; + + *capabilities = pp_backend->caps_pp.capabilities; _pthread_mutex_unlock(&private_display->lock); @@ -101,6 +119,8 @@ EXTERN tdm_error tdm_display_get_pp_available_formats(tdm_display *dpy, const tbm_format **formats, int *count) { + tdm_private_backend *pp_backend; + DISPLAY_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER); @@ -108,7 +128,7 @@ tdm_display_get_pp_available_formats(tdm_display *dpy, _pthread_mutex_lock(&private_display->lock); - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) { + if (!private_display->pp_backend) { /* LCOV_EXCL_START */ TDM_ERR("no pp capability"); _pthread_mutex_unlock(&private_display->lock); @@ -116,8 +136,10 @@ tdm_display_get_pp_available_formats(tdm_display *dpy, /* LCOV_EXCL_STOP */ } - *formats = (const tbm_format *)private_display->caps_pp.formats; - *count = private_display->caps_pp.format_count; + pp_backend = private_display->pp_backend; + + *formats = (const tbm_format *)pp_backend->caps_pp.formats; + *count = pp_backend->caps_pp.format_count; _pthread_mutex_unlock(&private_display->lock); @@ -128,11 +150,13 @@ EXTERN tdm_error tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h, int *max_w, int *max_h, int *preferred_align) { + tdm_private_backend *pp_backend; + DISPLAY_FUNC_ENTRY(); _pthread_mutex_lock(&private_display->lock); - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) { + if (!private_display->pp_backend) { /* LCOV_EXCL_START */ TDM_ERR("no pp capability"); _pthread_mutex_unlock(&private_display->lock); @@ -140,16 +164,18 @@ tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h, /* LCOV_EXCL_STOP */ } + pp_backend = private_display->pp_backend; + if (min_w) - *min_w = TDM_FRONT_VALUE(private_display->caps_pp.min_w); + *min_w = TDM_FRONT_VALUE(pp_backend->caps_pp.min_w); if (min_h) - *min_h = TDM_FRONT_VALUE(private_display->caps_pp.min_h); + *min_h = TDM_FRONT_VALUE(pp_backend->caps_pp.min_h); if (max_w) - *max_w = TDM_FRONT_VALUE(private_display->caps_pp.max_w); + *max_w = TDM_FRONT_VALUE(pp_backend->caps_pp.max_w); if (max_h) - *max_h = TDM_FRONT_VALUE(private_display->caps_pp.max_h); + *max_h = TDM_FRONT_VALUE(pp_backend->caps_pp.max_h); if (preferred_align) - *preferred_align = TDM_FRONT_VALUE(private_display->caps_pp.preferred_align); + *preferred_align = TDM_FRONT_VALUE(pp_backend->caps_pp.preferred_align); _pthread_mutex_unlock(&private_display->lock); @@ -160,13 +186,15 @@ EXTERN tdm_error tdm_display_get_capture_capabilities(tdm_display *dpy, tdm_capture_capability *capabilities) { + tdm_private_backend *capture_backend; + DISPLAY_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER); _pthread_mutex_lock(&private_display->lock); - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) { + if (!private_display->capture_backend) { /* LCOV_EXCL_START */ TDM_ERR("no capture capability"); _pthread_mutex_unlock(&private_display->lock); @@ -174,7 +202,9 @@ tdm_display_get_capture_capabilities(tdm_display *dpy, /* LCOV_EXCL_STOP */ } - *capabilities = private_display->caps_capture.capabilities; + capture_backend = private_display->capture_backend; + + *capabilities = capture_backend->caps_capture.capabilities; _pthread_mutex_unlock(&private_display->lock); @@ -185,6 +215,8 @@ EXTERN tdm_error tdm_display_get_capture_available_formats(tdm_display *dpy, const tbm_format **formats, int *count) { + tdm_private_backend *capture_backend; + DISPLAY_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER); @@ -192,7 +224,7 @@ tdm_display_get_capture_available_formats(tdm_display *dpy, _pthread_mutex_lock(&private_display->lock); - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) { + if (!private_display->capture_backend) { /* LCOV_EXCL_START */ TDM_ERR("no capture capability"); _pthread_mutex_unlock(&private_display->lock); @@ -200,8 +232,10 @@ tdm_display_get_capture_available_formats(tdm_display *dpy, /* LCOV_EXCL_STOP */ } - *formats = (const tbm_format *)private_display->caps_capture.formats; - *count = private_display->caps_capture.format_count; + capture_backend = private_display->capture_backend; + + *formats = (const tbm_format *)capture_backend->caps_capture.formats; + *count = capture_backend->caps_capture.format_count; _pthread_mutex_unlock(&private_display->lock); @@ -212,11 +246,13 @@ EXTERN tdm_error tdm_display_get_capture_available_size(tdm_display *dpy, int *min_w, int *min_h, int *max_w, int *max_h, int *preferred_align) { + tdm_private_backend *capture_backend; + DISPLAY_FUNC_ENTRY(); _pthread_mutex_lock(&private_display->lock); - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) { + if (!private_display->capture_backend) { /* LCOV_EXCL_START */ TDM_ERR("no capture capability"); _pthread_mutex_unlock(&private_display->lock); @@ -224,16 +260,18 @@ tdm_display_get_capture_available_size(tdm_display *dpy, int *min_w, int *min_h, /* LCOV_EXCL_STOP */ } + capture_backend = private_display->capture_backend; + if (min_w) - *min_w = TDM_FRONT_VALUE(private_display->caps_capture.min_w); + *min_w = TDM_FRONT_VALUE(capture_backend->caps_capture.min_w); if (min_h) - *min_h = TDM_FRONT_VALUE(private_display->caps_capture.min_h); + *min_h = TDM_FRONT_VALUE(capture_backend->caps_capture.min_h); if (max_w) - *max_w = TDM_FRONT_VALUE(private_display->caps_capture.max_w); + *max_w = TDM_FRONT_VALUE(capture_backend->caps_capture.max_w); if (max_h) - *max_h = TDM_FRONT_VALUE(private_display->caps_capture.max_h); + *max_h = TDM_FRONT_VALUE(capture_backend->caps_capture.max_h); if (preferred_align) - *preferred_align = TDM_FRONT_VALUE(private_display->caps_capture.preferred_align); + *preferred_align = TDM_FRONT_VALUE(capture_backend->caps_capture.preferred_align); _pthread_mutex_unlock(&private_display->lock); @@ -243,22 +281,20 @@ tdm_display_get_capture_available_size(tdm_display *dpy, int *min_w, int *min_h, EXTERN tdm_error tdm_display_get_max_layer_count(tdm_display *dpy, int *max_count) { - DISPLAY_FUNC_ENTRY(); - + TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(max_count != NULL, TDM_ERROR_INVALID_PARAMETER); - _pthread_mutex_lock(&private_display->lock); - - *max_count = TDM_FRONT_VALUE(private_display->caps_display.max_layer_count); + TDM_DEPRECATED(NULL); - _pthread_mutex_unlock(&private_display->lock); + *max_count = -1; - return ret; + return TDM_ERROR_NONE; } EXTERN tdm_error tdm_display_get_output_count(tdm_display *dpy, int *count) { + tdm_private_backend *private_backend = NULL; tdm_private_output *private_output = NULL; DISPLAY_FUNC_ENTRY(); @@ -268,14 +304,10 @@ tdm_display_get_output_count(tdm_display *dpy, int *count) _pthread_mutex_lock(&private_display->lock); *count = 0; - LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) - (*count)++; - - if (*count == 0) { - /* LCOV_EXCL_START */ - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_NONE; - /* LCOV_EXCL_STOP */ + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_backend->output_list, link) { + (*count)++; + } } _pthread_mutex_unlock(&private_display->lock); @@ -287,6 +319,7 @@ tdm_display_get_output_count(tdm_display *dpy, int *count) EXTERN tdm_output * tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error) { + tdm_private_backend *private_backend = NULL; tdm_private_output *private_output = NULL; DISPLAY_FUNC_ENTRY_ERROR(); @@ -296,10 +329,12 @@ tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error) if (error) *error = TDM_ERROR_NONE; - LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) { - if (private_output->index == index) { - _pthread_mutex_unlock(&private_display->lock); - return private_output; + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_backend->output_list, link) { + if (private_output->index == index) { + _pthread_mutex_unlock(&private_display->lock); + return private_output; + } } } @@ -374,13 +409,48 @@ EXTERN tdm_error tdm_display_get_backend_info(tdm_display *dpy, const char **name, const char **vendor, int *major, int *minor) { - tdm_backend_module *module_data; + tdm_private_backend *private_backend; + tdm_backend_module *module_data = NULL; DISPLAY_FUNC_ENTRY(); + TDM_DEPRECATED("Use tdm_backend_get_info"); + + _pthread_mutex_lock(&private_display->lock); + + /* use first backend */ + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + module_data = private_backend->module_data; + break; + } + + assert(module_data != NULL); + + if (name) + *name = module_data->name; + if (vendor) + *vendor = module_data->vendor; + if (major) + *major = TDM_BACKEND_GET_ABI_MAJOR(module_data->abi_version); + if (minor) + *minor = TDM_BACKEND_GET_ABI_MINOR(module_data->abi_version); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_backend_get_info(tdm_backend *backend, const char **name, + const char **vendor, int *major, int *minor) +{ + tdm_backend_module *module_data; + + BACKEND_FUNC_ENTRY(); + _pthread_mutex_lock(&private_display->lock); - module_data = private_display->module_data; + module_data = private_backend->module_data; if (name) *name = module_data->name; @@ -405,7 +475,7 @@ tdm_display_create_pp(tdm_display *dpy, tdm_error *error) _pthread_mutex_lock(&private_display->lock); - pp = (tdm_pp *)tdm_pp_create_internal(private_display, error); + pp = (tdm_pp *)tdm_pp_create_internal(private_display->pp_backend, error); _pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_event_loop.c b/src/tdm_event_loop.c index 1745d8e..157c8e8 100644 --- a/src/tdm_event_loop.c +++ b/src/tdm_event_loop.c @@ -60,25 +60,21 @@ typedef struct _tdm_event_loop_source_timer { static tdm_error _tdm_event_loop_main_fd_handler(int fd, tdm_event_loop_mask mask, void *user_data) { - tdm_private_display *private_display = (tdm_private_display*)user_data; - tdm_private_loop *private_loop; + tdm_private_backend *private_backend = (tdm_private_backend*)user_data; tdm_func_display *func_display; tdm_error ret; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); - TDM_RETURN_VAL_IF_FAIL(private_display != NULL, TDM_ERROR_OPERATION_FAILED); - TDM_RETURN_VAL_IF_FAIL(private_display->private_loop != NULL, TDM_ERROR_OPERATION_FAILED); - - private_loop = private_display->private_loop; + TDM_RETURN_VAL_IF_FAIL(private_backend != NULL, TDM_ERROR_OPERATION_FAILED); if (tdm_debug_module & TDM_DEBUG_EVENT) - TDM_INFO("backend fd(%d) event happens", private_loop->backend_fd); + TDM_INFO("backend fd(%d) event happens", private_backend->fd); - func_display = &private_display->func_display; + func_display = &private_backend->func_display; if (!func_display->display_handle_events) return TDM_ERROR_NONE; - ret = func_display->display_handle_events(private_display->bdata); + ret = func_display->display_handle_events(private_backend->bdata); return ret; } @@ -100,8 +96,6 @@ tdm_event_loop_init(tdm_private_display *private_display) return TDM_ERROR_OUT_OF_MEMORY; } - private_loop->backend_fd = -1; - private_loop->wl_display = wl_display_create(); if (!private_loop->wl_display) { TDM_ERR("creating a wayland display failed"); @@ -138,6 +132,8 @@ tdm_event_loop_init(tdm_private_display *private_display) INTERN void tdm_event_loop_deinit(tdm_private_display *private_display) { + tdm_private_backend *private_backend = NULL; + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); if (!private_display->private_loop) @@ -148,8 +144,12 @@ tdm_event_loop_deinit(tdm_private_display *private_display) tdm_server_deinit(private_display->private_loop); - if (private_display->private_loop->backend_source) - tdm_event_loop_source_remove(private_display->private_loop->backend_source); + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + if (private_backend->event_source) + tdm_event_loop_source_remove(private_backend->event_source); + private_backend->event_source = NULL; + private_backend->fd = -1; + } if (private_display->private_loop->wl_display) wl_display_destroy(private_display->private_loop->wl_display); @@ -171,43 +171,42 @@ INTERN void tdm_event_loop_create_backend_source(tdm_private_display *private_display) { tdm_private_loop *private_loop = private_display->private_loop; - tdm_func_display *func_display; + tdm_private_backend *private_backend = NULL; tdm_error ret; int fd = -1; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); TDM_RETURN_IF_FAIL(private_loop != NULL); - func_display = &private_display->func_display; - if (!func_display->display_get_fd) { - TDM_INFO("TDM backend module won't offer a display fd"); - return; - } + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + tdm_func_display *func_display = &private_backend->func_display; - ret = func_display->display_get_fd(private_display->bdata, &fd); - if (fd < 0) { - TDM_ERR("TDM backend module returns fd(%d)", fd); - return; - } + if (!func_display->display_get_fd) { + TDM_INFO("TDM backend module won't offer a display fd"); + private_backend->event_source = NULL; + private_backend->fd = -1; + continue; + } - if (!func_display->display_handle_events) { - TDM_ERR("no display_handle_events function"); - return; - } + ret = func_display->display_get_fd(private_backend->bdata, &fd); - private_loop->backend_source = - tdm_event_loop_add_fd_handler(private_display, fd, - TDM_EVENT_LOOP_READABLE, - _tdm_event_loop_main_fd_handler, - private_display, &ret); - if (!private_loop->backend_source) { - TDM_ERR("no backend fd(%d) source", fd); - return; - } + assert(ret == TDM_ERROR_NONE && fd >= 0); + assert(func_display->display_handle_events); - private_loop->backend_fd = fd; + private_backend->event_source = + tdm_event_loop_add_fd_handler(private_display, fd, + TDM_EVENT_LOOP_READABLE, + _tdm_event_loop_main_fd_handler, + private_backend, &ret); + if (!private_backend->event_source) { + TDM_ERR("no backend fd(%d) source", fd); + return; + } - TDM_INFO("backend fd(%d) source created", private_loop->backend_fd); + private_backend->fd = fd; + + TDM_INFO("backend fd(%d) source created", private_backend->fd); + } } INTERN int diff --git a/src/tdm_helper.c b/src/tdm_helper.c index e3d5f3f..6e2c5cf 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -753,10 +753,9 @@ tdm_helper_capture_output(tdm_output *output, tbm_surface_h dst_buffer, return TDM_ERROR_NONE; } -EXTERN void -tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) +static char * +_tdm_helper_get_backend_information(tdm_private_backend *private_backend, char *reply, int *len) { - tdm_private_display *private_display; tdm_backend_module *module_data; tdm_func_output *func_output; tdm_func_layer *func_layer; @@ -767,27 +766,23 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) tdm_error ret; int i; - TDM_DBG_RETURN_IF_FAIL(dpy != NULL); - - private_display = dpy; - func_output = &private_display->func_output; - func_layer = &private_display->func_layer; + func_output = &private_backend->func_output; + func_layer = &private_backend->func_layer; /* module information */ - module_data = private_display->module_data; - TDM_SNPRINTF(reply, len, "[TDM backend information]\n"); - TDM_SNPRINTF(reply, len, "name: %s\n", module_data->name); + module_data = private_backend->module_data; + TDM_SNPRINTF(reply, len, "['%s' backend information]\n", module_data->name); TDM_SNPRINTF(reply, len, "vendor: %s\n", module_data->vendor); TDM_SNPRINTF(reply, len, "version: %d.%d\n\n", (int)TDM_BACKEND_GET_ABI_MAJOR(module_data->abi_version), (int)TDM_BACKEND_GET_ABI_MINOR(module_data->abi_version)); /* output information */ - TDM_SNPRINTF(reply, len, "[Output information]\n"); + TDM_SNPRINTF(reply, len, "['%s' backend output information]\n", module_data->name); TDM_SNPRINTF(reply, len, "--------------------------------------------------------------------------------------------\n"); TDM_SNPRINTF(reply, len, "idx maker model name type status dpms subpixel align_w min max phy(mm)\n"); TDM_SNPRINTF(reply, len, "--------------------------------------------------------------------------------------------\n"); - LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_backend->output_list, link) { TDM_SNPRINTF(reply, len, "%d %s %s %s %s %s %s %u %d %dx%d %dx%d %ux%u\n", private_output->index, private_output->caps.maker, private_output->caps.model, private_output->caps.name, @@ -805,15 +800,9 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) TDM_SNPRINTF(reply, len, "\t%u modes:\n", private_output->caps.mode_count); if (private_output->caps.mode_count > 0) { - const tdm_output_mode *current_mode = NULL; - - TDM_DBG_RETURN_IF_FAIL(func_output->output_get_mode); - ret = func_output->output_get_mode(private_output->output_backend, ¤t_mode); - TDM_DBG_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); - TDM_SNPRINTF(reply, len, "\t\t name refresh (Hz) clk hdisp hss hse htot vdisp vss vse vtot vscan\n"); for (i = 0; i < private_output->caps.mode_count; i++) { - char *current = (current_mode == private_output->caps.modes + i) ? "*" : " "; + char *current = (private_output->current_mode == private_output->caps.modes + i) ? "*" : " "; TDM_SNPRINTF(reply, len, "\t\t%s%s %u %u %u %u %u %u %u %u %u %u %u ", current, private_output->caps.modes[i].name, @@ -840,11 +829,11 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) TDM_SNPRINTF(reply, len, "\t\tname\ttype\tidx\tvalue\n"); for (i = 0; i < private_output->caps.prop_count; i++) { tdm_value value; - TDM_DBG_RETURN_IF_FAIL(func_output->output_get_property); + TDM_DBG_RETURN_VAL_IF_FAIL(func_output->output_get_property, reply); ret = func_output->output_get_property(private_output->output_backend, private_output->caps.props[i].id, &value); - TDM_DBG_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); + TDM_DBG_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, reply); TDM_SNPRINTF(reply, len, "\t\t%s\t%s\t%u\t", private_output->caps.props[i].name, tdm_value_type_str(private_output->caps.props[i].type), @@ -873,11 +862,11 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) TDM_SNPRINTF(reply, len, "\n"); /* layer information */ - TDM_SNPRINTF(reply, len, "[Layer information]\n"); + TDM_SNPRINTF(reply, len, "['%s' backend layer information]\n", module_data->name); TDM_SNPRINTF(reply, len, "-----------------------------------------------------------------------\n"); TDM_SNPRINTF(reply, len, "idx output zpos buf format size crop geometry transform\n"); TDM_SNPRINTF(reply, len, "-----------------------------------------------------------------------\n"); - LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_backend->output_list, link) { LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) { if (!private_layer->usable) { tdm_info_layer info; @@ -885,10 +874,10 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) tdm_size size; tbm_surface_info_s buf_info; - TDM_DBG_RETURN_IF_FAIL(func_layer->layer_get_info); + TDM_DBG_RETURN_VAL_IF_FAIL(func_layer->layer_get_info, reply); memset(&info, 0, sizeof info); ret = func_layer->layer_get_info(private_layer->layer_backend, &info); - TDM_DBG_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); + TDM_DBG_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, reply); if (!private_layer->showing_buffer) continue; @@ -941,11 +930,11 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) TDM_SNPRINTF(reply, len, "\t\tname\ttype\tidx\tvalue\n"); for (i = 0; i < private_layer->caps.prop_count; i++) { tdm_value value; - TDM_DBG_RETURN_IF_FAIL(func_layer->layer_get_property); + TDM_DBG_RETURN_VAL_IF_FAIL(func_layer->layer_get_property, reply); ret = func_layer->layer_get_property(private_layer->layer_backend, private_layer->caps.props[i].id, &value); - TDM_DBG_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); + TDM_DBG_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, reply); TDM_SNPRINTF(reply, len, "\t\t%s\t%s\t%u\t", private_layer->caps.props[i].name, tdm_value_type_str(private_output->caps.props[i].type), @@ -974,31 +963,31 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) } TDM_SNPRINTF(reply, len, "\n"); - if (private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP) { + if (private_backend->capabilities & TDM_DISPLAY_CAPABILITY_PP) { const char *sep = ""; - TDM_SNPRINTF(reply, len, "[PP information]\n"); + TDM_SNPRINTF(reply, len, "['%s' backend PP information]\n", module_data->name); TDM_SNPRINTF(reply, len, "caps\t: "); - tdm_pp_caps_str(private_display->caps_pp.capabilities, &reply, len); + tdm_pp_caps_str(private_backend->caps_pp.capabilities, &reply, len); TDM_SNPRINTF(reply, len, "\n"); TDM_SNPRINTF(reply, len, "formats\t: "); - for (i = 0; i < private_display->caps_pp.format_count; i++) { - if (private_display->caps_pp.formats[i] == 0) + for (i = 0; i < private_backend->caps_pp.format_count; i++) { + if (private_backend->caps_pp.formats[i] == 0) continue; - TDM_SNPRINTF(reply, len, "%s%c%c%c%c", sep, FOURCC_STR(private_display->caps_pp.formats[i])); + TDM_SNPRINTF(reply, len, "%s%c%c%c%c", sep, FOURCC_STR(private_backend->caps_pp.formats[i])); sep = ","; } TDM_SNPRINTF(reply, len, "\n"); TDM_SNPRINTF(reply, len, "size\t: min(%dx%d) max(%dx%d) align_w(%d)\n", - TDM_FRONT_VALUE(private_display->caps_pp.min_w), - TDM_FRONT_VALUE(private_display->caps_pp.min_h), - TDM_FRONT_VALUE(private_display->caps_pp.max_w), - TDM_FRONT_VALUE(private_display->caps_pp.max_h), - TDM_FRONT_VALUE(private_display->caps_pp.preferred_align)); - if (!LIST_IS_EMPTY(&private_display->pp_list)) { + TDM_FRONT_VALUE(private_backend->caps_pp.min_w), + TDM_FRONT_VALUE(private_backend->caps_pp.min_h), + TDM_FRONT_VALUE(private_backend->caps_pp.max_w), + TDM_FRONT_VALUE(private_backend->caps_pp.max_h), + TDM_FRONT_VALUE(private_backend->caps_pp.preferred_align)); + if (!LIST_IS_EMPTY(&private_backend->pp_list)) { TDM_SNPRINTF(reply, len, "-------------------------------------------------------------\n"); TDM_SNPRINTF(reply, len, "src(format size crop) | dst(format size crop) | transform\n"); TDM_SNPRINTF(reply, len, "-------------------------------------------------------------\n"); - LIST_FOR_EACH_ENTRY(private_pp, &private_display->pp_list, link) { + LIST_FOR_EACH_ENTRY(private_pp, &private_backend->pp_list, link) { TDM_SNPRINTF(reply, len, "%c%c%c%c %ux%u %ux%u+%u+%u | %c%c%c%c %ux%u %ux%u+%u+%u | %s\n", FOURCC_STR(private_pp->info.src_config.format), private_pp->info.src_config.size.h, @@ -1014,35 +1003,35 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) } } } else { - TDM_SNPRINTF(reply, len, "[No PP capability]\n"); + TDM_SNPRINTF(reply, len, "['%s' backend No PP capability]\n", module_data->name); } TDM_SNPRINTF(reply, len, "\n"); - if (private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE) { + if (private_backend->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE) { const char *sep = ""; - TDM_SNPRINTF(reply, len, "[Capture information]\n"); + TDM_SNPRINTF(reply, len, "['%s' backend capture information]\n", module_data->name); TDM_SNPRINTF(reply, len, "caps\t: "); - tdm_capture_caps_str(private_display->caps_capture.capabilities, &reply, len); + tdm_capture_caps_str(private_backend->caps_capture.capabilities, &reply, len); TDM_SNPRINTF(reply, len, "\n"); TDM_SNPRINTF(reply, len, "formats\t: "); - for (i = 0; i < private_display->caps_capture.format_count; i++) { - if (private_display->caps_capture.formats[i] == 0) + for (i = 0; i < private_backend->caps_capture.format_count; i++) { + if (private_backend->caps_capture.formats[i] == 0) continue; - TDM_SNPRINTF(reply, len, "%s%c%c%c%c", sep, FOURCC_STR(private_display->caps_capture.formats[i])); + TDM_SNPRINTF(reply, len, "%s%c%c%c%c", sep, FOURCC_STR(private_backend->caps_capture.formats[i])); sep = ","; } TDM_SNPRINTF(reply, len, "\n"); TDM_SNPRINTF(reply, len, "size\t: min(%dx%d) max(%dx%d) align_w(%d)\n", - TDM_FRONT_VALUE(private_display->caps_capture.min_w), - TDM_FRONT_VALUE(private_display->caps_capture.min_h), - TDM_FRONT_VALUE(private_display->caps_capture.max_w), - TDM_FRONT_VALUE(private_display->caps_capture.max_h), - TDM_FRONT_VALUE(private_display->caps_capture.preferred_align)); - if (!LIST_IS_EMPTY(&private_display->capture_list)) { + TDM_FRONT_VALUE(private_backend->caps_capture.min_w), + TDM_FRONT_VALUE(private_backend->caps_capture.min_h), + TDM_FRONT_VALUE(private_backend->caps_capture.max_w), + TDM_FRONT_VALUE(private_backend->caps_capture.max_h), + TDM_FRONT_VALUE(private_backend->caps_capture.preferred_align)); + if (!LIST_IS_EMPTY(&private_backend->capture_list)) { TDM_SNPRINTF(reply, len, "-----------------------------------\n"); TDM_SNPRINTF(reply, len, "dst(format size crop) | transform\n"); TDM_SNPRINTF(reply, len, "-----------------------------------\n"); - LIST_FOR_EACH_ENTRY(private_capture, &private_display->capture_list, link) { + LIST_FOR_EACH_ENTRY(private_capture, &private_backend->capture_list, link) { TDM_SNPRINTF(reply, len, "%c%c%c%c %ux%u %ux%u+%u+%u | %s\n", FOURCC_STR(private_capture->info.dst_config.format), private_capture->info.dst_config.size.h, @@ -1053,16 +1042,36 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) } } } else { - TDM_SNPRINTF(reply, len, "[No Capture capability]\n"); + TDM_SNPRINTF(reply, len, "['%s' backend No Capture capability]\n", module_data->name); } TDM_SNPRINTF(reply, len, "\n"); + return reply; +} + +EXTERN void +tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) +{ + tdm_private_display *private_display; + tdm_private_backend *private_backend = NULL; + + TDM_DBG_RETURN_IF_FAIL(dpy != NULL); + + private_display = dpy; + + _pthread_mutex_lock(&private_display->lock); + + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + reply = _tdm_helper_get_backend_information(private_backend, reply, len); + } + + _pthread_mutex_unlock(&private_display->lock); } /* LCOV_EXCL_START */ EXTERN int tdm_helper_commit_per_vblank_enabled(tdm_display *dpy) { - TDM_ERR("the deprecated function, use 'tdm_helper_output_commit_per_vblank_enabled' instead."); + TDM_DEPRECATED("Use tdm_helper_output_commit_per_vblank_enabled"); return 0; } diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 417fcd0..ea59e9b 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -74,6 +74,7 @@ tbm_surface_queue_h tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; tbm_surface_queue_h queue = NULL; @@ -81,12 +82,13 @@ tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_get_tbm_buffer_queue) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); if (error) *error = TDM_ERROR_NOT_IMPLEMENTED; return NULL; @@ -104,6 +106,7 @@ EXTERN tdm_error tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, tdm_hwc_window_composition composition_type) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; HWC_WINDOW_FUNC_ENTRY(); @@ -112,12 +115,13 @@ tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_set_composition_type) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -132,6 +136,7 @@ tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, EXTERN tdm_error tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; HWC_WINDOW_FUNC_ENTRY(); @@ -140,12 +145,13 @@ tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region dama _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_set_buffer_damage) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -161,6 +167,7 @@ tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region dama EXTERN tdm_error tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; char fmtstr[128]; @@ -170,12 +177,13 @@ tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info) _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_set_info) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -204,6 +212,7 @@ tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info) EXTERN tdm_error tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window; HWC_WINDOW_FUNC_ENTRY(); @@ -219,12 +228,13 @@ tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer) /* LCOV_EXCL_STOP */ } - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_set_buffer) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -239,13 +249,15 @@ tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer) EXTERN tdm_error tdm_hwc_window_unset_buffer(tdm_hwc_window *hwc_window) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window; HWC_WINDOW_FUNC_ENTRY(); _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_unset_buffer) { /* LCOV_EXCL_START */ @@ -267,7 +279,8 @@ tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, tdm_error *error) { tdm_private_display *private_display = private_output->private_display; - tdm_func_output *func_output = &private_display->func_output; + tdm_private_backend *private_backend = private_output->private_backend; + tdm_func_output *func_output = &private_backend->func_output; tdm_private_hwc_window *private_hwc_window = NULL; tdm_hwc_window *hwc_window_backend = NULL; tdm_error ret = TDM_ERROR_NONE; @@ -336,8 +349,8 @@ tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, INTERN tdm_error tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window) { - tdm_private_display *private_display; tdm_private_output *private_output; + tdm_private_backend *private_backend; tdm_func_output *func_output; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); @@ -345,12 +358,12 @@ tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window) if (!private_hwc_window) return TDM_ERROR_OPERATION_FAILED; - private_display = private_hwc_window->private_display; private_output = private_hwc_window->private_output; + private_backend = private_output->private_backend; LIST_DEL(&private_hwc_window->link); - func_output = &private_display->func_output; + func_output = &private_backend->func_output; func_output->output_hwc_destroy_window(private_output->output_backend, private_hwc_window->hwc_window_backend); free(private_hwc_window); @@ -360,18 +373,20 @@ tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window) EXTERN tdm_error tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; HWC_WINDOW_FUNC_ENTRY(); _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_set_flags) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -386,18 +401,20 @@ tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags) EXTERN tdm_error tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; HWC_WINDOW_FUNC_ENTRY(); _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_unset_flags) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -427,6 +444,7 @@ _tdm_hwc_window_layer_commit_handler(tdm_layer *layer, unsigned int sequence, tdm_error tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; tdm_private_hwc_window_commit_handler *hwc_window_commit_handler; tdm_layer *layer = NULL; @@ -439,7 +457,8 @@ tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_get_layer) { /* LCOV_EXCL_START */ @@ -522,6 +541,7 @@ EXTERN tdm_error tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, tdm_hwc_window_video_capability *video_capability) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; HWC_WINDOW_FUNC_ENTRY(); @@ -530,12 +550,13 @@ tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_video_get_capability) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -552,6 +573,7 @@ EXTERN tdm_error tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, const tdm_prop **props, int *count) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; HWC_WINDOW_FUNC_ENTRY(); @@ -561,12 +583,13 @@ tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_video_get_available_properties) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -583,6 +606,7 @@ EXTERN tdm_error tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; HWC_WINDOW_FUNC_ENTRY(); @@ -591,12 +615,13 @@ tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_video_get_property) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -613,18 +638,20 @@ EXTERN tdm_error tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value) { + tdm_private_backend *private_backend; tdm_func_hwc_window *func_hwc_window = NULL; HWC_WINDOW_FUNC_ENTRY(); _pthread_mutex_lock(&private_display->lock); - func_hwc_window = &private_display->func_hwc_window; + private_backend = private_output->private_backend; + func_hwc_window = &private_backend->func_hwc_window; if (!func_hwc_window->hwc_window_video_set_property) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } diff --git a/src/tdm_layer.c b/src/tdm_layer.c index 2d31817..3afebd1 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -170,12 +170,14 @@ tdm_layer_get_zpos(tdm_layer *layer, int *zpos) EXTERN tdm_error tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) { + tdm_private_backend *private_backend; tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); _pthread_mutex_lock(&private_display->lock); - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; if (private_layer->usable) TDM_INFO("layer(%d) not usable", private_layer->index); @@ -200,6 +202,7 @@ tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) EXTERN tdm_error tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) { + tdm_private_backend *private_backend; tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); @@ -207,7 +210,8 @@ tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) _pthread_mutex_lock(&private_display->lock); - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; if (!func_layer->layer_get_property) { /* LCOV_EXCL_START */ @@ -227,12 +231,12 @@ tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) INTERN tdm_error tdm_layer_set_info_internal(tdm_private_layer *private_layer, tdm_info_layer *info) { - tdm_private_output *private_output = private_layer->private_output; - tdm_private_display *private_display = private_output->private_display; + tdm_private_backend *private_backend; tdm_func_layer *func_layer; char fmtstr[128]; - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; if (private_layer->usable) TDM_INFO("layer(%p) not usable", private_layer); @@ -285,6 +289,7 @@ tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) EXTERN tdm_error tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info) { + tdm_private_backend *private_backend; tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); @@ -292,7 +297,8 @@ tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info) _pthread_mutex_lock(&private_display->lock); - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; if (!func_layer->layer_get_info) { /* LCOV_EXCL_START */ @@ -437,8 +443,8 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) INTERN tdm_error tdm_layer_set_buffer_internal(tdm_private_layer *private_layer, tbm_surface_h buffer) { + tdm_private_backend *private_backend; tdm_private_output *private_output = private_layer->private_output; - tdm_private_display *private_display = private_output->private_display; tdm_func_layer *func_layer; /* LCOV_EXCL_START */ @@ -456,7 +462,8 @@ tdm_layer_set_buffer_internal(tdm_private_layer *private_layer, tbm_surface_h bu } /* LCOV_EXCL_STOP */ - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; if (private_layer->usable) TDM_INFO("layer(%p) not usable", private_layer); @@ -520,12 +527,12 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) INTERN tdm_error tdm_layer_unset_buffer_internal(tdm_private_layer *private_layer) { - tdm_private_output *private_output = private_layer->private_output; - tdm_private_display *private_display = private_output->private_display; + tdm_private_backend *private_backend; tdm_func_layer *func_layer; tdm_error ret = TDM_ERROR_NONE; - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; _tdm_layer_free_all_buffers(private_layer); @@ -840,12 +847,12 @@ _tdm_layer_reset_pending_data(tdm_private_layer *private_layer) INTERN tdm_error tdm_layer_commit_pending_data(tdm_private_layer *private_layer) { - tdm_private_output *private_output = private_layer->private_output; - tdm_private_display *private_display = private_output->private_display; + tdm_private_backend *private_backend; tdm_func_layer *func_layer; tdm_error ret = TDM_ERROR_NONE; - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; if (private_layer->pending_info_changed) { ret = func_layer->layer_set_info(private_layer->layer_backend, &private_layer->pending_info); @@ -1124,6 +1131,7 @@ _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data) { TDM_RETURN_IF_FAIL(data != NULL); tdm_layer *layer = data; + tdm_private_backend *private_backend; tdm_func_layer *func_layer; tbm_surface_h surface = NULL; tdm_private_layer_buffer *layer_buffer; @@ -1131,7 +1139,9 @@ _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data) _pthread_mutex_lock(&private_display->lock); - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; + if (!func_layer->layer_set_buffer) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); @@ -1216,6 +1226,7 @@ _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data) EXTERN tdm_error tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue) { + tdm_private_backend *private_backend; tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); @@ -1223,7 +1234,8 @@ tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue) _pthread_mutex_lock(&private_display->lock); - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; if (private_layer->usable) TDM_INFO("layer(%p) not usable", private_layer); @@ -1289,12 +1301,14 @@ tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable) EXTERN tdm_error tdm_layer_set_video_pos(tdm_layer *layer, int zpos) { + tdm_private_backend *private_backend; tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); _pthread_mutex_lock(&private_display->lock); - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) { TDM_ERR("layer(%p) is not video layer", private_layer); @@ -1336,13 +1350,15 @@ tdm_layer_create_capture(tdm_layer *layer, tdm_error *error) EXTERN tdm_error tdm_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags) { + tdm_private_backend *private_backend; tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(flags != NULL, TDM_ERROR_INVALID_PARAMETER); _pthread_mutex_lock(&private_display->lock); - func_layer = &private_display->func_layer; + private_backend = private_layer->private_backend; + func_layer = &private_backend->func_layer; if (!func_layer->layer_get_buffer_flags) { /* LCOV_EXCL_START */ diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 98f25b4..5d41886 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -74,8 +74,6 @@ extern "C" { #define TDM_SWAP(a, b) ({ int t; t = a; a = b; b = t; }) #define TDM_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -#define TDM_NEVER_GET_HERE() TDM_WRN("** NEVER GET HERE **") - #define TDM_SNPRINTF(p, len, fmt, ARG...) \ do { \ if (p && len && *len > 0) { \ @@ -368,6 +366,12 @@ TDM_BIT_NAME_FB(capture_caps) return; \ } \ } +#define TDM_DBG_RETURN_VAL_IF_FAIL(cond, val) { \ + if (!(cond)) { \ + TDM_SNPRINTF(reply, len, "[%s %d] '%s' failed\n", __func__, __LINE__, #cond); \ + return val; \ + } \ +} #define TDM_DBG_GOTO_IF_FAIL(cond, dst) { \ if (!(cond)) { \ TDM_SNPRINTF(reply, len, "[%s %d] '%s' failed\n", __func__, __LINE__, #cond); \ diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index f1edee7..e566681 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -43,9 +43,7 @@ static void _tdm_monitor_server_usage(char *app_name, char *reply, int *len); static void _tdm_monitor_server_query(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) { - tdm_display_lock(dpy); tdm_helper_get_display_information(dpy, reply, len); - tdm_display_unlock(dpy); } static void diff --git a/src/tdm_output.c b/src/tdm_output.c index accdfa3..689eed0 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -145,6 +145,25 @@ tdm_output_init(tdm_private_display *private_display) return TDM_ERROR_NONE; } +EXTERN tdm_backend * +tdm_output_get_backend(tdm_output *output, tdm_error *error) +{ + tdm_private_backend *private_backend; + + OUTPUT_FUNC_ENTRY_ERROR(); + + _pthread_mutex_lock(&private_display->lock); + + private_backend = private_output->private_backend; + + if (error) + *error = TDM_ERROR_NONE; + + _pthread_mutex_unlock(&private_display->lock); + + return private_backend; +} + EXTERN tdm_error tdm_output_get_model_info(tdm_output *output, const char **maker, const char **model, const char **name) @@ -201,15 +220,12 @@ tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status) static void _tdm_output_update(tdm_output *output_backend, void *user_data) { - tdm_private_display *private_display; tdm_private_output *private_output = user_data; tdm_error ret; TDM_RETURN_IF_FAIL(private_output); - private_display = private_output->private_display; - - ret = tdm_display_update_output(private_display, output_backend, private_output->pipe); + ret = tdm_display_update_output(private_output->private_backend, output_backend, private_output->pipe); TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); } /* LCOV_EXCL_STOP */ @@ -514,7 +530,7 @@ tdm_output_get_cursor_available_size(tdm_output *output, int *min_w, int *min_h, _pthread_mutex_lock(&private_display->lock); - if (!tdm_display_check_module_abi(private_display, 1, 5)) { + if (!tdm_backend_check_module_abi(private_output->private_backend, 1, 5)) { if (min_w) *min_w = -1; @@ -621,17 +637,19 @@ tdm_output_get_primary_index(tdm_output *output, int *index) EXTERN tdm_error tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value) { + tdm_private_backend *private_backend; tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); _pthread_mutex_lock(&private_display->lock); - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_set_property) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -647,6 +665,7 @@ tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value) EXTERN tdm_error tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) { + tdm_private_backend *private_backend; tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); @@ -654,12 +673,13 @@ tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) _pthread_mutex_lock(&private_display->lock); - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_get_property) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -840,13 +860,15 @@ _tdm_output_wait_vblank(tdm_private_output *private_output, int interval, int sy tdm_output_vblank_handler func, void *user_data, unsigned int add_front) { + tdm_private_backend *private_backend; tdm_func_output *func_output; tdm_private_output_vblank_handler *vblank_handler = NULL, *v = NULL; unsigned int skip_request = 0; pid_t tid = syscall(SYS_gettid); tdm_error ret = TDM_ERROR_NONE; - func_output = &private_output->private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; /* interval SHOULD be at least 1 */ if (interval <= 0) @@ -854,7 +876,7 @@ _tdm_output_wait_vblank(tdm_private_output *private_output, int interval, int sy if (!func_output->output_wait_vblank) { /* LCOV_EXCL_START */ - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -1041,18 +1063,23 @@ tdm_output_remove_commit_handler(tdm_output *output, tdm_output_commit_handler f INTERN tdm_error tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data) { + tdm_private_output *private_output; + tdm_private_backend *private_backend; tdm_func_output *func_output; tdm_private_output_commit_handler *output_commit_handler = NULL; tdm_private_layer *private_layer = NULL; tdm_output_dpms dpms_value = TDM_OUTPUT_DPMS_ON; + tdm_error ret = TDM_ERROR_NONE; - OUTPUT_FUNC_ENTRY(); + TDM_RETURN_VAL_IF_FAIL(tdm_output_is_valid(output), TDM_ERROR_INVALID_PARAMETER); - func_output = &private_display->func_output; + private_output = (tdm_private_output*)output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_commit) { /* LCOV_EXCL_START */ - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -1182,6 +1209,7 @@ tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, EXTERN tdm_error tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode) { + tdm_private_backend *private_backend; tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); @@ -1189,12 +1217,13 @@ tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode) _pthread_mutex_lock(&private_display->lock); - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_set_mode) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -1230,6 +1259,7 @@ tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode) EXTERN tdm_error tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) { + tdm_private_backend *private_backend; tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); @@ -1254,7 +1284,8 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) return TDM_ERROR_BAD_REQUEST; } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; TDM_INFO("output(%d) dpms '%s'", private_output->pipe, tdm_dpms_str(dpms_value)); @@ -1295,6 +1326,7 @@ done: EXTERN tdm_error tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) { + tdm_private_backend *private_backend; tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); @@ -1324,15 +1356,16 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) return TDM_ERROR_BAD_REQUEST; } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_set_dpms_handler) { - TDM_ERR("not implemented: output_set_dpms_handler"); + TDM_WRN("not implemented: output_set_dpms_handler"); _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NOT_IMPLEMENTED; } if (!func_output->output_set_dpms_async) { - TDM_ERR("not implemented: output_set_dpms_async"); + TDM_WRN("not implemented: output_set_dpms_async"); _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NOT_IMPLEMENTED; } @@ -1373,10 +1406,14 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) INTERN tdm_error tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) { + tdm_private_output *private_output; + tdm_private_backend *private_backend; tdm_func_output *func_output; - OUTPUT_FUNC_ENTRY(); + tdm_error ret = TDM_ERROR_NONE; - TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(tdm_output_is_valid(output), TDM_ERROR_INVALID_PARAMETER); + + private_output = (tdm_private_output*)output; /* TODO: this is ugly. But before calling backend's output_get_dpms(), we have * to check if all backends's DPMS operation has no problem. In future, we'd @@ -1388,7 +1425,8 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) return TDM_ERROR_NONE; } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_get_dpms) { /* LCOV_EXCL_START */ @@ -1520,6 +1558,7 @@ EXTERN tdm_error tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types) { + tdm_private_backend *private_backend; tdm_func_output *func_output = NULL; tdm_private_hwc_window **composited_wnds_frontend = NULL; tdm_hwc_window **composited_wnds_backend = NULL; @@ -1537,12 +1576,13 @@ tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, return TDM_ERROR_BAD_REQUEST; } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_hwc_validate) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -1613,6 +1653,7 @@ tdm_output_hwc_get_changed_composition_types(tdm_output *output, tdm_hwc_window **hwc_window, tdm_hwc_window_composition *composition_types) { + tdm_private_backend *private_backend; tdm_func_output *func_output = NULL; tdm_private_hwc_window * private_hwc_window = NULL; int i = 0; @@ -1629,12 +1670,13 @@ tdm_output_hwc_get_changed_composition_types(tdm_output *output, return TDM_ERROR_BAD_REQUEST; } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_hwc_get_changed_composition_types) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -1678,6 +1720,7 @@ tdm_output_hwc_get_changed_composition_types(tdm_output *output, tdm_error tdm_output_hwc_accept_changes(tdm_output *output) { + tdm_private_backend *private_backend; tdm_func_output *func_output = NULL; OUTPUT_FUNC_ENTRY(); @@ -1690,12 +1733,13 @@ tdm_output_hwc_accept_changes(tdm_output *output) return TDM_ERROR_BAD_REQUEST; } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_hwc_validate) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -1710,6 +1754,7 @@ tdm_output_hwc_accept_changes(tdm_output *output) tbm_surface_queue_h tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error) { + tdm_private_backend *private_backend; tdm_func_output *func_output = NULL; tbm_surface_queue_h queue = NULL; @@ -1725,12 +1770,13 @@ tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error) return NULL; } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_hwc_get_target_buffer_queue) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return NULL; /* LCOV_EXCL_STOP */ } @@ -1745,6 +1791,7 @@ tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error) EXTERN tdm_error tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target_buffer, tdm_hwc_region damage) { + tdm_private_backend *private_backend; tdm_func_output *func_output = NULL; OUTPUT_FUNC_ENTRY(); @@ -1767,12 +1814,13 @@ tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target /* LCOV_EXCL_STOP */ } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_hwc_set_client_target_buffer) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -1787,6 +1835,7 @@ tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target EXTERN tdm_error tdm_output_hwc_unset_client_target_buffer(tdm_output *output) { + tdm_private_backend *private_backend; tdm_func_output *func_output = NULL; OUTPUT_FUNC_ENTRY(); @@ -1799,7 +1848,8 @@ tdm_output_hwc_unset_client_target_buffer(tdm_output *output) return TDM_ERROR_BAD_REQUEST; } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_hwc_unset_client_target_buffer) { /* LCOV_EXCL_START */ @@ -1834,6 +1884,7 @@ _tdm_output_hwc_layer_commit_handler(tdm_layer *layer, unsigned int sequence, tdm_error tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_target_buffer_commit_handler func, void *user_data) { + tdm_private_backend *private_backend; tdm_func_output *func_output; tdm_private_output_hwc_target_buffer_commit_handler *output_hwc_target_buffer_commit_handler; tdm_layer *layer = NULL; @@ -1851,7 +1902,8 @@ tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_ta return TDM_ERROR_BAD_REQUEST; } - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_hwc_get_client_target_buffer_layer) { /* LCOV_EXCL_START */ @@ -1949,6 +2001,7 @@ tdm_error tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format **formats, int *count) { + tdm_private_backend *private_backend; tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); @@ -1957,12 +2010,13 @@ tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format _pthread_mutex_lock(&private_display->lock); - func_output = &private_display->func_output; + private_backend = private_output->private_backend; + func_output = &private_backend->func_output; if (!func_output->output_hwc_get_video_supported_formats) { /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); + TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; /* LCOV_EXCL_STOP */ } @@ -1978,13 +2032,10 @@ tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format static int _is_hwc_output_still_existed(tdm_private_output *private_output) { - tdm_private_display *dpy; + tdm_private_backend *private_backend = private_output->private_backend; tdm_private_output *o = NULL; - dpy = tdm_display_init(NULL); - TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_OPERATION_FAILED); - - LIST_FOR_EACH_ENTRY(o, &dpy->output_list, link) { + LIST_FOR_EACH_ENTRY(o, &private_backend->output_list, link) { if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) continue; @@ -1992,11 +2043,9 @@ _is_hwc_output_still_existed(tdm_private_output *private_output) goto exist; } - tdm_display_deinit(dpy); return 0; exist: - tdm_display_deinit(dpy); return 1; } diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 8f4fd8d..cdc0bde 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -40,6 +40,7 @@ #include "tdm_private.h" #define PP_FUNC_ENTRY() \ + tdm_private_backend *private_backend; \ tdm_func_pp *func_pp; \ tdm_private_display *private_display; \ tdm_private_pp *private_pp; \ @@ -47,7 +48,8 @@ TDM_RETURN_VAL_IF_FAIL(pp != NULL, TDM_ERROR_INVALID_PARAMETER); \ private_pp = (tdm_private_pp*)pp; \ private_display = private_pp->private_display; \ - func_pp = &private_display->func_pp + private_backend = private_pp->private_backend; \ + func_pp = &private_backend->func_pp static void _tdm_pp_print_list(struct list_head *list) @@ -178,13 +180,16 @@ _tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, void * static void * _tdm_pp_find_object(tdm_private_display *private_display, double stamp) { + tdm_private_backend *private_backend = NULL; tdm_private_pp *private_pp = NULL; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); - LIST_FOR_EACH_ENTRY(private_pp, &private_display->pp_list, link) { - if (private_pp->stamp == stamp) - return private_pp; + LIST_FOR_EACH_ENTRY(private_backend, &private_display->backend_list, link) { + LIST_FOR_EACH_ENTRY(private_pp, &private_backend->pp_list, link) { + if (private_pp->stamp == stamp) + return private_pp; + } } return NULL; @@ -199,8 +204,9 @@ tdm_pp_init(tdm_private_display *private_display) } INTERN tdm_private_pp * -tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) +tdm_pp_create_internal(tdm_private_backend *private_backend, tdm_error *error) { + tdm_private_display *private_display; tdm_func_display *func_display; tdm_func_pp *func_pp; tdm_private_pp *private_pp = NULL; @@ -208,20 +214,22 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) tdm_error ret = TDM_ERROR_NONE; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); + TDM_RETURN_VAL_IF_FAIL(private_backend != NULL, NULL); - func_display = &private_display->func_display; - func_pp = &private_display->func_pp; + private_display = private_backend->private_display; + func_display = &private_backend->func_display; + func_pp = &private_backend->func_pp; - if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) { + if (!(private_backend->capabilities & TDM_DISPLAY_CAPABILITY_PP)) { /* LCOV_EXCL_START */ - TDM_ERR("no pp capability"); + TDM_ERR("backedn(%s) no pp capability", private_backend->module_data->name); if (error) *error = TDM_ERROR_NO_CAPABILITY; return NULL; /* LCOV_EXCL_STOP */ } - pp_backend = func_display->display_create_pp(private_display->bdata, &ret); + pp_backend = func_display->display_create_pp(private_backend->bdata, &ret); if (ret != TDM_ERROR_NONE) { /* LCOV_EXCL_START */ if (error) @@ -267,8 +275,9 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) while (_tdm_pp_find_object(private_display, private_pp->stamp)) private_pp->stamp++; - LIST_ADD(&private_pp->link, &private_display->pp_list); - private_pp->private_display = private_display; + LIST_ADD(&private_pp->link, &private_backend->pp_list); + private_pp->private_display = private_backend->private_display; + private_pp->private_backend = private_backend; private_pp->pp_backend = pp_backend; private_pp->owner_tid = syscall(SYS_gettid); @@ -285,6 +294,7 @@ INTERN void tdm_pp_destroy_internal(tdm_private_pp *private_pp) { tdm_private_display *private_display; + tdm_private_backend *private_backend; tdm_func_pp *func_pp; tdm_pp_private_buffer *b = NULL, *bb = NULL; struct list_head clone_list; @@ -297,7 +307,8 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) tdm_thread_cb_remove(private_pp, TDM_THREAD_CB_PP_DONE, NULL, _tdm_pp_thread_cb_done, NULL); private_display = private_pp->private_display; - func_pp = &private_display->func_pp; + private_backend = private_pp->private_backend; + func_pp = &private_backend->func_pp; LIST_DEL(&private_pp->link); @@ -457,15 +468,15 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) /* LCOV_EXCL_STOP */ } - if (tdm_display_check_module_abi(private_display, 1, 2) && - private_display->caps_pp.max_attach_count > 0) { + if (tdm_backend_check_module_abi(private_backend, 1, 2) && + private_backend->caps_pp.max_attach_count > 0) { /* LCOV_EXCL_START */ int length = LIST_LENGTH(&private_pp->pending_buffer_list) + LIST_LENGTH(&private_pp->buffer_list); - if (length >= private_display->caps_pp.max_attach_count) { + if (length >= private_backend->caps_pp.max_attach_count) { _pthread_mutex_unlock(&private_display->lock); - TDM_DBG("failed: too many attached!! max_attach_count(%d)", - private_display->caps_pp.max_attach_count); + TDM_DBG("failed: backend(%s) too many attached!! max_attach_count(%d)", + private_backend->module_data->name, private_backend->caps_pp.max_attach_count); return TDM_ERROR_BAD_REQUEST; } /* LCOV_EXCL_STOP */ diff --git a/src/tdm_private.h b/src/tdm_private.h index a35aea8..45b1bab 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -88,7 +88,7 @@ tdm_private_display * tdm_display_get(void); int -tdm_display_check_module_abi(tdm_private_display *private_display, int abimaj, int abimin); +tdm_backend_check_module_abi(tdm_private_backend *private_backend, int abimaj, int abimin); void * tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp); @@ -166,7 +166,7 @@ tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len); tdm_error tdm_pp_init(tdm_private_display *private_display); tdm_private_pp * -tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error); +tdm_pp_create_internal(tdm_private_backend *private_backend, tdm_error *error); void tdm_pp_destroy_internal(tdm_private_pp *private_pp); @@ -228,7 +228,7 @@ extern int tdm_dump_enable; extern char *tdm_debug_dump_dir; tdm_error -tdm_display_update_output(tdm_private_display *private_display, +tdm_display_update_output(tdm_private_backend *private_backend, tdm_output *output_backend, int pipe); tdm_error tdm_display_enable_debug_module(const char*modules); diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 77393f1..099dae1 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -96,6 +96,7 @@ typedef enum { TDM_COMMIT_TYPE_LAYER, } tdm_commit_type; +typedef struct _tdm_private_backend tdm_private_backend; typedef struct _tdm_private_display tdm_private_display; typedef struct _tdm_private_output tdm_private_output; typedef struct _tdm_private_layer tdm_private_layer; @@ -114,21 +115,16 @@ typedef struct _tdm_private_output_hwc_target_buffer_window_commit_handler tdm_p typedef struct _tdm_private_layer_buffer tdm_private_layer_buffer; -struct _tdm_private_display { - pthread_mutex_t lock; - unsigned int init_count; +struct _tdm_private_backend { + struct list_head link; - double stamp; + tdm_private_display *private_display; /* backend module info */ void *module; tdm_backend_module *module_data; tdm_backend_data *bdata; -#ifdef INIT_BUFMGR - tbm_bufmgr bufmgr; -#endif - /* backend function */ tdm_display_capability capabilities; tdm_func_display func_display; @@ -148,20 +144,39 @@ struct _tdm_private_display { struct list_head pp_list; struct list_head capture_list; - void **outputs_ptr; + /* backend output objects. allocated in backend. freed in frontend. ordered */ + tdm_output **outputs; + + int fd; + tdm_event_loop_source *event_source; +}; + +struct _tdm_private_display { + pthread_mutex_t lock; + unsigned int init_count; + + double stamp; + +#ifdef INIT_BUFMGR + tbm_bufmgr bufmgr; +#endif + + struct list_head backend_list; + tdm_private_backend *current_backend; //setted only when loading + tdm_private_backend *pp_backend; //pp-support backend + tdm_private_backend *capture_backend; //TODO: remove later /* for event handling */ tdm_private_loop *private_loop; - /* output order */ - tdm_output **outputs; - int print_fps; }; struct _tdm_private_output { struct list_head link; + tdm_private_backend *private_backend; + int index; double stamp; @@ -221,6 +236,8 @@ struct _tdm_private_output { struct _tdm_private_layer { struct list_head link; + tdm_private_backend *private_backend; + int index; tdm_private_display *private_display; @@ -267,6 +284,8 @@ struct _tdm_private_hwc_window { struct _tdm_private_pp { struct list_head link; + tdm_private_backend *private_backend; + double stamp; tdm_private_display *private_display; @@ -287,6 +306,8 @@ struct _tdm_private_capture { struct list_head link; struct list_head display_link; + tdm_private_backend *private_backend; + double stamp; tdm_capture_target target; @@ -320,9 +341,6 @@ struct _tdm_private_loop { struct wl_display *wl_display; struct wl_event_loop *wl_loop; - int backend_fd; - tdm_event_loop_source *backend_source; - /* In event loop, all resources are accessed by this dpy. * CAUTION: * - DO NOT include other private structure in this structure because this diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 12b760d..d0839ba 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -350,7 +350,7 @@ _tdm_vblank_free_HW_wait(tdm_private_vblank *private_vblank, tdm_error error, un pid_t pid; const char *proc_name; _tdm_vblank_get_client_information(private_vblank, &pid, &proc_name); - VER("TDM HW vblank destroyed forcely!! (pid: %u, name: %s)", pid, proc_name); + VWR("TDM HW vblank destroyed forcely!! (pid: %u, name: %s)", pid, proc_name); } LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->HW_wait_list, link) { -- 2.7.4 From 9c7adf6d4fe394be239b1b134159c15a5c614bee Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 15:28:25 +0900 Subject: [PATCH 07/16] remove unused file Change-Id: I8c4e786bd29a33d5dad356d517fa137798dfac66 --- 0001-save.patch | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 0001-save.patch diff --git a/0001-save.patch b/0001-save.patch deleted file mode 100644 index 25ad8f0..0000000 --- a/0001-save.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 60fa1ef61f143eb5310588bba987bdfce5d33ad1 Mon Sep 17 00:00:00 2001 -From: Boram Park -Date: Wed, 21 Feb 2018 15:26:17 +0900 -Subject: [PATCH] save - -Change-Id: I5e33d25ad3678f4a77c5ec4396af2b1b45a32488 ---- - include/tdm.h | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/include/tdm.h b/include/tdm.h -index f4aa8d8..3cae42f 100644 ---- a/include/tdm.h -+++ b/include/tdm.h -@@ -222,10 +222,10 @@ tdm_backend_get_info(tdm_backend *backend, const char **name, - const char **vendor, int *major, int *minor); - - /** -- * @brief Get the capabilities of a output object. -+ * @brief Get a backend object of the given output. - * @param[in] output A output object -- * @param[out] capabilities The capabilities of a output object -- * @return #TDM_ERROR_NONE if success. Otherwise, error value. -+ * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. -+ * @return A backend object if success. Otherwise, NULL. - */ - tdm_backend * - tdm_output_get_backend(tdm_output *output, tdm_error *error); --- -1.9.1 - -- 2.7.4 From d7cab3249db011494da88586a9488de357194b15 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 16:09:04 +0900 Subject: [PATCH 08/16] log: restore stdout when set NULL. Change-Id: I25934b33f8468e55fdd063068f868fafab81f948 --- common/tdm_log.c | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index 3ddcda1..1befbfb 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -69,6 +69,8 @@ static pthread_mutex_t log_lock; unsigned int tdm_log_debug_level = TDM_LOG_LEVEL_INFO; +static int stdout_fd = -1; + EXTERN void tdm_log_enable_color(unsigned int enable) { @@ -105,26 +107,40 @@ tdm_log_set_assert_level(int level) EXTERN void tdm_log_set_path(const char *path) { - char fd_name[TDM_PATH_LEN]; - int log_fd = -1; - FILE *log_fl; + if (!path) { + if (stdout_fd != -1) { + fflush(stdout); + close(STDOUT_FILENO); + dup2(stdout_fd, STDOUT_FILENO); + close(stdout_fd); + stdout_fd = -1; + } + } else { + char fd_name[TDM_PATH_LEN]; + int log_fd = -1; + FILE *log_fl; - snprintf(fd_name, TDM_PATH_LEN, "%s", path); + snprintf(fd_name, TDM_PATH_LEN, "%s", path); - log_fl = fopen(fd_name, "a"); - if (!log_fl) { - TDM_ERR("failed: open file(%s)\n", fd_name); - return; - } + log_fl = fopen(fd_name, "a"); + if (!log_fl) { + TDM_ERR("failed: open file(%s)\n", fd_name); + return; + } - fflush(stdout); - close(STDOUT_FILENO); + if (stdout_fd == -1) { + fflush(stdout); + stdout_fd = dup(STDOUT_FILENO); + TDM_RETURN_IF_FAIL(stdout_fd != -1); + } - setvbuf(log_fl, NULL, _IOLBF, 512); - log_fd = fileno(log_fl); + setvbuf(log_fl, NULL, _IOLBF, 512); + log_fd = fileno(log_fl); - dup2(log_fd, STDOUT_FILENO); - fclose(log_fl); + close(STDOUT_FILENO); + dup2(log_fd, STDOUT_FILENO); + fclose(log_fl); + } } EXTERN void -- 2.7.4 From 65b89e98b7f61add110439f250cceab0e106c4af Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 22 Feb 2018 08:38:55 +0900 Subject: [PATCH 09/16] macro: move backend's name definition Change-Id: I53d086d54b8a9b13f686f91d93d6d543ffe0059e --- src/tdm.c | 4 ---- src/tdm_macro.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index d744875..3a0ecad 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -682,10 +682,6 @@ tdm_display_update(tdm_display *dpy) return TDM_ERROR_NONE; } -#define SUFFIX_MODULE ".so" -#define TDM_DEFAULT_MODULE "libtdm-default"SUFFIX_MODULE -#define TDM_DUMMY_MODULE "libtdm-dummy"SUFFIX_MODULE - int tdm_debug_module; int tdm_debug_dump; int tdm_ttrace_module; diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 5d41886..88dc034 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -83,6 +83,10 @@ extern "C" { } \ } while (0) +/* common backend names *****************************************************/ +#define TDM_DEFAULT_MODULE "libtdm-default.so" +#define TDM_DUMMY_MODULE "libtdm-dummy.so" + /* dump directory ***********************************************************/ #define TDM_DUMP_DIR "/tmp" -- 2.7.4 From 3e00a0eecd370289ff30426836f50c1e7874566e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 22 Feb 2018 14:02:51 +0900 Subject: [PATCH 10/16] thread: use two lists for each thread When tdm_thread_call_cb is called in both threads at the same time, the 'called' variable makes a thread issue. 1) Calling tdm_thread_call_cb in display-thread makes the 'called' variable as 1 2) Calling tdm_thread_call_cb in tdm-thread at the same time checks cb->called. 3) Because cb->called is 1 by display-thread, tdm_thread_call_cb in tdm-thread does nothing. Change-Id: I009e3a17b40d32502f3567b8ecd712fa7c8dc349 --- src/tdm_thread.c | 119 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 82 insertions(+), 37 deletions(-) diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 30966b4..6058bb3 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -69,11 +69,13 @@ typedef struct _tdm_private_thread_cb { void *user_data; pid_t owner_tid; - unsigned int called; } tdm_private_thread_cb; static tdm_thread_find_object find_funcs[TDM_THREAD_CB_MAX] = {0, }; -static struct list_head cb_list; + +/* 0: for display thread, 1: for tdm thread */ +static struct list_head cb_list[2]; +static pthread_mutex_t cb_list_lock; static void _tdm_thread_free_cb(tdm_private_thread_cb *cb); @@ -193,13 +195,19 @@ tdm_thread_init(tdm_private_loop *private_loop) private_display = private_loop->dpy; TDM_RETURN_VAL_IF_FAIL(private_display->private_loop, TDM_ERROR_OPERATION_FAILED); + if (private_loop->private_thread) + return TDM_ERROR_NONE; + for (i = 0; i < TDM_THREAD_CB_MAX; i++) find_funcs[i] = NULL; - LIST_INITHEAD(&cb_list); + if (pthread_mutex_init(&cb_list_lock, NULL)) { + TDM_ERR("mutex init failed: %m"); + return TDM_ERROR_OUT_OF_MEMORY; + } - if (private_loop->private_thread) - return TDM_ERROR_NONE; + LIST_INITHEAD(&cb_list[0]); + LIST_INITHEAD(&cb_list[1]); /* enable as default */ thread = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); @@ -291,7 +299,12 @@ tdm_thread_deinit(tdm_private_loop *private_loop) tdm_log_reset(); - LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &cb_list, link) { + pthread_mutex_destroy(&cb_list_lock); + + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &cb_list[0], link) { + _tdm_thread_free_cb(cb); + } + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &cb_list[1], link) { _tdm_thread_free_cb(cb); } @@ -358,7 +371,7 @@ tdm_thread_send_cb(tdm_private_loop *private_loop, tdm_thread_cb_base *base) pipe = private_thread->pipe[1]; if (tdm_debug_module & TDM_DEBUG_THREAD) - TDM_INFO("fd(%d) type(%d), length(%d)", pipe, base->type, base->length); + TDM_INFO("fd(%d) type(%s), length(%d)", pipe, tdm_cb_type_str(base->type), base->length); len = write(pipe, base, base->length); if (len != base->length) { @@ -419,7 +432,7 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) while (i < len) { base = (tdm_thread_cb_base*)&buffer[i]; if (tdm_debug_module & TDM_DEBUG_THREAD) - TDM_INFO("type(%d), length(%d)", base->type, base->length); + TDM_INFO("type(%s), length(%d)", tdm_cb_type_str(base->type), base->length); switch (base->type) { case TDM_THREAD_CB_OUTPUT_COMMIT: case TDM_THREAD_CB_OUTPUT_VBLANK: @@ -472,34 +485,24 @@ _tdm_thread_free_cb(tdm_private_thread_cb *cb) } static tdm_private_thread_cb * -_tdm_thread_find_cb(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_thread_cb func, void *user_data, pid_t owner_tid) +_tdm_thread_find_cb(struct list_head *list, void *object, tdm_thread_cb_type cb_type, + void *cb_data, tdm_thread_cb func, void *user_data, pid_t caller_tid) { tdm_private_thread_cb *cb = NULL; - LIST_FOR_EACH_ENTRY(cb, &cb_list, link) { + LIST_FOR_EACH_ENTRY(cb, list, link) { if (cb->object == object && cb->cb_type == cb_type && cb->cb_data == cb_data && cb->func == func && cb->user_data == user_data && - cb->owner_tid == owner_tid) + cb->owner_tid == caller_tid) return cb; } return NULL; } -static void -_tdm_thread_reset_cb(tdm_thread_cb_type cb_type) -{ - tdm_private_thread_cb *cb = NULL; - - LIST_FOR_EACH_ENTRY(cb, &cb_list, link) { - if (cb->cb_type == cb_type) - cb->called = 0; - } -} - INTERN void tdm_thread_cb_set_find_func(tdm_thread_cb_type cb_type, tdm_thread_find_object func) { @@ -516,6 +519,7 @@ tdm_thread_cb_add(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_t { tdm_private_thread_cb *cb = NULL; pid_t caller_tid; + struct list_head *list; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); TDM_RETURN_VAL_IF_FAIL(object != NULL, TDM_ERROR_INVALID_PARAMETER); @@ -524,8 +528,16 @@ tdm_thread_cb_add(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_t caller_tid = syscall(SYS_gettid); - cb = _tdm_thread_find_cb(object, cb_type, cb_data, func, user_data, caller_tid); + pthread_mutex_lock(&cb_list_lock); + + if (tdm_thread_in_display_thread(caller_tid)) + list = &cb_list[0]; + else + list = &cb_list[1]; + + cb = _tdm_thread_find_cb(list, object, cb_type, cb_data, func, user_data, caller_tid); if (cb) { + pthread_mutex_unlock(&cb_list_lock); TDM_ERR("can't be added twice with same data"); #if 1 assert(0); @@ -535,11 +547,12 @@ tdm_thread_cb_add(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_t cb = calloc(1, sizeof *cb); if (!cb) { + pthread_mutex_unlock(&cb_list_lock); TDM_ERR("calloc failed"); return TDM_ERROR_OUT_OF_MEMORY; } - LIST_ADDTAIL(&cb->link, &cb_list); + LIST_ADDTAIL(&cb->link, list); LIST_INITHEAD(&cb->call_link); cb->object = object; @@ -550,7 +563,9 @@ tdm_thread_cb_add(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_t cb->owner_tid = caller_tid; if (tdm_debug_module & TDM_DEBUG_THREAD) - TDM_INFO("cb_type(%d) cb(%p) added", cb_type, cb); + TDM_INFO("cb_type(%s) cb(%p) added", tdm_cb_type_str(cb_type), cb); + + pthread_mutex_unlock(&cb_list_lock); return TDM_ERROR_NONE; } @@ -560,6 +575,7 @@ tdm_thread_cb_remove(void *object, tdm_thread_cb_type cb_type, void *cb_data, td { tdm_private_thread_cb *cb; pid_t caller_tid; + struct list_head *list; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); TDM_RETURN_IF_FAIL(object != NULL); @@ -568,11 +584,21 @@ tdm_thread_cb_remove(void *object, tdm_thread_cb_type cb_type, void *cb_data, td caller_tid = syscall(SYS_gettid); - cb = _tdm_thread_find_cb(object, cb_type, cb_data, func, user_data, caller_tid); - if (!cb) + pthread_mutex_lock(&cb_list_lock); + + if (tdm_thread_in_display_thread(caller_tid)) + list = &cb_list[0]; + else + list = &cb_list[1]; + + cb = _tdm_thread_find_cb(list, object, cb_type, cb_data, func, user_data, caller_tid); + if (!cb) { + pthread_mutex_unlock(&cb_list_lock); return; + } _tdm_thread_free_cb(cb); + pthread_mutex_unlock(&cb_list_lock); } /* when call a callback, we check both cb_base's type and cb_base's data, @@ -585,6 +611,7 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) tdm_private_thread_cb *cb = NULL, *hh = NULL; int handler_in_other_thread = 0; pid_t caller_tid; + struct list_head *list, *other_list; struct list_head call_list; tdm_error ret; @@ -607,35 +634,53 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) } } + pthread_mutex_lock(&cb_list_lock); + + if (tdm_thread_in_display_thread(caller_tid)) { + list = &cb_list[0]; + other_list = &cb_list[1]; + } else { + other_list = &cb_list[0]; + list = &cb_list[1]; + } + LIST_INITHEAD(&call_list); - LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &cb_list, link) { - if (cb->called || - cb->object != object || + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, list, link) { + if (cb->object != object || cb->cb_type != cb_base->type || cb->cb_data != cb_base->data) continue; - if (cb->owner_tid == caller_tid) - LIST_ADDTAIL(&cb->call_link, &call_list); - else - handler_in_other_thread = 1; + LIST_ADDTAIL(&cb->call_link, &call_list); } if (!LIST_IS_EMPTY(&call_list)) { LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &call_list, call_link) { LIST_DELINIT(&cb->call_link); - cb->called = 1; if (tdm_debug_module & TDM_DEBUG_THREAD) - TDM_INFO("cb_type(%d) cb(%p) called", cb->cb_type, cb); + TDM_INFO("cb_type(%s) cb(%p) calling", tdm_cb_type_str(cb->cb_type), cb); + pthread_mutex_unlock(&cb_list_lock); cb->func(private_display, cb->object, cb_base, cb->user_data); + pthread_mutex_lock(&cb_list_lock); } } + pthread_mutex_unlock(&cb_list_lock); + assert(LIST_IS_EMPTY(&call_list)); + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, other_list, link) { + if (cb->object != object || + cb->cb_type != cb_base->type || + cb->cb_data != cb_base->data) + continue; + + handler_in_other_thread = 1; + break; + } + if (!handler_in_other_thread) { - _tdm_thread_reset_cb(cb_base->type); if (keep_private_thread) { if (cb_base->sync) { pthread_cond_signal(&keep_private_thread->event_cond); -- 2.7.4 From db5780af098f675d9c7105ce26ebcb8cedb38937 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 23 Feb 2018 07:50:21 +0900 Subject: [PATCH 11/16] layer: correct error type Change-Id: I6bc89d04588ac3f94ed129943a0be12b94fd6fb0 --- src/tdm_layer.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index 3afebd1..1f757ee 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -1115,8 +1115,6 @@ tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error) if (private_layer->showing_buffer) { buffer = private_layer->showing_buffer->buffer; } else { - if (error) - *error = TDM_ERROR_OPERATION_FAILED; _pthread_mutex_unlock(&private_display->lock); TDM_DBG("layer(%p) showing_buffer is null", private_layer); return NULL; @@ -1313,7 +1311,7 @@ tdm_layer_set_video_pos(tdm_layer *layer, int zpos) if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) { TDM_ERR("layer(%p) is not video layer", private_layer); _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_INVALID_PARAMETER; + return TDM_ERROR_BAD_REQUEST; } if (!func_layer->layer_set_video_pos) { -- 2.7.4 From fa0b43c5a0a3a5a81b27e8e36fb6ccc29159214c Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 23 Feb 2018 07:51:29 +0900 Subject: [PATCH 12/16] layer: correct set_buffer_queue behavior Change-Id: I7d72456f54ed91b392799918727886d8520e6b9f --- src/tdm_layer.c | 51 ++++++++++++++++----------------------------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index 1f757ee..79c7c2f 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -1131,7 +1131,7 @@ _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data) tdm_layer *layer = data; tdm_private_backend *private_backend; tdm_func_layer *func_layer; - tbm_surface_h surface = NULL; + tbm_surface_h buffer = NULL; tdm_private_layer_buffer *layer_buffer; LAYER_FUNC_ENTRY_VOID_RETURN(); @@ -1157,49 +1157,30 @@ _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data) } LIST_INITHEAD(&layer_buffer->link); - if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) || - surface == NULL) { + if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &buffer) || + buffer == NULL) { /* LCOV_EXCL_START */ TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p", - private_layer, surface); + private_layer, buffer); _pthread_mutex_unlock(&private_display->lock); free(layer_buffer); return; /* LCOV_EXCL_STOP */ } - /* we don't need to handle pending data here because the changes in this function - * should be applied immediately. we can't expect calling tdm_layer_commit. - */ - ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - if (ret == TDM_ERROR_NONE) { - if (private_layer->waiting_buffer) { - TDM_DBG("layer(%p) drop waiting_buffer(%p)", private_layer, private_layer->waiting_buffer->buffer); - _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); - } - - private_layer->waiting_buffer = layer_buffer; - private_layer->waiting_buffer->buffer = tdm_buffer_ref_backend(surface); - - if (tdm_debug_module & TDM_DEBUG_BUFFER) - TDM_INFO("layer(%p) waiting_buffer(%p)", - private_layer, private_layer->waiting_buffer->buffer); + ret = tdm_layer_set_buffer_internal(private_layer, buffer); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_layer_set_buffer_internal failed"); + _pthread_mutex_unlock(&private_display->lock); + return; + } - if (private_output->commit_type == TDM_COMMIT_TYPE_OUTPUT) { - ret = tdm_output_commit_internal(private_layer->private_output, 0, NULL, NULL); - if (ret != TDM_ERROR_NONE) - TDM_ERR("tdm_output_commit_internal() is fail"); - } else if (private_output->commit_type == TDM_COMMIT_TYPE_LAYER) { - ret = _tdm_layer_commit(private_layer, NULL, NULL); - if (ret != TDM_ERROR_NONE) - TDM_ERR("layer(%p) _tdm_layer_commit() is fail", private_layer); - } else { - TDM_NEVER_GET_HERE(); - } - } else - _tdm_layer_free_buffer(private_layer, layer_buffer); + ret = tdm_layer_commit_internal(private_layer, NULL, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_layer_commit_internal failed"); + _pthread_mutex_unlock(&private_display->lock); + return; + } _pthread_mutex_unlock(&private_display->lock); } -- 2.7.4 From 46b0ce93f95645589b5ee04092b9e768a7365e12 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 23 Feb 2018 08:08:32 +0900 Subject: [PATCH 13/16] log: remove time information from stdout Change-Id: I4328046076b3b4d6824a7eab5a357b8ddd163e82 --- common/tdm_log.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index 1befbfb..aa68703 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -179,12 +179,9 @@ tdm_log_print(int level, const char *fmt, ...) __dlog_vprint(LOG_ID_SYSTEM, dlog_prio, LOG_TAG, fmt, arg); va_end(arg); } else { - struct timespec ts; char *lvl_str[] = {"TDM_NON", "TDM_ERR", "TDM_WRN", "TDM_INF", "TDM_DBG"}; char *color[] = {COLOR_RESET, COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_RESET}; - clock_gettime(CLOCK_MONOTONIC, &ts); - pthread_mutex_lock(&log_lock); if (color_enable) @@ -192,7 +189,6 @@ tdm_log_print(int level, const char *fmt, ...) printf("[%s]", lvl_str[level]); if (color_enable) printf(COLOR_RESET); - printf("[%d.%06d]", (int)ts.tv_sec, (int)ts.tv_nsec / 1000); va_start(arg, fmt); vprintf(fmt, arg); va_end(arg); -- 2.7.4 From f1d99591b70ccd618592f2e9034f2d9b7b6ae205 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 23 Feb 2018 09:04:25 +0900 Subject: [PATCH 14/16] output: correct return type Change-Id: I927d257820e11dcfa5bf545c88f374d092d6fb7f --- src/tdm_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index 689eed0..49b113b 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -545,7 +545,7 @@ tdm_output_get_cursor_available_size(tdm_output *output, int *min_w, int *min_h, _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_MODULE; + return TDM_ERROR_BAD_REQUEST; } if (min_w) -- 2.7.4 From 9e7971e27e1a50142add6f46e71689f784989c58 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 23 Feb 2018 09:05:24 +0900 Subject: [PATCH 15/16] helper: add tdm_helper_output_vblank_timer_expired To check if output-vblank is expired Change-Id: I4c3339a62f970372c2749808f2a8d930dd211935 --- include/tdm_helper.h | 8 ++++++++ src/tdm_helper.c | 9 +++++++++ src/tdm_output.c | 8 +++++++- src/tdm_private_types.h | 1 + 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/tdm_helper.h b/include/tdm_helper.h index fa82602..99fd638 100644 --- a/include/tdm_helper.h +++ b/include/tdm_helper.h @@ -236,6 +236,14 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len); int tdm_helper_output_commit_per_vblank_enabled(tdm_output *output); +/** + * @brief Get whether the vblank timer is expired or not for the output. + * @param[in] output An output the functionality has to be checked for + * @return -1 if error occurred, 1 if enabled, 0 if disabled. + */ +unsigned int +tdm_helper_output_vblank_timer_expired(tdm_output *output); + #ifdef __cplusplus } #endif diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 6e2c5cf..0f6cd37 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -1087,3 +1087,12 @@ tdm_helper_output_commit_per_vblank_enabled(tdm_output *output) return !!private_output->commit_per_vblank; } +EXTERN unsigned int +tdm_helper_output_vblank_timer_expired(tdm_output *output) +{ + tdm_private_output *private_output = output; + + TDM_RETURN_VAL_IF_FAIL(private_output != NULL, -1); + + return private_output->vblank_timeout_timer_expired; +} \ No newline at end of file diff --git a/src/tdm_output.c b/src/tdm_output.c index 49b113b..53ea938 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -68,7 +68,12 @@ _tdm_output_vblank_timeout_cb(void *user_data) TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_OPERATION_FAILED); - TDM_ERR("TDM output(%d) vblank TIMEOUT!!", private_output->pipe); + private_output->vblank_timeout_timer_expired++; + + TDM_ERR("TDM output(%d) vblank TIMEOUT!! (%d time%s)", + private_output->pipe, + private_output->vblank_timeout_timer_expired, + (private_output->vblank_timeout_timer_expired > 1) ? "s" : ""); LIST_FOR_EACH_ENTRY(v, &private_output->vblank_handler_list, link) { TDM_ERR("vblank_handler(%p) interval(%d) sync(%d) sent_to_frontend(%u) owner_tid(%d)", @@ -112,6 +117,7 @@ _tdm_output_vblank_timeout_update(tdm_private_output *private_output, int ms_del return; } TDM_INFO("output(%d) create vblank timeout timer", private_output->pipe); + private_output->vblank_timeout_timer_expired = 0; } ret = tdm_event_loop_source_timer_update(private_output->vblank_timeout_timer, ms_delay); diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 099dae1..2b6d25d 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -208,6 +208,7 @@ struct _tdm_private_output { int layer_waiting_vblank; tdm_event_loop_source *vblank_timeout_timer; + unsigned int vblank_timeout_timer_expired; struct list_head change_handler_list; -- 2.7.4 From 83e01cfd8d96500b77c4fb905bc8d768e425ea16 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 23 Feb 2018 09:09:59 +0900 Subject: [PATCH 16/16] thread: remove test code Change-Id: I70f8d4bde93c521ba12ec2177666806da921e7e6 --- src/tdm_thread.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 6058bb3..3811bdc 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -539,9 +539,6 @@ tdm_thread_cb_add(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_t if (cb) { pthread_mutex_unlock(&cb_list_lock); TDM_ERR("can't be added twice with same data"); -#if 1 - assert(0); -#endif return TDM_ERROR_BAD_REQUEST; } -- 2.7.4