Correctly track texture cleared state for sharing
[chromium-blink-merge.git] / ui / display / chromeos / update_display_configuration_task.cc
blobfea9214dc021c899b1aac6c41c4eec548b683a29
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
3 // found in the LICENSE file.
5 #include "ui/display/chromeos/update_display_configuration_task.h"
7 #include "ui/display/chromeos/configure_displays_task.h"
8 #include "ui/display/chromeos/display_util.h"
9 #include "ui/display/types/display_snapshot.h"
10 #include "ui/display/types/native_display_delegate.h"
12 namespace ui {
14 UpdateDisplayConfigurationTask::UpdateDisplayConfigurationTask(
15 NativeDisplayDelegate* delegate,
16 DisplayConfigurator::DisplayLayoutManager* layout_manager,
17 MultipleDisplayState new_display_state,
18 chromeos::DisplayPowerState new_power_state,
19 int power_flags,
20 uint32_t background_color_argb,
21 bool force_configure,
22 const ResponseCallback& callback)
23 : delegate_(delegate),
24 layout_manager_(layout_manager),
25 new_display_state_(new_display_state),
26 new_power_state_(new_power_state),
27 power_flags_(power_flags),
28 background_color_argb_(background_color_argb),
29 force_configure_(force_configure),
30 callback_(callback),
31 force_dpms_(false),
32 weak_ptr_factory_(this) {
33 delegate_->GrabServer();
36 UpdateDisplayConfigurationTask::~UpdateDisplayConfigurationTask() {
37 delegate_->UngrabServer();
40 void UpdateDisplayConfigurationTask::Run() {
41 delegate_->GetDisplays(
42 base::Bind(&UpdateDisplayConfigurationTask::OnDisplaysUpdated,
43 weak_ptr_factory_.GetWeakPtr()));
46 void UpdateDisplayConfigurationTask::OnDisplaysUpdated(
47 const std::vector<DisplaySnapshot*>& displays) {
48 cached_displays_ = layout_manager_->ParseDisplays(displays);
50 if (cached_displays_.size() > 1 && background_color_argb_)
51 delegate_->SetBackgroundColor(background_color_argb_);
53 // If the user hasn't requested a display state, update it using the requested
54 // power state.
55 if (new_display_state_ == MULTIPLE_DISPLAY_STATE_INVALID)
56 new_display_state_ = ChooseDisplayState();
58 VLOG(1) << "OnDisplaysUpdated: new_display_state="
59 << MultipleDisplayStateToString(new_display_state_)
60 << " new_power_state=" << DisplayPowerStateToString(new_power_state_)
61 << " flags=" << power_flags_
62 << " force_configure=" << force_configure_
63 << " display_count=" << cached_displays_.size();
64 // If there has been any change in the requested power state and the displays
65 // aren't being turned off force a change in DPMS state.
66 force_dpms_ = ShouldForceDpms() && ShouldConfigure();
68 if (ShouldConfigure()) {
69 EnterState(base::Bind(&UpdateDisplayConfigurationTask::OnStateEntered,
70 weak_ptr_factory_.GetWeakPtr()));
71 } else {
72 // If we don't have to configure then we're sticking with the old
73 // configuration. Update it such that it reflects in the reported value.
74 new_power_state_ = layout_manager_->GetPowerState();
75 FinishConfiguration(true);
79 void UpdateDisplayConfigurationTask::EnterState(
80 const ConfigureDisplaysTask::ResponseCallback& callback) {
81 VLOG(2) << "EnterState";
82 std::vector<DisplayConfigureRequest> requests;
83 if (!layout_manager_->GetDisplayLayout(cached_displays_, new_display_state_,
84 new_power_state_, &requests,
85 &framebuffer_size_)) {
86 callback.Run(ConfigureDisplaysTask::ERROR);
87 return;
90 if (!requests.empty()) {
91 delegate_->CreateFrameBuffer(framebuffer_size_);
92 configure_task_.reset(
93 new ConfigureDisplaysTask(delegate_, requests, callback));
94 configure_task_->Run();
95 } else {
96 VLOG(2) << "No displays";
97 callback.Run(ConfigureDisplaysTask::SUCCESS);
101 void UpdateDisplayConfigurationTask::OnStateEntered(
102 ConfigureDisplaysTask::Status status) {
103 bool success = status != ConfigureDisplaysTask::ERROR;
104 if (new_display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR &&
105 status == ConfigureDisplaysTask::PARTIAL_SUCCESS)
106 success = false;
108 if (layout_manager_->GetSoftwareMirroringController()) {
109 bool enable_software_mirroring = false;
110 if (!success && new_display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) {
111 if (layout_manager_->GetDisplayState() !=
112 MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED ||
113 layout_manager_->GetPowerState() != new_power_state_) {
114 new_display_state_ = MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED;
115 EnterState(base::Bind(
116 &UpdateDisplayConfigurationTask::OnEnableSoftwareMirroring,
117 weak_ptr_factory_.GetWeakPtr()));
118 return;
121 success = layout_manager_->GetDisplayState() ==
122 MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED;
123 enable_software_mirroring = success;
124 if (success)
125 new_display_state_ = MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED;
128 layout_manager_->GetSoftwareMirroringController()->SetSoftwareMirroring(
129 enable_software_mirroring);
132 FinishConfiguration(success);
135 void UpdateDisplayConfigurationTask::OnEnableSoftwareMirroring(
136 ConfigureDisplaysTask::Status status) {
137 bool success = status != ConfigureDisplaysTask::ERROR;
138 layout_manager_->GetSoftwareMirroringController()->SetSoftwareMirroring(
139 success);
140 FinishConfiguration(success);
143 void UpdateDisplayConfigurationTask::FinishConfiguration(bool success) {
144 if (success && force_dpms_)
145 delegate_->ForceDPMSOn();
147 callback_.Run(success, cached_displays_, framebuffer_size_,
148 new_display_state_, new_power_state_);
151 bool UpdateDisplayConfigurationTask::ShouldForceDpms() const {
152 return new_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF &&
153 (layout_manager_->GetPowerState() != new_power_state_ ||
154 (power_flags_ & DisplayConfigurator::kSetDisplayPowerForceProbe));
157 bool UpdateDisplayConfigurationTask::ShouldConfigure() const {
158 if (force_configure_)
159 return true;
161 if (cached_displays_.size() == 1 &&
162 cached_displays_[0].display->type() == DISPLAY_CONNECTION_TYPE_INTERNAL)
163 return true;
165 if (!(power_flags_ &
166 DisplayConfigurator::kSetDisplayPowerOnlyIfSingleInternalDisplay))
167 return true;
169 if (new_display_state_ != layout_manager_->GetDisplayState())
170 return true;
172 return false;
175 MultipleDisplayState UpdateDisplayConfigurationTask::ChooseDisplayState()
176 const {
177 int num_on_displays =
178 GetDisplayPower(cached_displays_, new_power_state_, NULL);
179 switch (cached_displays_.size()) {
180 case 0:
181 return MULTIPLE_DISPLAY_STATE_HEADLESS;
182 case 1:
183 return MULTIPLE_DISPLAY_STATE_SINGLE;
184 default: {
185 if (num_on_displays == 1) {
186 // If only one display is currently turned on, return the "single"
187 // state so that its native mode will be used.
188 return MULTIPLE_DISPLAY_STATE_SINGLE;
190 if (num_on_displays >= 3) {
191 return MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED;
192 } else if (cached_displays_.size() == 2) {
193 if (!layout_manager_->GetStateController())
194 return MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED;
195 // With either both displays on or both displays off, use one of the
196 // dual modes.
197 std::vector<int64_t> display_ids;
198 for (size_t i = 0; i < cached_displays_.size(); ++i)
199 display_ids.push_back(cached_displays_[i].display->display_id());
201 return layout_manager_->GetStateController()->GetStateForDisplayIds(
202 display_ids);
204 NOTREACHED();
207 return MULTIPLE_DISPLAY_STATE_INVALID;
210 } // namespace ui