[mutter] monitor: Do not overlap when checking for applicable scaling values



commit 3e1e2cb91f6f1f9332a72f65d737b727260b2a23
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Fri May 28 19:45:42 2021 +0200

    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>

 src/backends/meta-monitor.c    | 19 ++++++++++++++-----
 src/tests/monitor-test-utils.c |  7 +++++++
 src/tests/monitor-unit-tests.c |  4 ++--
 3 files changed, 23 insertions(+), 7 deletions(-)
---
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index e4e8036724..5fc8b1f858 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -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);
             }
diff --git a/src/tests/monitor-test-utils.c b/src/tests/monitor-test-utils.c
index 00823d22fe..c5e838c851 100644
--- a/src/tests/monitor-test-utils.c
+++ b/src/tests/monitor-test-utils.c
@@ -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));
+        }
     }
 }
 
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
index 06b1703181..d7d3fdc356 100644
--- a/src/tests/monitor-unit-tests.c
+++ b/src/tests/monitor-unit-tests.c
@@ -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
               }
             },
             {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]