kms/connector: Set DPMS and underscanning directly on the update

Instead of telling MetaKmsConnector fill a MetaKmsUpdate with connector
property changes, make the update itself aware of the changes, making
the impl side translate that to property changes.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
Jonas Ådahl 2020-07-14 16:48:47 +02:00 committed by Marge Bot
parent c1ce36f08e
commit ec7667fc31
8 changed files with 195 additions and 126 deletions

View File

@ -20,7 +20,22 @@
#ifndef META_KMS_CONNECTOR_PRIVATE_H
#define META_KMS_CONNECTOR_PRIVATE_H
#include "backends/native/meta-kms-types.h"
#include "backends/native/meta-kms-connector.h"
typedef enum _MetaKmsConnectorProp
{
META_KMS_CONNECTOR_PROP_DPMS = 0,
META_KMS_CONNECTOR_PROP_UNDERSCAN,
META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER,
META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER,
META_KMS_CONNECTOR_N_PROPS
} MetaKmsConnectorProp;
uint32_t meta_kms_connector_get_prop_id (MetaKmsConnector *connector,
MetaKmsConnectorProp prop);
const char * meta_kms_connector_get_prop_name (MetaKmsConnector *connector,
MetaKmsConnectorProp prop);
void meta_kms_connector_update_state (MetaKmsConnector *connector,
drmModeRes *drm_resources);

View File

@ -30,15 +30,6 @@
#include "backends/native/meta-kms-mode-private.h"
#include "backends/native/meta-kms-update-private.h"
typedef enum _MetaKmsConnectorProp
{
META_KMS_CONNECTOR_PROP_DPMS = 0,
META_KMS_CONNECTOR_PROP_UNDERSCAN,
META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER,
META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER,
META_KMS_CONNECTOR_N_PROPS
} MetaKmsConnectorProp;
typedef struct _MetaKmsConnectorPropTable
{
MetaKmsProp props[META_KMS_CONNECTOR_N_PROPS];
@ -71,64 +62,18 @@ meta_kms_connector_get_device (MetaKmsConnector *connector)
return connector->device;
}
void
meta_kms_connector_update_set_dpms_state (MetaKmsConnector *connector,
MetaKmsUpdate *update,
uint64_t state)
uint32_t
meta_kms_connector_get_prop_id (MetaKmsConnector *connector,
MetaKmsConnectorProp prop)
{
uint32_t prop_id;
prop_id = connector->prop_table.props[META_KMS_CONNECTOR_PROP_DPMS].prop_id;
meta_kms_update_set_connector_property (update,
connector,
prop_id,
state);
return connector->prop_table.props[prop].prop_id;
}
void
meta_kms_connector_set_underscanning (MetaKmsConnector *connector,
MetaKmsUpdate *update,
uint64_t hborder,
uint64_t vborder)
const char *
meta_kms_connector_get_prop_name (MetaKmsConnector *connector,
MetaKmsConnectorProp prop)
{
MetaKmsProp *props = connector->prop_table.props;
uint32_t underscan_prop_id;
uint32_t underscan_hborder_prop_id;
uint32_t underscan_vborder_prop_id;
underscan_prop_id =
props[META_KMS_CONNECTOR_PROP_UNDERSCAN].prop_id;
underscan_hborder_prop_id =
props[META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER].prop_id;
underscan_vborder_prop_id =
props[META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER].prop_id;
meta_kms_update_set_connector_property (update,
connector,
underscan_prop_id,
1);
meta_kms_update_set_connector_property (update,
connector,
underscan_hborder_prop_id,
hborder);
meta_kms_update_set_connector_property (update,
connector,
underscan_vborder_prop_id,
vborder);
}
void
meta_kms_connector_unset_underscanning (MetaKmsConnector *connector,
MetaKmsUpdate *update)
{
MetaKmsProp *props = connector->prop_table.props;
uint32_t underscan_prop_id;
underscan_prop_id = props[META_KMS_CONNECTOR_PROP_UNDERSCAN].prop_id;
meta_kms_update_set_connector_property (update,
connector,
underscan_prop_id,
0);
return connector->prop_table.props[prop].name;
}
MetaConnectorType

