OLD | NEW |
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 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 OutputSnapshot* output = &updated_outputs[i]; | 934 OutputSnapshot* output = &updated_outputs[i]; |
935 if (output->touch_device_id) | 935 if (output->touch_device_id) |
936 output->transform = GetExtendedModeCTM(*output, width, height); | 936 output->transform = GetExtendedModeCTM(*output, width, height); |
937 } | 937 } |
938 break; | 938 break; |
939 } | 939 } |
940 } | 940 } |
941 | 941 |
942 // Finally, apply the desired changes. | 942 // Finally, apply the desired changes. |
943 DCHECK_EQ(cached_outputs_.size(), updated_outputs.size()); | 943 DCHECK_EQ(cached_outputs_.size(), updated_outputs.size()); |
| 944 bool all_succeeded = true; |
944 if (!updated_outputs.empty()) { | 945 if (!updated_outputs.empty()) { |
945 delegate_->CreateFrameBuffer(width, height, updated_outputs); | 946 delegate_->CreateFrameBuffer(width, height, updated_outputs); |
946 for (size_t i = 0; i < updated_outputs.size(); ++i) { | 947 for (size_t i = 0; i < updated_outputs.size(); ++i) { |
947 const OutputSnapshot& output = updated_outputs[i]; | 948 const OutputSnapshot& output = updated_outputs[i]; |
948 if (delegate_->ConfigureCrtc(output.crtc, output.current_mode, | 949 bool configure_succeeded =false; |
949 output.output, output.x, output.y)) { | 950 |
950 if (output.touch_device_id) | 951 while (true) { |
951 delegate_->ConfigureCTM(output.touch_device_id, output.transform); | 952 if (delegate_->ConfigureCrtc(output.crtc, output.current_mode, |
952 cached_outputs_[i] = updated_outputs[i]; | 953 output.output, output.x, output.y)) { |
953 } else { | 954 configure_succeeded = true; |
| 955 break; |
| 956 } |
| 957 |
954 LOG(WARNING) << "Unable to configure CRTC " << output.crtc << ":" | 958 LOG(WARNING) << "Unable to configure CRTC " << output.crtc << ":" |
955 << " mode=" << output.current_mode | 959 << " mode=" << output.current_mode |
956 << " output=" << output.output | 960 << " output=" << output.output |
957 << " x=" << output.x | 961 << " x=" << output.x |
958 << " y=" << output.y; | 962 << " y=" << output.y; |
| 963 |
| 964 const ModeInfo* mode_info = GetModeInfo(output, output.current_mode); |
| 965 if (!mode_info) |
| 966 break; |
| 967 |
| 968 // Find the mode with the next-best resolution and see if that can |
| 969 // be set. |
| 970 int best_mode_pixels = 0; |
| 971 |
| 972 int current_mode_pixels = mode_info->width * mode_info->height; |
| 973 for (ModeInfoMap::const_iterator it = output.mode_infos.begin(); |
| 974 it != output.mode_infos.end(); it++) { |
| 975 int pixel_count = it->second.width * it->second.height; |
| 976 if ((pixel_count < current_mode_pixels) && |
| 977 (pixel_count > best_mode_pixels)) { |
| 978 updated_outputs[i].current_mode = it->first; |
| 979 best_mode_pixels = pixel_count; |
| 980 } |
| 981 } |
| 982 |
| 983 if (best_mode_pixels == 0) |
| 984 break; |
959 } | 985 } |
| 986 |
| 987 if (configure_succeeded) { |
| 988 if (output.touch_device_id) |
| 989 delegate_->ConfigureCTM(output.touch_device_id, output.transform); |
| 990 cached_outputs_[i] = updated_outputs[i]; |
| 991 } else { |
| 992 all_succeeded = false; |
| 993 } |
| 994 |
| 995 // If we are trying to set mirror mode and one of the modesets fails, |
| 996 // then the two monitors will be mis-matched. In this case, return |
| 997 // false to let the observers be aware. |
| 998 if (output_state == STATE_DUAL_MIRROR && |
| 999 output_power[i] && |
| 1000 output.current_mode != output.mirror_mode) |
| 1001 all_succeeded = false; |
| 1002 |
960 } | 1003 } |
961 } | 1004 } |
962 | 1005 |
963 output_state_ = output_state; | 1006 if (all_succeeded) { |
964 power_state_ = power_state; | 1007 output_state_ = output_state; |
965 return true; | 1008 power_state_ = power_state; |
| 1009 } |
| 1010 return all_succeeded; |
966 } | 1011 } |
967 | 1012 |
968 OutputState OutputConfigurator::ChooseOutputState( | 1013 OutputState OutputConfigurator::ChooseOutputState( |
969 DisplayPowerState power_state) const { | 1014 DisplayPowerState power_state) const { |
970 int num_on_outputs = GetOutputPower(cached_outputs_, power_state, NULL); | 1015 int num_on_outputs = GetOutputPower(cached_outputs_, power_state, NULL); |
971 switch (cached_outputs_.size()) { | 1016 switch (cached_outputs_.size()) { |
972 case 0: | 1017 case 0: |
973 return STATE_HEADLESS; | 1018 return STATE_HEADLESS; |
974 case 1: | 1019 case 1: |
975 return STATE_SINGLE; | 1020 return STATE_SINGLE; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1085 float width_ratio = static_cast<float>(mirror_mode_info->width) / | 1130 float width_ratio = static_cast<float>(mirror_mode_info->width) / |
1086 static_cast<float>(native_mode_info->width); | 1131 static_cast<float>(native_mode_info->width); |
1087 float height_ratio = static_cast<float>(mirror_mode_info->height) / | 1132 float height_ratio = static_cast<float>(mirror_mode_info->height) / |
1088 static_cast<float>(native_mode_info->height); | 1133 static_cast<float>(native_mode_info->height); |
1089 | 1134 |
1090 area_ratio = width_ratio * height_ratio; | 1135 area_ratio = width_ratio * height_ratio; |
1091 return area_ratio; | 1136 return area_ratio; |
1092 } | 1137 } |
1093 | 1138 |
1094 } // namespace chromeos | 1139 } // namespace chromeos |
OLD | NEW |