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->number = monitor_number;
logical_monitor->winsys_id = main_output->winsys_id; logical_monitor->winsys_id = main_output->winsys_id;
logical_monitor->scale = logical_monitor_config->scale; logical_monitor->scale = logical_monitor_config->scale;
logical_monitor->transform = logical_monitor_config->transform;
logical_monitor->in_fullscreen = -1; logical_monitor->in_fullscreen = -1;
logical_monitor->rect = logical_monitor_config->layout; logical_monitor->rect = logical_monitor_config->layout;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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