OLD | NEW |
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 <cstdarg> | 7 #include <cstdarg> |
8 #include <map> | 8 #include <map> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 21 matching lines...) Expand all Loading... |
32 | 32 |
33 // String returned by TestDelegate::GetActionsAndClear() if no actions were | 33 // String returned by TestDelegate::GetActionsAndClear() if no actions were |
34 // requested. | 34 // requested. |
35 const char kNoActions[] = ""; | 35 const char kNoActions[] = ""; |
36 | 36 |
37 // Returns a string describing a TestDelegate::SetBackgroundColor() call. | 37 // Returns a string describing a TestDelegate::SetBackgroundColor() call. |
38 std::string GetBackgroundAction(uint32 color_argb) { | 38 std::string GetBackgroundAction(uint32 color_argb) { |
39 return base::StringPrintf("background(0x%x)", color_argb); | 39 return base::StringPrintf("background(0x%x)", color_argb); |
40 } | 40 } |
41 | 41 |
| 42 // Returns a string describing a TestDelegate::AddOutputMode() call. |
| 43 std::string GetAddOutputModeAction(RROutput output, RRMode mode) { |
| 44 return base::StringPrintf("add_mode(output=%lu,mode=%lu)", output, mode); |
| 45 } |
| 46 |
42 // Returns a string describing a TestDelegate::ConfigureCrtc() call. | 47 // Returns a string describing a TestDelegate::ConfigureCrtc() call. |
43 std::string GetCrtcAction(RRCrtc crtc, | 48 std::string GetCrtcAction(RRCrtc crtc, |
44 int x, | 49 int x, |
45 int y, | 50 int y, |
46 RRMode mode, | 51 RRMode mode, |
47 RROutput output) { | 52 RROutput output) { |
48 return base::StringPrintf("crtc(crtc=%lu,x=%d,y=%d,mode=%lu,output=%lu)", | 53 return base::StringPrintf("crtc(crtc=%lu,x=%d,y=%d,mode=%lu,output=%lu)", |
49 crtc, x, y, mode, output); | 54 crtc, x, y, mode, output); |
50 } | 55 } |
51 | 56 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 // Returns a comma-separated string describing the actions that were | 113 // Returns a comma-separated string describing the actions that were |
109 // requested since the previous call to GetActionsAndClear() (i.e. | 114 // requested since the previous call to GetActionsAndClear() (i.e. |
110 // results are non-repeatable). | 115 // results are non-repeatable). |
111 std::string GetActionsAndClear() { | 116 std::string GetActionsAndClear() { |
112 std::string actions = actions_; | 117 std::string actions = actions_; |
113 actions_.clear(); | 118 actions_.clear(); |
114 return actions; | 119 return actions; |
115 } | 120 } |
116 | 121 |
117 // OutputConfigurator::Delegate overrides: | 122 // OutputConfigurator::Delegate overrides: |
118 virtual void SetPanelFittingEnabled(bool enabled) OVERRIDE {} | |
119 virtual void InitXRandRExtension(int* event_base) OVERRIDE { | 123 virtual void InitXRandRExtension(int* event_base) OVERRIDE { |
120 AppendAction(kInitXRandR); | 124 AppendAction(kInitXRandR); |
121 *event_base = kXRandREventBase; | 125 *event_base = kXRandREventBase; |
122 } | 126 } |
123 virtual void UpdateXRandRConfiguration( | 127 virtual void UpdateXRandRConfiguration( |
124 const base::NativeEvent& event) OVERRIDE { AppendAction(kUpdateXRandR); } | 128 const base::NativeEvent& event) OVERRIDE { AppendAction(kUpdateXRandR); } |
125 virtual void GrabServer() OVERRIDE { AppendAction(kGrab); } | 129 virtual void GrabServer() OVERRIDE { AppendAction(kGrab); } |
126 virtual void UngrabServer() OVERRIDE { AppendAction(kUngrab); } | 130 virtual void UngrabServer() OVERRIDE { AppendAction(kUngrab); } |
127 virtual void SyncWithServer() OVERRIDE { AppendAction(kSync); } | 131 virtual void SyncWithServer() OVERRIDE { AppendAction(kSync); } |
128 virtual void SetBackgroundColor(uint32 color_argb) OVERRIDE { | 132 virtual void SetBackgroundColor(uint32 color_argb) OVERRIDE { |
129 AppendAction(GetBackgroundAction(color_argb)); | 133 AppendAction(GetBackgroundAction(color_argb)); |
130 } | 134 } |
131 virtual void ForceDPMSOn() OVERRIDE { AppendAction(kForceDPMS); } | 135 virtual void ForceDPMSOn() OVERRIDE { AppendAction(kForceDPMS); } |
132 virtual std::vector<OutputConfigurator::OutputSnapshot> GetOutputs( | 136 virtual std::vector<OutputConfigurator::OutputSnapshot> GetOutputs() |
133 const OutputConfigurator::StateController* controller) OVERRIDE { | 137 OVERRIDE { |
134 return outputs_; | 138 return outputs_; |
135 } | 139 } |
| 140 virtual void AddOutputMode(RROutput output, RRMode mode) OVERRIDE { |
| 141 AppendAction(GetAddOutputModeAction(output, mode)); |
| 142 } |
136 virtual bool ConfigureCrtc(RRCrtc crtc, | 143 virtual bool ConfigureCrtc(RRCrtc crtc, |
137 RRMode mode, | 144 RRMode mode, |
138 RROutput output, | 145 RROutput output, |
139 int x, | 146 int x, |
140 int y) OVERRIDE { | 147 int y) OVERRIDE { |
141 AppendAction(GetCrtcAction(crtc, x, y, mode, output)); | 148 AppendAction(GetCrtcAction(crtc, x, y, mode, output)); |
142 return configure_crtc_result_; | 149 return configure_crtc_result_; |
143 } | 150 } |
144 virtual void CreateFrameBuffer( | 151 virtual void CreateFrameBuffer( |
145 int width, | 152 int width, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 : configurator_(configurator) { | 205 : configurator_(configurator) { |
199 Reset(); | 206 Reset(); |
200 configurator_->AddObserver(this); | 207 configurator_->AddObserver(this); |
201 } | 208 } |
202 virtual ~TestObserver() { | 209 virtual ~TestObserver() { |
203 configurator_->RemoveObserver(this); | 210 configurator_->RemoveObserver(this); |
204 } | 211 } |
205 | 212 |
206 int num_changes() const { return num_changes_; } | 213 int num_changes() const { return num_changes_; } |
207 int num_failures() const { return num_failures_; } | 214 int num_failures() const { return num_failures_; } |
208 std::vector<OutputConfigurator::OutputSnapshot> latest_outputs() const { | 215 const std::vector<OutputConfigurator::OutputSnapshot>& latest_outputs() |
| 216 const { |
209 return latest_outputs_; | 217 return latest_outputs_; |
210 } | 218 } |
211 OutputState latest_failed_state() const { return latest_failed_state_; } | 219 OutputState latest_failed_state() const { return latest_failed_state_; } |
212 | 220 |
213 void Reset() { | 221 void Reset() { |
214 num_changes_ = 0; | 222 num_changes_ = 0; |
215 num_failures_ = 0; | 223 num_failures_ = 0; |
216 latest_outputs_.clear(); | 224 latest_outputs_.clear(); |
217 latest_failed_state_ = STATE_INVALID; | 225 latest_failed_state_ = STATE_INVALID; |
218 } | 226 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 } | 290 } |
283 | 291 |
284 private: | 292 private: |
285 bool software_mirroring_enabled_; | 293 bool software_mirroring_enabled_; |
286 | 294 |
287 DISALLOW_COPY_AND_ASSIGN(TestMirroringController); | 295 DISALLOW_COPY_AND_ASSIGN(TestMirroringController); |
288 }; | 296 }; |
289 | 297 |
290 class OutputConfiguratorTest : public testing::Test { | 298 class OutputConfiguratorTest : public testing::Test { |
291 public: | 299 public: |
| 300 // Predefined modes that can be used by outputs. |
| 301 static const RRMode kSmallModeId; |
| 302 static const int kSmallModeWidth; |
| 303 static const int kSmallModeHeight; |
| 304 |
| 305 static const RRMode kBigModeId; |
| 306 static const int kBigModeWidth; |
| 307 static const int kBigModeHeight; |
| 308 |
292 OutputConfiguratorTest() | 309 OutputConfiguratorTest() |
293 : observer_(&configurator_), | 310 : observer_(&configurator_), |
294 test_api_(&configurator_, TestDelegate::kXRandREventBase) {} | 311 test_api_(&configurator_, TestDelegate::kXRandREventBase) {} |
295 virtual ~OutputConfiguratorTest() {} | 312 virtual ~OutputConfiguratorTest() {} |
296 | 313 |
297 virtual void SetUp() OVERRIDE { | 314 virtual void SetUp() OVERRIDE { |
298 delegate_ = new TestDelegate(); | 315 delegate_ = new TestDelegate(); |
299 configurator_.SetDelegateForTesting( | 316 configurator_.SetDelegateForTesting( |
300 scoped_ptr<OutputConfigurator::Delegate>(delegate_)); | 317 scoped_ptr<OutputConfigurator::Delegate>(delegate_)); |
301 configurator_.set_state_controller(&state_controller_); | 318 configurator_.set_state_controller(&state_controller_); |
302 configurator_.set_mirroring_controller(&mirroring_controller_); | 319 configurator_.set_mirroring_controller(&mirroring_controller_); |
303 | 320 |
304 OutputConfigurator::ModeInfo small_mode_info; | 321 OutputConfigurator::ModeInfo small_mode_info; |
305 small_mode_info.width = kSmallModeWidth; | 322 small_mode_info.width = kSmallModeWidth; |
306 small_mode_info.height = kSmallModeHeight; | 323 small_mode_info.height = kSmallModeHeight; |
307 | 324 |
308 OutputConfigurator::ModeInfo big_mode_info; | 325 OutputConfigurator::ModeInfo big_mode_info; |
309 big_mode_info.width = kBigModeWidth; | 326 big_mode_info.width = kBigModeWidth; |
310 big_mode_info.height = kBigModeHeight; | 327 big_mode_info.height = kBigModeHeight; |
311 | 328 |
312 OutputConfigurator::OutputSnapshot* o = &outputs_[0]; | 329 OutputConfigurator::OutputSnapshot* o = &outputs_[0]; |
313 o->output = 1; | 330 o->output = 1; |
314 o->crtc = 10; | 331 o->crtc = 10; |
315 o->current_mode = kSmallModeId; | 332 o->current_mode = kSmallModeId; |
316 o->native_mode = kSmallModeId; | 333 o->native_mode = kSmallModeId; |
317 o->selected_mode = kSmallModeId; | |
318 o->mirror_mode = kSmallModeId; | |
319 o->x = 0; | |
320 o->y = 0; | |
321 o->is_internal = true; | 334 o->is_internal = true; |
322 o->is_aspect_preserving_scaling = true; | 335 o->is_aspect_preserving_scaling = true; |
323 o->mode_infos[kSmallModeId] = small_mode_info; | 336 o->mode_infos[kSmallModeId] = small_mode_info; |
324 o->touch_device_id = 0; | |
325 o->has_display_id = true; | 337 o->has_display_id = true; |
| 338 o->index = 0; |
326 | 339 |
327 o = &outputs_[1]; | 340 o = &outputs_[1]; |
328 o->output = 2; | 341 o->output = 2; |
329 o->crtc = 11; | 342 o->crtc = 11; |
330 o->current_mode = kBigModeId; | 343 o->current_mode = kBigModeId; |
331 o->native_mode = kBigModeId; | 344 o->native_mode = kBigModeId; |
332 o->selected_mode = kBigModeId; | |
333 o->mirror_mode = kSmallModeId; | |
334 o->x = 0; | |
335 o->y = 0; | |
336 o->is_internal = false; | 345 o->is_internal = false; |
337 o->is_aspect_preserving_scaling = true; | 346 o->is_aspect_preserving_scaling = true; |
338 o->mode_infos[kSmallModeId] = small_mode_info; | 347 o->mode_infos[kSmallModeId] = small_mode_info; |
339 o->mode_infos[kBigModeId] = big_mode_info; | 348 o->mode_infos[kBigModeId] = big_mode_info; |
340 o->touch_device_id = 0; | |
341 o->has_display_id = true; | 349 o->has_display_id = true; |
| 350 o->index = 1; |
342 | 351 |
343 UpdateOutputs(2, false); | 352 UpdateOutputs(2, false); |
344 } | 353 } |
345 | 354 |
346 void DisableNativeMirroring() { | |
347 outputs_[0].mirror_mode = outputs_[1].mirror_mode = 0L; | |
348 } | |
349 | |
350 protected: | 355 protected: |
351 // Predefined modes that can be used by outputs. | |
352 static const int kSmallModeId = 20; | |
353 static const int kSmallModeWidth = 1366; | |
354 static const int kSmallModeHeight = 768; | |
355 | |
356 static const int kBigModeId = 21; | |
357 static const int kBigModeWidth = 2560; | |
358 static const int kBigModeHeight = 1600; | |
359 | |
360 // Configures |delegate_| to return the first |num_outputs| entries from | 356 // Configures |delegate_| to return the first |num_outputs| entries from |
361 // |outputs_|. If |send_events| is true, also sends screen-change and | 357 // |outputs_|. If |send_events| is true, also sends screen-change and |
362 // output-change events to |configurator_| and triggers the configure | 358 // output-change events to |configurator_| and triggers the configure |
363 // timeout if one was scheduled. | 359 // timeout if one was scheduled. |
364 void UpdateOutputs(size_t num_outputs, bool send_events) { | 360 void UpdateOutputs(size_t num_outputs, bool send_events) { |
365 ASSERT_LE(num_outputs, arraysize(outputs_)); | 361 ASSERT_LE(num_outputs, arraysize(outputs_)); |
366 std::vector<OutputConfigurator::OutputSnapshot> outputs; | 362 std::vector<OutputConfigurator::OutputSnapshot> outputs; |
367 for (size_t i = 0; i < num_outputs; ++i) | 363 for (size_t i = 0; i < num_outputs; ++i) |
368 outputs.push_back(outputs_[i]); | 364 outputs.push_back(outputs_[i]); |
369 delegate_->set_outputs(outputs); | 365 delegate_->set_outputs(outputs); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 TestObserver observer_; | 399 TestObserver observer_; |
404 TestDelegate* delegate_; // not owned | 400 TestDelegate* delegate_; // not owned |
405 OutputConfigurator::TestApi test_api_; | 401 OutputConfigurator::TestApi test_api_; |
406 | 402 |
407 OutputConfigurator::OutputSnapshot outputs_[2]; | 403 OutputConfigurator::OutputSnapshot outputs_[2]; |
408 | 404 |
409 private: | 405 private: |
410 DISALLOW_COPY_AND_ASSIGN(OutputConfiguratorTest); | 406 DISALLOW_COPY_AND_ASSIGN(OutputConfiguratorTest); |
411 }; | 407 }; |
412 | 408 |
| 409 const RRMode OutputConfiguratorTest::kSmallModeId = 20; |
| 410 const int OutputConfiguratorTest::kSmallModeWidth = 1366; |
| 411 const int OutputConfiguratorTest::kSmallModeHeight = 768; |
| 412 |
| 413 const RRMode OutputConfiguratorTest::kBigModeId = 21; |
| 414 const int OutputConfiguratorTest::kBigModeWidth = 2560; |
| 415 const int OutputConfiguratorTest::kBigModeHeight = 1600; |
| 416 |
413 } // namespace | 417 } // namespace |
414 | 418 |
| 419 TEST_F(OutputConfiguratorTest, FindOutputModeMatchingSize) { |
| 420 OutputConfigurator::OutputSnapshot output; |
| 421 |
| 422 // Fields are width, height, interlaced, refresh rate. |
| 423 output.mode_infos[11] = OutputConfigurator::ModeInfo(1920, 1200, false, 60.0); |
| 424 // Different rates. |
| 425 output.mode_infos[12] = OutputConfigurator::ModeInfo(1920, 1080, false, 30.0); |
| 426 output.mode_infos[13] = OutputConfigurator::ModeInfo(1920, 1080, false, 50.0); |
| 427 output.mode_infos[14] = OutputConfigurator::ModeInfo(1920, 1080, false, 40.0); |
| 428 output.mode_infos[15] = OutputConfigurator::ModeInfo(1920, 1080, false, 0.0); |
| 429 // Interlaced vs non-interlaced. |
| 430 output.mode_infos[16] = OutputConfigurator::ModeInfo(1280, 720, true, 60.0); |
| 431 output.mode_infos[17] = OutputConfigurator::ModeInfo(1280, 720, false, 40.0); |
| 432 // Interlaced only. |
| 433 output.mode_infos[18] = OutputConfigurator::ModeInfo(1024, 768, true, 0.0); |
| 434 output.mode_infos[19] = OutputConfigurator::ModeInfo(1024, 768, true, 40.0); |
| 435 output.mode_infos[20] = OutputConfigurator::ModeInfo(1024, 768, true, 60.0); |
| 436 // Mixed. |
| 437 output.mode_infos[21] = OutputConfigurator::ModeInfo(1024, 600, true, 60.0); |
| 438 output.mode_infos[22] = OutputConfigurator::ModeInfo(1024, 600, false, 40.0); |
| 439 output.mode_infos[23] = OutputConfigurator::ModeInfo(1024, 600, false, 50.0); |
| 440 // Just one interlaced mode. |
| 441 output.mode_infos[24] = OutputConfigurator::ModeInfo(640, 480, true, 60.0); |
| 442 // Refresh rate not available. |
| 443 output.mode_infos[25] = OutputConfigurator::ModeInfo(320, 200, false, 0.0); |
| 444 |
| 445 EXPECT_EQ(11u, OutputConfigurator::FindOutputModeMatchingSize(output, |
| 446 1920, 1200)); |
| 447 |
| 448 // Should pick highest refresh rate. |
| 449 EXPECT_EQ(13u, OutputConfigurator::FindOutputModeMatchingSize(output, |
| 450 1920, 1080)); |
| 451 |
| 452 // Should pick non-interlaced mode. |
| 453 EXPECT_EQ(17u, OutputConfigurator::FindOutputModeMatchingSize(output, |
| 454 1280, 720)); |
| 455 |
| 456 // Interlaced only. Should pick one with the highest refresh rate in |
| 457 // interlaced mode. |
| 458 EXPECT_EQ(20u, OutputConfigurator::FindOutputModeMatchingSize(output, |
| 459 1024, 768)); |
| 460 |
| 461 // Mixed: Should pick one with the highest refresh rate in |
| 462 // interlaced mode. |
| 463 EXPECT_EQ(23u, OutputConfigurator::FindOutputModeMatchingSize(output, |
| 464 1024, 600)); |
| 465 |
| 466 // Just one interlaced mode. |
| 467 EXPECT_EQ(24u, OutputConfigurator::FindOutputModeMatchingSize(output, |
| 468 640, 480)); |
| 469 |
| 470 // Refresh rate not available. |
| 471 EXPECT_EQ(25u, OutputConfigurator::FindOutputModeMatchingSize(output, |
| 472 320, 200)); |
| 473 |
| 474 // No mode found. |
| 475 EXPECT_EQ(0u, OutputConfigurator::FindOutputModeMatchingSize(output, |
| 476 1440, 900)); |
| 477 } |
| 478 |
415 TEST_F(OutputConfiguratorTest, ConnectSecondOutput) { | 479 TEST_F(OutputConfiguratorTest, ConnectSecondOutput) { |
416 InitWithSingleOutput(); | 480 InitWithSingleOutput(); |
417 | 481 |
418 // Connect a second output and check that the configurator enters | 482 // Connect a second output and check that the configurator enters |
419 // extended mode. | 483 // extended mode. |
420 observer_.Reset(); | 484 observer_.Reset(); |
421 state_controller_.set_state(STATE_DUAL_EXTENDED); | 485 state_controller_.set_state(STATE_DUAL_EXTENDED); |
422 UpdateOutputs(2, true); | 486 UpdateOutputs(2, true); |
423 const int kDualHeight = | 487 const int kDualHeight = |
424 kSmallModeHeight + OutputConfigurator::kVerticalGap + kBigModeHeight; | 488 kSmallModeHeight + OutputConfigurator::kVerticalGap + kBigModeHeight; |
(...skipping 30 matching lines...) Expand all Loading... |
455 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, | 519 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, |
456 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, | 520 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, |
457 outputs_[0].crtc, 0).c_str(), | 521 outputs_[0].crtc, 0).c_str(), |
458 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, | 522 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, |
459 outputs_[0].output).c_str(), | 523 outputs_[0].output).c_str(), |
460 kUngrab, kProjectingOff, NULL), | 524 kUngrab, kProjectingOff, NULL), |
461 delegate_->GetActionsAndClear()); | 525 delegate_->GetActionsAndClear()); |
462 EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); | 526 EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); |
463 EXPECT_EQ(1, observer_.num_changes()); | 527 EXPECT_EQ(1, observer_.num_changes()); |
464 | 528 |
465 // Software Mirroring | 529 // Get rid of shared modes to force software mirroring. |
466 DisableNativeMirroring(); | 530 outputs_[1].mode_infos.erase(kSmallModeId); |
467 state_controller_.set_state(STATE_DUAL_EXTENDED); | 531 state_controller_.set_state(STATE_DUAL_EXTENDED); |
468 UpdateOutputs(2, true); | 532 UpdateOutputs(2, true); |
469 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, | 533 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, |
470 GetFramebufferAction(kBigModeWidth, kDualHeight, | 534 GetFramebufferAction(kBigModeWidth, kDualHeight, |
471 outputs_[0].crtc, outputs_[1].crtc).c_str(), | 535 outputs_[0].crtc, outputs_[1].crtc).c_str(), |
472 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, | 536 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, |
473 outputs_[0].output).c_str(), | 537 outputs_[0].output).c_str(), |
474 GetCrtcAction(outputs_[1].crtc, 0, | 538 GetCrtcAction(outputs_[1].crtc, 0, |
475 kSmallModeHeight + OutputConfigurator::kVerticalGap, | 539 kSmallModeHeight + OutputConfigurator::kVerticalGap, |
476 kBigModeId, outputs_[1].output).c_str(), | 540 kBigModeId, outputs_[1].output).c_str(), |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, | 642 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, |
579 outputs_[0].output).c_str(), | 643 outputs_[0].output).c_str(), |
580 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, | 644 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, |
581 outputs_[1].output).c_str(), | 645 outputs_[1].output).c_str(), |
582 kForceDPMS, kUngrab, NULL), | 646 kForceDPMS, kUngrab, NULL), |
583 delegate_->GetActionsAndClear()); | 647 delegate_->GetActionsAndClear()); |
584 EXPECT_EQ(STATE_DUAL_MIRROR, configurator_.output_state()); | 648 EXPECT_EQ(STATE_DUAL_MIRROR, configurator_.output_state()); |
585 EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); | 649 EXPECT_FALSE(mirroring_controller_.software_mirroring_enabled()); |
586 EXPECT_EQ(1, observer_.num_changes()); | 650 EXPECT_EQ(1, observer_.num_changes()); |
587 | 651 |
588 // Software Mirroring | 652 // Get rid of shared modes to force software mirroring. |
589 DisableNativeMirroring(); | 653 outputs_[1].mode_infos.erase(kSmallModeId); |
590 state_controller_.set_state(STATE_DUAL_MIRROR); | 654 state_controller_.set_state(STATE_DUAL_MIRROR); |
591 observer_.Reset(); | 655 observer_.Reset(); |
592 UpdateOutputs(2, true); | 656 UpdateOutputs(2, true); |
593 const int kDualHeight = | 657 const int kDualHeight = |
594 kSmallModeHeight + OutputConfigurator::kVerticalGap + kBigModeHeight; | 658 kSmallModeHeight + OutputConfigurator::kVerticalGap + kBigModeHeight; |
595 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, | 659 EXPECT_EQ(JoinActions(kUpdateXRandR, kGrab, |
596 GetFramebufferAction(kBigModeWidth, kDualHeight, | 660 GetFramebufferAction(kBigModeWidth, kDualHeight, |
597 outputs_[0].crtc, outputs_[1].crtc).c_str(), | 661 outputs_[0].crtc, outputs_[1].crtc).c_str(), |
598 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, | 662 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, |
599 outputs_[0].output).c_str(), | 663 outputs_[0].output).c_str(), |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, | 1007 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, |
944 outputs_[0].crtc, outputs_[1].crtc).c_str(), | 1008 outputs_[0].crtc, outputs_[1].crtc).c_str(), |
945 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, | 1009 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, |
946 outputs_[0].output).c_str(), | 1010 outputs_[0].output).c_str(), |
947 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, | 1011 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, |
948 outputs_[1].output).c_str(), | 1012 outputs_[1].output).c_str(), |
949 kUngrab, kProjectingOn, NULL), | 1013 kUngrab, kProjectingOn, NULL), |
950 delegate_->GetActionsAndClear()); | 1014 delegate_->GetActionsAndClear()); |
951 } | 1015 } |
952 | 1016 |
| 1017 TEST_F(OutputConfiguratorTest, PanelFitting) { |
| 1018 // Configure the internal display to support only the big mode and the |
| 1019 // external display to support only the small mode. |
| 1020 outputs_[0].current_mode = kBigModeId; |
| 1021 outputs_[0].native_mode = kBigModeId; |
| 1022 outputs_[0].mode_infos.clear(); |
| 1023 outputs_[0].mode_infos[kBigModeId] = OutputConfigurator::ModeInfo( |
| 1024 kBigModeWidth, kBigModeHeight, false, 60.0); |
| 1025 |
| 1026 outputs_[1].current_mode = kSmallModeId; |
| 1027 outputs_[1].native_mode = kSmallModeId; |
| 1028 outputs_[1].mode_infos.clear(); |
| 1029 outputs_[1].mode_infos[kSmallModeId] = OutputConfigurator::ModeInfo( |
| 1030 kSmallModeWidth, kSmallModeHeight, false, 60.0); |
| 1031 |
| 1032 // The small mode should be added to the internal output when requesting |
| 1033 // mirrored mode. |
| 1034 UpdateOutputs(2, false); |
| 1035 state_controller_.set_state(STATE_DUAL_MIRROR); |
| 1036 configurator_.Init(true /* is_panel_fitting_enabled */); |
| 1037 configurator_.Start(0); |
| 1038 EXPECT_EQ(STATE_DUAL_MIRROR, configurator_.output_state()); |
| 1039 EXPECT_EQ(JoinActions(kGrab, kInitXRandR, |
| 1040 GetAddOutputModeAction( |
| 1041 outputs_[0].output, kSmallModeId).c_str(), |
| 1042 GetFramebufferAction(kSmallModeWidth, kSmallModeHeight, |
| 1043 outputs_[0].crtc, outputs_[1].crtc).c_str(), |
| 1044 GetCrtcAction(outputs_[0].crtc, 0, 0, kSmallModeId, |
| 1045 outputs_[0].output).c_str(), |
| 1046 GetCrtcAction(outputs_[1].crtc, 0, 0, kSmallModeId, |
| 1047 outputs_[1].output).c_str(), |
| 1048 kForceDPMS, kUngrab, kProjectingOn, NULL), |
| 1049 delegate_->GetActionsAndClear()); |
| 1050 |
| 1051 // Both outputs should be using the small mode. |
| 1052 ASSERT_EQ(1, observer_.num_changes()); |
| 1053 ASSERT_EQ(static_cast<size_t>(2), observer_.latest_outputs().size()); |
| 1054 EXPECT_EQ(kSmallModeId, observer_.latest_outputs()[0].mirror_mode); |
| 1055 EXPECT_EQ(kSmallModeId, observer_.latest_outputs()[0].current_mode); |
| 1056 EXPECT_EQ(kSmallModeId, observer_.latest_outputs()[1].mirror_mode); |
| 1057 EXPECT_EQ(kSmallModeId, observer_.latest_outputs()[1].current_mode); |
| 1058 |
| 1059 // Also check that the newly-added small mode is present in the internal |
| 1060 // snapshot that was passed to the observer (http://crbug.com/289159). |
| 1061 const OutputConfigurator::ModeInfo* info = OutputConfigurator::GetModeInfo( |
| 1062 observer_.latest_outputs()[0], kSmallModeId); |
| 1063 ASSERT_TRUE(info); |
| 1064 EXPECT_EQ(kSmallModeWidth, info->width); |
| 1065 EXPECT_EQ(kSmallModeHeight, info->height); |
| 1066 } |
| 1067 |
953 } // namespace chromeos | 1068 } // namespace chromeos |
OLD | NEW |