[mutter] Add support for rudimentary fractional scaling



commit 10b0351a595690d74a71c8c62e2f8df5dcaf6dfd
Author: Jonas Ådahl <jadahl gmail com>
Date:   Thu May 25 17:20:59 2017 +0800

    Add support for rudimentary fractional scaling
    
    When the logical layout mode is used, allow configuring the scaling to
    be non-integer. Supported scales are so far hard coded to include at
    most 1, 1.5 and 2, and scales that doesn't result in non-fractional
    logical monitor sizes are discarded.
    
    Wayland outputs are set to have scale ceil(actual_scale) meaning well
    behaving Wayland clients will provide buffers with buffer scale 2, thus
    being scaled down to the fractional scale.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=765011

 src/backends/meta-monitor-config-manager.c     |    5 ++-
 src/backends/meta-monitor-config-manager.h     |    1 +
 src/backends/meta-monitor-config-store.c       |    9 ++++-
 src/backends/meta-monitor-manager-dummy.c      |   46 +++++++++++++-----------
 src/backends/meta-monitor-manager-private.h    |   11 ++++--
 src/backends/meta-monitor-manager.c            |   23 ++++++++----
 src/backends/native/meta-monitor-manager-kms.c |   28 +++++++++++---
 src/backends/x11/meta-monitor-manager-xrandr.c |    7 ++--
 src/tests/meta-monitor-manager-test.c          |   28 +++++++++++---
 src/tests/monitor-store-unit-tests.c           |    8 ++--
 src/tests/monitor-unit-tests.c                 |    6 ++--
 src/wayland/meta-wayland-outputs.c             |   13 ++++++-
 12 files changed, 126 insertions(+), 59 deletions(-)
