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 17 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |