[mutter] wayland/output: Pass 'unknown' subpixel order when mismatch



commit 6262b46928d8b1e9c58f3c82e7216bf5a3e0af4c
Author: Jonas Ådahl <jadahl gmail com>
Date:   Thu Dec 22 15:16:48 2016 +0800

    wayland/output: Pass 'unknown' subpixel order when mismatch
    
    When a logical monitor constains monitors with different subpixel
    ordering, make the wl_output have the subpixel order 'unknown' so that
    clients don't make assumptions given only a subset of the monitors of
    the given region.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777732

 src/backends/meta-monitor.c        |   14 ++++++++-
 src/backends/meta-monitor.h        |    2 +
 src/wayland/meta-wayland-outputs.c |   54 +++++++++++++++++++++++++++++++++++-
 3 files changed, 68 insertions(+), 2 deletions(-)
---
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index ed1f661..1c5e60a 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -202,6 +202,15 @@ meta_monitor_get_physical_dimensions (MetaMonitor *monitor,
   *height_mm = output->height_mm;
 }
 
+CoglSubpixelOrder
+meta_monitor_get_subpixel_order (MetaMonitor *monitor)
+{
+  MetaOutput *output;
+
+  output = meta_monitor_get_main_output (monitor);
+  return output->subpixel_order;
+}
+
 const char *
 meta_monitor_get_product (MetaMonitor *monitor)
 {
@@ -347,6 +356,9 @@ add_tiled_monitor_outputs (MetaMonitorManager *monitor_manager,
       if (output->tile_info.group_id != monitor_tiled->tile_group_id)
         continue;
 
+      g_warn_if_fail (output->subpixel_order ==
+                      monitor_tiled->main_output->subpixel_order);
+
       monitor_priv->outputs = g_list_append (monitor_priv->outputs, output);
     }
 }
@@ -467,8 +479,8 @@ meta_monitor_tiled_new (MetaMonitorManager *monitor_manager,
   monitor_tiled->tile_group_id = output->tile_info.group_id;
   monitor_priv->winsys_id = output->winsys_id;
 
-  add_tiled_monitor_outputs (monitor_manager, monitor_tiled);
   monitor_tiled->main_output = output;
+  add_tiled_monitor_outputs (monitor_manager, monitor_tiled);
 
   meta_monitor_manager_tiled_monitor_added (monitor_manager,
                                             META_MONITOR (monitor_tiled));
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
index 9c6211e..f4a583d 100644
--- a/src/backends/meta-monitor.h
+++ b/src/backends/meta-monitor.h
@@ -105,6 +105,8 @@ void meta_monitor_get_physical_dimensions (MetaMonitor *monitor,
                                            int         *width_mm,
                                            int         *height_mm);
 
+CoglSubpixelOrder meta_monitor_get_subpixel_order (MetaMonitor *monitor);
+
 const char * meta_monitor_get_product (MetaMonitor *monitor);
 
 uint32_t meta_monitor_tiled_get_tile_group_id (MetaMonitorTiled *monitor_tiled);
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
index 5489b7b..dd0e86c 100644
--- a/src/wayland/meta-wayland-outputs.c
+++ b/src/wayland/meta-wayland-outputs.c
@@ -65,6 +65,54 @@ pick_main_output (MetaLogicalMonitor *logical_monitor)
   return meta_monitor_get_main_output (monitor);
 }
 
+static enum wl_output_subpixel
+cogl_subpixel_order_to_wl_output_subpixel (CoglSubpixelOrder subpixel_order)
+{
+  switch (subpixel_order)
+    {
+    case COGL_SUBPIXEL_ORDER_UNKNOWN:
+      return WL_OUTPUT_SUBPIXEL_UNKNOWN;
+    case COGL_SUBPIXEL_ORDER_NONE:
+      return WL_OUTPUT_SUBPIXEL_NONE;
+    case COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB:
+      return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
+    case COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR:
+      return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
+    case COGL_SUBPIXEL_ORDER_VERTICAL_RGB:
+      return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
+    case COGL_SUBPIXEL_ORDER_VERTICAL_BGR:
+      return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
+    }
+
+  g_assert_not_reached ();
+}
+
+static enum wl_output_subpixel
+calculate_suitable_subpixel_order (MetaLogicalMonitor *logical_monitor)
+{
+  GList *monitors;
+  GList *l;
+  MetaMonitor *first_monitor;
+  CoglSubpixelOrder subpixel_order;
+
+  monitors = meta_logical_monitor_get_monitors (logical_monitor);
+  first_monitor = monitors->data;
+  subpixel_order = meta_monitor_get_subpixel_order (first_monitor);
+
+  for (l = monitors->next; l; l = l->next)
+    {
+      MetaMonitor *monitor = l->data;
+
+      if (meta_monitor_get_subpixel_order (monitor) != subpixel_order)
+        {
+          subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
+          break;
+        }
+    }
+
+  return cogl_subpixel_order_to_wl_output_subpixel (subpixel_order);
+}
+
 static void
 send_output_events (struct wl_resource *resource,
                     MetaWaylandOutput  *wayland_output,
@@ -94,6 +142,10 @@ send_output_events (struct wl_resource *resource,
       old_logical_monitor->rect.x != logical_monitor->rect.x ||
       old_logical_monitor->rect.y != logical_monitor->rect.y)
     {
+      enum wl_output_subpixel subpixel_order;
+
+      subpixel_order = calculate_suitable_subpixel_order (logical_monitor);
+
       /*
        * TODO: When we support wl_surface.set_buffer_transform, pass along
        * the correct transform here instead of always pretending its 'normal'.
@@ -105,7 +157,7 @@ send_output_events (struct wl_resource *resource,
                                logical_monitor->rect.y,
                                output->width_mm,
                                output->height_mm,
-                               output->subpixel_order,
+                               subpixel_order,
                                output->vendor,
                                output->product,
                                WL_OUTPUT_TRANSFORM_NORMAL);


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