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

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

Issue 13756002: chromeos: Add testing support code to OutputConfigurator. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove delegate check Created 7 years, 8 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/chromeos/chromeos_version.h" 11 #include "base/chromeos/chromeos_version.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/time.h" 14 #include "base/time.h"
15 #include "chromeos/dbus/dbus_thread_manager.h"
16 #include "chromeos/dbus/power_manager_client.h"
17 #include "chromeos/display/real_output_configurator_delegate.h" 15 #include "chromeos/display/real_output_configurator_delegate.h"
18 16
19 namespace chromeos { 17 namespace chromeos {
20 18
21 namespace { 19 namespace {
22 20
23 // Prefixes for the built-in displays. 21 // Prefixes for the built-in displays.
24 const char kInternal_LVDS[] = "LVDS"; 22 const char kInternal_LVDS[] = "LVDS";
25 const char kInternal_eDP[] = "eDP"; 23 const char kInternal_eDP[] = "eDP";
26 24
27 // The delay to perform configuration after RRNotify. See the comment 25 // The delay to perform configuration after RRNotify. See the comment
28 // in |Dispatch()|. 26 // in |Dispatch()|.
29 const int64 kConfigureDelayMs = 500; 27 const int64 kConfigureDelayMs = 500;
30 28
31 // Gap between screens so cursor at bottom of active display doesn't partially
32 // appear on top of inactive display. Higher numbers guard against larger
33 // cursors, but also waste more memory.
34 // For simplicity, this is hard-coded to 60 to avoid the complexity of always
35 // determining the DPI of the screen and rationalizing which screen we need to
36 // use for the DPI calculation.
37 // See crbug.com/130188 for initial discussion.
38 const int kVerticalGap = 60;
39
40 // Returns a string describing |state|. 29 // Returns a string describing |state|.
41 std::string DisplayPowerStateToString(DisplayPowerState state) { 30 std::string DisplayPowerStateToString(DisplayPowerState state) {
42 switch (state) { 31 switch (state) {
43 case DISPLAY_POWER_ALL_ON: 32 case DISPLAY_POWER_ALL_ON:
44 return "ALL_ON"; 33 return "ALL_ON";
45 case DISPLAY_POWER_ALL_OFF: 34 case DISPLAY_POWER_ALL_OFF:
46 return "ALL_OFF"; 35 return "ALL_OFF";
47 case DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON: 36 case DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON:
48 return "INTERNAL_OFF_EXTERNAL_ON"; 37 return "INTERNAL_OFF_EXTERNAL_ON";
49 case DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF: 38 case DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // At this point, we expect both displays to be in native mode and tiled 77 // At this point, we expect both displays to be in native mode and tiled
89 // such that one is primary and another is correctly positioned as 78 // such that one is primary and another is correctly positioned as
90 // secondary. If any of these assumptions are false, this is an unknown 79 // secondary. If any of these assumptions are false, this is an unknown
91 // configuration. 80 // configuration.
92 bool primary_native = (primary_mode == outputs[0].native_mode) || 81 bool primary_native = (primary_mode == outputs[0].native_mode) ||
93 (primary_mode == None); 82 (primary_mode == None);
94 bool secondary_native = (secondary_mode == outputs[1].native_mode) || 83 bool secondary_native = (secondary_mode == outputs[1].native_mode) ||
95 (secondary_mode == None); 84 (secondary_mode == None);
96 if (primary_native && secondary_native) { 85 if (primary_native && secondary_native) {
97 // Just check the relative locations. 86 // Just check the relative locations.
98 int secondary_offset = outputs[0].height + kVerticalGap; 87 int secondary_offset = outputs[0].height +
88 OutputConfigurator::kVerticalGap;
99 if (outputs[0].y == 0 && outputs[1].y == secondary_offset) { 89 if (outputs[0].y == 0 && outputs[1].y == secondary_offset) {
100 state = STATE_DUAL_EXTENDED; 90 state = STATE_DUAL_EXTENDED;
101 } else { 91 } else {
102 // Unexpected locations. 92 // Unexpected locations.
103 state = STATE_DUAL_UNKNOWN; 93 state = STATE_DUAL_UNKNOWN;
104 } 94 }
105 } else { 95 } else {
106 // Mode assumptions don't hold. 96 // Mode assumptions don't hold.
107 state = STATE_DUAL_UNKNOWN; 97 state = STATE_DUAL_UNKNOWN;
108 } 98 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 OutputConfigurator::CrtcConfig::CrtcConfig(RRCrtc crtc, 149 OutputConfigurator::CrtcConfig::CrtcConfig(RRCrtc crtc,
160 int x, int y, 150 int x, int y,
161 RRMode mode, 151 RRMode mode,
162 RROutput output) 152 RROutput output)
163 : crtc(crtc), 153 : crtc(crtc),
164 x(x), 154 x(x),
165 y(y), 155 y(y),
166 mode(mode), 156 mode(mode),
167 output(output) {} 157 output(output) {}
168 158
159 bool OutputConfigurator::TestApi::SendOutputChangeEvents(bool connected) {
160 XRRScreenChangeNotifyEvent screen_event;
161 memset(&screen_event, 0, sizeof(screen_event));
162 screen_event.type = xrandr_event_base_ + RRScreenChangeNotify;
163 configurator_->Dispatch(
164 reinterpret_cast<const base::NativeEvent>(&screen_event));
165
166 XRROutputChangeNotifyEvent notify_event;
167 memset(&notify_event, 0, sizeof(notify_event));
168 notify_event.type = xrandr_event_base_ + RRNotify;
169 notify_event.subtype = RRNotify_OutputChange;
170 notify_event.connection = connected ? RR_Connected : RR_Disconnected;
171 configurator_->Dispatch(
172 reinterpret_cast<const base::NativeEvent>(&notify_event));
173
174 if (!configurator_->configure_timer_->IsRunning()) {
175 LOG(ERROR) << "ConfigureOutputs() timer not running";
176 return false;
177 }
178
179 configurator_->ConfigureOutputs();
180 return true;
181 }
182
169 // static 183 // static
170 bool OutputConfigurator::IsInternalOutputName(const std::string& name) { 184 bool OutputConfigurator::IsInternalOutputName(const std::string& name) {
171 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0; 185 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0;
172 } 186 }
173 187
174 OutputConfigurator::OutputConfigurator() 188 OutputConfigurator::OutputConfigurator()
175 : state_controller_(NULL), 189 : state_controller_(NULL),
176 delegate_(new RealOutputConfiguratorDelegate()),
177 configure_display_(base::chromeos::IsRunningOnChromeOS()), 190 configure_display_(base::chromeos::IsRunningOnChromeOS()),
178 connected_output_count_(0), 191 connected_output_count_(0),
179 xrandr_event_base_(0), 192 xrandr_event_base_(0),
180 output_state_(STATE_INVALID), 193 output_state_(STATE_INVALID),
181 power_state_(DISPLAY_POWER_ALL_ON) { 194 power_state_(DISPLAY_POWER_ALL_ON) {
182 } 195 }
183 196
184 OutputConfigurator::~OutputConfigurator() {} 197 OutputConfigurator::~OutputConfigurator() {}
185 198
199 void OutputConfigurator::SetDelegateForTesting(
200 scoped_ptr<Delegate> delegate) {
201 delegate_ = delegate.Pass();
202 configure_display_ = true;
203 }
204
186 void OutputConfigurator::Init(bool is_panel_fitting_enabled, 205 void OutputConfigurator::Init(bool is_panel_fitting_enabled,
187 uint32 background_color_argb) { 206 uint32 background_color_argb) {
188 if (!configure_display_) 207 if (!configure_display_)
189 return; 208 return;
190 209
210 if (!delegate_)
211 delegate_.reset(new RealOutputConfiguratorDelegate());
212
191 // Cache the initial output state. 213 // Cache the initial output state.
192 delegate_->SetPanelFittingEnabled(is_panel_fitting_enabled); 214 delegate_->SetPanelFittingEnabled(is_panel_fitting_enabled);
193 delegate_->GrabServer(); 215 delegate_->GrabServer();
194 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 216 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs();
195 if (outputs.size() > 1 && background_color_argb) 217 if (outputs.size() > 1 && background_color_argb)
196 delegate_->SetBackgroundColor(background_color_argb); 218 delegate_->SetBackgroundColor(background_color_argb);
197 delegate_->UngrabServer(); 219 delegate_->UngrabServer();
198 } 220 }
199 221
200 void OutputConfigurator::Start() { 222 void OutputConfigurator::Start() {
223 if (!configure_display_)
224 return;
225
201 delegate_->GrabServer(); 226 delegate_->GrabServer();
202 // Detect our initial state.
203 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 227 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs();
204 connected_output_count_ = outputs.size(); 228 connected_output_count_ = outputs.size();
205 229
206 output_state_ = InferCurrentState(outputs); 230 output_state_ = InferCurrentState(outputs);
207 // Ensure that we are in a supported state with all connected displays powered 231 // Ensure that we are in a supported state with all connected displays powered
208 // on. 232 // on.
209 OutputState starting_state = GetNextState(outputs); 233 OutputState starting_state = GetNextState(outputs);
210 if (output_state_ != starting_state && 234 if (output_state_ != starting_state &&
211 EnterState(starting_state, power_state_, outputs)) { 235 EnterState(starting_state, power_state_, outputs)) {
212 output_state_ = starting_state; 236 output_state_ = starting_state;
213 } 237 }
214 bool is_projecting = IsProjecting(outputs); 238 bool is_projecting = IsProjecting(outputs);
215 239
216 delegate_->InitXRandRExtension(&xrandr_event_base_); 240 delegate_->InitXRandRExtension(&xrandr_event_base_);
217 241
218 // Force the DPMS on chrome startup as the driver doesn't always detect 242 // Force the DPMS on chrome startup as the driver doesn't always detect
219 // that all displays are on when signing out. 243 // that all displays are on when signing out.
220 delegate_->ForceDPMSOn(); 244 delegate_->ForceDPMSOn();
221
222 // Relinquish X resources.
223 delegate_->UngrabServer(); 245 delegate_->UngrabServer();
224 246 delegate_->SendProjectingStateToPowerManager(is_projecting);
225 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
226 SetIsProjecting(is_projecting);
227 } 247 }
228 248
229 void OutputConfigurator::Stop() { 249 void OutputConfigurator::Stop() {
230 configure_display_ = false; 250 configure_display_ = false;
231 } 251 }
232 252
233 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, 253 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state,
234 int flags) { 254 int flags) {
255 if (!configure_display_)
256 return false;
257
235 VLOG(1) << "SetDisplayPower: power_state=" 258 VLOG(1) << "SetDisplayPower: power_state="
236 << DisplayPowerStateToString(power_state) << " flags=" << flags; 259 << DisplayPowerStateToString(power_state) << " flags=" << flags;
237
238 if (!configure_display_)
239 return false;
240 if (power_state == power_state_ && !(flags & kSetDisplayPowerForceProbe)) 260 if (power_state == power_state_ && !(flags & kSetDisplayPowerForceProbe))
241 return true; 261 return true;
242 262
243 delegate_->GrabServer(); 263 delegate_->GrabServer();
244 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 264 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs();
245 connected_output_count_ = outputs.size(); 265 connected_output_count_ = outputs.size();
246 266
247 bool only_if_single_internal_display = 267 bool only_if_single_internal_display =
248 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay; 268 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay;
249 bool single_internal_display = outputs.size() == 1 && outputs[0].is_internal; 269 bool single_internal_display = outputs.size() == 1 && outputs[0].is_internal;
250 if ((single_internal_display || !only_if_single_internal_display) && 270 if ((single_internal_display || !only_if_single_internal_display) &&
251 EnterState(output_state_, power_state, outputs)) { 271 EnterState(output_state_, power_state, outputs)) {
252 power_state_ = power_state; 272 power_state_ = power_state;
253 if (power_state != DISPLAY_POWER_ALL_OFF) { 273 if (power_state != DISPLAY_POWER_ALL_OFF) {
254 // Force the DPMS on since the driver doesn't always detect that it 274 // Force the DPMS on since the driver doesn't always detect that it
255 // should turn on. This is needed when coming back from idle suspend. 275 // should turn on. This is needed when coming back from idle suspend.
256 delegate_->ForceDPMSOn(); 276 delegate_->ForceDPMSOn();
257 } 277 }
258 } 278 }
259 279
260 delegate_->UngrabServer(); 280 delegate_->UngrabServer();
261 return true; 281 return true;
262 } 282 }
263 283
264 bool OutputConfigurator::SetDisplayMode(OutputState new_state) { 284 bool OutputConfigurator::SetDisplayMode(OutputState new_state) {
285 if (!configure_display_)
286 return false;
287
265 if (output_state_ == STATE_INVALID || 288 if (output_state_ == STATE_INVALID ||
266 output_state_ == STATE_HEADLESS || 289 output_state_ == STATE_HEADLESS ||
267 output_state_ == STATE_SINGLE) 290 output_state_ == STATE_SINGLE)
268 return false; 291 return false;
269 292
270 if (output_state_ == new_state) 293 if (output_state_ == new_state)
271 return true; 294 return true;
272 295
273 delegate_->GrabServer(); 296 delegate_->GrabServer();
274 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 297 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs();
275 connected_output_count_ = outputs.size(); 298 connected_output_count_ = outputs.size();
276 if (EnterState(new_state, power_state_, outputs)) 299 if (EnterState(new_state, power_state_, outputs))
277 output_state_ = new_state; 300 output_state_ = new_state;
278 delegate_->UngrabServer(); 301 delegate_->UngrabServer();
279 302
280 if (output_state_ == new_state) { 303 if (output_state_ == new_state) {
281 NotifyOnDisplayChanged(); 304 NotifyOnDisplayChanged();
282 } else { 305 } else {
283 FOR_EACH_OBSERVER( 306 FOR_EACH_OBSERVER(
284 Observer, observers_, OnDisplayModeChangeFailed(new_state)); 307 Observer, observers_, OnDisplayModeChangeFailed(new_state));
285 } 308 }
286 return true; 309 return true;
287 } 310 }
288 311
289 bool OutputConfigurator::Dispatch(const base::NativeEvent& event) { 312 bool OutputConfigurator::Dispatch(const base::NativeEvent& event) {
290 if (event->type - xrandr_event_base_ == RRScreenChangeNotify) 313 if (!configure_display_)
314 return true;
315
316 if (event->type - xrandr_event_base_ == RRScreenChangeNotify) {
291 delegate_->UpdateXRandRConfiguration(event); 317 delegate_->UpdateXRandRConfiguration(event);
292 // Ignore this event if the Xrandr extension isn't supported, or
293 // the device is being shutdown.
294 if (!configure_display_ ||
295 (event->type - xrandr_event_base_ != RRNotify)) {
296 return true; 318 return true;
297 } 319 }
320
321 if (event->type - xrandr_event_base_ != RRNotify)
322 return true;
323
298 XEvent* xevent = static_cast<XEvent*>(event); 324 XEvent* xevent = static_cast<XEvent*>(event);
299 XRRNotifyEvent* notify_event = 325 XRRNotifyEvent* notify_event =
300 reinterpret_cast<XRRNotifyEvent*>(xevent); 326 reinterpret_cast<XRRNotifyEvent*>(xevent);
301 if (notify_event->subtype == RRNotify_OutputChange) { 327 if (notify_event->subtype == RRNotify_OutputChange) {
302 XRROutputChangeNotifyEvent* output_change_event = 328 XRROutputChangeNotifyEvent* output_change_event =
303 reinterpret_cast<XRROutputChangeNotifyEvent*>(xevent); 329 reinterpret_cast<XRROutputChangeNotifyEvent*>(xevent);
304 if ((output_change_event->connection == RR_Connected) || 330 if ((output_change_event->connection == RR_Connected) ||
305 (output_change_event->connection == RR_Disconnected)) { 331 (output_change_event->connection == RR_Disconnected)) {
306 // Connecting/Disconnecting display may generate multiple 332 // Connecting/Disconnecting display may generate multiple
307 // RRNotify. Defer configuring outputs to avoid 333 // RRNotify. Defer configuring outputs to avoid
308 // grabbing X and configuring displays multiple times. 334 // grabbing X and configuring displays multiple times.
309 if (configure_timer_.get()) { 335 if (configure_timer_.get()) {
310 configure_timer_->Reset(); 336 configure_timer_->Reset();
311 } else { 337 } else {
312 configure_timer_.reset(new base::OneShotTimer<OutputConfigurator>()); 338 configure_timer_.reset(new base::OneShotTimer<OutputConfigurator>());
313 configure_timer_->Start( 339 configure_timer_->Start(
314 FROM_HERE, 340 FROM_HERE,
315 base::TimeDelta::FromMilliseconds(kConfigureDelayMs), 341 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
316 this, 342 this,
317 &OutputConfigurator::ConfigureOutputs); 343 &OutputConfigurator::ConfigureOutputs);
318 } 344 }
319 } 345 }
320 } 346 }
321 347
322 // Ignore the case of RR_UnknownConnection.
323 return true; 348 return true;
324 } 349 }
325 350
326 void OutputConfigurator::ConfigureOutputs() {
327 configure_timer_.reset();
328
329 delegate_->GrabServer();
330 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs();
331 int new_output_count = outputs.size();
332 // Don't skip even if the output counts didn't change because
333 // a display might have been swapped during the suspend.
334 connected_output_count_ = new_output_count;
335 OutputState new_state = GetNextState(outputs);
336 // When a display was swapped, the state moves from
337 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED, so don't rely on
338 // the state chagne to tell if it was successful.
339 bool success = EnterState(new_state, power_state_, outputs);
340 bool is_projecting = IsProjecting(outputs);
341 delegate_->UngrabServer();
342
343 if (success) {
344 output_state_ = new_state;
345 NotifyOnDisplayChanged();
346 } else {
347 FOR_EACH_OBSERVER(
348 Observer, observers_, OnDisplayModeChangeFailed(new_state));
349 }
350 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
351 SetIsProjecting(is_projecting);
352 }
353
354 void OutputConfigurator::AddObserver(Observer* observer) { 351 void OutputConfigurator::AddObserver(Observer* observer) {
355 observers_.AddObserver(observer); 352 observers_.AddObserver(observer);
356 } 353 }
357 354
358 void OutputConfigurator::RemoveObserver(Observer* observer) { 355 void OutputConfigurator::RemoveObserver(Observer* observer) {
359 observers_.RemoveObserver(observer); 356 observers_.RemoveObserver(observer);
360 } 357 }
361 358
362 void OutputConfigurator::SuspendDisplays() { 359 void OutputConfigurator::SuspendDisplays() {
363 // If the display is off due to user inactivity and there's only a single 360 // If the display is off due to user inactivity and there's only a single
(...skipping 11 matching lines...) Expand all
375 // racing with the HandleSuspendReadiness message. 372 // racing with the HandleSuspendReadiness message.
376 delegate_->SyncWithServer(); 373 delegate_->SyncWithServer();
377 } 374 }
378 375
379 void OutputConfigurator::ResumeDisplays() { 376 void OutputConfigurator::ResumeDisplays() {
380 // Force probing to ensure that we pick up any changes that were made 377 // Force probing to ensure that we pick up any changes that were made
381 // while the system was suspended. 378 // while the system was suspended.
382 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe); 379 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe);
383 } 380 }
384 381
382 void OutputConfigurator::ConfigureOutputs() {
383 configure_timer_.reset();
384
385 delegate_->GrabServer();
386 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs();
387 int new_output_count = outputs.size();
388 // Don't skip even if the output counts didn't change because
389 // a display might have been swapped during the suspend.
390 connected_output_count_ = new_output_count;
391 OutputState new_state = GetNextState(outputs);
392 // When a display was swapped, the state moves from
393 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED, so don't rely on
394 // the state chagne to tell if it was successful.
395 bool success = EnterState(new_state, power_state_, outputs);
396 bool is_projecting = IsProjecting(outputs);
397 delegate_->UngrabServer();
398
399 if (success) {
400 output_state_ = new_state;
401 NotifyOnDisplayChanged();
402 } else {
403 FOR_EACH_OBSERVER(
404 Observer, observers_, OnDisplayModeChangeFailed(new_state));
405 }
406 delegate_->SendProjectingStateToPowerManager(is_projecting);
407 }
408
385 void OutputConfigurator::NotifyOnDisplayChanged() { 409 void OutputConfigurator::NotifyOnDisplayChanged() {
386 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); 410 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged());
387 } 411 }
388 412
389 bool OutputConfigurator::EnterState( 413 bool OutputConfigurator::EnterState(
390 OutputState output_state, 414 OutputState output_state,
391 DisplayPowerState power_state, 415 DisplayPowerState power_state,
392 const std::vector<OutputSnapshot>& outputs) { 416 const std::vector<OutputSnapshot>& outputs) {
393 std::vector<bool> output_power(outputs.size()); 417 std::vector<bool> output_power(outputs.size());
394 bool all_outputs_off = true; 418 bool all_outputs_off = true;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 std::vector<CrtcConfig> configs(outputs.size()); 488 std::vector<CrtcConfig> configs(outputs.size());
465 int width = 0, height = 0; 489 int width = 0, height = 0;
466 490
467 for (size_t i = 0; i < outputs.size(); ++i) { 491 for (size_t i = 0; i < outputs.size(); ++i) {
468 if (!delegate_->GetModeDetails(outputs[i].native_mode, 492 if (!delegate_->GetModeDetails(outputs[i].native_mode,
469 &(mode_sizes[i].first), &(mode_sizes[i].second), NULL)) { 493 &(mode_sizes[i].first), &(mode_sizes[i].second), NULL)) {
470 return false; 494 return false;
471 } 495 }
472 496
473 configs[i] = CrtcConfig( 497 configs[i] = CrtcConfig(
474 outputs[i].crtc, 0, height, 498 outputs[i].crtc, 0, (height ? height + kVerticalGap : 0),
475 output_power[i] ? outputs[i].native_mode : None, 499 output_power[i] ? outputs[i].native_mode : None,
476 outputs[i].output); 500 outputs[i].output);
477 501
478 // Retain the full screen size if all outputs are off so the same 502 // Retain the full screen size if all outputs are off so the same
479 // desktop configuration can be restored when the outputs are 503 // desktop configuration can be restored when the outputs are
480 // turned back on. 504 // turned back on.
481 if (output_power[i] || all_outputs_off) { 505 if (output_power[i] || all_outputs_off) {
482 width = std::max<int>(width, mode_sizes[i].first); 506 width = std::max<int>(width, mode_sizes[i].first);
483 height += (height ? kVerticalGap : 0) + mode_sizes[i].second; 507 height += (height ? kVerticalGap : 0) + mode_sizes[i].second;
484 } 508 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 ctm.y_offset = 0.0; 586 ctm.y_offset = 0.0;
563 ctm.x_scale = native_mode_ar / mirror_mode_ar; 587 ctm.x_scale = native_mode_ar / mirror_mode_ar;
564 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5; 588 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5;
565 return ctm; 589 return ctm;
566 } 590 }
567 591
568 return ctm; // Same aspect ratio - return identity 592 return ctm; // Same aspect ratio - return identity
569 } 593 }
570 594
571 } // namespace chromeos 595 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/display/output_configurator.h ('k') | chromeos/display/real_output_configurator_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698