View File

@ -61,18 +61,6 @@ typedef struct _MetaKmsConnectorState
MetaKmsDevice * meta_kms_connector_get_device (MetaKmsConnector *connector);
void meta_kms_connector_update_set_dpms_state (MetaKmsConnector *connector,
MetaKmsUpdate *update,
uint64_t state);
void meta_kms_connector_set_underscanning (MetaKmsConnector *connector,
MetaKmsUpdate *update,
uint64_t hborder,
uint64_t vborder);
void meta_kms_connector_unset_underscanning (MetaKmsConnector *connector,
MetaKmsUpdate *update);
MetaConnectorType meta_kms_connector_get_connector_type (MetaKmsConnector *connector);
uint32_t meta_kms_connector_get_id (MetaKmsConnector *connector);

View File

@ -26,7 +26,7 @@
#include <gbm.h>
#include <xf86drmMode.h>
#include "backends/native/meta-kms-connector.h"
#include "backends/native/meta-kms-connector-private.h"
#include "backends/native/meta-kms-crtc.h"
#include "backends/native/meta-kms-device-private.h"
#include "backends/native/meta-kms-mode.h"
@ -74,31 +74,40 @@ meta_kms_impl_simple_new (MetaKms *kms,
}
static gboolean
process_connector_property (MetaKmsImpl *impl,
MetaKmsUpdate *update,
gpointer update_entry,
GError **error)
set_connector_property (MetaKmsConnector *connector,
MetaKmsConnectorProp prop,
uint64_t value,
GError **error)
{
MetaKmsConnectorProperty *connector_property = update_entry;
MetaKmsConnector *connector = connector_property->connector;
MetaKmsDevice *device = meta_kms_connector_get_device (connector);
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
uint32_t prop_id;
int fd;
int ret;
prop_id = meta_kms_connector_get_prop_id (connector, prop);
if (!prop_id)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"Property (%s) not found on connector %u",
meta_kms_connector_get_prop_name (connector, prop),
meta_kms_connector_get_id (connector));
return FALSE;
}
fd = meta_kms_impl_device_get_fd (impl_device);
ret = drmModeObjectSetProperty (fd,
meta_kms_connector_get_id (connector),
DRM_MODE_OBJECT_CONNECTOR,
connector_property->prop_id,
connector_property->value);
prop_id,
value);
if (ret != 0)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
"Failed to set connector %u property %u: %s",
meta_kms_connector_get_id (connector),
connector_property->prop_id,
prop_id,
g_strerror (-ret));
return FALSE;
}
@ -106,6 +115,55 @@ process_connector_property (MetaKmsImpl *impl,
return TRUE;
}
static gboolean
process_connector_update (MetaKmsImpl *impl,
MetaKmsUpdate *update,
gpointer update_entry,
GError **error)
{
MetaKmsConnectorUpdate *connector_update = update_entry;
MetaKmsConnector *connector = connector_update->connector;
if (connector_update->dpms.has_update)
{
if (!set_connector_property (connector,
META_KMS_CONNECTOR_PROP_DPMS,
connector_update->dpms.state,
error))
return FALSE;
}
if (connector_update->underscanning.has_update &&
connector_update->underscanning.is_active)
{
if (!set_connector_property (connector,
META_KMS_CONNECTOR_PROP_UNDERSCAN,
1,
error))
return FALSE;
if (!set_connector_property (connector,
META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER,
connector_update->underscanning.hborder,
error))
return FALSE;
if (!set_connector_property (connector,
META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER,
connector_update->underscanning.vborder,
error))
return FALSE;
}
else if (connector_update->underscanning.has_update)
{
if (!set_connector_property (connector,
META_KMS_CONNECTOR_PROP_UNDERSCAN,
0,
error))
return FALSE;
}
return TRUE;
}
static CachedModeSet *
cached_mode_set_new (GList *connectors,
const drmModeModeInfo *drm_mode)
@ -953,8 +1011,8 @@ meta_kms_impl_simple_process_update (MetaKmsImpl *impl,
if (!process_entries (impl,
update,
meta_kms_update_get_connector_properties (update),
process_connector_property,
meta_kms_update_get_connector_updates (update),
process_connector_update,
&error))
goto err_planes_not_assigned;

View File

@ -60,13 +60,22 @@ typedef struct _MetaKmsModeSet
MetaKmsMode *mode;
} MetaKmsModeSet;
typedef struct _MetaKmsConnectorProperty
typedef struct _MetaKmsConnectorUpdate
{
MetaKmsDevice *device;
MetaKmsConnector *connector;
uint32_t prop_id;
uint64_t value;
} MetaKmsConnectorProperty;
struct {
gboolean has_update;
gboolean is_active;
uint64_t hborder;
uint64_t vborder;
} underscanning;
struct {
gboolean has_update;
uint64_t state;
} dpms;
} MetaKmsConnectorUpdate;
typedef struct _MetaKmsCrtcGamma
{
@ -102,11 +111,6 @@ void meta_kms_update_seal (MetaKmsUpdate *update);
gboolean meta_kms_update_is_sealed (MetaKmsUpdate *update);
void meta_kms_update_set_connector_property (MetaKmsUpdate *update,
MetaKmsConnector *connector,
uint32_t prop_id,
uint64_t value);
void meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
int size,
@ -126,7 +130,7 @@ GList * meta_kms_update_get_mode_sets (MetaKmsUpdate *update);
GList * meta_kms_update_get_page_flips (MetaKmsUpdate *update);
GList * meta_kms_update_get_connector_properties (MetaKmsUpdate *update);
GList * meta_kms_update_get_connector_updates (MetaKmsUpdate *update);
GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update);

