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 #ifndef META_KMS_CONNECTOR_PRIVATE_H
#define 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, void meta_kms_connector_update_state (MetaKmsConnector *connector,
drmModeRes *drm_resources); drmModeRes *drm_resources);

View File

@ -30,15 +30,6 @@
#include "backends/native/meta-kms-mode-private.h" #include "backends/native/meta-kms-mode-private.h"
#include "backends/native/meta-kms-update-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 typedef struct _MetaKmsConnectorPropTable
{ {
MetaKmsProp props[META_KMS_CONNECTOR_N_PROPS]; MetaKmsProp props[META_KMS_CONNECTOR_N_PROPS];
@ -71,64 +62,18 @@ meta_kms_connector_get_device (MetaKmsConnector *connector)
return connector->device; return connector->device;
} }
void uint32_t
meta_kms_connector_update_set_dpms_state (MetaKmsConnector *connector, meta_kms_connector_get_prop_id (MetaKmsConnector *connector,
MetaKmsUpdate *update, MetaKmsConnectorProp prop)
uint64_t state)
{ {
uint32_t prop_id; return connector->prop_table.props[prop].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);
} }
void const char *
meta_kms_connector_set_underscanning (MetaKmsConnector *connector, meta_kms_connector_get_prop_name (MetaKmsConnector *connector,
MetaKmsUpdate *update, MetaKmsConnectorProp prop)
uint64_t hborder,
uint64_t vborder)
{ {
MetaKmsProp *props = connector->prop_table.props; return connector->prop_table.props[prop].name;
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);
} }
MetaConnectorType MetaConnectorType

View File

@ -61,18 +61,6 @@ typedef struct _MetaKmsConnectorState
MetaKmsDevice * meta_kms_connector_get_device (MetaKmsConnector *connector); 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); MetaConnectorType meta_kms_connector_get_connector_type (MetaKmsConnector *connector);
uint32_t meta_kms_connector_get_id (MetaKmsConnector *connector); uint32_t meta_kms_connector_get_id (MetaKmsConnector *connector);

View File

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

View File

@ -60,13 +60,22 @@ typedef struct _MetaKmsModeSet
MetaKmsMode *mode; MetaKmsMode *mode;
} MetaKmsModeSet; } MetaKmsModeSet;
typedef struct _MetaKmsConnectorProperty typedef struct _MetaKmsConnectorUpdate
{ {
MetaKmsDevice *device;
MetaKmsConnector *connector; MetaKmsConnector *connector;
uint32_t prop_id;
uint64_t value; struct {
} MetaKmsConnectorProperty; 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 typedef struct _MetaKmsCrtcGamma
{ {
@ -102,11 +111,6 @@ void meta_kms_update_seal (MetaKmsUpdate *update);
gboolean meta_kms_update_is_sealed (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, void meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
MetaKmsCrtc *crtc, MetaKmsCrtc *crtc,
int size, 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_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); GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update);

View File

@ -34,7 +34,7 @@ struct _MetaKmsUpdate
GList *mode_sets; GList *mode_sets;
GList *plane_assignments; GList *plane_assignments;
GList *page_flips; GList *page_flips;
GList *connector_properties; GList *connector_updates;
GList *crtc_gammas; 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); update->mode_sets = g_list_prepend (update->mode_sets, mode_set);
} }
void static MetaKmsConnectorUpdate *
meta_kms_update_set_connector_property (MetaKmsUpdate *update, ensure_connector_update (MetaKmsUpdate *update,
MetaKmsConnector *connector, MetaKmsConnector *connector)
uint32_t prop_id,
uint64_t value)
{ {
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)); g_assert (!meta_kms_update_is_sealed (update));
prop = g_new0 (MetaKmsConnectorProperty, 1); connector_update = ensure_connector_update (update, connector);
*prop = (MetaKmsConnectorProperty) { connector_update->underscanning.has_update = TRUE;
.connector = connector, connector_update->underscanning.is_active = TRUE;
.prop_id = prop_id, connector_update->underscanning.hborder = hborder;
.value = value, connector_update->underscanning.vborder = vborder;
}; }
update->connector_properties = g_list_prepend (update->connector_properties, void
prop); 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 static void
@ -360,9 +407,9 @@ meta_kms_update_get_page_flips (MetaKmsUpdate *update)
} }
GList * 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 * GList *
@ -397,7 +444,7 @@ meta_kms_update_free (MetaKmsUpdate *update)
g_list_free_full (update->mode_sets, g_list_free_full (update->mode_sets,
(GDestroyNotify) meta_kms_mode_set_free); (GDestroyNotify) meta_kms_mode_set_free);
g_list_free_full (update->page_flips, g_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_list_free_full (update->crtc_gammas, (GDestroyNotify) meta_kms_crtc_gamma_free);
g_free (update); 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_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, void meta_kms_update_mode_set (MetaKmsUpdate *update,
MetaKmsCrtc *crtc, MetaKmsCrtc *crtc,
GList *connectors, GList *connectors,

View File

@ -32,6 +32,7 @@
#include "backends/native/meta-kms-connector.h" #include "backends/native/meta-kms-connector.h"
#include "backends/native/meta-kms-device.h" #include "backends/native/meta-kms-device.h"
#include "backends/native/meta-kms-mode.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-kms-utils.h"
#include "backends/native/meta-crtc-kms.h" #include "backends/native/meta-crtc-kms.h"
#include "backends/native/meta-crtc-mode-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), meta_kms_connector_get_name (output_kms->kms_connector),
hborder, vborder); hborder, vborder);
meta_kms_connector_set_underscanning (output_kms->kms_connector, meta_kms_update_set_underscanning (kms_update,
kms_update, output_kms->kms_connector,
hborder, hborder, vborder);
vborder);
} }
else else
{ {
g_debug ("Unsetting underscan of connector %s", g_debug ("Unsetting underscan of connector %s",
meta_kms_connector_get_name (output_kms->kms_connector)); meta_kms_connector_get_name (output_kms->kms_connector));
meta_kms_connector_unset_underscanning (output_kms->kms_connector, meta_kms_update_unset_underscanning (kms_update,
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), meta_kms_connector_get_name (output_kms->kms_connector),
dpms_state); dpms_state);
meta_kms_connector_update_set_dpms_state (output_kms->kms_connector, meta_kms_update_set_dpms_state (kms_update,
kms_update, output_kms->kms_connector,
dpms_state); dpms_state);
} }
gboolean gboolean