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

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: restructuring 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 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 116
117 OutputConfigurator::ModeInfo::ModeInfo(int width, 117 OutputConfigurator::ModeInfo::ModeInfo(int width,
118 int height, 118 int height,
119 bool interlaced, 119 bool interlaced,
120 float refresh_rate) 120 float refresh_rate)
121 : width(width), 121 : width(width),
122 height(height), 122 height(height),
123 interlaced(interlaced), 123 interlaced(interlaced),
124 refresh_rate(refresh_rate) {} 124 refresh_rate(refresh_rate) {}
125 125
126 OutputConfigurator::CoordinateTransformation::CoordinateTransformation()
127 : x_scale(1.0),
128 x_offset(0.0),
129 y_scale(1.0),
130 y_offset(0.0) {}
131
132 OutputConfigurator::OutputSnapshot::OutputSnapshot() 126 OutputConfigurator::OutputSnapshot::OutputSnapshot()
133 : output(None), 127 : output(None),
134 crtc(None), 128 crtc(None),
135 current_mode(None), 129 current_mode(None),
136 native_mode(None), 130 native_mode(None),
137 mirror_mode(None), 131 mirror_mode(None),
138 selected_mode(None), 132 selected_mode(None),
139 x(0), 133 x(0),
140 y(0), 134 y(0),
141 width_mm(0), 135 width_mm(0),
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 return false; 791 return false;
798 width = mode_info->width; 792 width = mode_info->width;
799 height = mode_info->height; 793 height = mode_info->height;
800 794
801 for (size_t i = 0; i < updated_outputs.size(); ++i) { 795 for (size_t i = 0; i < updated_outputs.size(); ++i) {
802 OutputSnapshot* output = &updated_outputs[i]; 796 OutputSnapshot* output = &updated_outputs[i];
803 output->x = 0; 797 output->x = 0;
804 output->y = 0; 798 output->y = 0;
805 output->current_mode = output_power[i] ? output->mirror_mode : None; 799 output->current_mode = output_power[i] ? output->mirror_mode : None;
806 if (output->touch_device_id) { 800 if (output->touch_device_id) {
807 // CTM needs to be calculated if aspect preserving scaling is used.
808 // Otherwise, assume it is full screen, and use identity CTM.
809 if (output->mirror_mode != output->native_mode && 801 if (output->mirror_mode != output->native_mode &&
810 output->is_aspect_preserving_scaling) { 802 output->is_aspect_preserving_scaling) {
811 output->transform = GetMirrorModeCTM(*output);
812 mirrored_display_area_ratio_map_[output->touch_device_id] = 803 mirrored_display_area_ratio_map_[output->touch_device_id] =
813 GetMirroredDisplayAreaRatio(*output); 804 GetMirroredDisplayAreaRatio(*output);
814 } 805 }
815 } 806 }
816 } 807 }
817 break; 808 break;
818 } 809 }
819 case ui::OUTPUT_STATE_DUAL_EXTENDED: { 810 case ui::OUTPUT_STATE_DUAL_EXTENDED: {
820 if (updated_outputs.size() != 2 || 811 if (updated_outputs.size() != 2 ||
821 (num_on_outputs != 0 && num_on_outputs != 2)) { 812 (num_on_outputs != 0 && num_on_outputs != 2)) {
(...skipping 12 matching lines...) Expand all
834 // Retain the full screen size even if all outputs are off so the 825 // Retain the full screen size even if all outputs are off so the
835 // same desktop configuration can be restored when the outputs are 826 // same desktop configuration can be restored when the outputs are
836 // turned back on. 827 // turned back on.
837 const ModeInfo* mode_info = 828 const ModeInfo* mode_info =
838 GetModeInfo(updated_outputs[i], updated_outputs[i].selected_mode); 829 GetModeInfo(updated_outputs[i], updated_outputs[i].selected_mode);
839 if (!mode_info) 830 if (!mode_info)
840 return false; 831 return false;
841 width = std::max<int>(width, mode_info->width); 832 width = std::max<int>(width, mode_info->width);
842 height += (height ? kVerticalGap : 0) + mode_info->height; 833 height += (height ? kVerticalGap : 0) + mode_info->height;
843 } 834 }
844
845 for (size_t i = 0; i < updated_outputs.size(); ++i) {
846 OutputSnapshot* output = &updated_outputs[i];
847 if (output->touch_device_id)
848 output->transform = GetExtendedModeCTM(*output, width, height);
849 }
850 break; 835 break;
851 } 836 }
852 } 837 }
853 838
854 // Finally, apply the desired changes. 839 // Finally, apply the desired changes.
855 DCHECK_EQ(cached_outputs_.size(), updated_outputs.size()); 840 DCHECK_EQ(cached_outputs_.size(), updated_outputs.size());
856 bool all_succeeded = true; 841 bool all_succeeded = true;
857 if (!updated_outputs.empty()) { 842 if (!updated_outputs.empty()) {
858 native_display_delegate_->CreateFrameBuffer(width, height, updated_outputs); 843 native_display_delegate_->CreateFrameBuffer(width, height, updated_outputs);
859 for (size_t i = 0; i < updated_outputs.size(); ++i) { 844 for (size_t i = 0; i < updated_outputs.size(); ++i) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 updated_outputs[i].current_mode = it->first; 877 updated_outputs[i].current_mode = it->first;
893 best_mode_pixels = pixel_count; 878 best_mode_pixels = pixel_count;
894 } 879 }
895 } 880 }
896 881
897 if (best_mode_pixels == 0) 882 if (best_mode_pixels == 0)
898 break; 883 break;
899 } 884 }
900 885
901 if (configure_succeeded) { 886 if (configure_succeeded) {
902 if (output.touch_device_id)
903 touchscreen_delegate_->ConfigureCTM(output.touch_device_id,
904 output.transform);
905 cached_outputs_[i] = updated_outputs[i]; 887 cached_outputs_[i] = updated_outputs[i];
906 } else { 888 } else {
907 all_succeeded = false; 889 all_succeeded = false;
908 } 890 }
909 891
910 // If we are trying to set mirror mode and one of the modesets fails, 892 // If we are trying to set mirror mode and one of the modesets fails,
911 // then the two monitors will be mis-matched. In this case, return 893 // then the two monitors will be mis-matched. In this case, return
912 // false to let the observers be aware. 894 // false to let the observers be aware.
913 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR && output_power[i] && 895 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR && output_power[i] &&
914 output.current_mode != output.mirror_mode) 896 output.current_mode != output.mirror_mode)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 } 931 }
950 return state_controller_->GetStateForDisplayIds(display_ids); 932 return state_controller_->GetStateForDisplayIds(display_ids);
951 } 933 }
952 } 934 }
953 default: 935 default:
954 NOTREACHED(); 936 NOTREACHED();
955 } 937 }
956 return ui::OUTPUT_STATE_INVALID; 938 return ui::OUTPUT_STATE_INVALID;
957 } 939 }
958 940
959 OutputConfigurator::CoordinateTransformation
960 OutputConfigurator::GetMirrorModeCTM(
961 const OutputConfigurator::OutputSnapshot& output) {
962 CoordinateTransformation ctm; // Default to identity
963 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode);
964 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode);
965
966 if (!native_mode_info || !mirror_mode_info ||
967 native_mode_info->height == 0 || mirror_mode_info->height == 0 ||
968 native_mode_info->width == 0 || mirror_mode_info->width == 0)
969 return ctm;
970
971 float native_mode_ar = static_cast<float>(native_mode_info->width) /
972 static_cast<float>(native_mode_info->height);
973 float mirror_mode_ar = static_cast<float>(mirror_mode_info->width) /
974 static_cast<float>(mirror_mode_info->height);
975
976 if (mirror_mode_ar > native_mode_ar) { // Letterboxing
977 ctm.x_scale = 1.0;
978 ctm.x_offset = 0.0;
979 ctm.y_scale = mirror_mode_ar / native_mode_ar;
980 ctm.y_offset = (native_mode_ar / mirror_mode_ar - 1.0) * 0.5;
981 return ctm;
982 }
983 if (native_mode_ar > mirror_mode_ar) { // Pillarboxing
984 ctm.y_scale = 1.0;
985 ctm.y_offset = 0.0;
986 ctm.x_scale = native_mode_ar / mirror_mode_ar;
987 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5;
988 return ctm;
989 }
990
991 return ctm; // Same aspect ratio - return identity
992 }
993
994 OutputConfigurator::CoordinateTransformation
995 OutputConfigurator::GetExtendedModeCTM(
996 const OutputConfigurator::OutputSnapshot& output,
997 int framebuffer_width,
998 int framebuffer_height) {
999 CoordinateTransformation ctm; // Default to identity
1000 const ModeInfo* mode_info = GetModeInfo(output, output.selected_mode);
1001 DCHECK(mode_info);
1002 if (!mode_info)
1003 return ctm;
1004 // An example of how to calculate the CTM.
1005 // Suppose we have 2 monitors, the first one has size 1366 x 768.
1006 // The second one has size 2560 x 1600
1007 // The total size of framebuffer is 2560 x 2428
1008 // where 2428 = 768 + 60 (hidden gap) + 1600
1009 // and the sceond monitor is translated to Point (0, 828) in the
1010 // framebuffer.
1011 // X will first map input event location to [0, 2560) x [0, 2428),
1012 // then apply CTM on it.
1013 // So to compute CTM, for monitor1, we have
1014 // x_scale = (1366 - 1) / (2560 - 1)
1015 // x_offset = 0 / (2560 - 1)
1016 // y_scale = (768 - 1) / (2428 - 1)
1017 // y_offset = 0 / (2428 -1)
1018 // For Monitor 2, we have
1019 // x_scale = (2560 - 1) / (2560 - 1)
1020 // x_offset = 0 / (2560 - 1)
1021 // y_scale = (1600 - 1) / (2428 - 1)
1022 // y_offset = 828 / (2428 -1)
1023 // See the unittest OutputConfiguratorTest.CTMForMultiScreens.
1024 ctm.x_scale =
1025 static_cast<float>(mode_info->width - 1) / (framebuffer_width - 1);
1026 ctm.x_offset = static_cast<float>(output.x) / (framebuffer_width - 1);
1027 ctm.y_scale =
1028 static_cast<float>(mode_info->height - 1) / (framebuffer_height - 1);
1029 ctm.y_offset = static_cast<float>(output.y) / (framebuffer_height - 1);
1030 return ctm;
1031 }
1032
1033 float OutputConfigurator::GetMirroredDisplayAreaRatio( 941 float OutputConfigurator::GetMirroredDisplayAreaRatio(
1034 const OutputConfigurator::OutputSnapshot& output) { 942 const OutputConfigurator::OutputSnapshot& output) {
1035 float area_ratio = 1.0f; 943 float area_ratio = 1.0f;
1036 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode); 944 const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode);
1037 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode); 945 const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode);
1038 946
1039 if (!native_mode_info || !mirror_mode_info || 947 if (!native_mode_info || !mirror_mode_info ||
1040 native_mode_info->height == 0 || mirror_mode_info->height == 0 || 948 native_mode_info->height == 0 || mirror_mode_info->height == 0 ||
1041 native_mode_info->width == 0 || mirror_mode_info->width == 0) 949 native_mode_info->width == 0 || mirror_mode_info->width == 0)
1042 return area_ratio; 950 return area_ratio;
1043 951
1044 float width_ratio = static_cast<float>(mirror_mode_info->width) / 952 float width_ratio = static_cast<float>(mirror_mode_info->width) /
1045 static_cast<float>(native_mode_info->width); 953 static_cast<float>(native_mode_info->width);
1046 float height_ratio = static_cast<float>(mirror_mode_info->height) / 954 float height_ratio = static_cast<float>(mirror_mode_info->height) /
1047 static_cast<float>(native_mode_info->height); 955 static_cast<float>(native_mode_info->height);
1048 956
1049 area_ratio = width_ratio * height_ratio; 957 area_ratio = width_ratio * height_ratio;
1050 return area_ratio; 958 return area_ratio;
1051 } 959 }
1052 960
1053 } // namespace chromeos 961 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698