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

Side by Side Diff: ash/display/display_manager.cc

Issue 417113012: Introduce user customization of external HighDPI mode for 4K monitor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 6 years, 4 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 | « ash/display/display_manager.h ('k') | ash/display/display_manager_unittest.cc » ('j') | 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 "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
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
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
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
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
OLDNEW
« no previous file with comments | « ash/display/display_manager.h ('k') | ash/display/display_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698