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

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

Issue 191223007: Move touch CTM from X into Chrome (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: add file ui/aura/touch_ctm.h(cc) Created 6 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
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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 117
118 OutputConfigurator::ModeInfo::ModeInfo(int width, 118 OutputConfigurator::ModeInfo::ModeInfo(int width,
119 int height, 119 int height,
120 bool interlaced, 120 bool interlaced,
121 float refresh_rate) 121 float refresh_rate)
122 : width(width), 122 : width(width),
123 height(height), 123 height(height),
124 interlaced(interlaced), 124 interlaced(interlaced),
125 refresh_rate(refresh_rate) {} 125 refresh_rate(refresh_rate) {}
126 126
127 OutputConfigurator::CoordinateTransformation::CoordinateTransformation()
128 : x_scale(1.0),
129 x_offset(0.0),
130 y_scale(1.0),
131 y_offset(0.0) {}
132
133 OutputConfigurator::OutputSnapshot::OutputSnapshot() 127 OutputConfigurator::OutputSnapshot::OutputSnapshot()
134 : output(None), 128 : output(None),
135 crtc(None), 129 crtc(None),
136 current_mode(None), 130 current_mode(None),
137 native_mode(None), 131 native_mode(None),
138 mirror_mode(None), 132 mirror_mode(None),
139 selected_mode(None), 133 selected_mode(None),
140 x(0), 134 x(0),
141 y(0), 135 y(0),
142 width_mm(0), 136 width_mm(0),
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 return false; 874 return false;
881 width = mode_info->width; 875 width = mode_info->width;
882 height = mode_info->height; 876 height = mode_info->height;
883 877
884 for (size_t i = 0; i < updated_outputs.size(); ++i) { 878 for (size_t i = 0; i < updated_outputs.size(); ++i) {
885 OutputSnapshot* output = &updated_outputs[i]; 879 OutputSnapshot* output = &updated_outputs[i];
886 output->x = 0; 880 output->x = 0;
887 output->y = 0; 881 output->y = 0;
888 output->current_mode = output_power[i] ? output->mirror_mode : None; 882 output->current_mode = output_power[i] ? output->mirror_mode : None;
889 if (output->touch_device_id) { 883 if (output->touch_device_id) {
890 // CTM needs to be calculated if aspect preserving scaling is used.
891 // Otherwise, assume it is full screen, and use identity CTM.
892 if (output->mirror_mode != output->native_mode && 884 if (output->mirror_mode != output->native_mode &&
893 output->is_aspect_preserving_scaling) { 885 output->is_aspect_preserving_scaling) {
894 output->transform = GetMirrorModeCTM(*output);
895 mirrored_display_area_ratio_map_[output->touch_device_id] = 886 mirrored_display_area_ratio_map_[output->touch_device_id] =
896 GetMirroredDisplayAreaRatio(*output); 887 GetMirroredDisplayAreaRatio(*output);
897 } 888 }
898 } 889 }
899 } 890 }
900 break; 891 break;
901 } 892 }
902 case ui::OUTPUT_STATE_DUAL_EXTENDED: { 893 case ui::OUTPUT_STATE_DUAL_EXTENDED: {
903 if (updated_outputs.size() != 2 || 894 if (updated_outputs.size() != 2 ||
904 (num_on_outputs != 0 && num_on_outputs != 2)) { 895 (num_on_outputs != 0 && num_on_outputs != 2)) {
(...skipping 12 matching lines...) Expand all
917 // Retain the full screen size even if all outputs are off so the 908 // Retain the full screen size even if all outputs are off so the
918 // same desktop configuration can be restored when the outputs are 909 // same desktop configuration can be restored when the outputs are
919 // turned back on. 910 // turned back on.
920 const ModeInfo* mode_info = 911 const ModeInfo* mode_info =
921 GetModeInfo(updated_outputs[i], updated_outputs[i].selected_mode); 912 GetModeInfo(updated_outputs[i], updated_outputs[i].selected_mode);
922 if (!mode_info) 913 if (!mode_info)
923 return false; 914 return false;
924 width = std::max<int>(width, mode_info->width); 915 width = std::max<int>(width, mode_info->width);
925 height += (height ? kVerticalGap : 0) + mode_info->height; 916 height += (height ? kVerticalGap : 0) + mode_info->height;
926 } 917 }
927
928 for (size_t i = 0; i < updated_outputs.size(); ++i) {
929 OutputSnapshot* output = &updated_outputs[i];
930 if (output->touch_device_id)
931 output->transform = GetExtendedModeCTM(*output, width, height);
932 }
933 break; 918 break;
934 } 919 }
935 } 920 }
936 921
937 // Finally, apply the desired changes. 922 // Finally, apply the desired changes.
938 DCHECK_EQ(cached_outputs_.size(), updated_outputs.size()); 923 DCHECK_EQ(cached_outputs_.size(), updated_outputs.size());
939 bool all_succeeded = true; 924 bool all_succeeded = true;
940 if (!updated_outputs.empty()) { 925 if (!updated_outputs.empty()) {
941 native_display_delegate_->CreateFrameBuffer(width, height, updated_outputs); 926 native_display_delegate_->CreateFrameBuffer(width, height, updated_outputs);
942 for (size_t i = 0; i < updated_outputs.size(); ++i) { 927 for (size_t i = 0; i < updated_outputs.size(); ++i) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 updated_outputs[i].current_mode = it->first; 961 updated_outputs[i].current_mode = it->first;
977 best_mode_pixels = pixel_count; 962 best_mode_pixels = pixel_count;
978 } 963 }
979 } 964 }
980 965
981 if (best_mode_pixels == 0) 966 if (best_mode_pixels == 0)
982 break; 967 break;
983 } 968 }
984 969
985 if (configure_succeeded) { 970 if (configure_succeeded) {
986 if (output.touch_device_id)
987 touchscreen_delegate_->ConfigureCTM(output.touch_device_id,
988 output.transform);
989 cached_outputs_[i] = updated_outputs[i]; 971 cached_outputs_[i] = updated_outputs[i];
990 } else { 972 } else {
991 all_succeeded = false; 973 all_succeeded = false;
992 } 974 }
993 975
994 // If we are trying to set mirror mode and one of the modesets fails, 976 // If we are trying to set mirror mode and one of the modesets fails,
995 // then the two monitors will be mis-matched. In this case, return 977 // then the two monitors will be mis-matched. In this case, return
996 // false to let the observers be aware. 978 // false to let the observers be aware.
997 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR && output_power[i] && 979 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR && output_power[i] &&
998 output.current_mode != output.mirror_mode) 980 output.current_mode != output.mirror_mode)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 } 1015 }
1034 return state_controller_->GetStateForDisplayIds(display_ids); 1016 return state_controller_->GetStateForDisplayIds(display_ids);
1035 } 1017 }
1036 } 1018 }
1037 default: 1019 default:
1038 NOTREACHED(); 1020 NOTREACHED();
1039 } 1021 }
1040 return ui::OUTPUT_STATE_INVALID; 1022 return ui::OUTPUT_STATE_INVALID;
1041 } 1023 }
1042 1024
1043 OutputConfigurator::CoordinateTransformation
1044 OutputConfigurator::GetMirrorModeCTM(
1045 const OutputConfigurator::OutputSnapshot& output) {
1046 CoordinateTransformation ctm; // Default to identity
1047 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode);
1048 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode);
1049
1050 if (!native_mode_info || !mirror_mode_info ||
1051 native_mode_info->height == 0 || mirror_mode_info->height == 0 ||
1052 native_mode_info->width == 0 || mirror_mode_info->width == 0)
1053 return ctm;
1054
1055 float native_mode_ar = static_cast<float>(native_mode_info->width) /
1056 static_cast<float>(native_mode_info->height);
1057 float mirror_mode_ar = static_cast<float>(mirror_mode_info->width) /
1058 static_cast<float>(mirror_mode_info->height);
1059
1060 if (mirror_mode_ar > native_mode_ar) { // Letterboxing
1061 ctm.x_scale = 1.0;
1062 ctm.x_offset = 0.0;
1063 ctm.y_scale = mirror_mode_ar / native_mode_ar;
1064 ctm.y_offset = (native_mode_ar / mirror_mode_ar - 1.0) * 0.5;
1065 return ctm;
1066 }
1067 if (native_mode_ar > mirror_mode_ar) { // Pillarboxing
1068 ctm.y_scale = 1.0;
1069 ctm.y_offset = 0.0;
1070 ctm.x_scale = native_mode_ar / mirror_mode_ar;
1071 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5;
1072 return ctm;
1073 }
1074
1075 return ctm; // Same aspect ratio - return identity
1076 }
1077
1078 OutputConfigurator::CoordinateTransformation
1079 OutputConfigurator::GetExtendedModeCTM(
1080 const OutputConfigurator::OutputSnapshot& output,
1081 int framebuffer_width,
1082 int framebuffer_height) {
1083 CoordinateTransformation ctm; // Default to identity
1084 const ModeInfo* mode_info = GetModeInfo(output, output.selected_mode);
1085 DCHECK(mode_info);
1086 if (!mode_info)
1087 return ctm;
1088 // An example of how to calculate the CTM.
1089 // Suppose we have 2 monitors, the first one has size 1366 x 768.
1090 // The second one has size 2560 x 1600
1091 // The total size of framebuffer is 2560 x 2428
1092 // where 2428 = 768 + 60 (hidden gap) + 1600
1093 // and the sceond monitor is translated to Point (0, 828) in the
1094 // framebuffer.
1095 // X will first map input event location to [0, 2560) x [0, 2428),
1096 // then apply CTM on it.
1097 // So to compute CTM, for monitor1, we have
1098 // x_scale = (1366 - 1) / (2560 - 1)
1099 // x_offset = 0 / (2560 - 1)
1100 // y_scale = (768 - 1) / (2428 - 1)
1101 // y_offset = 0 / (2428 -1)
1102 // For Monitor 2, we have
1103 // x_scale = (2560 - 1) / (2560 - 1)
1104 // x_offset = 0 / (2560 - 1)
1105 // y_scale = (1600 - 1) / (2428 - 1)
1106 // y_offset = 828 / (2428 -1)
1107 // See the unittest OutputConfiguratorTest.CTMForMultiScreens.
1108 ctm.x_scale =
1109 static_cast<float>(mode_info->width - 1) / (framebuffer_width - 1);
1110 ctm.x_offset = static_cast<float>(output.x) / (framebuffer_width - 1);
1111 ctm.y_scale =
1112 static_cast<float>(mode_info->height - 1) / (framebuffer_height - 1);
1113 ctm.y_offset = static_cast<float>(output.y) / (framebuffer_height - 1);
1114 return ctm;
1115 }
1116
1117 float OutputConfigurator::GetMirroredDisplayAreaRatio( 1025 float OutputConfigurator::GetMirroredDisplayAreaRatio(
1118 const OutputConfigurator::OutputSnapshot& output) { 1026 const OutputConfigurator::OutputSnapshot& output) {
1119 float area_ratio = 1.0f; 1027 float area_ratio = 1.0f;
1120 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode); 1028 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode);
1121 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode); 1029 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode);
1122 1030
1123 if (!native_mode_info || !mirror_mode_info || 1031 if (!native_mode_info || !mirror_mode_info ||
1124 native_mode_info->height == 0 || mirror_mode_info->height == 0 || 1032 native_mode_info->height == 0 || mirror_mode_info->height == 0 ||
1125 native_mode_info->width == 0 || mirror_mode_info->width == 0) 1033 native_mode_info->width == 0 || mirror_mode_info->width == 0)
1126 return area_ratio; 1034 return area_ratio;
1127 1035
1128 float width_ratio = static_cast<float>(mirror_mode_info->width) / 1036 float width_ratio = static_cast<float>(mirror_mode_info->width) /
1129 static_cast<float>(native_mode_info->width); 1037 static_cast<float>(native_mode_info->width);
1130 float height_ratio = static_cast<float>(mirror_mode_info->height) / 1038 float height_ratio = static_cast<float>(mirror_mode_info->height) /
1131 static_cast<float>(native_mode_info->height); 1039 static_cast<float>(native_mode_info->height);
1132 1040
1133 area_ratio = width_ratio * height_ratio; 1041 area_ratio = width_ratio * height_ratio;
1134 return area_ratio; 1042 return area_ratio;
1135 } 1043 }
1136 1044
1137 } // namespace chromeos 1045 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698