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
This commit is contained in:
Jonas Ådahl 2020-02-27 00:08:58 +01:00 committed by Georges Basile Stavracas Neto
parent 980ece9a4b
commit 4b37c2e446
16 changed files with 373 additions and 108 deletions

View File

@ -21,17 +21,142 @@
#include "backends/meta-crtc-mode.h" #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 static void
meta_crtc_mode_finalize (GObject *object) meta_crtc_mode_finalize (GObject *object)
{ {
MetaCrtcMode *crtc_mode = META_CRTC_MODE (object); MetaCrtcMode *crtc_mode = META_CRTC_MODE (object);
MetaCrtcModePrivate *priv = meta_crtc_mode_get_instance_private (crtc_mode);
if (crtc_mode->driver_notify) if (crtc_mode->driver_notify)
crtc_mode->driver_notify (crtc_mode); 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); 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); 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; 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);
} }

View File

@ -47,17 +47,19 @@ typedef enum _MetaCrtcModeFlag
META_CRTC_MODE_FLAG_MASK = 0x3fff META_CRTC_MODE_FLAG_MASK = 0x3fff
} MetaCrtcModeFlag; } MetaCrtcModeFlag;
struct _MetaCrtcMode typedef struct _MetaCrtcModeInfo
{ {
GObject parent; grefcount ref_count;
uint64_t mode_id;
char *name;
int width; int width;
int height; int height;
float refresh_rate; float refresh_rate;
MetaCrtcModeFlag flags; MetaCrtcModeFlag flags;
} MetaCrtcModeInfo;
struct _MetaCrtcMode
{
GObject parent;
gpointer driver_private; gpointer driver_private;
GDestroyNotify driver_notify; GDestroyNotify driver_notify;
@ -69,4 +71,25 @@ G_DECLARE_FINAL_TYPE (MetaCrtcMode, meta_crtc_mode,
META, CRTC_MODE, META, CRTC_MODE,
GObject) 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 */ #endif /* META_CRTC_MODE_H */

View File

@ -184,6 +184,7 @@ assign_monitor_crtc (MetaMonitor *monitor,
float scale = 0.0; float scale = 0.0;
float width, height; float width, height;
MetaCrtcMode *crtc_mode; MetaCrtcMode *crtc_mode;
const MetaCrtcModeInfo *crtc_mode_info;
graphene_rect_t crtc_layout; graphene_rect_t crtc_layout;
MetaCrtcAssignment *crtc_assignment; MetaCrtcAssignment *crtc_assignment;
MetaOutputAssignment *output_assignment; MetaOutputAssignment *output_assignment;
@ -233,16 +234,17 @@ assign_monitor_crtc (MetaMonitor *monitor,
} }
crtc_mode = monitor_crtc_mode->crtc_mode; 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)) if (meta_monitor_transform_is_rotated (crtc_transform))
{ {
width = crtc_mode->height / scale; width = crtc_mode_info->height / scale;
height = crtc_mode->width / scale; height = crtc_mode_info->width / scale;
} }
else else
{ {
width = crtc_mode->width / scale; width = crtc_mode_info->width / scale;
height = crtc_mode->height / scale; height = crtc_mode_info->height / scale;
} }
crtc_layout = GRAPHENE_RECT_INIT (x_offset + (crtc_x / scale), crtc_layout = GRAPHENE_RECT_INIT (x_offset + (crtc_x / scale),

View File

@ -88,16 +88,17 @@ static MetaCrtcMode *
create_mode (CrtcModeSpec *spec, create_mode (CrtcModeSpec *spec,
long mode_id) 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; return g_object_new (META_TYPE_CRTC_MODE,
mode->width = spec->width; "id", mode_id,
mode->height = spec->height; "info", crtc_mode_info,
mode->refresh_rate = spec->refresh_rate; NULL);
return mode;
} }
static MetaGpu * static MetaGpu *
@ -302,6 +303,7 @@ append_tiled_monitor (MetaMonitorManager *manager,
{ {
MetaOutputDummy *output_dummy; MetaOutputDummy *output_dummy;
MetaCrtcMode *preferred_mode; MetaCrtcMode *preferred_mode;
const MetaCrtcModeInfo *preferred_mode_info;
unsigned int j; unsigned int j;
unsigned int number; unsigned int number;
g_autoptr (MetaOutputInfo) output_info = NULL; g_autoptr (MetaOutputInfo) output_info = NULL;
@ -311,6 +313,7 @@ append_tiled_monitor (MetaMonitorManager *manager,
number = g_list_length (*outputs) + 1; number = g_list_length (*outputs) + 1;
preferred_mode = g_list_last (*modes)->data; preferred_mode = g_list_last (*modes)->data;
preferred_mode_info = meta_crtc_mode_get_info (preferred_mode);
output_info = meta_output_info_new (); output_info = meta_output_info_new ();
@ -332,8 +335,8 @@ append_tiled_monitor (MetaMonitorManager *manager,
.max_v_tiles = 1, .max_v_tiles = 1,
.loc_h_tile = i, .loc_h_tile = i,
.loc_v_tile = 0, .loc_v_tile = 0,
.tile_w = preferred_mode->width, .tile_w = preferred_mode_info->width,
.tile_h = preferred_mode->height .tile_h = preferred_mode_info->height
}, },
output_info->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs)); output_info->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs));

