diff options
Diffstat (limited to 'chromeos')
-rw-r--r-- | chromeos/display/output_configurator.cc | 51 | ||||
-rw-r--r-- | chromeos/display/output_configurator.h | 9 | ||||
-rw-r--r-- | chromeos/display/output_configurator_unittest.cc | 40 |
3 files changed, 90 insertions, 10 deletions
diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc index 1a3cc31..67da273 100644 --- a/chromeos/display/output_configurator.cc +++ b/chromeos/display/output_configurator.cc @@ -932,16 +932,8 @@ bool OutputConfigurator::EnterState( for (size_t i = 0; i < updated_outputs.size(); ++i) { OutputSnapshot* output = &updated_outputs[i]; - if (output->touch_device_id) { - const ModeInfo* mode_info = - GetModeInfo(*output, output->selected_mode); - DCHECK(mode_info); - CoordinateTransformation* ctm = &(output->transform); - ctm->x_scale = static_cast<float>(mode_info->width) / width; - ctm->x_offset = static_cast<float>(output->x) / width; - ctm->y_scale = static_cast<float>(mode_info->height) / height; - ctm->y_offset = static_cast<float>(output->y) / height; - } + if (output->touch_device_id) + output->transform = GetExtendedModeCTM(*output, width, height); } break; } @@ -1040,6 +1032,45 @@ OutputConfigurator::GetMirrorModeCTM( return ctm; // Same aspect ratio - return identity } +OutputConfigurator::CoordinateTransformation +OutputConfigurator::GetExtendedModeCTM( + const OutputConfigurator::OutputSnapshot& output, + int framebuffer_width, + int framebuffer_height) { + CoordinateTransformation ctm; // Default to identity + const ModeInfo* mode_info = GetModeInfo(output, output.selected_mode); + DCHECK(mode_info); + if (!mode_info) + return ctm; + // An example of how to calculate the CTM. + // Suppose we have 2 monitors, the first one has size 1366 x 768. + // The second one has size 2560 x 1600 + // The total size of framebuffer is 2560 x 2428 + // where 2428 = 768 + 60 (hidden gap) + 1600 + // and the sceond monitor is translated to Point (0, 828) in the + // framebuffer. + // X will first map input event location to [0, 2560) x [0, 2428), + // then apply CTM on it. + // So to compute CTM, for monitor1, we have + // x_scale = (1366 - 1) / (2560 - 1) + // x_offset = 0 / (2560 - 1) + // y_scale = (768 - 1) / (2428 - 1) + // y_offset = 0 / (2428 -1) + // For Monitor 2, we have + // x_scale = (2560 - 1) / (2560 - 1) + // x_offset = 0 / (2560 - 1) + // y_scale = (1600 - 1) / (2428 - 1) + // y_offset = 828 / (2428 -1) + // See the unittest OutputConfiguratorTest.CTMForMultiScreens. + ctm.x_scale = + static_cast<float>(mode_info->width - 1) / (framebuffer_width - 1); + ctm.x_offset = static_cast<float>(output.x) / (framebuffer_width - 1); + ctm.y_scale = + static_cast<float>(mode_info->height - 1) / (framebuffer_height - 1); + ctm.y_offset = static_cast<float>(output.y) / (framebuffer_height - 1); + return ctm; +} + float OutputConfigurator::GetMirroredDisplayAreaRatio( const OutputConfigurator::OutputSnapshot& output) { float area_ratio = 1.0f; diff --git a/chromeos/display/output_configurator.h b/chromeos/display/output_configurator.h index ef5085e..c927519 100644 --- a/chromeos/display/output_configurator.h +++ b/chromeos/display/output_configurator.h @@ -487,6 +487,15 @@ class CHROMEOS_EXPORT OutputConfigurator CoordinateTransformation GetMirrorModeCTM( const OutputConfigurator::OutputSnapshot& output); + // Computes the relevant transformation for extended mode. + // |output| is the output on which extended mode is being applied. + // |width| and |height| are the width and height of the combined framebuffer. + // Returns the transformation or identity if computations fail. + CoordinateTransformation GetExtendedModeCTM( + const OutputConfigurator::OutputSnapshot& output, + int framebuffer_width, + int frame_buffer_height); + // Returns the ratio between mirrored mode area and native mode area: // (mirror_mode_width * mirrow_mode_height) / (native_width * native_height) float GetMirroredDisplayAreaRatio( diff --git a/chromeos/display/output_configurator_unittest.cc b/chromeos/display/output_configurator_unittest.cc index 28f0553..571df38 100644 --- a/chromeos/display/output_configurator_unittest.cc +++ b/chromeos/display/output_configurator_unittest.cc @@ -4,6 +4,7 @@ #include "chromeos/display/output_configurator.h" +#include <cmath> #include <cstdarg> #include <map> #include <string> @@ -128,6 +129,11 @@ class TestDelegate : public OutputConfigurator::Delegate { return actions; } + const OutputConfigurator::CoordinateTransformation& get_ctm( + int touch_device_id) { + return ctms_[touch_device_id]; + } + // OutputConfigurator::Delegate overrides: virtual void InitXRandRExtension(int* event_base) OVERRIDE { AppendAction(kInitXRandR); @@ -171,6 +177,7 @@ class TestDelegate : public OutputConfigurator::Delegate { int touch_device_id, const OutputConfigurator::CoordinateTransformation& ctm) OVERRIDE { AppendAction(GetCTMAction(touch_device_id, ctm)); + ctms_[touch_device_id] = ctm; } virtual void SendProjectingStateToPowerManager(bool projecting) OVERRIDE { AppendAction(projecting ? kProjectingOn : kProjectingOff); @@ -207,6 +214,9 @@ class TestDelegate : public OutputConfigurator::Delegate { std::map<RRMode, ModeDetails> modes_; + // Most-recently-configured transformation matrices, keyed by touch device ID. + std::map<int, OutputConfigurator::CoordinateTransformation> ctms_; + // Outputs to be returned by GetOutputs(). std::vector<OutputConfigurator::OutputSnapshot> outputs_; @@ -1223,4 +1233,34 @@ TEST_F(OutputConfiguratorTest, OutputProtectionTwoClients) { delegate_->GetActionsAndClear()); } +TEST_F(OutputConfiguratorTest, CTMForMultiScreens) { + outputs_[0].touch_device_id = 1; + outputs_[1].touch_device_id = 2; + + UpdateOutputs(2, false); + configurator_.Init(false); + state_controller_.set_state(STATE_DUAL_EXTENDED); + configurator_.Start(0); + + const int kDualHeight = + kSmallModeHeight + OutputConfigurator::kVerticalGap + kBigModeHeight; + const int kDualWidth = kBigModeWidth; + + OutputConfigurator::CoordinateTransformation ctm1 = delegate_->get_ctm(1); + OutputConfigurator::CoordinateTransformation ctm2 = delegate_->get_ctm(2); + + EXPECT_EQ(kSmallModeHeight - 1, round((kDualHeight - 1) * ctm1.y_scale)); + EXPECT_EQ(0, round((kDualHeight - 1) * ctm1.y_offset)); + + EXPECT_EQ(kBigModeHeight - 1, round((kDualHeight - 1) * ctm2.y_scale)); + EXPECT_EQ(kSmallModeHeight + OutputConfigurator::kVerticalGap, + round((kDualHeight - 1) * ctm2.y_offset)); + + EXPECT_EQ(kSmallModeWidth - 1, round((kDualWidth - 1) * ctm1.x_scale)); + EXPECT_EQ(0, round((kDualWidth - 1) * ctm1.x_offset)); + + EXPECT_EQ(kBigModeWidth - 1, round((kDualWidth - 1) * ctm2.x_scale)); + EXPECT_EQ(0, round((kDualWidth - 1) * ctm2.x_offset)); +} + } // namespace chromeos |