[mutter] monitor: Add monitor modes abstraction
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] monitor: Add monitor modes abstraction
- Date: Wed, 25 Jan 2017 08:35:20 +0000 (UTC)
commit a6f464a6000d1ec23fa8b84f477327721b197993
Author: Jonas Ådahl <jadahl gmail com>
Date: Wed Dec 14 17:22:07 2016 +0800
monitor: Add monitor modes abstraction
Add "monitor modes" abstracting the modes set on a monitor. On normal
monitors, this directly maps to the CRTC modes, but on tiled monitors,
a monitor mode can consist modes per tiled output.
https://bugzilla.gnome.org/show_bug.cgi?id=777732
src/backends/meta-monitor.c | 221 ++++++++++++++++++++++++++++++++++++++-----
src/backends/meta-monitor.h | 28 ++++++
2 files changed, 226 insertions(+), 23 deletions(-)
---
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index 32c0fcf..9fad8b6 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -26,9 +26,18 @@
#include "backends/meta-backend-private.h"
#include "backends/meta-monitor-manager-private.h"
+typedef struct _MetaMonitorMode
+{
+ int width;
+ int height;
+ float refresh_rate;
+ MetaMonitorCrtcMode *crtc_modes;
+} MetaMonitorMode;
+
typedef struct _MetaMonitorPrivate
{
GList *outputs;
+ GList *modes;
/*
* The primary or first output for this monitor, 0 if we can't figure out.
@@ -62,6 +71,9 @@ struct _MetaMonitorTiled
G_DEFINE_TYPE (MetaMonitorTiled, meta_monitor_tiled, META_TYPE_MONITOR)
+static void
+meta_monitor_mode_free (MetaMonitorMode *mode);
+
GList *
meta_monitor_get_outputs (MetaMonitor *monitor)
{
@@ -131,6 +143,7 @@ meta_monitor_finalize (GObject *object)
MetaMonitor *monitor = META_MONITOR (object);
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
+ g_list_free_full (priv->modes, (GDestroyNotify) meta_monitor_mode_free);
g_clear_pointer (&priv->outputs, g_list_free);
}
@@ -147,6 +160,37 @@ meta_monitor_class_init (MetaMonitorClass *klass)
object_class->finalize = meta_monitor_finalize;
}
+static void
+meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
+{
+ MetaMonitor *monitor = META_MONITOR (monitor_normal);
+ MetaMonitorPrivate *monitor_priv =
+ meta_monitor_get_instance_private (monitor);
+ MetaOutput *output;
+ unsigned int i;
+
+ output = meta_monitor_get_main_output (monitor);
+ for (i = 0; i < output->n_modes; i++)
+ {
+ MetaCrtcMode *crtc_mode = output->modes[i];
+ MetaMonitorMode *mode;
+
+ mode = g_new0 (MetaMonitorMode, 1);
+ mode->width = crtc_mode->width;
+ mode->height = crtc_mode->height;
+ mode->refresh_rate = crtc_mode->refresh_rate;
+ mode->crtc_modes = g_new (MetaMonitorCrtcMode, 1);
+ mode->crtc_modes[0] = (MetaMonitorCrtcMode) {
+ .x = 0,
+ .y = 0,
+ .output = output,
+ .crtc_mode = crtc_mode
+ };
+
+ monitor_priv->modes = g_list_append (monitor_priv->modes, mode);
+ }
+}
+
MetaMonitorNormal *
meta_monitor_normal_new (MetaOutput *output)
{
@@ -160,6 +204,8 @@ meta_monitor_normal_new (MetaOutput *output)
monitor_priv->outputs = g_list_append (NULL, output);
monitor_priv->winsys_id = output->winsys_id;
+ meta_monitor_normal_generate_modes (monitor_normal);
+
return monitor_normal;
}
@@ -223,6 +269,104 @@ add_tiled_monitor_outputs (MetaMonitorManager *monitor_manager,
}
}
+static void
+calculate_tile_coordinate (MetaMonitor *monitor,
+ MetaOutput *output,
+ int *out_x,
+ int *out_y)
+{
+ MetaMonitorPrivate *monitor_priv =
+ meta_monitor_get_instance_private (monitor);
+ GList *l;
+ int x = 0;
+ int y = 0;
+
+ for (l = monitor_priv->outputs; l; l = l->next)
+ {
+ MetaOutput *other_output = l->data;
+
+ 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;
+ }
+
+ *out_x = x;
+ *out_y = y;
+}
+
+static void
+meta_monitor_tiled_calculate_tiled_size (MetaMonitor *monitor,
+ int *out_width,
+ int *out_height)
+{
+ MetaMonitorPrivate *monitor_priv =
+ meta_monitor_get_instance_private (monitor);
+ GList *l;
+ int width;
+ int height;
+
+ width = 0;
+ height = 0;
+ for (l = monitor_priv->outputs; l; l = l->next)
+ {
+ MetaOutput *output = l->data;
+
+ 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
+meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled)
+{
+ MetaMonitor *monitor = META_MONITOR (monitor_tiled);
+ MetaMonitorPrivate *monitor_priv =
+ meta_monitor_get_instance_private (monitor);
+ MetaMonitorMode *mode;
+ GList *l;
+ int i;
+
+ mode = g_new0 (MetaMonitorMode, 1);
+ meta_monitor_tiled_calculate_tiled_size (monitor,
+ &mode->width, &mode->height);
+ mode->crtc_modes = g_new (MetaMonitorCrtcMode,
+ g_list_length (monitor_priv->outputs));
+ for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++)
+ {
+ MetaOutput *output = l->data;
+ MetaCrtcMode *preferred_crtc_mode = output->preferred_mode;
+ int x;
+ int y;
+
+ calculate_tile_coordinate (monitor, output, &x, &y);
+
+ mode->crtc_modes[i] = (MetaMonitorCrtcMode) {
+ .x = x,
+ .y = y,
+ .output = output,
+ .crtc_mode = preferred_crtc_mode
+ };
+
+ g_warn_if_fail (mode->refresh_rate == 0.0f ||
+ mode->refresh_rate == preferred_crtc_mode->refresh_rate);
+
+ mode->refresh_rate = preferred_crtc_mode->refresh_rate;
+ }
+
+ monitor_priv->modes = g_list_append (monitor_priv->modes, mode);
+
+ /* TODO: Add single tile modes */
+}
+
MetaMonitorTiled *
meta_monitor_tiled_new (MetaMonitorManager *monitor_manager,
MetaOutput *output)
@@ -243,6 +387,8 @@ meta_monitor_tiled_new (MetaMonitorManager *monitor_manager,
meta_monitor_manager_tiled_monitor_added (monitor_manager,
META_MONITOR (monitor_tiled));
+ meta_monitor_tiled_generate_modes (monitor_tiled);
+
return monitor_tiled;
}
@@ -256,30 +402,10 @@ meta_monitor_tiled_get_main_output (MetaMonitor *monitor)
static void
meta_monitor_tiled_get_dimensions (MetaMonitor *monitor,
- int *out_width,
- int *out_height)
+ int *width,
+ int *height)
{
- MetaMonitorPrivate *monitor_priv =
- meta_monitor_get_instance_private (monitor);
- GList *l;
- int width;
- int height;
-
- width = 0;
- height = 0;
- for (l = monitor_priv->outputs; l; l = l->next)
- {
- MetaOutput *output = l->data;
-
- 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;
+ meta_monitor_tiled_calculate_tiled_size (monitor, width, height);
}
static void
@@ -310,3 +436,52 @@ meta_monitor_tiled_class_init (MetaMonitorTiledClass *klass)
monitor_class->get_main_output = meta_monitor_tiled_get_main_output;
monitor_class->get_dimensions = meta_monitor_tiled_get_dimensions;
}
+
+static void
+meta_monitor_mode_free (MetaMonitorMode *monitor_mode)
+{
+ g_free (monitor_mode->crtc_modes);
+ g_free (monitor_mode);
+}
+
+GList *
+meta_monitor_get_modes (MetaMonitor *monitor)
+{
+ MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
+
+ return priv->modes;
+}
+
+void
+meta_monitor_mode_get_resolution (MetaMonitorMode *monitor_mode,
+ int *width,
+ int *height)
+{
+ *width = monitor_mode->width;
+ *height = monitor_mode->height;
+}
+
+float
+meta_monitor_mode_get_refresh_rate (MetaMonitorMode *monitor_mode)
+{
+ return monitor_mode->refresh_rate;
+}
+
+void
+meta_monitor_mode_foreach_crtc (MetaMonitor *monitor,
+ MetaMonitorMode *mode,
+ MetaMonitorModeFunc func,
+ gpointer user_data)
+{
+ MetaMonitorPrivate *monitor_priv =
+ meta_monitor_get_instance_private (monitor);
+ GList *l;
+ int i;
+
+ for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++)
+ {
+ MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i];
+
+ func (monitor, mode, monitor_crtc_mode, user_data);
+ }
+}
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
index 50d5105..fc8511b 100644
--- a/src/backends/meta-monitor.h
+++ b/src/backends/meta-monitor.h
@@ -26,6 +26,21 @@
#include "backends/meta-monitor-manager-private.h"
+typedef struct _MetaMonitorMode MetaMonitorMode;
+
+typedef struct _MetaMonitorCrtcMode
+{
+ int x;
+ int y;
+ MetaOutput *output;
+ MetaCrtcMode *crtc_mode;
+} MetaMonitorCrtcMode;
+
+typedef void (* MetaMonitorModeFunc) (MetaMonitor *monitor,
+ MetaMonitorMode *mode,
+ MetaMonitorCrtcMode *monitor_crtc_mode,
+ gpointer user_data);
+
#define META_TYPE_MONITOR (meta_monitor_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaMonitor, meta_monitor, META, MONITOR, GObject)
@@ -74,4 +89,17 @@ const char * meta_monitor_get_product (MetaMonitor *monitor);
uint32_t meta_monitor_tiled_get_tile_group_id (MetaMonitorTiled *monitor_tiled);
+GList * meta_monitor_get_modes (MetaMonitor *monitor);
+
+void meta_monitor_mode_get_resolution (MetaMonitorMode *monitor_mode,
+ int *width,
+ int *height);
+
+float meta_monitor_mode_get_refresh_rate (MetaMonitorMode *monitor_mode);
+
+void meta_monitor_mode_foreach_crtc (MetaMonitor *monitor,
+ MetaMonitorMode *mode,
+ MetaMonitorModeFunc func,
+ gpointer user_data);
+
#endif /* META_MONITOR_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]