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; drmModeEncoder *current_encoder;
GUdevClient *udev; GUdevClient *udev;
GSettings *desktop_settings;
}; };
struct _MetaMonitorManagerKmsClass struct _MetaMonitorManagerKmsClass
@ -269,6 +271,68 @@ find_output_by_id (MetaOutput *outputs,
return NULL; 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 static void
meta_monitor_manager_kms_read_current (MetaMonitorManager *manager) 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 */ /* MetaConnectorType matches DRM's connector types */
meta_output->connector_type = (MetaConnectorType) connector->connector_type; 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, /* FIXME: backlight is a very driver specific thing unfortunately,
every DDX does its own thing, and the dumb KMS API does not include it. 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); manager_kms->udev = g_udev_client_new (subsystems);
g_signal_connect (manager_kms->udev, "uevent", g_signal_connect (manager_kms->udev, "uevent",
G_CALLBACK (on_uevent), manager_kms); G_CALLBACK (on_uevent), manager_kms);
manager_kms->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
} }
static void static void
@ -927,6 +995,7 @@ meta_monitor_manager_kms_dispose (GObject *object)
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object); MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
g_clear_object (&manager_kms->udev); g_clear_object (&manager_kms->udev);
g_clear_object (&manager_kms->desktop_settings);
G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object); G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object);
} }

View File

@ -40,17 +40,6 @@ typedef struct {
GList *resources; GList *resources;
} MetaWaylandOutput; } 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 static void
output_resource_destroy (struct wl_resource *res) 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); 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 static void
bind_output (struct wl_client *client, bind_output (struct wl_client *client,
void *data, void *data,
@ -158,7 +96,6 @@ bind_output (struct wl_client *client,
(int)output->crtc->current_mode->height, (int)output->crtc->current_mode->height,
(int)output->crtc->current_mode->refresh_rate); (int)output->crtc->current_mode->refresh_rate);
output->scale = get_output_scale (output);
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
wl_output_send_scale (resource, output->scale); wl_output_send_scale (resource, output->scale);
@ -295,8 +232,6 @@ meta_wayland_outputs_init (MetaWaylandCompositor *compositor)
{ {
MetaMonitorManager *monitors; MetaMonitorManager *monitors;
desktop_settings = g_settings_new ("org.gnome.desktop.interface");
monitors = meta_monitor_manager_get (); monitors = meta_monitor_manager_get ();
g_signal_connect (monitors, "monitors-changed", g_signal_connect (monitors, "monitors-changed",
G_CALLBACK (on_monitors_changed), compositor); G_CALLBACK (on_monitors_changed), compositor);