diff options
author | dnicoara <dnicoara@chromium.org> | 2014-10-30 12:53:39 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-30 19:54:33 +0000 |
commit | 8c3bd1e68124be19b17420144b4b76ece0c87035 (patch) | |
tree | 4286ec8c26b28b69769c9eb85ed375dd616a0dee /ash/touch | |
parent | 636e0eb369b639e074068fc1a82fe32f7cc6f082 (diff) | |
download | chromium_src-8c3bd1e68124be19b17420144b4b76ece0c87035.zip chromium_src-8c3bd1e68124be19b17420144b4b76ece0c87035.tar.gz chromium_src-8c3bd1e68124be19b17420144b4b76ece0c87035.tar.bz2 |
Refactor TouchTransformerConverter to allow support for Ozone
In Ozone the touch events are received in device coordinates. This
change consolidates the different transformations into one function and
makes it use the touchscreen size when computing the transformation for
Ozone and the framebuffer size for X11.
BUG=425258
TESTS=Manually verified that X11 in single, mirror, extended and docked
mode work with external touchscreen.
Review URL: https://codereview.chromium.org/688183002
Cr-Commit-Position: refs/heads/master@{#302135}
Diffstat (limited to 'ash/touch')
-rw-r--r-- | ash/touch/touch_transformer_controller.cc | 142 | ||||
-rw-r--r-- | ash/touch/touch_transformer_controller.h | 24 | ||||
-rw-r--r-- | ash/touch/touch_transformer_controller_unittest.cc | 75 |
3 files changed, 137 insertions, 104 deletions
diff --git a/ash/touch/touch_transformer_controller.cc b/ash/touch/touch_transformer_controller.cc index d9aed0e..e093863 100644 --- a/ash/touch/touch_transformer_controller.cc +++ b/ash/touch/touch_transformer_controller.cc @@ -62,83 +62,51 @@ double TouchTransformerController::GetTouchResolutionScale( return ratio; } -// This function computes the extended mode TouchTransformer for -// |touch_display|. The TouchTransformer maps the touch event position -// from framebuffer size to the display size. -gfx::Transform -TouchTransformerController::GetExtendedModeTouchTransformer( - const DisplayInfo& touch_display, const gfx::Size& fb_size) const { - gfx::Transform ctm; - if (touch_display.touch_device_id() == 0u || fb_size.width() == 0.0 || - fb_size.height() == 0.0) - return ctm; - float width = touch_display.bounds_in_native().width(); - float height = touch_display.bounds_in_native().height(); - ctm.Scale(width / fb_size.width(), height / fb_size.height()); - return ctm; -} - -bool TouchTransformerController::ShouldComputeMirrorModeTouchTransformer( - const DisplayInfo& touch_display) const { - if (force_compute_mirror_mode_touch_transformer_) - return true; - - if (touch_display.touch_device_id() == 0u) - return false; - - if (touch_display.size_in_pixel() == touch_display.GetNativeModeSize() || - !touch_display.is_aspect_preserving_scaling()) { - return false; - } - - return true; -} +gfx::Transform TouchTransformerController::GetTouchTransform( + const DisplayInfo& display, + const ui::TouchscreenDevice& touchscreen, + const gfx::Size& framebuffer_size) const { + gfx::SizeF current_size = display.bounds_in_native().size(); + gfx::SizeF native_size = display.GetNativeModeSize(); +#if defined(USE_OZONE) + gfx::SizeF touch_area = touchscreen.size; +#elif defined(USE_X11) + // On X11 touches are reported in the framebuffer coordinate space. + gfx::SizeF touch_area = framebuffer_size; +#endif -// This function computes the mirror mode TouchTransformer for |touch_display|. -// When internal monitor is applied a resolution that does not have -// the same aspect ratio as its native resolution, there would be -// blank regions in the letterboxing/pillarboxing mode. -// The TouchTransformer will make sure the touch events on the blank region -// have negative coordinates and touch events within the chrome region -// have the correct positive coordinates. -gfx::Transform TouchTransformerController::GetMirrorModeTouchTransformer( - const DisplayInfo& touch_display) const { gfx::Transform ctm; - if (!ShouldComputeMirrorModeTouchTransformer(touch_display)) - return ctm; - - float mirror_width = touch_display.bounds_in_native().width(); - float mirror_height = touch_display.bounds_in_native().height(); - gfx::Size native_mode_size = touch_display.GetNativeModeSize(); - float native_width = native_mode_size.width(); - float native_height = native_mode_size.height(); - - if (native_height == 0.0 || mirror_height == 0.0 || - native_width == 0.0 || mirror_width == 0.0) - return ctm; - - float native_ar = native_width / native_height; - float mirror_ar = mirror_width / mirror_height; - if (mirror_ar > native_ar) { // Letterboxing - // Translate before scale. - ctm.Translate(0.0, (1.0 - mirror_ar / native_ar) * 0.5 * mirror_height); - ctm.Scale(1.0, mirror_ar / native_ar); + if (current_size.IsEmpty() || native_size.IsEmpty() || touch_area.IsEmpty() || + touchscreen.id == ui::InputDevice::kInvalidId) return ctm; - } - if (native_ar > mirror_ar) { // Pillarboxing - // Translate before scale. - ctm.Translate((1.0 - native_ar / mirror_ar) * 0.5 * mirror_width, 0.0); - ctm.Scale(native_ar / mirror_ar, 1.0); - return ctm; + // Take care of panel fitting only if supported. + // If panel fitting is enabled then the aspect ratio is preserved and the + // display is scaled acordingly. In this case blank regions would be present + // in order to center the displayed area. + if (display.is_aspect_preserving_scaling()) { + float native_ar = native_size.width() / native_size.height(); + float current_ar = current_size.width() / current_size.height(); + + if (current_ar > native_ar) { // Letterboxing + ctm.Translate( + 0, (1 - current_ar / native_ar) * 0.5 * current_size.height()); + ctm.Scale(1, current_ar / native_ar); + } else if (native_ar > current_ar) { // Pillarboxing + ctm.Translate( + (1 - native_ar / current_ar) * 0.5 * current_size.width(), 0); + ctm.Scale(native_ar / current_ar, 1); + } } - return ctm; // Same aspect ratio - return identity + // Take care of scaling between touchscreen area and display resolution. + ctm.Scale(current_size.width() / touch_area.width(), + current_size.height() / touch_area.height()); + return ctm; } -TouchTransformerController::TouchTransformerController() : - force_compute_mirror_mode_touch_transformer_ (false) { +TouchTransformerController::TouchTransformerController() { Shell::GetInstance()->display_controller()->AddObserver(this); } @@ -196,6 +164,9 @@ void TouchTransformerController::UpdateTouchTransformer() const { FindTouchscreenById(single_display.touch_device_id()))); } + gfx::Size fb_size = + Shell::GetInstance()->display_configurator()->framebuffer_size(); + if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) { // In mirror mode, both displays share the same root window so // both display ids are associated with the root window. @@ -205,17 +176,19 @@ void TouchTransformerController::UpdateTouchTransformer() const { device_manager->UpdateTouchInfoForDisplay( display1_id, display1.touch_device_id(), - GetMirrorModeTouchTransformer(display1)); + GetTouchTransform(display1, + FindTouchscreenById(display1.touch_device_id()), + fb_size)); device_manager->UpdateTouchInfoForDisplay( display2_id, display2.touch_device_id(), - GetMirrorModeTouchTransformer(display2)); + GetTouchTransform(display2, + FindTouchscreenById(display2.touch_device_id()), + fb_size)); return; } if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) { - gfx::Size fb_size = - Shell::GetInstance()->display_configurator()->framebuffer_size(); // In extended but software mirroring mode, ther is only one X root window // that associates with both displays. if (GetDisplayManager()->software_mirroring_enabled()) { @@ -230,11 +203,15 @@ void TouchTransformerController::UpdateTouchTransformer() const { device_manager->UpdateTouchInfoForDisplay( display1_id, display1.touch_device_id(), - GetExtendedModeTouchTransformer(source_display, fb_size)); + GetTouchTransform(source_display, + FindTouchscreenById(display1.touch_device_id()), + fb_size)); device_manager->UpdateTouchInfoForDisplay( display2_id, display2.touch_device_id(), - GetExtendedModeTouchTransformer(source_display, fb_size)); + GetTouchTransform(source_display, + FindTouchscreenById(display2.touch_device_id()), + fb_size)); } else { // In actual extended mode, each display is associated with one root // window. @@ -250,11 +227,15 @@ void TouchTransformerController::UpdateTouchTransformer() const { device_manager->UpdateTouchInfoForDisplay( display1_id, display1.touch_device_id(), - GetExtendedModeTouchTransformer(display1, fb_size)); + GetTouchTransform(display1, + FindTouchscreenById(display1.touch_device_id()), + fb_size)); device_manager->UpdateTouchInfoForDisplay( display2_id, display2.touch_device_id(), - GetExtendedModeTouchTransformer(display2, fb_size)); + GetTouchTransform(display2, + FindTouchscreenById(display2.touch_device_id()), + fb_size)); } return; } @@ -264,9 +245,12 @@ void TouchTransformerController::UpdateTouchTransformer() const { display_controller->GetRootWindowForDisplayId(single_display.id()); RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( single_display.id(), gfx::Display::kInvalidDisplayID); - device_manager->UpdateTouchInfoForDisplay(single_display_id, - single_display.touch_device_id(), - gfx::Transform()); + device_manager->UpdateTouchInfoForDisplay( + single_display_id, + single_display.touch_device_id(), + GetTouchTransform(single_display, + FindTouchscreenById(single_display.touch_device_id()), + fb_size)); } void TouchTransformerController::OnDisplaysInitialized() { diff --git a/ash/touch/touch_transformer_controller.h b/ash/touch/touch_transformer_controller.h index 66a0b38..b210c04 100644 --- a/ash/touch/touch_transformer_controller.h +++ b/ash/touch/touch_transformer_controller.h @@ -41,14 +41,19 @@ class ASH_EXPORT TouchTransformerController FRIEND_TEST_ALL_PREFIXES(TouchTransformerControllerTest, TouchRadiusScale); - bool ShouldComputeMirrorModeTouchTransformer( - const DisplayInfo& touch_display) const ; - - gfx::Transform GetMirrorModeTouchTransformer( - const DisplayInfo& touch_display) const; - - gfx::Transform GetExtendedModeTouchTransformer( - const DisplayInfo& touch_display, const gfx::Size& fb_size) const; + // Returns a transform that will be used to change an event's location from + // the touchscreen's coordinate system into the display's coordinate system. + // The transform is also responsible for properly scaling the display if the + // display support panel fitting. + // + // On X11 events are reported in framebuffer coordinate space, so the + // |framebuffer_size| is used for scaling. + // On Ozone events are reported in the touchscreen's resolution, so + // |touchscreen| is used to determine the size and scale the event. + gfx::Transform GetTouchTransform( + const DisplayInfo& display, + const ui::TouchscreenDevice& touchscreen, + const gfx::Size& framebuffer_size) const; // Returns the scaling factor for the touch radius such that it scales the // radius from |touch_device|'s coordiante system to the |touch_display|'s @@ -57,9 +62,6 @@ class ASH_EXPORT TouchTransformerController const DisplayInfo& touch_display, const ui::TouchscreenDevice& touch_device) const; - // For unittests only. - bool force_compute_mirror_mode_touch_transformer_; - DISALLOW_COPY_AND_ASSIGN(TouchTransformerController); }; diff --git a/ash/touch/touch_transformer_controller_unittest.cc b/ash/touch/touch_transformer_controller_unittest.cc index 7ffab14..3123314 100644 --- a/ash/touch/touch_transformer_controller_unittest.cc +++ b/ash/touch/touch_transformer_controller_unittest.cc @@ -14,14 +14,30 @@ namespace ash { namespace { + DisplayInfo CreateDisplayInfo(int64 id, unsigned int touch_device_id, const gfx::Rect& bounds) { DisplayInfo info(id, std::string(), false); info.SetBounds(bounds); info.set_touch_device_id(touch_device_id); + + // Create a default mode. + std::vector<DisplayMode> default_modes( + 1, DisplayMode(bounds.size(), 60, false, true)); + info.set_display_modes(default_modes); + return info; } + +ui::TouchscreenDevice CreateTouchscreenDevice(unsigned int id, + const gfx::Size& size) { + return ui::TouchscreenDevice(id, + ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, + std::string(), + size); +} + } // namespace typedef test::AshTestBase TouchTransformerControllerTest; @@ -32,6 +48,7 @@ TEST_F(TouchTransformerControllerTest, TouchTransformerMirrorModeLetterboxing) { // mode. DisplayInfo internal_display_info = CreateDisplayInfo(1, 10u, gfx::Rect(0, 0, 1920, 1200)); + internal_display_info.set_is_aspect_preserving_scaling(true); std::vector<DisplayMode> internal_modes; internal_modes.push_back( DisplayMode(gfx::Size(2560, 1700), 60, false, true)); @@ -42,21 +59,32 @@ TEST_F(TouchTransformerControllerTest, TouchTransformerMirrorModeLetterboxing) { DisplayInfo external_display_info = CreateDisplayInfo(2, 11u, gfx::Rect(0, 0, 1920, 1200)); + gfx::Size fb_size(1920, 1200); + + // Create the touchscreens with the same size as the framebuffer so we can + // share the tests between Ozone & X11. + ui::TouchscreenDevice internal_touchscreen = + CreateTouchscreenDevice(10, fb_size); + ui::TouchscreenDevice external_touchscreen = + CreateTouchscreenDevice(11, fb_size); + TouchTransformerController* tt_controller = Shell::GetInstance()->touch_transformer_controller(); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - tt_controller->force_compute_mirror_mode_touch_transformer_ = true; device_manager->UpdateTouchInfoForDisplay( internal_display_info.id(), internal_display_info.touch_device_id(), - tt_controller->GetMirrorModeTouchTransformer(internal_display_info)); + tt_controller->GetTouchTransform(internal_display_info, + internal_touchscreen, + fb_size)); - tt_controller->force_compute_mirror_mode_touch_transformer_ = false; device_manager->UpdateTouchInfoForDisplay( external_display_info.id(), external_display_info.touch_device_id(), - tt_controller->GetMirrorModeTouchTransformer(external_display_info)); + tt_controller->GetTouchTransform(external_display_info, + external_touchscreen, + fb_size)); EXPECT_EQ(1, device_manager->GetDisplayForTouchDevice(10)); EXPECT_EQ(2, device_manager->GetDisplayForTouchDevice(11)); @@ -93,6 +121,7 @@ TEST_F(TouchTransformerControllerTest, TouchTransformerMirrorModePillarboxing) { // mode. DisplayInfo internal_display_info = CreateDisplayInfo(1, 10, gfx::Rect(0, 0, 1024, 768)); + internal_display_info.set_is_aspect_preserving_scaling(true); std::vector<DisplayMode> internal_modes; internal_modes.push_back( DisplayMode(gfx::Size(1366, 768), 60, false, true)); @@ -103,21 +132,32 @@ TEST_F(TouchTransformerControllerTest, TouchTransformerMirrorModePillarboxing) { DisplayInfo external_display_info = CreateDisplayInfo(2, 11, gfx::Rect(0, 0, 1024, 768)); + gfx::Size fb_size(1024, 768); + + // Create the touchscreens with the same size as the framebuffer so we can + // share the tests between Ozone & X11. + ui::TouchscreenDevice internal_touchscreen = + CreateTouchscreenDevice(10, fb_size); + ui::TouchscreenDevice external_touchscreen = + CreateTouchscreenDevice(11, fb_size); + TouchTransformerController* tt_controller = Shell::GetInstance()->touch_transformer_controller(); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - tt_controller->force_compute_mirror_mode_touch_transformer_ = true; device_manager->UpdateTouchInfoForDisplay( internal_display_info.id(), internal_display_info.touch_device_id(), - tt_controller->GetMirrorModeTouchTransformer(internal_display_info)); + tt_controller->GetTouchTransform(internal_display_info, + internal_touchscreen, + fb_size)); - tt_controller->force_compute_mirror_mode_touch_transformer_ = false; device_manager->UpdateTouchInfoForDisplay( external_display_info.id(), external_display_info.touch_device_id(), - tt_controller->GetMirrorModeTouchTransformer(external_display_info)); + tt_controller->GetTouchTransform(external_display_info, + external_touchscreen, + fb_size)); EXPECT_EQ(1, device_manager->GetDisplayForTouchDevice(10)); EXPECT_EQ(2, device_manager->GetDisplayForTouchDevice(11)); @@ -159,6 +199,11 @@ TEST_F(TouchTransformerControllerTest, TouchTransformerExtendedMode) { CreateDisplayInfo(2, 6u, gfx::Rect(0, 828, 2560, 1600)); gfx::Size fb_size(2560, 2428); + // Create the touchscreens with the same size as the framebuffer so we can + // share the tests between Ozone & X11. + ui::TouchscreenDevice touchscreen1 = CreateTouchscreenDevice(5, fb_size); + ui::TouchscreenDevice touchscreen2 = CreateTouchscreenDevice(6, fb_size); + TouchTransformerController* tt_controller = Shell::GetInstance()->touch_transformer_controller(); ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); @@ -166,12 +211,16 @@ TEST_F(TouchTransformerControllerTest, TouchTransformerExtendedMode) { device_manager->UpdateTouchInfoForDisplay( display1.id(), display1.touch_device_id(), - tt_controller->GetExtendedModeTouchTransformer(display1, fb_size)); + tt_controller->GetTouchTransform(display1, + touchscreen1, + fb_size)); device_manager->UpdateTouchInfoForDisplay( display2.id(), display2.touch_device_id(), - tt_controller->GetExtendedModeTouchTransformer(display2, fb_size)); + tt_controller->GetTouchTransform(display2, + touchscreen2, + fb_size)); EXPECT_EQ(1, device_manager->GetDisplayForTouchDevice(5)); EXPECT_EQ(2, device_manager->GetDisplayForTouchDevice(6)); @@ -207,10 +256,8 @@ TEST_F(TouchTransformerControllerTest, TouchTransformerExtendedMode) { TEST_F(TouchTransformerControllerTest, TouchRadiusScale) { DisplayInfo display = CreateDisplayInfo(1, 5u, gfx::Rect(0, 0, 2560, 1600)); - ui::TouchscreenDevice touch_device(5, - ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, - std::string(), - gfx::Size(1001, 1001)); + ui::TouchscreenDevice touch_device = + CreateTouchscreenDevice(5, gfx::Size(1001, 1001)); TouchTransformerController* tt_controller = Shell::GetInstance()->touch_transformer_controller(); |