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

Side by Side Diff: ash/display/display_controller.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
« no previous file with comments | « ash/display/display_controller.h ('k') | ash/display/display_controller_unittest.cc » ('j') | 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 "ash/display/display_controller.h" 5 #include "ash/display/display_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <map> 9 #include <map>
10 10
(...skipping 17 matching lines...) Expand all
28 #include "ui/aura/client/capture_client.h" 28 #include "ui/aura/client/capture_client.h"
29 #include "ui/aura/client/focus_client.h" 29 #include "ui/aura/client/focus_client.h"
30 #include "ui/aura/client/screen_position_client.h" 30 #include "ui/aura/client/screen_position_client.h"
31 #include "ui/aura/root_window_transformer.h" 31 #include "ui/aura/root_window_transformer.h"
32 #include "ui/aura/window.h" 32 #include "ui/aura/window.h"
33 #include "ui/aura/window_event_dispatcher.h" 33 #include "ui/aura/window_event_dispatcher.h"
34 #include "ui/aura/window_property.h" 34 #include "ui/aura/window_property.h"
35 #include "ui/aura/window_tracker.h" 35 #include "ui/aura/window_tracker.h"
36 #include "ui/compositor/compositor.h" 36 #include "ui/compositor/compositor.h"
37 #include "ui/compositor/compositor_vsync_manager.h" 37 #include "ui/compositor/compositor_vsync_manager.h"
38 #include "ui/events/touch_ctm.h"
38 #include "ui/gfx/display.h" 39 #include "ui/gfx/display.h"
39 #include "ui/gfx/screen.h" 40 #include "ui/gfx/screen.h"
40 41
41 #if defined(OS_CHROMEOS) 42 #if defined(OS_CHROMEOS)
42 #include "base/sys_info.h" 43 #include "base/sys_info.h"
43 #include "base/time/time.h" 44 #include "base/time/time.h"
44 #if defined(USE_X11) 45 #if defined(USE_X11)
45 #include "ash/display/output_configurator_animation.h" 46 #include "ash/display/output_configurator_animation.h"
46 #include "chromeos/display/output_configurator.h" 47 #include "chromeos/display/output_configurator.h"
47 #include "ui/base/x/x11_util.h" 48 #include "ui/base/x/x11_util.h"
49 #include "ui/events/x/device_data_manager.h"
48 #include "ui/gfx/x/x11_types.h" 50 #include "ui/gfx/x/x11_types.h"
49 51
50 // Including this at the bottom to avoid other 52 // Including this at the bottom to avoid other
51 // potential conflict with chrome headers. 53 // potential conflict with chrome headers.
52 #include <X11/extensions/Xrandr.h> 54 #include <X11/extensions/Xrandr.h>
53 #undef RootWindow 55 #undef RootWindow
54 #endif // defined(USE_X11) 56 #endif // defined(USE_X11)
55 #endif // defined(OS_CHROMEOS) 57 #endif // defined(OS_CHROMEOS)
56 58
57 namespace ash { 59 namespace ash {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 127
126 internal::DisplayMode mode; 128 internal::DisplayMode mode;
127 if (GetDisplayManager()->GetSelectedModeForDisplayId(display.id(), &mode) && 129 if (GetDisplayManager()->GetSelectedModeForDisplayId(display.id(), &mode) &&
128 mode.refresh_rate > 0.0f) { 130 mode.refresh_rate > 0.0f) {
129 host->compositor()->vsync_manager()->SetAuthoritativeVSyncInterval( 131 host->compositor()->vsync_manager()->SetAuthoritativeVSyncInterval(
130 base::TimeDelta::FromMicroseconds( 132 base::TimeDelta::FromMicroseconds(
131 base::Time::kMicrosecondsPerSecond / mode.refresh_rate)); 133 base::Time::kMicrosecondsPerSecond / mode.refresh_rate));
132 } 134 }
133 } 135 }
134 136
137 #if defined(OS_CHROMEOS) && defined(USE_X11)
138 // This function computes the extended mode TouchCTM for |touch_display|.
139 // An example of how to calculate the extended CTM.
140 // Suppose we have 2 monitors, the first one has size 1366 x 768.
141 // The second one has size 2560 x 1600
142 // The total size of framebuffer is 2560 x 2428
143 // where 2428 = 768 + 60 (hidden gap) + 1600
144 // and the sceond monitor is translated to Point (0, 828) in the
145 // framebuffer.
146 // X will first map input event location to [0, 2560) x [0, 2428),
147 // Then the TouchCTM should map touch events from framebuffer space
148 // to root window space.
149 // For monitor1, we have
150 // x_scale = (1366 - 1) / (2560 - 1)
151 // x_offset = 0
152 // y_scale = (768 - 1) / (2428 - 1)
153 // y_offset = 0
154 // For Monitor 2, we have
155 // x_scale = (2560 - 1) / (2560 - 1)
156 // x_offset = 0
157 // y_scale = (1600 - 1) / (2428 - 1)
158 // y_offset = 0
159 // See DisplayControllerTest.TouchCTMExtendedMode for the test.
160 ui::TouchCTM GetExtendedModeTouchCTM(
161 const internal::DisplayInfo& touch_display,
162 const internal::DisplayInfo& second_display) {
163 ui::TouchCTM ctm;
164 float width = touch_display.bounds_in_native().width();
165 float height = touch_display.bounds_in_native().height();
166 // float origin_x = touch_display.bounds_in_native().origin().x();
167 // float origin_y = touch_display.bounds_in_native().origin().y();
168 float framebuffer_width = std::max<int>(
169 width, second_display.bounds_in_native().width());
170 float framebuffer_height =
171 height + chromeos::OutputConfigurator::kVerticalGap +
172 second_display.bounds_in_native().height();
173 ctm.x_scale = (width - 1) / (framebuffer_width - 1);
174 ctm.x_offset = 0;
175 ctm.y_scale = (height -1) / (framebuffer_height - 1);
176 ctm.y_offset = 0;
177 return ctm;
178 }
179
180 // This function computes the mirror mode TouchCTM for |touch_display|.
181 // When internal monitor is applied a resolution that does not have
182 // the same aspect ratio as its native resolution, there would be
183 // blank regions in the letterboxing/pillarboxing mode.
184 // The TouchCTM will make sure the touch events on the blank region
185 // have negative coordinates and touch events within the chrome region
186 // have the correct positive coordinates.
187 ui::TouchCTM GetMirrorModeTouchCTM(
188 const internal::DisplayInfo& touch_display) {
189 ui::TouchCTM ctm;
190 // For external monitor, assuming no letterboxing or pillarboxing
191 // and just use the default TouchCTM.
192 if (touch_display.id() != gfx::Display::InternalDisplayId())
193 return ctm;
194
195 float mirror_width = touch_display.bounds_in_native().width();
196 float mirror_height = touch_display.bounds_in_native().height();
197 float native_width = 0;
198 float native_height = 0;
199
200 internal::DisplayMode native_mode;
201 std::vector<internal::DisplayMode> modes = touch_display.display_modes();
202 for (size_t i = 0; i < modes.size(); i++) {
203 if (modes[i].native) {
204 native_width = modes[i].size.width();
205 native_height = modes[i].size.height();
206 break;
207 }
208 }
209
210 if (native_height == 0.0 || mirror_height == 0.0 ||
211 native_width == 0.0 || mirror_width == 0.0)
212 return ctm;
213
214 float native_ar = static_cast<float>(native_width) /
215 static_cast<float>(native_height);
216 float mirror_ar = static_cast<float>(mirror_width) /
217 static_cast<float>(mirror_height);
218
219 if (mirror_ar > native_ar) { // Letterboxing
220 ctm.x_scale = 1.0;
221 ctm.x_offset = 0.0;
222 ctm.y_scale = mirror_ar / native_ar;
223 ctm.y_offset = (1.0 / mirror_ar - 1.0 / native_ar) * 0.5 * mirror_width;
224 return ctm;
225 }
226
227 if (native_ar > mirror_ar) { // Pillarboxing
228 ctm.y_scale = 1.0;
229 ctm.y_offset = 0.0;
230 ctm.x_scale = native_ar / mirror_ar;
231 ctm.x_offset = (mirror_ar - native_ar) * 0.5 * mirror_height;
232 return ctm;
233 }
234
235 return ctm; // Same aspect ratio - return identity
236 }
237 #endif // defined(OS_CHROMEOS) && defined(USE_X11)
238
135 } // namespace 239 } // namespace
136 240
137 namespace internal { 241 namespace internal {
138 242
139 // A utility class to store/restore focused/active window 243 // A utility class to store/restore focused/active window
140 // when the display configuration has changed. 244 // when the display configuration has changed.
141 class FocusActivationStore { 245 class FocusActivationStore {
142 public: 246 public:
143 FocusActivationStore() 247 FocusActivationStore()
144 : activation_client_(NULL), 248 : activation_client_(NULL),
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 DCHECK(controller); 377 DCHECK(controller);
274 delete controller; 378 delete controller;
275 } 379 }
276 } 380 }
277 381
278 void DisplayController::InitPrimaryDisplay() { 382 void DisplayController::InitPrimaryDisplay() {
279 const gfx::Display& primary_candidate = 383 const gfx::Display& primary_candidate =
280 GetDisplayManager()->GetPrimaryDisplayCandidate(); 384 GetDisplayManager()->GetPrimaryDisplayCandidate();
281 primary_display_id = primary_candidate.id(); 385 primary_display_id = primary_candidate.id();
282 AddWindowTreeHostForDisplay(primary_candidate); 386 AddWindowTreeHostForDisplay(primary_candidate);
387 UpdateTouchCTM();
283 } 388 }
284 389
285 void DisplayController::InitSecondaryDisplays() { 390 void DisplayController::InitSecondaryDisplays() {
286 internal::DisplayManager* display_manager = GetDisplayManager(); 391 internal::DisplayManager* display_manager = GetDisplayManager();
287 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { 392 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
288 const gfx::Display& display = display_manager->GetDisplayAt(i); 393 const gfx::Display& display = display_manager->GetDisplayAt(i);
289 if (primary_display_id != display.id()) { 394 if (primary_display_id != display.id()) {
290 aura::WindowTreeHost* host = AddWindowTreeHostForDisplay(display); 395 aura::WindowTreeHost* host = AddWindowTreeHostForDisplay(display);
291 internal::RootWindowController::CreateForSecondaryDisplay(host); 396 internal::RootWindowController::CreateForSecondaryDisplay(host);
292 } 397 }
293 } 398 }
294 UpdateHostWindowNames(); 399 UpdateHostWindowNames();
400 UpdateTouchCTM();
295 } 401 }
296 402
297 void DisplayController::AddObserver(Observer* observer) { 403 void DisplayController::AddObserver(Observer* observer) {
298 observers_.AddObserver(observer); 404 observers_.AddObserver(observer);
299 } 405 }
300 406
301 void DisplayController::RemoveObserver(Observer* observer) { 407 void DisplayController::RemoveObserver(Observer* observer) {
302 observers_.RemoveObserver(observer); 408 observers_.RemoveObserver(observer);
303 } 409 }
304 410
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 primary_id == gfx::Display::kInvalidDisplayID ? 788 primary_id == gfx::Display::kInvalidDisplayID ?
683 pair.first : primary_id); 789 pair.first : primary_id);
684 // Update the primary_id in case the above call is 790 // Update the primary_id in case the above call is
685 // ignored. Happens when a) default layout's primary id 791 // ignored. Happens when a) default layout's primary id
686 // doesn't exist, or b) the primary_id has already been 792 // doesn't exist, or b) the primary_id has already been
687 // set to the same and didn't update it. 793 // set to the same and didn't update it.
688 layout_store->UpdatePrimaryDisplayId( 794 layout_store->UpdatePrimaryDisplayId(
689 pair, Shell::GetScreen()->GetPrimaryDisplay().id()); 795 pair, Shell::GetScreen()->GetPrimaryDisplay().id());
690 } 796 }
691 } 797 }
692 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); 798 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged());
oshima 2014/03/13 20:43:54 Looks like new code don't have to be in DisplayCon
Yufeng Shen (Slow to review) 2014/03/13 20:55:46 but is OnDisplayConfigurationChanged() is always c
oshima 2014/03/13 21:34:48 It's always called when display configuration chan
693 UpdateHostWindowNames(); 799 UpdateHostWindowNames();
694 EnsurePointerInDisplays(); 800 EnsurePointerInDisplays();
801 UpdateTouchCTM();
802 }
803
804 void DisplayController::UpdateTouchCTM() {
805 #if defined(OS_CHROMEOS) && defined(USE_X11)
806 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
807 device_manager->ClearTouchCTM();
808 device_manager->ClearTouchDeviceToDisplayMap();
809
810 // Display IDs and DisplayInfo for mirror or extended mode.
811 int64 display1_id = gfx::Display::kInvalidDisplayID;
812 int64 display2_id = gfx::Display::kInvalidDisplayID;
813 internal::DisplayInfo display1;
814 internal::DisplayInfo display2;
815 // Display ID and DisplayInfo for single display mode.
816 int64 single_display_id = gfx::Display::kInvalidDisplayID;
817 internal::DisplayInfo single_display;
818
819 ui::OutputState output_state =
820 Shell::GetInstance()->output_configurator()->output_state();
821 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR ||
822 output_state == ui::OUTPUT_STATE_DUAL_EXTENDED) {
823 DisplayIdPair id_pair = GetDisplayManager()->GetCurrentDisplayIdPair();
824 display1_id = id_pair.first;
825 display2_id = id_pair.second;
826 if (display1_id == gfx::Display::kInvalidDisplayID ||
827 display2_id == gfx::Display::kInvalidDisplayID)
828 return;
829 display1 = GetDisplayManager()->GetDisplayInfo(display1_id);
830 display2 = GetDisplayManager()->GetDisplayInfo(display2_id);
831 } else {
832 single_display_id = GetDisplayManager()->first_display_id();
833 if (single_display_id == gfx::Display::kInvalidDisplayID)
834 return;
835 single_display = GetDisplayManager()->GetDisplayInfo(single_display_id);
836 }
837
838 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR) {
839 std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
840 // In mirror mode, both displays share the same root window so
841 // both display ids are associated with the root window.
842 for (; it != root_windows_.end(); it++)
843 it->second->GetHost()->UpdateDisplayID(display1_id, display2_id);
844 // Update the associated display id and TouchCTM in device manager
845 // if the display is a touch device.
846 if (display1.touch_device_id() != 0) {
847 device_manager->MapTouchDeviceToDisplay(display1.touch_device_id(),
848 display1.id());
849 device_manager->SetTouchCTM(display1.touch_device_id(),
850 GetMirrorModeTouchCTM(display1));
851 }
852 if (display2.touch_device_id() != 0) {
853 device_manager->MapTouchDeviceToDisplay(display2.touch_device_id(),
854 display2.id());
855 device_manager->SetTouchCTM(display2.touch_device_id(),
856 GetMirrorModeTouchCTM(display2));
857 }
858 return;
859 }
860
861 if (output_state == ui::OUTPUT_STATE_DUAL_EXTENDED) {
862 std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
863 // In extended mode, each display has one associated root window.
864 for (; it != root_windows_.end(); it++) {
865 if (it->first == display1_id) {
866 it->second->GetHost()->UpdateDisplayID(display1_id,
867 gfx::Display::kInvalidDisplayID);
868 } else if (it->first == display2_id) {
869 it->second->GetHost()->UpdateDisplayID(display2_id,
870 gfx::Display::kInvalidDisplayID);
871 }
872 }
873 // Update the associated display id and TouchCTM in device manager
874 // if the display is a touch device.
875 if (display1.touch_device_id() != 0) {
876 device_manager->MapTouchDeviceToDisplay(display1.touch_device_id(),
877 display1.id());
878 device_manager->SetTouchCTM(display1.touch_device_id(),
879 GetExtendedModeTouchCTM(display1, display2));
880 }
881 if (display2.touch_device_id() != 0) {
882 device_manager->MapTouchDeviceToDisplay(display2.touch_device_id(),
883 display2.id());
884 device_manager->SetTouchCTM(display2.touch_device_id(),
885 GetExtendedModeTouchCTM(display2, display1));
886 }
887 return;
888 }
889
890 // Single display mode. The root window has one associated display id.
891 std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
892 for (; it != root_windows_.end(); it++) {
893 if (it->first == single_display.id()) {
894 it->second->GetHost()->UpdateDisplayID(single_display.id(),
895 gfx::Display::kInvalidDisplayID);
896 }
897 }
898 // If the display is a touch display, we add a deafult TouchCTM to the
899 // according root window.
900 if (single_display.touch_device_id() != 0) {
901 device_manager->MapTouchDeviceToDisplay(single_display.touch_device_id(),
902 single_display.id());
903 device_manager->SetTouchCTM(single_display.touch_device_id(),
904 ui::TouchCTM());
905 }
906 #endif
695 } 907 }
696 908
697 aura::WindowTreeHost* DisplayController::AddWindowTreeHostForDisplay( 909 aura::WindowTreeHost* DisplayController::AddWindowTreeHostForDisplay(
698 const gfx::Display& display) { 910 const gfx::Display& display) {
699 static int host_count = 0; 911 static int host_count = 0;
700 const internal::DisplayInfo& display_info = 912 const internal::DisplayInfo& display_info =
701 GetDisplayManager()->GetDisplayInfo(display.id()); 913 GetDisplayManager()->GetDisplayInfo(display.id());
702 const gfx::Rect& bounds_in_native = display_info.bounds_in_native(); 914 const gfx::Rect& bounds_in_native = display_info.bounds_in_native();
703 aura::WindowTreeHost* host = 915 aura::WindowTreeHost* host =
704 Shell::GetInstance()->window_tree_host_factory()->CreateWindowTreeHost( 916 Shell::GetInstance()->window_tree_host_factory()->CreateWindowTreeHost(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 std::string name = 954 std::string name =
743 root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; 955 root_windows[i] == primary ? "aura_root_0" : "aura_root_x";
744 gfx::AcceleratedWidget xwindow = 956 gfx::AcceleratedWidget xwindow =
745 root_windows[i]->GetHost()->GetAcceleratedWidget(); 957 root_windows[i]->GetHost()->GetAcceleratedWidget();
746 XStoreName(gfx::GetXDisplay(), xwindow, name.c_str()); 958 XStoreName(gfx::GetXDisplay(), xwindow, name.c_str());
747 } 959 }
748 #endif 960 #endif
749 } 961 }
750 962
751 } // namespace ash 963 } // namespace ash
OLDNEW
« no previous file with comments | « ash/display/display_controller.h ('k') | ash/display/display_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698