diff --git a/src/backends/native/meta-kms-connector-private.h b/src/backends/native/meta-kms-connector-private.h index 29901c487..bb6bb115c 100644 --- a/src/backends/native/meta-kms-connector-private.h +++ b/src/backends/native/meta-kms-connector-private.h @@ -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); diff --git a/src/backends/native/meta-kms-connector.c b/src/backends/native/meta-kms-connector.c index c25b9e817..950def3f2 100644 --- a/src/backends/native/meta-kms-connector.c +++ b/src/backends/native/meta-kms-connector.c @@ -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 diff --git a/src/backends/native/meta-kms-connector.h b/src/backends/native/meta-kms-connector.h index b2a0fa9b4..50ffdd851 100644 --- a/src/backends/native/meta-kms-connector.h +++ b/src/backends/native/meta-kms-connector.h @@ -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); diff --git a/src/backends/native/meta-kms-impl-simple.c b/src/backends/native/meta-kms-impl-simple.c index 43283716d..ede7d6fbf 100644 --- a/src/backends/native/meta-kms-impl-simple.c +++ b/src/backends/native/meta-kms-impl-simple.c @@ -26,7 +26,7 @@ #include #include -#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; diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index d33d92327..c5931003f 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -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); diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index ed1ddd0a7..8d9b4002e 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -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); diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index 5d2b6ef7f..fba90a7f7 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -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, diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index 57e34bb24..ca744ba41 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -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