From ffd3cecfa5117811d4016bff1b39307139765703 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Fri, 20 Jul 2018 18:48:41 +0900 Subject: [PATCH] virtual: add set_available_mode & set_phsycal_size function Change-Id: I9f0e0115ab64786207db49f934d72a0d7c7e8ffc Signed-off-by: Junkyeong Kim --- backends/virtual/tdm_virtual.c | 2 + backends/virtual/tdm_virtual.h | 2 + backends/virtual/tdm_virtual_display.c | 125 ++++++++++++++++++++++----------- include/tdm_backend.h | 4 ++ src/tdm_display.c | 17 ++++- src/tdm_output.c | 48 +++++++++++++ src/tdm_private.h | 5 ++ 7 files changed, 160 insertions(+), 43 deletions(-) diff --git a/backends/virtual/tdm_virtual.c b/backends/virtual/tdm_virtual.c index 9c9e4dd..426feaf 100644 --- a/backends/virtual/tdm_virtual.c +++ b/backends/virtual/tdm_virtual.c @@ -75,6 +75,8 @@ tdm_virtual_init(tdm_display *dpy, tdm_error *error) virtual_func_output.output_set_commit_handler = virtual_output_set_commit_handler; virtual_func_output.output_set_mode = virtual_output_set_mode; virtual_func_output.output_get_mode = virtual_output_get_mode; + virtual_func_output.output_set_available_mode = virtual_output_set_available_mode; + virtual_func_output.output_set_physical_size = virtual_output_set_physical_size; memset(&virtual_func_layer, 0, sizeof(virtual_func_layer)); virtual_func_layer.layer_get_capability = virtual_layer_get_capability; diff --git a/backends/virtual/tdm_virtual.h b/backends/virtual/tdm_virtual.h index f1cdf91..1ad4550 100644 --- a/backends/virtual/tdm_virtual.h +++ b/backends/virtual/tdm_virtual.h @@ -40,6 +40,8 @@ tdm_error virtual_output_commit(tdm_output *output, int sync, void *user_data); tdm_error virtual_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func); tdm_error virtual_output_set_mode(tdm_output *output, const tdm_output_mode *mode); tdm_error virtual_output_get_mode(tdm_output *output, const tdm_output_mode **mode); +tdm_error virtual_output_set_available_mode(tdm_output *output, const tdm_output_mode *modes, int count); +tdm_error virtual_output_set_physical_size(tdm_output *output, unsigned int mmwidth, unsigned int mmheight); tdm_error virtual_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps); tdm_error virtual_layer_set_info(tdm_layer *layer, tdm_info_layer *info); diff --git a/backends/virtual/tdm_virtual_display.c b/backends/virtual/tdm_virtual_display.c index 9bf7363..2288a72 100644 --- a/backends/virtual/tdm_virtual_display.c +++ b/backends/virtual/tdm_virtual_display.c @@ -28,7 +28,7 @@ struct _tdm_virtual_output_data { tdm_virtual_data *virtual_data; uint32_t pipe; - tdm_output_mode *output_mode; + tdm_output_mode *output_modes; int mode_count; tdm_output_type connector_type; struct list_head layer_list; @@ -122,14 +122,14 @@ _tdm_virtual_display_wait_vblank(tdm_virtual_output_data *output_data, int inter unsigned int ms; RETURN_VAL_IF_FAIL(output_data->timer != NULL, TDM_ERROR_OPERATION_FAILED); - RETURN_VAL_IF_FAIL(output_data->output_mode->vrefresh > 0, TDM_ERROR_OPERATION_FAILED); + RETURN_VAL_IF_FAIL(output_data->current_mode->vrefresh > 0, TDM_ERROR_OPERATION_FAILED); if (output_data->timer_waiting) { LIST_ADDTAIL(&event_data->link, &output_data->timer_event_list); return TDM_ERROR_NONE; } - ms = ((double)1000.0 / output_data->output_mode->vrefresh) * interval; + ms = ((double)1000.0 / output_data->current_mode->vrefresh) * interval; ret = tdm_event_loop_source_timer_update(output_data->timer, ms); if (ret != TDM_ERROR_NONE) @@ -214,7 +214,7 @@ tdm_virtual_display_destroy_output_list(tdm_virtual_data *virtual_data) if (o->timer) tdm_event_loop_source_remove(o->timer); - free(o->output_mode); + free(o->output_modes); free(o); } } @@ -241,29 +241,29 @@ tdm_virtual_display_create_output_list(tdm_virtual_data *virtual_data) output_data->connector_type = TDM_OUTPUT_TYPE_Unknown; output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; - output_data->output_mode = calloc(1, sizeof(tdm_output_mode)); - if (!output_data->output_mode) { + output_data->output_modes = calloc(1, sizeof(tdm_output_mode)); + if (!output_data->output_modes) { TDM_ERR("alloc failed"); free(output_data); ret = TDM_ERROR_OUT_OF_MEMORY; goto failed_create; } - snprintf(output_data->output_mode->name, TDM_NAME_LEN, "640x480"); - output_data->output_mode->vrefresh = 30; - output_data->output_mode->clock = 25200; - output_data->output_mode->hdisplay = 640; - output_data->output_mode->hsync_start = 656; - output_data->output_mode->hsync_end = 752; - output_data->output_mode->htotal = 800; - output_data->output_mode->hskew = 0; - output_data->output_mode->vdisplay = 480; - output_data->output_mode->vsync_start = 490; - output_data->output_mode->vsync_end = 492; - output_data->output_mode->vtotal = 525; - output_data->output_mode->vscan = 0; - output_data->output_mode->flags = 0; - output_data->output_mode->type = 0; + snprintf(output_data->output_modes->name, TDM_NAME_LEN, "640x480"); + output_data->output_modes->vrefresh = 30; + output_data->output_modes->clock = 25200; + output_data->output_modes->hdisplay = 640; + output_data->output_modes->hsync_start = 656; + output_data->output_modes->hsync_end = 752; + output_data->output_modes->htotal = 800; + output_data->output_modes->hskew = 0; + output_data->output_modes->vdisplay = 480; + output_data->output_modes->vsync_start = 490; + output_data->output_modes->vsync_end = 492; + output_data->output_modes->vtotal = 525; + output_data->output_modes->vscan = 0; + output_data->output_modes->flags = 0; + output_data->output_modes->type = 0; output_data->timer = tdm_event_loop_add_timer_handler(virtual_data->dpy, _tdm_virtual_display_cb_timeout, @@ -390,28 +390,28 @@ virtual_display_output_create(tdm_backend_data *bdata, const char *name, tdm_err else snprintf(output_data->name, TDM_NAME_LEN, "unknown"); #if 0 - output_data->output_mode = calloc(1, sizeof(tdm_output_mode)); - if (!output_data->output_mode) { + output_data->output_modes = calloc(1, sizeof(tdm_output_mode)); + if (!output_data->output_modes) { TDM_ERR("alloc failed"); ret = TDM_ERROR_OUT_OF_MEMORY; goto create_fail; } - snprintf(output_data->output_mode->name, TDM_NAME_LEN, "640x480"); - output_data->output_mode->vrefresh = 30; - output_data->output_mode->clock = 25200; - output_data->output_mode->hdisplay = 640; - output_data->output_mode->hsync_start = 656; - output_data->output_mode->hsync_end = 752; - output_data->output_mode->htotal = 800; - output_data->output_mode->hskew = 0; - output_data->output_mode->vdisplay = 480; - output_data->output_mode->vsync_start = 490; - output_data->output_mode->vsync_end = 492; - output_data->output_mode->vtotal = 525; - output_data->output_mode->vscan = 0; - output_data->output_mode->flags = 0; - output_data->output_mode->type = 0; + snprintf(output_data->output_modes->name, TDM_NAME_LEN, "640x480"); + output_data->output_modes->vrefresh = 30; + output_data->output_modes->clock = 25200; + output_data->output_modes->hdisplay = 640; + output_data->output_modes->hsync_start = 656; + output_data->output_modes->hsync_end = 752; + output_data->output_modes->htotal = 800; + output_data->output_modes->hskew = 0; + output_data->output_modes->vdisplay = 480; + output_data->output_modes->vsync_start = 490; + output_data->output_modes->vsync_end = 492; + output_data->output_modes->vtotal = 525; + output_data->output_modes->vscan = 0; + output_data->output_modes->flags = 0; + output_data->output_modes->type = 0; output_data->mode_count = 1; #endif @@ -449,7 +449,7 @@ virtual_display_output_create(tdm_backend_data *bdata, const char *name, tdm_err create_fail: if (layer_data) free(layer_data); - if (output_data->output_mode) free(output_data->output_mode); + if (output_data->output_modes) free(output_data->output_modes); free(output_data); *error = ret; @@ -474,8 +474,11 @@ virtual_display_output_destroy(tdm_backend_data *bdata, tdm_output *output) } } - if (find) + if (find) { + if (output_data->output_modes) + free(output_data->output_modes); tdm_backend_unregister_output(virtual_data->dpy, output); + } else return TDM_ERROR_INVALID_PARAMETER; @@ -510,7 +513,7 @@ virtual_output_get_capability(tdm_output *output, tdm_caps_output *caps) goto failed_get; } - *caps->modes = *output_data->output_mode; + *caps->modes = *output_data->output_modes; } caps->mmWidth = output_data->mmwidth; @@ -685,6 +688,46 @@ virtual_output_get_mode(tdm_output *output, const tdm_output_mode **mode) } tdm_error +virtual_output_set_available_mode(tdm_output *output, const tdm_output_mode *modes, int count) +{ + tdm_virtual_output_data *output_data = output; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(modes, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(count > 0, TDM_ERROR_INVALID_PARAMETER); + + /* set available mode only permittied disconnect status */ + RETURN_VAL_IF_FAIL(output_data->status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED, TDM_ERROR_BUSY); + + if (output_data->output_modes) + free(output_data->output_modes); + output_data->output_modes = NULL; + + output_data->output_modes = calloc(1, count * sizeof(tdm_output_mode)); + RETURN_VAL_IF_FAIL(output_data->output_modes != NULL, TDM_ERROR_OUT_OF_MEMORY); + + memcpy(output_data->output_modes, modes, count * sizeof(tdm_output_mode)); + output_data->mode_count = count; + + return TDM_ERROR_NONE; +} + +tdm_error +virtual_output_set_physical_size(tdm_output *output, unsigned int mmwidth, unsigned int mmheight) +{ + tdm_virtual_output_data *output_data = output; + + RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(mmwidth != 0, TDM_ERROR_INVALID_PARAMETER); + RETURN_VAL_IF_FAIL(mmheight != 0, TDM_ERROR_INVALID_PARAMETER); + + output_data->mmwidth = mmwidth; + output_data->mmheight = mmheight; + + return TDM_ERROR_NONE; +} + +tdm_error virtual_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps) { tdm_virtual_layer_data *layer_data = layer; diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 2e80d99..7f43ee2 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -550,6 +550,10 @@ typedef struct _tdm_func_output { */ tdm_hwc *(*output_get_hwc)(tdm_output *output, tdm_error *error); + /* virtual */ + tdm_error (*output_set_available_mode)(tdm_output *output, const tdm_output_mode *modes, int count); + tdm_error (*output_set_physical_size)(tdm_output *output, unsigned int mmwidth, unsigned int mmheight); + void (*reserved5)(void); void (*reserved6)(void); void (*reserved7)(void); diff --git a/src/tdm_display.c b/src/tdm_display.c index a355ab7..3373f88 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -820,8 +820,10 @@ tdm_display_create_output(tdm_display *dpy, const char *name, tdm_error *error) { tdm_private_module *private_module = NULL; tdm_private_module *current_module = NULL; + tdm_private_output *private_output = NULL; tdm_func_display *func_display = NULL; tdm_output *output = NULL; + int output_find = 0; DISPLAY_FUNC_ENTRY_ERROR(); @@ -840,13 +842,21 @@ tdm_display_create_output(tdm_display *dpy, const char *name, tdm_error *error) current_module = private_display->current_module; private_display->current_module = private_module; output = func_display->display_output_create(private_module->bdata, name, &ret); + LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { + if (private_output->output_backend == output) { + output_find = 1; + break; + } + } private_display->current_module = current_module; _pthread_mutex_unlock(&private_display->lock); TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, ret, NULL); + if (output_find != 1) + private_output = NULL; - return output; + return private_output; } INTERN tdm_error @@ -854,6 +864,7 @@ tdm_display_destroy_output(tdm_display *dpy, tdm_output *output) { tdm_private_module *private_module = NULL; tdm_private_module *current_module = NULL; + tdm_private_output *private_output = NULL; tdm_func_display *func_display = NULL; DISPLAY_FUNC_ENTRY(); @@ -864,12 +875,14 @@ tdm_display_destroy_output(tdm_display *dpy, tdm_output *output) private_module = private_display->virtual_module; TDM_RETURN_VAL_IF_FAIL(private_module != NULL, TDM_ERROR_BAD_MODULE); + private_output = (tdm_private_output*)output; + _pthread_mutex_lock(&private_display->lock); func_display = &private_module->func_display; current_module = private_display->current_module; private_display->current_module = private_module; - ret = func_display->display_output_destroy(private_module->bdata, output); + ret = func_display->display_output_destroy(private_module->bdata, private_output->output_backend); private_display->current_module = current_module; _pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_output.c b/src/tdm_output.c index 550a750..a7813da 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1717,4 +1717,52 @@ tdm_output_choose_commit_per_vblank_mode(tdm_private_output *private_output, int return TDM_ERROR_NONE; } + +INTERN tdm_error +tdm_output_set_available_mode(tdm_output *output, const tdm_output_mode *modes, int count) +{ + tdm_private_module *private_module = NULL; + tdm_func_output *func_output = NULL; + + OUTPUT_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(count != 0, TDM_ERROR_INVALID_PARAMETER); + + private_module = private_output->private_module; + TDM_RETURN_VAL_IF_FAIL(private_module == private_display->virtual_module, TDM_ERROR_BAD_MODULE); + + _pthread_mutex_lock(&private_display->lock); + + func_output = &private_module->func_output; + ret = func_output->output_set_available_mode(private_output->output_backend, modes, count); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +INTERN tdm_error +tdm_output_set_physical_size(tdm_output *output, unsigned int mmwidth, unsigned int mmheight) +{ + tdm_private_module *private_module = NULL; + tdm_func_output *func_output = NULL; + + OUTPUT_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(mmwidth != 0, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(mmheight != 0, TDM_ERROR_INVALID_PARAMETER); + + private_module = private_output->private_module; + TDM_RETURN_VAL_IF_FAIL(private_module == private_display->virtual_module, TDM_ERROR_BAD_MODULE); + + _pthread_mutex_lock(&private_display->lock); + + func_output = &private_module->func_output; + ret = func_output->output_set_physical_size(private_output->output_backend, mmwidth, mmheight); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} /* LCOV_EXCL_STOP */ diff --git a/src/tdm_private.h b/src/tdm_private.h index d747993..2e7ffa3 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -255,10 +255,15 @@ tdm_config_deinit(void); void tdm_monitor_server_command(tdm_display *dpy, const char *options, char *reply, int *len); +/* virtual */ tdm_output * tdm_display_create_output(tdm_display *dpy, const char *name, tdm_error *error); tdm_error tdm_display_destroy_output(tdm_display *dpy, tdm_output *output); +tdm_error +tdm_output_set_available_mode(tdm_output *output, const tdm_output_mode *modes, int count); +tdm_error +tdm_output_set_physical_size(tdm_output *output, unsigned int mmwidth, unsigned int mmheight); #ifdef __cplusplus } -- 2.7.4