Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: ui/display/chromeos/display_configurator.cc

Issue 1861593002: chromeos: Turn off displays on suspend (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: chromeos: Turn off displays on suspend Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/display/chromeos/display_configurator.h" 5 #include "ui/display/chromeos/display_configurator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 17 matching lines...) Expand all
28 namespace ui { 28 namespace ui {
29 29
30 namespace { 30 namespace {
31 31
32 typedef std::vector<const DisplayMode*> DisplayModeList; 32 typedef std::vector<const DisplayMode*> DisplayModeList;
33 33
34 // The delay to perform configuration after RRNotify. See the comment for 34 // The delay to perform configuration after RRNotify. See the comment for
35 // |configure_timer_|. 35 // |configure_timer_|.
36 const int kConfigureDelayMs = 500; 36 const int kConfigureDelayMs = 500;
37 37
38 // The delay spent before reading the display configuration after coming out of
39 // suspend. While coming out of suspend the display state may be updating. This
40 // is used to wait until the hardware had a chance to update the display state
41 // such that we read an up to date state.
42 const int kResumeDelayMs = 500;
43
44 // The EDID specification marks the top bit of the manufacturer id as reserved. 38 // The EDID specification marks the top bit of the manufacturer id as reserved.
45 const int16_t kReservedManufacturerID = static_cast<int16_t>(1 << 15); 39 const int16_t kReservedManufacturerID = static_cast<int16_t>(1 << 15);
46 40
47 struct DisplayState { 41 struct DisplayState {
48 DisplaySnapshot* display = nullptr; // Not owned. 42 DisplaySnapshot* display = nullptr; // Not owned.
49 43
50 // User-selected mode for the display. 44 // User-selected mode for the display.
51 const DisplayMode* selected_mode = nullptr; 45 const DisplayMode* selected_mode = nullptr;
52 46
53 // Mode used when displaying the same desktop on multiple displays. 47 // Mode used when displaying the same desktop on multiple displays.
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 463
470 DisplayConfigurator::DisplayConfigurator() 464 DisplayConfigurator::DisplayConfigurator()
471 : state_controller_(NULL), 465 : state_controller_(NULL),
472 mirroring_controller_(NULL), 466 mirroring_controller_(NULL),
473 is_panel_fitting_enabled_(false), 467 is_panel_fitting_enabled_(false),
474 configure_display_(base::SysInfo::IsRunningOnChromeOS()), 468 configure_display_(base::SysInfo::IsRunningOnChromeOS()),
475 current_display_state_(MULTIPLE_DISPLAY_STATE_INVALID), 469 current_display_state_(MULTIPLE_DISPLAY_STATE_INVALID),
476 current_power_state_(chromeos::DISPLAY_POWER_ALL_ON), 470 current_power_state_(chromeos::DISPLAY_POWER_ALL_ON),
477 requested_display_state_(MULTIPLE_DISPLAY_STATE_INVALID), 471 requested_display_state_(MULTIPLE_DISPLAY_STATE_INVALID),
478 requested_power_state_(chromeos::DISPLAY_POWER_ALL_ON), 472 requested_power_state_(chromeos::DISPLAY_POWER_ALL_ON),
479 requested_power_state_change_(false), 473 config_power_state_(chromeos::DISPLAY_POWER_ALL_ON),
480 requested_power_flags_(kSetDisplayPowerNoFlags), 474 power_state_change_(false),
475 config_power_flags_(kSetDisplayPowerNoFlags),
481 force_configure_(false), 476 force_configure_(false),
482 next_display_protection_client_id_(1), 477 next_display_protection_client_id_(1),
483 display_externally_controlled_(false), 478 display_externally_controlled_(false),
484 display_control_changing_(false), 479 display_control_changing_(false),
485 displays_suspended_(false), 480 displays_suspended_(false),
486 layout_manager_(new DisplayLayoutManagerImpl(this)), 481 layout_manager_(new DisplayLayoutManagerImpl(this)),
487 weak_ptr_factory_(this) { 482 weak_ptr_factory_(this) {
488 } 483 }
489 484
490 DisplayConfigurator::~DisplayConfigurator() { 485 DisplayConfigurator::~DisplayConfigurator() {
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 *display, degamma_lut, gamma_lut, correction_matrix); 832 *display, degamma_lut, gamma_lut, correction_matrix);
838 } 833 }
839 834
840 return false; 835 return false;
841 } 836 }
842 837
843 void DisplayConfigurator::PrepareForExit() { 838 void DisplayConfigurator::PrepareForExit() {
844 configure_display_ = false; 839 configure_display_ = false;
845 } 840 }
846 841
842 void DisplayConfigurator::SetDisplayPowerInternal(
843 chromeos::DisplayPowerState power_state,
844 int flags,
845 const ConfigurationCallback& callback) {
846 if (power_state == current_power_state_ &&
847 !(flags & kSetDisplayPowerForceProbe)) {
848 callback.Run(true);
849 return;
850 }
851
852 config_power_state_ = power_state;
853 power_state_change_ = true;
854 config_power_flags_ = flags;
855 queued_configuration_callbacks_.push_back(callback);
856
857 RunPendingConfiguration();
858 }
859
847 void DisplayConfigurator::SetDisplayPower( 860 void DisplayConfigurator::SetDisplayPower(
848 chromeos::DisplayPowerState power_state, 861 chromeos::DisplayPowerState power_state,
849 int flags, 862 int flags,
850 const ConfigurationCallback& callback) { 863 const ConfigurationCallback& callback) {
851 if (!configure_display_ || display_externally_controlled_) { 864 if (!configure_display_ || display_externally_controlled_) {
852 callback.Run(false); 865 callback.Run(false);
853 return; 866 return;
854 } 867 }
855 868
856 VLOG(1) << "SetDisplayPower: power_state=" 869 VLOG(1) << "SetDisplayPower: power_state="
857 << DisplayPowerStateToString(power_state) << " flags=" << flags 870 << DisplayPowerStateToString(power_state) << " flags=" << flags
858 << ", configure timer=" 871 << ", configure timer="
859 << (configure_timer_.IsRunning() ? "Running" : "Stopped"); 872 << (configure_timer_.IsRunning() ? "Running" : "Stopped");
860 if (power_state == requested_power_state_ &&
861 !(flags & kSetDisplayPowerForceProbe)) {
862 callback.Run(true);
863 return;
864 }
865 873
866 requested_power_state_ = power_state; 874 requested_power_state_ = power_state;
867 requested_power_state_change_ = true; 875 SetDisplayPowerInternal(requested_power_state_, flags, callback);
868 requested_power_flags_ = flags;
869 queued_configuration_callbacks_.push_back(callback);
870
871 RunPendingConfiguration();
872 } 876 }
873 877
874 void DisplayConfigurator::SetDisplayMode(MultipleDisplayState new_state) { 878 void DisplayConfigurator::SetDisplayMode(MultipleDisplayState new_state) {
875 if (!configure_display_ || display_externally_controlled_) 879 if (!configure_display_ || display_externally_controlled_)
876 return; 880 return;
877 881
878 VLOG(1) << "SetDisplayMode: state=" 882 VLOG(1) << "SetDisplayMode: state="
879 << MultipleDisplayStateToString(new_state); 883 << MultipleDisplayStateToString(new_state);
880 if (current_display_state_ == new_state) { 884 if (current_display_state_ == new_state) {
881 // Cancel software mirroring if the state is moving from 885 // Cancel software mirroring if the state is moving from
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 void DisplayConfigurator::AddObserver(Observer* observer) { 928 void DisplayConfigurator::AddObserver(Observer* observer) {
925 observers_.AddObserver(observer); 929 observers_.AddObserver(observer);
926 } 930 }
927 931
928 void DisplayConfigurator::RemoveObserver(Observer* observer) { 932 void DisplayConfigurator::RemoveObserver(Observer* observer) {
929 observers_.RemoveObserver(observer); 933 observers_.RemoveObserver(observer);
930 } 934 }
931 935
932 void DisplayConfigurator::SuspendDisplays( 936 void DisplayConfigurator::SuspendDisplays(
933 const ConfigurationCallback& callback) { 937 const ConfigurationCallback& callback) {
934 // If the display is off due to user inactivity and there's only a single
935 // internal display connected, switch to the all-on state before
936 // suspending. This shouldn't be very noticeable to the user since the
937 // backlight is off at this point, and doing this lets us resume directly
938 // into the "on" state, which greatly reduces resume times.
939 if (requested_power_state_ == chromeos::DISPLAY_POWER_ALL_OFF) {
940 SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON,
941 kSetDisplayPowerOnlyIfSingleInternalDisplay, callback);
942
943 // We need to make sure that the monitor configuration we just did actually
944 // completes before we return, because otherwise the X message could be
945 // racing with the HandleSuspendReadiness message.
946 native_display_delegate_->SyncWithServer();
947 } else {
948 callback.Run(true);
949 }
950
951 displays_suspended_ = true; 938 displays_suspended_ = true;
952 939
953 // Stop |configure_timer_| because we will force probe and configure all the 940 // Stop |configure_timer_| because we will force probe and configure all the
954 // displays at resume time anyway. 941 // displays at resume time anyway.
955 configure_timer_.Stop(); 942 configure_timer_.Stop();
943
944 // Turn off the displays for suspend. This way, if we wake up for lucid sleep,
945 // the displays will not turn on (all displays should be off for lucid sleep
946 // unless explicitly requested by lucid sleep code). Use
947 // SetDisplayPowerInternal so requested_power_state_ is maintained.
948 SetDisplayPowerInternal(chromeos::DISPLAY_POWER_ALL_OFF,
949 kSetDisplayPowerNoFlags, callback);
950
951 // We need to make sure that the monitor configuration we just did actually
952 // completes before we return.
953 native_display_delegate_->SyncWithServer();
956 } 954 }
957 955
958 void DisplayConfigurator::ResumeDisplays() { 956 void DisplayConfigurator::ResumeDisplays() {
957 chromeos::DisplayPowerState power_state = chromeos::DISPLAY_POWER_ALL_ON;
958
959 // Restore requested_power_state_ unless it's DISPLAY_POWER_ALL_OFF.
960 if (requested_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF) {
Daniel Erat 2016/04/21 22:16:41 can you explain this to me again (and also update
dbasehore 2016/04/21 22:35:10 Might be able to get rid of this. If we call SetDi
961 power_state = requested_power_state_;
962 }
963
959 displays_suspended_ = false; 964 displays_suspended_ = false;
960 965 // If we aren't restoring requested_power_state_, we need to make sure we
961 configure_timer_.Start( 966 // overwrite it with DISPLAY_POWER_ALL_ON, so call SetDisplayPower.
962 FROM_HERE, 967 SetDisplayPower(power_state, kSetDisplayPowerForceProbe,
Daniel Erat 2016/04/21 22:16:41 it seems weird to call the public method here. if
dbasehore 2016/04/21 22:35:10 Works for me. Will do.
963 base::TimeDelta::FromMilliseconds(kResumeDelayMs), 968 base::Bind(&DoNothing));
964 base::Bind(&DisplayConfigurator::RestoreRequestedPowerStateAfterResume,
965 base::Unretained(this)));
966 } 969 }
967 970
968 void DisplayConfigurator::ConfigureDisplays() { 971 void DisplayConfigurator::ConfigureDisplays() {
969 if (!configure_display_ || display_externally_controlled_) 972 if (!configure_display_ || display_externally_controlled_)
970 return; 973 return;
971 974
972 force_configure_ = true; 975 force_configure_ = true;
973 RunPendingConfiguration(); 976 RunPendingConfiguration();
974 } 977 }
975 978
976 void DisplayConfigurator::RunPendingConfiguration() { 979 void DisplayConfigurator::RunPendingConfiguration() {
977 // Configuration task is currently running. Do not start a second 980 // Configuration task is currently running. Do not start a second
978 // configuration. 981 // configuration.
979 if (configuration_task_) 982 if (configuration_task_)
980 return; 983 return;
981 984
982 if (!ShouldRunConfigurationTask()) { 985 if (!ShouldRunConfigurationTask()) {
983 LOG(ERROR) << "Called RunPendingConfiguration without any changes" 986 LOG(ERROR) << "Called RunPendingConfiguration without any changes"
984 " requested"; 987 " requested";
985 CallAndClearQueuedCallbacks(true); 988 CallAndClearQueuedCallbacks(true);
986 return; 989 return;
987 } 990 }
988 991
989 configuration_task_.reset(new UpdateDisplayConfigurationTask( 992 configuration_task_.reset(new UpdateDisplayConfigurationTask(
990 native_display_delegate_.get(), layout_manager_.get(), 993 native_display_delegate_.get(), layout_manager_.get(),
991 requested_display_state_, requested_power_state_, requested_power_flags_, 994 requested_display_state_, config_power_state_, config_power_flags_,
992 0, force_configure_, base::Bind(&DisplayConfigurator::OnConfigured, 995 0, force_configure_, base::Bind(&DisplayConfigurator::OnConfigured,
993 weak_ptr_factory_.GetWeakPtr()))); 996 weak_ptr_factory_.GetWeakPtr())));
994 configuration_task_->set_virtual_display_snapshots( 997 configuration_task_->set_virtual_display_snapshots(
995 virtual_display_snapshots_.get()); 998 virtual_display_snapshots_.get());
996 999
997 // Reset the flags before running the task; otherwise it may end up scheduling 1000 // Reset the flags before running the task; otherwise it may end up scheduling
998 // another configuration. 1001 // another configuration.
999 force_configure_ = false; 1002 force_configure_ = false;
1000 requested_power_flags_ = kSetDisplayPowerNoFlags; 1003 config_power_flags_ = kSetDisplayPowerNoFlags;
1001 requested_power_state_change_ = false; 1004 power_state_change_ = false;
1002 requested_display_state_ = MULTIPLE_DISPLAY_STATE_INVALID; 1005 requested_display_state_ = MULTIPLE_DISPLAY_STATE_INVALID;
1003 1006
1004 DCHECK(in_progress_configuration_callbacks_.empty()); 1007 DCHECK(in_progress_configuration_callbacks_.empty());
1005 in_progress_configuration_callbacks_.swap(queued_configuration_callbacks_); 1008 in_progress_configuration_callbacks_.swap(queued_configuration_callbacks_);
1006 1009
1007 configuration_task_->Run(); 1010 configuration_task_->Run();
1008 } 1011 }
1009 1012
1010 void DisplayConfigurator::OnConfigured( 1013 void DisplayConfigurator::OnConfigured(
1011 bool success, 1014 bool success,
(...skipping 19 matching lines...) Expand all
1031 new_display_state == MULTIPLE_DISPLAY_STATE_HEADLESS || 1034 new_display_state == MULTIPLE_DISPLAY_STATE_HEADLESS ||
1032 new_power_state == chromeos::DISPLAY_POWER_ALL_OFF); 1035 new_power_state == chromeos::DISPLAY_POWER_ALL_OFF);
1033 1036
1034 if (!framebuffer_size.IsEmpty()) 1037 if (!framebuffer_size.IsEmpty())
1035 framebuffer_size_ = framebuffer_size; 1038 framebuffer_size_ = framebuffer_size;
1036 1039
1037 // If the requested power state hasn't changed then make sure that value 1040 // If the requested power state hasn't changed then make sure that value
1038 // gets updated as well since the last requested value may have been 1041 // gets updated as well since the last requested value may have been
1039 // dependent on certain conditions (ie: if only the internal monitor was 1042 // dependent on certain conditions (ie: if only the internal monitor was
1040 // present). 1043 // present).
1041 if (!requested_power_state_change_) 1044 if (!power_state_change_)
1042 requested_power_state_ = new_power_state; 1045 requested_power_state_ = new_power_state;
1043 1046
1044 if (old_power_state != current_power_state_) 1047 if (old_power_state != current_power_state_)
1045 NotifyPowerStateObservers(); 1048 NotifyPowerStateObservers();
1046 } 1049 }
1047 1050
1048 configuration_task_.reset(); 1051 configuration_task_.reset();
1049 NotifyDisplayStateObservers(success, new_display_state); 1052 NotifyDisplayStateObservers(success, new_display_state);
1050 CallAndClearInProgressCallbacks(success); 1053 CallAndClearInProgressCallbacks(success);
1051 1054
(...skipping 13 matching lines...) Expand all
1065 bool DisplayConfigurator::ShouldRunConfigurationTask() const { 1068 bool DisplayConfigurator::ShouldRunConfigurationTask() const {
1066 if (force_configure_) 1069 if (force_configure_)
1067 return true; 1070 return true;
1068 1071
1069 // Schedule if there is a request to change the display state. 1072 // Schedule if there is a request to change the display state.
1070 if (requested_display_state_ != current_display_state_ && 1073 if (requested_display_state_ != current_display_state_ &&
1071 requested_display_state_ != MULTIPLE_DISPLAY_STATE_INVALID) 1074 requested_display_state_ != MULTIPLE_DISPLAY_STATE_INVALID)
1072 return true; 1075 return true;
1073 1076
1074 // Schedule if there is a request to change the power state. 1077 // Schedule if there is a request to change the power state.
1075 if (requested_power_state_change_) 1078 if (power_state_change_)
1076 return true; 1079 return true;
1077 1080
1078 return false; 1081 return false;
1079 } 1082 }
1080 1083
1081 void DisplayConfigurator::CallAndClearInProgressCallbacks(bool success) { 1084 void DisplayConfigurator::CallAndClearInProgressCallbacks(bool success) {
1082 for (const auto& callback : in_progress_configuration_callbacks_) 1085 for (const auto& callback : in_progress_configuration_callbacks_)
1083 callback.Run(success); 1086 callback.Run(success);
1084 1087
1085 in_progress_configuration_callbacks_.clear(); 1088 in_progress_configuration_callbacks_.clear();
1086 } 1089 }
1087 1090
1088 void DisplayConfigurator::CallAndClearQueuedCallbacks(bool success) { 1091 void DisplayConfigurator::CallAndClearQueuedCallbacks(bool success) {
1089 for (const auto& callback : queued_configuration_callbacks_) 1092 for (const auto& callback : queued_configuration_callbacks_)
1090 callback.Run(success); 1093 callback.Run(success);
1091 1094
1092 queued_configuration_callbacks_.clear(); 1095 queued_configuration_callbacks_.clear();
1093 } 1096 }
1094 1097
1095 void DisplayConfigurator::RestoreRequestedPowerStateAfterResume() {
1096 // Force probing to ensure that we pick up any changes that were made while
1097 // the system was suspended.
1098 SetDisplayPower(requested_power_state_, kSetDisplayPowerForceProbe,
1099 base::Bind(&DoNothing));
1100 }
1101
1102 void DisplayConfigurator::NotifyDisplayStateObservers( 1098 void DisplayConfigurator::NotifyDisplayStateObservers(
1103 bool success, 1099 bool success,
1104 MultipleDisplayState attempted_state) { 1100 MultipleDisplayState attempted_state) {
1105 if (success) { 1101 if (success) {
1106 FOR_EACH_OBSERVER( 1102 FOR_EACH_OBSERVER(
1107 Observer, observers_, OnDisplayModeChanged(cached_displays_)); 1103 Observer, observers_, OnDisplayModeChanged(cached_displays_));
1108 } else { 1104 } else {
1109 FOR_EACH_OBSERVER( 1105 FOR_EACH_OBSERVER(
1110 Observer, observers_, OnDisplayModeChangeFailed(cached_displays_, 1106 Observer, observers_, OnDisplayModeChangeFailed(cached_displays_,
1111 attempted_state)); 1107 attempted_state));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 last_virtual_display_id_ = max_display_id & 0xff; 1150 last_virtual_display_id_ = max_display_id & 0xff;
1155 1151
1156 return true; 1152 return true;
1157 } 1153 }
1158 1154
1159 bool DisplayConfigurator::IsDisplayOn() const { 1155 bool DisplayConfigurator::IsDisplayOn() const {
1160 return current_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF; 1156 return current_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF;
1161 } 1157 }
1162 1158
1163 } // namespace ui 1159 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698