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

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: Update unittest and response to code review 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 // max_configurable_pixels_ represents the maximum number of pixels that
118 configure_crtc_result_ = result; 118 // ConfigureCrtc will support. Tests can use this to force ConfigureCrtc
119 // to fail if attempting to set a resolution that is higher than what
120 // a device might support under a given circumstance.
121 // A value of 0 means that no limit is enforced and ConfigureCrtc will
122 // 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.
123 void set_max_configurable_pixels(int pixels) {
124 max_configurable_pixels_ = pixels;
119 } 125 }
120 126
121 void set_hdcp_state(HDCPState state) { hdcp_state_ = state; } 127 void set_hdcp_state(HDCPState state) { hdcp_state_ = state; }
122 128
123 // Returns a comma-separated string describing the actions that were 129 // Returns a comma-separated string describing the actions that were
124 // requested since the previous call to GetActionsAndClear() (i.e. 130 // requested since the previous call to GetActionsAndClear() (i.e.
125 // results are non-repeatable). 131 // results are non-repeatable).
126 std::string GetActionsAndClear() { 132 std::string GetActionsAndClear() {
127 std::string actions = actions_; 133 std::string actions = actions_;
128 actions_.clear(); 134 actions_.clear();
(...skipping 18 matching lines...) Expand all
147 virtual void SetBackgroundColor(uint32 color_argb) OVERRIDE { 153 virtual void SetBackgroundColor(uint32 color_argb) OVERRIDE {
148 AppendAction(GetBackgroundAction(color_argb)); 154 AppendAction(GetBackgroundAction(color_argb));
149 } 155 }
150 virtual void ForceDPMSOn() OVERRIDE { AppendAction(kForceDPMS); } 156 virtual void ForceDPMSOn() OVERRIDE { AppendAction(kForceDPMS); }
151 virtual std::vector<OutputConfigurator::OutputSnapshot> GetOutputs() 157 virtual std::vector<OutputConfigurator::OutputSnapshot> GetOutputs()
152 OVERRIDE { 158 OVERRIDE {
153 return outputs_; 159 return outputs_;
154 } 160 }
155 virtual void AddOutputMode(RROutput output, RRMode mode) OVERRIDE { 161 virtual void AddOutputMode(RROutput output, RRMode mode) OVERRIDE {
156 AppendAction(GetAddOutputModeAction(output, mode)); 162 AppendAction(GetAddOutputModeAction(output, mode));
163 OutputConfigurator::OutputSnapshot* snapshot =
164 GetOutputFromId(output);
165 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
166 snapshot->mode_infos[mode] =
167 *OutputConfigurator::GetModeInfo(*snapshot, mode);
Daniel Erat 2014/01/08 21:40:28 probably also want to check GetModeInfo()'s return
168 }
157 } 169 }
158 virtual bool ConfigureCrtc(RRCrtc crtc, 170 virtual bool ConfigureCrtc(RRCrtc crtc,
159 RRMode mode, 171 RRMode mode,
160 RROutput output, 172 RROutput output,
161 int x, 173 int x,
162 int y) OVERRIDE { 174 int y) OVERRIDE {
163 AppendAction(GetCrtcAction(crtc, x, y, mode, output)); 175 AppendAction(GetCrtcAction(crtc, x, y, mode, output));
164 return configure_crtc_result_; 176
177 // |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.
178 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.
179 return true;
180 }
181
182 OutputConfigurator::OutputSnapshot* snapshot = GetOutputFromId(output);
183 if (snapshot) {
Daniel Erat 2014/01/08 21:40:28 nit: if (!snapshot) return false; const
dsodman 2014/01/09 00:26:28 Done.
184 const OutputConfigurator::ModeInfo* mode_info =
185 OutputConfigurator::GetModeInfo(*snapshot, mode);
186
187 if (mode_info)
188 return mode_info->width * mode_info->height <= max_configurable_pixels_;
189 }
190
191 return false;
165 } 192 }
166 virtual void CreateFrameBuffer( 193 virtual void CreateFrameBuffer(
167 int width, 194 int width,
168 int height, 195 int height,
169 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) OVERRIDE { 196 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) OVERRIDE {
170 AppendAction( 197 AppendAction(
171 GetFramebufferAction(width, 198 GetFramebufferAction(width,
172 height, 199 height,
173 outputs.size() >= 1 ? outputs[0].crtc : 0, 200 outputs.size() >= 1 ? outputs[0].crtc : 0,
174 outputs.size() >= 2 ? outputs[1].crtc : 0)); 201 outputs.size() >= 2 ? outputs[1].crtc : 0));
(...skipping 30 matching lines...) Expand all
205 int height; 232 int height;
206 bool interlaced; 233 bool interlaced;
207 }; 234 };
208 235
209 void AppendAction(const std::string& action) { 236 void AppendAction(const std::string& action) {
210 if (!actions_.empty()) 237 if (!actions_.empty())
211 actions_ += ","; 238 actions_ += ",";
212 actions_ += action; 239 actions_ += action;
213 } 240 }
214 241
242 OutputConfigurator::OutputSnapshot* GetOutputFromId(RROutput output_id) {
243 for (unsigned int i = 0; i < outputs_.size(); i++) {
244 if (outputs_[i].output == output_id)
245 return &outputs_[i];
246 }
247 return NULL;
248 }
249
215 std::map<RRMode, ModeDetails> modes_; 250 std::map<RRMode, ModeDetails> modes_;
216 251
217 // Most-recently-configured transformation matrices, keyed by touch device ID. 252 // Most-recently-configured transformation matrices, keyed by touch device ID.
218 std::map<int, OutputConfigurator::CoordinateTransformation> ctms_; 253 std::map<int, OutputConfigurator::CoordinateTransformation> ctms_;
219 254
220 // Outputs to be returned by GetOutputs(). 255 // Outputs to be returned by GetOutputs().
221 std::vector<OutputConfigurator::OutputSnapshot> outputs_; 256 std::vector<OutputConfigurator::OutputSnapshot> outputs_;
222 257
223 std::string actions_; 258 std::string actions_;
224 259
225 // Return value returned by ConfigureCrtc(). 260 // Represents the maximum number of pixels that a modeset can handle. Any
226 bool configure_crtc_result_; 261 // attempt to set a resolution with more pixels will fail.
262 int max_configurable_pixels_;
227 263
228 // Result value of GetHDCPState(). 264 // Result value of GetHDCPState().
229 HDCPState hdcp_state_; 265 HDCPState hdcp_state_;
230 266
231 DISALLOW_COPY_AND_ASSIGN(TestDelegate); 267 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
232 }; 268 };
233 269
234 class TestObserver : public OutputConfigurator::Observer { 270 class TestObserver : public OutputConfigurator::Observer {
235 public: 271 public:
236 explicit TestObserver(OutputConfigurator* configurator) 272 explicit TestObserver(OutputConfigurator* configurator)
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 kUngrab, kProjectingOff, NULL), 1048 kUngrab, kProjectingOff, NULL),
1013 delegate_->GetActionsAndClear()); 1049 delegate_->GetActionsAndClear());
1014 1050
1015 // An additional event about the second output being disconnected should 1051 // An additional event about the second output being disconnected should
1016 // be ignored. 1052 // be ignored.
1017 test_api_.SendOutputChangeEvent( 1053 test_api_.SendOutputChangeEvent(
1018 outputs_[1].output, outputs_[1].crtc, outputs_[1].current_mode, false); 1054 outputs_[1].output, outputs_[1].crtc, outputs_[1].current_mode, false);
1019 EXPECT_FALSE(test_api_.TriggerConfigureTimeout()); 1055 EXPECT_FALSE(test_api_.TriggerConfigureTimeout());
1020 EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear()); 1056 EXPECT_EQ(kNoActions, delegate_->GetActionsAndClear());
1021 1057
1022 // Tell the delegate to report failure, which should result in the 1058 // Lower the limit for which the delegate will succeed, which should result
1023 // second output sticking with its native mode. 1059 // in the second output sticking with its native mode.
1024 delegate_->set_configure_crtc_result(false); 1060 delegate_->set_max_configurable_pixels(1);
1025 UpdateOutputs(2, true); 1061 UpdateOutputs(2, true);
1026 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, 1062 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab,
1027 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, 1063 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight,
1028 outputs_[0].crtc, outputs_[1].crtc).c_str(), 1064 outputs_[0].crtc, outputs_[1].crtc).c_str(),
1029 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, 1065 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId,
1030 outputs_[0].output).c_str(), 1066 outputs_[0].output).c_str(),
1031 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, 1067 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId,
1032 outputs_[1].output).c_str(), 1068 outputs_[1].output).c_str(),
1033 kUngrab, kProjectingOn, NULL), 1069 kUngrab, kProjectingOn, NULL),
1034 delegate_->GetActionsAndClear()); 1070 delegate_->GetActionsAndClear());
1035 1071
1036 // An change event reporting a mode change on the second output should 1072 // A change event reporting a mode change on the second output should
1037 // trigger another reconfigure. 1073 // trigger another reconfigure.
1038 delegate_->set_configure_crtc_result(true); 1074 delegate_->set_max_configurable_pixels(0);
1039 test_api_.SendOutputChangeEvent( 1075 test_api_.SendOutputChangeEvent(
1040 outputs_[1].output, outputs_[1].crtc, outputs_[1].mirror_mode, true); 1076 outputs_[1].output, outputs_[1].crtc, outputs_[1].mirror_mode, true);
1041 EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); 1077 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
1042 EXPECT_EQ(JoinActions(kGrab, 1078 EXPECT_EQ(JoinActions(kGrab,
1043 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, 1079 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight,
1044 outputs_[0].crtc, outputs_[1].crtc).c_str(), 1080 outputs_[0].crtc, outputs_[1].crtc).c_str(),
1045 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, 1081 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId,
1046 outputs_[0].output).c_str(), 1082 outputs_[0].output).c_str(),
1047 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, 1083 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId,
1048 outputs_[1].output).c_str(), 1084 outputs_[1].output).c_str(),
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 EXPECT_EQ(kSmallModeHeight + OutputConfigurator::kVerticalGap, 1292 EXPECT_EQ(kSmallModeHeight + OutputConfigurator::kVerticalGap,
1257 round((kDualHeight - 1) * ctm2.y_offset)); 1293 round((kDualHeight - 1) * ctm2.y_offset));
1258 1294
1259 EXPECT_EQ(kSmallModeWidth - 1, round((kDualWidth - 1) * ctm1.x_scale)); 1295 EXPECT_EQ(kSmallModeWidth - 1, round((kDualWidth - 1) * ctm1.x_scale));
1260 EXPECT_EQ(0, round((kDualWidth - 1) * ctm1.x_offset)); 1296 EXPECT_EQ(0, round((kDualWidth - 1) * ctm1.x_offset));
1261 1297
1262 EXPECT_EQ(kBigModeWidth - 1, round((kDualWidth - 1) * ctm2.x_scale)); 1298 EXPECT_EQ(kBigModeWidth - 1, round((kDualWidth - 1) * ctm2.x_scale));
1263 EXPECT_EQ(0, round((kDualWidth - 1) * ctm2.x_offset)); 1299 EXPECT_EQ(0, round((kDualWidth - 1) * ctm2.x_offset));
1264 } 1300 }
1265 1301
1302 TEST_F(OutputConfiguratorTest, HandleConfigureCrtcFailure) {
1303 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.
1304 InitWithSingleOutput();
1305 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
1306 EXPECT_EQ(kUpdateXRandR, delegate_->GetActionsAndClear());
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 (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,
1316 outputs_[i].mode_infos.clear();
1317
1318 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].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.
1331 outputs_[i].native_mode = kFirstMode;
1332 }
1333
1334 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.
1335 configurator_.Init(false);
1336
1337 // First test simply fails in STATE_SINGLE mode. This is probably
1338 // unrealistic but the want to make sure any assumptions don't
1339 // creep in.
1340 delegate_->set_max_configurable_pixels(
1341 outputs_[0].mode_infos[kFirstMode + 2].width *
1342 outputs_[0].mode_infos[kFirstMode + 2].height);
1343 state_controller_.set_state(STATE_SINGLE);
1344 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
1345 outputs_[0].output, outputs_[0].crtc, outputs_[0].selected_mode, true);
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 test_api_.SendOutputChangeEvent(
Daniel Erat 2014/01/08 21:40:28 same here
dsodman 2014/01/09 00:26:28 Done.
1367 outputs_[1].output, outputs_[1].crtc, outputs_[1].selected_mode, true);
1368 UpdateOutputs(2, true);
1369
1370 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab,
1371 GetFramebufferAction(
1372 outputs_[0].mode_infos[kFirstMode].width,
1373 outputs_[0].mode_infos[kFirstMode].height,
1374 outputs_[0].crtc,
1375 outputs_[1].crtc).c_str(),
1376 GetCrtcAction(outputs_[0].crtc,
1377 0, 0, kFirstMode, outputs_[0].output).c_str(),
1378 // First mode tried is expected to fail and it will
1379 // retry wil the 4th mode in the list.
1380 GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3,
1381 outputs_[0].output).c_str(),
1382 // Then attempt to configure crtc1 with the first mode.
1383 GetCrtcAction(outputs_[1].crtc, 0, 0, kFirstMode,
1384 outputs_[1].output).c_str(),
1385 GetCrtcAction(outputs_[1].crtc, 0, 0, kFirstMode + 3,
1386 outputs_[1].output).c_str(),
1387 // Since it was requested to go into mirror mode
1388 // and the configured modes were different, it
1389 // should now try and setup a valid configurable
1390 // extended mode.
1391 GetFramebufferAction(
1392 outputs_[0].mode_infos[kFirstMode].width,
1393 outputs_[0].mode_infos[kFirstMode].height +
1394 outputs_[1].mode_infos[kFirstMode].height +
1395 OutputConfigurator::kVerticalGap,
1396 outputs_[0].crtc, outputs_[1].crtc).c_str(),
1397 GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode,
1398 outputs_[0].output).c_str(),
1399 GetCrtcAction(outputs_[0].crtc, 0, 0, kFirstMode + 3,
1400 outputs_[0].output).c_str(),
1401 GetCrtcAction(outputs_[1].crtc, 0,
1402 outputs_[1].mode_infos[kFirstMode].height +
1403 OutputConfigurator::kVerticalGap, kFirstMode,
1404 outputs_[1].output).c_str(),
1405 GetCrtcAction(outputs_[1].crtc, 0,
1406 outputs_[1].mode_infos[kFirstMode].height +
1407 OutputConfigurator::kVerticalGap, kFirstMode + 3,
1408 outputs_[1].output).c_str(),
1409 kUngrab, kProjectingOn, NULL),
1410 delegate_->GetActionsAndClear());
1411
1412 }
1413
1266 } // namespace chromeos 1414 } // 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