Commit 11a790a5 authored by Marco Trevisan's avatar Marco Trevisan 🎺

x11: Add support to use Randr output fractional scaling

Added an experimental feature under the "x11-randr-fractional-scaling" setting,
to enable fractional scaling under X11 using randr output transformations.

In this first basic implementation, we just scale everything up using pure
transformation, and so everything will be blurry.
parent 74c01f09
......@@ -120,6 +120,11 @@
framebuffers instead of window content,
to manage HiDPI monitors. Does not
require a restart.
• “x11-randr-fractional-scaling” — enable fractional scaling under X11
using xrandr scaling. It might reduce
performances.
Does not require a restart.
</description>
</key>
......
......@@ -762,6 +762,8 @@ experimental_features_changed (MetaSettings *settings,
{
gboolean was_stage_views_scaled;
gboolean is_stage_views_scaled;
gboolean was_x11_scaling;
gboolean x11_scaling;
gboolean should_reconfigure = FALSE;
was_stage_views_scaled =
......@@ -771,8 +773,16 @@ experimental_features_changed (MetaSettings *settings,
meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
was_x11_scaling =
!!(old_experimental_features &
META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING);
x11_scaling =
meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING);
if (is_stage_views_scaled != was_stage_views_scaled)
if (is_stage_views_scaled != was_stage_views_scaled ||
x11_scaling != was_x11_scaling)
should_reconfigure = TRUE;
if (should_reconfigure)
......@@ -1592,6 +1602,13 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
"global-scale-required",
g_variant_new_boolean (TRUE));
}
else if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
capabilities & META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING)
{
g_variant_builder_add (&properties_builder, "{sv}",
"x11-fractional-scaling",
g_variant_new_boolean (TRUE));
}
ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings);
g_variant_builder_add (&properties_builder, "{sv}",
......
......@@ -1673,8 +1673,14 @@ meta_monitor_calculate_supported_scales (MetaMonitor *monitor,
if (constraints & META_MONITOR_SCALES_CONSTRAINT_NO_FRAC)
{
if (fmodf (scale_value, 1.0) != 0.0 ||
!is_scale_valid_for_size (width, height, scale_value))
if (fmodf (scale_value, 1.0) != 0.0)
continue;
}
if ((constraints & META_MONITOR_SCALES_CONSTRAINT_NO_FRAC) ||
(constraints & META_MONITOR_SCALES_CONSTRAINT_NO_LOGICAL))
{
if (!is_scale_valid_for_size (width, height, scale_value))
continue;
scale = scale_value;
......
......@@ -62,6 +62,7 @@ typedef enum _MetaMonitorScalesConstraint
{
META_MONITOR_SCALES_CONSTRAINT_NONE = 0,
META_MONITOR_SCALES_CONSTRAINT_NO_FRAC = (1 << 0),
META_MONITOR_SCALES_CONSTRAINT_NO_LOGICAL = (1 << 1),
} MetaMonitorScalesConstraint;
#define META_TYPE_MONITOR (meta_monitor_get_type ())
......
......@@ -33,6 +33,7 @@ typedef enum _MetaExperimentalFeature
META_EXPERIMENTAL_FEATURE_NONE = 0,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 1),
META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING = (1 << 2),
} MetaExperimentalFeature;
#define META_TYPE_SETTINGS (meta_settings_get_type ())
......
......@@ -92,7 +92,9 @@ update_ui_scaling_factor (MetaSettings *settings)
{
int ui_scaling_factor;
if (meta_is_stage_views_scaled ())
if (meta_is_stage_views_scaled () ||
meta_settings_is_experimental_feature_enabled (settings,
META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING))
ui_scaling_factor = 1;
else
ui_scaling_factor = calculate_ui_scaling_factor (settings);
......@@ -264,6 +266,8 @@ experimental_features_handler (GVariant *features_variant,
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
else if (g_str_equal (feature, "kms-modifiers"))
features |= META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS;
else if (g_str_equal (feature, "x11-randr-fractional-scaling"))
features |= META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING;
else
g_info ("Unknown experimental feature '%s'\n", feature);
}
......
......@@ -250,9 +250,10 @@ xrandr_set_crtc_config (MetaMonitorManagerXrandr *manager_xrandr,
}
static gboolean
is_crtc_assignment_changed (MetaCrtc *crtc,
MetaCrtcInfo **crtc_infos,
unsigned int n_crtc_infos)
is_crtc_assignment_changed (MetaMonitorManager *monitor_manager,
MetaCrtc *crtc,
MetaCrtcInfo **crtc_infos,
unsigned int n_crtc_infos)
{
unsigned int i;
......@@ -276,6 +277,13 @@ is_crtc_assignment_changed (MetaCrtc *crtc,
if (crtc->transform != crtc_info->transform)
return TRUE;
if ((meta_monitor_manager_get_capabilities (monitor_manager) &
META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING))
{
if (crtc->scale != crtc_info->scale)
return TRUE;
}
for (j = 0; j < crtc_info->outputs->len; j++)
{
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[j];
......@@ -361,7 +369,7 @@ is_assignments_changed (MetaMonitorManager *manager,
{
MetaCrtc *crtc = l->data;
if (is_crtc_assignment_changed (crtc, crtc_infos, n_crtc_infos))
if (is_crtc_assignment_changed (manager, crtc, crtc_infos, n_crtc_infos))
return TRUE;
}
......@@ -447,12 +455,14 @@ apply_crtc_assignments (MetaMonitorManager *manager,
0, 0, XCB_NONE,
XCB_RANDR_ROTATION_ROTATE_0,
NULL, 0);
meta_crtc_xrandr_set_scale (crtc, (xcb_randr_crtc_t) crtc->crtc_id, 1);
crtc->rect.x = 0;
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
crtc->scale = 1.0f;
}
}
......@@ -477,12 +487,14 @@ apply_crtc_assignments (MetaMonitorManager *manager,
0, 0, XCB_NONE,
XCB_RANDR_ROTATION_ROTATE_0,
NULL, 0);
meta_crtc_xrandr_set_scale (crtc, (xcb_randr_crtc_t) crtc->crtc_id, 1.0f);
crtc->rect.x = 0;
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
crtc->scale = 1.0f;
}
meta_monitor_manager_xrandr_update_screen_size (manager_xrandr, width, height,
......@@ -499,8 +511,10 @@ apply_crtc_assignments (MetaMonitorManager *manager,
g_autofree xcb_randr_output_t *output_ids = NULL;
unsigned int j, n_output_ids;
xcb_randr_rotation_t rotation;
float scale;
mode = crtc_info->mode;
scale = crtc_info->scale;
n_output_ids = crtc_info->outputs->len;
output_ids = g_new (xcb_randr_output_t, n_output_ids);
......@@ -517,6 +531,11 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output_ids[j] = output->winsys_id;
}
if (!meta_crtc_xrandr_set_scale (crtc,
(xcb_randr_crtc_t) crtc->crtc_id,
scale))
scale = 1.0f;
rotation = meta_monitor_transform_to_xrandr (crtc_info->transform);
if (!xrandr_set_crtc_config (manager_xrandr,
crtc,
......@@ -552,6 +571,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
crtc->rect.height = height;
crtc->current_mode = mode;
crtc->transform = crtc_info->transform;
crtc->scale = scale;
}
}
......@@ -886,16 +906,26 @@ meta_monitor_manager_xrandr_is_transform_handled (MetaMonitorManager *manager,
return TRUE;
}
static MetaMonitorScalesConstraint
get_scale_constraints (MetaMonitorManager *manager)
{
MetaMonitorScalesConstraint constraints = META_MONITOR_SCALES_CONSTRAINT_NO_LOGICAL;
if ((meta_monitor_manager_get_capabilities (manager) &
META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED))
constraints |= META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
return constraints;
}
static float
meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
MetaMonitorScalesConstraint constraints;
constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
return meta_monitor_calculate_mode_scale (monitor, monitor_mode, constraints);
return meta_monitor_calculate_mode_scale (monitor, monitor_mode,
get_scale_constraints (manager));
}
static float *
......@@ -905,11 +935,8 @@ meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
{
MetaMonitorScalesConstraint constraints;
constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
return meta_monitor_calculate_supported_scales (monitor, monitor_mode,
constraints,
get_scale_constraints (manager),
n_supported_scales);
}
......@@ -918,15 +945,23 @@ meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager)
{
MetaMonitorManagerCapability capabilities;
MetaMonitorManagerXrandr *xrandr_manager = META_MONITOR_MANAGER_XRANDR (manager);
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
MetaSettings *settings = meta_backend_get_settings (backend);
capabilities = META_MONITOR_MANAGER_CAPABILITY_MIRRORING |
META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED;
capabilities = META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
if (xrandr_manager->randr_version >= RANDR_TILING_MIN_VERSION)
capabilities |= META_MONITOR_MANAGER_CAPABILITY_TILING;
if (xrandr_manager->randr_version >= RANDR_TRANSFOMR_MIN_VERSION)
capabilities |= META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING;
if (meta_settings_is_experimental_feature_enabled (settings,
META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING) &&
xrandr_manager->randr_version >= RANDR_TRANSFOMR_MIN_VERSION)
{
capabilities |= META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING |
META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;
}
else
capabilities |= META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED;
return capabilities;
}
......@@ -948,6 +983,10 @@ meta_monitor_manager_xrandr_get_max_screen_size (MetaMonitorManager *manager,
static MetaLogicalMonitorLayoutMode
meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager)
{
if (meta_monitor_manager_get_capabilities (manager) &
META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING)
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment