Commit fee6ba82 authored by dbasehore's avatar dbasehore Committed by Commit bot

chromeos: Turn off displays on suspend

To handle lucid sleep (where we need to silently resume the system), turn
off the displays on suspend. This also removes the delay for restoring the
display state added in "On resume perform a delayed call to
SetDisplayPower()" According to the bug for that change, it didn't seem to
help with the issue anyways.

BUG=535021
TEST=suspend/resume of various cros platforms with/without external monitor
connected

Review URL: https://codereview.chromium.org/1861593002

Cr-Commit-Position: refs/heads/master@{#389875}
parent cc58c0d6
...@@ -35,12 +35,6 @@ typedef std::vector<const DisplayMode*> DisplayModeList; ...@@ -35,12 +35,6 @@ typedef std::vector<const DisplayMode*> DisplayModeList;
// |configure_timer_|. // |configure_timer_|.
const int kConfigureDelayMs = 500; const int kConfigureDelayMs = 500;
// The delay spent before reading the display configuration after coming out of
// suspend. While coming out of suspend the display state may be updating. This
// is used to wait until the hardware had a chance to update the display state
// such that we read an up to date state.
const int kResumeDelayMs = 500;
// The EDID specification marks the top bit of the manufacturer id as reserved. // The EDID specification marks the top bit of the manufacturer id as reserved.
const int16_t kReservedManufacturerID = static_cast<int16_t>(1 << 15); const int16_t kReservedManufacturerID = static_cast<int16_t>(1 << 15);
...@@ -476,8 +470,9 @@ DisplayConfigurator::DisplayConfigurator() ...@@ -476,8 +470,9 @@ DisplayConfigurator::DisplayConfigurator()
current_power_state_(chromeos::DISPLAY_POWER_ALL_ON), current_power_state_(chromeos::DISPLAY_POWER_ALL_ON),
requested_display_state_(MULTIPLE_DISPLAY_STATE_INVALID), requested_display_state_(MULTIPLE_DISPLAY_STATE_INVALID),
requested_power_state_(chromeos::DISPLAY_POWER_ALL_ON), requested_power_state_(chromeos::DISPLAY_POWER_ALL_ON),
requested_power_state_change_(false), pending_power_state_(chromeos::DISPLAY_POWER_ALL_ON),
requested_power_flags_(kSetDisplayPowerNoFlags), has_pending_power_state_(false),
pending_power_flags_(kSetDisplayPowerNoFlags),
force_configure_(false), force_configure_(false),
next_display_protection_client_id_(1), next_display_protection_client_id_(1),
display_externally_controlled_(false), display_externally_controlled_(false),
...@@ -844,6 +839,24 @@ void DisplayConfigurator::PrepareForExit() { ...@@ -844,6 +839,24 @@ void DisplayConfigurator::PrepareForExit() {
configure_display_ = false; configure_display_ = false;
} }
void DisplayConfigurator::SetDisplayPowerInternal(
chromeos::DisplayPowerState power_state,
int flags,
const ConfigurationCallback& callback) {
if (power_state == current_power_state_ &&
!(flags & kSetDisplayPowerForceProbe)) {
callback.Run(true);
return;
}
pending_power_state_ = power_state;
has_pending_power_state_ = true;
pending_power_flags_ = flags;
queued_configuration_callbacks_.push_back(callback);
RunPendingConfiguration();
}
void DisplayConfigurator::SetDisplayPower( void DisplayConfigurator::SetDisplayPower(
chromeos::DisplayPowerState power_state, chromeos::DisplayPowerState power_state,
int flags, int flags,
...@@ -857,18 +870,9 @@ void DisplayConfigurator::SetDisplayPower( ...@@ -857,18 +870,9 @@ void DisplayConfigurator::SetDisplayPower(
<< DisplayPowerStateToString(power_state) << " flags=" << flags << DisplayPowerStateToString(power_state) << " flags=" << flags
<< ", configure timer=" << ", configure timer="
<< (configure_timer_.IsRunning() ? "Running" : "Stopped"); << (configure_timer_.IsRunning() ? "Running" : "Stopped");
if (power_state == requested_power_state_ &&
!(flags & kSetDisplayPowerForceProbe)) {
callback.Run(true);
return;
}
requested_power_state_ = power_state; requested_power_state_ = power_state;
requested_power_state_change_ = true; SetDisplayPowerInternal(requested_power_state_, flags, callback);
requested_power_flags_ = flags;
queued_configuration_callbacks_.push_back(callback);
RunPendingConfiguration();
} }
void DisplayConfigurator::SetDisplayMode(MultipleDisplayState new_state) { void DisplayConfigurator::SetDisplayMode(MultipleDisplayState new_state) {
...@@ -931,21 +935,9 @@ void DisplayConfigurator::RemoveObserver(Observer* observer) { ...@@ -931,21 +935,9 @@ void DisplayConfigurator::RemoveObserver(Observer* observer) {
void DisplayConfigurator::SuspendDisplays( void DisplayConfigurator::SuspendDisplays(
const ConfigurationCallback& callback) { const ConfigurationCallback& callback) {
// If the display is off due to user inactivity and there's only a single if (!configure_display_ || display_externally_controlled_) {
// internal display connected, switch to the all-on state before callback.Run(false);
// suspending. This shouldn't be very noticeable to the user since the return;
// backlight is off at this point, and doing this lets us resume directly
// into the "on" state, which greatly reduces resume times.
if (requested_power_state_ == chromeos::DISPLAY_POWER_ALL_OFF) {
SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON,
kSetDisplayPowerOnlyIfSingleInternalDisplay, callback);
// We need to make sure that the monitor configuration we just did actually
// completes before we return, because otherwise the X message could be
// racing with the HandleSuspendReadiness message.
native_display_delegate_->SyncWithServer();
} else {
callback.Run(true);
} }
displays_suspended_ = true; displays_suspended_ = true;
...@@ -953,16 +945,29 @@ void DisplayConfigurator::SuspendDisplays( ...@@ -953,16 +945,29 @@ void DisplayConfigurator::SuspendDisplays(
// Stop |configure_timer_| because we will force probe and configure all the // Stop |configure_timer_| because we will force probe and configure all the
// displays at resume time anyway. // displays at resume time anyway.
configure_timer_.Stop(); configure_timer_.Stop();
// Turn off the displays for suspend. This way, if we wake up for lucid sleep,
// the displays will not turn on (all displays should be off for lucid sleep
// unless explicitly requested by lucid sleep code). Use
// SetDisplayPowerInternal so requested_power_state_ is maintained.
SetDisplayPowerInternal(chromeos::DISPLAY_POWER_ALL_OFF,
kSetDisplayPowerNoFlags, callback);
// We need to make sure that the monitor configuration we just did actually
// completes before we return.
native_display_delegate_->SyncWithServer();
} }
void DisplayConfigurator::ResumeDisplays() { void DisplayConfigurator::ResumeDisplays() {
if (!configure_display_ || display_externally_controlled_)
return;
displays_suspended_ = false; displays_suspended_ = false;
configure_timer_.Start( // If requested_power_state_ is ALL_OFF due to idle suspend, powerd will turn
FROM_HERE, // the display power on when it enables the backlight.
base::TimeDelta::FromMilliseconds(kResumeDelayMs), SetDisplayPower(requested_power_state_, kSetDisplayPowerNoFlags,
base::Bind(&DisplayConfigurator::RestoreRequestedPowerStateAfterResume, base::Bind(&DoNothing));
base::Unretained(this)));
} }
void DisplayConfigurator::ConfigureDisplays() { void DisplayConfigurator::ConfigureDisplays() {
...@@ -988,7 +993,7 @@ void DisplayConfigurator::RunPendingConfiguration() { ...@@ -988,7 +993,7 @@ void DisplayConfigurator::RunPendingConfiguration() {
configuration_task_.reset(new UpdateDisplayConfigurationTask( configuration_task_.reset(new UpdateDisplayConfigurationTask(
native_display_delegate_.get(), layout_manager_.get(), native_display_delegate_.get(), layout_manager_.get(),
requested_display_state_, requested_power_state_, requested_power_flags_, requested_display_state_, pending_power_state_, pending_power_flags_,
0, force_configure_, base::Bind(&DisplayConfigurator::OnConfigured, 0, force_configure_, base::Bind(&DisplayConfigurator::OnConfigured,
weak_ptr_factory_.GetWeakPtr()))); weak_ptr_factory_.GetWeakPtr())));
configuration_task_->set_virtual_display_snapshots( configuration_task_->set_virtual_display_snapshots(
...@@ -997,8 +1002,8 @@ void DisplayConfigurator::RunPendingConfiguration() { ...@@ -997,8 +1002,8 @@ void DisplayConfigurator::RunPendingConfiguration() {
// Reset the flags before running the task; otherwise it may end up scheduling // Reset the flags before running the task; otherwise it may end up scheduling
// another configuration. // another configuration.
force_configure_ = false; force_configure_ = false;
requested_power_flags_ = kSetDisplayPowerNoFlags; pending_power_flags_ = kSetDisplayPowerNoFlags;
requested_power_state_change_ = false; has_pending_power_state_ = false;
requested_display_state_ = MULTIPLE_DISPLAY_STATE_INVALID; requested_display_state_ = MULTIPLE_DISPLAY_STATE_INVALID;
DCHECK(in_progress_configuration_callbacks_.empty()); DCHECK(in_progress_configuration_callbacks_.empty());
...@@ -1034,12 +1039,12 @@ void DisplayConfigurator::OnConfigured( ...@@ -1034,12 +1039,12 @@ void DisplayConfigurator::OnConfigured(
if (!framebuffer_size.IsEmpty()) if (!framebuffer_size.IsEmpty())
framebuffer_size_ = framebuffer_size; framebuffer_size_ = framebuffer_size;
// If the requested power state hasn't changed then make sure that value // If the pending power state hasn't changed then make sure that value
// gets updated as well since the last requested value may have been // gets updated as well since the last requested value may have been
// dependent on certain conditions (ie: if only the internal monitor was // dependent on certain conditions (ie: if only the internal monitor was
// present). // present).
if (!requested_power_state_change_) if (!has_pending_power_state_)
requested_power_state_ = new_power_state; pending_power_state_ = new_power_state;
if (old_power_state != current_power_state_) if (old_power_state != current_power_state_)
NotifyPowerStateObservers(); NotifyPowerStateObservers();
...@@ -1072,7 +1077,7 @@ bool DisplayConfigurator::ShouldRunConfigurationTask() const { ...@@ -1072,7 +1077,7 @@ bool DisplayConfigurator::ShouldRunConfigurationTask() const {
return true; return true;
// Schedule if there is a request to change the power state. // Schedule if there is a request to change the power state.
if (requested_power_state_change_) if (has_pending_power_state_)
return true; return true;
return false; return false;
...@@ -1092,13 +1097,6 @@ void DisplayConfigurator::CallAndClearQueuedCallbacks(bool success) { ...@@ -1092,13 +1097,6 @@ void DisplayConfigurator::CallAndClearQueuedCallbacks(bool success) {
queued_configuration_callbacks_.clear(); queued_configuration_callbacks_.clear();
} }
void DisplayConfigurator::RestoreRequestedPowerStateAfterResume() {
// Force probing to ensure that we pick up any changes that were made while
// the system was suspended.
SetDisplayPower(requested_power_state_, kSetDisplayPowerForceProbe,
base::Bind(&DoNothing));
}
void DisplayConfigurator::NotifyDisplayStateObservers( void DisplayConfigurator::NotifyDisplayStateObservers(
bool success, bool success,
MultipleDisplayState attempted_state) { MultipleDisplayState attempted_state) {
......
...@@ -300,13 +300,15 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { ...@@ -300,13 +300,15 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver {
typedef std::map<ContentProtectionClientId, ContentProtections> typedef std::map<ContentProtectionClientId, ContentProtections>
ProtectionRequests; ProtectionRequests;
// Updates |pending_*| members and applies the passed-in state. |callback| is
// invoked (perhaps synchronously) on completion.
void SetDisplayPowerInternal(chromeos::DisplayPowerState power_state,
int flags,
const ConfigurationCallback& callback);
// Configures displays. Invoked by |configure_timer_|. // Configures displays. Invoked by |configure_timer_|.
void ConfigureDisplays(); void ConfigureDisplays();
// Restores |requested_power_state_| after the system has resumed,
// additionally forcing a probe. Invoked by |configure_timer_|.
void RestoreRequestedPowerStateAfterResume();
// Notifies observers about an attempted state change. // Notifies observers about an attempted state change.
void NotifyDisplayStateObservers(bool success, void NotifyDisplayStateObservers(bool success,
MultipleDisplayState attempted_state); MultipleDisplayState attempted_state);
...@@ -394,11 +396,15 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { ...@@ -394,11 +396,15 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver {
// Stores the requested power state. // Stores the requested power state.
chromeos::DisplayPowerState requested_power_state_; chromeos::DisplayPowerState requested_power_state_;
// True if |requested_power_state_| has been changed due to a user request. // The power state used by RunPendingConfiguration(). May be
bool requested_power_state_change_; // |requested_power_state_| or DISPLAY_POWER_ALL_OFF for suspend.
chromeos::DisplayPowerState pending_power_state_;
// True if |pending_power_state_| has been changed.
bool has_pending_power_state_;
// Bitwise-or value of the |kSetDisplayPower*| flags defined above. // Bitwise-or value of the |kSetDisplayPower*| flags defined above.
int requested_power_flags_; int pending_power_flags_;
// List of callbacks from callers waiting for the display configuration to // List of callbacks from callers waiting for the display configuration to
// start/finish. Note these callbacks belong to the pending request, not a // start/finish. Note these callbacks belong to the pending request, not a
......
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