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

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

Issue 22871010: chromeos: Include mode details in OutputSnapshot. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add out-of-line dtor for OutputSnapshot 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 for (size_t i = 0; i < outputs.size(); ++i) 91 for (size_t i = 0; i < outputs.size(); ++i)
92 has_internal_output |= outputs[i].is_internal; 92 has_internal_output |= outputs[i].is_internal;
93 93
94 // "Projecting" is defined as having more than 1 output connected while at 94 // "Projecting" is defined as having more than 1 output connected while at
95 // least one of them is an internal output. 95 // least one of them is an internal output.
96 return has_internal_output && (connected_output_count > 1); 96 return has_internal_output && (connected_output_count > 1);
97 } 97 }
98 98
99 } // namespace 99 } // namespace
100 100
101 OutputConfigurator::ModeInfo::ModeInfo()
102 : width(0),
103 height(0),
104 interlaced(false) {}
105
101 OutputConfigurator::CoordinateTransformation::CoordinateTransformation() 106 OutputConfigurator::CoordinateTransformation::CoordinateTransformation()
102 : x_scale(1.0), 107 : x_scale(1.0),
103 x_offset(0.0), 108 x_offset(0.0),
104 y_scale(1.0), 109 y_scale(1.0),
105 y_offset(0.0) {} 110 y_offset(0.0) {}
106 111
107 OutputConfigurator::OutputSnapshot::OutputSnapshot() 112 OutputConfigurator::OutputSnapshot::OutputSnapshot()
108 : output(None), 113 : output(None),
109 crtc(None), 114 crtc(None),
110 current_mode(None), 115 current_mode(None),
111 native_mode(None), 116 native_mode(None),
112 mirror_mode(None), 117 mirror_mode(None),
113 selected_mode(None), 118 selected_mode(None),
114 x(0), 119 x(0),
115 y(0), 120 y(0),
121 width_mm(0),
122 height_mm(0),
116 is_internal(false), 123 is_internal(false),
117 is_aspect_preserving_scaling(false), 124 is_aspect_preserving_scaling(false),
118 touch_device_id(0), 125 touch_device_id(0),
119 display_id(0), 126 display_id(0),
120 has_display_id(false) {} 127 has_display_id(false) {}
121 128
129 OutputConfigurator::OutputSnapshot::~OutputSnapshot() {}
130
122 void OutputConfigurator::TestApi::SendScreenChangeEvent() { 131 void OutputConfigurator::TestApi::SendScreenChangeEvent() {
123 XRRScreenChangeNotifyEvent event = {0}; 132 XRRScreenChangeNotifyEvent event = {0};
124 event.type = xrandr_event_base_ + RRScreenChangeNotify; 133 event.type = xrandr_event_base_ + RRScreenChangeNotify;
125 configurator_->Dispatch(reinterpret_cast<const base::NativeEvent>(&event)); 134 configurator_->Dispatch(reinterpret_cast<const base::NativeEvent>(&event));
126 } 135 }
127 136
128 void OutputConfigurator::TestApi::SendOutputChangeEvent(RROutput output, 137 void OutputConfigurator::TestApi::SendOutputChangeEvent(RROutput output,
129 RRCrtc crtc, 138 RRCrtc crtc,
130 RRMode mode, 139 RRMode mode,
131 bool connected) { 140 bool connected) {
(...skipping 11 matching lines...) Expand all
143 if (configurator_->configure_timer_.get() && 152 if (configurator_->configure_timer_.get() &&
144 configurator_->configure_timer_->IsRunning()) { 153 configurator_->configure_timer_->IsRunning()) {
145 configurator_->configure_timer_.reset(); 154 configurator_->configure_timer_.reset();
146 configurator_->ConfigureOutputs(); 155 configurator_->ConfigureOutputs();
147 return true; 156 return true;
148 } else { 157 } else {
149 return false; 158 return false;
150 } 159 }
151 } 160 }
152 161
162 // static
163 const OutputConfigurator::ModeInfo* OutputConfigurator::GetModeInfo(
164 const OutputSnapshot& output,
165 RRMode mode) {
166 std::map<RRMode, ModeInfo>::const_iterator it = output.mode_infos.find(mode);
167 if (it == output.mode_infos.end()) {
168 LOG(WARNING) << "Unable to find info about mode " << mode
169 << " for output " << output.output;
170 return NULL;
171 }
172 return &it->second;
173 }
174
153 OutputConfigurator::OutputConfigurator() 175 OutputConfigurator::OutputConfigurator()
154 : state_controller_(NULL), 176 : state_controller_(NULL),
155 mirroring_controller_(NULL), 177 mirroring_controller_(NULL),
156 configure_display_(base::chromeos::IsRunningOnChromeOS()), 178 configure_display_(base::chromeos::IsRunningOnChromeOS()),
157 xrandr_event_base_(0), 179 xrandr_event_base_(0),
158 output_state_(STATE_INVALID), 180 output_state_(STATE_INVALID),
159 power_state_(DISPLAY_POWER_ALL_ON) { 181 power_state_(DISPLAY_POWER_ALL_ON) {
160 } 182 }
161 183
162 OutputConfigurator::~OutputConfigurator() {} 184 OutputConfigurator::~OutputConfigurator() {}
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 if (success) { 420 if (success) {
399 NotifyOnDisplayChanged(); 421 NotifyOnDisplayChanged();
400 } else { 422 } else {
401 FOR_EACH_OBSERVER( 423 FOR_EACH_OBSERVER(
402 Observer, observers_, OnDisplayModeChangeFailed(new_state)); 424 Observer, observers_, OnDisplayModeChangeFailed(new_state));
403 } 425 }
404 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs)); 426 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs));
405 } 427 }
406 428
407 void OutputConfigurator::NotifyOnDisplayChanged() { 429 void OutputConfigurator::NotifyOnDisplayChanged() {
408 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); 430 FOR_EACH_OBSERVER(Observer, observers_,
431 OnDisplayModeChanged(cached_outputs_));
409 } 432 }
410 433
411 bool OutputConfigurator::EnterStateOrFallBackToSoftwareMirroring( 434 bool OutputConfigurator::EnterStateOrFallBackToSoftwareMirroring(
412 OutputState output_state, 435 OutputState output_state,
413 DisplayPowerState power_state, 436 DisplayPowerState power_state,
414 const std::vector<OutputSnapshot>& outputs) { 437 const std::vector<OutputSnapshot>& outputs) {
415 bool success = EnterState(output_state, power_state, outputs); 438 bool success = EnterState(output_state, power_state, outputs);
416 if (mirroring_controller_) { 439 if (mirroring_controller_) {
417 bool enable_software_mirroring = false; 440 bool enable_software_mirroring = false;
418 if (!success && output_state == STATE_DUAL_MIRROR) { 441 if (!success && output_state == STATE_DUAL_MIRROR) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 return false; 483 return false;
461 } 484 }
462 485
463 for (size_t i = 0; i < updated_outputs.size(); ++i) { 486 for (size_t i = 0; i < updated_outputs.size(); ++i) {
464 OutputSnapshot* output = &updated_outputs[i]; 487 OutputSnapshot* output = &updated_outputs[i];
465 output->x = 0; 488 output->x = 0;
466 output->y = 0; 489 output->y = 0;
467 output->current_mode = output_power[i] ? output->selected_mode : None; 490 output->current_mode = output_power[i] ? output->selected_mode : None;
468 491
469 if (output_power[i] || outputs.size() == 1) { 492 if (output_power[i] || outputs.size() == 1) {
470 if (!delegate_->GetModeDetails( 493 const ModeInfo* mode_info =
471 output->selected_mode, &width, &height, NULL)) 494 GetModeInfo(*output, output->selected_mode);
495 if (!mode_info)
472 return false; 496 return false;
497 width = mode_info->width;
498 height = mode_info->height;
473 } 499 }
474 } 500 }
475 break; 501 break;
476 } 502 }
477 case STATE_DUAL_MIRROR: { 503 case STATE_DUAL_MIRROR: {
478 if (outputs.size() != 2 || (num_on_outputs != 0 && num_on_outputs != 2)) { 504 if (outputs.size() != 2 || (num_on_outputs != 0 && num_on_outputs != 2)) {
479 LOG(WARNING) << "Ignoring request to enter mirrored mode with " 505 LOG(WARNING) << "Ignoring request to enter mirrored mode with "
480 << outputs.size() << " connected output(s) and " 506 << outputs.size() << " connected output(s) and "
481 << num_on_outputs << " turned on"; 507 << num_on_outputs << " turned on";
482 return false; 508 return false;
483 } 509 }
484 510
485 if (!delegate_->GetModeDetails( 511 if (!outputs[0].mirror_mode)
486 outputs[0].mirror_mode, &width, &height, NULL))
487 return false; 512 return false;
513 const ModeInfo* mode_info =
514 GetModeInfo(outputs[0], outputs[0].mirror_mode);
515 if (!mode_info)
516 return false;
517 width = mode_info->width;
518 height = mode_info->height;
488 519
489 for (size_t i = 0; i < outputs.size(); ++i) { 520 for (size_t i = 0; i < outputs.size(); ++i) {
490 OutputSnapshot* output = &updated_outputs[i]; 521 OutputSnapshot* output = &updated_outputs[i];
491 output->x = 0; 522 output->x = 0;
492 output->y = 0; 523 output->y = 0;
493 output->current_mode = output_power[i] ? output->mirror_mode : None; 524 output->current_mode = output_power[i] ? output->mirror_mode : None;
494 if (output->touch_device_id) { 525 if (output->touch_device_id) {
495 // CTM needs to be calculated if aspect preserving scaling is used. 526 // CTM needs to be calculated if aspect preserving scaling is used.
496 // Otherwise, assume it is full screen, and use identity CTM. 527 // Otherwise, assume it is full screen, and use identity CTM.
497 if (output->mirror_mode != output->native_mode && 528 if (output->mirror_mode != output->native_mode &&
498 output->is_aspect_preserving_scaling) { 529 output->is_aspect_preserving_scaling) {
499 output->transform = GetMirrorModeCTM(output); 530 output->transform = GetMirrorModeCTM(*output);
500 mirrored_display_area_ratio_map_[output->touch_device_id] = 531 mirrored_display_area_ratio_map_[output->touch_device_id] =
501 GetMirroredDisplayAreaRatio(output); 532 GetMirroredDisplayAreaRatio(*output);
502 } 533 }
503 } 534 }
504 } 535 }
505 break; 536 break;
506 } 537 }
507 case STATE_DUAL_EXTENDED: { 538 case STATE_DUAL_EXTENDED: {
508 if (outputs.size() != 2 || (num_on_outputs != 0 && num_on_outputs != 2)) { 539 if (outputs.size() != 2 || (num_on_outputs != 0 && num_on_outputs != 2)) {
509 LOG(WARNING) << "Ignoring request to enter extended mode with " 540 LOG(WARNING) << "Ignoring request to enter extended mode with "
510 << outputs.size() << " connected output(s) and " 541 << outputs.size() << " connected output(s) and "
511 << num_on_outputs << " turned on"; 542 << num_on_outputs << " turned on";
512 return false; 543 return false;
513 } 544 }
514 545
515 // Pairs are [width, height] corresponding to the given output's mode.
516 std::vector<std::pair<int, int> > mode_sizes(outputs.size());
517
518 for (size_t i = 0; i < outputs.size(); ++i) { 546 for (size_t i = 0; i < outputs.size(); ++i) {
519 if (!delegate_->GetModeDetails(outputs[i].selected_mode,
520 &(mode_sizes[i].first), &(mode_sizes[i].second), NULL)) {
521 return false;
522 }
523
524 OutputSnapshot* output = &updated_outputs[i]; 547 OutputSnapshot* output = &updated_outputs[i];
525 output->x = 0; 548 output->x = 0;
526 output->y = height ? height + kVerticalGap : 0; 549 output->y = height ? height + kVerticalGap : 0;
527 output->current_mode = output_power[i] ? output->selected_mode : None; 550 output->current_mode = output_power[i] ? output->selected_mode : None;
528 551
529 // Retain the full screen size even if all outputs are off so the 552 // Retain the full screen size even if all outputs are off so the
530 // same desktop configuration can be restored when the outputs are 553 // same desktop configuration can be restored when the outputs are
531 // turned back on. 554 // turned back on.
532 width = std::max<int>(width, mode_sizes[i].first); 555 const ModeInfo* mode_info =
533 height += (height ? kVerticalGap : 0) + mode_sizes[i].second; 556 GetModeInfo(outputs[i], outputs[i].selected_mode);
557 if (!mode_info)
558 return false;
559 width = std::max<int>(width, mode_info->width);
560 height += (height ? kVerticalGap : 0) + mode_info->height;
534 } 561 }
535 562
536 for (size_t i = 0; i < outputs.size(); ++i) { 563 for (size_t i = 0; i < outputs.size(); ++i) {
537 OutputSnapshot* output = &updated_outputs[i]; 564 OutputSnapshot* output = &updated_outputs[i];
538 if (output->touch_device_id) { 565 if (output->touch_device_id) {
566 const ModeInfo* mode_info =
567 GetModeInfo(*output, output->selected_mode);
568 DCHECK(mode_info);
539 CoordinateTransformation* ctm = &(output->transform); 569 CoordinateTransformation* ctm = &(output->transform);
540 ctm->x_scale = static_cast<float>(mode_sizes[i].first) / width; 570 ctm->x_scale = static_cast<float>(mode_info->width) / width;
541 ctm->x_offset = static_cast<float>(output->x) / width; 571 ctm->x_offset = static_cast<float>(output->x) / width;
542 ctm->y_scale = static_cast<float>(mode_sizes[i].second) / height; 572 ctm->y_scale = static_cast<float>(mode_info->height) / height;
543 ctm->y_offset = static_cast<float>(output->y) / height; 573 ctm->y_offset = static_cast<float>(output->y) / height;
544 } 574 }
545 } 575 }
546 break; 576 break;
547 } 577 }
548 } 578 }
549 579
550 // Finally, apply the desired changes. 580 // Finally, apply the desired changes.
551 DCHECK_EQ(outputs.size(), updated_outputs.size()); 581 DCHECK_EQ(outputs.size(), updated_outputs.size());
552 if (!outputs.empty()) { 582 if (!outputs.empty()) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } 632 }
603 } 633 }
604 default: 634 default:
605 NOTREACHED(); 635 NOTREACHED();
606 } 636 }
607 return STATE_INVALID; 637 return STATE_INVALID;
608 } 638 }
609 639
610 OutputConfigurator::CoordinateTransformation 640 OutputConfigurator::CoordinateTransformation
611 OutputConfigurator::GetMirrorModeCTM( 641 OutputConfigurator::GetMirrorModeCTM(
612 const OutputConfigurator::OutputSnapshot* output) { 642 const OutputConfigurator::OutputSnapshot& output) {
613 CoordinateTransformation ctm; // Default to identity 643 CoordinateTransformation ctm; // Default to identity
614 int native_mode_width = 0, native_mode_height = 0; 644 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode);
615 int mirror_mode_width = 0, mirror_mode_height = 0; 645 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode);
616 if (!delegate_->GetModeDetails(output->native_mode, 646
617 &native_mode_width, &native_mode_height, NULL) || 647 if (!native_mode_info || !mirror_mode_info ||
618 !delegate_->GetModeDetails(output->mirror_mode, 648 native_mode_info->height == 0 || mirror_mode_info->height == 0 ||
619 &mirror_mode_width, &mirror_mode_height, NULL)) 649 native_mode_info->width == 0 || mirror_mode_info->width == 0)
620 return ctm; 650 return ctm;
621 651
622 if (native_mode_height == 0 || mirror_mode_height == 0 || 652 float native_mode_ar = static_cast<float>(native_mode_info->width) /
623 native_mode_width == 0 || mirror_mode_width == 0) 653 static_cast<float>(native_mode_info->height);
624 return ctm; 654 float mirror_mode_ar = static_cast<float>(mirror_mode_info->width) /
625 655 static_cast<float>(mirror_mode_info->height);
626 float native_mode_ar = static_cast<float>(native_mode_width) /
627 static_cast<float>(native_mode_height);
628 float mirror_mode_ar = static_cast<float>(mirror_mode_width) /
629 static_cast<float>(mirror_mode_height);
630 656
631 if (mirror_mode_ar > native_mode_ar) { // Letterboxing 657 if (mirror_mode_ar > native_mode_ar) { // Letterboxing
632 ctm.x_scale = 1.0; 658 ctm.x_scale = 1.0;
633 ctm.x_offset = 0.0; 659 ctm.x_offset = 0.0;
634 ctm.y_scale = mirror_mode_ar / native_mode_ar; 660 ctm.y_scale = mirror_mode_ar / native_mode_ar;
635 ctm.y_offset = (native_mode_ar / mirror_mode_ar - 1.0) * 0.5; 661 ctm.y_offset = (native_mode_ar / mirror_mode_ar - 1.0) * 0.5;
636 return ctm; 662 return ctm;
637 } 663 }
638 if (native_mode_ar > mirror_mode_ar) { // Pillarboxing 664 if (native_mode_ar > mirror_mode_ar) { // Pillarboxing
639 ctm.y_scale = 1.0; 665 ctm.y_scale = 1.0;
640 ctm.y_offset = 0.0; 666 ctm.y_offset = 0.0;
641 ctm.x_scale = native_mode_ar / mirror_mode_ar; 667 ctm.x_scale = native_mode_ar / mirror_mode_ar;
642 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5; 668 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5;
643 return ctm; 669 return ctm;
644 } 670 }
645 671
646 return ctm; // Same aspect ratio - return identity 672 return ctm; // Same aspect ratio - return identity
647 } 673 }
648 674
649 float OutputConfigurator::GetMirroredDisplayAreaRatio( 675 float OutputConfigurator::GetMirroredDisplayAreaRatio(
650 const OutputConfigurator::OutputSnapshot* output) { 676 const OutputConfigurator::OutputSnapshot& output) {
651 float area_ratio = 1.0f; 677 float area_ratio = 1.0f;
652 int native_mode_width = 0, native_mode_height = 0; 678 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode);
653 int mirror_mode_width = 0, mirror_mode_height = 0; 679 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode);
654 if (!delegate_->GetModeDetails(output->native_mode, 680
655 &native_mode_width, &native_mode_height, NULL) || 681 if (!native_mode_info || !mirror_mode_info ||
656 !delegate_->GetModeDetails(output->mirror_mode, 682 native_mode_info->height == 0 || mirror_mode_info->height == 0 ||
657 &mirror_mode_width, &mirror_mode_height, NULL)) 683 native_mode_info->width == 0 || mirror_mode_info->width == 0)
658 return area_ratio; 684 return area_ratio;
659 685
660 if (native_mode_height == 0 || mirror_mode_height == 0 || 686 float width_ratio = static_cast<float>(mirror_mode_info->width) /
661 native_mode_width == 0 || mirror_mode_width == 0) 687 static_cast<float>(native_mode_info->width);
662 return area_ratio; 688 float height_ratio = static_cast<float>(mirror_mode_info->height) /
663 689 static_cast<float>(native_mode_info->height);
664 float width_ratio = static_cast<float>(mirror_mode_width) /
665 static_cast<float>(native_mode_width);
666 float height_ratio = static_cast<float>(mirror_mode_height) /
667 static_cast<float>(native_mode_height);
668 690
669 area_ratio = width_ratio * height_ratio; 691 area_ratio = width_ratio * height_ratio;
670 return area_ratio; 692 return area_ratio;
671 } 693 }
672 694
673 } // namespace chromeos 695 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698