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

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

Issue 21297003: Add ability to set resolution on external display (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: adraddressed comment, adjusted test Created 7 years, 4 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 #include <X11/extensions/XInput2.h> 9 #include <X11/extensions/XInput2.h>
10 10
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 } 97 }
98 98
99 } // namespace 99 } // namespace
100 100
101 OutputConfigurator::OutputSnapshot::OutputSnapshot() 101 OutputConfigurator::OutputSnapshot::OutputSnapshot()
102 : output(None), 102 : output(None),
103 crtc(None), 103 crtc(None),
104 current_mode(None), 104 current_mode(None),
105 native_mode(None), 105 native_mode(None),
106 mirror_mode(None), 106 mirror_mode(None),
107 selected_mode(None),
107 y(0), 108 y(0),
108 height(0), 109 height(0),
109 is_internal(false), 110 is_internal(false),
110 is_aspect_preserving_scaling(false), 111 is_aspect_preserving_scaling(false),
111 touch_device_id(0), 112 touch_device_id(0),
112 display_id(0), 113 display_id(0),
113 has_display_id(false) {} 114 has_display_id(false) {}
114 115
115 OutputConfigurator::CoordinateTransformation::CoordinateTransformation() 116 OutputConfigurator::CoordinateTransformation::CoordinateTransformation()
116 : x_scale(1.0), 117 : x_scale(1.0),
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 delegate_->SetPanelFittingEnabled(is_panel_fitting_enabled); 190 delegate_->SetPanelFittingEnabled(is_panel_fitting_enabled);
190 } 191 }
191 192
192 void OutputConfigurator::Start(uint32 background_color_argb) { 193 void OutputConfigurator::Start(uint32 background_color_argb) {
193 if (!configure_display_) 194 if (!configure_display_)
194 return; 195 return;
195 196
196 delegate_->GrabServer(); 197 delegate_->GrabServer();
197 delegate_->InitXRandRExtension(&xrandr_event_base_); 198 delegate_->InitXRandRExtension(&xrandr_event_base_);
198 199
199 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 200 std::vector<OutputSnapshot> outputs =
201 delegate_->GetOutputs(state_controller_);
200 if (outputs.size() > 1 && background_color_argb) 202 if (outputs.size() > 1 && background_color_argb)
201 delegate_->SetBackgroundColor(background_color_argb); 203 delegate_->SetBackgroundColor(background_color_argb);
202 EnterStateOrFallBackToSoftwareMirroring( 204 EnterStateOrFallBackToSoftwareMirroring(
203 GetOutputState(outputs, power_state_), power_state_, outputs); 205 GetOutputState(outputs, power_state_), power_state_, outputs);
204 206
205 // Force the DPMS on chrome startup as the driver doesn't always detect 207 // Force the DPMS on chrome startup as the driver doesn't always detect
206 // that all displays are on when signing out. 208 // that all displays are on when signing out.
207 delegate_->ForceDPMSOn(); 209 delegate_->ForceDPMSOn();
208 delegate_->UngrabServer(); 210 delegate_->UngrabServer();
209 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs)); 211 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs));
210 NotifyOnDisplayChanged(); 212 NotifyOnDisplayChanged();
211 } 213 }
212 214
213 void OutputConfigurator::Stop() { 215 void OutputConfigurator::Stop() {
214 configure_display_ = false; 216 configure_display_ = false;
215 } 217 }
216 218
217 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, 219 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state,
218 int flags) { 220 int flags) {
219 if (!configure_display_) 221 if (!configure_display_)
220 return false; 222 return false;
221 223
222 VLOG(1) << "SetDisplayPower: power_state=" 224 VLOG(1) << "SetDisplayPower: power_state="
223 << DisplayPowerStateToString(power_state) << " flags=" << flags; 225 << DisplayPowerStateToString(power_state) << " flags=" << flags;
224 if (power_state == power_state_ && !(flags & kSetDisplayPowerForceProbe)) 226 if (power_state == power_state_ && !(flags & kSetDisplayPowerForceProbe))
225 return true; 227 return true;
226 228
227 delegate_->GrabServer(); 229 delegate_->GrabServer();
228 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 230 std::vector<OutputSnapshot> outputs =
231 delegate_->GetOutputs(state_controller_);
229 232
230 bool only_if_single_internal_display = 233 bool only_if_single_internal_display =
231 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay; 234 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay;
232 bool single_internal_display = outputs.size() == 1 && outputs[0].is_internal; 235 bool single_internal_display = outputs.size() == 1 && outputs[0].is_internal;
233 if ((single_internal_display || !only_if_single_internal_display) && 236 if ((single_internal_display || !only_if_single_internal_display) &&
234 EnterStateOrFallBackToSoftwareMirroring( 237 EnterStateOrFallBackToSoftwareMirroring(
235 GetOutputState(outputs, power_state), power_state, outputs)) { 238 GetOutputState(outputs, power_state), power_state, outputs)) {
236 if (power_state != DISPLAY_POWER_ALL_OFF) { 239 if (power_state != DISPLAY_POWER_ALL_OFF) {
237 // Force the DPMS on since the driver doesn't always detect that it 240 // Force the DPMS on since the driver doesn't always detect that it
238 // should turn on. This is needed when coming back from idle suspend. 241 // should turn on. This is needed when coming back from idle suspend.
(...skipping 13 matching lines...) Expand all
252 if (output_state_ == new_state) { 255 if (output_state_ == new_state) {
253 // Cancel software mirroring if the state is moving from 256 // Cancel software mirroring if the state is moving from
254 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED. 257 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED.
255 if (mirroring_controller_ && new_state == STATE_DUAL_EXTENDED) 258 if (mirroring_controller_ && new_state == STATE_DUAL_EXTENDED)
256 mirroring_controller_->SetSoftwareMirroring(false); 259 mirroring_controller_->SetSoftwareMirroring(false);
257 NotifyOnDisplayChanged(); 260 NotifyOnDisplayChanged();
258 return true; 261 return true;
259 } 262 }
260 263
261 delegate_->GrabServer(); 264 delegate_->GrabServer();
262 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 265 std::vector<OutputSnapshot> outputs =
266 delegate_->GetOutputs(state_controller_);
263 bool success = EnterStateOrFallBackToSoftwareMirroring( 267 bool success = EnterStateOrFallBackToSoftwareMirroring(
264 new_state, power_state_, outputs); 268 new_state, power_state_, outputs);
265 delegate_->UngrabServer(); 269 delegate_->UngrabServer();
266 270
267 if (success) { 271 if (success) {
268 NotifyOnDisplayChanged(); 272 NotifyOnDisplayChanged();
269 } else { 273 } else {
270 FOR_EACH_OBSERVER( 274 FOR_EACH_OBSERVER(
271 Observer, observers_, OnDisplayModeChangeFailed(new_state)); 275 Observer, observers_, OnDisplayModeChangeFailed(new_state));
272 } 276 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 delegate_->SyncWithServer(); 348 delegate_->SyncWithServer();
345 } 349 }
346 } 350 }
347 351
348 void OutputConfigurator::ResumeDisplays() { 352 void OutputConfigurator::ResumeDisplays() {
349 // Force probing to ensure that we pick up any changes that were made 353 // Force probing to ensure that we pick up any changes that were made
350 // while the system was suspended. 354 // while the system was suspended.
351 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe); 355 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe);
352 } 356 }
353 357
358 void OutputConfigurator::ScheduleConfigureOutputs() {
359 if (configure_timer_.get()) {
360 configure_timer_->Reset();
361 } else {
362 configure_timer_.reset(new base::OneShotTimer<OutputConfigurator>());
363 configure_timer_->Start(
364 FROM_HERE,
365 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
366 this,
367 &OutputConfigurator::ConfigureOutputs);
368 }
369 }
370
354 void OutputConfigurator::ConfigureOutputs() { 371 void OutputConfigurator::ConfigureOutputs() {
355 configure_timer_.reset(); 372 configure_timer_.reset();
356 373
357 delegate_->GrabServer(); 374 delegate_->GrabServer();
358 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 375 std::vector<OutputSnapshot> outputs =
376 delegate_->GetOutputs(state_controller_);
359 OutputState new_state = GetOutputState(outputs, power_state_); 377 OutputState new_state = GetOutputState(outputs, power_state_);
360 bool success = EnterStateOrFallBackToSoftwareMirroring( 378 bool success = EnterStateOrFallBackToSoftwareMirroring(
361 new_state, power_state_, outputs); 379 new_state, power_state_, outputs);
362 delegate_->UngrabServer(); 380 delegate_->UngrabServer();
363 381
364 if (success) { 382 if (success) {
365 NotifyOnDisplayChanged(); 383 NotifyOnDisplayChanged();
366 } else { 384 } else {
367 FOR_EACH_OBSERVER( 385 FOR_EACH_OBSERVER(
368 Observer, observers_, OnDisplayModeChangeFailed(new_state)); 386 Observer, observers_, OnDisplayModeChangeFailed(new_state));
369 } 387 }
370 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs)); 388 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs));
371 } 389 }
372 390
373 void OutputConfigurator::ScheduleConfigureOutputs() {
374 if (configure_timer_.get()) {
375 configure_timer_->Reset();
376 } else {
377 configure_timer_.reset(new base::OneShotTimer<OutputConfigurator>());
378 configure_timer_->Start(
379 FROM_HERE,
380 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
381 this,
382 &OutputConfigurator::ConfigureOutputs);
383 }
384 }
385
386 void OutputConfigurator::NotifyOnDisplayChanged() { 391 void OutputConfigurator::NotifyOnDisplayChanged() {
387 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); 392 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged());
388 } 393 }
389 394
390 bool OutputConfigurator::EnterStateOrFallBackToSoftwareMirroring( 395 bool OutputConfigurator::EnterStateOrFallBackToSoftwareMirroring(
391 OutputState output_state, 396 OutputState output_state,
392 DisplayPowerState power_state, 397 DisplayPowerState power_state,
393 const std::vector<OutputSnapshot>& outputs) { 398 const std::vector<OutputSnapshot>& outputs) {
394 bool success = EnterState(output_state, power_state, outputs); 399 bool success = EnterState(output_state, power_state, outputs);
395 if (mirroring_controller_) { 400 if (mirroring_controller_) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 LOG(WARNING) << "Ignoring request to enter single mode with " 432 LOG(WARNING) << "Ignoring request to enter single mode with "
428 << outputs.size() << " connected outputs and " 433 << outputs.size() << " connected outputs and "
429 << num_on_outputs << " turned on"; 434 << num_on_outputs << " turned on";
430 return false; 435 return false;
431 } 436 }
432 437
433 // Determine which output to use. 438 // Determine which output to use.
434 const OutputSnapshot& output = outputs.size() == 1 ? outputs[0] : 439 const OutputSnapshot& output = outputs.size() == 1 ? outputs[0] :
435 (output_power[0] ? outputs[0] : outputs[1]); 440 (output_power[0] ? outputs[0] : outputs[1]);
436 int width = 0, height = 0; 441 int width = 0, height = 0;
437 if (!delegate_->GetModeDetails(output.native_mode, &width, &height, NULL)) 442 if (!delegate_->GetModeDetails(
443 output.selected_mode, &width, &height, NULL))
438 return false; 444 return false;
439 445
440 std::vector<CrtcConfig> configs(outputs.size()); 446 std::vector<CrtcConfig> configs(outputs.size());
441 for (size_t i = 0; i < outputs.size(); ++i) { 447 for (size_t i = 0; i < outputs.size(); ++i) {
442 configs[i] = CrtcConfig( 448 configs[i] = CrtcConfig(
443 outputs[i].crtc, 0, 0, 449 outputs[i].crtc, 0, 0,
444 output_power[i] ? outputs[i].native_mode : None, 450 output_power[i] ? outputs[i].selected_mode : None,
445 outputs[i].output); 451 outputs[i].output);
446 } 452 }
447 delegate_->CreateFrameBuffer(width, height, configs); 453 delegate_->CreateFrameBuffer(width, height, configs);
448 454
449 for (size_t i = 0; i < outputs.size(); ++i) { 455 for (size_t i = 0; i < outputs.size(); ++i) {
450 delegate_->ConfigureCrtc(&configs[i]); 456 delegate_->ConfigureCrtc(&configs[i]);
451 if (outputs[i].touch_device_id) { 457 if (outputs[i].touch_device_id) {
452 delegate_->ConfigureCTM(outputs[i].touch_device_id, 458 delegate_->ConfigureCTM(outputs[i].touch_device_id,
453 CoordinateTransformation()); 459 CoordinateTransformation());
454 } 460 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 << num_on_outputs << " turned on"; 508 << num_on_outputs << " turned on";
503 return false; 509 return false;
504 } 510 }
505 511
506 // Pairs are [width, height] corresponding to the given output's mode. 512 // Pairs are [width, height] corresponding to the given output's mode.
507 std::vector<std::pair<int, int> > mode_sizes(outputs.size()); 513 std::vector<std::pair<int, int> > mode_sizes(outputs.size());
508 std::vector<CrtcConfig> configs(outputs.size()); 514 std::vector<CrtcConfig> configs(outputs.size());
509 int width = 0, height = 0; 515 int width = 0, height = 0;
510 516
511 for (size_t i = 0; i < outputs.size(); ++i) { 517 for (size_t i = 0; i < outputs.size(); ++i) {
512 if (!delegate_->GetModeDetails(outputs[i].native_mode, 518 if (!delegate_->GetModeDetails(outputs[i].selected_mode,
513 &(mode_sizes[i].first), &(mode_sizes[i].second), NULL)) { 519 &(mode_sizes[i].first), &(mode_sizes[i].second), NULL)) {
514 return false; 520 return false;
515 } 521 }
516 522
517 configs[i] = CrtcConfig( 523 configs[i] = CrtcConfig(
518 outputs[i].crtc, 0, (height ? height + kVerticalGap : 0), 524 outputs[i].crtc, 0, (height ? height + kVerticalGap : 0),
519 output_power[i] ? outputs[i].native_mode : None, 525 output_power[i] ? outputs[i].selected_mode : None,
520 outputs[i].output); 526 outputs[i].output);
521 527
522 // Retain the full screen size even if all outputs are off so the 528 // Retain the full screen size even if all outputs are off so the
523 // same desktop configuration can be restored when the outputs are 529 // same desktop configuration can be restored when the outputs are
524 // turned back on. 530 // turned back on.
525 width = std::max<int>(width, mode_sizes[i].first); 531 width = std::max<int>(width, mode_sizes[i].first);
526 height += (height ? kVerticalGap : 0) + mode_sizes[i].second; 532 height += (height ? kVerticalGap : 0) + mode_sizes[i].second;
527 } 533 }
528 534
529 delegate_->CreateFrameBuffer(width, height, configs); 535 delegate_->CreateFrameBuffer(width, height, configs);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 float width_ratio = static_cast<float>(mirror_mode_width) / 648 float width_ratio = static_cast<float>(mirror_mode_width) /
643 static_cast<float>(native_mode_width); 649 static_cast<float>(native_mode_width);
644 float height_ratio = static_cast<float>(mirror_mode_height) / 650 float height_ratio = static_cast<float>(mirror_mode_height) /
645 static_cast<float>(native_mode_height); 651 static_cast<float>(native_mode_height);
646 652
647 area_ratio = width_ratio * height_ratio; 653 area_ratio = width_ratio * height_ratio;
648 return area_ratio; 654 return area_ratio;
649 } 655 }
650 656
651 } // namespace chromeos 657 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/display/output_configurator.h ('k') | chromeos/display/output_configurator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698