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

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

Issue 12391004: chromeos: Add DisplayPowerServiceProvider. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ugh, TrayDisplay was including output_configurator.h on windows Created 7 years, 9 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
« no previous file with comments | « chromeos/display/output_configurator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <cmath> 7 #include <cmath>
8 8
9 #include <X11/Xatom.h> 9 #include <X11/Xatom.h>
10 #include <X11/Xlib.h> 10 #include <X11/Xlib.h>
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 } // namespace 531 } // namespace
532 532
533 OutputConfigurator::OutputConfigurator() 533 OutputConfigurator::OutputConfigurator()
534 // If we aren't running on ChromeOS (like linux desktop), 534 // If we aren't running on ChromeOS (like linux desktop),
535 // don't try to configure display. 535 // don't try to configure display.
536 : configure_display_(base::chromeos::IsRunningOnChromeOS()), 536 : configure_display_(base::chromeos::IsRunningOnChromeOS()),
537 is_panel_fitting_enabled_(false), 537 is_panel_fitting_enabled_(false),
538 connected_output_count_(0), 538 connected_output_count_(0),
539 xrandr_event_base_(0), 539 xrandr_event_base_(0),
540 output_state_(STATE_INVALID), 540 output_state_(STATE_INVALID),
541 power_state_(DISPLAY_POWER_ALL_ON),
541 mirror_mode_will_preserve_aspect_(false), 542 mirror_mode_will_preserve_aspect_(false),
542 mirror_mode_preserved_aspect_(false), 543 mirror_mode_preserved_aspect_(false),
543 last_enter_state_time_() { 544 last_enter_state_time_() {
544 } 545 }
545 546
546 OutputConfigurator::~OutputConfigurator() { 547 OutputConfigurator::~OutputConfigurator() {
547 RecordPreviousStateUMA(); 548 RecordPreviousStateUMA();
548 } 549 }
549 550
550 void OutputConfigurator::Init(bool is_panel_fitting_enabled, 551 void OutputConfigurator::Init(bool is_panel_fitting_enabled,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 } 588 }
588 589
589 output_state_ = InferCurrentState(display, screen, outputs); 590 output_state_ = InferCurrentState(display, screen, outputs);
590 // Ensure that we are in a supported state with all connected displays powered 591 // Ensure that we are in a supported state with all connected displays powered
591 // on. 592 // on.
592 OutputState starting_state = GetNextState(display, 593 OutputState starting_state = GetNextState(display,
593 screen, 594 screen,
594 STATE_INVALID, 595 STATE_INVALID,
595 outputs); 596 outputs);
596 if (output_state_ != starting_state && 597 if (output_state_ != starting_state &&
597 EnterState(display, 598 EnterState(display, screen, window, starting_state, power_state_,
598 screen,
599 window,
600 starting_state,
601 outputs)) { 599 outputs)) {
602 output_state_ = starting_state; 600 output_state_ = starting_state;
603 } 601 }
604 bool is_projecting = IsProjecting(outputs); 602 bool is_projecting = IsProjecting(outputs);
605 603
606 // Find xrandr_event_base_ since we need it to interpret events, later. 604 // Find xrandr_event_base_ since we need it to interpret events, later.
607 int error_base_ignored = 0; 605 int error_base_ignored = 0;
608 XRRQueryExtension(display, &xrandr_event_base_, &error_base_ignored); 606 XRRQueryExtension(display, &xrandr_event_base_, &error_base_ignored);
609 607
610 // Force the DPMS on chrome startup as the driver doesn't always detect 608 // Force the DPMS on chrome startup as the driver doesn't always detect
(...skipping 25 matching lines...) Expand all
636 XGrabServer(display); 634 XGrabServer(display);
637 Window window = DefaultRootWindow(display); 635 Window window = DefaultRootWindow(display);
638 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window); 636 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window);
639 CHECK(screen != NULL); 637 CHECK(screen != NULL);
640 638
641 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); 639 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen);
642 connected_output_count_ = outputs.size(); 640 connected_output_count_ = outputs.size();
643 OutputState original = InferCurrentState(display, screen, outputs); 641 OutputState original = InferCurrentState(display, screen, outputs);
644 OutputState next_state = GetNextState(display, screen, original, outputs); 642 OutputState next_state = GetNextState(display, screen, original, outputs);
645 if (original != next_state && 643 if (original != next_state &&
646 EnterState(display, screen, window, next_state, outputs)) { 644 EnterState(display, screen, window, next_state, power_state_, outputs)) {
647 did_change = true; 645 did_change = true;
648 } 646 }
649 // We have seen cases where the XRandR data can get out of sync with our own 647 // We have seen cases where the XRandR data can get out of sync with our own
650 // cache so over-write it with whatever we detected, even if we didn't think 648 // cache so over-write it with whatever we detected, even if we didn't think
651 // anything changed. 649 // anything changed.
652 output_state_ = next_state; 650 output_state_ = next_state;
653 651
654 XRRFreeScreenResources(screen); 652 XRRFreeScreenResources(screen);
655 XUngrabServer(display); 653 XUngrabServer(display);
656 654
657 if (did_change) { 655 if (did_change) {
658 NotifyOnDisplayChanged(); 656 NotifyOnDisplayChanged();
659 } else { 657 } else {
660 FOR_EACH_OBSERVER( 658 FOR_EACH_OBSERVER(
661 Observer, observers_, OnDisplayModeChangeFailed(next_state)); 659 Observer, observers_, OnDisplayModeChangeFailed(next_state));
662 } 660 }
663 return did_change; 661 return did_change;
664 } 662 }
665 663
666 bool OutputConfigurator::ScreenPowerSet(bool power_on, bool all_displays) { 664 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state,
667 TRACE_EVENT0("chromeos", "OutputConfigurator::ScreenPowerSet"); 665 bool force_probe) {
668 VLOG(1) << "OutputConfigurator::SetScreensOn " << power_on 666 TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayPower");
669 << " all displays " << all_displays; 667 VLOG(1) << "OutputConfigurator::SetDisplayPower: power_state=" << power_state
668 << " force_probe=" << force_probe;
669
670 if (!configure_display_) 670 if (!configure_display_)
671 return false; 671 return false;
672 if (power_state == power_state_ && !force_probe)
673 return true;
672 674
673 bool success = false;
674 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); 675 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
675 CHECK(display != NULL); 676 CHECK(display);
676 XGrabServer(display); 677 XGrabServer(display);
677 Window window = DefaultRootWindow(display); 678 Window window = DefaultRootWindow(display);
678 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window); 679 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window);
679 CHECK(screen != NULL); 680 CHECK(screen);
680
681 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); 681 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen);
682 connected_output_count_ = outputs.size(); 682 connected_output_count_ = outputs.size();
683 683
684 if (all_displays && power_on) { 684 if (EnterState(display, screen, window, output_state_, power_state,
685 // Resume all displays using the current state. 685 outputs)) {
686 if (EnterState(display, screen, window, output_state_, outputs)) { 686 power_state_ = power_state;
687 // Force the DPMS on since the driver doesn't always detect that it should 687 if (power_state != DISPLAY_POWER_ALL_OFF) {
688 // turn on. This is needed when coming back from idle suspend. 688 // Force the DPMS on since the driver doesn't always detect that it
689 // should turn on. This is needed when coming back from idle suspend.
689 CHECK(DPMSEnable(display)); 690 CHECK(DPMSEnable(display));
690 CHECK(DPMSForceLevel(display, DPMSModeOn)); 691 CHECK(DPMSForceLevel(display, DPMSModeOn));
691
692 XRRFreeScreenResources(screen);
693 XUngrabServer(display);
694 return true;
695 } 692 }
696 } 693 }
697 694
698 CrtcConfig config;
699 config.crtc = None;
700 // Set the CRTCs based on whether we want to turn the power on or off and
701 // select the outputs to operate on by name or all_displays.
702 for (int i = 0; i < connected_output_count_; ++i) {
703 if (all_displays || outputs[i].is_internal || power_on) {
704 config.x = 0;
705 config.y = outputs[i].y;
706 config.output = outputs[i].output;
707 config.mode = None;
708 if (power_on) {
709 config.mode = (output_state_ == STATE_DUAL_MIRROR) ?
710 outputs[i].mirror_mode : outputs[i].native_mode;
711 } else if (connected_output_count_ > 1 && !all_displays &&
712 outputs[i].is_internal) {
713 // Workaround for crbug.com/148365: leave internal display in native
714 // mode so user can move cursor (and hence windows) onto internal
715 // display even when dimmed
716 config.mode = outputs[i].native_mode;
717 }
718 config.crtc = GetNextCrtcAfter(display, screen, config.output,
719 config.crtc);
720
721 ConfigureCrtc(display, screen, &config);
722 success = true;
723 }
724 }
725
726 // Force the DPMS on since the driver doesn't always detect that it should
727 // turn on. This is needed when coming back from idle suspend.
728 if (power_on) {
729 CHECK(DPMSEnable(display));
730 CHECK(DPMSForceLevel(display, DPMSModeOn));
731 }
732
733 XRRFreeScreenResources(screen); 695 XRRFreeScreenResources(screen);
734 XUngrabServer(display); 696 XUngrabServer(display);
735 697
736 return success; 698 return true;
737 } 699 }
738 700
739 bool OutputConfigurator::SetDisplayMode(OutputState new_state) { 701 bool OutputConfigurator::SetDisplayMode(OutputState new_state) {
740 TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayMode"); 702 TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayMode");
741 if (output_state_ == STATE_INVALID || 703 if (output_state_ == STATE_INVALID ||
742 output_state_ == STATE_HEADLESS || 704 output_state_ == STATE_HEADLESS ||
743 output_state_ == STATE_SINGLE) 705 output_state_ == STATE_SINGLE)
744 return false; 706 return false;
745 707
746 if (output_state_ == new_state) 708 if (output_state_ == new_state)
747 return true; 709 return true;
748 710
749 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); 711 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
750 CHECK(display != NULL); 712 CHECK(display != NULL);
751 XGrabServer(display); 713 XGrabServer(display);
752 Window window = DefaultRootWindow(display); 714 Window window = DefaultRootWindow(display);
753 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window); 715 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window);
754 CHECK(screen != NULL); 716 CHECK(screen != NULL);
755 717
756 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); 718 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen);
757 connected_output_count_ = outputs.size(); 719 connected_output_count_ = outputs.size();
758 if (EnterState(display, screen, window, new_state, outputs)) 720 if (EnterState(display, screen, window, new_state, power_state_, outputs))
759 output_state_ = new_state; 721 output_state_ = new_state;
760 722
761 XRRFreeScreenResources(screen); 723 XRRFreeScreenResources(screen);
762 XUngrabServer(display); 724 XUngrabServer(display);
763 725
764 if (output_state_ == new_state) { 726 if (output_state_ == new_state) {
765 NotifyOnDisplayChanged(); 727 NotifyOnDisplayChanged();
766 } else { 728 } else {
767 FOR_EACH_OBSERVER( 729 FOR_EACH_OBSERVER(
768 Observer, observers_, OnDisplayModeChangeFailed(new_state)); 730 Observer, observers_, OnDisplayModeChangeFailed(new_state));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); 784 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen);
823 int new_output_count = outputs.size(); 785 int new_output_count = outputs.size();
824 // Don't skip even if the output counts didn't change because 786 // Don't skip even if the output counts didn't change because
825 // a display might have been swapped during the suspend. 787 // a display might have been swapped during the suspend.
826 connected_output_count_ = new_output_count; 788 connected_output_count_ = new_output_count;
827 OutputState new_state = 789 OutputState new_state =
828 GetNextState(display, screen, STATE_INVALID, outputs); 790 GetNextState(display, screen, STATE_INVALID, outputs);
829 // When a display was swapped, the state moves from 791 // When a display was swapped, the state moves from
830 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED, so don't rely on 792 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED, so don't rely on
831 // the state chagne to tell if it was successful. 793 // the state chagne to tell if it was successful.
832 bool success = EnterState(display, screen, window, new_state, outputs); 794 bool success =
795 EnterState(display, screen, window, new_state, power_state_, outputs);
833 bool is_projecting = IsProjecting(outputs); 796 bool is_projecting = IsProjecting(outputs);
834 XRRFreeScreenResources(screen); 797 XRRFreeScreenResources(screen);
835 XUngrabServer(display); 798 XUngrabServer(display);
836 799
837 if (success) { 800 if (success) {
838 output_state_ = new_state; 801 output_state_ = new_state;
839 NotifyOnDisplayChanged(); 802 NotifyOnDisplayChanged();
840 } else { 803 } else {
841 FOR_EACH_OBSERVER( 804 FOR_EACH_OBSERVER(
842 Observer, observers_, OnDisplayModeChangeFailed(new_state)); 805 Observer, observers_, OnDisplayModeChangeFailed(new_state));
843 } 806 }
844 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> 807 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
845 SetIsProjecting(is_projecting); 808 SetIsProjecting(is_projecting);
846 } 809 }
847 810
848 void OutputConfigurator::AddObserver(Observer* observer) { 811 void OutputConfigurator::AddObserver(Observer* observer) {
849 observers_.AddObserver(observer); 812 observers_.AddObserver(observer);
850 } 813 }
851 814
852 void OutputConfigurator::RemoveObserver(Observer* observer) { 815 void OutputConfigurator::RemoveObserver(Observer* observer) {
853 observers_.RemoveObserver(observer); 816 observers_.RemoveObserver(observer);
854 } 817 }
855 818
856 // static 819 // static
857 bool OutputConfigurator::IsInternalOutputName(const std::string& name) { 820 bool OutputConfigurator::IsInternalOutputName(const std::string& name) {
858 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0; 821 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0;
859 } 822 }
860 823
861 void OutputConfigurator::SuspendDisplays() { 824 void OutputConfigurator::SuspendDisplays() {
862 // Turn displays on before suspend. At this point, the backlight is off, 825 // Turn internal displays on before suspend. At this point, the backlight
863 // so we turn on the internal display so that we can resume directly into 826 // is off, so we turn on the internal display so that we can resume
864 // "on" state. This greatly reduces resume times. 827 // directly into "on" state. This greatly reduces resume times.
865 ScreenPowerSet(true, true); 828 SetDisplayPower(DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF, false);
829
866 // We need to make sure that the monitor configuration we just did actually 830 // We need to make sure that the monitor configuration we just did actually
867 // completes before we return, because otherwise the X message could be 831 // completes before we return, because otherwise the X message could be
868 // racing with the HandleSuspendReadiness message. 832 // racing with the HandleSuspendReadiness message.
869 XSync(base::MessagePumpAuraX11::GetDefaultXDisplay(), 0); 833 XSync(base::MessagePumpAuraX11::GetDefaultXDisplay(), 0);
870 } 834 }
871 835
836 void OutputConfigurator::ResumeDisplays() {
837 // Force probing to ensure that we pick up any changes that were made
838 // while the system was suspended.
839 SetDisplayPower(DISPLAY_POWER_ALL_ON, true);
840 }
841
872 void OutputConfigurator::NotifyOnDisplayChanged() { 842 void OutputConfigurator::NotifyOnDisplayChanged() {
873 TRACE_EVENT0("chromeos", "OutputConfigurator::NotifyOnDisplayChanged"); 843 TRACE_EVENT0("chromeos", "OutputConfigurator::NotifyOnDisplayChanged");
874 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); 844 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged());
875 } 845 }
876 846
877 std::vector<OutputSnapshot> OutputConfigurator::GetDualOutputs( 847 std::vector<OutputSnapshot> OutputConfigurator::GetDualOutputs(
878 Display* display, 848 Display* display,
879 XRRScreenResources* screen) { 849 XRRScreenResources* screen) {
880 std::vector<OutputSnapshot> outputs; 850 std::vector<OutputSnapshot> outputs;
881 XRROutputInfo* one_info = NULL; 851 XRROutputInfo* one_info = NULL;
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 } 1155 }
1186 } 1156 }
1187 1157
1188 XIFreeDeviceInfo(info); 1158 XIFreeDeviceInfo(info);
1189 } 1159 }
1190 1160
1191 bool OutputConfigurator::EnterState( 1161 bool OutputConfigurator::EnterState(
1192 Display* display, 1162 Display* display,
1193 XRRScreenResources* screen, 1163 XRRScreenResources* screen,
1194 Window window, 1164 Window window,
1195 OutputState new_state, 1165 OutputState output_state,
1166 DisplayPowerState power_state,
1196 const std::vector<OutputSnapshot>& outputs) { 1167 const std::vector<OutputSnapshot>& outputs) {
1197 TRACE_EVENT0("chromeos", "OutputConfigurator::EnterState"); 1168 TRACE_EVENT0("chromeos", "OutputConfigurator::EnterState");
1198 switch (outputs.size()) { 1169 switch (outputs.size()) {
1199 case 0: 1170 case 0:
1200 // Do nothing as no 0-display states are supported. 1171 // Do nothing as no 0-display states are supported.
1201 break; 1172 break;
1202 case 1: { 1173 case 1: {
1203 // Re-allocate the framebuffer to fit. 1174 // Re-allocate the framebuffer to fit.
1204 XRRModeInfo* mode_info = ModeInfoForID(screen, outputs[0].native_mode); 1175 XRRModeInfo* mode_info = ModeInfoForID(screen, outputs[0].native_mode);
1205 if (mode_info == NULL) { 1176 if (mode_info == NULL) {
1206 UMA_HISTOGRAM_COUNTS("Display.EnterState.single_failures", 1); 1177 UMA_HISTOGRAM_COUNTS("Display.EnterState.single_failures", 1);
1207 return false; 1178 return false;
1208 } 1179 }
1209 1180
1181 bool power_on = power_state == DISPLAY_POWER_ALL_ON ||
1182 (power_state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON &&
1183 !outputs[0].is_internal) ||
1184 (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF &&
1185 outputs[0].is_internal);
1210 CrtcConfig config( 1186 CrtcConfig config(
1211 GetNextCrtcAfter(display, screen, outputs[0].output, None), 1187 GetNextCrtcAfter(display, screen, outputs[0].output, None),
1212 0, 0, outputs[0].native_mode, outputs[0].output); 1188 0, 0, power_on ? outputs[0].native_mode : None, outputs[0].output);
1213 1189
1214 int width = mode_info->width; 1190 CreateFrameBuffer(display, screen, window, mode_info->width,
1215 int height = mode_info->height; 1191 mode_info->height, &config, NULL);
1216 CreateFrameBuffer(display, screen, window, width, height, &config, NULL);
1217 1192
1218 // Re-attach native mode for the CRTC.
1219 ConfigureCrtc(display, screen, &config); 1193 ConfigureCrtc(display, screen, &config);
1194
1220 // Restore identity transformation for single monitor in native mode. 1195 // Restore identity transformation for single monitor in native mode.
1221 if (outputs[0].touch_device_id != None) { 1196 if (outputs[0].touch_device_id != None) {
1222 CoordinateTransformation ctm; // Defaults to identity 1197 CoordinateTransformation ctm; // Defaults to identity
1223 ConfigureCTM(display, outputs[0].touch_device_id, ctm); 1198 ConfigureCTM(display, outputs[0].touch_device_id, ctm);
1224 } 1199 }
1225 break; 1200 break;
1226 } 1201 }
1227 case 2: { 1202 case 2: {
1228 RRCrtc primary_crtc = 1203 RRCrtc primary_crtc =
1229 GetNextCrtcAfter(display, screen, outputs[0].output, None); 1204 GetNextCrtcAfter(display, screen, outputs[0].output, None);
1230 RRCrtc secondary_crtc = 1205 RRCrtc secondary_crtc =
1231 GetNextCrtcAfter(display, screen, outputs[1].output, primary_crtc); 1206 GetNextCrtcAfter(display, screen, outputs[1].output, primary_crtc);
1232 1207
1233 if (new_state == STATE_DUAL_MIRROR) { 1208 // Workaround for crbug.com/148365: leave internal display on for
1209 // internal-off, external-on so user can move cursor (and hence
1210 // windows) onto internal display even when it's off.
1211 bool primary_power_on = power_state == DISPLAY_POWER_ALL_ON ||
1212 (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF &&
1213 outputs[0].is_internal);
1214 bool secondary_power_on = power_state == DISPLAY_POWER_ALL_ON ||
1215 (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF &&
1216 outputs[1].is_internal);
1217
1218 if (output_state == STATE_DUAL_MIRROR) {
1234 XRRModeInfo* mode_info = ModeInfoForID(screen, outputs[0].mirror_mode); 1219 XRRModeInfo* mode_info = ModeInfoForID(screen, outputs[0].mirror_mode);
1235 if (mode_info == NULL) { 1220 if (mode_info == NULL) {
1236 UMA_HISTOGRAM_COUNTS("Display.EnterState.mirror_failures", 1); 1221 UMA_HISTOGRAM_COUNTS("Display.EnterState.mirror_failures", 1);
1237 return false; 1222 return false;
1238 } 1223 }
1239 1224
1240 CrtcConfig config1(primary_crtc, 0, 0, outputs[0].mirror_mode, 1225 CrtcConfig config1(primary_crtc, 0, 0,
1226 primary_power_on ? outputs[0].mirror_mode : None,
1241 outputs[0].output); 1227 outputs[0].output);
1242 CrtcConfig config2(secondary_crtc, 0, 0, outputs[1].mirror_mode, 1228 CrtcConfig config2(secondary_crtc, 0, 0,
1229 secondary_power_on ? outputs[1].mirror_mode : None,
1243 outputs[1].output); 1230 outputs[1].output);
1244 1231
1245 int width = mode_info->width; 1232 CreateFrameBuffer(display, screen, window, mode_info->width,
1246 int height = mode_info->height; 1233 mode_info->height, &config1, &config2);
1247 CreateFrameBuffer(display, screen, window, width, height,
1248 &config1, &config2);
1249 1234
1250 ConfigureCrtc(display, screen, &config1); 1235 ConfigureCrtc(display, screen, &config1);
1251 ConfigureCrtc(display, screen, &config2); 1236 ConfigureCrtc(display, screen, &config2);
1237
1252 for (size_t i = 0; i < outputs.size(); i++) { 1238 for (size_t i = 0; i < outputs.size(); i++) {
1253 if (outputs[i].touch_device_id == None) 1239 if (outputs[i].touch_device_id == None)
1254 continue; 1240 continue;
1255 1241
1256 CoordinateTransformation ctm; 1242 CoordinateTransformation ctm;
1257 // CTM needs to be calculated if aspect preserving scaling is used. 1243 // CTM needs to be calculated if aspect preserving scaling is used.
1258 // Otherwise, assume it is full screen, and use identity CTM. 1244 // Otherwise, assume it is full screen, and use identity CTM.
1259 if (outputs[i].mirror_mode != outputs[i].native_mode && 1245 if (outputs[i].mirror_mode != outputs[i].native_mode &&
1260 outputs[i].is_aspect_preserving_scaling) { 1246 outputs[i].is_aspect_preserving_scaling) {
1261 ctm = GetMirrorModeCTM(screen, &outputs[i]); 1247 ctm = GetMirrorModeCTM(screen, &outputs[i]);
1262 } 1248 }
1263 ConfigureCTM(display, outputs[i].touch_device_id, ctm); 1249 ConfigureCTM(display, outputs[i].touch_device_id, ctm);
1264 } 1250 }
1265 } else { 1251 } else {
1266 XRRModeInfo* primary_mode_info = 1252 XRRModeInfo* primary_mode_info =
1267 ModeInfoForID(screen, outputs[0].native_mode); 1253 ModeInfoForID(screen, outputs[0].native_mode);
1268 XRRModeInfo* secondary_mode_info = 1254 XRRModeInfo* secondary_mode_info =
1269 ModeInfoForID(screen, outputs[1].native_mode); 1255 ModeInfoForID(screen, outputs[1].native_mode);
1270 if (primary_mode_info == NULL || secondary_mode_info == NULL) { 1256 if (primary_mode_info == NULL || secondary_mode_info == NULL) {
1271 UMA_HISTOGRAM_COUNTS("Display.EnterState.dual_failures", 1); 1257 UMA_HISTOGRAM_COUNTS("Display.EnterState.dual_failures", 1);
1272 return false; 1258 return false;
1273 } 1259 }
1274 1260
1275 int primary_height = primary_mode_info->height; 1261 int primary_height = primary_mode_info->height;
1276 int secondary_height = secondary_mode_info->height; 1262 int secondary_height = secondary_mode_info->height;
1277 CrtcConfig config1(primary_crtc, 0, 0, outputs[0].native_mode, 1263 CrtcConfig config1(primary_crtc, 0, 0,
1264 primary_power_on ? outputs[0].native_mode : None,
1278 outputs[0].output); 1265 outputs[0].output);
1279 CrtcConfig config2(secondary_crtc, 0, 0, outputs[1].native_mode, 1266 CrtcConfig config2(secondary_crtc, 0, 0,
1267 secondary_power_on ? outputs[1].native_mode : None,
1280 outputs[1].output); 1268 outputs[1].output);
1281 1269
1282 if (new_state == STATE_DUAL_EXTENDED) 1270 if (output_state == STATE_DUAL_EXTENDED)
1283 config2.y = primary_height + kVerticalGap; 1271 config2.y = primary_height + kVerticalGap;
1284 else 1272 else
1285 config1.y = secondary_height + kVerticalGap; 1273 config1.y = secondary_height + kVerticalGap;
1286 1274
1287 1275 int width = std::max<int>(
1288 int width = 1276 primary_mode_info->width, secondary_mode_info->width);
1289 std::max<int>(primary_mode_info->width, secondary_mode_info->width);
1290 int height = primary_height + secondary_height + kVerticalGap; 1277 int height = primary_height + secondary_height + kVerticalGap;
1291 1278
1292 CreateFrameBuffer(display, screen, window, width, height, &config1, 1279 CreateFrameBuffer(display, screen, window, width, height, &config1,
1293 &config2); 1280 &config2);
1294 1281
1295 ConfigureCrtc(display, screen, &config1); 1282 ConfigureCrtc(display, screen, &config1);
1296 ConfigureCrtc(display, screen, &config2); 1283 ConfigureCrtc(display, screen, &config2);
1297 1284
1298 if (outputs[0].touch_device_id != None) { 1285 if (outputs[0].touch_device_id != None) {
1299 CoordinateTransformation ctm; 1286 CoordinateTransformation ctm;
1300 ctm.x_scale = static_cast<float>(primary_mode_info->width) / width; 1287 ctm.x_scale = static_cast<float>(primary_mode_info->width) / width;
1301 ctm.x_offset = static_cast<float>(config1.x) / width; 1288 ctm.x_offset = static_cast<float>(config1.x) / width;
1302 ctm.y_scale = static_cast<float>(primary_height) / height; 1289 ctm.y_scale = static_cast<float>(primary_height) / height;
1303 ctm.y_offset = static_cast<float>(config1.y) / height; 1290 ctm.y_offset = static_cast<float>(config1.y) / height;
1304 ConfigureCTM(display, outputs[0].touch_device_id, ctm); 1291 ConfigureCTM(display, outputs[0].touch_device_id, ctm);
1305 } 1292 }
1306 if (outputs[1].touch_device_id != None) { 1293 if (outputs[1].touch_device_id != None) {
1307 CoordinateTransformation ctm; 1294 CoordinateTransformation ctm;
1308 ctm.x_scale = static_cast<float>(secondary_mode_info->width) / width; 1295 ctm.x_scale = static_cast<float>(secondary_mode_info->width) /
1296 width;
1309 ctm.x_offset = static_cast<float>(config2.x) / width; 1297 ctm.x_offset = static_cast<float>(config2.x) / width;
1310 ctm.y_scale = static_cast<float>(secondary_height) / height; 1298 ctm.y_scale = static_cast<float>(secondary_height) / height;
1311 ctm.y_offset = static_cast<float>(config2.y) / height; 1299 ctm.y_offset = static_cast<float>(config2.y) / height;
1312 ConfigureCTM(display, outputs[1].touch_device_id, ctm); 1300 ConfigureCTM(display, outputs[1].touch_device_id, ctm);
1313 } 1301 }
1314 } 1302 }
1315 break; 1303 break;
1316 } 1304 }
1317 default: 1305 default:
1318 CHECK(false); 1306 CHECK(false);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 // static 1349 // static
1362 RRMode OutputConfigurator::GetOutputNativeMode( 1350 RRMode OutputConfigurator::GetOutputNativeMode(
1363 const XRROutputInfo* output_info) { 1351 const XRROutputInfo* output_info) {
1364 if (output_info->nmode <= 0) 1352 if (output_info->nmode <= 0)
1365 return None; 1353 return None;
1366 1354
1367 return output_info->modes[0]; 1355 return output_info->modes[0];
1368 } 1356 }
1369 1357
1370 } // namespace chromeos 1358 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/display/output_configurator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698