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
This commit is contained in:
Jonas Ådahl 2017-05-25 17:20:59 +08:00
parent b64c69e4bc
commit 10b0351a59
12 changed files with 126 additions and 59 deletions

View File

@ -943,13 +943,16 @@ meta_verify_monitor_config (MetaMonitorConfig *monitor_config,
gboolean gboolean
meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config, meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
MetaLogicalMonitorLayoutMode layout_mode, MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitorManager *monitor_manager,
GError **error) GError **error)
{ {
GList *l; GList *l;
int expected_mode_width = 0; int expected_mode_width = 0;
int expected_mode_height = 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, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Invalid logical monitor config scale %g", "Invalid logical monitor config scale %g",

View File

@ -117,6 +117,7 @@ gboolean meta_verify_monitor_config (MetaMonitorConfig *monitor_config,
gboolean meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config, gboolean meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
MetaLogicalMonitorLayoutMode layout_mode, MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitorManager *monitor_manager,
GError **error); GError **error);
gboolean meta_verify_monitors_config (MetaMonitorsConfig *config, gboolean meta_verify_monitors_config (MetaMonitorsConfig *config,

View File

@ -630,6 +630,7 @@ handle_end_element (GMarkupParseContext *context,
if (!meta_verify_logical_monitor_config (logical_monitor_config, if (!meta_verify_logical_monitor_config (logical_monitor_config,
layout_mode, layout_mode,
store->monitor_manager,
error)) error))
return; return;
} }
@ -1069,13 +1070,17 @@ static void
append_logical_monitor_xml (GString *buffer, append_logical_monitor_xml (GString *buffer,
MetaLogicalMonitorConfig *logical_monitor_config) MetaLogicalMonitorConfig *logical_monitor_config)
{ {
char scale_str[G_ASCII_DTOSTR_BUF_SIZE];
g_string_append (buffer, " <logicalmonitor>\n"); g_string_append (buffer, " <logicalmonitor>\n");
g_string_append_printf (buffer, " <x>%d</x>\n", g_string_append_printf (buffer, " <x>%d</x>\n",
logical_monitor_config->layout.x); logical_monitor_config->layout.x);
g_string_append_printf (buffer, " <y>%d</y>\n", g_string_append_printf (buffer, " <y>%d</y>\n",
logical_monitor_config->layout.y); logical_monitor_config->layout.y);
g_string_append_printf (buffer, " <scale>%g</scale>\n", g_ascii_dtostr (scale_str, G_ASCII_DTOSTR_BUF_SIZE,
logical_monitor_config->scale); logical_monitor_config->scale);
g_string_append_printf (buffer, " <scale>%s</scale>\n",
scale_str);
if (logical_monitor_config->is_primary) if (logical_monitor_config->is_primary)
g_string_append (buffer, " <primary>yes</primary>\n"); g_string_append (buffer, " <primary>yes</primary>\n");
if (logical_monitor_config->is_presentation) if (logical_monitor_config->is_presentation)

View File

@ -40,7 +40,13 @@
#define MAX_CRTCS (MAX_MONITORS * 2) #define MAX_CRTCS (MAX_MONITORS * 2)
#define MAX_MODES (MAX_MONITORS * 4) #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, 1.0,
2.0 2.0
}; };
@ -242,20 +248,6 @@ meta_output_dummy_notify_destroy (MetaOutput *output)
g_clear_pointer (&output->driver_private, g_free); 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 static void
meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager) 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++) for (i = 0; i < num_monitors && scales_str_list[i]; i++)
{ {
float scale = g_ascii_strtod (scales_str_list[i], NULL); 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; monitor_scales[i] = scale;
else else
meta_warning ("Invalid dummy monitor scale\n"); meta_warning ("Invalid dummy monitor scale\n");
@ -621,12 +615,22 @@ meta_monitor_manager_dummy_calculate_monitor_mode_scale (MetaMonitorManager *man
} }
static void static void
meta_monitor_manager_dummy_get_supported_scales (MetaMonitorManager *manager, meta_monitor_manager_dummy_get_supported_scales (MetaMonitorManager *manager,
float **scales, MetaLogicalMonitorLayoutMode layout_mode,
int *n_scales) float **scales,
int *n_scales)
{ {
*scales = supported_scales_dummy; switch (layout_mode)
*n_scales = G_N_ELEMENTS (supported_scales_dummy); {
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 static gboolean

View File

@ -394,9 +394,10 @@ struct _MetaMonitorManagerClass
MetaMonitor *, MetaMonitor *,
MetaMonitorMode *); MetaMonitorMode *);
void (*get_supported_scales) (MetaMonitorManager *, void (*get_supported_scales) (MetaMonitorManager *,
float **, MetaLogicalMonitorLayoutMode ,
int *); float **,
int *);
MetaMonitorManagerCapability (*get_capabilities) (MetaMonitorManager *); MetaMonitorManagerCapability (*get_capabilities) (MetaMonitorManager *);
@ -508,6 +509,10 @@ float meta_monitor_manager_calculate_monitor_mode_scale (MetaMonito
MetaMonitor *monitor, MetaMonitor *monitor,
MetaMonitorMode *monitor_mode); MetaMonitorMode *monitor_mode);
gboolean meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
float scale);
MetaMonitorManagerCapability MetaMonitorManagerCapability
meta_monitor_manager_get_capabilities (MetaMonitorManager *manager); meta_monitor_manager_get_capabilities (MetaMonitorManager *manager);

