monitor-manager: Refactor tiled monitor assembly code

Refactor the tiled monitor assembly code (that constructs a logical
monitor out of tiling information. Part of the reason is to move away
from array based storage, part is to make the code easier to follow,
and part is to separate logical monitor construction from list
manipulation.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit is contained in:
Jonas Ådahl 2016-12-02 15:48:53 +08:00
parent 016359ede2
commit 20b8743f21

View File

@ -71,98 +71,91 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
{ {
} }
/* static gboolean
* rules for constructing a tiled monitor is_main_tiled_monitor_output (MetaOutput *output)
* 1. find a tile_group_id
* 2. iterate over all outputs for that tile group id
* 3. see if output has a crtc and if it is configured for the tile size
* 4. calculate the total tile size
* 5. set tile finished size
* 6. check for more tile_group_id
*/
static void
construct_tile_monitor (MetaMonitorManager *manager,
GArray *logical_monitors,
uint32_t tile_group_id)
{ {
MetaLogicalMonitor new_logical_monitor; return output->tile_info.loc_h_tile == 0 && output->tile_info.loc_v_tile == 0;
unsigned i;
for (i = 0; i < logical_monitors->len; i++)
{
MetaLogicalMonitor *logical_monitor = &g_array_index (logical_monitors,
MetaLogicalMonitor,
i);
if (logical_monitor->tile_group_id == tile_group_id)
return;
} }
/* didn't find it */ static void
new_logical_monitor.number = logical_monitors->len; calculate_tiled_monitor_size (MetaMonitorManager *manager,
new_logical_monitor.tile_group_id = tile_group_id; uint32_t tile_group_id,
new_logical_monitor.is_presentation = FALSE; int *out_width,
new_logical_monitor.refresh_rate = 0.0; int *out_height)
new_logical_monitor.width_mm = 0; {
new_logical_monitor.height_mm = 0; int width, height;
new_logical_monitor.is_primary = FALSE; unsigned int i;
new_logical_monitor.rect.x = INT_MAX;
new_logical_monitor.rect.y = INT_MAX; width = 0;
new_logical_monitor.rect.width = 0; height = 0;
new_logical_monitor.rect.height = 0; for (i = 0; i < manager->n_outputs; i++)
new_logical_monitor.winsys_id = 0; {
new_logical_monitor.n_outputs = 0; MetaOutput *output = &manager->outputs[i];
new_logical_monitor.monitor_winsys_xid = 0;
if (output->tile_info.group_id != tile_group_id)
continue;
if (output->tile_info.loc_v_tile == 0)
width += output->tile_info.tile_w;
if (output->tile_info.loc_h_tile == 0)
height += output->tile_info.tile_h;
}
*out_width = width;
*out_height = height;
}
static void
add_tiled_monitor_outputs (MetaMonitorManager *manager,
MetaLogicalMonitor *logical_monitor,
uint32_t tile_group_id)
{
unsigned int i;
for (i = 0; i < manager->n_outputs; i++) for (i = 0; i < manager->n_outputs; i++)
{ {
MetaOutput *output = &manager->outputs[i]; MetaOutput *output = &manager->outputs[i];
if (!output->tile_info.group_id)
continue;
if (output->tile_info.group_id != tile_group_id) if (output->tile_info.group_id != tile_group_id)
continue; continue;
if (!output->crtc) if (logical_monitor->n_outputs > META_MAX_OUTPUTS_PER_MONITOR)
continue;
if (output->crtc->rect.width != (int)output->tile_info.tile_w ||
output->crtc->rect.height != (int)output->tile_info.tile_h)
continue;
if (output->tile_info.loc_h_tile == 0 && output->tile_info.loc_v_tile == 0)
{ {
new_logical_monitor.refresh_rate = output->crtc->current_mode->refresh_rate; g_warning ("Couldn't add all outputs to monitor");
new_logical_monitor.width_mm = output->width_mm;
new_logical_monitor.height_mm = output->height_mm;
new_logical_monitor.winsys_id = output->winsys_id;
}
/* hack */
if (output->crtc->rect.x < new_logical_monitor.rect.x)
new_logical_monitor.rect.x = output->crtc->rect.x;
if (output->crtc->rect.y < new_logical_monitor.rect.y)
new_logical_monitor.rect.y = output->crtc->rect.y;
if (output->tile_info.loc_h_tile == 0)
new_logical_monitor.rect.height += output->tile_info.tile_h;
if (output->tile_info.loc_v_tile == 0)
new_logical_monitor.rect.width += output->tile_info.tile_w;
if (new_logical_monitor.n_outputs > META_MAX_OUTPUTS_PER_MONITOR)
continue;
new_logical_monitor.outputs[new_logical_monitor.n_outputs++] = output;
}
/* if we don't have a winsys id, i.e. we haven't found tile 0,0
don't try and add this to the monitor infos */
if (!new_logical_monitor.winsys_id)
return; return;
}
g_array_append_val (logical_monitors, new_logical_monitor); logical_monitor->outputs[logical_monitor->n_outputs] = output;
logical_monitor->n_outputs++;
}
}
static MetaLogicalMonitor *
construct_tile_monitor (MetaMonitorManager *manager,
MetaOutput *output,
int monitor_number)
{
MetaLogicalMonitor *logical_monitor = NULL;
logical_monitor = g_new0 (MetaLogicalMonitor, 1);
logical_monitor->tile_group_id = output->tile_info.group_id;
logical_monitor->refresh_rate = output->crtc->current_mode->refresh_rate;
logical_monitor->width_mm = output->width_mm;
logical_monitor->height_mm = output->height_mm;
logical_monitor->winsys_id = output->winsys_id;
logical_monitor->rect.x = output->crtc->rect.x;
logical_monitor->rect.y = output->crtc->rect.y;
calculate_tiled_monitor_size (manager, output->tile_info.group_id,
&logical_monitor->rect.width,
&logical_monitor->rect.height);
add_tiled_monitor_outputs (manager, logical_monitor,
output->tile_info.group_id);
return logical_monitor;
} }
/* /*
@ -191,9 +184,22 @@ make_logical_config (MetaMonitorManager *manager)
{ {
MetaOutput *output = &manager->outputs[i]; MetaOutput *output = &manager->outputs[i];
if (output->tile_info.group_id) if (!output->crtc)
construct_tile_monitor (manager, logical_monitors, continue;
output->tile_info.group_id);
if (!output->tile_info.group_id)
continue;
if (is_main_tiled_monitor_output (output))
{
MetaLogicalMonitor *logical_monitor;
logical_monitor = construct_tile_monitor (manager,
output,
logical_monitors->len);
g_array_append_val (logical_monitors, logical_monitor);
}
} }
for (i = 0; i < manager->n_crtcs; i++) for (i = 0; i < manager->n_crtcs; i++)