From 4b37c2e446f0b613927ffc87c44a67ea4bfc7445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 27 Feb 2020 00:08:58 +0100 Subject: [PATCH] crtc-mode: Move away fields from public MetaCrtcMode struct The ID and name are just moved into the instance private, while the rest is moved to a `MetaCrtcModeInfo` struct which is used during construction and retrieved via a getter. Opens up the possibility to add actual sub types. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287 --- src/backends/meta-crtc-mode.c | 157 +++++++++++++++++- src/backends/meta-crtc-mode.h | 33 +++- src/backends/meta-monitor-config-manager.c | 10 +- src/backends/meta-monitor-manager-dummy.c | 23 +-- src/backends/meta-monitor-manager.c | 12 +- src/backends/meta-monitor.c | 39 +++-- src/backends/native/meta-crtc-kms.c | 10 +- .../native/meta-cursor-renderer-native.c | 15 +- src/backends/native/meta-gpu-kms.c | 23 ++- src/backends/native/meta-output-kms.c | 31 ++-- src/backends/native/meta-renderer-native.c | 40 +++-- src/backends/x11/meta-gpu-xrandr.c | 23 ++- .../x11/meta-monitor-manager-xrandr.c | 18 +- src/backends/x11/meta-output-xrandr.c | 8 +- src/tests/headless-start-test.c | 15 +- src/tests/monitor-test-utils.c | 24 ++- 16 files changed, 373 insertions(+), 108 deletions(-) diff --git a/src/backends/meta-crtc-mode.c b/src/backends/meta-crtc-mode.c index 85993867d..748145747 100644 --- a/src/backends/meta-crtc-mode.c +++ b/src/backends/meta-crtc-mode.c @@ -21,17 +21,142 @@ #include "backends/meta-crtc-mode.h" -G_DEFINE_TYPE (MetaCrtcMode, meta_crtc_mode, G_TYPE_OBJECT) +enum +{ + PROP_0, + + PROP_ID, + PROP_NAME, + PROP_INFO, + + N_PROPS +}; + +static GParamSpec *obj_props[N_PROPS]; + +typedef struct _MetaCrtcModePrivate +{ + uint64_t id; + char *name; + MetaCrtcModeInfo *info; +} MetaCrtcModePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaCrtcMode, meta_crtc_mode, G_TYPE_OBJECT) + +G_DEFINE_BOXED_TYPE (MetaCrtcModeInfo, meta_crtc_mode_info, + meta_crtc_mode_info_ref, + meta_crtc_mode_info_unref) + +MetaCrtcModeInfo * +meta_crtc_mode_info_new (void) +{ + MetaCrtcModeInfo *crtc_mode_info; + + crtc_mode_info = g_new0 (MetaCrtcModeInfo, 1); + g_ref_count_init (&crtc_mode_info->ref_count); + + return crtc_mode_info; +} + +MetaCrtcModeInfo * +meta_crtc_mode_info_ref (MetaCrtcModeInfo *crtc_mode_info) +{ + g_ref_count_inc (&crtc_mode_info->ref_count); + return crtc_mode_info; +} + +void +meta_crtc_mode_info_unref (MetaCrtcModeInfo *crtc_mode_info) +{ + if (g_ref_count_dec (&crtc_mode_info->ref_count)) + g_free (crtc_mode_info); +} + +uint64_t +meta_crtc_mode_get_id (MetaCrtcMode *crtc_mode) +{ + MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode); + + return priv->id; +} + +const char * +meta_crtc_mode_get_name (MetaCrtcMode *crtc_mode) +{ + MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode); + + return priv->name; +} + +const MetaCrtcModeInfo * +meta_crtc_mode_get_info (MetaCrtcMode *crtc_mode) +{ + MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode); + + return priv->info; +} + +static void +meta_crtc_mode_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaCrtcMode *crtc_mode = META_CRTC_MODE (object); + MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode); + + switch (prop_id) + { + case PROP_ID: + priv->id = g_value_get_uint64 (value); + break; + case PROP_NAME: + priv->name = g_value_dup_string (value); + break; + case PROP_INFO: + priv->info = meta_crtc_mode_info_ref (g_value_get_boxed (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_crtc_mode_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaCrtcMode *crtc_mode = META_CRTC_MODE (object); + MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode); + + switch (prop_id) + { + case PROP_ID: + g_value_set_uint64 (value, priv->id); + break; + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + case PROP_INFO: + g_value_set_boxed (value, priv->info); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} static void meta_crtc_mode_finalize (GObject *object) { MetaCrtcMode *crtc_mode = META_CRTC_MODE (object); + MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode); if (crtc_mode->driver_notify) crtc_mode->driver_notify (crtc_mode); - g_clear_pointer (&crtc_mode->name, g_free); + g_clear_pointer (&priv->name, g_free); + g_clear_pointer (&priv->info, meta_crtc_mode_info_unref); G_OBJECT_CLASS (meta_crtc_mode_parent_class)->finalize (object); } @@ -46,5 +171,33 @@ meta_crtc_mode_class_init (MetaCrtcModeClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->set_property = meta_crtc_mode_set_property; + object_class->get_property = meta_crtc_mode_get_property; object_class->finalize = meta_crtc_mode_finalize; + + obj_props[PROP_ID] = + g_param_spec_uint64 ("id", + "id", + "CRTC mode id", + 0, UINT64_MAX, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_props[PROP_NAME] = + g_param_spec_string ("name", + "name", + "Name of CRTC mode", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_props[PROP_INFO] = + g_param_spec_boxed ("info", + "info", + "MetaOutputInfo", + META_TYPE_CRTC_MODE_INFO, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, N_PROPS, obj_props); } diff --git a/src/backends/meta-crtc-mode.h b/src/backends/meta-crtc-mode.h index f5fdaa3ad..b7165265e 100644 --- a/src/backends/meta-crtc-mode.h +++ b/src/backends/meta-crtc-mode.h @@ -47,17 +47,19 @@ typedef enum _MetaCrtcModeFlag META_CRTC_MODE_FLAG_MASK = 0x3fff } MetaCrtcModeFlag; -struct _MetaCrtcMode +typedef struct _MetaCrtcModeInfo { - GObject parent; - - uint64_t mode_id; - char *name; + grefcount ref_count; int width; int height; float refresh_rate; MetaCrtcModeFlag flags; +} MetaCrtcModeInfo; + +struct _MetaCrtcMode +{ + GObject parent; gpointer driver_private; GDestroyNotify driver_notify; @@ -69,4 +71,25 @@ G_DECLARE_FINAL_TYPE (MetaCrtcMode, meta_crtc_mode, META, CRTC_MODE, GObject) +#define META_TYPE_CRTC_MODE_INFO (meta_crtc_mode_info_get_type ()) +GType meta_crtc_mode_info_get_type (void); + +META_EXPORT_TEST +MetaCrtcModeInfo * meta_crtc_mode_info_new (void); + +META_EXPORT_TEST +MetaCrtcModeInfo * meta_crtc_mode_info_ref (MetaCrtcModeInfo *crtc_mode_info); + +META_EXPORT_TEST +void meta_crtc_mode_info_unref (MetaCrtcModeInfo *crtc_mode_info); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaCrtcModeInfo, meta_crtc_mode_info_unref) + +uint64_t meta_crtc_mode_get_id (MetaCrtcMode *crtc_mode); + +const char * meta_crtc_mode_get_name (MetaCrtcMode *crtc_mode); + +META_EXPORT_TEST +const MetaCrtcModeInfo * meta_crtc_mode_get_info (MetaCrtcMode *crtc_mode); + #endif /* META_CRTC_MODE_H */ diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c index 55053276b..4c5ab77e7 100644 --- a/src/backends/meta-monitor-config-manager.c +++ b/src/backends/meta-monitor-config-manager.c @@ -184,6 +184,7 @@ assign_monitor_crtc (MetaMonitor *monitor, float scale = 0.0; float width, height; MetaCrtcMode *crtc_mode; + const MetaCrtcModeInfo *crtc_mode_info; graphene_rect_t crtc_layout; MetaCrtcAssignment *crtc_assignment; MetaOutputAssignment *output_assignment; @@ -233,16 +234,17 @@ assign_monitor_crtc (MetaMonitor *monitor, } crtc_mode = monitor_crtc_mode->crtc_mode; + crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode); if (meta_monitor_transform_is_rotated (crtc_transform)) { - width = crtc_mode->height / scale; - height = crtc_mode->width / scale; + width = crtc_mode_info->height / scale; + height = crtc_mode_info->width / scale; } else { - width = crtc_mode->width / scale; - height = crtc_mode->height / scale; + width = crtc_mode_info->width / scale; + height = crtc_mode_info->height / scale; } crtc_layout = GRAPHENE_RECT_INIT (x_offset + (crtc_x / scale), diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c index 7139d3180..ca3d200a7 100644 --- a/src/backends/meta-monitor-manager-dummy.c +++ b/src/backends/meta-monitor-manager-dummy.c @@ -88,16 +88,17 @@ static MetaCrtcMode * create_mode (CrtcModeSpec *spec, long mode_id) { - MetaCrtcMode *mode; + g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL; - mode = g_object_new (META_TYPE_CRTC_MODE, NULL); + crtc_mode_info = meta_crtc_mode_info_new (); + crtc_mode_info->width = spec->width; + crtc_mode_info->height = spec->height; + crtc_mode_info->refresh_rate = spec->refresh_rate; - mode->mode_id = mode_id; - mode->width = spec->width; - mode->height = spec->height; - mode->refresh_rate = spec->refresh_rate; - - return mode; + return g_object_new (META_TYPE_CRTC_MODE, + "id", mode_id, + "info", crtc_mode_info, + NULL); } static MetaGpu * @@ -302,6 +303,7 @@ append_tiled_monitor (MetaMonitorManager *manager, { MetaOutputDummy *output_dummy; MetaCrtcMode *preferred_mode; + const MetaCrtcModeInfo *preferred_mode_info; unsigned int j; unsigned int number; g_autoptr (MetaOutputInfo) output_info = NULL; @@ -311,6 +313,7 @@ append_tiled_monitor (MetaMonitorManager *manager, number = g_list_length (*outputs) + 1; preferred_mode = g_list_last (*modes)->data; + preferred_mode_info = meta_crtc_mode_get_info (preferred_mode); output_info = meta_output_info_new (); @@ -332,8 +335,8 @@ append_tiled_monitor (MetaMonitorManager *manager, .max_v_tiles = 1, .loc_h_tile = i, .loc_v_tile = 0, - .tile_w = preferred_mode->width, - .tile_h = preferred_mode->height + .tile_w = preferred_mode_info->width, + .tile_h = preferred_mode_info->height }, output_info->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs)); diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 95bb92d83..e2d16b7d0 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -1185,14 +1185,16 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, for (l = combined_modes, i = 0; l; l = l->next, i++) { MetaCrtcMode *mode = l->data; + const MetaCrtcModeInfo *crtc_mode_info = + meta_crtc_mode_get_info (mode);; g_variant_builder_add (&mode_builder, "(uxuudu)", i, /* ID */ - (gint64)mode->mode_id, - (guint32)mode->width, - (guint32)mode->height, - (double)mode->refresh_rate, - (guint32)mode->flags); + (int64_t) meta_crtc_mode_get_id (mode), + (uint32_t) crtc_mode_info->width, + (uint32_t) crtc_mode_info->height, + (double) crtc_mode_info->refresh_rate, + (uint32_t) crtc_mode_info->flags); } if (!meta_monitor_manager_get_max_screen_size (manager, diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c index bade4d166..4aaa516d7 100644 --- a/src/backends/meta-monitor.c +++ b/src/backends/meta-monitor.c @@ -571,6 +571,8 @@ meta_monitor_create_spec (MetaMonitor *monitor, { const MetaOutputInfo *output_info = meta_monitor_get_main_output_info (monitor); + const MetaCrtcModeInfo *crtc_mode_info = + meta_crtc_mode_get_info (crtc_mode); if (meta_monitor_transform_is_rotated (output_info->panel_orientation_transform)) { @@ -582,8 +584,8 @@ meta_monitor_create_spec (MetaMonitor *monitor, return (MetaMonitorModeSpec) { .width = width, .height = height, - .refresh_rate = crtc_mode->refresh_rate, - .flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS + .refresh_rate = crtc_mode_info->refresh_rate, + .flags = crtc_mode_info->flags & HANDLED_CRTC_MODE_FLAGS }; } @@ -595,16 +597,20 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal) meta_monitor_get_instance_private (monitor); MetaOutput *output; const MetaOutputInfo *output_info; + MetaCrtcMode *preferred_mode; MetaCrtcModeFlag preferred_mode_flags; unsigned int i; output = meta_monitor_get_main_output (monitor); output_info = meta_output_get_info (output); - preferred_mode_flags = output_info->preferred_mode->flags; + preferred_mode = output_info->preferred_mode; + preferred_mode_flags = meta_crtc_mode_get_info (preferred_mode)->flags; for (i = 0; i < output_info->n_modes; i++) { MetaCrtcMode *crtc_mode = output_info->modes[i]; + const MetaCrtcModeInfo *crtc_mode_info = + meta_crtc_mode_get_info (crtc_mode); MetaCrtc *crtc; MetaMonitorMode *mode; gboolean replace; @@ -612,8 +618,8 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal) mode = g_new0 (MetaMonitorMode, 1); mode->monitor = monitor; mode->spec = meta_monitor_create_spec (monitor, - crtc_mode->width, - crtc_mode->height, + crtc_mode_info->width, + crtc_mode_info->height, crtc_mode); mode->id = generate_mode_id (&mode->spec); mode->crtc_modes = g_new (MetaMonitorCrtcMode, 1); @@ -629,7 +635,7 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal) * otherwise take the first one in the list. This guarantees that the * preferred mode is always added. */ - replace = crtc_mode->flags == preferred_mode_flags; + replace = crtc_mode_info->flags == preferred_mode_flags; if (!meta_monitor_add_mode (monitor, mode, replace)) { @@ -940,9 +946,10 @@ is_crtc_mode_tiled (MetaOutput *output, MetaCrtcMode *crtc_mode) { const MetaOutputInfo *output_info = meta_output_get_info (output); + const MetaCrtcModeInfo *crtc_mode_info = meta_crtc_mode_get_info (crtc_mode); - return (crtc_mode->width == (int) output_info->tile_info.tile_w && - crtc_mode->height == (int) output_info->tile_info.tile_h); + return (crtc_mode_info->width == (int) output_info->tile_info.tile_w && + crtc_mode_info->height == (int) output_info->tile_info.tile_h); } static MetaCrtcMode * @@ -950,6 +957,8 @@ find_tiled_crtc_mode (MetaOutput *output, MetaCrtcMode *reference_crtc_mode) { const MetaOutputInfo *output_info = meta_output_get_info (output); + const MetaCrtcModeInfo *reference_crtc_mode_info = + meta_crtc_mode_get_info (reference_crtc_mode); MetaCrtcMode *crtc_mode; unsigned int i; @@ -959,15 +968,18 @@ find_tiled_crtc_mode (MetaOutput *output, for (i = 0; i < output_info->n_modes; i++) { + const MetaCrtcModeInfo *crtc_mode_info; + crtc_mode = output_info->modes[i]; + crtc_mode_info = meta_crtc_mode_get_info (crtc_mode); if (!is_crtc_mode_tiled (output, crtc_mode)) continue; - if (crtc_mode->refresh_rate != reference_crtc_mode->refresh_rate) + if (crtc_mode_info->refresh_rate != reference_crtc_mode_info->refresh_rate) continue; - if (crtc_mode->flags != reference_crtc_mode->flags) + if (crtc_mode_info->flags != reference_crtc_mode_info->flags) continue; return crtc_mode; @@ -1100,6 +1112,7 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled, MetaMonitorPrivate *monitor_priv = meta_monitor_get_instance_private (monitor); MetaMonitorModeTiled *mode; + const MetaCrtcModeInfo *crtc_mode_info; GList *l; int i; @@ -1109,9 +1122,11 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled, mode = g_new0 (MetaMonitorModeTiled, 1); mode->is_tiled = FALSE; mode->parent.monitor = monitor; + + crtc_mode_info = meta_crtc_mode_get_info (crtc_mode); mode->parent.spec = meta_monitor_create_spec (monitor, - crtc_mode->width, - crtc_mode->height, + crtc_mode_info->width, + crtc_mode_info->height, crtc_mode); mode->parent.id = generate_mode_id (&mode->parent.spec); mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode, diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c index 1bfd24832..5860f42a2 100644 --- a/src/backends/native/meta-crtc-kms.c +++ b/src/backends/native/meta-crtc-kms.c @@ -99,6 +99,7 @@ meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms, { MetaCrtc *crtc = META_CRTC (crtc_kms); const MetaCrtcConfig *crtc_config; + const MetaCrtcModeInfo *crtc_mode_info; MetaFixed16Rectangle src_rect; MetaFixed16Rectangle dst_rect; MetaKmsAssignPlaneFlag flags; @@ -108,18 +109,19 @@ meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms, MetaKmsPlaneAssignment *plane_assignment; crtc_config = meta_crtc_get_config (crtc); + crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode); src_rect = (MetaFixed16Rectangle) { .x = meta_fixed_16_from_int (0), .y = meta_fixed_16_from_int (0), - .width = meta_fixed_16_from_int (crtc_config->mode->width), - .height = meta_fixed_16_from_int (crtc_config->mode->height), + .width = meta_fixed_16_from_int (crtc_mode_info->width), + .height = meta_fixed_16_from_int (crtc_mode_info->height), }; dst_rect = (MetaFixed16Rectangle) { .x = meta_fixed_16_from_int (0), .y = meta_fixed_16_from_int (0), - .width = meta_fixed_16_from_int (crtc_config->mode->width), - .height = meta_fixed_16_from_int (crtc_config->mode->height), + .width = meta_fixed_16_from_int (crtc_mode_info->width), + .height = meta_fixed_16_from_int (crtc_mode_info->height), }; flags = META_KMS_ASSIGN_PLANE_FLAG_NONE; diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index 01c847c3a..02bb2aaf0 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -402,6 +402,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor, meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); MetaCrtc *crtc; MetaMonitorTransform transform; + const MetaCrtcModeInfo *crtc_mode_info; graphene_rect_t scaled_crtc_rect; float scale; int crtc_x, crtc_y; @@ -420,15 +421,17 @@ update_monitor_crtc_cursor (MetaMonitor *monitor, transform, &crtc_x, &crtc_y); + crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode); + if (meta_monitor_transform_is_rotated (transform)) { - crtc_width = monitor_crtc_mode->crtc_mode->height; - crtc_height = monitor_crtc_mode->crtc_mode->width; + crtc_width = crtc_mode_info->height; + crtc_height = crtc_mode_info->width; } else { - crtc_width = monitor_crtc_mode->crtc_mode->width; - crtc_height = monitor_crtc_mode->crtc_mode->height; + crtc_width = crtc_mode_info->width; + crtc_height = crtc_mode_info->height; } scaled_crtc_rect = (graphene_rect_t) { @@ -479,8 +482,8 @@ update_monitor_crtc_cursor (MetaMonitor *monitor, inverted_transform = meta_monitor_transform_invert (transform); meta_rectangle_transform (&cursor_rect, inverted_transform, - monitor_crtc_mode->crtc_mode->width, - monitor_crtc_mode->crtc_mode->height, + crtc_mode_info->width, + crtc_mode_info->height, &cursor_rect); set_crtc_cursor (data->in_cursor_renderer_native, diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c index 43bef5ab3..18f7d8036 100644 --- a/src/backends/native/meta-gpu-kms.c +++ b/src/backends/native/meta-gpu-kms.c @@ -343,15 +343,24 @@ static MetaCrtcMode * create_mode (const drmModeModeInfo *drm_mode, long mode_id) { + g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL; + g_autofree char *crtc_mode_name = NULL; MetaCrtcMode *mode; - mode = g_object_new (META_TYPE_CRTC_MODE, NULL); - mode->mode_id = mode_id; - mode->name = g_strndup (drm_mode->name, DRM_DISPLAY_MODE_LEN); - mode->width = drm_mode->hdisplay; - mode->height = drm_mode->vdisplay; - mode->flags = drm_mode->flags; - mode->refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); + crtc_mode_info = meta_crtc_mode_info_new (); + crtc_mode_info->width = drm_mode->hdisplay; + crtc_mode_info->height = drm_mode->vdisplay; + crtc_mode_info->flags = drm_mode->flags; + crtc_mode_info->refresh_rate = + meta_calculate_drm_mode_refresh_rate (drm_mode); + + crtc_mode_name = g_strndup (drm_mode->name, DRM_DISPLAY_MODE_LEN); + mode = g_object_new (META_TYPE_CRTC_MODE, + "id", mode_id, + "name", crtc_mode_name, + "info", crtc_mode_info, + NULL); + mode->driver_private = g_slice_dup (drmModeModeInfo, drm_mode); mode->driver_notify = (GDestroyNotify) meta_crtc_mode_destroy_notify; diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index d9c2a1932..6f40bed1f 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -66,12 +66,15 @@ meta_output_kms_set_underscan (MetaOutputKms *output_kms, { MetaCrtc *crtc; const MetaCrtcConfig *crtc_config; + const MetaCrtcModeInfo *crtc_mode_info; uint64_t hborder, vborder; crtc = meta_output_get_assigned_crtc (output); crtc_config = meta_crtc_get_config (crtc); - hborder = MIN (128, (uint64_t) round (crtc_config->mode->width * 0.05)); - vborder = MIN (128, (uint64_t) round (crtc_config->mode->height * 0.05)); + crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode); + + hborder = MIN (128, (uint64_t) round (crtc_mode_info->width * 0.05)); + vborder = MIN (128, (uint64_t) round (crtc_mode_info->height * 0.05)); g_debug ("Setting underscan of connector %s to %" G_GUINT64_FORMAT " x %" G_GUINT64_FORMAT, meta_kms_connector_get_name (output_kms->kms_connector), @@ -207,17 +210,23 @@ static int compare_modes (const void *one, const void *two) { - MetaCrtcMode *a = *(MetaCrtcMode **) one; - MetaCrtcMode *b = *(MetaCrtcMode **) two; + MetaCrtcMode *crtc_mode_one = *(MetaCrtcMode **) one; + MetaCrtcMode *crtc_mode_two = *(MetaCrtcMode **) two; + const MetaCrtcModeInfo *crtc_mode_info_one = + meta_crtc_mode_get_info (crtc_mode_one); + const MetaCrtcModeInfo *crtc_mode_info_two = + meta_crtc_mode_get_info (crtc_mode_two); - if (a->width != b->width) - return a->width > b->width ? -1 : 1; - if (a->height != b->height) - return a->height > b->height ? -1 : 1; - if (a->refresh_rate != b->refresh_rate) - return a->refresh_rate > b->refresh_rate ? -1 : 1; + if (crtc_mode_info_one->width != crtc_mode_info_two->width) + return crtc_mode_info_one->width > crtc_mode_info_two->width ? -1 : 1; + if (crtc_mode_info_one->height != crtc_mode_info_two->height) + return crtc_mode_info_one->height > crtc_mode_info_two->height ? -1 : 1; + if (crtc_mode_info_one->refresh_rate != crtc_mode_info_two->refresh_rate) + return (crtc_mode_info_one->refresh_rate > crtc_mode_info_two->refresh_rate + ? -1 : 1); - return g_strcmp0 (b->name, a->name); + return g_strcmp0 (meta_crtc_mode_get_name (crtc_mode_one), + meta_crtc_mode_get_name (crtc_mode_two)); } static gboolean diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index d75313486..8ec809b9d 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -1112,6 +1112,30 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen) swap_secondary_drm_fb (onscreen); } +static void +maybe_update_frame_info (MetaCrtc *crtc, + CoglFrameInfo *frame_info, + int64_t time_ns) +{ + const MetaCrtcConfig *crtc_config; + const MetaCrtcModeInfo *crtc_mode_info; + float refresh_rate; + + g_return_if_fail (crtc); + + crtc_config = meta_crtc_get_config (crtc); + if (!crtc_config) + return; + + crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode); + refresh_rate = crtc_mode_info->refresh_rate; + if (refresh_rate >= frame_info->refresh_rate) + { + frame_info->presentation_time = time_ns; + frame_info->refresh_rate = refresh_rate; + } +} + static void notify_view_crtc_presented (MetaRendererView *view, MetaKmsCrtc *kms_crtc, @@ -1127,8 +1151,6 @@ notify_view_crtc_presented (MetaRendererView *view, MetaGpuKms *render_gpu = onscreen_native->render_gpu; CoglFrameInfo *frame_info; MetaCrtc *crtc; - const MetaCrtcConfig *crtc_config; - float refresh_rate; MetaGpuKms *gpu_kms; /* Only keep the frame info for the fastest CRTC in use, which may not be @@ -1139,13 +1161,7 @@ notify_view_crtc_presented (MetaRendererView *view, frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos); crtc = META_CRTC (meta_crtc_kms_from_kms_crtc (kms_crtc)); - crtc_config = crtc ? meta_crtc_get_config (crtc) : NULL; - refresh_rate = crtc_config ? crtc_config->mode->refresh_rate : 0.0f; - if (refresh_rate >= frame_info->refresh_rate) - { - frame_info->presentation_time = time_ns; - frame_info->refresh_rate = refresh_rate; - } + maybe_update_frame_info (crtc, frame_info, time_ns); gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); if (gpu_kms != render_gpu) @@ -3161,6 +3177,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer, CoglDisplayEGL *cogl_display_egl; CoglOnscreenEGL *onscreen_egl; const MetaCrtcConfig *crtc_config; + const MetaCrtcModeInfo *crtc_mode_info; MetaMonitorTransform view_transform; CoglOnscreen *onscreen = NULL; CoglOffscreen *offscreen = NULL; @@ -3173,8 +3190,9 @@ meta_renderer_native_create_view (MetaRenderer *renderer, GError *error = NULL; crtc_config = meta_crtc_get_config (crtc); - onscreen_width = crtc_config->mode->width; - onscreen_height = crtc_config->mode->height; + crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode); + onscreen_width = crtc_mode_info->width; + onscreen_height = crtc_mode_info->height; onscreen = meta_renderer_native_create_onscreen (renderer_native, renderer_native->primary_gpu_kms, diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c index 3b1f41ff7..5f6bc7894 100644 --- a/src/backends/x11/meta-gpu-xrandr.c +++ b/src/backends/x11/meta-gpu-xrandr.c @@ -141,18 +141,23 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu, for (i = 0; i < (unsigned)resources->nmode; i++) { XRRModeInfo *xmode = &resources->modes[i]; + g_autofree char *crtc_mode_name = NULL; MetaCrtcMode *mode; + g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL; - mode = g_object_new (META_TYPE_CRTC_MODE, NULL); - - mode->mode_id = xmode->id; - mode->width = xmode->width; - mode->height = xmode->height; - mode->refresh_rate = (xmode->dotClock / - ((float)xmode->hTotal * xmode->vTotal)); - mode->flags = xmode->modeFlags; - mode->name = get_xmode_name (xmode); + crtc_mode_info = meta_crtc_mode_info_new (); + crtc_mode_info->width = xmode->width; + crtc_mode_info->height = xmode->height; + crtc_mode_info->refresh_rate = (xmode->dotClock / + ((float)xmode->hTotal * xmode->vTotal)); + crtc_mode_info->flags = xmode->modeFlags; + crtc_mode_name = get_xmode_name (xmode); + mode = g_object_new (META_TYPE_CRTC_MODE, + "id", xmode->id, + "name", crtc_mode_name, + "info", crtc_mode_info, + NULL); modes = g_list_append (modes, mode); } meta_gpu_take_modes (gpu, modes); diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c index 5eb933f01..946a22123 100644 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -475,14 +475,15 @@ apply_crtc_assignments (MetaMonitorManager *manager, if (crtc_assignment->mode != NULL) { - MetaCrtcMode *mode; + MetaCrtcMode *crtc_mode; g_autofree xcb_randr_output_t *output_ids = NULL; unsigned int j, n_output_ids; xcb_randr_crtc_t crtc_id; int x, y; xcb_randr_rotation_t rotation; + xcb_randr_mode_t mode; - mode = crtc_assignment->mode; + crtc_mode = crtc_assignment->mode; n_output_ids = crtc_assignment->outputs->len; output_ids = g_new (xcb_randr_output_t, n_output_ids); @@ -510,20 +511,25 @@ apply_crtc_assignments (MetaMonitorManager *manager, y = (int) roundf (crtc_assignment->layout.origin.y); rotation = meta_monitor_transform_to_xrandr (crtc_assignment->transform); + mode = meta_crtc_mode_get_id (crtc_mode); if (!xrandr_set_crtc_config (manager_xrandr, crtc, save_timestamp, crtc_id, XCB_CURRENT_TIME, x, y, - (xcb_randr_mode_t) mode->mode_id, + mode, rotation, output_ids, n_output_ids)) { + const MetaCrtcModeInfo *crtc_mode_info = + meta_crtc_mode_get_info (crtc_mode); + meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transform %u failed\n", (unsigned) meta_crtc_get_id (crtc), - (unsigned) mode->mode_id, - mode->width, mode->height, (float)mode->refresh_rate, + (unsigned) mode, + crtc_mode_info->width, crtc_mode_info->height, + (float) crtc_mode_info->refresh_rate, (int) roundf (crtc_assignment->layout.origin.x), (int) roundf (crtc_assignment->layout.origin.y), crtc_assignment->transform); @@ -532,7 +538,7 @@ apply_crtc_assignments (MetaMonitorManager *manager, meta_crtc_set_config (crtc, &crtc_assignment->layout, - mode, + crtc_mode, crtc_assignment->transform); } } diff --git a/src/backends/x11/meta-output-xrandr.c b/src/backends/x11/meta-output-xrandr.c index 5bf658129..49fa838db 100644 --- a/src/backends/x11/meta-output-xrandr.c +++ b/src/backends/x11/meta-output-xrandr.c @@ -114,13 +114,15 @@ output_set_underscanning_xrandr (MetaOutput *output, { MetaCrtc *crtc; const MetaCrtcConfig *crtc_config; + const MetaCrtcModeInfo *crtc_mode_info; uint32_t border_value; crtc = meta_output_get_assigned_crtc (output); crtc_config = meta_crtc_get_config (crtc); + crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode); prop = XInternAtom (xdisplay, "underscan hborder", False); - border_value = crtc_config->mode->width * 0.05; + border_value = crtc_mode_info->width * 0.05; xcb_randr_change_output_property (XGetXCBConnection (xdisplay), (XID) meta_output_get_id (output), @@ -129,7 +131,7 @@ output_set_underscanning_xrandr (MetaOutput *output, 1, &border_value); prop = XInternAtom (xdisplay, "underscan vborder", False); - border_value = crtc_config->mode->height * 0.05; + border_value = crtc_mode_info->height * 0.05; xcb_randr_change_output_property (XGetXCBConnection (xdisplay), (XID) meta_output_get_id (output), @@ -736,7 +738,7 @@ output_info_init_modes (MetaOutputInfo *output_info, { MetaCrtcMode *mode = l->data; - if (xrandr_output->modes[i] == (XID) mode->mode_id) + if (xrandr_output->modes[i] == (XID) meta_crtc_mode_get_id (mode)) { output_info->modes[n_actual_modes] = mode; n_actual_modes += 1; diff --git a/src/tests/headless-start-test.c b/src/tests/headless-start-test.c index 8cd63bc3a..075b9b809 100644 --- a/src/tests/headless-start-test.c +++ b/src/tests/headless-start-test.c @@ -119,6 +119,7 @@ meta_test_headless_monitor_connect (void) META_MONITOR_MANAGER_TEST (monitor_manager); MetaMonitorTestSetup *test_setup; MetaCrtcMode **modes; + g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL; MetaCrtcMode *crtc_mode; MetaGpu *gpu; MetaCrtc *crtc; @@ -130,11 +131,15 @@ meta_test_headless_monitor_connect (void) test_setup = g_new0 (MetaMonitorTestSetup, 1); - crtc_mode = g_object_new (META_TYPE_CRTC_MODE, NULL); - crtc_mode->mode_id = 1; - crtc_mode->width = 1024; - crtc_mode->height = 768; - crtc_mode->refresh_rate = 60.0; + crtc_mode_info = meta_crtc_mode_info_new (); + crtc_mode_info->width = 1024; + crtc_mode_info->height = 768; + crtc_mode_info->refresh_rate = 60.0; + + crtc_mode = g_object_new (META_TYPE_CRTC_MODE, + "id", 1, + "info", crtc_mode_info, + NULL); test_setup->modes = g_list_append (NULL, crtc_mode); gpu = META_GPU (meta_backend_get_gpus (meta_get_backend ())->data); diff --git a/src/tests/monitor-test-utils.c b/src/tests/monitor-test-utils.c index 710a11e77..3752a6537 100644 --- a/src/tests/monitor-test-utils.c +++ b/src/tests/monitor-test-utils.c @@ -148,14 +148,17 @@ check_monitor_mode (MetaMonitor *monitor, if (crtc_mode) { + const MetaCrtcModeInfo *crtc_mode_info = + meta_crtc_mode_get_info (crtc_mode); float refresh_rate; MetaCrtcModeFlag flags; refresh_rate = meta_monitor_mode_get_refresh_rate (mode); flags = meta_monitor_mode_get_flags (mode); - g_assert_cmpfloat (refresh_rate, ==, crtc_mode->refresh_rate); - g_assert_cmpint (flags, ==, (crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS)); + g_assert_cmpfloat (refresh_rate, ==, crtc_mode_info->refresh_rate); + g_assert_cmpint (flags, ==, (crtc_mode_info->flags & + HANDLED_CRTC_MODE_FLAGS)); } data->expect_crtc_mode_iter++; @@ -543,14 +546,19 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup, test_setup->modes = NULL; for (i = 0; i < setup->n_modes; i++) { + g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL; MetaCrtcMode *mode; - mode = g_object_new (META_TYPE_CRTC_MODE, NULL); - mode->mode_id = i; - mode->width = setup->modes[i].width; - mode->height = setup->modes[i].height; - mode->refresh_rate = setup->modes[i].refresh_rate; - mode->flags = setup->modes[i].flags; + crtc_mode_info = meta_crtc_mode_info_new (); + crtc_mode_info->width = setup->modes[i].width; + crtc_mode_info->height = setup->modes[i].height; + crtc_mode_info->refresh_rate = setup->modes[i].refresh_rate; + crtc_mode_info->flags = setup->modes[i].flags; + + mode = g_object_new (META_TYPE_CRTC_MODE, + "id", i, + "info", crtc_mode_info, + NULL); test_setup->modes = g_list_append (test_setup->modes, mode); }