View File

@ -407,14 +407,15 @@ meta_monitor_manager_calculate_monitor_mode_scale (MetaMonitorManager *manager,
} }
static void static void
meta_monitor_manager_get_supported_scales (MetaMonitorManager *manager, meta_monitor_manager_get_supported_scales (MetaMonitorManager *manager,
float **scales, MetaLogicalMonitorLayoutMode layout_mode,
int *n_scales) float **scales,
int *n_scales)
{ {
MetaMonitorManagerClass *manager_class = MetaMonitorManagerClass *manager_class =
META_MONITOR_MANAGER_GET_CLASS (manager); 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 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")); g_variant_builder_init (&supported_scales_builder, G_VARIANT_TYPE ("ad"));
meta_monitor_manager_get_supported_scales (manager, meta_monitor_manager_get_supported_scales (manager,
manager->layout_mode,
&supported_scales, &supported_scales,
&n_supported_scales); &n_supported_scales);
for (i = 0; i < n_supported_scales; i++) 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_MONITOR_FORMAT
#undef LOGICAL_MONITORS_FORMAT #undef LOGICAL_MONITORS_FORMAT
static gboolean gboolean
meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager, meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager,
float scale) MetaLogicalMonitorLayoutMode layout_mode,
float scale)
{ {
float *supported_scales; float *supported_scales;
int n_supported_scales; int n_supported_scales;
int i; int i;
meta_monitor_manager_get_supported_scales (manager, meta_monitor_manager_get_supported_scales (manager,
layout_mode,
&supported_scales, &supported_scales,
&n_supported_scales); &n_supported_scales);
for (i = 0; i < n_supported_scales; i++) 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; float scale = logical_monitor_config->scale;
GList *k; 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, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Scale not supported by backend"); "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, if (!meta_verify_logical_monitor_config (logical_monitor_config,
layout_mode, layout_mode,
manager,
error)) error))
{ {
meta_logical_monitor_config_free (logical_monitor_config); meta_logical_monitor_config_free (logical_monitor_config);

View File

@ -52,7 +52,13 @@
#define ALL_TRANSFORMS_MASK ((1 << ALL_TRANSFORMS) - 1) #define ALL_TRANSFORMS_MASK ((1 << ALL_TRANSFORMS) - 1)
#define SYNC_TOLERANCE 0.01 /* 1 percent */ #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, 1.0,
2.0 2.0
}; };
@ -1847,12 +1853,22 @@ meta_monitor_manager_kms_calculate_monitor_mode_scale (MetaMonitorManager *manag
} }
static void static void
meta_monitor_manager_kms_get_supported_scales (MetaMonitorManager *manager, meta_monitor_manager_kms_get_supported_scales (MetaMonitorManager *manager,
float **scales, MetaLogicalMonitorLayoutMode layout_mode,
int *n_scales) float **scales,
int *n_scales)
{ {
*scales = supported_scales_kms; switch (layout_mode)
*n_scales = G_N_ELEMENTS (supported_scales_kms); {
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 static MetaMonitorManagerCapability

View File

@ -1800,9 +1800,10 @@ meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *ma
} }
static void static void
meta_monitor_manager_xrandr_get_supported_scales (MetaMonitorManager *manager, meta_monitor_manager_xrandr_get_supported_scales (MetaMonitorManager *manager,
float **scales, MetaLogicalMonitorLayoutMode layout_mode,
int *n_scales) float **scales,
int *n_scales)
{ {
*scales = supported_scales_xrandr; *scales = supported_scales_xrandr;
*n_scales = G_N_ELEMENTS (supported_scales_xrandr); *n_scales = G_N_ELEMENTS (supported_scales_xrandr);

View File

@ -24,7 +24,13 @@
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/meta-monitor-config-manager.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, 1.0,
2.0 2.0
}; };
@ -415,12 +421,22 @@ meta_monitor_manager_test_calculate_monitor_mode_scale (MetaMonitorManager *mana
} }
static void static void
meta_monitor_manager_test_get_supported_scales (MetaMonitorManager *manager, meta_monitor_manager_test_get_supported_scales (MetaMonitorManager *manager,
float **scales, MetaLogicalMonitorLayoutMode layout_mode,
int *n_scales) float **scales,
int *n_scales)
{ {
*scales = supported_scales_test; switch (layout_mode)
*n_scales = G_N_ELEMENTS (supported_scales_test); {
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 static gboolean

View File

@ -51,7 +51,7 @@ typedef struct _MonitorTestCaseMonitor
typedef struct _MonitorTestCaseLogicalMonitor typedef struct _MonitorTestCaseLogicalMonitor
{ {
MetaRectangle layout; MetaRectangle layout;
int scale; float scale;
MetaMonitorTransform transform; MetaMonitorTransform transform;
gboolean is_primary; gboolean is_primary;
gboolean is_presentation; gboolean is_presentation;
@ -141,9 +141,9 @@ check_monitor_configuration (MetaMonitorConfigStore *config_store,
g_assert (meta_rectangle_equal (&logical_monitor_config->layout, g_assert (meta_rectangle_equal (&logical_monitor_config->layout,
&config_expect->logical_monitors[i].layout)); &config_expect->logical_monitors[i].layout));
g_assert_cmpint (logical_monitor_config->scale, g_assert_cmpfloat (logical_monitor_config->scale,
==, ==,
config_expect->logical_monitors[i].scale); config_expect->logical_monitors[i].scale);
g_assert_cmpint (logical_monitor_config->transform, g_assert_cmpint (logical_monitor_config->transform,
==, ==,
config_expect->logical_monitors[i].transform); config_expect->logical_monitors[i].transform);

View File

@ -437,9 +437,9 @@ check_logical_monitor (MonitorTestCase *test_case,
g_assert_cmpint (logical_monitor->rect.height, g_assert_cmpint (logical_monitor->rect.height,
==, ==,
test_logical_monitor->layout.height); test_logical_monitor->layout.height);
g_assert_cmpint (logical_monitor->scale, g_assert_cmpfloat (logical_monitor->scale,
==, ==,
test_logical_monitor->scale); test_logical_monitor->scale);
g_assert_cmpuint (logical_monitor->transform, g_assert_cmpuint (logical_monitor->transform,
==, ==,
test_logical_monitor->transform); test_logical_monitor->transform);

View File

@ -111,6 +111,15 @@ calculate_suitable_subpixel_order (MetaLogicalMonitor *logical_monitor)
return cogl_subpixel_order_to_wl_output_subpixel (subpixel_order); 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 static void
send_output_events (struct wl_resource *resource, send_output_events (struct wl_resource *resource,
MetaWaylandOutput *wayland_output, MetaWaylandOutput *wayland_output,
@ -205,7 +214,7 @@ send_output_events (struct wl_resource *resource,
{ {
int scale; int scale;
scale = (int) meta_logical_monitor_get_scale (logical_monitor); scale = calculate_wayland_output_scale (logical_monitor);
if (need_all_events || if (need_all_events ||
old_scale != scale) old_scale != scale)
{ {
@ -273,7 +282,7 @@ meta_wayland_output_set_logical_monitor (MetaWaylandOutput *wayland_output,
if (current_mode == preferred_mode) if (current_mode == preferred_mode)
wayland_output->mode_flags |= WL_OUTPUT_MODE_PREFERRED; 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); wayland_output->refresh_rate = meta_monitor_mode_get_refresh_rate (current_mode);
} }