Commit 2db55052 authored by Jonas Ådahl's avatar Jonas Ådahl
Browse files

monitor-manager: Turn MetaCrtcMode into a GObject

Convert MetaCrtcMode from a plain struct to a GObject. This changes the
storage format, and also the API, as the API was dependent on the
storage format.

https://bugzilla.gnome.org/show_bug.cgi?id=785381
parent f44b6c77
......@@ -23,6 +23,8 @@
G_DEFINE_TYPE (MetaCrtc, meta_crtc, G_TYPE_OBJECT)
G_DEFINE_TYPE (MetaCrtcMode, meta_crtc_mode, G_TYPE_OBJECT)
static void
meta_crtc_finalize (GObject *object)
{
......@@ -46,3 +48,27 @@ meta_crtc_class_init (MetaCrtcClass *klass)
object_class->finalize = meta_crtc_finalize;
}
static void
meta_crtc_mode_finalize (GObject *object)
{
MetaCrtcMode *crtc_mode = META_CRTC_MODE (object);
if (crtc_mode->driver_notify)
crtc_mode->driver_notify (crtc_mode);
G_OBJECT_CLASS (meta_crtc_mode_parent_class)->finalize (object);
}
static void
meta_crtc_mode_init (MetaCrtcMode *crtc_mode)
{
}
static void
meta_crtc_mode_class_init (MetaCrtcModeClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_crtc_mode_finalize;
}
......@@ -70,6 +70,8 @@ struct _MetaCrtc
struct _MetaCrtcMode
{
GObject parent;
/* The low-level ID of this mode, used to apply back configuration */
glong mode_id;
char *name;
......@@ -86,4 +88,7 @@ struct _MetaCrtcMode
#define META_TYPE_CRTC (meta_crtc_get_type ())
G_DECLARE_FINAL_TYPE (MetaCrtc, meta_crtc, META, CRTC, GObject)
#define META_TYPE_CRTC_MODE (meta_crtc_mode_get_type ())
G_DECLARE_FINAL_TYPE (MetaCrtcMode, meta_crtc_mode, META, CRTC_MODE, GObject)
#endif /* META_CRTC_H */
......@@ -65,16 +65,36 @@ G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MO
static void
meta_output_dummy_notify_destroy (MetaOutput *output);
#define array_last(a, t) \
g_array_index (a, t, a->len - 1)
typedef struct _CrtcModeSpec
{
int width;
int height;
float refresh_rate;
} CrtcModeSpec;
static MetaCrtcMode *
create_mode (CrtcModeSpec *spec,
long mode_id)
{
MetaCrtcMode *mode;
mode = g_object_new (META_TYPE_CRTC_MODE, NULL);
mode->mode_id = mode_id;
mode->width = spec->width;
mode->height = spec->height;
mode->refresh_rate = spec->refresh_rate;
return mode;
}
static void
append_monitor (GArray *modes,
append_monitor (GList **modes,
GList **crtcs,
GList **outputs,
float scale)
{
MetaCrtcMode modes_decl[] = {
CrtcModeSpec mode_specs[] = {
{
.width = 800,
.height = 600,
......@@ -86,15 +106,25 @@ append_monitor (GArray *modes,
.refresh_rate = 60.0
}
};
GList *new_modes = NULL;
MetaCrtc *crtc;
MetaOutputDummy *output_dummy;
MetaOutput *output;
unsigned int i;
unsigned int number;
GList *l;
for (i = 0; i < G_N_ELEMENTS (mode_specs); i++)
{
long mode_id;
MetaCrtcMode *mode;
for (i = 0; i < G_N_ELEMENTS (modes_decl); i++)
modes_decl[i].mode_id = modes->len + i;
g_array_append_vals (modes, modes_decl, G_N_ELEMENTS (modes_decl));
mode_id = g_list_length (*modes) + i + 1;
mode = create_mode (&mode_specs[i], mode_id);
new_modes = g_list_append (new_modes, mode);
}
*modes = g_list_concat (*modes, new_modes);
crtc = g_object_new (META_TYPE_CRTC, NULL);
crtc->crtc_id = g_list_length (*crtcs) + 1;
......@@ -120,7 +150,7 @@ append_monitor (GArray *modes,
output->width_mm = 222;
output->height_mm = 125;
output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
output->preferred_mode = &array_last (modes, MetaCrtcMode);
output->preferred_mode = g_list_last (*modes)->data;
output->n_possible_clones = 0;
output->backlight = -1;
output->connector_type = META_CONNECTOR_TYPE_LVDS;
......@@ -128,11 +158,14 @@ append_monitor (GArray *modes,
output->driver_notify =
(GDestroyNotify) meta_output_dummy_notify_destroy;
output->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (modes_decl));
for (i = 0; i < G_N_ELEMENTS (modes_decl); i++)
output->modes[i] = &g_array_index (modes, MetaCrtcMode,
modes->len - (i + 1));
output->n_modes = G_N_ELEMENTS (modes_decl);
output->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs));
for (l = new_modes, i = 0; l; l = l->next, i++)
{
MetaCrtcMode *mode = l->data;
output->modes[i] = mode;
}
output->n_modes = G_N_ELEMENTS (mode_specs);
output->possible_crtcs = g_new0 (MetaCrtc *, 1);
output->possible_crtcs[0] = g_list_last (*crtcs)->data;
output->n_possible_crtcs = 1;
......@@ -141,12 +174,12 @@ append_monitor (GArray *modes,
}
static void
append_tiled_monitor (GArray *modes,
append_tiled_monitor (GList **modes,
GList **crtcs,
GList **outputs,
int scale)
{
MetaCrtcMode modes_decl[] = {
CrtcModeSpec mode_specs[] = {
{
.width = 800,
.height = 600,
......@@ -159,14 +192,23 @@ append_tiled_monitor (GArray *modes,
}
};
unsigned int n_tiles = 2;
GList *new_modes = NULL;
GList *new_crtcs = NULL;
MetaOutput *output;
unsigned int i;
uint32_t tile_group_id;
for (i = 0; i < G_N_ELEMENTS (modes_decl); i++)
modes_decl[i].mode_id = modes->len + i;
g_array_append_vals (modes, modes_decl, G_N_ELEMENTS (modes_decl));
for (i = 0; i < G_N_ELEMENTS (mode_specs); i++)
{
long mode_id;
MetaCrtcMode *mode;
mode_id = g_list_length (*modes) + i + 1;
mode = create_mode (&mode_specs[i], mode_id);
new_modes = g_list_append (new_modes, mode);
}
*modes = g_list_concat (*modes, new_modes);
for (i = 0; i < n_tiles; i++)
{
......@@ -196,7 +238,7 @@ append_tiled_monitor (GArray *modes,
/* Arbitrary ID unique for this output */
number = g_list_length (*outputs) + 1;
preferred_mode = &array_last (modes, MetaCrtcMode);
preferred_mode = g_list_last (*modes)->data;
output = g_object_new (META_TYPE_OUTPUT, NULL);
......@@ -227,11 +269,14 @@ append_tiled_monitor (GArray *modes,
output->driver_notify =
(GDestroyNotify) meta_output_dummy_notify_destroy;
output->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (modes_decl));
for (j = 0; j < G_N_ELEMENTS (modes_decl); j++)
output->modes[j] = &g_array_index (modes, MetaCrtcMode,
modes->len - (j + 1));
output->n_modes = G_N_ELEMENTS (modes_decl);
output->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs));
for (l = new_modes, j = 0; l; l = l->next, j++)
{
MetaCrtcMode *mode = l->data;
output->modes[j] = mode;
}
output->n_modes = G_N_ELEMENTS (mode_specs);
output->possible_crtcs = g_new0 (MetaCrtc *, n_tiles);
for (l = new_crtcs, j = 0; l; l = l->next, j++)
......@@ -264,7 +309,7 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
unsigned int i;
GList *outputs;
GList *crtcs;
GArray *modes;
GList *modes;
/* To control what monitor configuration is generated, there are two available
* environmental variables that can be used:
......@@ -333,24 +378,21 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
tiled_monitors_str = g_getenv ("MUTTER_DEBUG_TILED_DUMMY_MONITORS");
tiled_monitors = g_strcmp0 (tiled_monitors_str, "1") == 0;
modes = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtcMode), MAX_MODES);
modes = NULL;
crtcs = NULL;
outputs = NULL;
for (i = 0; i < num_monitors; i++)
{
if (tiled_monitors)
append_tiled_monitor (modes, &crtcs, &outputs, monitor_scales[i]);
append_tiled_monitor (&modes, &crtcs, &outputs, monitor_scales[i]);
else
append_monitor (modes, &crtcs, &outputs, monitor_scales[i]);
append_monitor (&modes, &crtcs, &outputs, monitor_scales[i]);
}
manager->modes = (MetaCrtcMode *) modes->data;
manager->n_modes = modes->len;
manager->modes = modes;
manager->crtcs = crtcs;
manager->outputs = outputs;
g_array_free (modes, FALSE);
}
static void
......
......@@ -169,9 +169,7 @@ struct _MetaMonitorManager
*/
GList *outputs;
GList *crtcs;
MetaCrtcMode *modes;
unsigned int n_modes;
GList *modes;
GList *monitors;
......
......@@ -720,36 +720,13 @@ meta_monitor_manager_constructed (GObject *object)
manager->in_init = FALSE;
}
void
meta_monitor_manager_clear_mode (MetaCrtcMode *mode)
{
g_free (mode->name);
if (mode->driver_notify)
mode->driver_notify (mode);
memset (mode, 0, sizeof (*mode));
}
static void
meta_monitor_manager_free_mode_array (MetaCrtcMode *old_modes,
int n_old_modes)
{
int i;
for (i = 0; i < n_old_modes; i++)
meta_monitor_manager_clear_mode (&old_modes[i]);
g_free (old_modes);
}
static void
meta_monitor_manager_finalize (GObject *object)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
g_list_free_full (manager->outputs, g_object_unref);
meta_monitor_manager_free_mode_array (manager->modes, manager->n_modes);
g_list_free_full (manager->modes, g_object_unref);
g_list_free_full (manager->crtcs, g_object_unref);
g_list_free_full (manager->logical_monitors, g_object_unref);
......@@ -930,12 +907,17 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
{
MetaCrtc *crtc = l->data;
GVariantBuilder transforms;
int current_mode_index;
g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
if (crtc->all_transforms & (1 << j))
g_variant_builder_add (&transforms, "u", j);
if (crtc->current_mode)
current_mode_index = g_list_index (manager->modes, crtc->current_mode);
else
current_mode_index = -1;
g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
i, /* ID */
(gint64)crtc->crtc_id,
......@@ -943,7 +925,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
(int)crtc->rect.y,
(int)crtc->rect.width,
(int)crtc->rect.height,
(int)(crtc->current_mode ? crtc->current_mode - manager->modes : -1),
current_mode_index,
(guint32)crtc->transform,
&transforms,
NULL /* properties */);
......@@ -969,8 +951,12 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_variant_builder_init (&modes, G_VARIANT_TYPE ("au"));
for (j = 0; j < output->n_modes; j++)
g_variant_builder_add (&modes, "u",
(unsigned)(output->modes[j] - manager->modes));
{
unsigned mode_index;
mode_index = g_list_index (manager->modes, output->modes[j]);
g_variant_builder_add (&modes, "u", mode_index);
}
g_variant_builder_init (&clones, G_VARIANT_TYPE ("au"));
for (j = 0; j < output->n_possible_clones; j++)
......@@ -1057,9 +1043,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
&properties);
}
for (i = 0; i < manager->n_modes; i++)
for (l = manager->modes, i = 0; l; l = l->next, i++)
{
MetaCrtcMode *mode = &manager->modes[i];
MetaCrtcMode *mode = l->data;
g_variant_builder_add (&mode_builder, "(uxuudu)",
i, /* ID */
......@@ -2489,8 +2475,7 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
{
GList *old_outputs;
GList *old_crtcs;
MetaCrtcMode *old_modes;
unsigned int n_old_modes;
GList *old_modes;
/* Some implementations of read_current use the existing information
* we have available, so don't free the old configuration until after
......@@ -2498,7 +2483,6 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
old_outputs = manager->outputs;
old_crtcs = manager->crtcs;
old_modes = manager->modes;
n_old_modes = manager->n_modes;
manager->serial++;
META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
......@@ -2506,7 +2490,7 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
rebuild_monitors (manager);
g_list_free_full (old_outputs, g_object_unref);
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
g_list_free_full (old_modes, g_object_unref);
g_list_free_full (old_crtcs, g_object_unref);
}
......
......@@ -409,12 +409,14 @@ static MetaCrtcMode *
mode_from_drm_mode (MetaMonitorManager *manager,
const drmModeModeInfo *drm_mode)
{
unsigned k;
GList *l;
for (k = 0; k < manager->n_modes; k++)
for (l = manager->modes; l; l = l->next)
{
if (drm_mode_equal (drm_mode, manager->modes[k].driver_private))
return &manager->modes[k];
MetaCrtcMode *mode = l->data;
if (drm_mode_equal (drm_mode, mode->driver_private))
return mode;
}
g_assert_not_reached ();
......@@ -439,11 +441,13 @@ drm_mode_vrefresh (const drmModeModeInfo *mode)
return refresh;
}
static void
init_mode (MetaCrtcMode *mode,
const drmModeModeInfo *drm_mode,
long mode_id)
static MetaCrtcMode *
create_mode (const drmModeModeInfo *drm_mode,
long mode_id)
{
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;
......@@ -452,6 +456,8 @@ init_mode (MetaCrtcMode *mode,
mode->refresh_rate = drm_mode_vrefresh (drm_mode);
mode->driver_private = g_slice_dup (drmModeModeInfo, drm_mode);
mode->driver_notify = (GDestroyNotify)meta_monitor_mode_destroy_notify;
return mode;
}
static int
......@@ -669,7 +675,6 @@ create_crtc (MetaMonitorManager *manager,
drmModeCrtc *drm_crtc)
{
MetaCrtc *crtc;
unsigned int i;
crtc = g_object_new (META_TYPE_CRTC, NULL);
......@@ -685,11 +690,15 @@ create_crtc (MetaMonitorManager *manager,
if (drm_crtc->mode_valid)
{
for (i = 0; i < manager->n_modes; i++)
GList *l;
for (l = manager->modes; l; l = l->next)
{
if (drm_mode_equal (&drm_crtc->mode, manager->modes[i].driver_private))
MetaCrtcMode *mode = l->data;
if (drm_mode_equal (&drm_crtc->mode, mode->driver_private))
{
crtc->current_mode = &manager->modes[i];
crtc->current_mode = mode;
break;
}
}
......@@ -1015,8 +1024,7 @@ init_modes (MetaMonitorManager *manager,
}
}
manager->n_modes = g_hash_table_size (modes) + G_N_ELEMENTS (meta_default_drm_mode_infos);
manager->modes = g_new0 (MetaCrtcMode, manager->n_modes);
manager->modes = NULL;
g_hash_table_iter_init (&iter, modes);
mode_id = 0;
......@@ -1024,8 +1032,8 @@ init_modes (MetaMonitorManager *manager,
{
MetaCrtcMode *mode;
mode = &manager->modes[mode_id];
init_mode (mode, drm_mode, (long) mode_id);
mode = create_mode (drm_mode, (long) mode_id);
manager->modes = g_list_append (manager->modes, mode);
mode_id++;
}
......@@ -1036,8 +1044,8 @@ init_modes (MetaMonitorManager *manager,
{
MetaCrtcMode *mode;
mode = &manager->modes[mode_id];
init_mode (mode, &meta_default_drm_mode_infos[i], (long) mode_id);
mode = create_mode (&meta_default_drm_mode_infos[i], (long) mode_id);
manager->modes = g_list_append (manager->modes, mode);
mode_id++;
}
......
......@@ -659,7 +659,7 @@ output_get_modes (MetaMonitorManager *manager,
MetaOutput *output,
XRROutputInfo *xrandr_output)
{
guint j, k;
guint j;
guint n_actual_modes;
output->modes = g_new0 (MetaCrtcMode *, xrandr_output->nmode);
......@@ -667,11 +667,15 @@ output_get_modes (MetaMonitorManager *manager,
n_actual_modes = 0;
for (j = 0; j < (guint)xrandr_output->nmode; j++)
{
for (k = 0; k < manager->n_modes; k++)
GList *l;
for (l = manager->modes; l; l = l->next)
{
if (xrandr_output->modes[j] == (XID)manager->modes[k].mode_id)
MetaCrtcMode *mode = l->data;
if (xrandr_output->modes[j] == (XID) mode->mode_id)
{
output->modes[n_actual_modes] = &manager->modes[k];
output->modes[n_actual_modes] = mode;
n_actual_modes += 1;
break;
}
......@@ -797,9 +801,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
return;
manager_xrandr->resources = resources;
manager->n_modes = resources->nmode;
manager->outputs = NULL;
manager->modes = g_new0 (MetaCrtcMode, manager->n_modes);
manager->modes = NULL;
manager->crtcs = NULL;
for (i = 0; i < (unsigned)resources->nmode; i++)
......@@ -807,7 +810,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
XRRModeInfo *xmode = &resources->modes[i];
MetaCrtcMode *mode;
mode = &manager->modes[i];
mode = g_object_new (META_TYPE_CRTC_MODE, NULL);
mode->mode_id = xmode->id;
mode->width = xmode->width;
......@@ -816,6 +819,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
((float)xmode->hTotal * xmode->vTotal));
mode->flags = xmode->modeFlags;
mode->name = get_xmode_name (xmode);
manager->modes = g_list_append (manager->modes, mode);
}
for (i = 0; i < (unsigned)resources->ncrtc; i++)
......@@ -843,7 +848,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
{
if (resources->modes[j].id == xrandr_crtc->mode)
{
crtc->current_mode = &manager->modes[j];
crtc->current_mode = g_list_nth_data (manager->modes, j);
break;
}
}
......
......@@ -58,9 +58,7 @@ meta_test_headless_start (void)
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
g_assert_cmpint ((int) monitor_manager->n_modes,
==,
0);
g_assert_null (monitor_manager->modes);
g_assert_null (monitor_manager->outputs);
g_assert_null (monitor_manager->crtcs);
g_assert_null (monitor_manager->monitors);
......@@ -99,6 +97,7 @@ meta_test_headless_monitor_connect (void)
META_MONITOR_MANAGER_TEST (monitor_manager);
MetaMonitorTestSetup *test_setup;
MetaCrtcMode **modes;
MetaCrtcMode *crtc_mode;
MetaCrtc *crtc;
MetaCrtc **possible_crtcs;
MetaOutput *output;
......@@ -106,14 +105,13 @@ meta_test_headless_monitor_connect (void)
ClutterActor *stage;
test_setup = g_new0 (MetaMonitorTestSetup, 1);
test_setup->n_modes = 1;
test_setup->modes = g_new0 (MetaCrtcMode, test_setup->n_modes);
test_setup->modes[0] = (MetaCrtcMode) {
.mode_id = 1,
.width = 1024,
.height = 768,
.refresh_rate = 60.0
};
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;
test_setup->modes = g_list_append (NULL, crtc_mode);
crtc = g_object_new (META_TYPE_CRTC, NULL);
crtc->crtc_id = 1;
......@@ -121,7 +119,7 @@ meta_test_headless_monitor_connect (void)
test_setup->crtcs = g_list_append (NULL, crtc);
modes = g_new0 (MetaCrtcMode *, 1);
modes[0] = &test_setup->modes[0];
modes[0] = crtc_mode;
possible_crtcs = g_new0 (MetaCrtc *, 1);
possible_crtcs[0] = g_list_first (test_setup->crtcs)->data;