Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |