monitor-config-manager: Support logical monitor transforms

Add support for rotated monitors. This is done per logical monitor, as
every monitor assigned to a logical monitor must be transformed in the
same way. This includes being transformed on the same level; e.g. if
the backend does not support transforming any monitor of a logical
monitor natively, then all monitors will be transformed using the
offscreen intermediate framebuffer.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit is contained in:
Jonas Ådahl 2017-03-21 14:17:18 +08:00
parent 7c226462e0
commit 472a434212
7 changed files with 78 additions and 15 deletions

View File

@ -79,6 +79,7 @@ meta_logical_monitor_new (MetaMonitorManager *monitor_manager,
logical_monitor->number = monitor_number;
logical_monitor->winsys_id = main_output->winsys_id;
logical_monitor->scale = logical_monitor_config->scale;
logical_monitor->transform = logical_monitor_config->transform;
logical_monitor->in_fullscreen = -1;
logical_monitor->rect = logical_monitor_config->layout;

View File

@ -101,6 +101,7 @@ find_unassigned_crtc (MetaOutput *output,
typedef struct
{
MetaMonitorManager *monitor_manager;
MetaLogicalMonitorConfig *logical_monitor_config;
MetaMonitorConfig *monitor_config;
GPtrArray *crtc_infos;
@ -117,6 +118,8 @@ assign_monitor_crtc (MetaMonitor *monitor,
MonitorAssignmentData *data = user_data;
MetaOutput *output;
MetaCrtc *crtc;
MetaMonitorTransform transform;
MetaMonitorTransform crtc_transform;
int crtc_x, crtc_y;
MetaCrtcInfo *crtc_info;
MetaOutputInfo *output_info;
@ -137,7 +140,15 @@ assign_monitor_crtc (MetaMonitor *monitor,
return FALSE;
}
meta_monitor_calculate_crtc_pos (monitor, mode, output,
transform = data->logical_monitor_config->transform;
if (meta_monitor_manager_is_transform_handled (data->monitor_manager,
crtc,
transform))
crtc_transform = transform;
else
crtc_transform = META_MONITOR_TRANSFORM_NORMAL;
meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform,
&crtc_x, &crtc_y);
crtc_info = g_slice_new0 (MetaCrtcInfo);
@ -146,7 +157,7 @@ assign_monitor_crtc (MetaMonitor *monitor,
.mode = monitor_crtc_mode->crtc_mode,
.x = crtc_x,
.y = crtc_y,
.transform = META_MONITOR_TRANSFORM_NORMAL,
.transform = crtc_transform,
.outputs = g_ptr_array_new ()
};
g_ptr_array_add (crtc_info->outputs, output);
@ -229,6 +240,7 @@ assign_monitor_crtcs (MetaMonitorManager *manager,
}
data = (MonitorAssignmentData) {
.monitor_manager = manager,
.logical_monitor_config = logical_monitor_config,
.monitor_config = monitor_config,
.crtc_infos = crtc_infos,
@ -925,17 +937,24 @@ meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor
return FALSE;
}
if (meta_monitor_transform_is_rotated (logical_monitor_config->transform))
{
expected_mode_width = logical_monitor_config->layout.height;
expected_mode_height = logical_monitor_config->layout.width;
}
else
{
expected_mode_width = logical_monitor_config->layout.width;
expected_mode_height = logical_monitor_config->layout.height;
}
switch (layout_mode)
{
case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
expected_mode_width = (logical_monitor_config->layout.width *
logical_monitor_config->scale);
expected_mode_height = (logical_monitor_config->layout.height *
logical_monitor_config->scale);
expected_mode_width *= logical_monitor_config->scale;
expected_mode_height *= logical_monitor_config->scale;
break;
case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
expected_mode_width = logical_monitor_config->layout.width;
expected_mode_height = logical_monitor_config->layout.height;
break;
}

View File

@ -40,6 +40,7 @@ typedef struct _MetaLogicalMonitorConfig
{
MetaRectangle layout;
GList *monitor_configs;
MetaMonitorTransform transform;
int scale;
gboolean is_primary;
gboolean is_presentation;

View File

@ -1736,6 +1736,7 @@ create_logical_monitor_config_from_variant (MetaMonitorManager *manager
.width = width,
.height = height
},
.transform = META_MONITOR_TRANSFORM_NORMAL,
.scale = (int) scale,
.is_primary = is_primary,
.monitor_configs = monitor_configs

View File

@ -412,6 +412,7 @@ static void
meta_monitor_normal_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
@ -482,6 +483,7 @@ add_tiled_monitor_outputs (MetaMonitorManager *monitor_manager,
static void
calculate_tile_coordinate (MetaMonitor *monitor,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
@ -495,12 +497,45 @@ calculate_tile_coordinate (MetaMonitor *monitor,
{
MetaOutput *other_output = l->data;
switch (crtc_transform)
{
case META_MONITOR_TRANSFORM_NORMAL:
case META_MONITOR_TRANSFORM_FLIPPED:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
x += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
y += other_output->tile_info.tile_h;
break;
case META_MONITOR_TRANSFORM_180:
case META_MONITOR_TRANSFORM_FLIPPED_180:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
x += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
y += other_output->tile_info.tile_h;
break;
case META_MONITOR_TRANSFORM_270:
case META_MONITOR_TRANSFORM_FLIPPED_270:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
y += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
x += other_output->tile_info.tile_h;
break;
case META_MONITOR_TRANSFORM_90:
case META_MONITOR_TRANSFORM_FLIPPED_90:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
y += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
x += other_output->tile_info.tile_h;
break;
}
}
*out_x = x;
@ -759,6 +794,7 @@ static void
meta_monitor_tiled_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
@ -766,7 +802,7 @@ meta_monitor_tiled_calculate_crtc_pos (MetaMonitor *monitor,
if (mode_tiled->is_tiled)
{
calculate_tile_coordinate (monitor, output,
calculate_tile_coordinate (monitor, output, crtc_transform,
out_x, out_y);
}
else
@ -919,12 +955,14 @@ void
meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y)
{
META_MONITOR_GET_CLASS (monitor)->calculate_crtc_pos (monitor,
monitor_mode,
output,
crtc_transform,
out_x,
out_y);
}

View File

@ -67,6 +67,7 @@ struct _MetaMonitorClass
void (* calculate_crtc_pos) (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y);
};
@ -149,6 +150,7 @@ GList * meta_monitor_get_modes (MetaMonitor *monitor);
void meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaOutput *output,
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y);

View File

@ -249,6 +249,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
meta_monitor_calculate_crtc_pos (monitor, monitor_mode,
monitor_crtc_mode->output,
META_MONITOR_TRANSFORM_NORMAL,
&crtc_x, &crtc_y);
scaled_crtc_rect = (MetaRectangle) {