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

Side by Side Diff: chromeos/display/output_configurator.cc

Issue 187073002: Refactoring display configuration state to allow generic state objects (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chromeos/display/output_configurator.h" 5 #include "chromeos/display/output_configurator.h"
6 6
7 #include <X11/Xlib.h> 7 #include <X11/Xlib.h>
8 #include <X11/extensions/Xrandr.h> 8 #include <X11/extensions/Xrandr.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/sys_info.h" 14 #include "base/sys_info.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "chromeos/display/native_display_delegate_x11.h"
17 #include "chromeos/display/output_util.h"
18 #include "chromeos/display/touchscreen_delegate_x11.h" 16 #include "chromeos/display/touchscreen_delegate_x11.h"
17 #include "ui/display/chromeos/display_mode.h"
18 #include "ui/display/chromeos/display_snapshot.h"
19 #include "ui/display/chromeos/x11/native_display_delegate_x11.h"
19 20
20 namespace chromeos { 21 namespace chromeos {
21 22
22 namespace { 23 namespace {
23 24
24 // The delay to perform configuration after RRNotify. See the comment 25 // The delay to perform configuration after RRNotify. See the comment
25 // in |Dispatch()|. 26 // in |Dispatch()|.
26 const int64 kConfigureDelayMs = 500; 27 const int64 kConfigureDelayMs = 500;
27 28
28 // Returns a string describing |state|. 29 // Returns a string describing |state|.
(...skipping 23 matching lines...) Expand all
52 return "SINGLE"; 53 return "SINGLE";
53 case ui::OUTPUT_STATE_DUAL_MIRROR: 54 case ui::OUTPUT_STATE_DUAL_MIRROR:
54 return "DUAL_MIRROR"; 55 return "DUAL_MIRROR";
55 case ui::OUTPUT_STATE_DUAL_EXTENDED: 56 case ui::OUTPUT_STATE_DUAL_EXTENDED:
56 return "DUAL_EXTENDED"; 57 return "DUAL_EXTENDED";
57 } 58 }
58 NOTREACHED() << "Unknown state " << state; 59 NOTREACHED() << "Unknown state " << state;
59 return "INVALID"; 60 return "INVALID";
60 } 61 }
61 62
62 // Returns a string representation of OutputSnapshot. 63 // Returns a string representation of ui::DisplayMode.
Daniel Erat 2014/03/05 01:56:12 nit: maybe add a TODO to move this to DisplayMode
dnicoara 2014/03/05 17:29:25 Done.
63 std::string OutputSnapshotToString( 64 std::string DisplayModeToString(const ui::DisplayMode* mode) {
64 const OutputConfigurator::OutputSnapshot* output) {
65 return base::StringPrintf(
66 "[type=%d, output=%ld, crtc=%ld, mode=%ld, dim=%dx%d]",
67 output->type,
68 output->output,
69 output->crtc,
70 output->current_mode,
71 static_cast<int>(output->width_mm),
72 static_cast<int>(output->height_mm));
73 }
74
75 // Returns a string representation of ModeInfo.
76 std::string ModeInfoToString(const OutputConfigurator::ModeInfo* mode) {
77 return base::StringPrintf("[%dx%d %srate=%f]", 65 return base::StringPrintf("[%dx%d %srate=%f]",
78 mode->width, 66 mode->size().width(),
79 mode->height, 67 mode->size().height(),
80 mode->interlaced ? "interlaced " : "", 68 mode->is_interlaced() ? "interlaced " : "",
81 mode->refresh_rate); 69 mode->refresh_rate());
82
83 } 70 }
84 71
85 // Returns the number of outputs in |outputs| that should be turned on, per 72 // Returns the number of outputs in |outputs| that should be turned on, per
86 // |state|. If |output_power| is non-NULL, it is updated to contain the 73 // |state|. If |output_power| is non-NULL, it is updated to contain the
87 // on/off state of each corresponding entry in |outputs|. 74 // on/off state of each corresponding entry in |outputs|.
88 int GetOutputPower( 75 int GetOutputPower(
89 const std::vector<OutputConfigurator::OutputSnapshot>& outputs, 76 const std::vector<OutputConfigurator::InternalDisplayState>& outputs,
90 DisplayPowerState state, 77 DisplayPowerState state,
91 std::vector<bool>* output_power) { 78 std::vector<bool>* output_power) {
92 int num_on_outputs = 0; 79 int num_on_outputs = 0;
93 if (output_power) 80 if (output_power)
94 output_power->resize(outputs.size()); 81 output_power->resize(outputs.size());
95 82
96 for (size_t i = 0; i < outputs.size(); ++i) { 83 for (size_t i = 0; i < outputs.size(); ++i) {
97 bool internal = outputs[i].type == ui::OUTPUT_TYPE_INTERNAL; 84 bool internal = outputs[i].display->type() == ui::OUTPUT_TYPE_INTERNAL;
98 bool on = state == DISPLAY_POWER_ALL_ON || 85 bool on = state == DISPLAY_POWER_ALL_ON ||
99 (state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON && !internal) || 86 (state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON && !internal) ||
100 (state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && internal); 87 (state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && internal);
101 if (output_power) 88 if (output_power)
102 (*output_power)[i] = on; 89 (*output_power)[i] = on;
103 if (on) 90 if (on)
104 num_on_outputs++; 91 num_on_outputs++;
105 } 92 }
106 return num_on_outputs; 93 return num_on_outputs;
107 } 94 }
108 95
109 } // namespace 96 } // namespace
110 97
111 OutputConfigurator::ModeInfo::ModeInfo()
112 : width(0),
113 height(0),
114 interlaced(false),
115 refresh_rate(0.0) {}
116
117 OutputConfigurator::ModeInfo::ModeInfo(int width,
118 int height,
119 bool interlaced,
120 float refresh_rate)
121 : width(width),
122 height(height),
123 interlaced(interlaced),
124 refresh_rate(refresh_rate) {}
125
126 OutputConfigurator::CoordinateTransformation::CoordinateTransformation() 98 OutputConfigurator::CoordinateTransformation::CoordinateTransformation()
127 : x_scale(1.0), 99 : x_scale(1.0),
128 x_offset(0.0), 100 x_offset(0.0),
129 y_scale(1.0), 101 y_scale(1.0),
130 y_offset(0.0) {} 102 y_offset(0.0) {}
131 103
132 OutputConfigurator::OutputSnapshot::OutputSnapshot() 104 OutputConfigurator::InternalDisplayState::InternalDisplayState()
133 : output(None), 105 : display(NULL),
134 crtc(None),
135 current_mode(None),
136 native_mode(None),
137 mirror_mode(None),
138 selected_mode(None),
139 x(0),
140 y(0),
141 width_mm(0),
142 height_mm(0),
143 is_aspect_preserving_scaling(false),
144 type(ui::OUTPUT_TYPE_UNKNOWN),
145 touch_device_id(0), 106 touch_device_id(0),
146 display_id(0), 107 selected_mode(NULL),
147 has_display_id(false), 108 mirror_mode(NULL) {}
148 index(0) {}
149
150 OutputConfigurator::OutputSnapshot::~OutputSnapshot() {}
151 109
152 bool OutputConfigurator::TestApi::TriggerConfigureTimeout() { 110 bool OutputConfigurator::TestApi::TriggerConfigureTimeout() {
153 if (configurator_->configure_timer_.get() && 111 if (configurator_->configure_timer_.get() &&
154 configurator_->configure_timer_->IsRunning()) { 112 configurator_->configure_timer_->IsRunning()) {
155 configurator_->configure_timer_.reset(); 113 configurator_->configure_timer_.reset();
156 configurator_->ConfigureOutputs(); 114 configurator_->ConfigureOutputs();
157 return true; 115 return true;
158 } else { 116 } else {
159 return false; 117 return false;
160 } 118 }
161 } 119 }
162 120
163 // static 121 // static
164 const OutputConfigurator::ModeInfo* OutputConfigurator::GetModeInfo( 122 const ui::DisplayMode* OutputConfigurator::FindDisplayModeMatchingSize(
165 const OutputSnapshot& output, 123 const ui::DisplaySnapshot& output,
166 RRMode mode) { 124 const gfx::Size& size) {
167 if (mode == None) 125 const ui::DisplayMode* best_mode = NULL;
168 return NULL; 126 for (DisplayModeList::const_iterator it = output.modes().begin();
127 it != output.modes().end();
128 ++it) {
129 const ui::DisplayMode* mode = *it;
169 130
170 ModeInfoMap::const_iterator it = output.mode_infos.find(mode); 131 if (mode->size() != size)
171 if (it == output.mode_infos.end()) { 132 continue;
172 LOG(WARNING) << "Unable to find info about mode " << mode 133
173 << " for output " << output.output; 134 if (!best_mode) {
174 return NULL; 135 best_mode = mode;
136 continue;
137 }
138
139 if (mode->is_interlaced()) {
140 if (!best_mode->is_interlaced())
141 continue;
142 } else {
143 // Reset the best rate if the non interlaced is
144 // found the first time.
145 if (best_mode->is_interlaced()) {
146 best_mode = mode;
147 continue;
148 }
149 }
150 if (mode->refresh_rate() < best_mode->refresh_rate())
151 continue;
152
153 best_mode = mode;
175 } 154 }
176 return &it->second;
177 }
178 155
179 // static 156 return best_mode;
180 RRMode OutputConfigurator::FindOutputModeMatchingSize(
181 const OutputSnapshot& output,
182 int width,
183 int height) {
184 RRMode found = None;
185 float best_rate = 0;
186 bool non_interlaced_found = false;
187 for (ModeInfoMap::const_iterator it = output.mode_infos.begin();
188 it != output.mode_infos.end(); ++it) {
189 RRMode mode = it->first;
190 const ModeInfo& info = it->second;
191
192 if (info.width == width && info.height == height) {
193 if (info.interlaced) {
194 if (non_interlaced_found)
195 continue;
196 } else {
197 // Reset the best rate if the non interlaced is
198 // found the first time.
199 if (!non_interlaced_found)
200 best_rate = info.refresh_rate;
201 non_interlaced_found = true;
202 }
203 if (info.refresh_rate < best_rate)
204 continue;
205
206 found = mode;
207 best_rate = info.refresh_rate;
208 }
209 }
210 return found;
211 } 157 }
212 158
213 OutputConfigurator::OutputConfigurator() 159 OutputConfigurator::OutputConfigurator()
214 : state_controller_(NULL), 160 : state_controller_(NULL),
215 mirroring_controller_(NULL), 161 mirroring_controller_(NULL),
216 is_panel_fitting_enabled_(false), 162 is_panel_fitting_enabled_(false),
217 configure_display_(base::SysInfo::IsRunningOnChromeOS()), 163 configure_display_(base::SysInfo::IsRunningOnChromeOS()),
218 output_state_(ui::OUTPUT_STATE_INVALID), 164 output_state_(ui::OUTPUT_STATE_INVALID),
219 power_state_(DISPLAY_POWER_ALL_ON), 165 power_state_(DISPLAY_POWER_ALL_ON),
220 next_output_protection_client_id_(1) {} 166 next_output_protection_client_id_(1) {}
221 167
222 OutputConfigurator::~OutputConfigurator() { 168 OutputConfigurator::~OutputConfigurator() {
223 if (native_display_delegate_) 169 if (native_display_delegate_)
224 native_display_delegate_->RemoveObserver(this); 170 native_display_delegate_->RemoveObserver(this);
225 } 171 }
226 172
227 void OutputConfigurator::SetNativeDisplayDelegateForTesting( 173 void OutputConfigurator::SetNativeDisplayDelegateForTesting(
228 scoped_ptr<NativeDisplayDelegate> delegate) { 174 scoped_ptr<ui::NativeDisplayDelegate> delegate) {
229 DCHECK(!native_display_delegate_); 175 DCHECK(!native_display_delegate_);
230 176
231 native_display_delegate_ = delegate.Pass(); 177 native_display_delegate_ = delegate.Pass();
232 native_display_delegate_->AddObserver(this); 178 native_display_delegate_->AddObserver(this);
233 configure_display_ = true; 179 configure_display_ = true;
234 } 180 }
235 181
236 void OutputConfigurator::SetTouchscreenDelegateForTesting( 182 void OutputConfigurator::SetTouchscreenDelegateForTesting(
237 scoped_ptr<TouchscreenDelegate> delegate) { 183 scoped_ptr<TouchscreenDelegate> delegate) {
238 DCHECK(!touchscreen_delegate_); 184 DCHECK(!touchscreen_delegate_);
239 185
240 touchscreen_delegate_ = delegate.Pass(); 186 touchscreen_delegate_ = delegate.Pass();
241 } 187 }
242 188
243 void OutputConfigurator::SetInitialDisplayPower(DisplayPowerState power_state) { 189 void OutputConfigurator::SetInitialDisplayPower(DisplayPowerState power_state) {
244 DCHECK_EQ(output_state_, ui::OUTPUT_STATE_INVALID); 190 DCHECK_EQ(output_state_, ui::OUTPUT_STATE_INVALID);
245 power_state_ = power_state; 191 power_state_ = power_state;
246 } 192 }
247 193
248 void OutputConfigurator::Init(bool is_panel_fitting_enabled) { 194 void OutputConfigurator::Init(bool is_panel_fitting_enabled) {
249 is_panel_fitting_enabled_ = is_panel_fitting_enabled; 195 is_panel_fitting_enabled_ = is_panel_fitting_enabled;
250 if (!configure_display_) 196 if (!configure_display_)
251 return; 197 return;
252 198
253 if (!native_display_delegate_) { 199 if (!native_display_delegate_) {
254 native_display_delegate_.reset(new NativeDisplayDelegateX11()); 200 native_display_delegate_.reset(new ui::NativeDisplayDelegateX11());
255 native_display_delegate_->AddObserver(this); 201 native_display_delegate_->AddObserver(this);
256 } 202 }
257 203
258 if (!touchscreen_delegate_) 204 if (!touchscreen_delegate_)
259 touchscreen_delegate_.reset(new TouchscreenDelegateX11()); 205 touchscreen_delegate_.reset(new TouchscreenDelegateX11());
260 } 206 }
261 207
262 void OutputConfigurator::ForceInitialConfigure(uint32 background_color_argb) { 208 void OutputConfigurator::ForceInitialConfigure(uint32 background_color_argb) {
263 if (!configure_display_) 209 if (!configure_display_)
264 return; 210 return;
265 211
266 native_display_delegate_->GrabServer(); 212 native_display_delegate_->GrabServer();
267 native_display_delegate_->Initialize(); 213 native_display_delegate_->Initialize();
268 214
269 UpdateCachedOutputs(); 215 UpdateCachedOutputs();
270 if (cached_outputs_.size() > 1 && background_color_argb) 216 if (cached_outputs_.size() > 1 && background_color_argb)
271 native_display_delegate_->SetBackgroundColor(background_color_argb); 217 native_display_delegate_->SetBackgroundColor(background_color_argb);
272 const ui::OutputState new_state = ChooseOutputState(power_state_); 218 const ui::OutputState new_state = ChooseOutputState(power_state_);
273 const bool success = EnterStateOrFallBackToSoftwareMirroring( 219 const bool success = EnterStateOrFallBackToSoftwareMirroring(
274 new_state, power_state_); 220 new_state, power_state_);
275 221
276 // Force the DPMS on chrome startup as the driver doesn't always detect 222 // Force the DPMS on chrome startup as the driver doesn't always detect
277 // that all displays are on when signing out. 223 // that all displays are on when signing out.
278 native_display_delegate_->ForceDPMSOn(); 224 native_display_delegate_->ForceDPMSOn();
279 native_display_delegate_->UngrabServer(); 225 native_display_delegate_->UngrabServer();
280 NotifyObservers(success, new_state); 226 NotifyObservers(success, new_state);
281 } 227 }
282 228
283 bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) { 229 bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) {
284 for (std::vector<OutputSnapshot>::const_iterator it = cached_outputs_.begin(); 230 for (std::vector<InternalDisplayState>::const_iterator it =
285 it != cached_outputs_.end(); ++it) { 231 cached_outputs_.begin();
232 it != cached_outputs_.end();
233 ++it) {
286 uint32_t all_desired = 0; 234 uint32_t all_desired = 0;
287 DisplayProtections::const_iterator request_it = requests.find( 235 DisplayProtections::const_iterator request_it =
288 it->display_id); 236 requests.find(it->display->display_id());
289 if (request_it != requests.end()) 237 if (request_it != requests.end())
290 all_desired = request_it->second; 238 all_desired = request_it->second;
291 switch (it->type) { 239 switch (it->display->type()) {
292 case ui::OUTPUT_TYPE_UNKNOWN: 240 case ui::OUTPUT_TYPE_UNKNOWN:
293 return false; 241 return false;
294 // DisplayPort, DVI, and HDMI all support HDCP. 242 // DisplayPort, DVI, and HDMI all support HDCP.
295 case ui::OUTPUT_TYPE_DISPLAYPORT: 243 case ui::OUTPUT_TYPE_DISPLAYPORT:
296 case ui::OUTPUT_TYPE_DVI: 244 case ui::OUTPUT_TYPE_DVI:
297 case ui::OUTPUT_TYPE_HDMI: { 245 case ui::OUTPUT_TYPE_HDMI: {
298 ui::HDCPState new_desired_state = 246 ui::HDCPState new_desired_state =
299 (all_desired & ui::OUTPUT_PROTECTION_METHOD_HDCP) 247 (all_desired & ui::OUTPUT_PROTECTION_METHOD_HDCP)
300 ? ui::HDCP_STATE_DESIRED 248 ? ui::HDCP_STATE_DESIRED
301 : ui::HDCP_STATE_UNDESIRED; 249 : ui::HDCP_STATE_UNDESIRED;
302 if (!native_display_delegate_->SetHDCPState(*it, new_desired_state)) 250 if (!native_display_delegate_->SetHDCPState(*it->display,
251 new_desired_state))
303 return false; 252 return false;
304 break; 253 break;
305 } 254 }
306 case ui::OUTPUT_TYPE_INTERNAL: 255 case ui::OUTPUT_TYPE_INTERNAL:
307 case ui::OUTPUT_TYPE_VGA: 256 case ui::OUTPUT_TYPE_VGA:
308 case ui::OUTPUT_TYPE_NETWORK: 257 case ui::OUTPUT_TYPE_NETWORK:
309 // No protections for these types. Do nothing. 258 // No protections for these types. Do nothing.
310 break; 259 break;
311 case ui::OUTPUT_TYPE_NONE: 260 case ui::OUTPUT_TYPE_NONE:
312 NOTREACHED(); 261 NOTREACHED();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 OutputProtectionClientId client_id, 296 OutputProtectionClientId client_id,
348 int64 display_id, 297 int64 display_id,
349 uint32_t* link_mask, 298 uint32_t* link_mask,
350 uint32_t* protection_mask) { 299 uint32_t* protection_mask) {
351 if (!configure_display_) 300 if (!configure_display_)
352 return false; 301 return false;
353 302
354 uint32_t enabled = 0; 303 uint32_t enabled = 0;
355 uint32_t unfulfilled = 0; 304 uint32_t unfulfilled = 0;
356 *link_mask = 0; 305 *link_mask = 0;
357 for (std::vector<OutputSnapshot>::const_iterator it = cached_outputs_.begin(); 306 for (std::vector<InternalDisplayState>::const_iterator it =
358 it != cached_outputs_.end(); ++it) { 307 cached_outputs_.begin();
359 if (it->display_id != display_id) 308 it != cached_outputs_.end();
309 ++it) {
310 if (it->display->display_id() != display_id)
360 continue; 311 continue;
361 *link_mask |= it->type; 312 *link_mask |= it->display->type();
362 switch (it->type) { 313 switch (it->display->type()) {
363 case ui::OUTPUT_TYPE_UNKNOWN: 314 case ui::OUTPUT_TYPE_UNKNOWN:
364 return false; 315 return false;
365 // DisplayPort, DVI, and HDMI all support HDCP. 316 // DisplayPort, DVI, and HDMI all support HDCP.
366 case ui::OUTPUT_TYPE_DISPLAYPORT: 317 case ui::OUTPUT_TYPE_DISPLAYPORT:
367 case ui::OUTPUT_TYPE_DVI: 318 case ui::OUTPUT_TYPE_DVI:
368 case ui::OUTPUT_TYPE_HDMI: { 319 case ui::OUTPUT_TYPE_HDMI: {
369 ui::HDCPState state; 320 ui::HDCPState state;
370 if (!native_display_delegate_->GetHDCPState(*it, &state)) 321 if (!native_display_delegate_->GetHDCPState(*it->display, &state))
371 return false; 322 return false;
372 if (state == ui::HDCP_STATE_ENABLED) 323 if (state == ui::HDCP_STATE_ENABLED)
373 enabled |= ui::OUTPUT_PROTECTION_METHOD_HDCP; 324 enabled |= ui::OUTPUT_PROTECTION_METHOD_HDCP;
374 else 325 else
375 unfulfilled |= ui::OUTPUT_PROTECTION_METHOD_HDCP; 326 unfulfilled |= ui::OUTPUT_PROTECTION_METHOD_HDCP;
376 break; 327 break;
377 } 328 }
378 case ui::OUTPUT_TYPE_INTERNAL: 329 case ui::OUTPUT_TYPE_INTERNAL:
379 case ui::OUTPUT_TYPE_VGA: 330 case ui::OUTPUT_TYPE_VGA:
380 case ui::OUTPUT_TYPE_NETWORK: 331 case ui::OUTPUT_TYPE_NETWORK:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 UpdateCachedOutputs(); 409 UpdateCachedOutputs();
459 410
460 const ui::OutputState new_state = ChooseOutputState(power_state); 411 const ui::OutputState new_state = ChooseOutputState(power_state);
461 bool attempted_change = false; 412 bool attempted_change = false;
462 bool success = false; 413 bool success = false;
463 414
464 bool only_if_single_internal_display = 415 bool only_if_single_internal_display =
465 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay; 416 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay;
466 bool single_internal_display = 417 bool single_internal_display =
467 cached_outputs_.size() == 1 && 418 cached_outputs_.size() == 1 &&
468 cached_outputs_[0].type == ui::OUTPUT_TYPE_INTERNAL; 419 cached_outputs_[0].display->type() == ui::OUTPUT_TYPE_INTERNAL;
469 if (single_internal_display || !only_if_single_internal_display) { 420 if (single_internal_display || !only_if_single_internal_display) {
470 success = EnterStateOrFallBackToSoftwareMirroring(new_state, power_state); 421 success = EnterStateOrFallBackToSoftwareMirroring(new_state, power_state);
471 attempted_change = true; 422 attempted_change = true;
472 423
473 // Force the DPMS on since the driver doesn't always detect that it 424 // Force the DPMS on since the driver doesn't always detect that it
474 // should turn on. This is needed when coming back from idle suspend. 425 // should turn on. This is needed when coming back from idle suspend.
475 if (success && power_state != DISPLAY_POWER_ALL_OFF) 426 if (success && power_state != DISPLAY_POWER_ALL_OFF)
476 native_display_delegate_->ForceDPMSOn(); 427 native_display_delegate_->ForceDPMSOn();
477 } 428 }
478 429
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 } 497 }
547 } 498 }
548 499
549 void OutputConfigurator::ResumeDisplays() { 500 void OutputConfigurator::ResumeDisplays() {
550 // Force probing to ensure that we pick up any changes that were made 501 // Force probing to ensure that we pick up any changes that were made
551 // while the system was suspended. 502 // while the system was suspended.
552 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe); 503 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe);
553 } 504 }
554 505
555 void OutputConfigurator::UpdateCachedOutputs() { 506 void OutputConfigurator::UpdateCachedOutputs() {
556 cached_outputs_ = native_display_delegate_->GetOutputs(); 507 std::vector<ui::DisplaySnapshot*> snapshots =
508 native_display_delegate_->GetOutputs();
509
510 cached_outputs_.clear();
511 for (size_t i = 0; i < snapshots.size(); ++i) {
512 InternalDisplayState display_state;
513 display_state.display = snapshots[i];
514 cached_outputs_.push_back(display_state);
515 }
516
557 touchscreen_delegate_->AssociateTouchscreens(&cached_outputs_); 517 touchscreen_delegate_->AssociateTouchscreens(&cached_outputs_);
558 518
559 // Set |selected_mode| fields. 519 // Set |selected_mode| fields.
560 for (size_t i = 0; i < cached_outputs_.size(); ++i) { 520 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
561 OutputSnapshot* output = &cached_outputs_[i]; 521 InternalDisplayState* output = &cached_outputs_[i];
562 if (output->has_display_id) { 522 if (output->display->has_proper_display_id()) {
563 int width = 0, height = 0; 523 gfx::Size size;
564 if (state_controller_ && 524 if (state_controller_ && state_controller_->GetResolutionForDisplayId(
565 state_controller_->GetResolutionForDisplayId( 525 output->display->display_id(), &size)) {
566 output->display_id, &width, &height)) {
567 output->selected_mode = 526 output->selected_mode =
568 FindOutputModeMatchingSize(*output, width, height); 527 FindDisplayModeMatchingSize(*output->display, size);
569 } 528 }
570 } 529 }
571 // Fall back to native mode. 530 // Fall back to native mode.
572 if (output->selected_mode == None) 531 if (!output->selected_mode)
573 output->selected_mode = output->native_mode; 532 output->selected_mode = output->display->native_mode();
574 } 533 }
575 534
576 // Set |mirror_mode| fields. 535 // Set |mirror_mode| fields.
577 if (cached_outputs_.size() == 2) { 536 if (cached_outputs_.size() == 2) {
578 bool one_is_internal = cached_outputs_[0].type == ui::OUTPUT_TYPE_INTERNAL; 537 bool one_is_internal =
579 bool two_is_internal = cached_outputs_[1].type == ui::OUTPUT_TYPE_INTERNAL; 538 cached_outputs_[0].display->type() == ui::OUTPUT_TYPE_INTERNAL;
539 bool two_is_internal =
540 cached_outputs_[1].display->type() == ui::OUTPUT_TYPE_INTERNAL;
580 int internal_outputs = (one_is_internal ? 1 : 0) + 541 int internal_outputs = (one_is_internal ? 1 : 0) +
581 (two_is_internal ? 1 : 0); 542 (two_is_internal ? 1 : 0);
582 DCHECK_LT(internal_outputs, 2); 543 DCHECK_LT(internal_outputs, 2);
583 LOG_IF(WARNING, internal_outputs == 2) 544 LOG_IF(WARNING, internal_outputs == 2)
584 << "Two internal outputs detected."; 545 << "Two internal outputs detected.";
585 546
586 bool can_mirror = false; 547 bool can_mirror = false;
587 for (int attempt = 0; !can_mirror && attempt < 2; ++attempt) { 548 for (int attempt = 0; !can_mirror && attempt < 2; ++attempt) {
588 // Try preserving external output's aspect ratio on the first attempt. 549 // Try preserving external output's aspect ratio on the first attempt.
589 // If that fails, fall back to the highest matching resolution. 550 // If that fails, fall back to the highest matching resolution.
(...skipping 18 matching lines...) Expand all
608 // it will succeed with the other. This way we will have the correct 569 // it will succeed with the other. This way we will have the correct
609 // aspect ratio on at least one of them. 570 // aspect ratio on at least one of them.
610 can_mirror = FindMirrorMode(&cached_outputs_[1], &cached_outputs_[0], 571 can_mirror = FindMirrorMode(&cached_outputs_[1], &cached_outputs_[0],
611 false, preserve_aspect); 572 false, preserve_aspect);
612 } 573 }
613 } 574 }
614 } 575 }
615 } 576 }
616 } 577 }
617 578
618 bool OutputConfigurator::FindMirrorMode(OutputSnapshot* internal_output, 579 bool OutputConfigurator::FindMirrorMode(InternalDisplayState* internal_output,
619 OutputSnapshot* external_output, 580 InternalDisplayState* external_output,
620 bool try_panel_fitting, 581 bool try_panel_fitting,
621 bool preserve_aspect) { 582 bool preserve_aspect) {
622 const ModeInfo* internal_native_info = 583 const ui::DisplayMode* internal_native_info =
623 GetModeInfo(*internal_output, internal_output->native_mode); 584 internal_output->display->native_mode();
624 const ModeInfo* external_native_info = 585 const ui::DisplayMode* external_native_info =
625 GetModeInfo(*external_output, external_output->native_mode); 586 external_output->display->native_mode();
626 if (!internal_native_info || !external_native_info) 587 if (!internal_native_info || !external_native_info)
627 return false; 588 return false;
628 589
629 // Check if some external output resolution can be mirrored on internal. 590 // Check if some external output resolution can be mirrored on internal.
630 // Prefer the modes in the order that X sorts them, assuming this is the order 591 // Prefer the modes in the order that X sorts them, assuming this is the order
631 // in which they look better on the monitor. 592 // in which they look better on the monitor.
632 for (ModeInfoMap::const_iterator external_it = 593 for (DisplayModeList::const_iterator external_it =
633 external_output->mode_infos.begin(); 594 external_output->display->modes().begin();
634 external_it != external_output->mode_infos.end(); ++external_it) { 595 external_it != external_output->display->modes().end();
635 const ModeInfo& external_info = external_it->second; 596 ++external_it) {
597 const ui::DisplayMode& external_info = **external_it;
636 bool is_native_aspect_ratio = 598 bool is_native_aspect_ratio =
637 external_native_info->width * external_info.height == 599 external_native_info->size().width() * external_info.size().height() ==
638 external_native_info->height * external_info.width; 600 external_native_info->size().height() * external_info.size().width();
639 if (preserve_aspect && !is_native_aspect_ratio) 601 if (preserve_aspect && !is_native_aspect_ratio)
640 continue; // Allow only aspect ratio preserving modes for mirroring. 602 continue; // Allow only aspect ratio preserving modes for mirroring.
641 603
642 // Try finding an exact match. 604 // Try finding an exact match.
643 for (ModeInfoMap::const_iterator internal_it = 605 for (DisplayModeList::const_iterator internal_it =
644 internal_output->mode_infos.begin(); 606 internal_output->display->modes().begin();
645 internal_it != internal_output->mode_infos.end(); ++internal_it) { 607 internal_it != internal_output->display->modes().end();
646 const ModeInfo& internal_info = internal_it->second; 608 ++internal_it) {
647 if (internal_info.width == external_info.width && 609 const ui::DisplayMode& internal_info = **internal_it;
648 internal_info.height == external_info.height && 610 if (internal_info.size().width() == external_info.size().width() &&
649 internal_info.interlaced == external_info.interlaced) { 611 internal_info.size().height() == external_info.size().height() &&
650 internal_output->mirror_mode = internal_it->first; 612 internal_info.is_interlaced() == external_info.is_interlaced()) {
651 external_output->mirror_mode = external_it->first; 613 internal_output->mirror_mode = *internal_it;
614 external_output->mirror_mode = *external_it;
652 return true; // Mirror mode found. 615 return true; // Mirror mode found.
653 } 616 }
654 } 617 }
655 618
656 // Try to create a matching internal output mode by panel fitting. 619 // Try to create a matching internal output mode by panel fitting.
657 if (try_panel_fitting) { 620 if (try_panel_fitting) {
658 // We can downscale by 1.125, and upscale indefinitely. Downscaling looks 621 // We can downscale by 1.125, and upscale indefinitely. Downscaling looks
659 // ugly, so, can fit == can upscale. Also, internal panels don't support 622 // ugly, so, can fit == can upscale. Also, internal panels don't support
660 // fitting interlaced modes. 623 // fitting interlaced modes.
661 bool can_fit = 624 bool can_fit = internal_native_info->size().width() >=
662 internal_native_info->width >= external_info.width && 625 external_info.size().width() &&
663 internal_native_info->height >= external_info.height && 626 internal_native_info->size().height() >=
664 !external_info.interlaced; 627 external_info.size().height() &&
628 !external_info.is_interlaced();
665 if (can_fit) { 629 if (can_fit) {
666 RRMode mode = external_it->first; 630 native_display_delegate_->AddMode(*internal_output->display,
667 native_display_delegate_->AddMode(*internal_output, mode); 631 *external_it);
668 internal_output->mode_infos.insert(std::make_pair(mode, external_info)); 632 internal_output->display->add_mode(*external_it);
669 internal_output->mirror_mode = mode; 633 internal_output->mirror_mode = *external_it;
670 external_output->mirror_mode = mode; 634 external_output->mirror_mode = *external_it;
671 return true; // Mirror mode created. 635 return true; // Mirror mode created.
672 } 636 }
673 } 637 }
674 } 638 }
675 639
676 return false; 640 return false;
677 } 641 }
678 642
679 void OutputConfigurator::ConfigureOutputs() { 643 void OutputConfigurator::ConfigureOutputs() {
680 configure_timer_.reset(); 644 configure_timer_.reset();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 687
724 bool OutputConfigurator::EnterState(ui::OutputState output_state, 688 bool OutputConfigurator::EnterState(ui::OutputState output_state,
725 DisplayPowerState power_state) { 689 DisplayPowerState power_state) {
726 std::vector<bool> output_power; 690 std::vector<bool> output_power;
727 int num_on_outputs = GetOutputPower( 691 int num_on_outputs = GetOutputPower(
728 cached_outputs_, power_state, &output_power); 692 cached_outputs_, power_state, &output_power);
729 VLOG(1) << "EnterState: output=" << OutputStateToString(output_state) 693 VLOG(1) << "EnterState: output=" << OutputStateToString(output_state)
730 << " power=" << DisplayPowerStateToString(power_state); 694 << " power=" << DisplayPowerStateToString(power_state);
731 695
732 // Framebuffer dimensions. 696 // Framebuffer dimensions.
733 int width = 0, height = 0; 697 gfx::Size size;
734 std::vector<OutputSnapshot> updated_outputs = cached_outputs_; 698
699 std::vector<gfx::Point> new_origins(cached_outputs_.size(), gfx::Point());
700 std::vector<const ui::DisplayMode*> new_mode;
701 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
Daniel Erat 2014/03/05 01:56:12 nit: remove curly brackets
dnicoara 2014/03/05 17:29:25 Done.
702 new_mode.push_back(cached_outputs_[i].display->current_mode());
703 }
735 704
736 switch (output_state) { 705 switch (output_state) {
737 case ui::OUTPUT_STATE_INVALID: 706 case ui::OUTPUT_STATE_INVALID:
738 NOTREACHED() << "Ignoring request to enter invalid state with " 707 NOTREACHED() << "Ignoring request to enter invalid state with "
739 << updated_outputs.size() << " connected output(s)"; 708 << cached_outputs_.size() << " connected output(s)";
740 return false; 709 return false;
741 case ui::OUTPUT_STATE_HEADLESS: 710 case ui::OUTPUT_STATE_HEADLESS:
742 if (updated_outputs.size() != 0) { 711 if (cached_outputs_.size() != 0) {
743 LOG(WARNING) << "Ignoring request to enter headless mode with " 712 LOG(WARNING) << "Ignoring request to enter headless mode with "
744 << updated_outputs.size() << " connected output(s)"; 713 << cached_outputs_.size() << " connected output(s)";
745 return false; 714 return false;
746 } 715 }
747 break; 716 break;
748 case ui::OUTPUT_STATE_SINGLE: { 717 case ui::OUTPUT_STATE_SINGLE: {
749 // If there are multiple outputs connected, only one should be turned on. 718 // If there are multiple outputs connected, only one should be turned on.
750 if (updated_outputs.size() != 1 && num_on_outputs != 1) { 719 if (cached_outputs_.size() != 1 && num_on_outputs != 1) {
751 LOG(WARNING) << "Ignoring request to enter single mode with " 720 LOG(WARNING) << "Ignoring request to enter single mode with "
752 << updated_outputs.size() << " connected outputs and " 721 << cached_outputs_.size() << " connected outputs and "
753 << num_on_outputs << " turned on"; 722 << num_on_outputs << " turned on";
754 return false; 723 return false;
755 } 724 }
756 725
757 for (size_t i = 0; i < updated_outputs.size(); ++i) { 726 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
758 OutputSnapshot* output = &updated_outputs[i]; 727 InternalDisplayState* output = &cached_outputs_[i];
759 output->x = 0; 728 new_mode[i] = output_power[i] ? output->selected_mode : NULL;
760 output->y = 0;
761 output->current_mode = output_power[i] ? output->selected_mode : None;
762 729
763 if (output_power[i] || updated_outputs.size() == 1) { 730 if (output_power[i] || cached_outputs_.size() == 1) {
764 const ModeInfo* mode_info = 731 const ui::DisplayMode* mode_info = output->selected_mode;
765 GetModeInfo(*output, output->selected_mode);
766 if (!mode_info) 732 if (!mode_info)
767 return false; 733 return false;
768 if (mode_info->width == 1024 && mode_info->height == 768) { 734 if (mode_info->size() == gfx::Size(1024, 768)) {
769 VLOG(1) << "Potentially misdetecting display(1024x768):" 735 VLOG(1) << "Potentially misdetecting display(1024x768):"
770 << " outputs size=" << updated_outputs.size() 736 << " outputs size=" << cached_outputs_.size()
771 << ", num_on_outputs=" << num_on_outputs 737 << ", num_on_outputs=" << num_on_outputs
772 << ", current size:" << width << "x" << height 738 << ", current size:" << size.width() << "x" << size.height()
773 << ", i=" << i 739 << ", i=" << i << ", output=" << output->display->ToString()
774 << ", output=" << OutputSnapshotToString(output) 740 << ", display_mode=" << DisplayModeToString(mode_info);
775 << ", mode_info=" << ModeInfoToString(mode_info);
776 } 741 }
777 width = mode_info->width; 742 size = mode_info->size();
778 height = mode_info->height;
779 } 743 }
780 } 744 }
781 break; 745 break;
782 } 746 }
783 case ui::OUTPUT_STATE_DUAL_MIRROR: { 747 case ui::OUTPUT_STATE_DUAL_MIRROR: {
784 if (updated_outputs.size() != 2 || 748 if (cached_outputs_.size() != 2 ||
785 (num_on_outputs != 0 && num_on_outputs != 2)) { 749 (num_on_outputs != 0 && num_on_outputs != 2)) {
786 LOG(WARNING) << "Ignoring request to enter mirrored mode with " 750 LOG(WARNING) << "Ignoring request to enter mirrored mode with "
787 << updated_outputs.size() << " connected output(s) and " 751 << cached_outputs_.size() << " connected output(s) and "
788 << num_on_outputs << " turned on"; 752 << num_on_outputs << " turned on";
789 return false; 753 return false;
790 } 754 }
791 755
792 if (!updated_outputs[0].mirror_mode) 756 const ui::DisplayMode* mode_info = cached_outputs_[0].mirror_mode;
793 return false;
794 const ModeInfo* mode_info =
795 GetModeInfo(updated_outputs[0], updated_outputs[0].mirror_mode);
796 if (!mode_info) 757 if (!mode_info)
797 return false; 758 return false;
798 width = mode_info->width; 759 size = mode_info->size();
799 height = mode_info->height;
800 760
801 for (size_t i = 0; i < updated_outputs.size(); ++i) { 761 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
802 OutputSnapshot* output = &updated_outputs[i]; 762 InternalDisplayState* output = &cached_outputs_[i];
803 output->x = 0; 763 new_mode[i] = output_power[i] ? output->mirror_mode : NULL;
804 output->y = 0;
805 output->current_mode = output_power[i] ? output->mirror_mode : None;
806 if (output->touch_device_id) { 764 if (output->touch_device_id) {
807 // CTM needs to be calculated if aspect preserving scaling is used. 765 // CTM needs to be calculated if aspect preserving scaling is used.
808 // Otherwise, assume it is full screen, and use identity CTM. 766 // Otherwise, assume it is full screen, and use identity CTM.
809 if (output->mirror_mode != output->native_mode && 767 if (output->mirror_mode != output->display->native_mode() &&
810 output->is_aspect_preserving_scaling) { 768 output->display->is_aspect_preserving_scaling()) {
811 output->transform = GetMirrorModeCTM(*output); 769 output->transform = GetMirrorModeCTM(*output);
812 mirrored_display_area_ratio_map_[output->touch_device_id] = 770 mirrored_display_area_ratio_map_[output->touch_device_id] =
813 GetMirroredDisplayAreaRatio(*output); 771 GetMirroredDisplayAreaRatio(*output);
814 } 772 }
815 } 773 }
816 } 774 }
817 break; 775 break;
818 } 776 }
819 case ui::OUTPUT_STATE_DUAL_EXTENDED: { 777 case ui::OUTPUT_STATE_DUAL_EXTENDED: {
820 if (updated_outputs.size() != 2 || 778 if (cached_outputs_.size() != 2 ||
821 (num_on_outputs != 0 && num_on_outputs != 2)) { 779 (num_on_outputs != 0 && num_on_outputs != 2)) {
822 LOG(WARNING) << "Ignoring request to enter extended mode with " 780 LOG(WARNING) << "Ignoring request to enter extended mode with "
823 << updated_outputs.size() << " connected output(s) and " 781 << cached_outputs_.size() << " connected output(s) and "
824 << num_on_outputs << " turned on"; 782 << num_on_outputs << " turned on";
825 return false; 783 return false;
826 } 784 }
827 785
828 for (size_t i = 0; i < updated_outputs.size(); ++i) { 786 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
829 OutputSnapshot* output = &updated_outputs[i]; 787 InternalDisplayState* output = &cached_outputs_[i];
830 output->x = 0; 788 new_origins[i].set_y(size.height() ? size.height() + kVerticalGap : 0);
831 output->y = height ? height + kVerticalGap : 0; 789 new_mode[i] = output_power[i] ? output->selected_mode : NULL;
832 output->current_mode = output_power[i] ? output->selected_mode : None;
833 790
834 // Retain the full screen size even if all outputs are off so the 791 // Retain the full screen size even if all outputs are off so the
835 // same desktop configuration can be restored when the outputs are 792 // same desktop configuration can be restored when the outputs are
836 // turned back on. 793 // turned back on.
837 const ModeInfo* mode_info = 794 const ui::DisplayMode* mode_info = cached_outputs_[i].selected_mode;
838 GetModeInfo(updated_outputs[i], updated_outputs[i].selected_mode);
839 if (!mode_info) 795 if (!mode_info)
840 return false; 796 return false;
841 width = std::max<int>(width, mode_info->width); 797
842 height += (height ? kVerticalGap : 0) + mode_info->height; 798 size.set_width(std::max<int>(size.width(), mode_info->size().width()));
799 size.set_height(size.height() + (size.height() ? kVerticalGap : 0) +
800 mode_info->size().height());
843 } 801 }
844 802
845 for (size_t i = 0; i < updated_outputs.size(); ++i) { 803 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
846 OutputSnapshot* output = &updated_outputs[i]; 804 InternalDisplayState* output = &cached_outputs_[i];
847 if (output->touch_device_id) 805 if (output->touch_device_id)
848 output->transform = GetExtendedModeCTM(*output, width, height); 806 output->transform = GetExtendedModeCTM(*output, new_origins[i], size);
849 } 807 }
850 break; 808 break;
851 } 809 }
852 } 810 }
853 811
854 // Finally, apply the desired changes. 812 // Finally, apply the desired changes.
855 DCHECK_EQ(cached_outputs_.size(), updated_outputs.size());
856 bool all_succeeded = true; 813 bool all_succeeded = true;
857 if (!updated_outputs.empty()) { 814 if (!cached_outputs_.empty()) {
858 native_display_delegate_->CreateFrameBuffer(width, height, updated_outputs); 815 native_display_delegate_->CreateFrameBuffer(size);
859 for (size_t i = 0; i < updated_outputs.size(); ++i) { 816 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
860 const OutputSnapshot& output = updated_outputs[i]; 817 const InternalDisplayState& output = cached_outputs_[i];
861 bool configure_succeeded =false; 818 bool configure_succeeded = false;
862 819
863 while (true) { 820 while (true) {
864 if (native_display_delegate_->Configure(output, 821 if (native_display_delegate_->Configure(
865 output.current_mode, 822 *output.display, new_mode[i], new_origins[i])) {
866 output.x, 823 output.display->set_current_mode(new_mode[i]);
867 output.y)) { 824 output.display->set_origin(new_origins[i]);
825
868 configure_succeeded = true; 826 configure_succeeded = true;
869 break; 827 break;
870 } 828 }
871 829
872 LOG(WARNING) << "Unable to configure CRTC " << output.crtc << ":" 830 const ui::DisplayMode* mode_info = new_mode[i];
873 << " mode=" << output.current_mode
874 << " output=" << output.output
875 << " x=" << output.x
876 << " y=" << output.y;
877
878 const ModeInfo* mode_info = GetModeInfo(output, output.current_mode);
879 if (!mode_info) 831 if (!mode_info)
880 break; 832 break;
881 833
882 // Find the mode with the next-best resolution and see if that can 834 // Find the mode with the next-best resolution and see if that can
883 // be set. 835 // be set.
884 int best_mode_pixels = 0; 836 int best_mode_pixels = 0;
885 837
886 int current_mode_pixels = mode_info->width * mode_info->height; 838 int current_mode_pixels = mode_info->size().GetArea();
887 for (ModeInfoMap::const_iterator it = output.mode_infos.begin(); 839 for (DisplayModeList::const_iterator it =
888 it != output.mode_infos.end(); it++) { 840 output.display->modes().begin();
889 int pixel_count = it->second.width * it->second.height; 841 it != output.display->modes().end();
842 it++) {
843 int pixel_count = (*it)->size().GetArea();
890 if ((pixel_count < current_mode_pixels) && 844 if ((pixel_count < current_mode_pixels) &&
891 (pixel_count > best_mode_pixels)) { 845 (pixel_count > best_mode_pixels)) {
892 updated_outputs[i].current_mode = it->first; 846 new_mode[i] = *it;
893 best_mode_pixels = pixel_count; 847 best_mode_pixels = pixel_count;
894 } 848 }
895 } 849 }
896 850
897 if (best_mode_pixels == 0) 851 if (best_mode_pixels == 0)
898 break; 852 break;
899 } 853 }
900 854
901 if (configure_succeeded) { 855 if (configure_succeeded) {
902 if (output.touch_device_id) 856 if (output.touch_device_id)
903 touchscreen_delegate_->ConfigureCTM(output.touch_device_id, 857 touchscreen_delegate_->ConfigureCTM(output.touch_device_id,
904 output.transform); 858 output.transform);
905 cached_outputs_[i] = updated_outputs[i];
906 } else { 859 } else {
907 all_succeeded = false; 860 all_succeeded = false;
908 } 861 }
909 862
910 // If we are trying to set mirror mode and one of the modesets fails, 863 // If we are trying to set mirror mode and one of the modesets fails,
911 // then the two monitors will be mis-matched. In this case, return 864 // then the two monitors will be mis-matched. In this case, return
912 // false to let the observers be aware. 865 // false to let the observers be aware.
913 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR && output_power[i] && 866 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR && output_power[i] &&
914 output.current_mode != output.mirror_mode) 867 output.display->current_mode() != output.mirror_mode)
915 all_succeeded = false; 868 all_succeeded = false;
916 869
917 } 870 }
918 } 871 }
919 872
920 if (all_succeeded) { 873 if (all_succeeded) {
921 output_state_ = output_state; 874 output_state_ = output_state;
922 power_state_ = power_state; 875 power_state_ = power_state;
923 } 876 }
924 return all_succeeded; 877 return all_succeeded;
(...skipping 11 matching lines...) Expand all
936 if (num_on_outputs == 1) { 889 if (num_on_outputs == 1) {
937 // If only one output is currently turned on, return the "single" 890 // If only one output is currently turned on, return the "single"
938 // state so that its native mode will be used. 891 // state so that its native mode will be used.
939 return ui::OUTPUT_STATE_SINGLE; 892 return ui::OUTPUT_STATE_SINGLE;
940 } else { 893 } else {
941 // With either both outputs on or both outputs off, use one of the 894 // With either both outputs on or both outputs off, use one of the
942 // dual modes. 895 // dual modes.
943 std::vector<int64> display_ids; 896 std::vector<int64> display_ids;
944 for (size_t i = 0; i < cached_outputs_.size(); ++i) { 897 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
945 // If display id isn't available, switch to extended mode. 898 // If display id isn't available, switch to extended mode.
946 if (!cached_outputs_[i].has_display_id) 899 if (!cached_outputs_[i].display->has_proper_display_id())
947 return ui::OUTPUT_STATE_DUAL_EXTENDED; 900 return ui::OUTPUT_STATE_DUAL_EXTENDED;
948 display_ids.push_back(cached_outputs_[i].display_id); 901 display_ids.push_back(cached_outputs_[i].display->display_id());
949 } 902 }
950 return state_controller_->GetStateForDisplayIds(display_ids); 903 return state_controller_->GetStateForDisplayIds(display_ids);
951 } 904 }
952 } 905 }
953 default: 906 default:
954 NOTREACHED(); 907 NOTREACHED();
955 } 908 }
956 return ui::OUTPUT_STATE_INVALID; 909 return ui::OUTPUT_STATE_INVALID;
957 } 910 }
958 911
959 OutputConfigurator::CoordinateTransformation 912 OutputConfigurator::CoordinateTransformation
960 OutputConfigurator::GetMirrorModeCTM( 913 OutputConfigurator::GetMirrorModeCTM(const InternalDisplayState& output) {
961 const OutputConfigurator::OutputSnapshot& output) {
962 CoordinateTransformation ctm; // Default to identity 914 CoordinateTransformation ctm; // Default to identity
963 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode); 915 const ui::DisplayMode* native_mode_info = output.display->native_mode();
964 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode); 916 const ui::DisplayMode* mirror_mode_info = output.mirror_mode;
965 917
966 if (!native_mode_info || !mirror_mode_info || 918 if (!native_mode_info || !mirror_mode_info ||
967 native_mode_info->height == 0 || mirror_mode_info->height == 0 || 919 native_mode_info->size().height() == 0 ||
968 native_mode_info->width == 0 || mirror_mode_info->width == 0) 920 mirror_mode_info->size().height() == 0 ||
921 native_mode_info->size().width() == 0 ||
922 mirror_mode_info->size().width() == 0)
969 return ctm; 923 return ctm;
970 924
971 float native_mode_ar = static_cast<float>(native_mode_info->width) / 925 float native_mode_ar = static_cast<float>(native_mode_info->size().width()) /
972 static_cast<float>(native_mode_info->height); 926 static_cast<float>(native_mode_info->size().height());
973 float mirror_mode_ar = static_cast<float>(mirror_mode_info->width) / 927 float mirror_mode_ar = static_cast<float>(mirror_mode_info->size().width()) /
974 static_cast<float>(mirror_mode_info->height); 928 static_cast<float>(mirror_mode_info->size().height());
975 929
976 if (mirror_mode_ar > native_mode_ar) { // Letterboxing 930 if (mirror_mode_ar > native_mode_ar) { // Letterboxing
977 ctm.x_scale = 1.0; 931 ctm.x_scale = 1.0;
978 ctm.x_offset = 0.0; 932 ctm.x_offset = 0.0;
979 ctm.y_scale = mirror_mode_ar / native_mode_ar; 933 ctm.y_scale = mirror_mode_ar / native_mode_ar;
980 ctm.y_offset = (native_mode_ar / mirror_mode_ar - 1.0) * 0.5; 934 ctm.y_offset = (native_mode_ar / mirror_mode_ar - 1.0) * 0.5;
981 return ctm; 935 return ctm;
982 } 936 }
983 if (native_mode_ar > mirror_mode_ar) { // Pillarboxing 937 if (native_mode_ar > mirror_mode_ar) { // Pillarboxing
984 ctm.y_scale = 1.0; 938 ctm.y_scale = 1.0;
985 ctm.y_offset = 0.0; 939 ctm.y_offset = 0.0;
986 ctm.x_scale = native_mode_ar / mirror_mode_ar; 940 ctm.x_scale = native_mode_ar / mirror_mode_ar;
987 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5; 941 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5;
988 return ctm; 942 return ctm;
989 } 943 }
990 944
991 return ctm; // Same aspect ratio - return identity 945 return ctm; // Same aspect ratio - return identity
992 } 946 }
993 947
994 OutputConfigurator::CoordinateTransformation 948 OutputConfigurator::CoordinateTransformation
995 OutputConfigurator::GetExtendedModeCTM( 949 OutputConfigurator::GetExtendedModeCTM(const InternalDisplayState& output,
996 const OutputConfigurator::OutputSnapshot& output, 950 const gfx::Point& new_origin,
997 int framebuffer_width, 951 const gfx::Size& framebuffer_size) {
998 int framebuffer_height) {
999 CoordinateTransformation ctm; // Default to identity 952 CoordinateTransformation ctm; // Default to identity
1000 const ModeInfo* mode_info = GetModeInfo(output, output.selected_mode); 953 const ui::DisplayMode* mode_info = output.selected_mode;
1001 DCHECK(mode_info); 954 DCHECK(mode_info);
1002 if (!mode_info) 955 if (!mode_info)
1003 return ctm; 956 return ctm;
1004 // An example of how to calculate the CTM. 957 // An example of how to calculate the CTM.
1005 // Suppose we have 2 monitors, the first one has size 1366 x 768. 958 // Suppose we have 2 monitors, the first one has size 1366 x 768.
1006 // The second one has size 2560 x 1600 959 // The second one has size 2560 x 1600
1007 // The total size of framebuffer is 2560 x 2428 960 // The total size of framebuffer is 2560 x 2428
1008 // where 2428 = 768 + 60 (hidden gap) + 1600 961 // where 2428 = 768 + 60 (hidden gap) + 1600
1009 // and the sceond monitor is translated to Point (0, 828) in the 962 // and the sceond monitor is translated to Point (0, 828) in the
1010 // framebuffer. 963 // framebuffer.
1011 // X will first map input event location to [0, 2560) x [0, 2428), 964 // X will first map input event location to [0, 2560) x [0, 2428),
1012 // then apply CTM on it. 965 // then apply CTM on it.
1013 // So to compute CTM, for monitor1, we have 966 // So to compute CTM, for monitor1, we have
1014 // x_scale = (1366 - 1) / (2560 - 1) 967 // x_scale = (1366 - 1) / (2560 - 1)
1015 // x_offset = 0 / (2560 - 1) 968 // x_offset = 0 / (2560 - 1)
1016 // y_scale = (768 - 1) / (2428 - 1) 969 // y_scale = (768 - 1) / (2428 - 1)
1017 // y_offset = 0 / (2428 -1) 970 // y_offset = 0 / (2428 -1)
1018 // For Monitor 2, we have 971 // For Monitor 2, we have
1019 // x_scale = (2560 - 1) / (2560 - 1) 972 // x_scale = (2560 - 1) / (2560 - 1)
1020 // x_offset = 0 / (2560 - 1) 973 // x_offset = 0 / (2560 - 1)
1021 // y_scale = (1600 - 1) / (2428 - 1) 974 // y_scale = (1600 - 1) / (2428 - 1)
1022 // y_offset = 828 / (2428 -1) 975 // y_offset = 828 / (2428 -1)
1023 // See the unittest OutputConfiguratorTest.CTMForMultiScreens. 976 // See the unittest OutputConfiguratorTest.CTMForMultiScreens.
1024 ctm.x_scale = 977 ctm.x_scale = static_cast<float>(mode_info->size().width() - 1) /
1025 static_cast<float>(mode_info->width - 1) / (framebuffer_width - 1); 978 (framebuffer_size.width() - 1);
1026 ctm.x_offset = static_cast<float>(output.x) / (framebuffer_width - 1); 979 ctm.x_offset =
1027 ctm.y_scale = 980 static_cast<float>(new_origin.x()) / (framebuffer_size.width() - 1);
1028 static_cast<float>(mode_info->height - 1) / (framebuffer_height - 1); 981 ctm.y_scale = static_cast<float>(mode_info->size().height() - 1) /
1029 ctm.y_offset = static_cast<float>(output.y) / (framebuffer_height - 1); 982 (framebuffer_size.height() - 1);
983 ctm.y_offset =
984 static_cast<float>(new_origin.y()) / (framebuffer_size.height() - 1);
1030 return ctm; 985 return ctm;
1031 } 986 }
1032 987
1033 float OutputConfigurator::GetMirroredDisplayAreaRatio( 988 float OutputConfigurator::GetMirroredDisplayAreaRatio(
1034 const OutputConfigurator::OutputSnapshot& output) { 989 const InternalDisplayState& output) {
1035 float area_ratio = 1.0f; 990 float area_ratio = 1.0f;
1036 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode); 991 const ui::DisplayMode* native_mode_info = output.display->native_mode();
1037 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode); 992 const ui::DisplayMode* mirror_mode_info = output.mirror_mode;
1038 993
1039 if (!native_mode_info || !mirror_mode_info || 994 if (!native_mode_info || !mirror_mode_info ||
1040 native_mode_info->height == 0 || mirror_mode_info->height == 0 || 995 native_mode_info->size().height() == 0 ||
1041 native_mode_info->width == 0 || mirror_mode_info->width == 0) 996 mirror_mode_info->size().height() == 0 ||
997 native_mode_info->size().width() == 0 ||
998 mirror_mode_info->size().width() == 0)
1042 return area_ratio; 999 return area_ratio;
1043 1000
1044 float width_ratio = static_cast<float>(mirror_mode_info->width) / 1001 float width_ratio = static_cast<float>(mirror_mode_info->size().width()) /
1045 static_cast<float>(native_mode_info->width); 1002 static_cast<float>(native_mode_info->size().width());
1046 float height_ratio = static_cast<float>(mirror_mode_info->height) / 1003 float height_ratio = static_cast<float>(mirror_mode_info->size().height()) /
1047 static_cast<float>(native_mode_info->height); 1004 static_cast<float>(native_mode_info->size().height());
1048 1005
1049 area_ratio = width_ratio * height_ratio; 1006 area_ratio = width_ratio * height_ratio;
1050 return area_ratio; 1007 return area_ratio;
1051 } 1008 }
1052 1009
1053 } // namespace chromeos 1010 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698