View File

@ -34,7 +34,7 @@ struct _MetaKmsUpdate
GList *mode_sets;
GList *plane_assignments;
GList *page_flips;
GList *connector_properties;
GList *connector_updates;
GList *crtc_gammas;
};
@ -204,25 +204,72 @@ meta_kms_update_mode_set (MetaKmsUpdate *update,
update->mode_sets = g_list_prepend (update->mode_sets, mode_set);
}
void
meta_kms_update_set_connector_property (MetaKmsUpdate *update,
MetaKmsConnector *connector,
uint32_t prop_id,
uint64_t value)
static MetaKmsConnectorUpdate *
ensure_connector_update (MetaKmsUpdate *update,
MetaKmsConnector *connector)
{
MetaKmsConnectorProperty *prop;
GList *l;
MetaKmsConnectorUpdate *connector_update;
for (l = update->connector_updates; l; l = l->next)
{
connector_update = l->data;
if (connector_update->connector == connector)
return connector_update;
}
connector_update = g_new0 (MetaKmsConnectorUpdate, 1);
connector_update->connector = connector;
update->connector_updates = g_list_prepend (update->connector_updates,
connector_update);
return connector_update;
}
void
meta_kms_update_set_underscanning (MetaKmsUpdate *update,
MetaKmsConnector *connector,
uint64_t hborder,
uint64_t vborder)
{
MetaKmsConnectorUpdate *connector_update;
g_assert (!meta_kms_update_is_sealed (update));
prop = g_new0 (MetaKmsConnectorProperty, 1);
*prop = (MetaKmsConnectorProperty) {
.connector = connector,
.prop_id = prop_id,
.value = value,
};
connector_update = ensure_connector_update (update, connector);
connector_update->underscanning.has_update = TRUE;
connector_update->underscanning.is_active = TRUE;
connector_update->underscanning.hborder = hborder;
connector_update->underscanning.vborder = vborder;
}
update->connector_properties = g_list_prepend (update->connector_properties,
prop);
void
meta_kms_update_unset_underscanning (MetaKmsUpdate *update,
MetaKmsConnector *connector)
{
MetaKmsConnectorUpdate *connector_update;
g_assert (!meta_kms_update_is_sealed (update));
connector_update = ensure_connector_update (update, connector);
connector_update->underscanning.has_update = TRUE;
connector_update->underscanning.is_active = FALSE;
}
void
meta_kms_update_set_dpms_state (MetaKmsUpdate *update,
MetaKmsConnector *connector,
uint64_t state)
{
MetaKmsConnectorUpdate *connector_update;
g_assert (!meta_kms_update_is_sealed (update));
connector_update = ensure_connector_update (update, connector);
connector_update->dpms.has_update = TRUE;
connector_update->dpms.state = state;
}
static void
@ -360,9 +407,9 @@ meta_kms_update_get_page_flips (MetaKmsUpdate *update)
}
GList *
meta_kms_update_get_connector_properties (MetaKmsUpdate *update)
meta_kms_update_get_connector_updates (MetaKmsUpdate *update)
{
return update->connector_properties;
return update->connector_updates;
}
GList *
@ -397,7 +444,7 @@ meta_kms_update_free (MetaKmsUpdate *update)
g_list_free_full (update->mode_sets,
(GDestroyNotify) meta_kms_mode_set_free);
g_list_free_full (update->page_flips, g_free);
g_list_free_full (update->connector_properties, g_free);
g_list_free_full (update->connector_updates, g_free);
g_list_free_full (update->crtc_gammas, (GDestroyNotify) meta_kms_crtc_gamma_free);
g_free (update);

