Commit f59d62bc authored by Jonas Ådahl's avatar Jonas Ådahl Committed by Georges Basile Stavracas Neto

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.

GNOME/mutter#548
GNOME/mutter!525
parent 5d5d2965
......@@ -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];
if (connector && connector->connection == DRM_MODE_CONNECTED)
connector = gpu_kms->connectors[i++];
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);
}
}
......
/*
* 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 */
/*
* 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;
}
/*
* 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 */
......@@ -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) {
......
......@@ -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,
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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,
......
......@@ -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',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment