backends/native: Calculate the output scale in here

It makes more sense as a backend thing, not a frontend thing.
This commit is contained in:
Jasper St. Pierre 2015-02-22 11:21:37 -08:00
parent 23c00688b4
commit 78d8525699
2 changed files with 69 additions and 65 deletions

View File

@ -72,6 +72,8 @@ struct _MetaMonitorManagerKms
drmModeEncoder *current_encoder;
GUdevClient *udev;
GSettings *desktop_settings;
};
struct _MetaMonitorManagerKmsClass
@ -269,6 +271,68 @@ 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;
/* Scaling makes no sense */
if (output->crtc->rect.width < HIDPI_MIN_HEIGHT)
goto out;
/* 4K TV */
if (output->name != NULL && strstr(output->name, "HDMI") != NULL &&
output->crtc->rect.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)output->crtc->rect.width / (output->width_mm / 25.4);
dpi_y = (double)output->crtc->rect.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 void
meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
{
@ -518,6 +582,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
/* MetaConnectorType matches DRM's connector types */
meta_output->connector_type = (MetaConnectorType) connector->connector_type;
meta_output->scale = get_output_scale (manager, meta_output);
/* FIXME: backlight is a very driver specific thing unfortunately,
every DDX does its own thing, and the dumb KMS API does not include it.
@ -919,6 +985,8 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
manager_kms->udev = g_udev_client_new (subsystems);
g_signal_connect (manager_kms->udev, "uevent",
G_CALLBACK (on_uevent), manager_kms);
manager_kms->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
}
static void
@ -927,6 +995,7 @@ meta_monitor_manager_kms_dispose (GObject *object)
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
g_clear_object (&manager_kms->udev);
g_clear_object (&manager_kms->desktop_settings);
G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object);
}

View File

@ -40,17 +40,6 @@ typedef struct {
GList *resources;
} MetaWaylandOutput;
/* 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 void
output_resource_destroy (struct wl_resource *res)
{
@ -60,57 +49,6 @@ output_resource_destroy (struct wl_resource *res)
wayland_output->resources = g_list_remove (wayland_output->resources, res);
}
/* Based on code from gnome-settings-daemon */
static int
compute_scale (MetaOutput *output)
{
int scale = 1;
/* Scaling makes no sense */
if (output->crtc->rect.width < HIDPI_MIN_HEIGHT)
goto out;
/* 4K TV */
if (output->name != NULL && strstr(output->name, "HDMI") != NULL &&
output->crtc->rect.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)output->crtc->rect.width / (output->width_mm / 25.4);
dpi_y = (double)output->crtc->rect.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 GSettings *desktop_settings;
static int
get_output_scale (MetaOutput *output)
{
int scale = g_settings_get_uint (desktop_settings, "scaling-factor");
if (scale > 0)
return scale;
else
return compute_scale (output);
}
static void
bind_output (struct wl_client *client,
void *data,
@ -158,7 +96,6 @@ bind_output (struct wl_client *client,
(int)output->crtc->current_mode->height,
(int)output->crtc->current_mode->refresh_rate);
output->scale = get_output_scale (output);
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
wl_output_send_scale (resource, output->scale);
@ -295,8 +232,6 @@ meta_wayland_outputs_init (MetaWaylandCompositor *compositor)
{
MetaMonitorManager *monitors;
desktop_settings = g_settings_new ("org.gnome.desktop.interface");
monitors = meta_monitor_manager_get ();
g_signal_connect (monitors, "monitors-changed",
G_CALLBACK (on_monitors_changed), compositor);