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

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

Issue 2427843002: Delay display configuration after waking up from suspend with multi displays (Closed)
Patch Set: Working solution on stumpy Created 4 years, 1 month 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 13 matching lines...) Expand all
24 #include "ui/display/types/display_snapshot.h" 24 #include "ui/display/types/display_snapshot.h"
25 #include "ui/display/types/native_display_delegate.h" 25 #include "ui/display/types/native_display_delegate.h"
26 #include "ui/display/util/display_util.h" 26 #include "ui/display/util/display_util.h"
27 27
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
35 // |configure_timer_|.
36 const int kConfigureDelayMs = 500;
37
38 // The EDID specification marks the top bit of the manufacturer id as reserved. 34 // The EDID specification marks the top bit of the manufacturer id as reserved.
39 const int16_t kReservedManufacturerID = static_cast<int16_t>(1 << 15); 35 const int16_t kReservedManufacturerID = static_cast<int16_t>(1 << 15);
40 36
41 struct DisplayState { 37 struct DisplayState {
42 DisplaySnapshot* display = nullptr; // Not owned. 38 DisplaySnapshot* display = nullptr; // Not owned.
43 39
44 // User-selected mode for the display. 40 // User-selected mode for the display.
45 const DisplayMode* selected_mode = nullptr; 41 const DisplayMode* selected_mode = nullptr;
46 42
47 // Mode used when displaying the same desktop on multiple displays. 43 // Mode used when displaying the same desktop on multiple displays.
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 !(flags & kSetDisplayPowerForceProbe)) { 851 !(flags & kSetDisplayPowerForceProbe)) {
856 callback.Run(true); 852 callback.Run(true);
857 return; 853 return;
858 } 854 }
859 855
860 pending_power_state_ = power_state; 856 pending_power_state_ = power_state;
861 has_pending_power_state_ = true; 857 has_pending_power_state_ = true;
862 pending_power_flags_ = flags; 858 pending_power_flags_ = flags;
863 queued_configuration_callbacks_.push_back(callback); 859 queued_configuration_callbacks_.push_back(callback);
864 860
861 if (configure_timer_.IsRunning()) {
862 // If there is a configuration task scheduled, avoid performing
863 // configuration immediately. Instead reset the timer to wait for things to
864 // settle.
865 configure_timer_.Reset();
866 return;
867 }
868
865 RunPendingConfiguration(); 869 RunPendingConfiguration();
866 } 870 }
867 871
868 void DisplayConfigurator::SetDisplayPower( 872 void DisplayConfigurator::SetDisplayPower(
869 chromeos::DisplayPowerState power_state, 873 chromeos::DisplayPowerState power_state,
870 int flags, 874 int flags,
871 const ConfigurationCallback& callback) { 875 const ConfigurationCallback& callback) {
872 if (!configure_display_ || display_externally_controlled_) { 876 if (!configure_display_ || display_externally_controlled_) {
873 callback.Run(false); 877 callback.Run(false);
874 return; 878 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 // Don't do anything if the displays are currently suspended. Instead we will 913 // Don't do anything if the displays are currently suspended. Instead we will
910 // probe and reconfigure the displays if necessary in ResumeDisplays(). 914 // probe and reconfigure the displays if necessary in ResumeDisplays().
911 if (displays_suspended_) { 915 if (displays_suspended_) {
912 VLOG(1) << "Displays are currently suspended. Not attempting to " 916 VLOG(1) << "Displays are currently suspended. Not attempting to "
913 << "reconfigure them."; 917 << "reconfigure them.";
914 return; 918 return;
915 } 919 }
916 920
917 // Configure displays with |kConfigureDelayMs| delay, 921 // Configure displays with |kConfigureDelayMs| delay,
918 // so that time-consuming ConfigureDisplays() won't be called multiple times. 922 // so that time-consuming ConfigureDisplays() won't be called multiple times.
919 if (configure_timer_.IsRunning()) { 923 if (configure_timer_.IsRunning() &&
920 // Note: when the timer is running it is possible that a different task 924 configure_timer_.GetCurrentDelay() <=
921 // (RestoreRequestedPowerStateAfterResume()) is scheduled. In these cases, 925 base::TimeDelta::FromMilliseconds(kConfigureDelayMs)) {
922 // prefer the already scheduled task to ConfigureDisplays() since 926 // Avoid resetting the timer to a huge delay if we are currently pending
923 // ConfigureDisplays() performs only basic configuration while 927 // the delayed configuration after waking up from suspend.
924 // RestoreRequestedPowerStateAfterResume() will perform additional
925 // operations.
926 configure_timer_.Reset(); 928 configure_timer_.Reset();
927 } else { 929 } else {
928 configure_timer_.Start( 930 configure_timer_.Start(
929 FROM_HERE, 931 FROM_HERE,
930 base::TimeDelta::FromMilliseconds(kConfigureDelayMs), 932 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
931 this, 933 this,
932 &DisplayConfigurator::ConfigureDisplays); 934 &DisplayConfigurator::ConfigureDisplays);
933 } 935 }
934 } 936 }
935 937
(...skipping 24 matching lines...) Expand all
960 // SetDisplayPowerInternal so requested_power_state_ is maintained. 962 // SetDisplayPowerInternal so requested_power_state_ is maintained.
961 SetDisplayPowerInternal(chromeos::DISPLAY_POWER_ALL_OFF, 963 SetDisplayPowerInternal(chromeos::DISPLAY_POWER_ALL_OFF,
962 kSetDisplayPowerNoFlags, callback); 964 kSetDisplayPowerNoFlags, callback);
963 965
964 // We need to make sure that the monitor configuration we just did actually 966 // We need to make sure that the monitor configuration we just did actually
965 // completes before we return. 967 // completes before we return.
966 native_display_delegate_->SyncWithServer(); 968 native_display_delegate_->SyncWithServer();
967 } 969 }
968 970
969 void DisplayConfigurator::ResumeDisplays() { 971 void DisplayConfigurator::ResumeDisplays() {
970 if (!configure_display_ || display_externally_controlled_) 972 ResumeDisplaysInternal(base::Bind(&DoNothing));
Daniel Erat 2016/10/21 21:09:44 this seems weird: a helper method that's only call
afakhry 2016/10/22 00:28:48 Unittests need to provide a callback, but clients
971 return;
972
973 displays_suspended_ = false;
974
975 // If requested_power_state_ is ALL_OFF due to idle suspend, powerd will turn
976 // the display power on when it enables the backlight.
977 SetDisplayPower(requested_power_state_, kSetDisplayPowerNoFlags,
978 base::Bind(&DoNothing));
979 } 973 }
980 974
981 void DisplayConfigurator::ConfigureDisplays() { 975 void DisplayConfigurator::ConfigureDisplays() {
982 if (!configure_display_ || display_externally_controlled_) 976 if (!configure_display_ || display_externally_controlled_)
983 return; 977 return;
984 978
985 force_configure_ = true; 979 force_configure_ = true;
986 RunPendingConfiguration(); 980 RunPendingConfiguration();
987 } 981 }
988 982
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 max_display_id = std::max(max_display_id, display->display_id()); 1152 max_display_id = std::max(max_display_id, display->display_id());
1159 last_virtual_display_id_ = max_display_id & 0xff; 1153 last_virtual_display_id_ = max_display_id & 0xff;
1160 1154
1161 return true; 1155 return true;
1162 } 1156 }
1163 1157
1164 bool DisplayConfigurator::IsDisplayOn() const { 1158 bool DisplayConfigurator::IsDisplayOn() const {
1165 return current_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF; 1159 return current_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF;
1166 } 1160 }
1167 1161
1162 void DisplayConfigurator::ResumeDisplaysInternal(
1163 const ConfigurationCallback& callback) {
1164 if (!configure_display_ || display_externally_controlled_)
1165 return;
1166
1167 displays_suspended_ = false;
1168
1169 // If requested_power_state_ is ALL_OFF due to idle suspend, powerd will turn
1170 // the display power on when it enables the backlight.
Daniel Erat 2016/10/21 21:09:44 did you mean to keep this comment above the SetDis
afakhry 2016/10/22 00:28:48 Yep, thanks for catching that. Done.
1171 if (current_display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR ||
1172 current_display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED ||
1173 current_display_state_ == MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED) {
1174 // When waking up from suspend while being in a multi display mode, we
1175 // schedule a delayed forced configuration, which will make
1176 // SetDisplayPowerInternal() avoid performing the configuration immediately.
1177 // This gives a chance to wait for all displays to be added and detected
1178 // before configuration is performed.
1179 configure_timer_.Start(FROM_HERE,
1180 base::TimeDelta::FromMilliseconds(
1181 kResumeConfigureMultiDisplayDelayMs),
1182 this,
1183 &DisplayConfigurator::ConfigureDisplays);
1184 }
1185
1186 SetDisplayPower(requested_power_state_, kSetDisplayPowerNoFlags, callback);
1187 }
1188
1168 } // namespace ui 1189 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698