X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftdm.c;h=6f938ec9d6b68ebab798984b52e865925997237d;hb=c62d87e018d27ccd2074b3ef26a37b60110e5d0d;hp=9f41287e646fb9ff97be0c58c74b673bb4004496;hpb=5f5db38c60ac7e80131ba48a5804f3be5325a740;p=platform%2Fcore%2Fuifw%2Flibtdm.git diff --git a/src/tdm.c b/src/tdm.c index 9f41287..6f938ec 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -97,6 +97,44 @@ tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp return NULL; } +tdm_private_hwc * +tdm_display_find_private_hwc(tdm_private_display *private_display, tdm_hwc *hwc_backend) +{ + tdm_private_module *private_module = NULL; + tdm_private_output *private_output = NULL; + tdm_private_hwc *private_hwc = NULL; + + LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { + if (!private_output->private_hwc) continue; + private_hwc = private_output->private_hwc; + if (private_hwc->hwc_backend == hwc_backend) + return private_hwc; + } + } + + return NULL; +} + +INTERN void * +tdm_display_find_hwc_stamp(tdm_private_display *private_display, double stamp) +{ + tdm_private_module *private_module = NULL; + tdm_private_output *private_output = NULL; + tdm_private_hwc *private_hwc = NULL; + + LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { + if (!private_output->private_hwc) continue; + private_hwc = private_output->private_hwc; + if (private_hwc->stamp == stamp) + return private_hwc; + } + } + + return NULL; +} + static void _tdm_display_destroy_caps_pp(tdm_caps_pp *caps_pp) { @@ -164,10 +202,12 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) { tdm_private_display *private_display = private_output->private_display; tdm_private_layer *l = NULL, *ll = NULL; + tdm_private_hwc *private_hwc = NULL; tdm_private_hwc_window *hw = NULL, *hww = NULL; tdm_private_capture *c = NULL, *cc = NULL; tdm_private_output_vblank_handler *v = NULL, *vv = NULL; tdm_private_output_commit_handler *om = NULL, *omm = NULL; + tdm_private_hwc_commit_handler *hm = NULL, *hmm = NULL; tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL; tdm_private_output_change_handler *h = NULL, *hh = NULL; @@ -186,9 +226,17 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) free(om); } - LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) { - LIST_DEL(&lm->link); - free(lm); + if (private_output->private_hwc) { + private_hwc = private_output->private_hwc; + LIST_FOR_EACH_ENTRY_SAFE(hm, hmm, &private_hwc->hwc_commit_handler_list, link) { + LIST_DEL(&hm->link); + free(hm); + } + } else { + LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) { + LIST_DEL(&lm->link); + free(lm); + } } LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) { @@ -218,21 +266,20 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) } LIST_FOR_EACH_ENTRY_SAFE(c, cc, &private_output->capture_list, link) - tdm_capture_destroy_internal(c); - - LIST_FOR_EACH_ENTRY_SAFE(hw, hww, &private_output->hwc_window_list, link) - tdm_hwc_window_destroy_internal(hw); - - LIST_FOR_EACH_ENTRY_SAFE(l, ll, &private_output->layer_list, link) - _tdm_display_destroy_private_layer(l); + tdm_capture_destroy_internal(c); + + if (private_output->private_hwc) { + private_hwc = private_output->private_hwc; + LIST_FOR_EACH_ENTRY_SAFE(hw, hww, &private_hwc->hwc_window_list, link) + tdm_hwc_window_destroy_internal(hw); + free(private_hwc); + } else { + LIST_FOR_EACH_ENTRY_SAFE(l, ll, &private_output->layer_list, link) + _tdm_display_destroy_private_layer(l); + } _tdm_display_destroy_caps_output(&private_output->caps); - 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. */ @@ -405,6 +452,8 @@ tdm_display_update_output(tdm_private_module *private_module, tdm_func_output *func_output = &private_module->func_output; tdm_private_output *private_output = NULL; tdm_layer **layers = NULL; + tdm_private_hwc *private_hwc = NULL; + tdm_hwc *hwc; int layer_count = 0, i; tdm_error ret; @@ -426,67 +475,97 @@ tdm_display_update_output(tdm_private_module *private_module, private_output->pipe = pipe; private_output->index = pipe; - LIST_INITHEAD(&private_output->layer_list); - LIST_INITHEAD(&private_output->hwc_window_list); LIST_INITHEAD(&private_output->capture_list); LIST_INITHEAD(&private_output->vblank_handler_list); 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); - private_output->need_validate.event_fd = -1; - if (func_output->output_set_status_handler) { func_output->output_set_status_handler(private_output->output_backend, tdm_output_cb_status, private_output); private_output->regist_change_cb = 1; } - } - - /* need_new_caps will be true only in case of "disconnected -> connected" and "connected -> disconnected" - * because we have to get new modes. - */ - if (need_new_caps) { - _tdm_display_destroy_caps_output(&private_output->caps); ret = _tdm_display_update_caps_output(private_module, pipe, output_backend, &private_output->caps); TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); - } - layers = func_output->output_get_layers(output_backend, &layer_count, &ret); - if (ret != TDM_ERROR_NONE) { - free(layers); - return ret; + if (private_output->caps.status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) + private_output->current_mode = NULL; + + /* get the tdm_hwc object */ + if (private_output->caps.capabilities&TDM_OUTPUT_CAPABILITY_HWC) { + hwc = func_output->output_get_hwc(output_backend, &ret); + TDM_RETURN_VAL_IF_FAIL(hwc != NULL, ret); + + private_hwc = calloc(1, sizeof(tdm_private_hwc)); + TDM_RETURN_VAL_IF_FAIL(private_hwc != NULL, TDM_ERROR_OUT_OF_MEMORY); + + private_hwc->private_module = private_module; + private_hwc->private_output = private_output; + private_hwc->hwc_backend = hwc; + private_hwc->index = pipe; + private_hwc->stamp = tdm_helper_get_time(); + while (tdm_display_find_hwc_stamp(private_module->private_display, private_hwc->stamp)) + private_hwc->stamp++; + + LIST_INITHEAD(&private_hwc->hwc_window_list); + LIST_INITHEAD(&private_hwc->hwc_commit_handler_list); + + private_output->private_hwc = private_hwc; + } else { + LIST_INITHEAD(&private_output->layer_list); + LIST_INITHEAD(&private_output->layer_commit_handler_list); + } + } else { + /* need_new_caps will be true only in case of "disconnected -> connected" and "connected -> disconnected" + * because we have to get new modes. + */ + if (need_new_caps) { + _tdm_display_destroy_caps_output(&private_output->caps); + + ret = _tdm_display_update_caps_output(private_module, pipe, output_backend, &private_output->caps); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + + if (private_output->caps.status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) + private_output->current_mode = NULL; + } } - for (i = 0; i < layer_count; i++) { - ret = _tdm_display_update_layer(private_output, layers[i], i); + /* do not use the layer object when the tdm_output has the hwc capability */ + if ((private_output->caps.capabilities&TDM_OUTPUT_CAPABILITY_HWC) == 0) { + layers = func_output->output_get_layers(output_backend, &layer_count, &ret); if (ret != TDM_ERROR_NONE) { free(layers); return ret; } - } - free(layers); + for (i = 0; i < layer_count; i++) { + ret = _tdm_display_update_layer(private_output, layers[i], i); + if (ret != TDM_ERROR_NONE) { + free(layers); + return ret; + } + } + + free(layers); + } return TDM_ERROR_NONE; } -static tdm_output ** +static void _tdm_display_set_main_first(tdm_output **outputs, int index) { tdm_output *output_tmp = NULL; if (index == 0) - return outputs; + return; output_tmp = outputs[0]; outputs[0] = outputs[index]; outputs[index] = output_tmp; - - return outputs; } static tdm_output ** @@ -494,7 +573,6 @@ _tdm_display_get_ordered_outputs(tdm_private_module *private_module, int *count) { tdm_func_display *func_display = &private_module->func_display; tdm_output **outputs = NULL; - tdm_output **new_outputs = NULL; tdm_output *output_dsi = NULL; tdm_output *output_lvds = NULL; tdm_output *output_hdmia = NULL; @@ -528,11 +606,6 @@ _tdm_display_get_ordered_outputs(tdm_private_module *private_module, int *count) tdm_caps_output caps; memset(&caps, 0, sizeof(tdm_caps_output)); - if (!func_output->output_get_capability) { - TDM_ERR("no output_get_capability()"); - goto failed_get_outputs; - } - ret = func_output->output_get_capability(outputs[i], &caps); if (ret != TDM_ERROR_NONE) { TDM_ERR("output_get_capability() failed"); @@ -577,32 +650,28 @@ _tdm_display_get_ordered_outputs(tdm_private_module *private_module, int *count) if (output_connected_count == 0) { /* hdmi > dsi > lvds > else */ if (output_hdmia != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_hdmia); + _tdm_display_set_main_first(outputs, index_hdmia); else if (output_hdmib != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_hdmib); + _tdm_display_set_main_first(outputs, index_hdmib); else if (output_dsi != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_dsi); + _tdm_display_set_main_first(outputs, index_dsi); else if (output_lvds != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_lvds); - else - new_outputs = outputs; + _tdm_display_set_main_first(outputs, index_lvds); } else { /* (output_connected_count > 1) */ /* dsi > lvds > hdmi > else */ if (output_dsi != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_dsi); + _tdm_display_set_main_first(outputs, index_dsi); else if (output_lvds != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_lvds); + _tdm_display_set_main_first(outputs, index_lvds); else if (output_hdmia != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_hdmia); + _tdm_display_set_main_first(outputs, index_hdmia); else if (output_hdmib != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_hdmib); - else - new_outputs = outputs; + _tdm_display_set_main_first(outputs, index_hdmib); } - private_module->outputs = new_outputs; + private_module->outputs = outputs; - return new_outputs; + return outputs; failed_get_outputs: free(outputs); @@ -676,10 +745,14 @@ static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER; static tdm_error _tdm_display_check_module(tdm_backend_module *module) { - int major, minor; + int tdm_backend_major, tdm_backend_minor; + int backend_module_major, backend_module_minor; + + tdm_backend_major = TDM_BACKEND_GET_ABI_MAJOR(TDM_BACKEND_ABI_LATEST_VERSION); + tdm_backend_minor = TDM_BACKEND_GET_ABI_MINOR(TDM_BACKEND_ABI_LATEST_VERSION); - TDM_INFO("TDM ABI version : %d.%d", - TDM_MAJOR_VERSION, TDM_MINOR_VERSION); + TDM_INFO("TDM Backend ABI version : %d.%d", + tdm_backend_major, tdm_backend_minor); if (!module->name) { TDM_ERR("TDM backend doesn't have name"); @@ -691,22 +764,23 @@ _tdm_display_check_module(tdm_backend_module *module) return TDM_ERROR_BAD_MODULE; } - major = TDM_BACKEND_GET_ABI_MAJOR(module->abi_version); - minor = TDM_BACKEND_GET_ABI_MINOR(module->abi_version); + backend_module_major = TDM_BACKEND_GET_ABI_MAJOR(module->abi_version); + backend_module_minor = TDM_BACKEND_GET_ABI_MINOR(module->abi_version); TDM_INFO("TDM module name: %s", module->name); TDM_INFO("'%s' vendor: %s", module->name, module->vendor); - TDM_INFO("'%s' version: %d.%d", module->name, major, minor); + TDM_INFO("'%s' backend ABI version: %d.%d", module->name, backend_module_major, backend_module_minor); - if (major != TDM_MAJOR_VERSION) { - TDM_ERR("'%s' major version mismatch, %d != %d", - module->name, major, TDM_MAJOR_VERSION); + if (backend_module_major > tdm_backend_major) { + TDM_ERR("'%s' major version(%d) is newer than %d", + module->name, backend_module_major, tdm_backend_major); return TDM_ERROR_BAD_MODULE; } - if (minor > TDM_MINOR_VERSION) { + if (tdm_backend_major == backend_module_major && + backend_module_minor > tdm_backend_minor) { TDM_ERR("'%s' minor version(%d) is newer than %d", - module->name, minor, TDM_MINOR_VERSION); + module->name, backend_module_minor, tdm_backend_minor); return TDM_ERROR_BAD_MODULE; } @@ -887,7 +961,7 @@ static tdm_error _tdm_display_load_modules(tdm_private_display *private_display) { const char *module_names; - tdm_error ret = 0; + tdm_error ret = TDM_ERROR_NONE; char temp[TDM_PATH_LEN]; char *arg; char *end; @@ -1014,6 +1088,10 @@ tdm_display_init(tdm_error *error) if (ret != TDM_ERROR_NONE) goto failed_load; + ret = tdm_hwc_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; @@ -1063,15 +1141,6 @@ tdm_display_init(tdm_error *error) private_display->init_count = 1; g_private_display = private_display; - tdm_private_module *b = NULL; - tdm_private_output *o = NULL; - LIST_FOR_EACH_ENTRY(b, &private_display->module_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 * several operational modes (commit_per_vblank modes) related to tdm_commit; * this functionality can be turned off which means a default mode */