diff --git a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml index af78ec051..45c9c633a 100644 --- a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml +++ b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml @@ -337,6 +337,9 @@ - "is-current" (b): the mode is currently active mode - "is-preferred" (b): the mode is the preferred mode - "is-interlaced" (b): the mode is an interlaced mode + - "refresh-rate-mode" (s): the refresh rate mode, either + "variable" or "fixed" (absence + of this means "fixed") * a{sv} properties: optional properties, including: - "width-mm" (i): physical width of monitor in millimeters - "height-mm" (i): physical height of monitor in millimeters diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c index 2f95c0bd8..e7fcc5527 100644 --- a/src/backends/meta-monitor-config-store.c +++ b/src/backends/meta-monitor-config-store.c @@ -163,6 +163,7 @@ typedef enum STATE_MONITOR_MODE_WIDTH, STATE_MONITOR_MODE_HEIGHT, STATE_MONITOR_MODE_RATE, + STATE_MONITOR_MODE_RATE_MODE, STATE_MONITOR_MODE_FLAG, STATE_MONITOR_UNDERSCANNING, STATE_MONITOR_MAXBPC, @@ -531,6 +532,10 @@ handle_start_element (GMarkupParseContext *context, { parser->state = STATE_MONITOR_MODE_RATE; } + else if (g_str_equal (element_name, "ratemode")) + { + parser->state = STATE_MONITOR_MODE_RATE_MODE; + } else if (g_str_equal (element_name, "flag")) { parser->state = STATE_MONITOR_MODE_FLAG; @@ -548,6 +553,7 @@ handle_start_element (GMarkupParseContext *context, case STATE_MONITOR_MODE_WIDTH: case STATE_MONITOR_MODE_HEIGHT: case STATE_MONITOR_MODE_RATE: + case STATE_MONITOR_MODE_RATE_MODE: case STATE_MONITOR_MODE_FLAG: { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, @@ -829,6 +835,7 @@ handle_end_element (GMarkupParseContext *context, case STATE_MONITOR_MODE_WIDTH: case STATE_MONITOR_MODE_HEIGHT: case STATE_MONITOR_MODE_RATE: + case STATE_MONITOR_MODE_RATE_MODE: case STATE_MONITOR_MODE_FLAG: { parser->state = STATE_MONITOR_MODE; @@ -1342,6 +1349,27 @@ handle_text (GMarkupParseContext *context, return; } + case STATE_MONITOR_MODE_RATE_MODE: + { + if (text_equals (text, text_len, "fixed")) + { + parser->current_monitor_mode_spec->refresh_rate_mode = + META_CRTC_REFRESH_RATE_MODE_FIXED; + } + else if (text_equals (text, text_len, "variable")) + { + parser->current_monitor_mode_spec->refresh_rate_mode = + META_CRTC_REFRESH_RATE_MODE_VARIABLE; + } + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid refresh rate mode %.*s", (int) text_len, text); + } + + return; + } + case STATE_MONITOR_MODE_FLAG: { if (text_equals (text, text_len, "interlace")) @@ -1598,6 +1626,9 @@ append_monitors (GString *buffer, monitor_config->mode_spec->height); g_string_append_printf (buffer, " %s\n", rate_str); + if (monitor_config->mode_spec->refresh_rate_mode == + META_CRTC_REFRESH_RATE_MODE_VARIABLE) + g_string_append_printf (buffer, " variable\n"); if (monitor_config->mode_spec->flags & META_CRTC_MODE_FLAG_INTERLACE) g_string_append_printf (buffer, " interlace\n"); g_string_append (buffer, " \n"); diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 50238515d..a73ee5d87 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -2140,6 +2140,11 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, g_variant_builder_add (&mode_properties_builder, "{sv}", "is-interlaced", g_variant_new_boolean (TRUE)); + if (meta_monitor_mode_get_refresh_rate_mode (monitor_mode) == + META_CRTC_REFRESH_RATE_MODE_VARIABLE) + g_variant_builder_add (&mode_properties_builder, "{sv}", + "refresh-rate-mode", + g_variant_new_string ("variable")); g_variant_builder_add (&modes_builder, MODE_FORMAT, mode_id, diff --git a/src/tests/meta-monitor-test-utils.c b/src/tests/meta-monitor-test-utils.c index 440536daa..d7d88f6a1 100644 --- a/src/tests/meta-monitor-test-utils.c +++ b/src/tests/meta-monitor-test-utils.c @@ -149,12 +149,15 @@ check_monitor_mode (MetaMonitor *monitor, const MetaCrtcModeInfo *crtc_mode_info = meta_crtc_mode_get_info (crtc_mode); float refresh_rate; + MetaCrtcRefreshRateMode refresh_rate_mode; MetaCrtcModeFlag flags; refresh_rate = meta_monitor_mode_get_refresh_rate (mode); + refresh_rate_mode = meta_monitor_mode_get_refresh_rate_mode (mode); flags = meta_monitor_mode_get_flags (mode); g_assert_cmpfloat (refresh_rate, ==, crtc_mode_info->refresh_rate); + g_assert_cmpint (refresh_rate_mode, ==, crtc_mode_info->refresh_rate_mode); g_assert_cmpint (flags, ==, (crtc_mode_info->flags & HANDLED_CRTC_MODE_FLAGS)); } @@ -437,11 +440,13 @@ meta_check_monitor_configuration (MetaContext *context, int width; int height; float refresh_rate; + MetaCrtcRefreshRateMode refresh_rate_mode; MetaCrtcModeFlag flags; CheckMonitorModeData data; meta_monitor_mode_get_resolution (mode, &width, &height); refresh_rate = meta_monitor_mode_get_refresh_rate (mode); + refresh_rate_mode = meta_monitor_mode_get_refresh_rate_mode (mode); flags = meta_monitor_mode_get_flags (mode); g_debug ("Checking mode %dx%d @ %f", width, height, refresh_rate); @@ -455,6 +460,9 @@ meta_check_monitor_configuration (MetaContext *context, g_assert_cmpfloat (refresh_rate, ==, expect->monitors[i].modes[j].refresh_rate); + g_assert_cmpint (refresh_rate_mode, + ==, + expect->monitors[i].modes[j].refresh_rate_mode); g_assert_cmpint (flags, ==, expect->monitors[i].modes[j].flags); @@ -652,6 +660,7 @@ meta_create_monitor_test_setup (MetaBackend *backend, crtc_mode_info->width = setup->modes[i].width; crtc_mode_info->height = setup->modes[i].height; crtc_mode_info->refresh_rate = setup->modes[i].refresh_rate; + crtc_mode_info->refresh_rate_mode = setup->modes[i].refresh_rate_mode; crtc_mode_info->flags = setup->modes[i].flags; mode = g_object_new (META_TYPE_CRTC_MODE, diff --git a/src/tests/meta-monitor-test-utils.h b/src/tests/meta-monitor-test-utils.h index 6e4937542..696cbad4a 100644 --- a/src/tests/meta-monitor-test-utils.h +++ b/src/tests/meta-monitor-test-utils.h @@ -88,6 +88,7 @@ typedef struct _MonitorTestCaseMode int width; int height; float refresh_rate; + MetaCrtcRefreshRateMode refresh_rate_mode; MetaCrtcModeFlag flags; } MonitorTestCaseMode; @@ -145,6 +146,7 @@ typedef struct _MonitorTestCaseMonitorMode int width; int height; float refresh_rate; + MetaCrtcRefreshRateMode refresh_rate_mode; int n_scales; float scales[MAX_N_SCALES]; MetaCrtcModeFlag flags; diff --git a/src/tests/monitor-configs/refresh-rate-mode-fixed.xml b/src/tests/monitor-configs/refresh-rate-mode-fixed.xml new file mode 100644 index 000000000..e26a572d1 --- /dev/null +++ b/src/tests/monitor-configs/refresh-rate-mode-fixed.xml @@ -0,0 +1,23 @@ + + + + 0 + 0 + yes + + + DP-1 + MetaProduct's Inc. + MetaMonitor + 0x123456 + + + 1024 + 768 + 60.000495910644531 + fixed + + + + + diff --git a/src/tests/monitor-configs/refresh-rate-mode-variable.xml b/src/tests/monitor-configs/refresh-rate-mode-variable.xml new file mode 100644 index 000000000..1307c17cc --- /dev/null +++ b/src/tests/monitor-configs/refresh-rate-mode-variable.xml @@ -0,0 +1,23 @@ + + + + 0 + 0 + yes + + + DP-1 + MetaProduct's Inc. + MetaMonitor + 0x123456 + + + 1024 + 768 + 60.000495910644531 + variable + + + + + diff --git a/src/tests/monitor-store-unit-tests.c b/src/tests/monitor-store-unit-tests.c index 872a8bf0f..175e1cf6f 100644 --- a/src/tests/monitor-store-unit-tests.c +++ b/src/tests/monitor-store-unit-tests.c @@ -37,6 +37,7 @@ typedef struct _MonitorStoreTestCaseMonitorMode int width; int height; float refresh_rate; + MetaCrtcRefreshRateMode refresh_rate_mode; MetaCrtcModeFlag flags; } MonitorStoreTestCaseMonitorMode; @@ -192,6 +193,9 @@ check_monitor_store_configuration (MetaMonitorConfigStore *config_store, g_assert_cmpfloat (monitor_config->mode_spec->refresh_rate, ==, test_monitor->mode.refresh_rate); + g_assert_cmpint (monitor_config->mode_spec->refresh_rate_mode, + ==, + test_monitor->mode.refresh_rate_mode); g_assert_cmpint (monitor_config->mode_spec->flags, ==, test_monitor->mode.flags); @@ -463,6 +467,98 @@ meta_test_monitor_store_underscanning (void) check_monitor_store_configurations (&expect); } +static void +meta_test_monitor_store_refresh_rate_mode_fixed (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 1024, + .height = 768 + }, + .scale = 1, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .refresh_rate_mode = META_CRTC_REFRESH_RATE_MODE_FIXED, + }, + .rgb_range = META_OUTPUT_RGB_RANGE_AUTO, + } + }, + .n_monitors = 1, + }, + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + meta_set_custom_monitor_config (test_context, "refresh-rate-mode-fixed.xml"); + + check_monitor_store_configurations (&expect); +} + +static void +meta_test_monitor_store_refresh_rate_mode_variable (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 1024, + .height = 768 + }, + .scale = 1, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .refresh_rate_mode = META_CRTC_REFRESH_RATE_MODE_VARIABLE, + }, + .rgb_range = META_OUTPUT_RGB_RANGE_AUTO, + } + }, + .n_monitors = 1, + }, + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + meta_set_custom_monitor_config (test_context, "refresh-rate-mode-variable.xml"); + + check_monitor_store_configurations (&expect); +} + static void meta_test_monitor_store_max_bpc (void) { @@ -1114,6 +1210,10 @@ init_monitor_store_tests (void) meta_test_monitor_store_primary); g_test_add_func ("/backends/monitor-store/underscanning", meta_test_monitor_store_underscanning); + g_test_add_func ("/backends/monitor-store/refresh-rate-mode-fixed", + meta_test_monitor_store_refresh_rate_mode_fixed); + g_test_add_func ("/backends/monitor-store/refresh-rate-mode-variable", + meta_test_monitor_store_refresh_rate_mode_variable); g_test_add_func ("/backends/monitor-store/max-bpc", meta_test_monitor_store_max_bpc); g_test_add_func ("/backends/monitor-store/rgb-range", diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c index 3a1dd3cc1..0caab13bc 100644 --- a/src/tests/monitor-unit-tests.c +++ b/src/tests/monitor-unit-tests.c @@ -3254,6 +3254,100 @@ meta_test_monitor_underscanning_config (void) check_monitor_test_clients_state (); } +static void +meta_test_monitor_refresh_rate_mode_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .refresh_rate_mode = META_CRTC_REFRESH_RATE_MODE_VARIABLE, + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .refresh_rate_mode = META_CRTC_REFRESH_RATE_MODE_VARIABLE, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = meta_create_monitor_test_setup (test_backend, + &test_case.setup, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + META_TEST_LOG_CALL ("Checking monitor configuration", + meta_check_monitor_configuration (test_context, + &test_case.expect)); + check_monitor_test_clients_state (); +} + static void meta_test_monitor_max_bpc_config (void) { @@ -5933,6 +6027,203 @@ meta_test_monitor_custom_underscanning_config (void) check_monitor_test_clients_state (); } +static void +meta_test_monitor_custom_refresh_rate_mode_fixed_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .refresh_rate_mode = META_CRTC_REFRESH_RATE_MODE_FIXED, + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .serial = "0x123456", + }, + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + }, + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .refresh_rate_mode = META_CRTC_REFRESH_RATE_MODE_FIXED, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = meta_create_monitor_test_setup (test_backend, + &test_case.setup, + MONITOR_TEST_FLAG_NONE); + meta_set_custom_monitor_config (test_context, "refresh-rate-mode-fixed.xml"); + emulate_hotplug (test_setup); + + META_TEST_LOG_CALL ("Checking monitor configuration", + meta_check_monitor_configuration (test_context, + &test_case.expect)); + check_monitor_test_clients_state (); +} + + +static void +meta_test_monitor_custom_refresh_rate_mode_variable_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .refresh_rate_mode = META_CRTC_REFRESH_RATE_MODE_VARIABLE, + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .serial = "0x123456", + }, + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + }, + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .refresh_rate_mode = META_CRTC_REFRESH_RATE_MODE_VARIABLE, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = meta_create_monitor_test_setup (test_backend, + &test_case.setup, + MONITOR_TEST_FLAG_NONE); + meta_set_custom_monitor_config (test_context, "refresh-rate-mode-variable.xml"); + emulate_hotplug (test_setup); + + META_TEST_LOG_CALL ("Checking monitor configuration", + meta_check_monitor_configuration (test_context, + &test_case.expect)); + check_monitor_test_clients_state (); +} + static void meta_test_monitor_custom_scale_config (void) { @@ -9718,6 +10009,8 @@ init_monitor_tests (void) meta_test_monitor_no_outputs); add_monitor_test ("/backends/monitor/underscanning-config", meta_test_monitor_underscanning_config); + add_monitor_test ("/backends/monitor/refresh-rate-mode-config", + meta_test_monitor_refresh_rate_mode_config); add_monitor_test ("/backends/monitor/max-bpc-config", meta_test_monitor_max_bpc_config); add_monitor_test ("/backends/monitor/rgb-range-config", @@ -9754,6 +10047,10 @@ init_monitor_tests (void) meta_test_monitor_custom_primary_config); add_monitor_test ("/backends/monitor/custom/underscanning-config", meta_test_monitor_custom_underscanning_config); + add_monitor_test ("/backends/monitor/custom/refresh-rate-mode-fixed-config", + meta_test_monitor_custom_refresh_rate_mode_fixed_config); + add_monitor_test ("/backends/monitor/custom/refresh-rate-mode-variable-config", + meta_test_monitor_custom_refresh_rate_mode_variable_config); add_monitor_test ("/backends/monitor/custom/scale-config", meta_test_monitor_custom_scale_config); add_monitor_test ("/backends/monitor/custom/fractional-scale-config",