View File

@ -1185,14 +1185,16 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
for (l = combined_modes, i = 0; l; l = l->next, i++) for (l = combined_modes, i = 0; l; l = l->next, i++)
{ {
MetaCrtcMode *mode = l->data; MetaCrtcMode *mode = l->data;
const MetaCrtcModeInfo *crtc_mode_info =
meta_crtc_mode_get_info (mode);;
g_variant_builder_add (&mode_builder, "(uxuudu)", g_variant_builder_add (&mode_builder, "(uxuudu)",
i, /* ID */ i, /* ID */
(gint64)mode->mode_id, (int64_t) meta_crtc_mode_get_id (mode),
(guint32)mode->width, (uint32_t) crtc_mode_info->width,
(guint32)mode->height, (uint32_t) crtc_mode_info->height,
(double)mode->refresh_rate, (double) crtc_mode_info->refresh_rate,
(guint32)mode->flags); (uint32_t) crtc_mode_info->flags);
} }
if (!meta_monitor_manager_get_max_screen_size (manager, if (!meta_monitor_manager_get_max_screen_size (manager,

View File

@ -571,6 +571,8 @@ meta_monitor_create_spec (MetaMonitor *monitor,
{ {
const MetaOutputInfo *output_info = const MetaOutputInfo *output_info =
meta_monitor_get_main_output_info (monitor); 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)) if (meta_monitor_transform_is_rotated (output_info->panel_orientation_transform))
{ {
@ -582,8 +584,8 @@ meta_monitor_create_spec (MetaMonitor *monitor,
return (MetaMonitorModeSpec) { return (MetaMonitorModeSpec) {
.width = width, .width = width,
.height = height, .height = height,
.refresh_rate = crtc_mode->refresh_rate, .refresh_rate = crtc_mode_info->refresh_rate,
.flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS .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); meta_monitor_get_instance_private (monitor);
MetaOutput *output; MetaOutput *output;
const MetaOutputInfo *output_info; const MetaOutputInfo *output_info;
MetaCrtcMode *preferred_mode;
MetaCrtcModeFlag preferred_mode_flags; MetaCrtcModeFlag preferred_mode_flags;
unsigned int i; unsigned int i;
output = meta_monitor_get_main_output (monitor); output = meta_monitor_get_main_output (monitor);
output_info = meta_output_get_info (output); 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++) for (i = 0; i < output_info->n_modes; i++)
{ {
MetaCrtcMode *crtc_mode = output_info->modes[i]; MetaCrtcMode *crtc_mode = output_info->modes[i];
const MetaCrtcModeInfo *crtc_mode_info =
meta_crtc_mode_get_info (crtc_mode);
MetaCrtc *crtc; MetaCrtc *crtc;
MetaMonitorMode *mode; MetaMonitorMode *mode;
gboolean replace; gboolean replace;
@ -612,8 +618,8 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
mode = g_new0 (MetaMonitorMode, 1); mode = g_new0 (MetaMonitorMode, 1);
mode->monitor = monitor; mode->monitor = monitor;
mode->spec = meta_monitor_create_spec (monitor, mode->spec = meta_monitor_create_spec (monitor,
crtc_mode->width, crtc_mode_info->width,
crtc_mode->height, crtc_mode_info->height,
crtc_mode); crtc_mode);
mode->id = generate_mode_id (&mode->spec); mode->id = generate_mode_id (&mode->spec);
mode->crtc_modes = g_new (MetaMonitorCrtcMode, 1); 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 * otherwise take the first one in the list. This guarantees that the
* preferred mode is always added. * 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)) if (!meta_monitor_add_mode (monitor, mode, replace))
{ {
@ -940,9 +946,10 @@ is_crtc_mode_tiled (MetaOutput *output,
MetaCrtcMode *crtc_mode) MetaCrtcMode *crtc_mode)
{ {
const MetaOutputInfo *output_info = meta_output_get_info (output); 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 && return (crtc_mode_info->width == (int) output_info->tile_info.tile_w &&
crtc_mode->height == (int) output_info->tile_info.tile_h); crtc_mode_info->height == (int) output_info->tile_info.tile_h);
} }
static MetaCrtcMode * static MetaCrtcMode *
@ -950,6 +957,8 @@ find_tiled_crtc_mode (MetaOutput *output,
MetaCrtcMode *reference_crtc_mode) MetaCrtcMode *reference_crtc_mode)
{ {
const MetaOutputInfo *output_info = meta_output_get_info (output); 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; MetaCrtcMode *crtc_mode;
unsigned int i; unsigned int i;
@ -959,15 +968,18 @@ find_tiled_crtc_mode (MetaOutput *output,
for (i = 0; i < output_info->n_modes; i++) for (i = 0; i < output_info->n_modes; i++)
{ {
const MetaCrtcModeInfo *crtc_mode_info;
crtc_mode = output_info->modes[i]; crtc_mode = output_info->modes[i];
crtc_mode_info = meta_crtc_mode_get_info (crtc_mode);
if (!is_crtc_mode_tiled (output, crtc_mode)) if (!is_crtc_mode_tiled (output, crtc_mode))
continue; continue;
if (crtc_mode->refresh_rate != reference_crtc_mode->refresh_rate) if (crtc_mode_info->refresh_rate != reference_crtc_mode_info->refresh_rate)
continue; continue;
if (crtc_mode->flags != reference_crtc_mode->flags) if (crtc_mode_info->flags != reference_crtc_mode_info->flags)
continue; continue;
return crtc_mode; return crtc_mode;
@ -1100,6 +1112,7 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
MetaMonitorPrivate *monitor_priv = MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor); meta_monitor_get_instance_private (monitor);
MetaMonitorModeTiled *mode; MetaMonitorModeTiled *mode;
const MetaCrtcModeInfo *crtc_mode_info;
GList *l; GList *l;
int i; int i;
@ -1109,9 +1122,11 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
mode = g_new0 (MetaMonitorModeTiled, 1); mode = g_new0 (MetaMonitorModeTiled, 1);
mode->is_tiled = FALSE; mode->is_tiled = FALSE;
mode->parent.monitor = monitor; mode->parent.monitor = monitor;
crtc_mode_info = meta_crtc_mode_get_info (crtc_mode);
mode->parent.spec = meta_monitor_create_spec (monitor, mode->parent.spec = meta_monitor_create_spec (monitor,
crtc_mode->width, crtc_mode_info->width,
crtc_mode->height, crtc_mode_info->height,
crtc_mode); crtc_mode);
mode->parent.id = generate_mode_id (&mode->parent.spec); mode->parent.id = generate_mode_id (&mode->parent.spec);
mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode, mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode,

View File

@ -99,6 +99,7 @@ meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms,
{ {
MetaCrtc *crtc = META_CRTC (crtc_kms); MetaCrtc *crtc = META_CRTC (crtc_kms);
const MetaCrtcConfig *crtc_config; const MetaCrtcConfig *crtc_config;
const MetaCrtcModeInfo *crtc_mode_info;
MetaFixed16Rectangle src_rect; MetaFixed16Rectangle src_rect;
MetaFixed16Rectangle dst_rect; MetaFixed16Rectangle dst_rect;
MetaKmsAssignPlaneFlag flags; MetaKmsAssignPlaneFlag flags;
@ -108,18 +109,19 @@ meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms,
MetaKmsPlaneAssignment *plane_assignment; MetaKmsPlaneAssignment *plane_assignment;
crtc_config = meta_crtc_get_config (crtc); crtc_config = meta_crtc_get_config (crtc);
crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
src_rect = (MetaFixed16Rectangle) { src_rect = (MetaFixed16Rectangle) {
.x = meta_fixed_16_from_int (0), .x = meta_fixed_16_from_int (0),
.y = meta_fixed_16_from_int (0), .y = meta_fixed_16_from_int (0),
.width = meta_fixed_16_from_int (crtc_config->mode->width), .width = meta_fixed_16_from_int (crtc_mode_info->width),
.height = meta_fixed_16_from_int (crtc_config->mode->height), .height = meta_fixed_16_from_int (crtc_mode_info->height),
}; };
dst_rect = (MetaFixed16Rectangle) { dst_rect = (MetaFixed16Rectangle) {
.x = meta_fixed_16_from_int (0), .x = meta_fixed_16_from_int (0),
.y = meta_fixed_16_from_int (0), .y = meta_fixed_16_from_int (0),
.width = meta_fixed_16_from_int (crtc_config->mode->width), .width = meta_fixed_16_from_int (crtc_mode_info->width),
.height = meta_fixed_16_from_int (crtc_config->mode->height), .height = meta_fixed_16_from_int (crtc_mode_info->height),
}; };
flags = META_KMS_ASSIGN_PLANE_FLAG_NONE; flags = META_KMS_ASSIGN_PLANE_FLAG_NONE;

View File

@ -402,6 +402,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaCrtc *crtc; MetaCrtc *crtc;
MetaMonitorTransform transform; MetaMonitorTransform transform;
const MetaCrtcModeInfo *crtc_mode_info;
graphene_rect_t scaled_crtc_rect; graphene_rect_t scaled_crtc_rect;
float scale; float scale;
int crtc_x, crtc_y; int crtc_x, crtc_y;
@ -420,15 +421,17 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
transform, transform,
&crtc_x, &crtc_y); &crtc_x, &crtc_y);
crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode);
if (meta_monitor_transform_is_rotated (transform)) if (meta_monitor_transform_is_rotated (transform))
{ {
crtc_width = monitor_crtc_mode->crtc_mode->height; crtc_width = crtc_mode_info->height;
crtc_height = monitor_crtc_mode->crtc_mode->width; crtc_height = crtc_mode_info->width;
} }
else else
{ {
crtc_width = monitor_crtc_mode->crtc_mode->width; crtc_width = crtc_mode_info->width;
crtc_height = monitor_crtc_mode->crtc_mode->height; crtc_height = crtc_mode_info->height;
} }
scaled_crtc_rect = (graphene_rect_t) { scaled_crtc_rect = (graphene_rect_t) {
@ -479,8 +482,8 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
inverted_transform = meta_monitor_transform_invert (transform); inverted_transform = meta_monitor_transform_invert (transform);
meta_rectangle_transform (&cursor_rect, meta_rectangle_transform (&cursor_rect,
inverted_transform, inverted_transform,
monitor_crtc_mode->crtc_mode->width, crtc_mode_info->width,
monitor_crtc_mode->crtc_mode->height, crtc_mode_info->height,
&cursor_rect); &cursor_rect);
set_crtc_cursor (data->in_cursor_renderer_native, set_crtc_cursor (data->in_cursor_renderer_native,

View File

@ -343,15 +343,24 @@ static MetaCrtcMode *
create_mode (const drmModeModeInfo *drm_mode, create_mode (const drmModeModeInfo *drm_mode,
long mode_id) long mode_id)
{ {
g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
g_autofree char *crtc_mode_name = NULL;
MetaCrtcMode *mode; MetaCrtcMode *mode;
mode = g_object_new (META_TYPE_CRTC_MODE, NULL); crtc_mode_info = meta_crtc_mode_info_new ();
mode->mode_id = mode_id; crtc_mode_info->width = drm_mode->hdisplay;
mode->name = g_strndup (drm_mode->name, DRM_DISPLAY_MODE_LEN); crtc_mode_info->height = drm_mode->vdisplay;
mode->width = drm_mode->hdisplay; crtc_mode_info->flags = drm_mode->flags;
mode->height = drm_mode->vdisplay; crtc_mode_info->refresh_rate =
mode->flags = drm_mode->flags; meta_calculate_drm_mode_refresh_rate (drm_mode);
mode->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_private = g_slice_dup (drmModeModeInfo, drm_mode);
mode->driver_notify = (GDestroyNotify) meta_crtc_mode_destroy_notify; mode->driver_notify = (GDestroyNotify) meta_crtc_mode_destroy_notify;

View File

@ -66,12 +66,15 @@ meta_output_kms_set_underscan (MetaOutputKms *output_kms,
{ {
MetaCrtc *crtc; MetaCrtc *crtc;
const MetaCrtcConfig *crtc_config; const MetaCrtcConfig *crtc_config;
const MetaCrtcModeInfo *crtc_mode_info;
uint64_t hborder, vborder; uint64_t hborder, vborder;
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
crtc_config = meta_crtc_get_config (crtc); crtc_config = meta_crtc_get_config (crtc);
hborder = MIN (128, (uint64_t) round (crtc_config->mode->width * 0.05)); crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
vborder = MIN (128, (uint64_t) round (crtc_config->mode->height * 0.05));
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, g_debug ("Setting underscan of connector %s to %" G_GUINT64_FORMAT " x %" G_GUINT64_FORMAT,
meta_kms_connector_get_name (output_kms->kms_connector), meta_kms_connector_get_name (output_kms->kms_connector),
@ -207,17 +210,23 @@ static int
compare_modes (const void *one, compare_modes (const void *one,
const void *two) const void *two)
{ {
MetaCrtcMode *a = *(MetaCrtcMode **) one; MetaCrtcMode *crtc_mode_one = *(MetaCrtcMode **) one;
MetaCrtcMode *b = *(MetaCrtcMode **) two; 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) if (crtc_mode_info_one->width != crtc_mode_info_two->width)
return a->width > b->width ? -1 : 1; return crtc_mode_info_one->width > crtc_mode_info_two->width ? -1 : 1;
if (a->height != b->height) if (crtc_mode_info_one->height != crtc_mode_info_two->height)
return a->height > b->height ? -1 : 1; return crtc_mode_info_one->height > crtc_mode_info_two->height ? -1 : 1;
if (a->refresh_rate != b->refresh_rate) if (crtc_mode_info_one->refresh_rate != crtc_mode_info_two->refresh_rate)
return a->refresh_rate > b->refresh_rate ? -1 : 1; 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 static gboolean

View File

@ -1112,6 +1112,30 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
swap_secondary_drm_fb (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 static void
notify_view_crtc_presented (MetaRendererView *view, notify_view_crtc_presented (MetaRendererView *view,
MetaKmsCrtc *kms_crtc, MetaKmsCrtc *kms_crtc,
@ -1127,8 +1151,6 @@ notify_view_crtc_presented (MetaRendererView *view,
MetaGpuKms *render_gpu = onscreen_native->render_gpu; MetaGpuKms *render_gpu = onscreen_native->render_gpu;
CoglFrameInfo *frame_info; CoglFrameInfo *frame_info;
MetaCrtc *crtc; MetaCrtc *crtc;
const MetaCrtcConfig *crtc_config;
float refresh_rate;
MetaGpuKms *gpu_kms; MetaGpuKms *gpu_kms;
/* Only keep the frame info for the fastest CRTC in use, which may not be /* 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); frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
crtc = META_CRTC (meta_crtc_kms_from_kms_crtc (kms_crtc)); crtc = META_CRTC (meta_crtc_kms_from_kms_crtc (kms_crtc));
crtc_config = crtc ? meta_crtc_get_config (crtc) : NULL; maybe_update_frame_info (crtc, frame_info, time_ns);
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;
}
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
if (gpu_kms != render_gpu) if (gpu_kms != render_gpu)
@ -3161,6 +3177,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
CoglDisplayEGL *cogl_display_egl; CoglDisplayEGL *cogl_display_egl;
CoglOnscreenEGL *onscreen_egl; CoglOnscreenEGL *onscreen_egl;
const MetaCrtcConfig *crtc_config; const MetaCrtcConfig *crtc_config;
const MetaCrtcModeInfo *crtc_mode_info;
MetaMonitorTransform view_transform; MetaMonitorTransform view_transform;
CoglOnscreen *onscreen = NULL; CoglOnscreen *onscreen = NULL;
CoglOffscreen *offscreen = NULL; CoglOffscreen *offscreen = NULL;
@ -3173,8 +3190,9 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
GError *error = NULL; GError *error = NULL;
crtc_config = meta_crtc_get_config (crtc); crtc_config = meta_crtc_get_config (crtc);
onscreen_width = crtc_config->mode->width; crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
onscreen_height = crtc_config->mode->height; onscreen_width = crtc_mode_info->width;
onscreen_height = crtc_mode_info->height;
onscreen = meta_renderer_native_create_onscreen (renderer_native, onscreen = meta_renderer_native_create_onscreen (renderer_native,
renderer_native->primary_gpu_kms, renderer_native->primary_gpu_kms,

View File

@ -141,18 +141,23 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
for (i = 0; i < (unsigned)resources->nmode; i++) for (i = 0; i < (unsigned)resources->nmode; i++)
{ {
XRRModeInfo *xmode = &resources->modes[i]; XRRModeInfo *xmode = &resources->modes[i];
g_autofree char *crtc_mode_name = NULL;
MetaCrtcMode *mode; 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 = xmode->width;
mode->mode_id = xmode->id; crtc_mode_info->height = xmode->height;
mode->width = xmode->width; crtc_mode_info->refresh_rate = (xmode->dotClock /
mode->height = xmode->height; ((float)xmode->hTotal * xmode->vTotal));
mode->refresh_rate = (xmode->dotClock / crtc_mode_info->flags = xmode->modeFlags;
((float)xmode->hTotal * xmode->vTotal));
mode->flags = xmode->modeFlags;
mode->name = get_xmode_name (xmode);
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); modes = g_list_append (modes, mode);
} }
meta_gpu_take_modes (gpu, modes); meta_gpu_take_modes (gpu, modes);

View File

@ -475,14 +475,15 @@ apply_crtc_assignments (MetaMonitorManager *manager,
if (crtc_assignment->mode != NULL) if (crtc_assignment->mode != NULL)
{ {
MetaCrtcMode *mode; MetaCrtcMode *crtc_mode;
g_autofree xcb_randr_output_t *output_ids = NULL; g_autofree xcb_randr_output_t *output_ids = NULL;
unsigned int j, n_output_ids; unsigned int j, n_output_ids;
xcb_randr_crtc_t crtc_id; xcb_randr_crtc_t crtc_id;
int x, y; int x, y;
xcb_randr_rotation_t rotation; 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; n_output_ids = crtc_assignment->outputs->len;
output_ids = g_new (xcb_randr_output_t, n_output_ids); 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); y = (int) roundf (crtc_assignment->layout.origin.y);
rotation = rotation =
meta_monitor_transform_to_xrandr (crtc_assignment->transform); meta_monitor_transform_to_xrandr (crtc_assignment->transform);
mode = meta_crtc_mode_get_id (crtc_mode);
if (!xrandr_set_crtc_config (manager_xrandr, if (!xrandr_set_crtc_config (manager_xrandr,
crtc, crtc,
save_timestamp, save_timestamp,
crtc_id, crtc_id,
XCB_CURRENT_TIME, XCB_CURRENT_TIME,
x, y, x, y,
(xcb_randr_mode_t) mode->mode_id, mode,
rotation, rotation,
output_ids, n_output_ids)) 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", 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) meta_crtc_get_id (crtc),
(unsigned) mode->mode_id, (unsigned) mode,
mode->width, mode->height, (float)mode->refresh_rate, 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.x),
(int) roundf (crtc_assignment->layout.origin.y), (int) roundf (crtc_assignment->layout.origin.y),
crtc_assignment->transform); crtc_assignment->transform);
@ -532,7 +538,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
meta_crtc_set_config (crtc, meta_crtc_set_config (crtc,
&crtc_assignment->layout, &crtc_assignment->layout,
mode, crtc_mode,
crtc_assignment->transform); crtc_assignment->transform);
} }
} }

View File

@ -114,13 +114,15 @@ output_set_underscanning_xrandr (MetaOutput *output,
{ {
MetaCrtc *crtc; MetaCrtc *crtc;
const MetaCrtcConfig *crtc_config; const MetaCrtcConfig *crtc_config;
const MetaCrtcModeInfo *crtc_mode_info;
uint32_t border_value; uint32_t border_value;
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
crtc_config = meta_crtc_get_config (crtc); crtc_config = meta_crtc_get_config (crtc);
crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode);
prop = XInternAtom (xdisplay, "underscan hborder", False); 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), xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
(XID) meta_output_get_id (output), (XID) meta_output_get_id (output),
@ -129,7 +131,7 @@ output_set_underscanning_xrandr (MetaOutput *output,
1, &border_value); 1, &border_value);
prop = XInternAtom (xdisplay, "underscan vborder", False); 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), xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
(XID) meta_output_get_id (output), (XID) meta_output_get_id (output),
@ -736,7 +738,7 @@ output_info_init_modes (MetaOutputInfo *output_info,
{ {
MetaCrtcMode *mode = l->data; 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; output_info->modes[n_actual_modes] = mode;
n_actual_modes += 1; n_actual_modes += 1;

View File

@ -119,6 +119,7 @@ meta_test_headless_monitor_connect (void)
META_MONITOR_MANAGER_TEST (monitor_manager); META_MONITOR_MANAGER_TEST (monitor_manager);
MetaMonitorTestSetup *test_setup; MetaMonitorTestSetup *test_setup;
MetaCrtcMode **modes; MetaCrtcMode **modes;
g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
MetaCrtcMode *crtc_mode; MetaCrtcMode *crtc_mode;
MetaGpu *gpu; MetaGpu *gpu;
MetaCrtc *crtc; MetaCrtc *crtc;
@ -130,11 +131,15 @@ meta_test_headless_monitor_connect (void)
test_setup = g_new0 (MetaMonitorTestSetup, 1); test_setup = g_new0 (MetaMonitorTestSetup, 1);
crtc_mode = g_object_new (META_TYPE_CRTC_MODE, NULL); crtc_mode_info = meta_crtc_mode_info_new ();
crtc_mode->mode_id = 1; crtc_mode_info->width = 1024;
crtc_mode->width = 1024; crtc_mode_info->height = 768;
crtc_mode->height = 768; crtc_mode_info->refresh_rate = 60.0;
crtc_mode->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); test_setup->modes = g_list_append (NULL, crtc_mode);
gpu = META_GPU (meta_backend_get_gpus (meta_get_backend ())->data); gpu = META_GPU (meta_backend_get_gpus (meta_get_backend ())->data);

View File

@ -148,14 +148,17 @@ check_monitor_mode (MetaMonitor *monitor,
if (crtc_mode) if (crtc_mode)
{ {
const MetaCrtcModeInfo *crtc_mode_info =
meta_crtc_mode_get_info (crtc_mode);
float refresh_rate; float refresh_rate;
MetaCrtcModeFlag flags; MetaCrtcModeFlag flags;
refresh_rate = meta_monitor_mode_get_refresh_rate (mode); refresh_rate = meta_monitor_mode_get_refresh_rate (mode);
flags = meta_monitor_mode_get_flags (mode); flags = meta_monitor_mode_get_flags (mode);
g_assert_cmpfloat (refresh_rate, ==, crtc_mode->refresh_rate); g_assert_cmpfloat (refresh_rate, ==, crtc_mode_info->refresh_rate);
g_assert_cmpint (flags, ==, (crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS)); g_assert_cmpint (flags, ==, (crtc_mode_info->flags &
HANDLED_CRTC_MODE_FLAGS));
} }
data->expect_crtc_mode_iter++; data->expect_crtc_mode_iter++;
@ -543,14 +546,19 @@ create_monitor_test_setup (MonitorTestCaseSetup *setup,
test_setup->modes = NULL; test_setup->modes = NULL;
for (i = 0; i < setup->n_modes; i++) for (i = 0; i < setup->n_modes; i++)
{ {
g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL;
MetaCrtcMode *mode; MetaCrtcMode *mode;
mode = g_object_new (META_TYPE_CRTC_MODE, NULL); crtc_mode_info = meta_crtc_mode_info_new ();
mode->mode_id = i; crtc_mode_info->width = setup->modes[i].width;
mode->width = setup->modes[i].width; crtc_mode_info->height = setup->modes[i].height;
mode->height = setup->modes[i].height; crtc_mode_info->refresh_rate = setup->modes[i].refresh_rate;
mode->refresh_rate = setup->modes[i].refresh_rate; crtc_mode_info->flags = setup->modes[i].flags;
mode->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); test_setup->modes = g_list_append (test_setup->modes, mode);
} }