kms: Add connector representation

Represents drmModeConnector; both connected and disconnected. Currently
only provides non-changing meta data. MetaOutputKms is changed to use
MetaKmsConnector to get basic metadata, but variable metadata, those
changing depending on what is connected (e.g. physical dimension, EDID,
etc), are still manually retrieved by MetaOutputKms.

https://gitlab.gnome.org/GNOME/mutter/issues/548
https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
This commit is contained in:
Jonas Ådahl 2019-03-08 16:23:15 +01:00 committed by Georges Basile Stavracas Neto
parent 5d5d296551
commit f59d62bc8f
12 changed files with 304 additions and 61 deletions

View File

@ -37,6 +37,7 @@
#include "backends/meta-output.h"
#include "backends/native/meta-backend-native.h"
#include "backends/native/meta-crtc-kms.h"
#include "backends/native/meta-kms-connector.h"
#include "backends/native/meta-kms-device.h"
#include "backends/native/meta-kms.h"
#include "backends/native/meta-launcher.h"
@ -750,37 +751,43 @@ init_outputs (MetaGpuKms *gpu_kms,
GList *old_outputs;
GList *outputs;
unsigned int i;
GList *l;
old_outputs = meta_gpu_get_outputs (gpu);
outputs = NULL;
for (i = 0; i < gpu_kms->n_connectors; i++)
i = 0;
for (l = meta_kms_device_get_connectors (gpu_kms->kms_device); l; l = l->next)
{
MetaKmsConnector *kms_connector = l->data;
MetaOutput *output;
MetaOutput *old_output;
GError *error = NULL;
drmModeConnector *connector;
connector = gpu_kms->connectors[i];
connector = gpu_kms->connectors[i++];
if (connector && connector->connection == DRM_MODE_CONNECTED)
if (!connector || connector->connection != DRM_MODE_CONNECTED)
continue;
old_output =
find_output_by_connector_id (old_outputs,
meta_kms_connector_get_id (kms_connector));
output = meta_create_kms_output (gpu_kms,
kms_connector,
connector,
resources,
old_output,
&error);
if (!output)
{
MetaOutput *output;
MetaOutput *old_output;
GError *error = NULL;
old_output = find_output_by_connector_id (old_outputs,
connector->connector_id);
output = meta_create_kms_output (gpu_kms, connector, resources,
old_output,
&error);
if (!output)
{
g_warning ("Failed to create KMS output: %s", error->message);
g_error_free (error);
}
else
{
outputs = g_list_prepend (outputs, output);
}
g_warning ("Failed to create KMS output: %s", error->message);
g_error_free (error);
}
else
{
outputs = g_list_prepend (outputs, output);
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2019 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_KMS_CONNECTOR_PRIVATE_H
#define META_KMS_CONNECTOR_PRIVATE_H
#include "backends/native/meta-kms-types.h"
MetaKmsConnector * meta_kms_connector_new (MetaKmsImplDevice *impl_device,
drmModeConnector *drm_connector,
drmModeRes *drm_resources);
#endif /* META_KMS_CONNECTOR_PRIVATE_H */

View File

@ -0,0 +1,136 @@
/*
* Copyright (C) 2019 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/native/meta-kms-connector.h"
#include "backends/native/meta-kms-connector-private.h"
#include <errno.h>
#include "backends/native/meta-kms-impl-device.h"
struct _MetaKmsConnector
{
GObject parent;
MetaKmsDevice *device;
uint32_t id;
MetaConnectorType type;
char *name;
};
G_DEFINE_TYPE (MetaKmsConnector, meta_kms_connector, G_TYPE_OBJECT)
MetaKmsDevice *
meta_kms_connector_get_device (MetaKmsConnector *connector)
{
return connector->device;
}
MetaConnectorType
meta_kms_connector_get_connector_type (MetaKmsConnector *connector)
{
return connector->type;
}
uint32_t
meta_kms_connector_get_id (MetaKmsConnector *connector)
{
return connector->id;
}
const char *
meta_kms_connector_get_name (MetaKmsConnector *connector)
{
return connector->name;
}
static char *
make_connector_name (drmModeConnector *drm_connector)
{
static const char * const connector_type_names[] = {
"None",
"VGA",
"DVI-I",
"DVI-D",
"DVI-A",
"Composite",
"SVIDEO",
"LVDS",
"Component",
"DIN",
"DP",
"HDMI",
"HDMI-B",
"TV",
"eDP",
"Virtual",
"DSI",
};
if (drm_connector->connector_type < G_N_ELEMENTS (connector_type_names))
return g_strdup_printf ("%s-%d",
connector_type_names[drm_connector->connector_type],
drm_connector->connector_type_id);
else
return g_strdup_printf ("Unknown%d-%d",
drm_connector->connector_type,
drm_connector->connector_type_id);
}
MetaKmsConnector *
meta_kms_connector_new (MetaKmsImplDevice *impl_device,
drmModeConnector *drm_connector,
drmModeRes *drm_resources)
{
MetaKmsConnector *connector;
connector = g_object_new (META_TYPE_KMS_CONNECTOR, NULL);
connector->device = meta_kms_impl_device_get_device (impl_device);
connector->id = drm_connector->connector_id;
connector->type = (MetaConnectorType) drm_connector->connector_type;
connector->name = make_connector_name (drm_connector);
return connector;
}
static void
meta_kms_connector_finalize (GObject *object)
{
MetaKmsConnector *connector = META_KMS_CONNECTOR (object);
g_free (connector->name);
G_OBJECT_CLASS (meta_kms_connector_parent_class)->finalize (object);
}
static void
meta_kms_connector_init (MetaKmsConnector *connector)
{
}
static void
meta_kms_connector_class_init (MetaKmsConnectorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_kms_connector_finalize;
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2019 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_KMS_CONNECTOR_H
#define META_KMS_CONNECTOR_H
#include <glib-object.h>
#include <stdint.h>
#include <xf86drmMode.h>
#include "backends/native/meta-kms-types.h"
#include "backends/meta-output.h"
#define META_TYPE_KMS_CONNECTOR (meta_kms_connector_get_type ())
G_DECLARE_FINAL_TYPE (MetaKmsConnector, meta_kms_connector,
META, KMS_CONNECTOR, GObject)
MetaKmsDevice * meta_kms_connector_get_device (MetaKmsConnector *connector);
MetaConnectorType meta_kms_connector_get_connector_type (MetaKmsConnector *connector);
uint32_t meta_kms_connector_get_id (MetaKmsConnector *connector);
const char * meta_kms_connector_get_name (MetaKmsConnector *connector);
#endif /* META_KMS_CONNECTOR_H */

View File

@ -38,6 +38,7 @@ struct _MetaKmsDevice
char *path;
GList *crtcs;
GList *connectors;
GList *planes;
};
@ -61,6 +62,12 @@ meta_kms_device_get_flags (MetaKmsDevice *device)
return device->flags;
}
GList *
meta_kms_device_get_connectors (MetaKmsDevice *device)
{
return device->connectors;
}
GList *
meta_kms_device_get_crtcs (MetaKmsDevice *device)
{
@ -74,6 +81,7 @@ typedef struct _CreateImplDeviceData
MetaKmsImplDevice *out_impl_device;
GList *out_crtcs;
GList *out_connectors;
GList *out_planes;
} CreateImplDeviceData;
@ -89,6 +97,7 @@ create_impl_device_in_impl (MetaKmsImpl *impl,
data->out_impl_device = impl_device;
data->out_crtcs = meta_kms_impl_device_copy_crtcs (impl_device);
data->out_connectors = meta_kms_impl_device_copy_connectors (impl_device);
data->out_planes = meta_kms_impl_device_copy_planes (impl_device);
return TRUE;
@ -130,6 +139,7 @@ meta_kms_device_new (MetaKms *kms,
device->flags = flags;
device->path = g_strdup (path);
device->crtcs = data.out_crtcs;
device->connectors = data.out_connectors;
device->planes = data.out_planes;
return device;
@ -170,6 +180,7 @@ meta_kms_device_finalize (GObject *object)
GError *error = NULL;
g_list_free (device->crtcs);
g_list_free (device->connectors);
g_list_free (device->planes);
data = (FreeImplDeviceData) {

View File

@ -35,6 +35,8 @@ const char * meta_kms_device_get_path (MetaKmsDevice *device);
MetaKmsDeviceFlag meta_kms_device_get_flags (MetaKmsDevice *device);
GList * meta_kms_device_get_connectors (MetaKmsDevice *device);
GList * meta_kms_device_get_crtcs (MetaKmsDevice *device);
MetaKmsDevice * meta_kms_device_new (MetaKms *kms,

View File

@ -23,6 +23,8 @@
#include <xf86drm.h>
#include "backends/native/meta-kms-connector-private.h"
#include "backends/native/meta-kms-connector.h"
#include "backends/native/meta-kms-crtc-private.h"
#include "backends/native/meta-kms-crtc.h"
#include "backends/native/meta-kms-impl.h"
@ -39,6 +41,7 @@ struct _MetaKmsImplDevice
int fd;
GList *crtcs;
GList *connectors;
GList *planes;
};
@ -50,6 +53,12 @@ meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device)
return impl_device->device;
}
GList *
meta_kms_impl_device_copy_connectors (MetaKmsImplDevice *impl_device)
{
return g_list_copy (impl_device->connectors);
}
GList *
meta_kms_impl_device_copy_crtcs (MetaKmsImplDevice *impl_device)
{
@ -112,6 +121,29 @@ init_crtcs (MetaKmsImplDevice *impl_device,
impl_device->crtcs = g_list_reverse (impl_device->crtcs);
}
static void
init_connectors (MetaKmsImplDevice *impl_device,
drmModeRes *drm_resources)
{
unsigned int i;
for (i = 0; i < drm_resources->count_connectors; i++)
{
drmModeConnector *drm_connector;
MetaKmsConnector *connector;
drm_connector = drmModeGetConnector (impl_device->fd,
drm_resources->connectors[i]);
connector = meta_kms_connector_new (impl_device, drm_connector,
drm_resources);
drmModeFreeConnector (drm_connector);
impl_device->connectors = g_list_prepend (impl_device->connectors,
connector);
}
impl_device->connectors = g_list_reverse (impl_device->connectors);
}
static MetaKmsPlaneType
get_plane_type (MetaKmsImplDevice *impl_device,
drmModeObjectProperties *props)
@ -204,6 +236,7 @@ meta_kms_impl_device_new (MetaKmsDevice *device,
drm_resources = drmModeGetResources (fd);
init_crtcs (impl_device, drm_resources);
init_connectors (impl_device, drm_resources);
init_planes (impl_device);
drmModeFreeResources (drm_resources);
@ -245,6 +278,7 @@ meta_kms_impl_device_finalize (GObject *object)
g_list_free_full (impl_device->planes, g_object_unref);
g_list_free_full (impl_device->crtcs, g_object_unref);
g_list_free_full (impl_device->connectors, g_object_unref);
G_OBJECT_CLASS (meta_kms_impl_device_parent_class)->finalize (object);
}

View File

@ -34,6 +34,8 @@ G_DECLARE_FINAL_TYPE (MetaKmsImplDevice, meta_kms_impl_device,
MetaKmsDevice * meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device);
GList * meta_kms_impl_device_copy_connectors (MetaKmsImplDevice *impl_device);
GList * meta_kms_impl_device_copy_crtcs (MetaKmsImplDevice *impl_device);
GList * meta_kms_impl_device_copy_planes (MetaKmsImplDevice *impl_device);

View File

@ -24,6 +24,7 @@ typedef struct _MetaKms MetaKms;
typedef struct _MetaKmsDevice MetaKmsDevice;
typedef struct _MetaKmsCrtc MetaKmsCrtc;
typedef struct _MetaKmsConnector MetaKmsConnector;
typedef struct _MetaKmsImpl MetaKmsImpl;
typedef struct _MetaKmsImplDevice MetaKmsImplDevice;

View File

@ -29,6 +29,7 @@
#include <string.h>
#include "backends/meta-crtc.h"
#include "backends/native/meta-kms-connector.h"
#include "backends/native/meta-crtc-kms.h"
#include "meta-default-modes.h"
@ -39,6 +40,8 @@ typedef struct _MetaOutputKms
{
MetaOutput parent;
MetaKmsConnector *kms_connector;
drmModeConnector *connector;
/*
@ -122,7 +125,7 @@ meta_output_kms_get_connector_id (MetaOutput *output)
{
MetaOutputKms *output_kms = output->driver_private;
return output_kms->connector->connector_id;
return meta_kms_connector_get_id (output_kms->kms_connector);
}
void
@ -368,39 +371,6 @@ find_connector_properties (MetaGpuKms *gpu_kms,
}
}
static char *
make_output_name (drmModeConnector *connector)
{
static const char * const connector_type_names[] = {
"None",
"VGA",
"DVI-I",
"DVI-D",
"DVI-A",
"Composite",
"SVIDEO",
"LVDS",
"Component",
"DIN",
"DP",
"HDMI",
"HDMI-B",
"TV",
"eDP",
"Virtual",
"DSI",
};
if (connector->connector_type < G_N_ELEMENTS (connector_type_names))
return g_strdup_printf ("%s-%d",
connector_type_names[connector->connector_type],
connector->connector_type_id);
else
return g_strdup_printf ("Unknown%d-%d",
connector->connector_type,
connector->connector_type_id);
}
static void
meta_output_destroy_notify (MetaOutput *output)
{
@ -544,6 +514,7 @@ init_output_modes (MetaOutput *output,
MetaOutput *
meta_create_kms_output (MetaGpuKms *gpu_kms,
MetaKmsConnector *kms_connector,
drmModeConnector *connector,
MetaKmsResources *resources,
MetaOutput *old_output,
@ -552,13 +523,14 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
MetaGpu *gpu = META_GPU (gpu_kms);
MetaOutput *output;
MetaOutputKms *output_kms;
uint32_t connector_id;
GArray *crtcs;
GBytes *edid;
GList *l;
unsigned int i;
unsigned int crtc_mask;
int fd;
uint32_t id;
uint32_t gpu_id;
unsigned int n_encoders;
drmModeEncoderPtr *encoders;
drmModeEncoderPtr current_encoder = NULL;
@ -570,10 +542,11 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
output->driver_notify = (GDestroyNotify) meta_output_destroy_notify;
output->gpu = gpu;
output->name = make_output_name (connector);
output->name = g_strdup (meta_kms_connector_get_name (kms_connector));
id = meta_gpu_kms_get_id (gpu_kms);
output->winsys_id = ((uint64_t) id << 32) | connector->connector_id;
gpu_id = meta_gpu_kms_get_id (gpu_kms);
connector_id = meta_kms_connector_get_id (kms_connector);
output->winsys_id = ((uint64_t) gpu_id << 32) | connector_id;
switch (connector->subpixel)
{
@ -598,6 +571,8 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
break;
}
output_kms->kms_connector = kms_connector;
output_kms->connector = connector;
find_connector_properties (gpu_kms, output);
@ -710,8 +685,7 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
meta_output_parse_edid (output, edid);
g_bytes_unref (edid);
/* MetaConnectorType matches DRM's connector types */
output->connector_type = (MetaConnectorType) connector->connector_type;
output->connector_type = meta_kms_connector_get_connector_type (kms_connector);
output_get_tile_info (gpu_kms, output);

View File

@ -25,6 +25,7 @@
#include "backends/meta-output.h"
#include "backends/native/meta-gpu-kms.h"
#include "backends/native/meta-kms-types.h"
void meta_output_kms_set_underscan (MetaOutput *output);
@ -39,6 +40,7 @@ uint32_t meta_output_kms_get_connector_id (MetaOutput *output);
GBytes * meta_output_kms_read_edid (MetaOutput *output);
MetaOutput * meta_create_kms_output (MetaGpuKms *gpu_kms,
MetaKmsConnector *kms_connector,
drmModeConnector *connector,
MetaKmsResources *resources,
MetaOutput *old_output,

View File

@ -595,6 +595,9 @@ if have_native_backend
'backends/native/meta-output-kms.c',
'backends/native/meta-output-kms.h',
'backends/native/meta-renderer-native.c',
'backends/native/meta-kms-connector-private.h',
'backends/native/meta-kms-connector.c',
'backends/native/meta-kms-connector.h',
'backends/native/meta-kms-crtc-private.h',
'backends/native/meta-kms-crtc.c',
'backends/native/meta-kms-crtc.h',