diff options
author | Jonas Ådahl <jadahl@gmail.com> | 2017-03-06 13:09:56 +0800 |
---|---|---|
committer | Jonas Ådahl <jadahl@gmail.com> | 2017-03-09 10:17:30 +0800 |
commit | df068a3649d346cabaa2b9232010791263a4382e (patch) | |
tree | d39ce466bb8d2acf2f6d23c950196b01a458c72a | |
parent | 7967ceee98f7c741a099fc1617c57003bef87aac (diff) | |
download | mutter-df068a3649d346cabaa2b9232010791263a4382e.tar.gz |
monitor-tiled: Generate non-tiled monitor modes
Add support for non-tiled monitor modes on tiled monitors. This is done
by adding all the other supported modes, except the modes with the
same resolution as the tile dimensions.
https://bugzilla.gnome.org/show_bug.cgi?id=779745
-rw-r--r-- | src/backends/meta-logical-monitor.c | 3 | ||||
-rw-r--r-- | src/backends/meta-monitor.c | 149 |
2 files changed, 119 insertions, 33 deletions
diff --git a/src/backends/meta-logical-monitor.c b/src/backends/meta-logical-monitor.c index a3c5accfa..52de55b20 100644 --- a/src/backends/meta-logical-monitor.c +++ b/src/backends/meta-logical-monitor.c @@ -59,7 +59,8 @@ meta_logical_monitor_new (MetaMonitor *monitor, { MetaOutput *output = l->data; - output->crtc->logical_monitor = logical_monitor; + if (output->crtc) + output->crtc->logical_monitor = logical_monitor; is_presentation = is_presentation && output->is_presentation; } diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c index b5ad94785..ada102a1a 100644 --- a/src/backends/meta-monitor.c +++ b/src/backends/meta-monitor.c @@ -488,14 +488,37 @@ meta_monitor_tiled_calculate_tiled_size (MetaMonitor *monitor, *out_height = height; } -static void -meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled) +static gboolean +is_monitor_mode_assigned (MetaMonitor *monitor, + MetaMonitorMode *mode) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + GList *l; + int i; + + for (l = priv->outputs, i = 0; l; l = l->next, i++) + { + MetaOutput *output = l->data; + MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i]; + + if (monitor_crtc_mode->crtc_mode && + (!output->crtc || + output->crtc->current_mode != monitor_crtc_mode->crtc_mode)) + return FALSE; + else if (!monitor_crtc_mode->crtc_mode && output->crtc) + return FALSE; + } + + return TRUE; +} + +static MetaMonitorMode * +create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled) { MetaMonitor *monitor = META_MONITOR (monitor_tiled); MetaMonitorPrivate *monitor_priv = meta_monitor_get_instance_private (monitor); MetaMonitorMode *mode; - gboolean preferred_mode_is_current; GList *l; int i; @@ -503,9 +526,8 @@ meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled) meta_monitor_tiled_calculate_tiled_size (monitor, &mode->spec.width, &mode->spec.height); - mode->crtc_modes = g_new (MetaMonitorCrtcMode, - g_list_length (monitor_priv->outputs)); - preferred_mode_is_current = TRUE; + mode->crtc_modes = g_new0 (MetaMonitorCrtcMode, + g_list_length (monitor_priv->outputs)); for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++) { MetaOutput *output = l->data; @@ -527,19 +549,103 @@ meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled) preferred_crtc_mode->refresh_rate)); mode->spec.refresh_rate = preferred_crtc_mode->refresh_rate; + } + + return mode; +} + +static MetaMonitorMode * +create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled, + MetaOutput *main_output, + MetaCrtcMode *crtc_mode) +{ + MetaMonitor *monitor = META_MONITOR (monitor_tiled); + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + MetaMonitorMode *mode; + GList *l; + int i; + + /* + * Assume modes with a resolution identical to the tile sizes are tiled + * modes. + */ + if (crtc_mode->width == (int) main_output->tile_info.tile_w && + crtc_mode->height == (int) main_output->tile_info.tile_h) + return NULL; + + mode = g_new0 (MetaMonitorMode, 1); + + mode->spec = (MetaMonitorModeSpec) { + .width = crtc_mode->width, + .height = crtc_mode->height, + .refresh_rate = crtc_mode->refresh_rate + }; + mode->crtc_modes = g_new0 (MetaMonitorCrtcMode, + g_list_length (monitor_priv->outputs)); + + for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++) + { + MetaOutput *output = l->data; - if (!output->crtc || - mode->crtc_modes[i].crtc_mode != output->crtc->current_mode) - preferred_mode_is_current = FALSE; + if (output == main_output) + { + mode->crtc_modes[i] = (MetaMonitorCrtcMode) { + .x = 0, + .y = 0, + .output = output, + .crtc_mode = crtc_mode + }; + } + else + { + mode->crtc_modes[i] = (MetaMonitorCrtcMode) { + .output = output, + .crtc_mode = NULL + }; + } } + return mode; +} + +static void +meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled) +{ + MetaMonitor *monitor = META_MONITOR (monitor_tiled); + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + MetaMonitorMode *mode; + MetaOutput *main_output; + unsigned int i; + + mode = create_tiled_monitor_mode (monitor_tiled); monitor_priv->modes = g_list_append (monitor_priv->modes, mode); + monitor_priv->preferred_mode = mode; - if (preferred_mode_is_current) + if (is_monitor_mode_assigned (monitor, mode)) monitor_priv->current_mode = mode; - /* TODO: Add single tile modes */ + main_output = meta_monitor_get_main_output (monitor); + for (i = 0; i < main_output->n_modes; i++) + { + MetaCrtcMode *crtc_mode = main_output->modes[i]; + + mode = create_untiled_monitor_mode (monitor_tiled, + main_output, + crtc_mode); + if (mode) + { + monitor_priv->modes = g_list_append (monitor_priv->modes, mode); + + if (is_monitor_mode_assigned (monitor, mode)) + { + g_assert (!monitor_priv->current_mode); + monitor_priv->current_mode = mode; + } + } + } } MetaMonitorTiled * @@ -685,27 +791,6 @@ meta_monitor_get_current_mode (MetaMonitor *monitor) return priv->current_mode; } -static gboolean -is_monitor_mode_assigned (MetaMonitor *monitor, - MetaMonitorMode *mode) -{ - MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); - GList *l; - int i; - - for (l = priv->outputs, i = 0; l; l = l->next, i++) - { - MetaOutput *output = l->data; - MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i]; - - if (!output->crtc || - output->crtc->current_mode != monitor_crtc_mode->crtc_mode) - return FALSE; - } - - return TRUE; -} - void meta_monitor_derive_current_mode (MetaMonitor *monitor) { |