monitor-manager-xrandr: Use monitor to calculate scaling

In Xrandr we were caching the available scaling modes that were computed just
for the current mode, for each monitor, while we can actually reuse the
default implementation, by just passing the proper scaling constraint.

In monitor we need then to properly filter these values, by only accepting
integer scaling factors that would allow to have a minimal logical monitor
size.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/407

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/336>
This commit is contained in:
Marco Trevisan (Treviño) 2018-11-23 22:35:51 -05:00
parent 67eb60c19a
commit 1ac63fcd77
2 changed files with 35 additions and 110 deletions

View File

@ -1737,6 +1737,18 @@ is_logical_size_large_enough (int width,
return width * height >= MINIMUM_LOGICAL_AREA; return width * height >= MINIMUM_LOGICAL_AREA;
} }
static gboolean
is_scale_valid_for_size (float width,
float height,
float scale)
{
if (scale < MINIMUM_SCALE_FACTOR || scale > MAXIMUM_SCALE_FACTOR)
return FALSE;
return is_logical_size_large_enough (floorf (width / scale),
floorf (height / scale));
}
gboolean gboolean
meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode) meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode)
{ {
@ -1766,20 +1778,16 @@ get_closest_scale_factor_for_resolution (float width,
gboolean found_one; gboolean found_one;
best_scale = 0; best_scale = 0;
scaled_w = width / scale;
scaled_h = height / scale;
if (scale < MINIMUM_SCALE_FACTOR || if (!is_scale_valid_for_size (width, height, scale))
scale > MAXIMUM_SCALE_FACTOR ||
!is_logical_size_large_enough (floorf (scaled_w), floorf (scaled_h)))
goto out; goto out;
if (floorf (scaled_w) == scaled_w && floorf (scaled_h) == scaled_h) if (fmodf (width, scale) == 0.0 && fmodf (height, scale) == 0.0)
return scale; return scale;
i = 0; i = 0;
found_one = FALSE; found_one = FALSE;
base_scaled_w = floorf (scaled_w); base_scaled_w = floorf (width / scale);
do do
{ {
@ -1840,15 +1848,20 @@ meta_monitor_calculate_supported_scales (MetaMonitor *monitor,
float scale; float scale;
float scale_value = i + j * SCALE_FACTORS_STEPS; float scale_value = i + j * SCALE_FACTORS_STEPS;
if ((constraints & META_MONITOR_SCALES_CONSTRAINT_NO_FRAC) && if (constraints & META_MONITOR_SCALES_CONSTRAINT_NO_FRAC)
fmodf (scale_value, 1.0) != 0.0)
{ {
if (fmodf (scale_value, 1.0) != 0.0 ||
!is_scale_valid_for_size (width, height, scale_value))
continue; continue;
}
scale = scale_value;
}
else
{
scale = get_closest_scale_factor_for_resolution (width, scale = get_closest_scale_factor_for_resolution (width,
height, height,
scale_value); scale_value);
}
if (scale > 0.0f) if (scale > 0.0f)
g_array_append_val (supported_scales, scale); g_array_append_val (supported_scales, scale);

View File

@ -77,9 +77,6 @@ struct _MetaMonitorManagerXrandr
xcb_timestamp_t last_xrandr_set_timestamp; xcb_timestamp_t last_xrandr_set_timestamp;
GHashTable *tiled_monitor_atoms; GHashTable *tiled_monitor_atoms;
float *supported_scales;
int n_supported_scales;
}; };
struct _MetaMonitorManagerXrandrClass struct _MetaMonitorManagerXrandrClass
@ -584,17 +581,6 @@ meta_monitor_manager_xrandr_ensure_initial_config (MetaMonitorManager *manager)
meta_monitor_manager_update_logical_state_derived (manager, config); meta_monitor_manager_update_logical_state_derived (manager, config);
} }
static void
meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager,
MetaMonitorsConfig *config)
{
MetaMonitorManagerXrandr *manager_xrandr =
META_MONITOR_MANAGER_XRANDR (manager);
g_clear_pointer (&manager_xrandr->supported_scales, g_free);
meta_monitor_manager_rebuild_derived (manager, config);
}
static gboolean static gboolean
meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *manager, meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *manager,
MetaMonitorsConfig *config, MetaMonitorsConfig *config,
@ -609,7 +595,7 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
if (!manager->in_init) if (!manager->in_init)
apply_crtc_assignments (manager, TRUE, NULL, 0, NULL, 0); apply_crtc_assignments (manager, TRUE, NULL, 0, NULL, 0);
meta_monitor_manager_xrandr_rebuild_derived (manager, NULL); meta_monitor_manager_rebuild_derived (manager, NULL);
return TRUE; return TRUE;
} }
@ -644,7 +630,7 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
} }
else else
{ {
meta_monitor_manager_xrandr_rebuild_derived (manager, config); meta_monitor_manager_rebuild_derived (manager, config);
} }
} }
@ -891,77 +877,6 @@ meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager
return meta_monitor_calculate_mode_scale (monitor, monitor_mode, constraints); return meta_monitor_calculate_mode_scale (monitor, monitor_mode, constraints);
} }
static void
add_supported_scale (GArray *supported_scales,
float scale)
{
unsigned int i;
for (i = 0; i < supported_scales->len; i++)
{
float supported_scale = g_array_index (supported_scales, float, i);
if (scale == supported_scale)
return;
}
g_array_append_val (supported_scales, scale);
}
static int
compare_scales (gconstpointer a,
gconstpointer b)
{
float f = *(float *) a - *(float *) b;
if (f < 0)
return -1;
if (f > 0)
return 1;
return 0;
}
static void
ensure_supported_monitor_scales (MetaMonitorManager *manager)
{
MetaMonitorManagerXrandr *manager_xrandr =
META_MONITOR_MANAGER_XRANDR (manager);
MetaMonitorScalesConstraint constraints;
GList *l;
GArray *supported_scales;
if (manager_xrandr->supported_scales)
return;
constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
supported_scales = g_array_new (FALSE, FALSE, sizeof (float));
for (l = manager->monitors; l; l = l->next)
{
MetaMonitor *monitor = l->data;
MetaMonitorMode *monitor_mode;
float *monitor_scales;
int n_monitor_scales;
int i;
monitor_mode = meta_monitor_get_preferred_mode (monitor);
monitor_scales =
meta_monitor_calculate_supported_scales (monitor,
monitor_mode,
constraints,
&n_monitor_scales);
for (i = 0; i < n_monitor_scales; i++)
add_supported_scale (supported_scales, monitor_scales[i]);
g_array_sort (supported_scales, compare_scales);
g_free (monitor_scales);
}
manager_xrandr->supported_scales = (float *) supported_scales->data;
manager_xrandr->n_supported_scales = supported_scales->len;
g_array_free (supported_scales, FALSE);
}
static float * static float *
meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager *manager, meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode, MetaLogicalMonitorLayoutMode layout_mode,
@ -969,14 +884,12 @@ meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager
MetaMonitorMode *monitor_mode, MetaMonitorMode *monitor_mode,
int *n_supported_scales) int *n_supported_scales)
{ {
MetaMonitorManagerXrandr *manager_xrandr = MetaMonitorScalesConstraint constraints;
META_MONITOR_MANAGER_XRANDR (manager);
ensure_supported_monitor_scales (manager); constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
return meta_monitor_calculate_supported_scales (monitor, monitor_mode,
*n_supported_scales = manager_xrandr->n_supported_scales; constraints,
return g_memdup2 (manager_xrandr->supported_scales, n_supported_scales);
manager_xrandr->n_supported_scales * sizeof (float));
} }
static MetaMonitorManagerCapability static MetaMonitorManagerCapability
@ -1063,7 +976,6 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object); MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object);
g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms); g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
g_free (manager_xrandr->supported_scales);
G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object); G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
} }
@ -1148,7 +1060,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
config = NULL; config = NULL;
} }
meta_monitor_manager_xrandr_rebuild_derived (manager, config); meta_monitor_manager_rebuild_derived (manager, config);
} }
return TRUE; return TRUE;