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

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: 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 "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 11 matching lines...) Expand all
22 #include "ash/shell.h" 22 #include "ash/shell.h"
23 #include "ash/shell_delegate.h" 23 #include "ash/shell_delegate.h"
24 #include "ash/wm/coordinate_conversion.h" 24 #include "ash/wm/coordinate_conversion.h"
25 #include "base/command_line.h" 25 #include "base/command_line.h"
26 #include "base/strings/stringprintf.h" 26 #include "base/strings/stringprintf.h"
27 #include "ui/aura/client/activation_client.h" 27 #include "ui/aura/client/activation_client.h"
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/touch_ctm.h"
32 #include "ui/aura/window.h" 33 #include "ui/aura/window.h"
33 #include "ui/aura/window_event_dispatcher.h" 34 #include "ui/aura/window_event_dispatcher.h"
34 #include "ui/aura/window_property.h" 35 #include "ui/aura/window_property.h"
35 #include "ui/aura/window_tracker.h" 36 #include "ui/aura/window_tracker.h"
36 #include "ui/compositor/compositor.h" 37 #include "ui/compositor/compositor.h"
37 #include "ui/compositor/compositor_vsync_manager.h" 38 #include "ui/compositor/compositor_vsync_manager.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)
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 internal::DisplayMode mode; 127 internal::DisplayMode mode;
127 if (GetDisplayManager()->GetSelectedModeForDisplayId(display.id(), &mode) && 128 if (GetDisplayManager()->GetSelectedModeForDisplayId(display.id(), &mode) &&
128 mode.refresh_rate > 0.0f) { 129 mode.refresh_rate > 0.0f) {
129 dispatcher->host()->compositor()->vsync_manager()-> 130 dispatcher->host()->compositor()->vsync_manager()->
130 SetAuthoritativeVSyncInterval( 131 SetAuthoritativeVSyncInterval(
131 base::TimeDelta::FromMicroseconds( 132 base::TimeDelta::FromMicroseconds(
132 base::Time::kMicrosecondsPerSecond / mode.refresh_rate)); 133 base::Time::kMicrosecondsPerSecond / mode.refresh_rate));
133 } 134 }
134 } 135 }
135 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 // So to compute CTM, for monitor1, we have
148 // x_scale = (1366 - 1) / (2560 - 1)
149 // x_offset = 0
150 // y_scale = (768 - 1) / (2428 - 1)
151 // y_offset = 0
152 // For Monitor 2, we have
153 // x_scale = (2560 - 1) / (2560 - 1)
154 // x_offset = 0
155 // y_scale = (1600 - 1) / (2428 - 1)
156 // y_offset = 828
157 // See DisplayControllerTest.TouchCTMExtendedMode for the test.
158 aura::TouchCTM GetExtendedModeTouchCTM(
159 const internal::DisplayInfo& touch_display,
160 const internal::DisplayInfo& second_display) {
161 aura::TouchCTM ctm;
162 float width = touch_display.bounds_in_native().width();
163 float height = touch_display.bounds_in_native().height();
164 float origin_x = touch_display.bounds_in_native().origin().x();
165 float origin_y = touch_display.bounds_in_native().origin().y();
166 float framebuffer_width = std::max<int>(
167 width, second_display.bounds_in_native().width());
168 float framebuffer_height =
169 height + chromeos::OutputConfigurator::kVerticalGap +
170 second_display.bounds_in_native().height();
171 ctm.x_scale = (width - 1) / (framebuffer_width - 1);
172 ctm.x_offset = origin_x;
173 ctm.y_scale = (height -1) / (framebuffer_height - 1);
174 ctm.y_offset = origin_y;
175 return ctm;
176 }
177
178 // This function computes the mirror mode TouchCTM for |touch_display|.
179 // When internal monitor is applied a resolution that does not have
180 // the same aspect ratio as its native resolution, there would be
181 // blank regions in the letterboxing/pillarboxing mode.
182 // The TouchCTM will make sure the touch events on the blank region
183 // have negative coordinates and touch events within the chrome region
184 // have the correct positive coordinates.
185 aura::TouchCTM GetMirrorModeTouchCTM(
186 const internal::DisplayInfo& touch_display) {
187 aura::TouchCTM ctm;
188 // For external monitor, assuming no letterboxing or pillarboxing
189 // and just use the default TouchCTM.
190 if (touch_display.id() != gfx::Display::InternalDisplayId())
191 return ctm;
192
193 float mirror_width = touch_display.bounds_in_native().width();
194 float mirror_height = touch_display.bounds_in_native().height();
195 float native_width = 0;
196 float native_height = 0;
197
198 internal::DisplayMode native_mode;
199 std::vector<internal::DisplayMode> modes = touch_display.display_modes();
200 for (size_t i = 0; i < modes.size(); i++) {
201 if (modes[i].native) {
202 native_width = modes[i].size.width();
203 native_height = modes[i].size.height();
204 break;
205 }
206 }
207
208 if (native_height == 0.0 || mirror_height == 0.0 ||
209 native_width == 0.0 || mirror_width == 0.0)
210 return ctm;
211
212 float native_ar = static_cast<float>(native_width) /
213 static_cast<float>(native_height);
214 float mirror_ar = static_cast<float>(mirror_width) /
215 static_cast<float>(mirror_height);
216
217 if (mirror_ar > native_ar) { // Letterboxing
218 ctm.x_scale = 1.0;
219 ctm.x_offset = 0.0;
220 ctm.y_scale = mirror_ar / native_ar;
221 ctm.y_offset = (1.0 / mirror_ar - 1.0 / native_ar) * 0.5 * mirror_width;
222 return ctm;
223 }
224
225 if (native_ar > mirror_ar) { // Pillarboxing
226 ctm.y_scale = 1.0;
227 ctm.y_offset = 0.0;
228 ctm.x_scale = native_ar / mirror_ar;
229 ctm.x_offset = (mirror_ar - native_ar) * 0.5 * mirror_height;
230 return ctm;
231 }
232
233 return ctm; // Same aspect ratio - return identity
234 }
235 #endif
236
136 } // namespace 237 } // namespace
137 238
138 namespace internal { 239 namespace internal {
139 240
140 // A utility class to store/restore focused/active window 241 // A utility class to store/restore focused/active window
141 // when the display configuration has changed. 242 // when the display configuration has changed.
142 class FocusActivationStore { 243 class FocusActivationStore {
143 public: 244 public:
144 FocusActivationStore() 245 FocusActivationStore()
145 : activation_client_(NULL), 246 : activation_client_(NULL),
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 DCHECK(controller); 375 DCHECK(controller);
275 delete controller; 376 delete controller;
276 } 377 }
277 } 378 }
278 379
279 void DisplayController::InitPrimaryDisplay() { 380 void DisplayController::InitPrimaryDisplay() {
280 const gfx::Display& primary_candidate = 381 const gfx::Display& primary_candidate =
281 GetDisplayManager()->GetPrimaryDisplayCandidate(); 382 GetDisplayManager()->GetPrimaryDisplayCandidate();
282 primary_display_id = primary_candidate.id(); 383 primary_display_id = primary_candidate.id();
283 AddRootWindowForDisplay(primary_candidate); 384 AddRootWindowForDisplay(primary_candidate);
385 UpdateTouchCTM();
284 } 386 }
285 387
286 void DisplayController::InitSecondaryDisplays() { 388 void DisplayController::InitSecondaryDisplays() {
287 internal::DisplayManager* display_manager = GetDisplayManager(); 389 internal::DisplayManager* display_manager = GetDisplayManager();
288 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { 390 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
289 const gfx::Display& display = display_manager->GetDisplayAt(i); 391 const gfx::Display& display = display_manager->GetDisplayAt(i);
290 if (primary_display_id != display.id()) { 392 if (primary_display_id != display.id()) {
291 aura::WindowEventDispatcher* dispatcher = 393 aura::WindowEventDispatcher* dispatcher =
292 AddRootWindowForDisplay(display); 394 AddRootWindowForDisplay(display);
293 internal::RootWindowController::CreateForSecondaryDisplay(dispatcher); 395 internal::RootWindowController::CreateForSecondaryDisplay(dispatcher);
294 } 396 }
295 } 397 }
296 UpdateHostWindowNames(); 398 UpdateHostWindowNames();
399 UpdateTouchCTM();
297 } 400 }
298 401
299 void DisplayController::AddObserver(Observer* observer) { 402 void DisplayController::AddObserver(Observer* observer) {
300 observers_.AddObserver(observer); 403 observers_.AddObserver(observer);
301 } 404 }
302 405
303 void DisplayController::RemoveObserver(Observer* observer) { 406 void DisplayController::RemoveObserver(Observer* observer) {
304 observers_.RemoveObserver(observer); 407 observers_.RemoveObserver(observer);
305 } 408 }
306 409
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 // ignored. Happens when a) default layout's primary id 797 // ignored. Happens when a) default layout's primary id
695 // doesn't exist, or b) the primary_id has already been 798 // doesn't exist, or b) the primary_id has already been
696 // set to the same and didn't update it. 799 // set to the same and didn't update it.
697 layout_store->UpdatePrimaryDisplayId( 800 layout_store->UpdatePrimaryDisplayId(
698 pair, Shell::GetScreen()->GetPrimaryDisplay().id()); 801 pair, Shell::GetScreen()->GetPrimaryDisplay().id());
699 } 802 }
700 } 803 }
701 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); 804 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged());
702 UpdateHostWindowNames(); 805 UpdateHostWindowNames();
703 EnsurePointerInDisplays(); 806 EnsurePointerInDisplays();
807 UpdateTouchCTM();
808 }
809
810 void DisplayController::UpdateTouchCTM() {
811 #if defined(OS_CHROMEOS) && defined(USE_X11)
812 // Clear all the old TouchCTM on all the root windows.
813 std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
814 for (; it != root_windows_.end(); it++)
815 it->second->GetDispatcher()->host()->ClearTouchCTM();
816
817 ui::OutputState output_state =
818 Shell::GetInstance()->output_configurator()->output_state();
819 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR ||
820 output_state == ui::OUTPUT_STATE_DUAL_EXTENDED) {
821 DisplayIdPair id_pair = GetDisplayManager()->GetCurrentDisplayIdPair();
822 internal::DisplayInfo display1 =
823 GetDisplayManager()->GetDisplayInfo(id_pair.first);
824 internal::DisplayInfo display2 =
825 GetDisplayManager()->GetDisplayInfo(id_pair.second);
826 // For mirror mode, there is one root window shared by two displays.
827 // We add the TouchCTM of the touch display to the only one root window.
828 // For extended mode, there is one root window for each display.
829 // We add the TouchCTM of the touch display to the according root window.
830 if (display1.id() != gfx::Display::kInvalidDisplayID &&
831 display1.touch_device_id() != 0) {
832 std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
833 for (; it != root_windows_.end(); it++) {
834 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR) {
835 it->second->GetDispatcher()->host()->SetTouchCTM(
836 display1.touch_device_id(),
837 GetMirrorModeTouchCTM(display1));
838 } else if (output_state == ui::OUTPUT_STATE_DUAL_EXTENDED &&
839 it->first == display1.id()) {
840 it->second->GetDispatcher()->host()->SetTouchCTM(
841 display1.touch_device_id(),
842 GetExtendedModeTouchCTM(display1, display2));
843 }
844 }
845 }
846
847 if (display2.id() != gfx::Display::kInvalidDisplayID &&
848 display2.touch_device_id() != 0) {
849 std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
850 for (; it != root_windows_.end(); it++) {
851 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR) {
852 it->second->GetDispatcher()->host()->SetTouchCTM(
853 display2.touch_device_id(),
854 GetMirrorModeTouchCTM(display2));
855 } else if (output_state == ui::OUTPUT_STATE_DUAL_EXTENDED &&
856 it->first == display2.id()) {
857 it->second->GetDispatcher()->host()->SetTouchCTM(
858 display2.touch_device_id(),
859 GetExtendedModeTouchCTM(display2, display1));
860 }
861 }
862 }
863 } else {
864 // Single display mode. If the display is a touch display, we add a deafult
865 // TouchCTM to the according root window.
866 int64 display_id = GetDisplayManager()->first_display_id();
867 if (display_id != gfx::Display::kInvalidDisplayID) {
868 internal::DisplayInfo display =
869 GetDisplayManager()->GetDisplayInfo(display_id);
870 std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
871 for (; it != root_windows_.end(); it++) {
872 if (it->first == display_id && display.touch_device_id() != 0) {
873 it->second->GetDispatcher()->host()->SetTouchCTM(
874 display.touch_device_id(),
875 aura::TouchCTM());
876 }
877 }
878 }
879 }
880 #endif
704 } 881 }
705 882
706 aura::WindowEventDispatcher* DisplayController::AddRootWindowForDisplay( 883 aura::WindowEventDispatcher* DisplayController::AddRootWindowForDisplay(
707 const gfx::Display& display) { 884 const gfx::Display& display) {
708 static int dispatcher_count = 0; 885 static int dispatcher_count = 0;
709 const internal::DisplayInfo& display_info = 886 const internal::DisplayInfo& display_info =
710 GetDisplayManager()->GetDisplayInfo(display.id()); 887 GetDisplayManager()->GetDisplayInfo(display.id());
711 const gfx::Rect& bounds_in_native = display_info.bounds_in_native(); 888 const gfx::Rect& bounds_in_native = display_info.bounds_in_native();
712 aura::WindowEventDispatcher::CreateParams params(bounds_in_native); 889 aura::WindowEventDispatcher::CreateParams params(bounds_in_native);
713 params.host = Shell::GetInstance()->window_tree_host_factory()-> 890 params.host = Shell::GetInstance()->window_tree_host_factory()->
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 std::string name = 932 std::string name =
756 root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; 933 root_windows[i] == primary ? "aura_root_0" : "aura_root_x";
757 gfx::AcceleratedWidget xwindow = 934 gfx::AcceleratedWidget xwindow =
758 root_windows[i]->GetDispatcher()->host()->GetAcceleratedWidget(); 935 root_windows[i]->GetDispatcher()->host()->GetAcceleratedWidget();
759 XStoreName(gfx::GetXDisplay(), xwindow, name.c_str()); 936 XStoreName(gfx::GetXDisplay(), xwindow, name.c_str());
760 } 937 }
761 #endif 938 #endif
762 } 939 }
763 940
764 } // namespace ash 941 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698