diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c index e37619b1c..d5e469e7a 100644 --- a/src/backends/native/meta-crtc-kms.c +++ b/src/backends/native/meta-crtc-kms.c @@ -227,30 +227,11 @@ meta_crtc_kms_set_mode (MetaCrtcKms *crtc_kms, { const MetaCrtcConfig *crtc_config = meta_crtc_get_config (crtc); MetaCrtcModeKms *crtc_mode_kms = META_CRTC_MODE_KMS (crtc_config->mode); - MetaBackend *backend = meta_gpu_get_backend (gpu); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - MetaPowerSave power_save; - uint64_t dpms_state; - GList *l; kms_mode = meta_crtc_mode_kms_get_kms_mode (crtc_mode_kms); g_debug ("Setting CRTC (%" G_GUINT64_FORMAT ") mode to %s", meta_crtc_get_id (crtc), meta_kms_mode_get_name (kms_mode)); - - power_save = meta_monitor_manager_get_power_save_mode (monitor_manager); - g_warn_if_fail (power_save == META_POWER_SAVE_ON); - - dpms_state = meta_power_save_to_dpms_state (power_save); - for (l = connectors; l; l = l->next) - { - MetaKmsConnector *kms_connector = l->data; - - meta_kms_update_set_dpms_state (kms_update, - kms_connector, - dpms_state); - } } else { diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c index 3df26ff3e..643c25882 100644 --- a/src/backends/native/meta-gpu-kms.c +++ b/src/backends/native/meta-gpu-kms.c @@ -143,35 +143,6 @@ meta_gpu_kms_get_current_time_ns (MetaGpuKms *gpu_kms) return timespec_to_nanoseconds (&ts); } -void -meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms, - uint64_t state, - MetaKmsUpdate *kms_update) -{ - MetaGpu *gpu = META_GPU (gpu_kms); - GList *l; - - g_return_if_fail (state != DRM_MODE_DPMS_ON); - - for (l = meta_gpu_get_outputs (gpu); l; l = l->next) - { - MetaOutput *output = l->data; - - meta_output_kms_set_power_save_mode (META_OUTPUT_KMS (output), - state, kms_update); - } - - /* Turn off CRTCs for DPMS */ - for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) - { - MetaCrtcKms *crtc_kms = META_CRTC_KMS (l->data); - - meta_kms_update_mode_set (kms_update, - meta_crtc_kms_get_kms_crtc (crtc_kms), - NULL, NULL); - } -} - gboolean meta_gpu_kms_is_boot_vga (MetaGpuKms *gpu_kms) { diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c index a045f8df6..1b6efa984 100644 --- a/src/backends/native/meta-kms-impl-device-simple.c +++ b/src/backends/native/meta-kms-impl-device-simple.c @@ -66,6 +66,65 @@ G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDeviceSimple, meta_kms_impl_device_simple, static void flush_postponed_page_flip_datas (MetaKmsImplDeviceSimple *impl_device_simple); +static gboolean +get_connector_property (MetaKmsImplDevice *impl_device, + MetaKmsConnector *connector, + MetaKmsConnectorProp prop, + uint64_t *value, + GError **error) +{ + uint32_t prop_id; + int fd; + drmModeConnector *drm_connector; + int i; + gboolean found; + + 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); + + drm_connector = drmModeGetConnector (fd, + meta_kms_connector_get_id (connector)); + if (!drm_connector) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), + "Failed to get connector %u resources: %s", + meta_kms_connector_get_id (connector), + g_strerror (errno)); + return FALSE; + } + + found = FALSE; + for (i = 0; i < drm_connector->count_props; i++) + { + if (drm_connector->props[i] == prop_id) + { + *value = drm_connector->prop_values[i]; + found = TRUE; + break; + } + } + + drmModeFreeConnector (drm_connector); + + if (!found) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "Connector property %u not found", prop_id); + return FALSE; + } + + return TRUE; +} + static gboolean set_connector_property (MetaKmsImplDevice *impl_device, MetaKmsConnector *connector, @@ -107,6 +166,32 @@ set_connector_property (MetaKmsImplDevice *impl_device, return TRUE; } +static gboolean +process_power_save (MetaKmsImplDevice *impl_device, + GError **error) +{ + GList *l; + + for (l = meta_kms_impl_device_peek_connectors (impl_device); l; l = l->next) + { + MetaKmsConnector *connector = l->data; + + meta_topic (META_DEBUG_KMS, + "[simple] Setting DPMS of connector %u (%s) to OFF", + meta_kms_connector_get_id (connector), + meta_kms_impl_device_get_path (impl_device)); + + if (!set_connector_property (impl_device, + connector, + META_KMS_CONNECTOR_PROP_DPMS, + DRM_MODE_DPMS_OFF, + error)) + return FALSE; + } + + return TRUE; +} + static gboolean process_connector_update (MetaKmsImplDevice *impl_device, MetaKmsUpdate *update, @@ -116,23 +201,6 @@ process_connector_update (MetaKmsImplDevice *impl_device, MetaKmsConnectorUpdate *connector_update = update_entry; MetaKmsConnector *connector = connector_update->connector; - if (connector_update->dpms.has_update) - { - meta_topic (META_DEBUG_KMS, - "[simple] Setting DPMS on connector %u (%s) to %" - G_GUINT64_FORMAT, - meta_kms_connector_get_id (connector), - meta_kms_impl_device_get_path (impl_device), - connector_update->dpms.state); - - if (!set_connector_property (impl_device, - connector, - META_KMS_CONNECTOR_PROP_DPMS, - connector_update->dpms.state, - error)) - return FALSE; - } - if (connector_update->underscanning.has_update && connector_update->underscanning.is_active) { @@ -288,6 +356,7 @@ process_mode_set (MetaKmsImplDevice *impl_device, if (mode_set->mode) { MetaDrmBuffer *buffer; + GList *l; drm_mode = g_alloca (sizeof *drm_mode); *drm_mode = *meta_kms_mode_get_drm_mode (mode_set->mode); @@ -321,6 +390,34 @@ process_mode_set (MetaKmsImplDevice *impl_device, buffer = plane_assignment->buffer; fb_id = meta_drm_buffer_get_fb_id (buffer); + for (l = mode_set->connectors; l; l = l->next) + { + MetaKmsConnector *connector = l->data; + uint64_t dpms_value; + + if (!get_connector_property (impl_device, + connector, + META_KMS_CONNECTOR_PROP_DPMS, + &dpms_value, + error)) + return FALSE; + + if (dpms_value != DRM_MODE_DPMS_ON) + { + meta_topic (META_DEBUG_KMS, + "[simple] Setting DPMS of connector %u (%s) to ON", + meta_kms_connector_get_id (connector), + meta_kms_impl_device_get_path (impl_device)); + + if (!set_connector_property (impl_device, + connector, + META_KMS_CONNECTOR_PROP_DPMS, + DRM_MODE_DPMS_ON, + error)) + return FALSE; + } + } + meta_topic (META_DEBUG_KMS, "[simple] Setting mode of CRTC %u (%s) to %s", meta_kms_crtc_get_id (crtc), @@ -1256,12 +1353,12 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device, "[simple] Processing update %" G_GUINT64_FORMAT, meta_kms_update_get_sequence_number (update)); - if (!process_entries (impl_device, - update, - meta_kms_update_get_connector_updates (update), - process_connector_update, - &error)) - goto err; + if (meta_kms_update_is_power_save (update)) + { + if (!process_power_save (impl_device, &error)) + goto err; + goto out; + } if (!process_entries (impl_device, update, @@ -1270,6 +1367,13 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device, &error)) goto err; + if (!process_entries (impl_device, + update, + meta_kms_update_get_connector_updates (update), + process_connector_update, + &error)) + goto err; + if (!process_entries (impl_device, update, meta_kms_update_get_crtc_gammas (update), @@ -1283,6 +1387,7 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device, if (!maybe_dispatch_page_flips (impl_device, update, &failed_planes, &error)) goto err; +out: return meta_kms_feedback_new_passed (failed_planes); err: diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index d944b6c07..c762e5ee2 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -120,6 +120,15 @@ meta_kms_impl_device_copy_planes (MetaKmsImplDevice *impl_device) return g_list_copy (priv->planes); } +GList * +meta_kms_impl_device_peek_connectors (MetaKmsImplDevice *impl_device) +{ + MetaKmsImplDevicePrivate *priv = + meta_kms_impl_device_get_instance_private (impl_device); + + return priv->connectors; +} + const MetaKmsDeviceCaps * meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device) { diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h index c378b78c3..79db8a575 100644 --- a/src/backends/native/meta-kms-impl-device.h +++ b/src/backends/native/meta-kms-impl-device.h @@ -78,6 +78,8 @@ GList * meta_kms_impl_device_copy_crtcs (MetaKmsImplDevice *impl_device); GList * meta_kms_impl_device_copy_planes (MetaKmsImplDevice *impl_device); +GList * meta_kms_impl_device_peek_connectors (MetaKmsImplDevice *impl_device); + const MetaKmsDeviceCaps * meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device); GList * meta_kms_impl_device_copy_fallback_modes (MetaKmsImplDevice *impl_device); diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 02afdc934..6546eb915 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -70,11 +70,6 @@ typedef struct _MetaKmsConnectorUpdate uint64_t hborder; uint64_t vborder; } underscanning; - - struct { - gboolean has_update; - uint64_t state; - } dpms; } MetaKmsConnectorUpdate; typedef struct _MetaKmsPageFlipListener @@ -127,6 +122,8 @@ GList * meta_kms_update_get_connector_updates (MetaKmsUpdate *update); GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update); +gboolean meta_kms_update_is_power_save (MetaKmsUpdate *update); + void meta_kms_update_get_custom_page_flip_func (MetaKmsUpdate *update, MetaKmsCustomPageFlipFunc *custom_page_flip_func, gpointer *custom_page_flip_user_data); diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 450883865..36c1761c3 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -35,7 +35,8 @@ struct _MetaKmsUpdate gboolean is_locked; uint64_t sequence_number; - MetaPowerSave power_save; + gboolean power_save; + GList *mode_sets; GList *plane_assignments; GList *connector_updates; @@ -188,6 +189,7 @@ meta_kms_update_assign_plane (MetaKmsUpdate *update, g_assert (!meta_kms_update_is_locked (update)); g_assert (meta_kms_crtc_get_device (crtc) == update->device); + g_assert (!update->power_save); g_assert (meta_kms_plane_get_device (plane) == update->device); g_assert (meta_kms_plane_get_plane_type (plane) != META_KMS_PLANE_TYPE_PRIMARY || @@ -226,6 +228,7 @@ meta_kms_update_unassign_plane (MetaKmsUpdate *update, g_assert (!meta_kms_update_is_locked (update)); g_assert (meta_kms_crtc_get_device (crtc) == update->device); g_assert (meta_kms_plane_get_device (plane) == update->device); + g_assert (!update->power_save); plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1); *plane_assignment = (MetaKmsPlaneAssignment) { @@ -251,6 +254,7 @@ meta_kms_update_mode_set (MetaKmsUpdate *update, g_assert (!meta_kms_update_is_locked (update)); g_assert (meta_kms_crtc_get_device (crtc) == update->device); + g_assert (!update->power_save); mode_set = g_new0 (MetaKmsModeSet, 1); *mode_set = (MetaKmsModeSet) { @@ -296,6 +300,7 @@ meta_kms_update_set_underscanning (MetaKmsUpdate *update, g_assert (!meta_kms_update_is_locked (update)); g_assert (meta_kms_connector_get_device (connector) == update->device); + g_assert (!update->power_save); connector_update = ensure_connector_update (update, connector); connector_update->underscanning.has_update = TRUE; @@ -312,6 +317,7 @@ meta_kms_update_unset_underscanning (MetaKmsUpdate *update, g_assert (!meta_kms_update_is_locked (update)); g_assert (meta_kms_connector_get_device (connector) == update->device); + g_assert (!update->power_save); connector_update = ensure_connector_update (update, connector); connector_update->underscanning.has_update = TRUE; @@ -319,18 +325,15 @@ meta_kms_update_unset_underscanning (MetaKmsUpdate *update, } void -meta_kms_update_set_dpms_state (MetaKmsUpdate *update, - MetaKmsConnector *connector, - uint64_t state) +meta_kms_update_set_power_save (MetaKmsUpdate *update) { - MetaKmsConnectorUpdate *connector_update; - g_assert (!meta_kms_update_is_locked (update)); - g_assert (meta_kms_connector_get_device (connector) == update->device); + g_assert (!update->mode_sets); + g_assert (!update->plane_assignments); + g_assert (!update->connector_updates); + g_assert (!update->crtc_gammas); - connector_update = ensure_connector_update (update, connector); - connector_update->dpms.has_update = TRUE; - connector_update->dpms.state = state; + update->power_save = TRUE; } void @@ -375,6 +378,7 @@ meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update, g_assert (!meta_kms_update_is_locked (update)); g_assert (meta_kms_crtc_get_device (crtc) == update->device); + g_assert (!update->power_save); gamma = meta_kms_crtc_gamma_new (crtc, size, red, green, blue); @@ -409,6 +413,7 @@ meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update, gpointer user_data) { g_assert (!meta_kms_update_is_locked (update)); + g_assert (!update->power_save); update->custom_page_flip_func = func; update->custom_page_flip_user_data = user_data; @@ -523,6 +528,12 @@ meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update) return update->crtc_gammas; } +gboolean +meta_kms_update_is_power_save (MetaKmsUpdate *update) +{ + return update->power_save; +} + void meta_kms_update_lock (MetaKmsUpdate *update) { diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index 2274b3791..6438ff99b 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -95,9 +95,7 @@ void meta_kms_update_set_underscanning (MetaKmsUpdate *update, 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_set_power_save (MetaKmsUpdate *update); void meta_kms_update_mode_set (MetaKmsUpdate *update, MetaKmsCrtc *crtc, diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index 72bdc91d0..13fb196a1 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -143,7 +143,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, MetaBackend *backend = meta_monitor_manager_get_backend (manager); MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaKms *kms = meta_backend_native_get_kms (backend_native); - uint64_t state; GList *l; switch (mode) @@ -158,8 +157,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, break; } - state = meta_power_save_to_dpms_state (mode); - for (l = meta_backend_get_gpus (backend); l; l = l->next) { MetaGpuKms *gpu_kms = l->data; @@ -169,7 +166,7 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, g_autoptr (MetaKmsFeedback) kms_feedback = NULL; kms_update = meta_kms_ensure_pending_update (kms, kms_device); - meta_gpu_kms_set_power_save_mode (gpu_kms, state, kms_update); + meta_kms_update_set_power_save (kms_update); flags = META_KMS_UPDATE_FLAG_NONE; kms_feedback = meta_kms_post_pending_update_sync (kms, @@ -178,7 +175,7 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) { - g_warning ("Failed to set DPMS: %s", + g_warning ("Failed to enter power saving mode: %s", meta_kms_feedback_get_error (kms_feedback)->message); } } diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index ca744ba41..16d33d601 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -102,20 +102,6 @@ meta_output_kms_get_connector_id (MetaOutputKms *output_kms) return meta_kms_connector_get_id (output_kms->kms_connector); } -void -meta_output_kms_set_power_save_mode (MetaOutputKms *output_kms, - uint64_t dpms_state, - MetaKmsUpdate *kms_update) -{ - g_debug ("Setting DPMS state of connector %s to %" G_GUINT64_FORMAT, - meta_kms_connector_get_name (output_kms->kms_connector), - dpms_state); - - meta_kms_update_set_dpms_state (kms_update, - output_kms->kms_connector, - dpms_state); -} - gboolean meta_output_kms_can_clone (MetaOutputKms *output_kms, MetaOutputKms *other_output_kms)