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

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

Powered by Google App Engine
This is Rietveld 408576698