---
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index fae9328..4a12bc6 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -943,13 +943,16 @@ meta_verify_monitor_config (MetaMonitorConfig *monitor_config,
 gboolean
 meta_verify_logical_monitor_config (MetaLogicalMonitorConfig    *logical_monitor_config,
                                     MetaLogicalMonitorLayoutMode layout_mode,
+                                    MetaMonitorManager          *monitor_manager,
                                     GError                     **error)
 {
   GList *l;
   int expected_mode_width = 0;
   int expected_mode_height = 0;
 
-  if (logical_monitor_config->scale < 1.0)
+  if (!meta_monitor_manager_is_scale_supported (monitor_manager,
+                                                layout_mode,
+                                                logical_monitor_config->scale))
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                    "Invalid logical monitor config scale %g",
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index d9f5342..f2f21bc 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -117,6 +117,7 @@ gboolean meta_verify_monitor_config (MetaMonitorConfig *monitor_config,
 
 gboolean meta_verify_logical_monitor_config (MetaLogicalMonitorConfig    *logical_monitor_config,
                                              MetaLogicalMonitorLayoutMode layout_mode,
+                                             MetaMonitorManager          *monitor_manager,
                                              GError                     **error);
 
 gboolean meta_verify_monitors_config (MetaMonitorsConfig *config,
diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c
index 1dd6402..d86c7a0 100644
--- a/src/backends/meta-monitor-config-store.c
+++ b/src/backends/meta-monitor-config-store.c
@@ -630,6 +630,7 @@ handle_end_element (GMarkupParseContext  *context,
 
             if (!meta_verify_logical_monitor_config (logical_monitor_config,
                                                      layout_mode,
+                                                     store->monitor_manager,
                                                      error))
               return;
           }
@@ -1069,13 +1070,17 @@ static void
 append_logical_monitor_xml (GString                  *buffer,
                             MetaLogicalMonitorConfig *logical_monitor_config)
 {
+  char scale_str[G_ASCII_DTOSTR_BUF_SIZE];
+
   g_string_append (buffer, "    <logicalmonitor>\n");
   g_string_append_printf (buffer, "      <x>%d</x>\n",
                           logical_monitor_config->layout.x);
   g_string_append_printf (buffer, "      <y>%d</y>\n",
                           logical_monitor_config->layout.y);
-  g_string_append_printf (buffer, "      <scale>%g</scale>\n",
-                          logical_monitor_config->scale);
+  g_ascii_dtostr (scale_str, G_ASCII_DTOSTR_BUF_SIZE,
+                  logical_monitor_config->scale);
+  g_string_append_printf (buffer, "      <scale>%s</scale>\n",
+                          scale_str);
   if (logical_monitor_config->is_primary)
     g_string_append (buffer, "      <primary>yes</primary>\n");
   if (logical_monitor_config->is_presentation)
diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c
index c4949df..0060726 100644
--- a/src/backends/meta-monitor-manager-dummy.c
+++ b/src/backends/meta-monitor-manager-dummy.c
@@ -40,7 +40,13 @@
 #define MAX_CRTCS (MAX_MONITORS * 2)
 #define MAX_MODES (MAX_MONITORS * 4)
 
-static float supported_scales_dummy[] = {
+static float supported_scales_dummy_logical[] = {
+  1.0,
+  1.5,
+  2.0
+};
+
+static float supported_scales_dummy_physical[] = {
   1.0,
   2.0
 };
@@ -242,20 +248,6 @@ meta_output_dummy_notify_destroy (MetaOutput *output)
   g_clear_pointer (&output->driver_private, g_free);
 }
 
-static gboolean
-is_scale_supported (float scale)
-{
-  unsigned int i;
-
-  for (i = 0; i < G_N_ELEMENTS (supported_scales_dummy); i++)
-    {
-      if (scale == supported_scales_dummy[i])
-        return TRUE;
-    }
-
-  return FALSE;
-}
-
 static void
 meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
 {
@@ -328,7 +320,9 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
       for (i = 0; i < num_monitors && scales_str_list[i]; i++)
         {
           float scale = g_ascii_strtod (scales_str_list[i], NULL);
-          if (is_scale_supported (scale))
+          if (meta_monitor_manager_is_scale_supported (manager,
+                                                       manager->layout_mode,
+                                                       scale))
             monitor_scales[i] = scale;
           else
             meta_warning ("Invalid dummy monitor scale\n");
@@ -621,12 +615,22 @@ meta_monitor_manager_dummy_calculate_monitor_mode_scale (MetaMonitorManager *man
 }
 
 static void
-meta_monitor_manager_dummy_get_supported_scales (MetaMonitorManager *manager,
-                                                 float             **scales,
-                                                 int                *n_scales)
+meta_monitor_manager_dummy_get_supported_scales (MetaMonitorManager          *manager,
+                                                 MetaLogicalMonitorLayoutMode layout_mode,
+                                                 float                      **scales,
+                                                 int                         *n_scales)
 {
-  *scales = supported_scales_dummy;
-  *n_scales = G_N_ELEMENTS (supported_scales_dummy);
+  switch (layout_mode)
+    {
+    case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
+      *scales = supported_scales_dummy_logical;
+      *n_scales = G_N_ELEMENTS (supported_scales_dummy_logical);
+      break;
+    case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
+      *scales = supported_scales_dummy_physical;
+      *n_scales = G_N_ELEMENTS (supported_scales_dummy_physical);
+      break;
+    }
 }
 
 static gboolean
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index 38ec7c7..53ffc50 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -394,9 +394,10 @@ struct _MetaMonitorManagerClass
                                          MetaMonitor        *,
                                          MetaMonitorMode    *);
 
-  void (*get_supported_scales) (MetaMonitorManager *,
-                                float             **,
-                                int                *);
+  void (*get_supported_scales) (MetaMonitorManager          *,
+                                MetaLogicalMonitorLayoutMode ,
+                                float                      **,
+                                int                         *);
 
   MetaMonitorManagerCapability (*get_capabilities) (MetaMonitorManager *);
 
@@ -508,6 +509,10 @@ float              meta_monitor_manager_calculate_monitor_mode_scale (MetaMonito
                                                                       MetaMonitor        *monitor,
                                                                       MetaMonitorMode    *monitor_mode);
 
+gboolean           meta_monitor_manager_is_scale_supported (MetaMonitorManager          *manager,
+                                                            MetaLogicalMonitorLayoutMode layout_mode,
+                                                            float                        scale);
+
 MetaMonitorManagerCapability
                    meta_monitor_manager_get_capabilities (MetaMonitorManager *manager);
 
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 96fde4a..43ef91b 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -407,14 +407,15 @@ meta_monitor_manager_calculate_monitor_mode_scale (MetaMonitorManager *manager,
 }
 
 static void
-meta_monitor_manager_get_supported_scales (MetaMonitorManager *manager,
-                                           float             **scales,
-                                           int                *n_scales)
+meta_monitor_manager_get_supported_scales (MetaMonitorManager          *manager,
+                                           MetaLogicalMonitorLayoutMode layout_mode,
+                                           float                      **scales,
+                                           int                         *n_scales)
 {
   MetaMonitorManagerClass *manager_class =
     META_MONITOR_MANAGER_GET_CLASS (manager);
 
-  manager_class->get_supported_scales (manager, scales, n_scales);
+  manager_class->get_supported_scales (manager, layout_mode, scales, n_scales);
 }
 
 MetaMonitorManagerCapability
@@ -1633,6 +1634,7 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
 
   g_variant_builder_init (&supported_scales_builder, G_VARIANT_TYPE ("ad"));
   meta_monitor_manager_get_supported_scales (manager,
+                                             manager->layout_mode,
                                              &supported_scales,
                                              &n_supported_scales);
   for (i = 0; i < n_supported_scales; i++)
@@ -1703,15 +1705,17 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
 #undef LOGICAL_MONITOR_FORMAT
 #undef LOGICAL_MONITORS_FORMAT
 
-static gboolean
-meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager,
-                                         float               scale)
+gboolean
+meta_monitor_manager_is_scale_supported (MetaMonitorManager          *manager,
+                                         MetaLogicalMonitorLayoutMode layout_mode,
+                                         float                        scale)
 {
   float *supported_scales;
   int n_supported_scales;
   int i;
 
   meta_monitor_manager_get_supported_scales (manager,
+                                             layout_mode,
                                              &supported_scales,
                                              &n_supported_scales);
   for (i = 0; i < n_supported_scales; i++)
@@ -1736,7 +1740,9 @@ meta_monitor_manager_is_config_applicable (MetaMonitorManager *manager,
       float scale = logical_monitor_config->scale;
       GList *k;
 
-      if (!meta_monitor_manager_is_scale_supported (manager, scale))
+      if (!meta_monitor_manager_is_scale_supported (manager,
+                                                    config->layout_mode,
+                                                    scale))
         {
           g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                        "Scale not supported by backend");
@@ -1982,6 +1988,7 @@ create_logical_monitor_config_from_variant (MetaMonitorManager          *manager
 
   if (!meta_verify_logical_monitor_config (logical_monitor_config,
                                            layout_mode,
+                                           manager,
                                            error))
     {
       meta_logical_monitor_config_free (logical_monitor_config);
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 12b4df4..bb4f2e0 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -52,7 +52,13 @@
 #define ALL_TRANSFORMS_MASK ((1 << ALL_TRANSFORMS) - 1)
 #define SYNC_TOLERANCE 0.01    /* 1 percent */
 
-static float supported_scales_kms[] = {
+static float supported_scales_kms_logical[] = {
+  1.0,
+  1.5,
+  2.0
+};
+
+static float supported_scales_kms_physical[] = {
   1.0,
   2.0
 };
@@ -1847,12 +1853,22 @@ meta_monitor_manager_kms_calculate_monitor_mode_scale (MetaMonitorManager *manag
 }
 
 static void
-meta_monitor_manager_kms_get_supported_scales (MetaMonitorManager *manager,
-                                               float             **scales,
-                                               int                *n_scales)
+meta_monitor_manager_kms_get_supported_scales (MetaMonitorManager          *manager,
+                                               MetaLogicalMonitorLayoutMode layout_mode,
+                                               float                      **scales,
+                                               int                         *n_scales)
 {
-  *scales = supported_scales_kms;
-  *n_scales = G_N_ELEMENTS (supported_scales_kms);
+  switch (layout_mode)
+    {
+    case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
+      *scales = supported_scales_kms_logical;
+      *n_scales = G_N_ELEMENTS (supported_scales_kms_logical);
+      break;
+    case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
+      *scales = supported_scales_kms_physical;
+      *n_scales = G_N_ELEMENTS (supported_scales_kms_physical);
+      break;
+    }
 }
 
 static MetaMonitorManagerCapability
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 487978e..e5d5216 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -1800,9 +1800,10 @@ meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *ma
 }
 
 static void
-meta_monitor_manager_xrandr_get_supported_scales (MetaMonitorManager *manager,
-                                                  float             **scales,
-                                                  int                *n_scales)
+meta_monitor_manager_xrandr_get_supported_scales (MetaMonitorManager          *manager,
+                                                  MetaLogicalMonitorLayoutMode layout_mode,
+                                                  float                      **scales,
+                                                  int                         *n_scales)
 {
   *scales = supported_scales_xrandr;
   *n_scales = G_N_ELEMENTS (supported_scales_xrandr);
diff --git a/src/tests/meta-monitor-manager-test.c b/src/tests/meta-monitor-manager-test.c
index 2055861..cf33102 100644
--- a/src/tests/meta-monitor-manager-test.c
+++ b/src/tests/meta-monitor-manager-test.c
@@ -24,7 +24,13 @@
 #include "backends/meta-backend-private.h"
 #include "backends/meta-monitor-config-manager.h"
 
-static float supported_scales_test[] = {
+static float supported_scales_test_logical[] = {
+  1.0,
+  1.5,
+  2.0
+};
+
+static float supported_scales_test_physical[] = {
   1.0,
   2.0
 };
@@ -415,12 +421,22 @@ meta_monitor_manager_test_calculate_monitor_mode_scale (MetaMonitorManager *mana
 }
 
 static void
-meta_monitor_manager_test_get_supported_scales (MetaMonitorManager *manager,
-                                                float             **scales,
-                                                int                *n_scales)
+meta_monitor_manager_test_get_supported_scales (MetaMonitorManager          *manager,
+                                                MetaLogicalMonitorLayoutMode layout_mode,
+                                                float                      **scales,
+                                                int                         *n_scales)
 {
-  *scales = supported_scales_test;
-  *n_scales = G_N_ELEMENTS (supported_scales_test);
+  switch (layout_mode)
+    {
+    case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
+      *scales = supported_scales_test_logical;
+      *n_scales = G_N_ELEMENTS (supported_scales_test_logical);
+      break;
+    case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
+      *scales = supported_scales_test_physical;
+      *n_scales = G_N_ELEMENTS (supported_scales_test_physical);
+      break;
+    }
 }
 
 static gboolean
diff --git a/src/tests/monitor-store-unit-tests.c b/src/tests/monitor-store-unit-tests.c
index e01562d..b9a8798 100644
--- a/src/tests/monitor-store-unit-tests.c
+++ b/src/tests/monitor-store-unit-tests.c
@@ -51,7 +51,7 @@ typedef struct _MonitorTestCaseMonitor
 typedef struct _MonitorTestCaseLogicalMonitor
 {
   MetaRectangle layout;
-  int scale;
+  float scale;
   MetaMonitorTransform transform;
   gboolean is_primary;
   gboolean is_presentation;
@@ -141,9 +141,9 @@ check_monitor_configuration (MetaMonitorConfigStore        *config_store,
 
       g_assert (meta_rectangle_equal (&logical_monitor_config->layout,
                                       &config_expect->logical_monitors[i].layout));
-      g_assert_cmpint (logical_monitor_config->scale,
-                       ==,
-                       config_expect->logical_monitors[i].scale);
+      g_assert_cmpfloat (logical_monitor_config->scale,
+                         ==,
+                         config_expect->logical_monitors[i].scale);
       g_assert_cmpint (logical_monitor_config->transform,
                        ==,
                        config_expect->logical_monitors[i].transform);
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
index ae592bb..aadd162 100644
--- a/src/tests/monitor-unit-tests.c
+++ b/src/tests/monitor-unit-tests.c
@@ -437,9 +437,9 @@ check_logical_monitor (MonitorTestCase               *test_case,
   g_assert_cmpint (logical_monitor->rect.height,
                    ==,
                    test_logical_monitor->layout.height);
-  g_assert_cmpint (logical_monitor->scale,
-                   ==,
-                   test_logical_monitor->scale);
+  g_assert_cmpfloat (logical_monitor->scale,
+                     ==,
+                     test_logical_monitor->scale);
   g_assert_cmpuint (logical_monitor->transform,
                     ==,
                     test_logical_monitor->transform);
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
index 356a01d..7cb10f9 100644
--- a/src/wayland/meta-wayland-outputs.c
+++ b/src/wayland/meta-wayland-outputs.c
@@ -111,6 +111,15 @@ calculate_suitable_subpixel_order (MetaLogicalMonitor *logical_monitor)
   return cogl_subpixel_order_to_wl_output_subpixel (subpixel_order);
 }
 
+static int
+calculate_wayland_output_scale (MetaLogicalMonitor *logical_monitor)
+{
+  float scale;
+
+  scale = meta_logical_monitor_get_scale (logical_monitor);
+  return ceilf (scale);
+}
+
 static void
 send_output_events (struct wl_resource *resource,
                     MetaWaylandOutput  *wayland_output,
@@ -205,7 +214,7 @@ send_output_events (struct wl_resource *resource,
     {
       int scale;
 
-      scale = (int) meta_logical_monitor_get_scale (logical_monitor);
+      scale = calculate_wayland_output_scale (logical_monitor);
       if (need_all_events ||
           old_scale != scale)
         {
@@ -273,7 +282,7 @@ meta_wayland_output_set_logical_monitor (MetaWaylandOutput  *wayland_output,
 
   if (current_mode == preferred_mode)
     wayland_output->mode_flags |= WL_OUTPUT_MODE_PREFERRED;
-  wayland_output->scale = (int) meta_logical_monitor_get_scale (logical_monitor);
+  wayland_output->scale = calculate_wayland_output_scale (logical_monitor);
   wayland_output->refresh_rate = meta_monitor_mode_get_refresh_rate (current_mode);
 }
 


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