[mutter] monitor: Dynamically calculate supported scales per resolution
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] monitor: Dynamically calculate supported scales per resolution
- Date: Fri, 14 Jul 2017 13:01:37 +0000 (UTC)
commit 3e8d0204bdb37507f06c51bb91ddd3cc0a511a2b
Author: Marco Trevisan (Treviño) <mail 3v1n0 net>
Date: Tue Jun 6 11:27:58 2017 +0800
monitor: Dynamically calculate supported scales per resolution
When using logical sized monitors we are allowed to use fractional scaling
but only if the resulting scaled logical monitor size is in integer form.
So, in order to get this, we allow to scale the monitor to up to
8 fractional values per integer, doing some computation in order to
fetch the nearest values which are closer to the scaling factors we can
permit.
https://bugzilla.gnome.org/show_bug.cgi?id=765011
src/backends/meta-monitor.c | 117 ++++++++++++++++++++++++++++++++++++-------
1 files changed, 98 insertions(+), 19 deletions(-)
---
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index c01daef..d86cea1 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -27,6 +27,10 @@
#include "backends/meta-monitor-manager-private.h"
#include "backends/meta-settings-private.h"
+#define SCALE_FACTORS_PER_INTEGER 8
+#define MINIMUM_SCALE_FACTOR 0.5f
+#define MAXIMUM_SCALE_FACTOR 4.0f
+
typedef struct _MetaMonitorMode
{
MetaMonitorModeSpec spec;
@@ -1336,37 +1340,112 @@ meta_monitor_calculate_mode_scale (MetaMonitor *monitor,
return calculate_scale (monitor, monitor_mode);
}
+static float
+get_closest_scale_factor_for_resolution (float width,
+ float height,
+ float scale,
+ float scale_step)
+{
+ unsigned int i, j;
+ float scaled_h;
+ float scaled_w;
+ float best_scale;
+ int base_scaled_w;
+ gboolean limit_exceeded;
+ gboolean found_one;
+
+ best_scale = 0;
+ scaled_w = width / scale;
+ scaled_h = height / scale;
+
+ if (scale < MINIMUM_SCALE_FACTOR || scale > MAXIMUM_SCALE_FACTOR)
+ goto out;
+
+ if (floorf (scaled_w) == scaled_w && floorf (scaled_h) == scaled_h)
+ return scale;
+
+ i = 0;
+ found_one = FALSE;
+ limit_exceeded = FALSE;
+ base_scaled_w = floorf (scaled_w);
+
+ do
+ {
+
+ for (j = 0; j < 2; j++)
+ {
+ float current_scale;
+ int offset = i * (j ? 1 : -1);
+
+ scaled_w = base_scaled_w + offset;
+ current_scale = width / scaled_w;
+ scaled_h = height / current_scale;
+
+ if (current_scale >= scale + scale_step ||
+ current_scale <= scale - scale_step ||
+ current_scale < MINIMUM_SCALE_FACTOR ||
+ current_scale > MAXIMUM_SCALE_FACTOR)
+ {
+ limit_exceeded = TRUE;
+ continue;
+ }
+
+ if (floorf (scaled_h) == scaled_h)
+ {
+ found_one = TRUE;
+
+ if (fabsf (current_scale - scale) < fabsf (best_scale - scale))
+ best_scale = current_scale;
+ }
+ }
+
+ i++;
+ }
+ while (!found_one && !limit_exceeded);
+
+out:
+ return best_scale;
+}
+
float *
meta_monitor_calculate_supported_scales (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaMonitorScalesConstraint constraints,
int *n_supported_scales)
{
- unsigned int i;
+ unsigned int i, j;
int width, height;
+ float scale_steps;
GArray *supported_scales;
- static const float all_scales[] = {
- 1.0,
- 1.5,
- 2.0
- };
-
- meta_monitor_mode_get_resolution (monitor_mode, &width, &height);
+ scale_steps = 1.0 / (float) SCALE_FACTORS_PER_INTEGER;
supported_scales = g_array_new (FALSE, FALSE, sizeof (float));
- for (i = 0; i < G_N_ELEMENTS (all_scales); i++)
- {
- float scale = all_scales[i];
-
- if ((constraints & META_MONITOR_SCALES_CONSTRAINT_NO_FRAC) &&
- fmodf (scale, 1.0) != 0.0)
- continue;
-
- if (fmodf (width, scale) != 0.0 || fmodf (height, scale) != 0.0)
- continue;
+ meta_monitor_mode_get_resolution (monitor_mode, &width, &height);
- g_array_append_val (supported_scales, scale);
+ for (i = floorf (MINIMUM_SCALE_FACTOR);
+ i <= ceilf (MAXIMUM_SCALE_FACTOR);
+ i++)
+ {
+ for (j = 0; j < SCALE_FACTORS_PER_INTEGER; j++)
+ {
+ float scale;
+ float scale_value = i + j * scale_steps;
+
+ if ((constraints & META_MONITOR_SCALES_CONSTRAINT_NO_FRAC) &&
+ fmodf (scale_value, 1.0) != 0.0)
+ {
+ continue;
+ }
+
+ scale = get_closest_scale_factor_for_resolution (width,
+ height,
+ scale_value,
+ scale_steps);
+
+ if (scale > 0.0f)
+ g_array_append_val (supported_scales, scale);
+ }
}
*n_supported_scales = supported_scales->len;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]