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

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: Painful Rebase 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 13 matching lines...) Expand all
61 bool DisplayConfigurator::TestApi::TriggerConfigureTimeout() { 57 bool DisplayConfigurator::TestApi::TriggerConfigureTimeout() {
62 if (configurator_->configure_timer_.IsRunning()) { 58 if (configurator_->configure_timer_.IsRunning()) {
63 configurator_->configure_timer_.user_task().Run(); 59 configurator_->configure_timer_.user_task().Run();
64 configurator_->configure_timer_.Stop(); 60 configurator_->configure_timer_.Stop();
65 return true; 61 return true;
66 } else { 62 } else {
67 return false; 63 return false;
68 } 64 }
69 } 65 }
70 66
67 base::TimeDelta DisplayConfigurator::TestApi::GetConfigureDelay() const {
68 return configurator_->configure_timer_.IsRunning()
69 ? configurator_->configure_timer_.GetCurrentDelay()
70 : base::TimeDelta();
71 }
72
71 //////////////////////////////////////////////////////////////////////////////// 73 ////////////////////////////////////////////////////////////////////////////////
72 // DisplayConfigurator::DisplayLayoutManagerImpl implementation 74 // DisplayConfigurator::DisplayLayoutManagerImpl implementation
73 75
74 class DisplayConfigurator::DisplayLayoutManagerImpl 76 class DisplayConfigurator::DisplayLayoutManagerImpl
75 : public DisplayLayoutManager { 77 : public DisplayLayoutManager {
76 public: 78 public:
77 DisplayLayoutManagerImpl(DisplayConfigurator* configurator); 79 DisplayLayoutManagerImpl(DisplayConfigurator* configurator);
78 ~DisplayLayoutManagerImpl() override; 80 ~DisplayLayoutManagerImpl() override;
79 81
80 // DisplayConfigurator::DisplayLayoutManager: 82 // DisplayConfigurator::DisplayLayoutManager:
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 !(flags & kSetDisplayPowerForceProbe)) { 857 !(flags & kSetDisplayPowerForceProbe)) {
856 callback.Run(true); 858 callback.Run(true);
857 return; 859 return;
858 } 860 }
859 861
860 pending_power_state_ = power_state; 862 pending_power_state_ = power_state;
861 has_pending_power_state_ = true; 863 has_pending_power_state_ = true;
862 pending_power_flags_ = flags; 864 pending_power_flags_ = flags;
863 queued_configuration_callbacks_.push_back(callback); 865 queued_configuration_callbacks_.push_back(callback);
864 866
867 if (configure_timer_.IsRunning()) {
868 // If there is a configuration task scheduled, avoid performing
869 // configuration immediately. Instead reset the timer to wait for things to
870 // settle.
871 configure_timer_.Reset();
872 return;
873 }
874
865 RunPendingConfiguration(); 875 RunPendingConfiguration();
866 } 876 }
867 877
868 void DisplayConfigurator::SetDisplayPower( 878 void DisplayConfigurator::SetDisplayPower(
869 chromeos::DisplayPowerState power_state, 879 chromeos::DisplayPowerState power_state,
870 int flags, 880 int flags,
871 const ConfigurationCallback& callback) { 881 const ConfigurationCallback& callback) {
872 if (!configure_display_ || display_externally_controlled_) { 882 if (!configure_display_ || display_externally_controlled_) {
873 callback.Run(false); 883 callback.Run(false);
874 return; 884 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 919 // Don't do anything if the displays are currently suspended. Instead we will
910 // probe and reconfigure the displays if necessary in ResumeDisplays(). 920 // probe and reconfigure the displays if necessary in ResumeDisplays().
911 if (displays_suspended_) { 921 if (displays_suspended_) {
912 VLOG(1) << "Displays are currently suspended. Not attempting to " 922 VLOG(1) << "Displays are currently suspended. Not attempting to "
913 << "reconfigure them."; 923 << "reconfigure them.";
914 return; 924 return;
915 } 925 }
916 926
917 // Configure displays with |kConfigureDelayMs| delay, 927 // Configure displays with |kConfigureDelayMs| delay,
918 // so that time-consuming ConfigureDisplays() won't be called multiple times. 928 // so that time-consuming ConfigureDisplays() won't be called multiple times.
919 if (configure_timer_.IsRunning()) { 929 if (configure_timer_.IsRunning() &&
920 // Note: when the timer is running it is possible that a different task 930 configure_timer_.GetCurrentDelay() <=
921 // (RestoreRequestedPowerStateAfterResume()) is scheduled. In these cases, 931 base::TimeDelta::FromMilliseconds(kConfigureDelayMs)) {
922 // prefer the already scheduled task to ConfigureDisplays() since 932 // Avoid resetting the timer to a huge delay if we are currently pending
923 // ConfigureDisplays() performs only basic configuration while 933 // the delayed configuration after waking up from suspend.
924 // RestoreRequestedPowerStateAfterResume() will perform additional
925 // operations.
926 configure_timer_.Reset(); 934 configure_timer_.Reset();
927 } else { 935 } else {
928 configure_timer_.Start( 936 configure_timer_.Start(
929 FROM_HERE, 937 FROM_HERE,
930 base::TimeDelta::FromMilliseconds(kConfigureDelayMs), 938 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
931 this, 939 this,
932 &DisplayConfigurator::ConfigureDisplays); 940 &DisplayConfigurator::ConfigureDisplays);
933 } 941 }
934 } 942 }
935 943
(...skipping 23 matching lines...) Expand all
959 // unless explicitly requested by lucid sleep code). Use 967 // unless explicitly requested by lucid sleep code). Use
960 // SetDisplayPowerInternal so requested_power_state_ is maintained. 968 // SetDisplayPowerInternal so requested_power_state_ is maintained.
961 SetDisplayPowerInternal(chromeos::DISPLAY_POWER_ALL_OFF, 969 SetDisplayPowerInternal(chromeos::DISPLAY_POWER_ALL_OFF,
962 kSetDisplayPowerNoFlags, callback); 970 kSetDisplayPowerNoFlags, callback);
963 971
964 // We need to make sure that the monitor configuration we just did actually 972 // We need to make sure that the monitor configuration we just did actually
965 // completes before we return. 973 // completes before we return.
966 native_display_delegate_->SyncWithServer(); 974 native_display_delegate_->SyncWithServer();
967 } 975 }
968 976
969 void DisplayConfigurator::ResumeDisplays() { 977 void DisplayConfigurator::ResumeDisplays(
970 if (!configure_display_ || display_externally_controlled_) 978 const ConfigurationCallback& callback) {
979 if (!configure_display_ || display_externally_controlled_) {
980 callback.Run(false);
971 return; 981 return;
982 }
972 983
973 displays_suspended_ = false; 984 displays_suspended_ = false;
974 985
986 if (current_display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR ||
987 current_display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED ||
988 current_display_state_ == MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED) {
989 // When waking up from suspend while being in a multi display mode, we
990 // schedule a delayed forced configuration, which will make
991 // SetDisplayPowerInternal() avoid performing the configuration immediately.
992 // This gives a chance to wait for all displays to be added and detected
993 // before configuration is performed.
994 configure_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
995 kResumeConfigureMultiDisplayDelayMs),
996 this, &DisplayConfigurator::ConfigureDisplays);
Daniel Erat 2016/10/25 16:05:32 this is part of why i'm confused (see question in
afakhry 2016/10/25 20:14:10 (Also see my answer in the test file). This is a
997 }
998
975 // If requested_power_state_ is ALL_OFF due to idle suspend, powerd will turn 999 // If requested_power_state_ is ALL_OFF due to idle suspend, powerd will turn
976 // the display power on when it enables the backlight. 1000 // the display power on when it enables the backlight.
977 SetDisplayPower(requested_power_state_, kSetDisplayPowerNoFlags, 1001 SetDisplayPower(requested_power_state_, kSetDisplayPowerNoFlags, callback);
978 base::Bind(&DoNothing));
979 } 1002 }
980 1003
981 void DisplayConfigurator::ConfigureDisplays() { 1004 void DisplayConfigurator::ConfigureDisplays() {
982 if (!configure_display_ || display_externally_controlled_) 1005 if (!configure_display_ || display_externally_controlled_)
983 return; 1006 return;
984 1007
985 force_configure_ = true; 1008 force_configure_ = true;
986 RunPendingConfiguration(); 1009 RunPendingConfiguration();
987 } 1010 }
988 1011
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 last_virtual_display_id_ = max_display_id & 0xff; 1182 last_virtual_display_id_ = max_display_id & 0xff;
1160 1183
1161 return true; 1184 return true;
1162 } 1185 }
1163 1186
1164 bool DisplayConfigurator::IsDisplayOn() const { 1187 bool DisplayConfigurator::IsDisplayOn() const {
1165 return current_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF; 1188 return current_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF;
1166 } 1189 }
1167 1190
1168 } // namespace ui 1191 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698