monitor-manager: Remove 'scale' from MetaOutput

Replace the 'scale' of an output with a vfunc on the MetaMonitorManager
class that takes a monitor and a monitor mode which calculates the
scale. On X11 this always returns 1, on KMS, the old formula is used.
On the dummy and test backends, the already configured values are
returned.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit is contained in:
Jonas Ådahl 2017-01-20 15:07:12 +08:00
parent 753e9c65a1
commit a393a614a1
12 changed files with 242 additions and 110 deletions

View File

@ -100,13 +100,20 @@ meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager,
{
MetaLogicalMonitor *logical_monitor;
MetaOutput *main_output;
MetaMonitorMode *monitor_mode;
int scale;
logical_monitor = g_object_new (META_TYPE_LOGICAL_MONITOR, NULL);
monitor_mode = meta_monitor_get_current_mode (monitor);
scale = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager,
monitor,
monitor_mode);
main_output = meta_monitor_get_main_output (monitor);
logical_monitor->number = monitor_number;
logical_monitor->winsys_id = main_output->winsys_id;
logical_monitor->scale = main_output->scale;
logical_monitor->scale = scale;
logical_monitor->in_fullscreen = -1;
logical_monitor->rect = *layout;

View File

@ -461,7 +461,8 @@ create_monitor_config (MetaMonitor *monitor,
}
static MetaLogicalMonitorConfig *
create_preferred_logical_monitor_config (MetaMonitor *monitor,
create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager,
MetaMonitor *monitor,
int x,
int y)
{
@ -473,7 +474,9 @@ create_preferred_logical_monitor_config (MetaMonitor *monitor,
mode = meta_monitor_get_preferred_mode (monitor);
meta_monitor_mode_get_resolution (mode, &width, &height);
scale = meta_monitor_get_calculated_scale (monitor);
scale = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager,
monitor,
mode);
monitor_config = create_monitor_config (monitor, mode);
@ -508,7 +511,9 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
return NULL;
primary_logical_monitor_config =
create_preferred_logical_monitor_config (primary_monitor, 0, 0);
create_preferred_logical_monitor_config (monitor_manager,
primary_monitor,
0, 0);
primary_logical_monitor_config->is_primary = TRUE;
logical_monitor_configs = g_list_append (NULL,
primary_logical_monitor_config);
@ -528,7 +533,9 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
continue;
logical_monitor_config =
create_preferred_logical_monitor_config (monitor, x, 0);
create_preferred_logical_monitor_config (monitor_manager,
monitor,
x, 0);
logical_monitor_configs = g_list_append (logical_monitor_configs,
logical_monitor_config);
@ -551,7 +558,9 @@ meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_ma
return NULL;
primary_logical_monitor_config =
create_preferred_logical_monitor_config (primary_monitor, 0, 0);
create_preferred_logical_monitor_config (monitor_manager,
primary_monitor,
0, 0);
primary_logical_monitor_config->is_primary = TRUE;
logical_monitor_configs = g_list_append (NULL,
primary_logical_monitor_config);
@ -587,7 +596,9 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
continue;
logical_monitor_config =
create_preferred_logical_monitor_config (monitor, x, y);
create_preferred_logical_monitor_config (monitor_manager,
monitor,
x, y);
logical_monitor_configs = g_list_append (logical_monitor_configs,
logical_monitor_config);

View File

@ -51,8 +51,16 @@ struct _MetaMonitorManagerDummyClass
MetaMonitorManagerClass parent_class;
};
typedef struct _MetaOutputDummy
{
int scale;
} MetaOutputDummy;
G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MONITOR_MANAGER);
static void
meta_output_dummy_notify_destroy (MetaOutput *output);
#define array_last(a, t) \
g_array_index (a, t, a->len - 1)
@ -75,6 +83,7 @@ append_monitor (GArray *modes,
}
};
MetaCrtc crtc;
MetaOutputDummy *output_dummy;
MetaOutput output;
unsigned int i;
@ -88,6 +97,11 @@ append_monitor (GArray *modes,
};
g_array_append_val (crtcs, crtc);
output_dummy = g_new0 (MetaOutputDummy, 1);
*output_dummy = (MetaOutputDummy) {
.scale = scale
};
output = (MetaOutput) {
.winsys_id = outputs->len + 1,
.name = g_strdup_printf ("LVDS%d", outputs->len + 1),
@ -103,7 +117,9 @@ append_monitor (GArray *modes,
.n_possible_clones = 0,
.backlight = -1,
.connector_type = META_CONNECTOR_TYPE_LVDS,
.scale = scale,
.driver_private = output_dummy,
.driver_notify =
(GDestroyNotify) meta_output_dummy_notify_destroy
};
output.modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (modes_decl));
@ -159,9 +175,15 @@ append_tiled_monitor (GArray *modes,
tile_group_id = outputs->len + 1;
for (i = 0; i < G_N_ELEMENTS (crtcs_decl); i++)
{
MetaOutputDummy *output_dummy;
MetaCrtcMode *preferred_mode;
unsigned int j;
output_dummy = g_new0 (MetaOutputDummy, 1);
*output_dummy = (MetaOutputDummy) {
.scale = scale
};
preferred_mode = &array_last (modes, MetaCrtcMode),
output = (MetaOutput) {
.winsys_id = outputs->len + 1,
@ -187,7 +209,9 @@ append_tiled_monitor (GArray *modes,
.tile_w = preferred_mode->width,
.tile_h = preferred_mode->height
},
.scale = scale
.driver_private = output_dummy,
.driver_notify =
(GDestroyNotify) meta_output_dummy_notify_destroy
};
output.modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (modes_decl));
@ -206,6 +230,12 @@ append_tiled_monitor (GArray *modes,
}
}
static void
meta_output_dummy_notify_destroy (MetaOutput *output)
{
g_clear_pointer (&output->driver_private, g_free);
}
static void
meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
{
@ -533,6 +563,20 @@ meta_monitor_manager_dummy_is_transform_handled (MetaMonitorManager *manager,
return manager_dummy->is_transform_handled;
}
static int
meta_monitor_manager_dummy_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
MetaOutput *output;
MetaOutputDummy *output_dummy;
output = meta_monitor_get_main_output (monitor);
output_dummy = output->driver_private;
return output_dummy->scale;
}
static void
meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
{
@ -543,6 +587,7 @@ meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
manager_class->apply_monitors_config = meta_monitor_manager_dummy_apply_monitors_config;
manager_class->apply_configuration = meta_monitor_manager_dummy_apply_config;
manager_class->is_transform_handled = meta_monitor_manager_dummy_is_transform_handled;
manager_class->calculate_monitor_mode_scale = meta_monitor_manager_dummy_calculate_monitor_mode_scale;
}
static void

