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

Side by Side Diff: chromeos/display/output_configurator_unittest.cc

Issue 120223003: Support failing modeset (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review feedback Created 6 years, 11 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 | Annotate | Revision Log
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 "chromeos/display/output_configurator.h" 5 #include "chromeos/display/output_configurator.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <cstdarg> 8 #include <cstdarg>
9 #include <map> 9 #include <map>
10 #include <string> 10 #include <string>
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 } 95 }
96 va_end(arg_list); 96 va_end(arg_list);
97 return actions; 97 return actions;
98 } 98 }
99 99
100 class TestDelegate : public OutputConfigurator::Delegate { 100 class TestDelegate : public OutputConfigurator::Delegate {
101 public: 101 public:
102 static const int kXRandREventBase = 10; 102 static const int kXRandREventBase = 10;
103 103
104 TestDelegate() 104 TestDelegate()
105 : configure_crtc_result_(true), 105 : max_configurable_pixels_(0),
106 hdcp_state_(HDCP_STATE_UNDESIRED) {} 106 hdcp_state_(HDCP_STATE_UNDESIRED) {}
107 virtual ~TestDelegate() {} 107 virtual ~TestDelegate() {}
108 108
109 const std::vector<OutputConfigurator::OutputSnapshot>& outputs() const { 109 const std::vector<OutputConfigurator::OutputSnapshot>& outputs() const {
110 return outputs_; 110 return outputs_;
111 } 111 }
112 void set_outputs( 112 void set_outputs(
113 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { 113 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) {
114 outputs_ = outputs; 114 outputs_ = outputs;
115 } 115 }
116 116
117 void set_configure_crtc_result(bool result) { 117 void set_max_configurable_pixels(int pixels) {
118 configure_crtc_result_ = result; 118 max_configurable_pixels_ = pixels;
119 } 119 }
120 120
121 void set_hdcp_state(HDCPState state) { hdcp_state_ = state; } 121 void set_hdcp_state(HDCPState state) { hdcp_state_ = state; }
122 122
123 // Returns a comma-separated string describing the actions that were 123 // Returns a comma-separated string describing the actions that were
124 // requested since the previous call to GetActionsAndClear() (i.e. 124 // requested since the previous call to GetActionsAndClear() (i.e.
125 // results are non-repeatable). 125 // results are non-repeatable).
126 std::string GetActionsAndClear() { 126 std::string GetActionsAndClear() {
127 std::string actions = actions_; 127 std::string actions = actions_;
128 actions_.clear(); 128 actions_.clear();
(...skipping 25 matching lines...) Expand all
154 } 154 }
155 virtual void AddOutputMode(RROutput output, RRMode mode) OVERRIDE { 155 virtual void AddOutputMode(RROutput output, RRMode mode) OVERRIDE {
156 AppendAction(GetAddOutputModeAction(output, mode)); 156 AppendAction(GetAddOutputModeAction(output, mode));
157 } 157 }
158 virtual bool ConfigureCrtc(RRCrtc crtc, 158 virtual bool ConfigureCrtc(RRCrtc crtc,
159 RRMode mode, 159 RRMode mode,
160 RROutput output, 160 RROutput output,
161 int x, 161 int x,
162 int y) OVERRIDE { 162 int y) OVERRIDE {
163 AppendAction(GetCrtcAction(crtc, x, y, mode, output)); 163 AppendAction(GetCrtcAction(crtc, x, y, mode, output));
164 return configure_crtc_result_; 164
165 if (max_configurable_pixels_ == 0)
166 return true;
167
168 OutputConfigurator::OutputSnapshot* snapshot = GetOutputFromId(output);
169
Daniel Erat 2014/01/09 00:40:34 nit: remove this blank line
170 if (!snapshot)
171 return false;
172
173 const OutputConfigurator::ModeInfo* mode_info =
174 OutputConfigurator::GetModeInfo(*snapshot, mode);
175
Daniel Erat 2014/01/09 00:40:34 nit: remove this blank line
176 if (!mode_info)
177 return false;
178
179 return mode_info->width * mode_info->height <= max_configurable_pixels_;
180
165 } 181 }
166 virtual void CreateFrameBuffer( 182 virtual void CreateFrameBuffer(
167 int width, 183 int width,
168 int height, 184 int height,
169 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) OVERRIDE { 185 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) OVERRIDE {
170 AppendAction( 186 AppendAction(
171 GetFramebufferAction(width, 187 GetFramebufferAction(width,
172 height, 188 height,
173 outputs.size() >= 1 ? outputs[0].crtc : 0, 189 outputs.size() >= 1 ? outputs[0].crtc : 0,
174 outputs.size() >= 2 ? outputs[1].crtc : 0)); 190 outputs.size() >= 2 ? outputs[1].crtc : 0));
(...skipping 30 matching lines...) Expand all
205 int height; 221 int height;
206 bool interlaced; 222 bool interlaced;
207 }; 223 };
208 224
209 void AppendAction(const std::string& action) { 225 void AppendAction(const std::string& action) {
210 if (!actions_.empty()) 226 if (!actions_.empty())
211 actions_ += ","; 227 actions_ += ",";
212 actions_ += action; 228 actions_ += action;
213 } 229 }
214 230
231 OutputConfigurator::OutputSnapshot* GetOutputFromId(RROutput output_id) {
232 for (unsigned int i = 0; i < outputs_.size(); i++) {
233 if (outputs_[i].output == output_id)
234 return &outputs_[i];
235 }
236 return NULL;
237 }
238
215 std::map<RRMode, ModeDetails> modes_; 239 std::map<RRMode, ModeDetails> modes_;
216 240
217 // Most-recently-configured transformation matrices, keyed by touch device ID. 241 // Most-recently-configured transformation matrices, keyed by touch device ID.
218 std::map<int, OutputConfigurator::CoordinateTransformation> ctms_; 242 std::map<int, OutputConfigurator::CoordinateTransformation> ctms_;
219 243
220 // Outputs to be returned by GetOutputs(). 244 // Outputs to be returned by GetOutputs().
221 std::vector<OutputConfigurator::OutputSnapshot> outputs_; 245 std::vector<OutputConfigurator::OutputSnapshot> outputs_;
222 246
223 std::string actions_; 247 std::string actions_;
224 248
225 // Return value returned by ConfigureCrtc(). 249 // |max_configurable_pixels_| represents the maximum number of pixels that
226 bool configure_crtc_result_; 250 // ConfigureCrtc will support. Tests can use this to force ConfigureCrtc
251 // to fail if attempting to set a resolution that is higher than what
252 // a device might support under a given circumstance.
253 // A value of 0 means that no limit is enforced and ConfigureCrtc will
254 // return success regardless of the resolution.
255 int max_configurable_pixels_;
227 256
228 // Result value of GetHDCPState(). 257 // Result value of GetHDCPState().
229 HDCPState hdcp_state_; 258 HDCPState hdcp_state_;
230 259
231 DISALLOW_COPY_AND_ASSIGN(TestDelegate); 260 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
232 }; 261 };
233 262
234 class TestObserver : public OutputConfigurator::Observer { 263 class TestObserver : public OutputConfigurator::Observer {
235 public: 264 public:
236 explicit TestObserver(OutputConfigurator* configurator) 265 explicit TestObserver(OutputConfigurator* configurator)
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 kUngrab, kProjectingOff, NULL), 1041 kUngrab, kProjectingOff, NULL),
1013 delegate_->GetActionsAndClear()); 1042 delegate_->GetActionsAndClear());
1014 1043
1015 // An additional event about the second output being disconnected should 1044 // An additional event about the second output being disconnected should
1016 // be ignored. 1045 // be ignored.
1017 test_api_.SendOutputChangeEvent( 1046 test_api_.SendOutputChangeEvent(
1018 outputs_[1].output, outputs_[1].crtc, outputs_[1].current_mode, false); 1047 outputs_[1].output, outputs_[1].crtc, outputs_[1].current_mode, false);
1019 EXPECT_FALSE(test_api_.TriggerConfigureTimeout()); 1048 EXPECT_FALSE(test_api_.TriggerConfigureTimeout());
1020 EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); 1049 EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear());
1021 1050
1022 // Tell the delegate to report failure, which should result in the 1051 // Lower the limit for which the delegate will succeed, which should result
1023 // second output sticking with its native mode. 1052 // in the second output sticking with its native mode.
1024 delegate_->set_configure_crtc_result(false); 1053 delegate_->set_max_configurable_pixels(1);
1025 UpdateOutputs(2, true); 1054 UpdateOutputs(2, true);
1026 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, 1055 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab,
1027 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, 1056 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight,
1028 outputs_[0].crtc, outputs_[1].crtc).c_str(), 1057 outputs_[0].crtc, outputs_[1].crtc).c_str(),
1029 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, 1058 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId,
1030 outputs_[0].output).c_str(), 1059 outputs_[0].output).c_str(),
1031 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, 1060 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId,
1032 outputs_[1].output).c_str(), 1061 outputs_[1].output).c_str(),
1062 GetFramebufferAction(kBigModeWidth,
1063 kSmallModeHeight + kBigModeHeight +
1064 OutputConfigurator::kVerticalGap,
1065 outputs_[0].crtc, outputs_[1].crtc).c_str(),
1066 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId,
1067 outputs_[0].output).c_str(),
1068 GetCrtcAction(outputs_[1].crtc, 0, kSmallModeHeight +
1069 OutputConfigurator::kVerticalGap, kBigModeId,
1070 outputs_[1].output).c_str(),
1071 GetCrtcAction(outputs_[1].crtc, 0, kSmallModeHeight +
1072 OutputConfigurator::kVerticalGap, kSmallModeId,
1073 outputs_[1].output).c_str(),
1033 kUngrab, kProjectingOn, NULL), 1074 kUngrab, kProjectingOn, NULL),
1034 delegate_->GetActionsAndClear()); 1075 delegate_->GetActionsAndClear());
1035 1076
1036 // An change event reporting a mode change on the second output should 1077 // A change event reporting a mode change on the second output should
1037 // trigger another reconfigure. 1078 // trigger another reconfigure.
1038 delegate_->set_configure_crtc_result(true); 1079 delegate_->set_max_configurable_pixels(0);
1039 test_api_.SendOutputChangeEvent( 1080 test_api_.SendOutputChangeEvent(
1040 outputs_[1].output, outputs_[1].crtc, outputs_[1].mirror_mode, true); 1081 outputs_[1].output, outputs_[1].crtc, outputs_[1].mirror_mode, true);
1041 EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); 1082 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
1042 EXPECT_EQ(JoinActions(kGrab, 1083 EXPECT_EQ(JoinActions(kGrab,
1043 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, 1084 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight,
1044 outputs_[0].crtc, outputs_[1].crtc).c_str(), 1085 outputs_[0].crtc, outputs_[1].crtc).c_str(),
1045 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, 1086 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId,
1046 outputs_[0].output).c_str(), 1087 outputs_[0].output).c_str(),
1047 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, 1088 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId,
1048 outputs_[1].output).c_str(), 1089 outputs_[1].output).c_str(),
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 EXPECT_EQ(kSmallModeHeight + OutputConfigurator::kVerticalGap, 1297 EXPECT_EQ(kSmallModeHeight + OutputConfigurator::kVerticalGap,
1257 round((kDualHeight - 1) * ctm2.y_offset)); 1298 round((kDualHeight - 1) * ctm2.y_offset));
1258 1299
1259 EXPECT_EQ(kSmallModeWidth - 1, round((kDualWidth - 1) * ctm1.x_scale)); 1300 EXPECT_EQ(kSmallModeWidth - 1, round((kDualWidth - 1) * ctm1.x_scale));
1260 EXPECT_EQ(0, round((kDualWidth - 1) * ctm1.x_offset)); 1301 EXPECT_EQ(0, round((kDualWidth - 1) * ctm1.x_offset));
1261 1302
1262 EXPECT_EQ(kBigModeWidth - 1, round((kDualWidth - 1) * ctm2.x_scale)); 1303 EXPECT_EQ(kBigModeWidth - 1, round((kDualWidth - 1) * ctm2.x_scale));
1263 EXPECT_EQ(0, round((kDualWidth - 1) * ctm2.x_offset)); 1304 EXPECT_EQ(0, round((kDualWidth - 1) * ctm2.x_offset));
1264 } 1305 }
1265 1306
1307 TEST_F(OutputConfiguratorTest, HandleConfigureCrtcFailure) {
1308 InitWithSingleOutput();
1309
1310 // kFirstMode represents the first mode in the list and
1311 // also the mode that we are requesting the output_configurator
1312 // to choose. The test will be setup so that this mode will fail
1313 // and it will have to choose the next best option.
1314 const int kFirstMode = 11;
1315 int current_mode = kFirstMode;
Daniel Erat 2014/01/09 00:40:34 nit: move this definition down to the place where
1316
1317 // Give the mode_info lists a few reasonable modes.
1318 for (int i = 0; i < 2; i++) {
1319 outputs_[i].mode_infos.clear();
1320
1321 current_mode = kFirstMode;
1322 outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo(
1323 2560, 1600, false, 60.0);
1324 outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo(
1325 1024, 768, false, 60.0);
1326 outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo(
1327 1280, 720, false, 60.0);
1328 outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo(
1329 1920, 1080, false, 60.0);
1330 outputs_[i].mode_infos[current_mode++] = OutputConfigurator::ModeInfo(
1331 1920, 1080, false, 40.0);
1332
1333 outputs_[i].current_mode = kFirstMode;
1334 outputs_[i].native_mode = kFirstMode;
1335 }
1336
1337 configurator_.Init(false);
1338
1339 // First test simply fails in STATE_SINGLE mode. This is probably
1340 // unrealistic but the want to make sure any assumptions don't
1341 // creep in.
1342 delegate_->set_max_configurable_pixels(
1343 outputs_[0].mode_infos[kFirstMode + 2].width *
1344 outputs_[0].mode_infos[kFirstMode + 2].height);
1345 state_controller_.set_state(STATE_SINGLE);
1346 UpdateOutputs(1, true);
1347
1348 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab,
1349 GetFramebufferAction(2560, 1600,
1350 outputs_[0].crtc, 0).c_str(),
1351 GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode,
1352 outputs_[0].output).c_str(),
1353 GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3,
1354 outputs_[0].output).c_str(),
1355 GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 2,
1356 outputs_[0].output).c_str(),
1357 kUngrab, kProjectingOff, NULL),
1358 delegate_->GetActionsAndClear());
1359
1360 // This test should attempt to configure a mirror mode that will not succeed
1361 // and should end up in extended mode.
1362 delegate_->set_max_configurable_pixels(
1363 outputs_[0].mode_infos[kFirstMode + 3].width *
1364 outputs_[0].mode_infos[kFirstMode + 3].height);
1365 state_controller_.set_state(STATE_DUAL_MIRROR);
1366 UpdateOutputs(2, true);
1367
1368 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab,
1369 GetFramebufferAction(
1370 outputs_[0].mode_infos[kFirstMode].width,
1371 outputs_[0].mode_infos[kFirstMode].height,
1372 outputs_[0].crtc,
1373 outputs_[1].crtc).c_str(),
1374 GetCrtcAction(outputs_[0].crtc,
1375 0, 0, kFirstMode, outputs_[0].output).c_str(),
1376 // First mode tried is expected to fail and it will
1377 // retry wil the 4th mode in the list.
1378 GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3,
1379 outputs_[0].output).c_str(),
1380 // Then attempt to configure crtc1 with the first mode.
1381 GetCrtcAction(outputs_[1].crtc, 0, 0, kFirstMode,
1382 outputs_[1].output).c_str(),
1383 GetCrtcAction(outputs_[1].crtc, 0, 0, kFirstMode + 3,
1384 outputs_[1].output).c_str(),
1385 // Since it was requested to go into mirror mode
1386 // and the configured modes were different, it
1387 // should now try and setup a valid configurable
1388 // extended mode.
1389 GetFramebufferAction(
1390 outputs_[0].mode_infos[kFirstMode].width,
1391 outputs_[0].mode_infos[kFirstMode].height +
1392 outputs_[1].mode_infos[kFirstMode].height +
1393 OutputConfigurator::kVerticalGap,
1394 outputs_[0].crtc, outputs_[1].crtc).c_str(),
1395 GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode,
1396 outputs_[0].output).c_str(),
1397 GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3,
1398 outputs_[0].output).c_str(),
1399 GetCrtcAction(outputs_[1].crtc, 0,
1400 outputs_[1].mode_infos[kFirstMode].height +
1401 OutputConfigurator::kVerticalGap, kFirstMode,
1402 outputs_[1].output).c_str(),
1403 GetCrtcAction(outputs_[1].crtc, 0,
1404 outputs_[1].mode_infos[kFirstMode].height +
1405 OutputConfigurator::kVerticalGap, kFirstMode + 3,
1406 outputs_[1].output).c_str(),
1407 kUngrab, kProjectingOn, NULL),
1408 delegate_->GetActionsAndClear());
1409
1410 }
1411
1266 } // namespace chromeos 1412 } // namespace chromeos
OLDNEW
« chromeos/display/output_configurator.cc ('K') | « chromeos/display/output_configurator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698