View File

@ -85,6 +85,18 @@ MetaKmsUpdate * meta_kms_update_new (void);
void meta_kms_update_free (MetaKmsUpdate *update);
void meta_kms_update_set_underscanning (MetaKmsUpdate *update,
MetaKmsConnector *connector,
uint64_t hborder,
uint64_t vborder);
void meta_kms_update_unset_underscanning (MetaKmsUpdate *update,
MetaKmsConnector *connector);
void meta_kms_update_set_dpms_state (MetaKmsUpdate *update,
MetaKmsConnector *connector,
uint64_t state);
void meta_kms_update_mode_set (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
GList *connectors,

View File

@ -32,6 +32,7 @@
#include "backends/native/meta-kms-connector.h"
#include "backends/native/meta-kms-device.h"
#include "backends/native/meta-kms-mode.h"
#include "backends/native/meta-kms-update.h"
#include "backends/native/meta-kms-utils.h"
#include "backends/native/meta-crtc-kms.h"
#include "backends/native/meta-crtc-mode-kms.h"
@ -81,18 +82,17 @@ meta_output_kms_set_underscan (MetaOutputKms *output_kms,
meta_kms_connector_get_name (output_kms->kms_connector),
hborder, vborder);
meta_kms_connector_set_underscanning (output_kms->kms_connector,
kms_update,
hborder,
vborder);
meta_kms_update_set_underscanning (kms_update,
output_kms->kms_connector,
hborder, vborder);
}
else
{
g_debug ("Unsetting underscan of connector %s",
meta_kms_connector_get_name (output_kms->kms_connector));
meta_kms_connector_unset_underscanning (output_kms->kms_connector,
kms_update);
meta_kms_update_unset_underscanning (kms_update,
output_kms->kms_connector);
}
}
@ -111,9 +111,9 @@ meta_output_kms_set_power_save_mode (MetaOutputKms *output_kms,
meta_kms_connector_get_name (output_kms->kms_connector),
dpms_state);
meta_kms_connector_update_set_dpms_state (output_kms->kms_connector,
kms_update,
dpms_state);
meta_kms_update_set_dpms_state (kms_update,
output_kms->kms_connector,
dpms_state);
}
gboolean