View File

@ -59,6 +59,8 @@ typedef struct _MetaMonitorTiled MetaMonitorTiled;
typedef struct _MetaMonitorSpec MetaMonitorSpec;
typedef struct _MetaLogicalMonitor MetaLogicalMonitor;
typedef struct _MetaMonitorMode MetaMonitorMode;
typedef struct _MetaCrtc MetaCrtc;
typedef struct _MetaOutput MetaOutput;
typedef struct _MetaCrtcMode MetaCrtcMode;
@ -125,7 +127,6 @@ struct _MetaOutput
int width_mm;
int height_mm;
CoglSubpixelOrder subpixel_order;
int scale;
MetaConnectorType connector_type;
@ -348,6 +349,10 @@ struct _MetaMonitorManagerClass
gboolean (*is_transform_handled) (MetaMonitorManager *,
MetaCrtc *,
MetaMonitorTransform);
int (*calculate_monitor_mode_scale) (MetaMonitorManager *,
MetaMonitor *,
MetaMonitorMode *);
};
void meta_monitor_manager_rebuild (MetaMonitorManager *manager,
@ -447,6 +452,10 @@ void meta_monitor_manager_lid_is_closed_changed (MetaMonitorManage
gboolean meta_monitor_manager_is_headless (MetaMonitorManager *manager);
int meta_monitor_manager_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode);
void meta_monitor_manager_clear_output (MetaOutput *output);
void meta_monitor_manager_clear_mode (MetaCrtcMode *mode);
void meta_monitor_manager_clear_crtc (MetaCrtc *crtc);

View File

@ -275,6 +275,19 @@ meta_monitor_manager_is_headless (MetaMonitorManager *manager)
return !manager->monitors;
}
int
meta_monitor_manager_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
MetaMonitorManagerClass *manager_class =
META_MONITOR_MANAGER_GET_CLASS (manager);
return manager_class->calculate_monitor_mode_scale (manager,
monitor,
monitor_mode);
}
static void
meta_monitor_manager_ensure_initial_config (MetaMonitorManager *manager)
{

View File

@ -196,16 +196,6 @@ meta_monitor_is_underscanning (MetaMonitor *monitor)
return output->is_underscanning;
}
int
meta_monitor_get_calculated_scale (MetaMonitor *monitor)
{
MetaOutput *output;
output = meta_monitor_get_main_output (monitor);
return output->scale;
}
gboolean
meta_monitor_is_laptop_panel (MetaMonitor *monitor)
{
@ -291,6 +281,15 @@ meta_monitor_get_serial (MetaMonitor *monitor)
return output->serial;
}
MetaConnectorType
meta_monitor_get_connector_type (MetaMonitor *monitor)
{
MetaOutput *output;
output = meta_monitor_get_main_output (monitor);
return output->connector_type;
}
static void
meta_monitor_finalize (GObject *object)
{

View File

@ -26,8 +26,6 @@
#include "backends/meta-monitor-manager-private.h"
typedef struct _MetaMonitorMode MetaMonitorMode;
typedef struct _MetaMonitorSpec
{
char *connector;
@ -97,8 +95,6 @@ gboolean meta_monitor_is_underscanning (MetaMonitor *monitor);
gboolean meta_monitor_is_laptop_panel (MetaMonitor *monitor);
int meta_monitor_get_calculated_scale (MetaMonitor *monitor);
GList * meta_monitor_get_outputs (MetaMonitor *monitor);
void meta_monitor_get_current_resolution (MetaMonitor *monitor,
@ -121,6 +117,8 @@ const char * meta_monitor_get_product (MetaMonitor *monitor);
const char * meta_monitor_get_serial (MetaMonitor *monitor);
MetaConnectorType meta_monitor_get_connector_type (MetaMonitor *monitor);
uint32_t meta_monitor_tiled_get_tile_group_id (MetaMonitorTiled *monitor_tiled);
gboolean meta_monitor_get_suggested_position (MetaMonitor *monitor,

View File

@ -483,85 +483,6 @@ find_output_by_id (MetaOutput *outputs,
return NULL;
}
/* The minimum resolution at which we turn on a window-scale of 2 */
#define HIDPI_LIMIT 192
/* The minimum screen height at which we turn on a window-scale of 2;
* below this there just isn't enough vertical real estate for GNOME
* apps to work, and it's better to just be tiny */
#define HIDPI_MIN_HEIGHT 1200
/* From http://en.wikipedia.org/wiki/4K_resolution#Resolutions_of_common_formats */
#define SMALLEST_4K_WIDTH 3656
/* Based on code from gnome-settings-daemon */
static int
compute_scale (MetaOutput *output)
{
int scale = 1, width, height;
if (!output->crtc)
goto out;
width = output->crtc->rect.width;
height = output->crtc->rect.height;
/* Swap values on rotated transforms, so pixel and mm sizes
* from the same axes is compared.
*/
if (meta_monitor_transform_is_rotated (output->crtc->transform))
{
int tmp = width;
width = height;
height = tmp;
}
/* Scaling makes no sense */
if (height < HIDPI_MIN_HEIGHT)
goto out;
/* 4K TV */
if (output->name != NULL && strstr(output->name, "HDMI") != NULL &&
width >= SMALLEST_4K_WIDTH)
goto out;
/* Somebody encoded the aspect ratio (16/9 or 16/10)
* instead of the physical size */
if ((output->width_mm == 160 && output->height_mm == 90) ||
(output->width_mm == 160 && output->height_mm == 100) ||
(output->width_mm == 16 && output->height_mm == 9) ||
(output->width_mm == 16 && output->height_mm == 10))
goto out;
if (output->width_mm > 0 && output->height_mm > 0)
{
double dpi_x, dpi_y;
dpi_x = (double)width / (output->width_mm / 25.4);
dpi_y = (double)height / (output->height_mm / 25.4);
/* We don't completely trust these values so both
must be high, and never pick higher ratio than
2 automatically */
if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT)
scale = 2;
}
out:
return scale;
}
static int
get_output_scale (MetaMonitorManager *manager,
MetaOutput *output)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
int scale = g_settings_get_uint (manager_kms->desktop_settings, "scaling-factor");
if (scale > 0)
return scale;
else
return compute_scale (output);
}
static int
find_property_index (MetaMonitorManager *manager,
drmModeObjectPropertiesPtr props,
@ -930,8 +851,6 @@ init_output (MetaOutput *output,
/* MetaConnectorType matches DRM's connector types */
output->connector_type = (MetaConnectorType) connector->connector_type;
output->scale = get_output_scale (manager, output);
output_get_tile_info (manager_kms, output);
/* FIXME: backlight is a very driver specific thing unfortunately,
@ -1399,7 +1318,6 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output->is_dirty = TRUE;
output->crtc = crtc;
output->scale = get_output_scale (manager, output);
}
}
@ -1898,6 +1816,93 @@ meta_monitor_manager_kms_is_transform_handled (MetaMonitorManager *manager,
return FALSE;
}
/* The minimum resolution at which we turn on a window-scale of 2 */
#define HIDPI_LIMIT 192
/* The minimum screen height at which we turn on a window-scale of 2;
* below this there just isn't enough vertical real estate for GNOME
* apps to work, and it's better to just be tiny */
#define HIDPI_MIN_HEIGHT 1200
/* From http://en.wikipedia.org/wiki/4K_resolution#Resolutions_of_common_formats */
#define SMALLEST_4K_WIDTH 3656
static int
compute_scale (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
int resolution_width, resolution_height;
int width_mm, height_mm;
int scale;
scale = 1;
meta_monitor_mode_get_resolution (monitor_mode,
&resolution_width,
&resolution_height);
if (resolution_height < HIDPI_MIN_HEIGHT)
goto out;
/* 4K TV */
switch (meta_monitor_get_connector_type (monitor))
{
case META_CONNECTOR_TYPE_HDMIA:
case META_CONNECTOR_TYPE_HDMIB:
if (resolution_width >= SMALLEST_4K_WIDTH)
goto out;
break;
default:
break;
}
meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm);
/*
* Somebody encoded the aspect ratio (16/9 or 16/10) instead of the physical
* size.
*/
if ((width_mm == 160 && height_mm == 90) ||
(width_mm == 160 && height_mm == 100) ||
(width_mm == 16 && height_mm == 9) ||
(width_mm == 16 && height_mm == 10))
goto out;
if (width_mm > 0 && height_mm > 0)
{
double dpi_x, dpi_y;
dpi_x = (double) resolution_width / (width_mm / 25.4);
dpi_y = (double) resolution_height / (height_mm / 25.4);
/*
* We don't completely trust these values so both must be high, and never
* pick higher ratio than 2 automatically.
*/
if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT)
scale = 2;
}
out:
return scale;
}
static int
meta_monitor_manager_kms_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
int global_scale;
global_scale = g_settings_get_uint (manager_kms->desktop_settings,
"scaling-factor");
if (global_scale > 0)
return global_scale;
else
return compute_scale (monitor, monitor_mode);
}
static void
meta_monitor_manager_kms_dispose (GObject *object)
{
@ -1938,4 +1943,5 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
manager_class->get_crtc_gamma = meta_monitor_manager_kms_get_crtc_gamma;
manager_class->set_crtc_gamma = meta_monitor_manager_kms_set_crtc_gamma;
manager_class->is_transform_handled = meta_monitor_manager_kms_is_transform_handled;
manager_class->calculate_monitor_mode_scale = meta_monitor_manager_kms_calculate_monitor_mode_scale;
}

View File

@ -1568,6 +1568,15 @@ meta_monitor_manager_xrandr_is_transform_handled (MetaMonitorManager *manager,
return TRUE;
}
static int
meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
/* X11 does not support anything other than scale 1. */
return 1;
}
static void
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
{
@ -1644,6 +1653,7 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
manager_class->tiled_monitor_removed = meta_monitor_manager_xrandr_tiled_monitor_removed;
#endif
manager_class->is_transform_handled = meta_monitor_manager_xrandr_is_transform_handled;
manager_class->calculate_monitor_mode_scale = meta_monitor_manager_xrandr_calculate_monitor_mode_scale;
quark_meta_monitor_xrandr_data =
g_quark_from_static_string ("-meta-monitor-xrandr-data");

View File

@ -335,6 +335,20 @@ meta_monitor_manager_test_is_transform_handled (MetaMonitorManager *manager,
return TRUE;
}
static int
meta_monitor_manager_test_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
MetaOutput *output;
MetaOutputTest *output_test;
output = meta_monitor_get_main_output (monitor);
output_test = output->driver_private;
return output_test->scale;
}
static void
meta_monitor_manager_test_dispose (GObject *object)
{
@ -367,4 +381,5 @@ meta_monitor_manager_test_class_init (MetaMonitorManagerTestClass *klass)
manager_class->tiled_monitor_added = meta_monitor_manager_test_tiled_monitor_added;
manager_class->tiled_monitor_removed = meta_monitor_manager_test_tiled_monitor_removed;
manager_class->is_transform_handled = meta_monitor_manager_test_is_transform_handled;
manager_class->calculate_monitor_mode_scale = meta_monitor_manager_test_calculate_monitor_mode_scale;
}

