monitor: Do not overlap when checking for applicable scaling values
With some resolutions (such as 4096x2160) we may compute duplicated scale factors because we used a too wide threshold to check for an applicable value. In fact, while when we're at the first and last values it's fine to search applicable values up to SCALE_FACTORS_STEP, on intermediate ones we should stop in the middle of it, or we're end up overlapping the previous scaling value domain. In the said example in fact we were returning 2.666667 both when looking to a scaling value close to 2.75 and 3.00 as the upper bound of 2.75 (3.0) was overlapping with the lower bound of 3.0 (2.75). With the current code, the lower and upper bounds will be instead 2.875. Adapt test to this, and this allows to also ensure that we're always returning a sorted and unique list of scales (which is useful as also g-c-c can ensure that this is true). Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1878>
This commit is contained in:
parent
c86a1e00c0
commit
3e1e2cb91f
@ -1767,7 +1767,8 @@ meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode)
|
||||
static float
|
||||
get_closest_scale_factor_for_resolution (float width,
|
||||
float height,
|
||||
float scale)
|
||||
float scale,
|
||||
float threshold)
|
||||
{
|
||||
unsigned int i, j;
|
||||
float scaled_h;
|
||||
@ -1799,8 +1800,8 @@ get_closest_scale_factor_for_resolution (float width,
|
||||
current_scale = width / scaled_w;
|
||||
scaled_h = height / current_scale;
|
||||
|
||||
if (current_scale >= scale + SCALE_FACTORS_STEPS ||
|
||||
current_scale <= scale - SCALE_FACTORS_STEPS ||
|
||||
if (current_scale >= scale + threshold ||
|
||||
current_scale <= scale - threshold ||
|
||||
current_scale < MINIMUM_SCALE_FACTOR ||
|
||||
current_scale > MAXIMUM_SCALE_FACTOR)
|
||||
{
|
||||
@ -1851,14 +1852,22 @@ meta_monitor_calculate_supported_scales (MetaMonitor *monitor,
|
||||
}
|
||||
else
|
||||
{
|
||||
float max_bound;
|
||||
|
||||
if (i == floorf (MINIMUM_SCALE_FACTOR) ||
|
||||
i == ceilf (MAXIMUM_SCALE_FACTOR))
|
||||
max_bound = SCALE_FACTORS_STEPS;
|
||||
else
|
||||
max_bound = SCALE_FACTORS_STEPS / 2.0;
|
||||
|
||||
for (j = 0; j < SCALE_FACTORS_PER_INTEGER; j++)
|
||||
{
|
||||
float scale;
|
||||
float scale_value = i + j * SCALE_FACTORS_STEPS;
|
||||
|
||||
scale = get_closest_scale_factor_for_resolution (width, height,
|
||||
scale_value);
|
||||
|
||||
scale_value,
|
||||
max_bound);
|
||||
if (scale > 0.0)
|
||||
g_array_append_val (supported_scales, scale);
|
||||
}
|
||||
|
@ -811,6 +811,13 @@ check_expected_scales (MetaMonitor *monitor,
|
||||
g_assert_cmpfloat (fmodf (width / scales[i], 1.0), ==, 0.0);
|
||||
g_assert_cmpfloat (fmodf (height / scales[i], 1.0), ==, 0.0);
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
/* And that scales are sorted and unique */
|
||||
g_assert_cmpfloat (scales[i], >, scales[i-1]);
|
||||
g_assert_false (G_APPROX_VALUE (scales[i], scales[i-1], 0.000001));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6273,9 +6273,9 @@ meta_test_monitor_supported_fractional_scales (void)
|
||||
{
|
||||
.width = 4096,
|
||||
.height = 2160,
|
||||
.n_scales = 10,
|
||||
.n_scales = 8,
|
||||
.scales = { 1.000000, 1.333333, 1.454545, 1.777778, 2.000000,
|
||||
2.666667, 2.666667, 3.200000, 3.200000, 4.000000
|
||||
2.666667, 3.200000, 4.000000
|
||||
}
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user