[mutter] monitors: construct tiled monitors info



commit ea2496c80a72b882b5b2a3f6eca2ca11d59c25ca
Author: Dave Airlie <airlied redhat com>
Date:   Tue Mar 31 11:08:34 2015 +1000

    monitors: construct tiled monitors info
    
    The monitors info structure is created from the tiled outputs
    and this is used as the central storage for info about a monitor
    as opposed to the output state.
    
    It appears at least the EDID mm w/h is for the whole monitor and
    not per tile.

 src/backends/meta-monitor-manager-private.h |   11 +++
 src/backends/meta-monitor-manager.c         |  119 ++++++++++++++++++++++++++-
 2 files changed, 127 insertions(+), 3 deletions(-)
---
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index efbca28..c5444d6 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -193,6 +193,7 @@ struct _MetaMonitorMode
   GDestroyNotify driver_notify;
 };
 
+#define META_MAX_OUTPUTS_PER_MONITOR 4
 /**
  * MetaMonitorInfo:
  *
@@ -208,6 +209,10 @@ struct _MetaMonitorInfo
   int number;
   int xinerama_index;
   MetaRectangle rect;
+  /* for tiled monitors these are calculated, from untiled just copied */
+  float refresh_rate;
+  int width_mm;
+  int height_mm;
   gboolean is_primary;
   gboolean is_presentation; /* XXX: not yet used */
   gboolean in_fullscreen;
@@ -221,6 +226,12 @@ struct _MetaMonitorInfo
      the primary one).
   */
   glong winsys_id;
+
+  guint32 tile_group_id;
+
+  int monitor_winsys_xid;
+  int n_outputs;
+  MetaOutput *outputs[META_MAX_OUTPUTS_PER_MONITOR];
 };
 
 /*
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 029c214..89efaca 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -72,6 +72,98 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
 }
 
 /*
+ * rules for constructing a tiled monitor
+ * 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 *monitor_infos,
+                        guint32 tile_group_id)
+{
+  MetaMonitorInfo info;
+  unsigned i;
+
+  for (i = 0; i < monitor_infos->len; i++)
+    {
+      MetaMonitorInfo *pinfo = &g_array_index (monitor_infos, MetaMonitorInfo, i);
+
+      if (pinfo->tile_group_id == tile_group_id)
+        return;
+    }
+
+  /* didn't find it */
+  info.number = monitor_infos->len;
+  info.tile_group_id = tile_group_id;
+  info.is_presentation = FALSE;
+  info.refresh_rate = 0.0;
+  info.width_mm = 0;
+  info.height_mm = 0;
+  info.is_primary = FALSE;
+  info.rect.x = INT_MAX;
+  info.rect.y = INT_MAX;
+  info.rect.width = 0;
+  info.rect.height = 0;
+  info.winsys_id = 0;
+  info.n_outputs = 0;
+  info.monitor_winsys_xid = 0;
+
+  for (i = 0; i < manager->n_outputs; i++)
+    {
+      MetaOutput *output = &manager->outputs[i];
+
+      if (!output->tile_info.group_id)
+        continue;
+
+      if (output->tile_info.group_id != tile_group_id)
+        continue;
+
+      if (!output->crtc)
+        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)
+        {
+          info.refresh_rate = output->crtc->current_mode->refresh_rate;
+          info.width_mm = output->width_mm;
+          info.height_mm = output->height_mm;
+          info.winsys_id = output->winsys_id;
+        }
+
+      /* hack */
+      if (output->crtc->rect.x < info.rect.x)
+        info.rect.x = output->crtc->rect.x;
+      if (output->crtc->rect.y < info.rect.y)
+        info.rect.y = output->crtc->rect.y;
+
+      if (output->tile_info.loc_h_tile == 0)
+        info.rect.height += output->tile_info.tile_h;
+
+      if (output->tile_info.loc_v_tile == 0)
+        info.rect.width += output->tile_info.tile_w;
+
+      if (info.n_outputs > META_MAX_OUTPUTS_PER_MONITOR)
+        continue;
+
+      info.outputs[info.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 (!info.winsys_id)
+    return;
+
+  g_array_append_val (monitor_infos, info);
+}
+
+/*
  * make_logical_config:
  *
  * Turn outputs and CRTCs into logical MetaMonitorInfo,
@@ -91,6 +183,15 @@ make_logical_config (MetaMonitorManager *manager)
      for each of them, unless they reference a rectangle that
      is already there.
   */
+  /* for tiling we need to work out how many tiled outputs there are */
+  for (i = 0; i < manager->n_outputs; i++)
+    {
+      MetaOutput *output = &manager->outputs[i];
+
+      if (output->tile_info.group_id)
+        construct_tile_monitor (manager, monitor_infos, output->tile_info.group_id);
+    }
+
   for (i = 0; i < manager->n_crtcs; i++)
     {
       MetaCRTC *crtc = &manager->crtcs[i];
@@ -102,8 +203,8 @@ make_logical_config (MetaMonitorManager *manager)
       for (j = 0; j < monitor_infos->len; j++)
         {
           MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, j);
-          if (meta_rectangle_equal (&crtc->rect,
-                                    &info->rect))
+          if (meta_rectangle_contains_rect (&info->rect,
+                                            &crtc->rect))
             {
               crtc->logical_monitor = info;
               break;
@@ -115,7 +216,9 @@ make_logical_config (MetaMonitorManager *manager)
           MetaMonitorInfo info;
 
           info.number = monitor_infos->len;
+          info.tile_group_id = 0;
           info.rect = crtc->rect;
+          info.refresh_rate = crtc->current_mode->refresh_rate;
           info.is_primary = FALSE;
           /* This starts true because we want
              is_presentation only if all outputs are
@@ -125,7 +228,8 @@ make_logical_config (MetaMonitorManager *manager)
           info.is_presentation = TRUE;
           info.in_fullscreen = -1;
           info.winsys_id = 0;
-
+          info.n_outputs = 0;
+          info.monitor_winsys_xid = 0;
           g_array_append_val (monitor_infos, info);
 
           crtc->logical_monitor = &g_array_index (monitor_infos, MetaMonitorInfo,
@@ -147,6 +251,9 @@ make_logical_config (MetaMonitorManager *manager)
       if (output->crtc == NULL)
         continue;
 
+      if (output->tile_info.group_id)
+        continue;
+
       /* We must have a logical monitor on every CRTC at this point */
       g_assert (output->crtc->logical_monitor != NULL);
 
@@ -155,6 +262,12 @@ make_logical_config (MetaMonitorManager *manager)
       info->is_primary = info->is_primary || output->is_primary;
       info->is_presentation = info->is_presentation && output->is_presentation;
 
+      info->width_mm = output->width_mm;
+      info->height_mm = output->height_mm;
+
+      info->outputs[0] = output;
+      info->n_outputs = 1;
+
       if (output->is_primary || info->winsys_id == 0)
         info->winsys_id = output->winsys_id;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]