From 6262b46928d8b1e9c58f3c82e7216bf5a3e0af4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 22 Dec 2016 15:16:48 +0800 Subject: [PATCH] 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 ed1f6617d..1c5e60aed 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 9c6211e86..f4a583da3 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 5489b7bc4..dd0e86c4e 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);