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

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: 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 uint32 background_color_argb) { 186 uint32 background_color_argb) {
186 if (!configure_display_) 187 if (!configure_display_)
187 return; 188 return;
188 189
189 if (!delegate_) 190 if (!delegate_)
190 delegate_.reset(new RealOutputConfiguratorDelegate()); 191 delegate_.reset(new RealOutputConfiguratorDelegate());
191 192
192 // Cache the initial output state. 193 // Cache the initial output state.
193 delegate_->SetPanelFittingEnabled(is_panel_fitting_enabled); 194 delegate_->SetPanelFittingEnabled(is_panel_fitting_enabled);
194 delegate_->GrabServer(); 195 delegate_->GrabServer();
195 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 196 std::vector<OutputSnapshot> outputs =
197 delegate_->GetOutputs(state_controller_);
196 if (outputs.size() > 1 && background_color_argb) 198 if (outputs.size() > 1 && background_color_argb)
197 delegate_->SetBackgroundColor(background_color_argb); 199 delegate_->SetBackgroundColor(background_color_argb);
198 delegate_->UngrabServer(); 200 delegate_->UngrabServer();
199 } 201 }
200 202
201 void OutputConfigurator::Start() { 203 void OutputConfigurator::Start() {
202 if (!configure_display_) 204 if (!configure_display_)
203 return; 205 return;
204 206
205 delegate_->GrabServer(); 207 delegate_->GrabServer();
206 delegate_->InitXRandRExtension(&xrandr_event_base_); 208 delegate_->InitXRandRExtension(&xrandr_event_base_);
207 209
208 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 210 std::vector<OutputSnapshot> outputs =
211 delegate_->GetOutputs(state_controller_);
209 EnterStateOrFallBackToSoftwareMirroring( 212 EnterStateOrFallBackToSoftwareMirroring(
210 GetOutputState(outputs, power_state_), power_state_, outputs); 213 GetOutputState(outputs, power_state_), power_state_, outputs);
211 214
212 // Force the DPMS on chrome startup as the driver doesn't always detect 215 // Force the DPMS on chrome startup as the driver doesn't always detect
213 // that all displays are on when signing out. 216 // that all displays are on when signing out.
214 delegate_->ForceDPMSOn(); 217 delegate_->ForceDPMSOn();
215 delegate_->UngrabServer(); 218 delegate_->UngrabServer();
216 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs)); 219 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs));
217 } 220 }
218 221
219 void OutputConfigurator::Stop() { 222 void OutputConfigurator::Stop() {
220 configure_display_ = false; 223 configure_display_ = false;
221 } 224 }
222 225
223 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, 226 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state,
224 int flags) { 227 int flags) {
225 if (!configure_display_) 228 if (!configure_display_)
226 return false; 229 return false;
227 230
228 VLOG(1) << "SetDisplayPower: power_state=" 231 VLOG(1) << "SetDisplayPower: power_state="
229 << DisplayPowerStateToString(power_state) << " flags=" << flags; 232 << DisplayPowerStateToString(power_state) << " flags=" << flags;
230 if (power_state == power_state_ && !(flags & kSetDisplayPowerForceProbe)) 233 if (power_state == power_state_ && !(flags & kSetDisplayPowerForceProbe))
231 return true; 234 return true;
232 235
233 delegate_->GrabServer(); 236 delegate_->GrabServer();
234 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 237 std::vector<OutputSnapshot> outputs =
238 delegate_->GetOutputs(state_controller_);
235 239
236 bool only_if_single_internal_display = 240 bool only_if_single_internal_display =
237 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay; 241 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay;
238 bool single_internal_display = outputs.size() == 1 && outputs[0].is_internal; 242 bool single_internal_display = outputs.size() == 1 && outputs[0].is_internal;
239 if ((single_internal_display || !only_if_single_internal_display) && 243 if ((single_internal_display || !only_if_single_internal_display) &&
240 EnterStateOrFallBackToSoftwareMirroring( 244 EnterStateOrFallBackToSoftwareMirroring(
241 GetOutputState(outputs, power_state), power_state, outputs)) { 245 GetOutputState(outputs, power_state), power_state, outputs)) {
242 if (power_state != DISPLAY_POWER_ALL_OFF) { 246 if (power_state != DISPLAY_POWER_ALL_OFF) {
243 // Force the DPMS on since the driver doesn't always detect that it 247 // Force the DPMS on since the driver doesn't always detect that it
244 // should turn on. This is needed when coming back from idle suspend. 248 // should turn on. This is needed when coming back from idle suspend.
(...skipping 13 matching lines...) Expand all
258 if (output_state_ == new_state) { 262 if (output_state_ == new_state) {
259 // Cancel software mirroring if the state is moving from 263 // Cancel software mirroring if the state is moving from
260 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED. 264 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED.
261 if (mirroring_controller_ && new_state == STATE_DUAL_EXTENDED) 265 if (mirroring_controller_ && new_state == STATE_DUAL_EXTENDED)
262 mirroring_controller_->SetSoftwareMirroring(false); 266 mirroring_controller_->SetSoftwareMirroring(false);
263 NotifyOnDisplayChanged(); 267 NotifyOnDisplayChanged();
264 return true; 268 return true;
265 } 269 }
266 270
267 delegate_->GrabServer(); 271 delegate_->GrabServer();
268 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 272 std::vector<OutputSnapshot> outputs =
273 delegate_->GetOutputs(state_controller_);
269 bool success = EnterStateOrFallBackToSoftwareMirroring( 274 bool success = EnterStateOrFallBackToSoftwareMirroring(
270 new_state, power_state_, outputs); 275 new_state, power_state_, outputs);
271 delegate_->UngrabServer(); 276 delegate_->UngrabServer();
272 277
273 if (success) { 278 if (success) {
274 NotifyOnDisplayChanged(); 279 NotifyOnDisplayChanged();
275 } else { 280 } else {
276 FOR_EACH_OBSERVER( 281 FOR_EACH_OBSERVER(
277 Observer, observers_, OnDisplayModeChangeFailed(new_state)); 282 Observer, observers_, OnDisplayModeChangeFailed(new_state));
278 } 283 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 delegate_->SyncWithServer(); 355 delegate_->SyncWithServer();
351 } 356 }
352 } 357 }
353 358
354 void OutputConfigurator::ResumeDisplays() { 359 void OutputConfigurator::ResumeDisplays() {
355 // Force probing to ensure that we pick up any changes that were made 360 // Force probing to ensure that we pick up any changes that were made
356 // while the system was suspended. 361 // while the system was suspended.
357 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe); 362 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe);
358 } 363 }
359 364
365 void OutputConfigurator::ScheduleConfigureOutputs() {
366 if (configure_timer_.get()) {
367 configure_timer_->Reset();
368 } else {
369 configure_timer_.reset(new base::OneShotTimer<OutputConfigurator>());
370 configure_timer_->Start(
371 FROM_HERE,
372 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
373 this,
374 &OutputConfigurator::ConfigureOutputs);
375 }
376 }
377
360 void OutputConfigurator::ConfigureOutputs() { 378 void OutputConfigurator::ConfigureOutputs() {
361 configure_timer_.reset(); 379 configure_timer_.reset();
362 380
363 delegate_->GrabServer(); 381 delegate_->GrabServer();
364 std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); 382 std::vector<OutputSnapshot> outputs =
383 delegate_->GetOutputs(state_controller_);
365 OutputState new_state = GetOutputState(outputs, power_state_); 384 OutputState new_state = GetOutputState(outputs, power_state_);
366 bool success = EnterStateOrFallBackToSoftwareMirroring( 385 bool success = EnterStateOrFallBackToSoftwareMirroring(
367 new_state, power_state_, outputs); 386 new_state, power_state_, outputs);
368 delegate_->UngrabServer(); 387 delegate_->UngrabServer();
369 388
370 if (success) { 389 if (success) {
371 NotifyOnDisplayChanged(); 390 NotifyOnDisplayChanged();
372 } else { 391 } else {
373 FOR_EACH_OBSERVER( 392 FOR_EACH_OBSERVER(
374 Observer, observers_, OnDisplayModeChangeFailed(new_state)); 393 Observer, observers_, OnDisplayModeChangeFailed(new_state));
375 } 394 }
376 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs)); 395 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs));
377 } 396 }
378 397
379 void OutputConfigurator::ScheduleConfigureOutputs() {
380 if (configure_timer_.get()) {
381 configure_timer_->Reset();
382 } else {
383 configure_timer_.reset(new base::OneShotTimer<OutputConfigurator>());
384 configure_timer_->Start(
385 FROM_HERE,
386 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
387 this,
388 &OutputConfigurator::ConfigureOutputs);
389 }
390 }
391
392 void OutputConfigurator::NotifyOnDisplayChanged() { 398 void OutputConfigurator::NotifyOnDisplayChanged() {
393 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); 399 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged());
394 } 400 }
395 401
396 bool OutputConfigurator::EnterStateOrFallBackToSoftwareMirroring( 402 bool OutputConfigurator::EnterStateOrFallBackToSoftwareMirroring(
397 OutputState output_state, 403 OutputState output_state,
398 DisplayPowerState power_state, 404 DisplayPowerState power_state,
399 const std::vector<OutputSnapshot>& outputs) { 405 const std::vector<OutputSnapshot>& outputs) {
400 bool success = EnterState(output_state, power_state, outputs); 406 bool success = EnterState(output_state, power_state, outputs);
401 if (mirroring_controller_) { 407 if (mirroring_controller_) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 LOG(WARNING) << "Ignoring request to enter single mode with " 439 LOG(WARNING) << "Ignoring request to enter single mode with "
434 << outputs.size() << " connected outputs and " 440 << outputs.size() << " connected outputs and "
435 << num_on_outputs << " turned on"; 441 << num_on_outputs << " turned on";
436 return false; 442 return false;
437 } 443 }
438 444
439 // Determine which output to use. 445 // Determine which output to use.
440 const OutputSnapshot& output = outputs.size() == 1 ? outputs[0] : 446 const OutputSnapshot& output = outputs.size() == 1 ? outputs[0] :
441 (output_power[0] ? outputs[0] : outputs[1]); 447 (output_power[0] ? outputs[0] : outputs[1]);
442 int width = 0, height = 0; 448 int width = 0, height = 0;
443 if (!delegate_->GetModeDetails(output.native_mode, &width, &height, NULL)) 449 if (!delegate_->GetModeDetails(
450 output.selected_mode, &width, &height, NULL))
444 return false; 451 return false;
445 452
446 std::vector<CrtcConfig> configs(outputs.size()); 453 std::vector<CrtcConfig> configs(outputs.size());
447 for (size_t i = 0; i < outputs.size(); ++i) { 454 for (size_t i = 0; i < outputs.size(); ++i) {
448 configs[i] = CrtcConfig( 455 configs[i] = CrtcConfig(
449 outputs[i].crtc, 0, 0, 456 outputs[i].crtc, 0, 0,
450 output_power[i] ? outputs[i].native_mode : None, 457 output_power[i] ? outputs[i].selected_mode : None,
451 outputs[i].output); 458 outputs[i].output);
452 } 459 }
453 delegate_->CreateFrameBuffer(width, height, configs); 460 delegate_->CreateFrameBuffer(width, height, configs);
454 461
455 for (size_t i = 0; i < outputs.size(); ++i) { 462 for (size_t i = 0; i < outputs.size(); ++i) {
456 delegate_->ConfigureCrtc(&configs[i]); 463 delegate_->ConfigureCrtc(&configs[i]);
457 if (outputs[i].touch_device_id) { 464 if (outputs[i].touch_device_id) {
458 delegate_->ConfigureCTM(outputs[i].touch_device_id, 465 delegate_->ConfigureCTM(outputs[i].touch_device_id,
459 CoordinateTransformation()); 466 CoordinateTransformation());
460 } 467 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 << num_on_outputs << " turned on"; 515 << num_on_outputs << " turned on";
509 return false; 516 return false;
510 } 517 }
511 518
512 // Pairs are [width, height] corresponding to the given output's mode. 519 // Pairs are [width, height] corresponding to the given output's mode.
513 std::vector<std::pair<int, int> > mode_sizes(outputs.size()); 520 std::vector<std::pair<int, int> > mode_sizes(outputs.size());
514 std::vector<CrtcConfig> configs(outputs.size()); 521 std::vector<CrtcConfig> configs(outputs.size());
515 int width = 0, height = 0; 522 int width = 0, height = 0;
516 523
517 for (size_t i = 0; i < outputs.size(); ++i) { 524 for (size_t i = 0; i < outputs.size(); ++i) {
518 if (!delegate_->GetModeDetails(outputs[i].native_mode, 525 if (!delegate_->GetModeDetails(outputs[i].selected_mode,
519 &(mode_sizes[i].first), &(mode_sizes[i].second), NULL)) { 526 &(mode_sizes[i].first), &(mode_sizes[i].second), NULL)) {
520 return false; 527 return false;
521 } 528 }
522 529
523 configs[i] = CrtcConfig( 530 configs[i] = CrtcConfig(
524 outputs[i].crtc, 0, (height ? height + kVerticalGap : 0), 531 outputs[i].crtc, 0, (height ? height + kVerticalGap : 0),
525 output_power[i] ? outputs[i].native_mode : None, 532 output_power[i] ? outputs[i].selected_mode : None,
526 outputs[i].output); 533 outputs[i].output);
527 534
528 // Retain the full screen size even if all outputs are off so the 535 // Retain the full screen size even if all outputs are off so the
529 // same desktop configuration can be restored when the outputs are 536 // same desktop configuration can be restored when the outputs are
530 // turned back on. 537 // turned back on.
531 width = std::max<int>(width, mode_sizes[i].first); 538 width = std::max<int>(width, mode_sizes[i].first);
532 height += (height ? kVerticalGap : 0) + mode_sizes[i].second; 539 height += (height ? kVerticalGap : 0) + mode_sizes[i].second;
533 } 540 }
534 541
535 delegate_->CreateFrameBuffer(width, height, configs); 542 delegate_->CreateFrameBuffer(width, height, configs);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 float width_ratio = static_cast<float>(mirror_mode_width) / 655 float width_ratio = static_cast<float>(mirror_mode_width) /
649 static_cast<float>(native_mode_width); 656 static_cast<float>(native_mode_width);
650 float height_ratio = static_cast<float>(mirror_mode_height) / 657 float height_ratio = static_cast<float>(mirror_mode_height) /
651 static_cast<float>(native_mode_height); 658 static_cast<float>(native_mode_height);
652 659
653 area_ratio = width_ratio * height_ratio; 660 area_ratio = width_ratio * height_ratio;
654 return area_ratio; 661 return area_ratio;
655 } 662 }
656 663
657 } // namespace chromeos 664 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698