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

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

Powered by Google App Engine
This is Rietveld 408576698