Index: chromeos/display/output_configurator_unittest.cc |
diff --git a/chromeos/display/output_configurator_unittest.cc b/chromeos/display/output_configurator_unittest.cc |
index 571df38f6cd4b3906e95f62bcbc506ea001d615b..526bb981d38e9edf7a3d26c0b0aeaa69b99442fd 100644 |
--- a/chromeos/display/output_configurator_unittest.cc |
+++ b/chromeos/display/output_configurator_unittest.cc |
@@ -102,7 +102,7 @@ class TestDelegate : public OutputConfigurator::Delegate { |
static const int kXRandREventBase = 10; |
TestDelegate() |
- : configure_crtc_result_(true), |
+ : max_configurable_pixels_(0), |
hdcp_state_(HDCP_STATE_UNDESIRED) {} |
virtual ~TestDelegate() {} |
@@ -114,8 +114,14 @@ class TestDelegate : public OutputConfigurator::Delegate { |
outputs_ = outputs; |
} |
- void set_configure_crtc_result(bool result) { |
- configure_crtc_result_ = result; |
+ // max_configurable_pixels_ represents the maximum number of pixels that |
+ // ConfigureCrtc will support. Tests can use this to force ConfigureCrtc |
+ // to fail if attempting to set a resolution that is higher than what |
+ // a device might support under a given circumstance. |
+ // A value of 0 means that no limit is enforced and ConfigureCrtc will |
+ // return success regardless of the resolution. |
Daniel Erat
2014/01/08 21:40:28
nit: merge all of this documentation with the othe
dsodman
2014/01/09 00:26:28
Done.
|
+ void set_max_configurable_pixels(int pixels) { |
+ max_configurable_pixels_ = pixels; |
} |
void set_hdcp_state(HDCPState state) { hdcp_state_ = state; } |
@@ -154,6 +160,12 @@ class TestDelegate : public OutputConfigurator::Delegate { |
} |
virtual void AddOutputMode(RROutput output, RRMode mode) OVERRIDE { |
AppendAction(GetAddOutputModeAction(output, mode)); |
+ OutputConfigurator::OutputSnapshot* snapshot = |
+ GetOutputFromId(output); |
+ if (snapshot != NULL) { |
Daniel Erat
2014/01/08 21:40:28
nit:
if (!snapshot)
return;
(or maybe just
dsodman
2014/01/09 00:26:28
I did this and also did the same with mode_info (u
|
+ snapshot->mode_infos[mode] = |
+ *OutputConfigurator::GetModeInfo(*snapshot, mode); |
Daniel Erat
2014/01/08 21:40:28
probably also want to check GetModeInfo()'s return
|
+ } |
} |
virtual bool ConfigureCrtc(RRCrtc crtc, |
RRMode mode, |
@@ -161,7 +173,22 @@ class TestDelegate : public OutputConfigurator::Delegate { |
int x, |
int y) OVERRIDE { |
AppendAction(GetCrtcAction(crtc, x, y, mode, output)); |
- return configure_crtc_result_; |
+ |
+ // |max_configurable_pixels_| value of 0 means no limit on resolution |
Daniel Erat
2014/01/08 21:40:28
nit: don't need this comment
dsodman
2014/01/09 00:26:28
Done.
|
+ if (max_configurable_pixels_ == 0) { |
Daniel Erat
2014/01/08 21:40:28
nit: don't need curly brackets for an 'if' with a
dsodman
2014/01/09 00:26:28
Done.
|
+ return true; |
+ } |
+ |
+ OutputConfigurator::OutputSnapshot* snapshot = GetOutputFromId(output); |
+ if (snapshot) { |
Daniel Erat
2014/01/08 21:40:28
nit:
if (!snapshot)
return false;
const
dsodman
2014/01/09 00:26:28
Done.
|
+ const OutputConfigurator::ModeInfo* mode_info = |
+ OutputConfigurator::GetModeInfo(*snapshot, mode); |
+ |
+ if (mode_info) |
+ return mode_info->width * mode_info->height <= max_configurable_pixels_; |
+ } |
+ |
+ return false; |
} |
virtual void CreateFrameBuffer( |
int width, |
@@ -212,6 +239,14 @@ class TestDelegate : public OutputConfigurator::Delegate { |
actions_ += action; |
} |
+ OutputConfigurator::OutputSnapshot* GetOutputFromId(RROutput output_id) { |
+ for (unsigned int i = 0; i < outputs_.size(); i++) { |
+ if (outputs_[i].output == output_id) |
+ return &outputs_[i]; |
+ } |
+ return NULL; |
+ } |
+ |
std::map<RRMode, ModeDetails> modes_; |
// Most-recently-configured transformation matrices, keyed by touch device ID. |
@@ -222,8 +257,9 @@ class TestDelegate : public OutputConfigurator::Delegate { |
std::string actions_; |
- // Return value returned by ConfigureCrtc(). |
- bool configure_crtc_result_; |
+ // Represents the maximum number of pixels that a modeset can handle. Any |
+ // attempt to set a resolution with more pixels will fail. |
+ int max_configurable_pixels_; |
// Result value of GetHDCPState(). |
HDCPState hdcp_state_; |
@@ -1019,9 +1055,9 @@ TEST_F(OutputConfiguratorTest, AvoidUnnecessaryProbes) { |
EXPECT_FALSE(test_api_.TriggerConfigureTimeout()); |
EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); |
- // Tell the delegate to report failure, which should result in the |
- // second output sticking with its native mode. |
- delegate_->set_configure_crtc_result(false); |
+ // Lower the limit for which the delegate will succeed, which should result |
+ // in the second output sticking with its native mode. |
+ delegate_->set_max_configurable_pixels(1); |
UpdateOutputs(2, true); |
EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, |
GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, |
@@ -1033,9 +1069,9 @@ TEST_F(OutputConfiguratorTest, AvoidUnnecessaryProbes) { |
kUngrab, kProjectingOn, NULL), |
delegate_->GetActionsAndClear()); |
- // An change event reporting a mode change on the second output should |
+ // A change event reporting a mode change on the second output should |
// trigger another reconfigure. |
- delegate_->set_configure_crtc_result(true); |
+ delegate_->set_max_configurable_pixels(0); |
test_api_.SendOutputChangeEvent( |
outputs_[1].output, outputs_[1].crtc, outputs_[1].mirror_mode, true); |
EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); |
@@ -1263,4 +1299,116 @@ TEST_F(OutputConfiguratorTest, CTMForMultiScreens) { |
EXPECT_EQ(0, round((kDualWidth - 1) * ctm2.x_offset)); |
} |
+TEST_F(OutputConfiguratorTest, HandleConfigureCrtcFailure) { |
+ int current_mode; |
Daniel Erat
2014/01/08 21:40:28
nit: move this down to the place where it's first
dsodman
2014/01/09 00:26:28
Done.
|
+ InitWithSingleOutput(); |
+ test_api_.SendScreenChangeEvent(); |
Daniel Erat
2014/01/08 21:40:28
i don't think you need this or the kUpdateXRandR c
dsodman
2014/01/09 00:26:28
That's fine. I had modeled this after the AvoidUn
|
+ EXPECT_EQ(kUpdateXRandR, delegate_->GetActionsAndClear()); |
+ |
+ // kFirstMode represents the first mode in the list and |
+ // also the mode that we are requesting the output_configurator |
+ // to choose. The test will be setup so that this mode will fail |
+ // and it will have to choose the next best option. |
+ const int kFirstMode = 11; |
+ |
+ // Give the mode_info lists a few reasonable modes. |
+ for (int i = 0; i < 2; i++) { |
Daniel Erat
2014/01/08 21:40:28
nit: s/2/outputs_.size()/
dsodman
2014/01/09 00:26:28
Here outputs_ is an array not a vector:
OutputCo
Daniel Erat
2014/01/09 00:40:34
ah, i think that arraysize(outputs_) should work,
|
+ outputs_[i].mode_infos.clear(); |
+ |
+ current_mode = kFirstMode; |
+ outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo( |
+ 2560, 1600, false, 60.0); |
+ outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo( |
+ 1024, 768, false, 60.0); |
+ outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo( |
+ 1280, 720, false, 60.0); |
+ outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo( |
+ 1920, 1080, false, 60.0); |
+ outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo( |
+ 1920, 1080, false, 40.0); |
+ |
+ outputs_[i].selected_mode = kFirstMode; |
Daniel Erat
2014/01/08 21:40:28
s/selected_mode/current_mode/ ?
(selected_mode ge
dsodman
2014/01/09 00:26:28
Done.
|
+ outputs_[i].native_mode = kFirstMode; |
+ } |
+ |
+ current_mode = kFirstMode; |
Daniel Erat
2014/01/08 21:40:28
this doesn't seem to do anything (i don't see it u
dsodman
2014/01/09 00:26:28
Done.
|
+ configurator_.Init(false); |
+ |
+ // First test simply fails in STATE_SINGLE mode. This is probably |
+ // unrealistic but the want to make sure any assumptions don't |
+ // creep in. |
+ delegate_->set_max_configurable_pixels( |
+ outputs_[0].mode_infos[kFirstMode + 2].width * |
+ outputs_[0].mode_infos[kFirstMode + 2].height); |
+ state_controller_.set_state(STATE_SINGLE); |
+ test_api_.SendOutputChangeEvent( |
Daniel Erat
2014/01/08 21:40:28
i don't think you need this call either; the next
dsodman
2014/01/09 00:26:28
I removed. I had modeled it after AvoidUnnecessar
|
+ outputs_[0].output, outputs_[0].crtc, outputs_[0].selected_mode, true); |
+ UpdateOutputs(1, true); |
+ |
+ EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, |
+ GetFramebufferAction(2560, 1600, |
+ outputs_[0].crtc, 0).c_str(), |
+ GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode, |
+ outputs_[0].output).c_str(), |
+ GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3, |
+ outputs_[0].output).c_str(), |
+ GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 2, |
+ outputs_[0].output).c_str(), |
+ kUngrab, kProjectingOff, NULL), |
+ delegate_->GetActionsAndClear()); |
+ |
+ // This test should attempt to configure a mirror mode that will not succeed |
+ // and should end up in extended mode. |
+ delegate_->set_max_configurable_pixels( |
+ outputs_[0].mode_infos[kFirstMode + 3].width * |
+ outputs_[0].mode_infos[kFirstMode + 3].height); |
+ state_controller_.set_state(STATE_DUAL_MIRROR); |
+ test_api_.SendOutputChangeEvent( |
Daniel Erat
2014/01/08 21:40:28
same here
dsodman
2014/01/09 00:26:28
Done.
|
+ outputs_[1].output, outputs_[1].crtc, outputs_[1].selected_mode, true); |
+ UpdateOutputs(2, true); |
+ |
+ EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, |
+ GetFramebufferAction( |
+ outputs_[0].mode_infos[kFirstMode].width, |
+ outputs_[0].mode_infos[kFirstMode].height, |
+ outputs_[0].crtc, |
+ outputs_[1].crtc).c_str(), |
+ GetCrtcAction(outputs_[0].crtc, |
+ 0, 0, kFirstMode, outputs_[0].output).c_str(), |
+ // First mode tried is expected to fail and it will |
+ // retry wil the 4th mode in the list. |
+ GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3, |
+ outputs_[0].output).c_str(), |
+ // Then attempt to configure crtc1 with the first mode. |
+ GetCrtcAction(outputs_[1].crtc, 0, 0, kFirstMode, |
+ outputs_[1].output).c_str(), |
+ GetCrtcAction(outputs_[1].crtc, 0, 0, kFirstMode + 3, |
+ outputs_[1].output).c_str(), |
+ // Since it was requested to go into mirror mode |
+ // and the configured modes were different, it |
+ // should now try and setup a valid configurable |
+ // extended mode. |
+ GetFramebufferAction( |
+ outputs_[0].mode_infos[kFirstMode].width, |
+ outputs_[0].mode_infos[kFirstMode].height + |
+ outputs_[1].mode_infos[kFirstMode].height + |
+ OutputConfigurator::kVerticalGap, |
+ outputs_[0].crtc, outputs_[1].crtc).c_str(), |
+ GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode, |
+ outputs_[0].output).c_str(), |
+ GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3, |
+ outputs_[0].output).c_str(), |
+ GetCrtcAction(outputs_[1].crtc, 0, |
+ outputs_[1].mode_infos[kFirstMode].height + |
+ OutputConfigurator::kVerticalGap, kFirstMode, |
+ outputs_[1].output).c_str(), |
+ GetCrtcAction(outputs_[1].crtc, 0, |
+ outputs_[1].mode_infos[kFirstMode].height + |
+ OutputConfigurator::kVerticalGap, kFirstMode + 3, |
+ outputs_[1].output).c_str(), |
+ kUngrab, kProjectingOn, NULL), |
+ delegate_->GetActionsAndClear()); |
+ |
+} |
+ |
} // namespace chromeos |