| 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 |