Commit f64fab1d authored by Jonas Ådahl's avatar Jonas Ådahl
Browse files

monitor-manager: Make MetaCrtc a GObject

Turn MetaCrtc into a GObject and move it to a separate file. This
changes the storage format, resulting in changing the API for accessing
MetaCrtcs from using an array, to using a GList.

https://bugzilla.gnome.org/show_bug.cgi?id=785381
parent 39bc2e03
......@@ -97,6 +97,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/meta-backend-private.h \
backends/meta-barrier.c \
backends/meta-barrier-private.h \
backends/meta-crtc.c \
backends/meta-crtc.h \
backends/meta-cursor.c \
backends/meta-cursor.h \
backends/meta-cursor-tracker.c \
......
/*
* Copyright (C) 2017 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "config.h"
#include "backends/meta-crtc.h"
G_DEFINE_TYPE (MetaCrtc, meta_crtc, G_TYPE_OBJECT)
static void
meta_crtc_finalize (GObject *object)
{
MetaCrtc *crtc = META_CRTC (object);
if (crtc->driver_notify)
crtc->driver_notify (crtc);
G_OBJECT_CLASS (meta_crtc_parent_class)->finalize (object);
}
static void
meta_crtc_init (MetaCrtc *crtc)
{
}
static void
meta_crtc_class_init (MetaCrtcClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_crtc_finalize;
}
/*
* Copyright (C) 2017 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_CRTC_H
#define META_CRTC_H
#include <glib-object.h>
#include "backends/meta-monitor-manager-private.h"
/* Same as KMS mode flags and X11 randr flags */
typedef enum _MetaCrtcModeFlag
{
META_CRTC_MODE_FLAG_NONE = 0,
META_CRTC_MODE_FLAG_PHSYNC = (1 << 0),
META_CRTC_MODE_FLAG_NHSYNC = (1 << 1),
META_CRTC_MODE_FLAG_PVSYNC = (1 << 2),
META_CRTC_MODE_FLAG_NVSYNC = (1 << 3),
META_CRTC_MODE_FLAG_INTERLACE = (1 << 4),
META_CRTC_MODE_FLAG_DBLSCAN = (1 << 5),
META_CRTC_MODE_FLAG_CSYNC = (1 << 6),
META_CRTC_MODE_FLAG_PCSYNC = (1 << 7),
META_CRTC_MODE_FLAG_NCSYNC = (1 << 8),
META_CRTC_MODE_FLAG_HSKEW = (1 << 9),
META_CRTC_MODE_FLAG_BCAST = (1 << 10),
META_CRTC_MODE_FLAG_PIXMUX = (1 << 11),
META_CRTC_MODE_FLAG_DBLCLK = (1 << 12),
META_CRTC_MODE_FLAG_CLKDIV2 = (1 << 13),
META_CRTC_MODE_FLAG_MASK = 0x3fff
} MetaCrtcModeFlag;
struct _MetaCrtc
{
GObject parent;
glong crtc_id;
MetaRectangle rect;
MetaCrtcMode *current_mode;
MetaMonitorTransform transform;
unsigned int all_transforms;
MetaLogicalMonitor *logical_monitor;
/* Used when changing configuration */
gboolean is_dirty;
/* Used by cursor renderer backend */
void *cursor_renderer_private;
gpointer driver_private;
GDestroyNotify driver_notify;
};
struct _MetaCrtcMode
{
/* The low-level ID of this mode, used to apply back configuration */
glong mode_id;
char *name;
int width;
int height;
float refresh_rate;
MetaCrtcModeFlag flags;
gpointer driver_private;
GDestroyNotify driver_notify;
};
#define META_TYPE_CRTC (meta_crtc_get_type ())
G_DECLARE_FINAL_TYPE (MetaCrtc, meta_crtc, META, CRTC, GObject)
#endif /* META_CRTC_H */
......@@ -24,6 +24,7 @@
#include "backends/meta-logical-monitor.h"
#include "backends/meta-backend-private.h"
#include "backends/meta-crtc.h"
#include "backends/meta-output.h"
G_DEFINE_TYPE (MetaLogicalMonitor, meta_logical_monitor, G_TYPE_OBJECT)
......
......@@ -31,6 +31,7 @@
#include <meta/util.h>
#include "backends/meta-backend-private.h"
#include "backends/meta-crtc.h"
#include "backends/meta-monitor.h"
#include "backends/meta-monitor-config-manager.h"
#include "backends/meta-output.h"
......@@ -69,7 +70,7 @@ meta_output_dummy_notify_destroy (MetaOutput *output);
static void
append_monitor (GArray *modes,
GArray *crtcs,
GList **crtcs,
GList **outputs,
float scale)
{
......@@ -85,7 +86,7 @@ append_monitor (GArray *modes,
.refresh_rate = 60.0
}
};
MetaCrtc crtc;
MetaCrtc *crtc;
MetaOutputDummy *output_dummy;
MetaOutput *output;
unsigned int i;
......@@ -95,11 +96,10 @@ append_monitor (GArray *modes,
modes_decl[i].mode_id = modes->len + i;
g_array_append_vals (modes, modes_decl, G_N_ELEMENTS (modes_decl));
crtc = (MetaCrtc) {
.crtc_id = crtcs->len + 1,
.all_transforms = ALL_TRANSFORMS,
};
g_array_append_val (crtcs, crtc);
crtc = g_object_new (META_TYPE_CRTC, NULL);
crtc->crtc_id = g_list_length (*crtcs) + 1;
crtc->all_transforms = ALL_TRANSFORMS;
*crtcs = g_list_append (*crtcs, crtc);
output = g_object_new (META_TYPE_OUTPUT, NULL);
......@@ -134,7 +134,7 @@ append_monitor (GArray *modes,
modes->len - (i + 1));
output->n_modes = G_N_ELEMENTS (modes_decl);
output->possible_crtcs = g_new0 (MetaCrtc *, 1);
output->possible_crtcs[0] = &array_last (crtcs, MetaCrtc);
output->possible_crtcs[0] = g_list_last (*crtcs)->data;
output->n_possible_crtcs = 1;
*outputs = g_list_append (*outputs, output);
......@@ -142,7 +142,7 @@ append_monitor (GArray *modes,
static void
append_tiled_monitor (GArray *modes,
GArray *crtcs,
GList **crtcs,
GList **outputs,
int scale)
{
......@@ -159,6 +159,7 @@ append_tiled_monitor (GArray *modes,
}
};
unsigned int n_tiles = 2;
GList *new_crtcs = NULL;
MetaOutput *output;
unsigned int i;
uint32_t tile_group_id;
......@@ -169,13 +170,14 @@ append_tiled_monitor (GArray *modes,
for (i = 0; i < n_tiles; i++)
{
MetaCrtc crtc = {
.crtc_id = crtcs->len + i + 1,
.all_transforms = ALL_TRANSFORMS
};
MetaCrtc *crtc;
g_array_append_val (crtcs, crtc);
crtc = g_object_new (META_TYPE_CRTC, NULL);
crtc->crtc_id = g_list_length (*crtcs) + i + 1;
crtc->all_transforms = ALL_TRANSFORMS;
new_crtcs = g_list_append (new_crtcs, crtc);
}
*crtcs = g_list_concat (*crtcs, new_crtcs);
tile_group_id = g_list_length (*outputs) + 1;
for (i = 0; i < n_tiles; i++)
......@@ -184,6 +186,7 @@ append_tiled_monitor (GArray *modes,
MetaCrtcMode *preferred_mode;
unsigned int j;
unsigned int number;
GList *l;
output_dummy = g_new0 (MetaOutputDummy, 1);
*output_dummy = (MetaOutputDummy) {
......@@ -231,9 +234,12 @@ append_tiled_monitor (GArray *modes,
output->n_modes = G_N_ELEMENTS (modes_decl);
output->possible_crtcs = g_new0 (MetaCrtc *, n_tiles);
for (j = 0; j < n_tiles; j++)
output->possible_crtcs[j] = &g_array_index (crtcs, MetaCrtc,
crtcs->len - (j + 1));
for (l = new_crtcs, j = 0; l; l = l->next, j++)
{
MetaCrtc *crtc = l->data;
output->possible_crtcs[j] = crtc;
}
output->n_possible_crtcs = n_tiles;
*outputs = g_list_append (*outputs, output);
......@@ -257,7 +263,7 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
gboolean tiled_monitors;
unsigned int i;
GList *outputs;
GArray *crtcs;
GList *crtcs;
GArray *modes;
/* To control what monitor configuration is generated, there are two available
......@@ -328,25 +334,23 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
tiled_monitors = g_strcmp0 (tiled_monitors_str, "1") == 0;
modes = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtcMode), MAX_MODES);
crtcs = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtc), MAX_CRTCS);
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->crtcs = (MetaCrtc *) crtcs->data;
manager->n_crtcs = crtcs->len;
manager->crtcs = crtcs;
manager->outputs = outputs;
g_array_free (modes, FALSE);
g_array_free (crtcs, FALSE);
}
static void
......@@ -433,9 +437,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
}
/* Disable CRTCs not mentioned in the list */
for (i = 0; i < manager->n_crtcs; i++)
for (l = manager->crtcs; l; l = l->next)
{
MetaCrtc *crtc = &manager->crtcs[i];
MetaCrtc *crtc = l->data;
crtc->logical_monitor = NULL;
......
......@@ -105,66 +105,6 @@ typedef enum
META_MONITOR_TRANSFORM_FLIPPED_270,
} MetaMonitorTransform;
/* Same as KMS mode flags and X11 randr flags */
typedef enum
{
META_CRTC_MODE_FLAG_NONE = 0,
META_CRTC_MODE_FLAG_PHSYNC = (1 << 0),
META_CRTC_MODE_FLAG_NHSYNC = (1 << 1),
META_CRTC_MODE_FLAG_PVSYNC = (1 << 2),
META_CRTC_MODE_FLAG_NVSYNC = (1 << 3),
META_CRTC_MODE_FLAG_INTERLACE = (1 << 4),
META_CRTC_MODE_FLAG_DBLSCAN = (1 << 5),
META_CRTC_MODE_FLAG_CSYNC = (1 << 6),
META_CRTC_MODE_FLAG_PCSYNC = (1 << 7),
META_CRTC_MODE_FLAG_NCSYNC = (1 << 8),
META_CRTC_MODE_FLAG_HSKEW = (1 << 9),
META_CRTC_MODE_FLAG_BCAST = (1 << 10),
META_CRTC_MODE_FLAG_PIXMUX = (1 << 11),
META_CRTC_MODE_FLAG_DBLCLK = (1 << 12),
META_CRTC_MODE_FLAG_CLKDIV2 = (1 << 13),
META_CRTC_MODE_FLAG_MASK = 0x3fff
} MetaCrtcModeFlag;
struct _MetaCrtc
{
glong crtc_id;
MetaRectangle rect;
MetaCrtcMode *current_mode;
MetaMonitorTransform transform;
unsigned int all_transforms;
/* Only used to build the logical configuration
from the HW one
*/
MetaLogicalMonitor *logical_monitor;
/* Used when changing configuration */
gboolean is_dirty;
/* Used by cursor renderer backend */
void *cursor_renderer_private;
gpointer driver_private;
GDestroyNotify driver_notify;
};
struct _MetaCrtcMode
{
/* The low-level ID of this mode, used to apply back configuration */
glong mode_id;
char *name;
int width;
int height;
float refresh_rate;
MetaCrtcModeFlag flags;
gpointer driver_private;
GDestroyNotify driver_notify;
};
/*
* MetaCrtcInfo:
*
......@@ -228,13 +168,11 @@ struct _MetaMonitorManager
while logical_monitors refer to logical ones.
*/
GList *outputs;
GList *crtcs;
MetaCrtcMode *modes;
unsigned int n_modes;
MetaCrtc *crtcs;
unsigned int n_crtcs;
GList *monitors;
GList *logical_monitors;
......@@ -362,6 +300,8 @@ GList * meta_monitor_manager_get_monitors (MetaMonitorManager *
GList * meta_monitor_manager_get_outputs (MetaMonitorManager *manager);
GList * meta_monitor_manager_get_crtcs (MetaMonitorManager *manager);
void meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
int *width,
int *height);
......
......@@ -36,6 +36,7 @@
#include "util-private.h"
#include <meta/errors.h>
#include "edid.h"
#include "backends/meta-crtc.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor.h"
#include "backends/meta-monitor-config-manager.h"
......@@ -742,27 +743,6 @@ meta_monitor_manager_free_mode_array (MetaCrtcMode *old_modes,
g_free (old_modes);
}
void
meta_monitor_manager_clear_crtc (MetaCrtc *crtc)
{
if (crtc->driver_notify)
crtc->driver_notify (crtc);
memset (crtc, 0, sizeof (*crtc));
}
static void
meta_monitor_manager_free_crtc_array (MetaCrtc *old_crtcs,
int n_old_crtcs)
{
int i;
for (i = 0; i < n_old_crtcs; i++)
meta_monitor_manager_clear_crtc (&old_crtcs[i]);
g_free (old_crtcs);
}
static void
meta_monitor_manager_finalize (GObject *object)
{
......@@ -770,7 +750,7 @@ meta_monitor_manager_finalize (GObject *object)
g_list_free_full (manager->outputs, g_object_unref);
meta_monitor_manager_free_mode_array (manager->modes, manager->n_modes);
meta_monitor_manager_free_crtc_array (manager->crtcs, manager->n_crtcs);
g_list_free_full (manager->crtcs, g_object_unref);
g_list_free_full (manager->logical_monitors, g_object_unref);
g_signal_handler_disconnect (meta_get_backend (),
......@@ -946,9 +926,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_variant_builder_init (&output_builder, G_VARIANT_TYPE ("a(uxiausauaua{sv})"));
g_variant_builder_init (&mode_builder, G_VARIANT_TYPE ("a(uxuudu)"));
for (i = 0; i < manager->n_crtcs; i++)
for (l = manager->crtcs, i = 0; l; l = l->next, i++)
{
MetaCrtc *crtc = &manager->crtcs[i];
MetaCrtc *crtc = l->data;
GVariantBuilder transforms;
g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
......@@ -975,11 +955,17 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
GVariantBuilder crtcs, modes, clones, properties;
GBytes *edid;
char *edid_file;
int crtc_index;
g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
for (j = 0; j < output->n_possible_crtcs; j++)
g_variant_builder_add (&crtcs, "u",
(unsigned)(output->possible_crtcs[j] - manager->crtcs));
{
MetaCrtc *possible_crtc = output->possible_crtcs[j];
unsigned possible_crtc_index;
possible_crtc_index = g_list_index (manager->crtcs, possible_crtc);
g_variant_builder_add (&crtcs, "u", possible_crtc_index);
}
g_variant_builder_init (&modes, G_VARIANT_TYPE ("au"));
for (j = 0; j < output->n_modes; j++)
......@@ -1058,10 +1044,12 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
output->tile_info.tile_h));
}
crtc_index = output->crtc ? g_list_index (manager->crtcs, output->crtc)
: -1;
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
i, /* ID */
(gint64)output->winsys_id,
(int)(output->crtc ? output->crtc - manager->crtcs : -1),
crtc_index,
&crtcs,
output->name,
&modes,
......@@ -2064,14 +2052,15 @@ meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton,
return TRUE;
}
if (crtc_id >= manager->n_crtcs)
if (crtc_id >= g_list_length (manager->crtcs))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Invalid crtc id");
return TRUE;
}
crtc = &manager->crtcs[crtc_id];
crtc = g_list_nth_data (manager->crtcs, crtc_id);
klass = META_MONITOR_MANAGER_GET_CLASS (manager);
if (klass->get_crtc_gamma)
......@@ -2126,14 +2115,15 @@ meta_monitor_manager_handle_set_crtc_gamma (MetaDBusDisplayConfig *skeleton,
return TRUE;
}
if (crtc_id >= manager->n_crtcs)
if (crtc_id >= g_list_length (manager->crtcs))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
"Invalid crtc id");
return TRUE;
}
crtc = &manager->crtcs[crtc_id];
crtc = g_list_nth_data (manager->crtcs, crtc_id);
red_bytes = g_variant_get_data_as_bytes (red_v);
green_bytes = g_variant_get_data_as_bytes (green_v);
......@@ -2409,6 +2399,12 @@ meta_monitor_manager_get_outputs (MetaMonitorManager *manager)
return manager->outputs;
}
GList *
meta_monitor_manager_get_crtcs (MetaMonitorManager *manager)
{
return manager->crtcs;
}
void
meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
int *width,
......@@ -2492,16 +2488,15 @@ void
meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
{
GList *old_outputs;
MetaCrtc *old_crtcs;
GList *old_crtcs;
MetaCrtcMode *old_modes;
unsigned int n_old_crtcs, n_old_modes;
unsigned int n_old_modes;
/* Some implementations of read_current use the existing information
* we have available, so don't free the old configuration until after
* read_current finishes. */
old_outputs = manager->outputs;
old_crtcs = manager->crtcs;
n_old_crtcs = manager->n_crtcs;
old_modes = manager->modes;
n_old_modes = manager->n_modes;
......@@ -2512,7 +2507,7 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
g_list_free_full (old_outputs, g_object_unref);
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
meta_monitor_manager_free_crtc_array (old_crtcs, n_old_crtcs);
g_list_free_full (old_crtcs, g_object_unref);
}
static void
......
......@@ -24,6 +24,7 @@
#include "backends/meta-monitor.h"
#include "backends/meta-backend-private.h"
#include "backends/meta-crtc.h"
#include "backends/meta-monitor-manager-private.h"
#include "backends/meta-settings-private.h"
#include "backends/meta-output.h"
......
......@@ -24,6 +24,7 @@
#include <glib-object.h>
#include "backends/meta-crtc.h"
#include "backends/meta-monitor-manager-private.h"
#include "backends/meta-output.h"
......
......@@ -25,6 +25,7 @@
#include "meta-monitor-manager-kms.h"
#include "meta-monitor-config-manager.h"
#include "meta-crtc.h"
#include "meta-output.h"
#include "meta-backend-private.h"
#include "meta-renderer-native.h"
......@@ -663,13 +664,15 @@ add_common_modes (MetaMonitorManager *manager,
g_ptr_array_free (array, TRUE);
}
static void
init_crtc (MetaCrtc *crtc,
MetaMonitorManager *manager,
drmModeCrtc *drm_crtc)
static MetaCrtc *
create_crtc (MetaMonitorManager *manager,
drmModeCrtc *drm_crtc)
{
MetaCrtc *crtc;
unsigned int i;
crtc = g_object_new (META_TYPE_CRTC, NULL);
crtc->crtc_id = drm_crtc->crtc_id;
crtc->rect.x = drm_crtc->x;