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 "ash/display/display_manager.h" | 5 #include "ash/display/display_manager.h" |
6 | 6 |
| 7 #include <algorithm> |
7 #include <cmath> | 8 #include <cmath> |
8 #include <set> | 9 #include <set> |
9 #include <string> | 10 #include <string> |
10 #include <vector> | 11 #include <vector> |
11 | 12 |
12 #include "ash/ash_switches.h" | 13 #include "ash/ash_switches.h" |
13 #include "ash/display/display_layout_store.h" | 14 #include "ash/display/display_layout_store.h" |
14 #include "ash/display/screen_ash.h" | 15 #include "ash/display/screen_ash.h" |
15 #include "ash/screen_util.h" | 16 #include "ash/screen_util.h" |
16 #include "ash/shell.h" | 17 #include "ash/shell.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 } | 76 } |
76 }; | 77 }; |
77 | 78 |
78 struct DisplayInfoSortFunctor { | 79 struct DisplayInfoSortFunctor { |
79 bool operator()(const DisplayInfo& a, const DisplayInfo& b) { | 80 bool operator()(const DisplayInfo& a, const DisplayInfo& b) { |
80 return a.id() < b.id(); | 81 return a.id() < b.id(); |
81 } | 82 } |
82 }; | 83 }; |
83 | 84 |
84 struct DisplayModeMatcher { | 85 struct DisplayModeMatcher { |
85 DisplayModeMatcher(const gfx::Size& size) : size(size) {} | 86 DisplayModeMatcher(const DisplayMode& target_mode) |
86 bool operator()(const DisplayMode& mode) { return mode.size == size; } | 87 : target_mode(target_mode) {} |
87 gfx::Size size; | 88 bool operator()(const DisplayMode& mode) { |
| 89 return target_mode.IsEquivalent(mode); |
| 90 } |
| 91 DisplayMode target_mode; |
88 }; | 92 }; |
89 | 93 |
90 struct ScaleComparator { | 94 struct ScaleComparator { |
91 explicit ScaleComparator(float s) : scale(s) {} | 95 explicit ScaleComparator(float s) : scale(s) {} |
92 | 96 |
93 bool operator()(float s) const { | 97 bool operator()(float s) const { |
94 const float kEpsilon = 0.0001f; | 98 const float kEpsilon = 0.0001f; |
95 return std::abs(scale - s) < kEpsilon; | 99 return std::abs(scale - s) < kEpsilon; |
96 } | 100 } |
97 float scale; | 101 float scale; |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 UpdateDisplays(display_info_list); | 426 UpdateDisplays(display_info_list); |
423 } | 427 } |
424 | 428 |
425 void DisplayManager::SetDisplayUIScale(int64 display_id, | 429 void DisplayManager::SetDisplayUIScale(int64 display_id, |
426 float ui_scale) { | 430 float ui_scale) { |
427 if (!IsDisplayUIScalingEnabled() || | 431 if (!IsDisplayUIScalingEnabled() || |
428 gfx::Display::InternalDisplayId() != display_id) { | 432 gfx::Display::InternalDisplayId() != display_id) { |
429 return; | 433 return; |
430 } | 434 } |
431 | 435 |
| 436 // TODO(mukai): merge this implementation into SetDisplayMode(). |
432 DisplayInfoList display_info_list; | 437 DisplayInfoList display_info_list; |
433 for (DisplayList::const_iterator iter = displays_.begin(); | 438 for (DisplayList::const_iterator iter = displays_.begin(); |
434 iter != displays_.end(); ++iter) { | 439 iter != displays_.end(); ++iter) { |
435 DisplayInfo info = GetDisplayInfo(iter->id()); | 440 DisplayInfo info = GetDisplayInfo(iter->id()); |
436 if (info.id() == display_id) { | 441 if (info.id() == display_id) { |
437 if (info.configured_ui_scale() == ui_scale) | 442 if (info.configured_ui_scale() == ui_scale) |
438 return; | 443 return; |
439 std::vector<float> scales = GetScalesForDisplay(info); | 444 std::vector<float> scales = GetScalesForDisplay(info); |
440 ScaleComparator comparator(ui_scale); | 445 ScaleComparator comparator(ui_scale); |
441 if (std::find_if(scales.begin(), scales.end(), comparator) == | 446 if (std::find_if(scales.begin(), scales.end(), comparator) == |
442 scales.end()) { | 447 scales.end()) { |
443 return; | 448 return; |
444 } | 449 } |
445 info.set_configured_ui_scale(ui_scale); | 450 info.set_configured_ui_scale(ui_scale); |
446 } | 451 } |
447 display_info_list.push_back(info); | 452 display_info_list.push_back(info); |
448 } | 453 } |
449 AddMirrorDisplayInfoIfAny(&display_info_list); | 454 AddMirrorDisplayInfoIfAny(&display_info_list); |
450 UpdateDisplays(display_info_list); | 455 UpdateDisplays(display_info_list); |
451 } | 456 } |
452 | 457 |
453 void DisplayManager::SetDisplayResolution(int64 display_id, | 458 void DisplayManager::SetDisplayResolution(int64 display_id, |
454 const gfx::Size& resolution) { | 459 const gfx::Size& resolution) { |
455 DCHECK_NE(gfx::Display::InternalDisplayId(), display_id); | 460 DCHECK_NE(gfx::Display::InternalDisplayId(), display_id); |
456 if (gfx::Display::InternalDisplayId() == display_id) | 461 if (gfx::Display::InternalDisplayId() == display_id) |
457 return; | 462 return; |
458 const DisplayInfo& display_info = GetDisplayInfo(display_id); | 463 const DisplayInfo& display_info = GetDisplayInfo(display_id); |
459 const std::vector<DisplayMode>& modes = display_info.display_modes(); | 464 const std::vector<DisplayMode>& modes = display_info.display_modes(); |
460 DCHECK_NE(0u, modes.size()); | 465 DCHECK_NE(0u, modes.size()); |
| 466 DisplayMode target_mode; |
| 467 target_mode.size = resolution; |
461 std::vector<DisplayMode>::const_iterator iter = | 468 std::vector<DisplayMode>::const_iterator iter = |
462 std::find_if(modes.begin(), modes.end(), DisplayModeMatcher(resolution)); | 469 std::find_if(modes.begin(), modes.end(), DisplayModeMatcher(target_mode)); |
463 if (iter == modes.end()) { | 470 if (iter == modes.end()) { |
464 LOG(WARNING) << "Unsupported resolution was requested:" | 471 LOG(WARNING) << "Unsupported resolution was requested:" |
465 << resolution.ToString(); | 472 << resolution.ToString(); |
466 return; | 473 return; |
467 } | 474 } |
468 display_modes_[display_id] = *iter; | 475 display_modes_[display_id] = *iter; |
469 #if defined(OS_CHROMEOS) | 476 #if defined(OS_CHROMEOS) |
470 if (base::SysInfo::IsRunningOnChromeOS()) | 477 if (base::SysInfo::IsRunningOnChromeOS()) |
471 Shell::GetInstance()->display_configurator()->OnConfigurationChanged(); | 478 Shell::GetInstance()->display_configurator()->OnConfigurationChanged(); |
472 #endif | 479 #endif |
473 } | 480 } |
474 | 481 |
| 482 bool DisplayManager::SetDisplayMode(int64 display_id, |
| 483 const DisplayMode& display_mode) { |
| 484 if (IsInternalDisplayId(display_id)) { |
| 485 SetDisplayUIScale(display_id, display_mode.ui_scale); |
| 486 return false; |
| 487 } |
| 488 |
| 489 DisplayInfoList display_info_list; |
| 490 bool display_property_changed = false; |
| 491 bool resolution_changed = false; |
| 492 for (DisplayList::const_iterator iter = displays_.begin(); |
| 493 iter != displays_.end(); ++iter) { |
| 494 DisplayInfo info = GetDisplayInfo(iter->id()); |
| 495 if (info.id() == display_id) { |
| 496 const std::vector<DisplayMode>& modes = info.display_modes(); |
| 497 std::vector<DisplayMode>::const_iterator iter = |
| 498 std::find_if(modes.begin(), |
| 499 modes.end(), |
| 500 DisplayModeMatcher(display_mode)); |
| 501 if (iter == modes.end()) { |
| 502 LOG(WARNING) << "Unsupported resolution was requested:" |
| 503 << display_mode.size.ToString(); |
| 504 return false; |
| 505 } |
| 506 display_modes_[display_id] = *iter; |
| 507 if (info.bounds_in_native().size() != display_mode.size) |
| 508 resolution_changed = true; |
| 509 if (info.device_scale_factor() != display_mode.device_scale_factor) { |
| 510 info.set_device_scale_factor(display_mode.device_scale_factor); |
| 511 display_property_changed = true; |
| 512 } |
| 513 } |
| 514 display_info_list.push_back(info); |
| 515 } |
| 516 if (display_property_changed) { |
| 517 AddMirrorDisplayInfoIfAny(&display_info_list); |
| 518 UpdateDisplays(display_info_list); |
| 519 } |
| 520 #if defined(OS_CHROMEOS) |
| 521 if (resolution_changed && base::SysInfo::IsRunningOnChromeOS()) |
| 522 Shell::GetInstance()->display_configurator()->OnConfigurationChanged(); |
| 523 #endif |
| 524 return resolution_changed; |
| 525 } |
| 526 |
475 void DisplayManager::RegisterDisplayProperty( | 527 void DisplayManager::RegisterDisplayProperty( |
476 int64 display_id, | 528 int64 display_id, |
477 gfx::Display::Rotation rotation, | 529 gfx::Display::Rotation rotation, |
478 float ui_scale, | 530 float ui_scale, |
479 const gfx::Insets* overscan_insets, | 531 const gfx::Insets* overscan_insets, |
480 const gfx::Size& resolution_in_pixels, | 532 const gfx::Size& resolution_in_pixels, |
481 ui::ColorCalibrationProfile color_profile) { | 533 ui::ColorCalibrationProfile color_profile) { |
482 if (display_info_.find(display_id) == display_info_.end()) | 534 if (display_info_.find(display_id) == display_info_.end()) |
483 display_info_[display_id] = DisplayInfo(display_id, std::string(), false); | 535 display_info_[display_id] = DisplayInfo(display_id, std::string(), false); |
484 | 536 |
485 display_info_[display_id].set_rotation(rotation); | 537 display_info_[display_id].set_rotation(rotation); |
486 display_info_[display_id].SetColorProfile(color_profile); | 538 display_info_[display_id].SetColorProfile(color_profile); |
487 // Just in case the preference file was corrupted. | 539 // Just in case the preference file was corrupted. |
| 540 // TODO(mukai): register |display_modes_| here as well, so the lookup for the |
| 541 // default mode in GetActiveModeForDisplayId() gets much simpler. |
488 if (0.5f <= ui_scale && ui_scale <= 2.0f) | 542 if (0.5f <= ui_scale && ui_scale <= 2.0f) |
489 display_info_[display_id].set_configured_ui_scale(ui_scale); | 543 display_info_[display_id].set_configured_ui_scale(ui_scale); |
490 if (overscan_insets) | 544 if (overscan_insets) |
491 display_info_[display_id].SetOverscanInsets(*overscan_insets); | 545 display_info_[display_id].SetOverscanInsets(*overscan_insets); |
492 if (!resolution_in_pixels.IsEmpty()) { | 546 if (!resolution_in_pixels.IsEmpty()) { |
493 // Default refresh rate, until OnNativeDisplaysChanged() updates us with the | 547 // Default refresh rate, until OnNativeDisplaysChanged() updates us with the |
494 // actual display info, is 60 Hz. | 548 // actual display info, is 60 Hz. |
495 display_modes_[display_id] = | 549 display_modes_[display_id] = |
496 DisplayMode(resolution_in_pixels, 60.0f, false, false); | 550 DisplayMode(resolution_in_pixels, 60.0f, false, false); |
497 } | 551 } |
498 } | 552 } |
499 | 553 |
| 554 DisplayMode DisplayManager::GetActiveModeForDisplayId(int64 display_id) const { |
| 555 DisplayMode selected_mode; |
| 556 if (GetSelectedModeForDisplayId(display_id, &selected_mode)) |
| 557 return selected_mode; |
| 558 |
| 559 // If 'selected' mode is empty, it should return the default mode. This means |
| 560 // the native mode for the external display. Unfortunately this is not true |
| 561 // for the internal display because restoring UI-scale doesn't register the |
| 562 // restored mode to |display_mode_|, so it needs to look up the mode whose |
| 563 // UI-scale value matches. See the TODO in RegisterDisplayProperty(). |
| 564 const DisplayInfo& info = GetDisplayInfo(display_id); |
| 565 const std::vector<DisplayMode>& display_modes = info.display_modes(); |
| 566 |
| 567 if (IsInternalDisplayId(display_id)) { |
| 568 for (size_t i = 0; i < display_modes.size(); ++i) { |
| 569 if (info.configured_ui_scale() == display_modes[i].ui_scale) |
| 570 return display_modes[i]; |
| 571 } |
| 572 } else { |
| 573 for (size_t i = 0; i < display_modes.size(); ++i) { |
| 574 if (display_modes[i].native) |
| 575 return display_modes[i]; |
| 576 } |
| 577 } |
| 578 return selected_mode; |
| 579 } |
| 580 |
500 bool DisplayManager::GetSelectedModeForDisplayId(int64 id, | 581 bool DisplayManager::GetSelectedModeForDisplayId(int64 id, |
501 DisplayMode* mode_out) const { | 582 DisplayMode* mode_out) const { |
502 std::map<int64, DisplayMode>::const_iterator iter = display_modes_.find(id); | 583 std::map<int64, DisplayMode>::const_iterator iter = display_modes_.find(id); |
503 if (iter == display_modes_.end()) | 584 if (iter == display_modes_.end()) |
504 return false; | 585 return false; |
505 *mode_out = iter->second; | 586 *mode_out = iter->second; |
506 return true; | 587 return true; |
507 } | 588 } |
508 | 589 |
509 bool DisplayManager::IsDisplayUIScalingEnabled() const { | 590 bool DisplayManager::IsDisplayUIScalingEnabled() const { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 // Mirrored monitors have the same origins. | 671 // Mirrored monitors have the same origins. |
591 gfx::Point origin = iter->bounds_in_native().origin(); | 672 gfx::Point origin = iter->bounds_in_native().origin(); |
592 if (origins.find(origin) != origins.end()) { | 673 if (origins.find(origin) != origins.end()) { |
593 InsertAndUpdateDisplayInfo(*iter); | 674 InsertAndUpdateDisplayInfo(*iter); |
594 mirrored_display_id_ = iter->id(); | 675 mirrored_display_id_ = iter->id(); |
595 } else { | 676 } else { |
596 origins.insert(origin); | 677 origins.insert(origin); |
597 new_display_info_list.push_back(*iter); | 678 new_display_info_list.push_back(*iter); |
598 } | 679 } |
599 | 680 |
600 const gfx::Size& resolution = iter->bounds_in_native().size(); | 681 DisplayMode new_mode; |
| 682 new_mode.size = iter->bounds_in_native().size(); |
| 683 new_mode.device_scale_factor = iter->device_scale_factor(); |
| 684 new_mode.ui_scale = iter->configured_ui_scale(); |
601 const std::vector<DisplayMode>& display_modes = iter->display_modes(); | 685 const std::vector<DisplayMode>& display_modes = iter->display_modes(); |
602 // This is empty the displays are initialized from InitFromCommandLine. | 686 // This is empty the displays are initialized from InitFromCommandLine. |
603 if (!display_modes.size()) | 687 if (!display_modes.size()) |
604 continue; | 688 continue; |
605 std::vector<DisplayMode>::const_iterator display_modes_iter = | 689 std::vector<DisplayMode>::const_iterator display_modes_iter = |
606 std::find_if(display_modes.begin(), | 690 std::find_if(display_modes.begin(), |
607 display_modes.end(), | 691 display_modes.end(), |
608 DisplayModeMatcher(resolution)); | 692 DisplayModeMatcher(new_mode)); |
609 // Update the actual resolution selected as the resolution request may fail. | 693 // Update the actual resolution selected as the resolution request may fail. |
610 if (display_modes_iter == display_modes.end()) | 694 if (display_modes_iter == display_modes.end()) |
611 display_modes_.erase(iter->id()); | 695 display_modes_.erase(iter->id()); |
612 else if (display_modes_.find(iter->id()) != display_modes_.end()) | 696 else if (display_modes_.find(iter->id()) != display_modes_.end()) |
613 display_modes_[iter->id()] = *display_modes_iter; | 697 display_modes_[iter->id()] = *display_modes_iter; |
614 } | 698 } |
615 if (HasInternalDisplay() && | 699 if (HasInternalDisplay() && |
616 !internal_display_connected && | 700 !internal_display_connected && |
617 display_info_.find(gfx::Display::InternalDisplayId()) == | 701 display_info_.find(gfx::Display::InternalDisplayId()) == |
618 display_info_.end()) { | 702 display_info_.end()) { |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 new_secondary_origin.Offset(-secondary_bounds.width(), offset); | 1228 new_secondary_origin.Offset(-secondary_bounds.width(), offset); |
1145 break; | 1229 break; |
1146 } | 1230 } |
1147 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); | 1231 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); |
1148 secondary_display->set_bounds( | 1232 secondary_display->set_bounds( |
1149 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 1233 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
1150 secondary_display->UpdateWorkAreaFromInsets(insets); | 1234 secondary_display->UpdateWorkAreaFromInsets(insets); |
1151 } | 1235 } |
1152 | 1236 |
1153 } // namespace ash | 1237 } // namespace ash |
OLD | NEW |