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

Side by Side Diff: ash/touch/touch_transformer_controller.cc

Issue 191223007: Move touch CTM from X into Chrome (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: move the logic of if a touch event should be dispatched to a root window into CanDispatchEvent() Created 6 years, 7 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
(Empty)
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/touch/touch_transformer_controller.h"
6
7 #include "ash/display/display_controller.h"
8 #include "ash/display/display_manager.h"
9 #include "ash/shell.h"
10 #include "ui/aura/window_tree_host.h"
11 #include "ui/display/chromeos/display_configurator.h"
12 #include "ui/display/types/chromeos/display_snapshot.h"
13 #include "ui/events/x/device_data_manager.h"
14
15 namespace ash {
16
17 namespace {
18
19 DisplayManager* GetDisplayManager() {
20 return Shell::GetInstance()->display_manager();
21 }
22
23 } // namespace
24
25 // This function computes the extended mode TouchTransformer for
26 // |touch_display|. The TouchTransformer maps the touch event position
27 // from framebuffer size to the display size.
28 ui::TouchTransformer
29 TouchTransformerController::GetExtendedModeTouchTransformer(
30 const DisplayInfo& touch_display, const gfx::Size& fb_size) {
31 ui::TouchTransformer ctm;
32 if (touch_display.touch_device_id() == 0 ||
33 fb_size.width() == 0.0 ||
34 fb_size.height() == 0.0)
35 return ctm;
36 float width = touch_display.bounds_in_native().width();
37 float height = touch_display.bounds_in_native().height();
38 ctm.x_scale = width / fb_size.width();
39 ctm.x_offset = 0;
40 ctm.y_scale = height / fb_size.height();
41 ctm.y_offset = 0;
42 return ctm;
43 }
44
45 bool TouchTransformerController::ShouldComputeMirrorModeTouchTransformer(
46 const DisplayInfo& touch_display) {
47 if (force_compute_mirror_mode_touch_transformer_)
48 return true;
49
50 if (touch_display.touch_device_id() == 0)
51 return false;
52
53 const ui::DisplayConfigurator::DisplayState* state = NULL;
54 const std::vector<ui::DisplayConfigurator::DisplayState>& cached_displays =
55 Shell::GetInstance()->display_configurator()->cached_displays();
56 for (size_t i = 0; i < cached_displays.size(); i++) {
57 if (cached_displays[i].touch_device_id == touch_display.touch_device_id()) {
58 state = &cached_displays[i];
59 break;
60 }
61 }
62
63 if (!state || state->mirror_mode == state->display->native_mode() ||
64 !state->display->is_aspect_preserving_scaling()) {
65 return false;
66 }
67 return true;
68 }
69
70 // This function computes the mirror mode TouchTransformer for |touch_display|.
71 // When internal monitor is applied a resolution that does not have
72 // the same aspect ratio as its native resolution, there would be
73 // blank regions in the letterboxing/pillarboxing mode.
74 // The TouchTransformer will make sure the touch events on the blank region
75 // have negative coordinates and touch events within the chrome region
76 // have the correct positive coordinates.
77 ui::TouchTransformer TouchTransformerController::GetMirrorModeTouchTransformer(
78 const DisplayInfo& touch_display) {
79 ui::TouchTransformer ctm;
80 if (!ShouldComputeMirrorModeTouchTransformer(touch_display))
81 return ctm;
82
83 float mirror_width = touch_display.bounds_in_native().width();
84 float mirror_height = touch_display.bounds_in_native().height();
85 float native_width = 0;
86 float native_height = 0;
87
88 std::vector<DisplayMode> modes = touch_display.display_modes();
89 for (size_t i = 0; i < modes.size(); i++) {
90 if (modes[i].native) {
91 native_width = modes[i].size.width();
92 native_height = modes[i].size.height();
93 break;
94 }
95 }
96
97 if (native_height == 0.0 || mirror_height == 0.0 ||
98 native_width == 0.0 || mirror_width == 0.0)
99 return ctm;
100
101 float native_ar = static_cast<float>(native_width) /
102 static_cast<float>(native_height);
103 float mirror_ar = static_cast<float>(mirror_width) /
104 static_cast<float>(mirror_height);
105
106 if (mirror_ar > native_ar) { // Letterboxing
107 ctm.y_scale = mirror_ar / native_ar;
108 ctm.y_offset = (1.0 / mirror_ar - 1.0 / native_ar) * 0.5 * mirror_width;
109 return ctm;
110 }
111
112 if (native_ar > mirror_ar) { // Pillarboxing
113 ctm.x_scale = native_ar / mirror_ar;
114 ctm.x_offset = (mirror_ar - native_ar) * 0.5 * mirror_height;
115 return ctm;
116 }
117
118 return ctm; // Same aspect ratio - return identity
119 }
120
121 TouchTransformerController::TouchTransformerController() :
122 force_compute_mirror_mode_touch_transformer_ (false) {
123 Shell::GetInstance()->display_controller()->AddObserver(this);
124 }
125
126 TouchTransformerController::~TouchTransformerController() {
127 Shell::GetInstance()->display_controller()->RemoveObserver(this);
128 }
129
130 void TouchTransformerController::UpdateTouchTransformer() {
131 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
132 device_manager->ClearTouchTransformerRecord();
133
134 // Display IDs and DisplayInfo for mirror or extended mode.
135 int64 display1_id = gfx::Display::kInvalidDisplayID;
136 int64 display2_id = gfx::Display::kInvalidDisplayID;
137 DisplayInfo display1;
138 DisplayInfo display2;
139 // Display ID and DisplayInfo for single display mode.
140 int64 single_display_id = gfx::Display::kInvalidDisplayID;
141 DisplayInfo single_display;
142
143 DisplayController* display_controller =
144 Shell::GetInstance()->display_controller();
145 ui::MultipleDisplayState display_state =
146 Shell::GetInstance()->display_configurator()->display_state();
oshima 2014/05/01 09:35:42 what value does this return for software mirror mo
Yufeng Shen (Slow to review) 2014/05/01 22:43:48 hmm, I actually don't know what is software mirror
oshima 2014/05/01 23:07:56 I just want to make sure things doesn't break in s
ynovikov 2014/05/01 23:16:10 AFAIK, the old code would treat software mirror mo
Yufeng Shen (Slow to review) 2014/05/02 00:03:39 no, touch events from second display also gets dis
147 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR ||
148 display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {
149 DisplayIdPair id_pair = GetDisplayManager()->GetCurrentDisplayIdPair();
150 display1_id = id_pair.first;
151 display2_id = id_pair.second;
152 if (display1_id == gfx::Display::kInvalidDisplayID ||
153 display2_id == gfx::Display::kInvalidDisplayID)
154 return;
oshima 2014/05/01 09:35:42 I believe this should not happen. Did you hit this
Yufeng Shen (Slow to review) 2014/05/01 22:43:48 Done.
155 display1 = GetDisplayManager()->GetDisplayInfo(display1_id);
156 display2 = GetDisplayManager()->GetDisplayInfo(display2_id);
157 } else {
158 single_display_id = GetDisplayManager()->first_display_id();
159 if (single_display_id == gfx::Display::kInvalidDisplayID)
160 return;
oshima 2014/05/01 09:35:42 same here
Yufeng Shen (Slow to review) 2014/05/01 22:43:48 Done.
161 single_display = GetDisplayManager()->GetDisplayInfo(single_display_id);
162 }
163
164 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) {
165 // In mirror mode, both displays share the same root window so
166 // both display ids are associated with the root window.
167 aura::Window* root = display_controller->GetPrimaryRootWindow();
168 root->GetHost()->UpdateDisplayID(display1_id, display2_id);
169 device_manager->UpdateTouchInfoForDisplay(
170 display1_id,
171 display1.touch_device_id(),
172 GetMirrorModeTouchTransformer(display1));
173 device_manager->UpdateTouchInfoForDisplay(
174 display2_id,
175 display2.touch_device_id(),
176 GetMirrorModeTouchTransformer(display2));
177 return;
178 }
179
180 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {
181 // In extended mode, each display is associated with one root window.
182 aura::Window* root1 =
183 display_controller->GetRootWindowForDisplayId(display1_id);
184 aura::Window* root2 =
185 display_controller->GetRootWindowForDisplayId(display2_id);
186 root1->GetHost()->UpdateDisplayID(display1_id,
187 gfx::Display::kInvalidDisplayID);
188 root2->GetHost()->UpdateDisplayID(display2_id,
189 gfx::Display::kInvalidDisplayID);
190
191 gfx::Size fb_size =
192 Shell::GetInstance()->display_configurator()->framebuffer_size();
193 device_manager->UpdateTouchInfoForDisplay(
194 display1_id,
195 display1.touch_device_id(),
196 GetExtendedModeTouchTransformer(display1, fb_size));
197 device_manager->UpdateTouchInfoForDisplay(
198 display2_id,
199 display2.touch_device_id(),
200 GetExtendedModeTouchTransformer(display2, fb_size));
201 return;
202 }
203
204 // Single display mode. The root window has one associated display id.
205 aura::Window* root =
206 display_controller->GetRootWindowForDisplayId(single_display.id());
207 root->GetHost()->UpdateDisplayID(single_display.id(),
208 gfx::Display::kInvalidDisplayID);
209 device_manager->UpdateTouchInfoForDisplay(single_display_id,
210 single_display.touch_device_id(),
211 ui::TouchTransformer());
212 }
213
214 void TouchTransformerController::OnDisplaysInitialized() {
215 UpdateTouchTransformer();
216 }
217
218 void TouchTransformerController::OnDisplayConfigurationChanged() {
219 UpdateTouchTransformer();
220 }
221
222 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698