View File

@ -32,6 +32,11 @@ typedef struct _MetaMonitorTestSetup
int n_crtcs;
} MetaMonitorTestSetup;
typedef struct _MetaOutputTest
{
int scale;
} MetaOutputTest;
#define META_TYPE_MONITOR_MANAGER_TEST (meta_monitor_manager_test_get_type ())
G_DECLARE_FINAL_TYPE (MetaMonitorManagerTest, meta_monitor_manager_test,
META, MONITOR_MANAGER_TEST, MetaMonitorManager)

View File

@ -658,6 +658,12 @@ check_monitor_configuration (MonitorTestCase *test_case)
}
}
static void
meta_output_test_destroy_notify (MetaOutput *output)
{
g_clear_pointer (&output->driver_private, g_free);
}
static MetaMonitorTestSetup *
create_monitor_test_setup (MonitorTestCase *test_case,
MonitorTestFlag flags)
@ -712,6 +718,7 @@ create_monitor_test_setup (MonitorTestCase *test_case,
test_setup->outputs = g_new0 (MetaOutput, test_setup->n_outputs);
for (i = 0; i < test_setup->n_outputs; i++)
{
MetaOutputTest *output_test;
int crtc_index;
MetaCrtc *crtc;
int preferred_mode_index;
@ -756,10 +763,16 @@ create_monitor_test_setup (MonitorTestCase *test_case,
possible_crtcs[j] = &test_setup->crtcs[possible_crtc_index];
}
output_test = g_new0 (MetaOutputTest, 1);
scale = test_case->setup.outputs[i].scale;
if (scale < 1)
scale = 1;
*output_test = (MetaOutputTest) {
.scale = scale
};
is_laptop_panel = test_case->setup.outputs[i].is_laptop_panel;
test_setup->outputs[i] = (MetaOutput) {
@ -789,8 +802,9 @@ create_monitor_test_setup (MonitorTestCase *test_case,
.connector_type = (is_laptop_panel ? META_CONNECTOR_TYPE_eDP
: META_CONNECTOR_TYPE_DisplayPort),
.tile_info = test_case->setup.outputs[i].tile_info,
.scale = scale,
.is_underscanning = test_case->setup.outputs[i].is_underscanning
.is_underscanning = test_case->setup.outputs[i].is_underscanning,
.driver_private = output_test,
.driver_notify = (GDestroyNotify) meta_output_test_destroy_notify
};
}