diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-28 14:37:34 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-28 14:37:34 +0000 |
commit | 7005d9fb0e445bab402cb2202bedb56cd53057d6 (patch) | |
tree | 7568b1863e8a6a3b2fa6ff3cbd06840b886a22b3 /ash/display/display_manager.cc | |
parent | a92ccf7474fa34018656e20d53aa922e1bad4f02 (diff) | |
download | chromium_src-7005d9fb0e445bab402cb2202bedb56cd53057d6.zip chromium_src-7005d9fb0e445bab402cb2202bedb56cd53057d6.tar.gz chromium_src-7005d9fb0e445bab402cb2202bedb56cd53057d6.tar.bz2 |
Revert "Refactor DisplayInfo/Display - 2nd try"
> This is a first step to fix overscan issue and implement
> screen rotation.
>
> * remove bounds_in_pixel from gfx::Display
> * promote DisplayInfo to separate class/file
> * All display information is now generated in display_change_observer_x11.cc.
> almost no X11 depenency in display_manager.cc
> (I'll move FindInternalDisplayID out from display_manager.cc once https://codereview.chromium.org/12217120/ is landed)
>
> This makes testing more consistent with real environment.
>
>* Add DisplayManager::ClearCustomOverscanInsets so that
> you can reset the insets to default value.
>* Removed obsolete AshTestBase::ChangeDisplayConfig
>
>BUG=174721,119268
>TEST=covered by test
>
BUG=174721,119268
Review URL: https://codereview.chromium.org/12374017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@185243 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/display/display_manager.cc')
-rw-r--r-- | ash/display/display_manager.cc | 393 |
1 files changed, 213 insertions, 180 deletions
diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc index 6aef6f4..170b340 100644 --- a/ash/display/display_manager.cc +++ b/ash/display/display_manager.cc @@ -46,12 +46,10 @@ #endif DECLARE_WINDOW_PROPERTY_TYPE(int64); +typedef std::vector<gfx::Display> DisplayList; namespace ash { namespace internal { -typedef std::vector<gfx::Display> DisplayList; -typedef std::vector<DisplayInfo> DisplayInfoList; - namespace { // Default bounds for a display. @@ -66,38 +64,29 @@ struct DisplaySortFunctor { } }; -struct DisplayInfoSortFunctor { - bool operator()(const DisplayInfo& a, const DisplayInfo& b) { - return a.id() < b.id(); - } -}; - gfx::Display& GetInvalidDisplay() { static gfx::Display* invalid_display = new gfx::Display(); return *invalid_display; } #if defined(OS_CHROMEOS) - -int64 FindInternalDisplayID() { - std::vector<XID> outputs; - ui::GetOutputDeviceHandles(&outputs); - std::vector<std::string> output_names = ui::GetOutputNames(outputs); - for (size_t i = 0; i < output_names.size(); ++i) { - if (chromeos::OutputConfigurator::IsInternalOutputName( - output_names[i])) { - uint16 manufacturer_id = 0; - uint16 product_code = 0; - ui::GetOutputDeviceData( - outputs[i], &manufacturer_id, &product_code, NULL); - return gfx::Display::GetID(manufacturer_id, product_code, i); - } - } - return gfx::Display::kInvalidDisplayID; +int64 GetDisplayIdForOutput(XID output, int output_index) { + uint16 manufacturer_id = 0; + uint16 product_code = 0; + ui::GetOutputDeviceData( + output, &manufacturer_id, &product_code, NULL); + return gfx::Display::GetID(manufacturer_id, product_code, output_index); } - #endif +gfx::Insets GetDefaultDisplayOverscan(const gfx::Display& display) { + // Currently we assume 5% overscan and hope for the best if TV claims it + // overscan, but doesn't expose how much. + int width = display.bounds().width() / 40; + int height = display.bounds().height() / 40; + return gfx::Insets(height, width, height, width); +} + } // namespace using aura::RootWindow; @@ -170,34 +159,24 @@ const gfx::Display& DisplayManager::FindDisplayContainingPoint( void DisplayManager::SetOverscanInsets(int64 display_id, const gfx::Insets& insets_in_dip) { - display_info_[display_id].SetOverscanInsets(true, insets_in_dip); - DisplayInfoList display_info_list; - for (DisplayList::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - display_info_list.push_back(GetDisplayInfo(*iter)); - } - UpdateDisplays(display_info_list); -} + display_info_[display_id].overscan_insets_in_dip = insets_in_dip; + display_info_[display_id].has_custom_overscan_insets = true; -void DisplayManager::ClearCustomOverscanInsets(int64 display_id) { - display_info_[display_id].clear_has_custom_overscan_insets(); - DisplayInfoList display_info_list; - for (DisplayList::const_iterator iter = displays_.begin(); - iter != displays_.end(); ++iter) { - display_info_list.push_back(GetDisplayInfo(*iter)); - } - UpdateDisplays(display_info_list); + // Copies the |displays_| because UpdateDisplays() compares the passed + // displays and its internal |displays_|. + DisplayList displays = displays_; + UpdateDisplays(displays); } gfx::Insets DisplayManager::GetOverscanInsets(int64 display_id) const { std::map<int64, DisplayInfo>::const_iterator it = display_info_.find(display_id); return (it != display_info_.end()) ? - it->second.overscan_insets_in_dip() : gfx::Insets(); + it->second.overscan_insets_in_dip : gfx::Insets(); } void DisplayManager::OnNativeDisplaysChanged( - const std::vector<DisplayInfo>& updated_displays) { + const std::vector<gfx::Display>& updated_displays) { if (updated_displays.empty()) { // Don't update the displays when all displays are disconnected. // This happens when: @@ -211,34 +190,55 @@ void DisplayManager::OnNativeDisplaysChanged( // display list will be updated correctly. return; } - - bool internal_display_connected = false; - for (DisplayInfoList::const_iterator iter = updated_displays.begin(); - iter != updated_displays.end() && !internal_display_connected; - ++iter) { - internal_display_connected = IsInternalDisplayId(iter->id()); - if (internal_display_connected) - internal_display_info_.reset(new DisplayInfo(*iter)); + DisplayList new_displays = updated_displays; + if (HasInternalDisplay()) { + bool internal_display_connected = false; + for (DisplayList::const_iterator iter = updated_displays.begin(); + iter != updated_displays.end(); ++iter) { + if ((*iter).IsInternal()) { + internal_display_connected = true; + // Update the internal display cache. + internal_display_.reset(new gfx::Display); + *internal_display_.get() = *iter; + break; + } + } + // If the internal display wasn't connected, use the cached value. + if (!internal_display_connected) { + // Internal display may be reported as disconnect during startup time. + if (!internal_display_.get()) { + internal_display_.reset( + new gfx::Display(gfx::Display::InternalDisplayId(), + gfx::Rect(800, 600))); + } + new_displays.push_back(*internal_display_.get()); + } + } else { + new_displays = updated_displays; } - DisplayInfoList new_display_info_list = updated_displays; - - if (HasInternalDisplay() && !internal_display_connected) { - if (!internal_display_info_.get()) { - // TODO(oshima): Get has_custom value. - internal_display_info_.reset(new DisplayInfo( - gfx::Display::InternalDisplayId(), - l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME), - false)); - internal_display_info_->SetBounds(gfx::Rect(0, 0, 800, 600)); + + RefreshDisplayInfo(); + + for (DisplayList::const_iterator iter = new_displays.begin(); + iter != new_displays.end(); ++iter) { + std::map<int64, DisplayInfo>::iterator info = + display_info_.find(iter->id()); + if (info != display_info_.end()) { + info->second.original_bounds_in_pixel = iter->bounds_in_pixel(); + if (info->second.has_overscan && !info->second.has_custom_overscan_insets) + info->second.overscan_insets_in_dip = GetDefaultDisplayOverscan(*iter); + } else { + display_info_[iter->id()].original_bounds_in_pixel = + iter->bounds_in_pixel(); } - new_display_info_list.push_back(*internal_display_info_.get()); } - UpdateDisplays(new_display_info_list); + UpdateDisplays(new_displays); } void DisplayManager::UpdateDisplays( - const std::vector<DisplayInfo>& updated_display_info_list) { + const std::vector<gfx::Display>& updated_displays) { + DisplayList new_displays = updated_displays; #if defined(OS_CHROMEOS) // Overscan is always enabled when not running on the device // in order for unit tests to work. @@ -246,15 +246,26 @@ void DisplayManager::UpdateDisplays( !base::chromeos::IsRunningOnChromeOS() || (Shell::GetInstance()->output_configurator()->output_state() != chromeos::STATE_DUAL_MIRROR && - updated_display_info_list.size() == 1); + updated_displays.size() == 1); #else bool can_overscan = true; #endif - DisplayInfoList new_display_info_list = updated_display_info_list; + if (can_overscan) { + for (DisplayList::iterator iter = new_displays.begin(); + iter != new_displays.end(); ++iter) { + std::map<int64, DisplayInfo>::const_iterator info = + display_info_.find(iter->id()); + if (info != display_info_.end()) { + gfx::Rect bounds = info->second.original_bounds_in_pixel; + bounds.Inset(info->second.overscan_insets_in_dip.Scale( + iter->device_scale_factor())); + iter->SetScaleAndBounds(iter->device_scale_factor(), bounds); + } + } + } + std::sort(displays_.begin(), displays_.end(), DisplaySortFunctor()); - std::sort(new_display_info_list.begin(), - new_display_info_list.end(), - DisplayInfoSortFunctor()); + std::sort(new_displays.begin(), new_displays.end(), DisplaySortFunctor()); DisplayList removed_displays; std::vector<size_t> changed_display_indices; std::vector<size_t> added_display_indices; @@ -262,54 +273,44 @@ void DisplayManager::UpdateDisplays( if (DisplayController::HasPrimaryDisplay()) current_primary = DisplayController::GetPrimaryDisplay(); - DisplayList::iterator curr_iter = displays_.begin(); - DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); - - DisplayList new_displays; - while (curr_iter != displays_.end() || - new_info_iter != new_display_info_list.end()) { + for (DisplayList::iterator curr_iter = displays_.begin(), + new_iter = new_displays.begin(); + curr_iter != displays_.end() || new_iter != new_displays.end();) { if (curr_iter == displays_.end()) { // more displays in new list. - added_display_indices.push_back(new_displays.size()); - InsertAndUpdateDisplayInfo(*new_info_iter, can_overscan); - new_displays.push_back( - CreateDisplayFromDisplayInfoById(new_info_iter->id())); - ++new_info_iter; - } else if (new_info_iter == new_display_info_list.end()) { + added_display_indices.push_back(new_iter - new_displays.begin()); + ++new_iter; + } else if (new_iter == new_displays.end()) { // more displays in current list. removed_displays.push_back(*curr_iter); ++curr_iter; - } else if (curr_iter->id() == new_info_iter->id()) { + } else if ((*curr_iter).id() == (*new_iter).id()) { const gfx::Display& current_display = *curr_iter; - // Copy the info because |CreateDisplayFromInfo| updates the instance. - const DisplayInfo current_display_info = GetDisplayInfo(current_display); - InsertAndUpdateDisplayInfo(*new_info_iter, can_overscan); - gfx::Display new_display = - CreateDisplayFromDisplayInfoById(new_info_iter->id()); - const DisplayInfo& new_display_info = GetDisplayInfo(new_display); + gfx::Display& new_display = *new_iter; if (force_bounds_changed_ || - (current_display_info.bounds_in_pixel() != - new_display_info.bounds_in_pixel()) || - (current_display.device_scale_factor() != - new_display.device_scale_factor())) { - changed_display_indices.push_back(new_displays.size()); + current_display.bounds_in_pixel() != new_display.bounds_in_pixel() || + current_display.device_scale_factor() != + new_display.device_scale_factor()) { + changed_display_indices.push_back(new_iter - new_displays.begin()); } + // If the display is primary, then simpy set the origin to (0,0). + // The secondary display's bounds will be updated by + // |DisplayController::UpdateDisplayBoundsForLayout|, so no need + // to change there. + if ((*new_iter).id() == current_primary.id()) + new_display.set_bounds(gfx::Rect(new_display.bounds().size())); new_display.UpdateWorkAreaFromInsets(current_display.GetWorkAreaInsets()); - new_displays.push_back(new_display); ++curr_iter; - ++new_info_iter; - } else if (curr_iter->id() < new_info_iter->id()) { + ++new_iter; + } else if ((*curr_iter).id() < (*new_iter).id()) { // more displays in current list between ids, which means it is deleted. removed_displays.push_back(*curr_iter); ++curr_iter; } else { // more displays in new list between ids, which means it is added. - added_display_indices.push_back(new_displays.size()); - InsertAndUpdateDisplayInfo(*new_info_iter, can_overscan); - new_displays.push_back( - CreateDisplayFromDisplayInfoById(new_info_iter->id())); - ++new_info_iter; + added_display_indices.push_back(new_iter - new_displays.begin()); + ++new_iter; } } @@ -351,10 +352,10 @@ void DisplayManager::UpdateDisplays( RootWindow* DisplayManager::CreateRootWindowForDisplay( const gfx::Display& display) { static int root_window_count = 0; - const gfx::Rect& bounds_in_pixel = GetDisplayInfo(display).bounds_in_pixel(); - RootWindow::CreateParams params(bounds_in_pixel); + + RootWindow::CreateParams params(display.bounds_in_pixel()); params.host = Shell::GetInstance()->root_window_host_factory()-> - CreateRootWindowHost(bounds_in_pixel); + CreateRootWindowHost(display.bounds_in_pixel()); aura::RootWindow* root_window = new aura::RootWindow(params); root_window->SetName(StringPrintf("RootWindow-%d", root_window_count++)); @@ -370,30 +371,6 @@ gfx::Display* DisplayManager::GetDisplayAt(size_t index) { return index < displays_.size() ? &displays_[index] : NULL; } -const gfx::Display* DisplayManager::GetPrimaryDisplayCandidate() const { - const gfx::Display* primary_candidate = &displays_[0]; -#if defined(OS_CHROMEOS) - if (base::chromeos::IsRunningOnChromeOS()) { - // On ChromeOS device, root windows are stacked vertically, and - // default primary is the one on top. - int count = GetNumDisplays(); - int y = GetDisplayInfo(*primary_candidate).bounds_in_pixel().y(); - for (int i = 1; i < count; ++i) { - const gfx::Display* display = &displays_[i]; - const DisplayInfo& display_info = GetDisplayInfo(*display); - if (display->IsInternal()) { - primary_candidate = display; - break; - } else if (display_info.bounds_in_pixel().y() < y) { - primary_candidate = display; - y = display_info.bounds_in_pixel().y(); - } - } - } -#endif - return primary_candidate; -} - size_t DisplayManager::GetNumDisplays() const { return displays_.size(); } @@ -438,14 +415,6 @@ const gfx::Display& DisplayManager::GetDisplayMatching( return matching ? *matching : DisplayController::GetPrimaryDisplay(); } -const DisplayInfo& DisplayManager::GetDisplayInfo( - const gfx::Display& display) const { - std::map<int64, DisplayInfo>::const_iterator iter = - display_info_.find(display.id()); - CHECK(iter != display_info_.end()); - return iter->second; -} - std::string DisplayManager::GetDisplayNameFor( const gfx::Display& display) { if (!display.is_valid()) @@ -453,8 +422,8 @@ std::string DisplayManager::GetDisplayNameFor( std::map<int64, DisplayInfo>::const_iterator iter = display_info_.find(display.id()); - if (iter != display_info_.end() && !iter->second.name().empty()) - return iter->second.name(); + if (iter != display_info_.end() && !iter->second.name.empty()) + return iter->second.name; return base::StringPrintf("Display %d", static_cast<int>(display.id())); } @@ -469,8 +438,6 @@ void DisplayManager::OnRootWindowResized(const aura::RootWindow* root, gfx::Display& display = FindDisplayForRootWindow(root); if (display.size() != root->GetHostSize()) { display.SetSize(root->GetHostSize()); - display_info_[display.id()].UpdateBounds( - gfx::Rect(root->GetHostOrigin(), root->GetHostSize())); Shell::GetInstance()->screen()->NotifyBoundsChanged(display); } } @@ -478,10 +445,23 @@ void DisplayManager::OnRootWindowResized(const aura::RootWindow* root, void DisplayManager::Init() { #if defined(OS_CHROMEOS) - if (base::chromeos::IsRunningOnChromeOS()) - gfx::Display::SetInternalDisplayId(FindInternalDisplayID()); + if (base::chromeos::IsRunningOnChromeOS()) { + std::vector<XID> outputs; + ui::GetOutputDeviceHandles(&outputs); + std::vector<std::string> output_names = ui::GetOutputNames(outputs); + for (size_t i = 0; i < output_names.size(); ++i) { + if (chromeos::OutputConfigurator::IsInternalOutputName( + output_names[i])) { + gfx::Display::SetInternalDisplayId( + GetDisplayIdForOutput(outputs[i], i)); + break; + } + } + } #endif + RefreshDisplayInfo(); + // TODO(oshima): Move this logic to DisplayChangeObserver. const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kAshHostWindowBounds); @@ -497,32 +477,34 @@ void DisplayManager::Init() { void DisplayManager::CycleDisplayImpl() { DCHECK(!displays_.empty()); - std::vector<DisplayInfo> new_display_info_list; - new_display_info_list.push_back( - GetDisplayInfo(DisplayController::GetPrimaryDisplay())); + std::vector<gfx::Display> new_displays; + new_displays.push_back(DisplayController::GetPrimaryDisplay()); // Add if there is only one display. if (displays_.size() == 1) { // Layout the 2nd display below the primary as with the real device. aura::RootWindow* primary = Shell::GetPrimaryRootWindow(); gfx::Rect host_bounds = gfx::Rect(primary->GetHostOrigin(), primary->GetHostSize()); - new_display_info_list.push_back(DisplayInfo::CreateFromSpec( + new_displays.push_back(CreateDisplayFromSpec( StringPrintf("%d+%d-500x400", host_bounds.x(), host_bounds.bottom()))); } - OnNativeDisplaysChanged(new_display_info_list); + OnNativeDisplaysChanged(new_displays); } void DisplayManager::ScaleDisplayImpl() { DCHECK(!displays_.empty()); - std::vector<DisplayInfo> new_display_info_list; + std::vector<gfx::Display> new_displays; for (DisplayList::const_iterator iter = displays_.begin(); iter != displays_.end(); ++iter) { - DisplayInfo display_info = GetDisplayInfo(*iter); - display_info.set_device_scale_factor( - display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); - new_display_info_list.push_back(display_info); + gfx::Display display = *iter; + float factor = display.device_scale_factor() == 1.0f ? 2.0f : 1.0f; + gfx::Point display_origin = display.bounds_in_pixel().origin(); + gfx::Size display_size = gfx::ToFlooredSize( + gfx::ScaleSize(display.size(), factor)); + display.SetScaleAndBounds(factor, gfx::Rect(display_origin, display_size)); + new_displays.push_back(display); } - OnNativeDisplaysChanged(new_display_info_list); + OnNativeDisplaysChanged(new_displays); } gfx::Display& DisplayManager::FindDisplayForRootWindow( @@ -546,12 +528,22 @@ gfx::Display& DisplayManager::FindDisplayForId(int64 id) { } void DisplayManager::AddDisplayFromSpec(const std::string& spec) { - DisplayInfo display_info = DisplayInfo::CreateFromSpec(spec); - InsertAndUpdateDisplayInfo(display_info, false); - gfx::Display display = CreateDisplayFromDisplayInfoById(display_info.id()); + gfx::Display display = CreateDisplayFromSpec(spec); + + const gfx::Insets insets = display.GetWorkAreaInsets(); + const gfx::Rect& native_bounds = display.bounds_in_pixel(); + display.SetScaleAndBounds(display.device_scale_factor(), native_bounds); + display.UpdateWorkAreaFromInsets(insets); displays_.push_back(display); } +int64 DisplayManager::SetFirstDisplayAsInternalDisplayForTest() { + gfx::Display::SetInternalDisplayId(displays_[0].id()); + internal_display_.reset(new gfx::Display); + *internal_display_ = displays_[0]; + return gfx::Display::InternalDisplayId(); +} + void DisplayManager::EnsurePointerInDisplays() { // Don't try to move the pointer during the boot/startup. if (!DisplayController::HasPrimaryDisplay()) @@ -590,35 +582,76 @@ void DisplayManager::EnsurePointerInDisplays() { root_window->MoveCursorTo(target_location); } -void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info, - bool can_overscan) { - std::map<int64, DisplayInfo>::iterator info = - display_info_.find(new_info.id()); - if (info != display_info_.end()) - info->second.CopyFromNative(new_info); - else - display_info_[new_info.id()] = new_info; +DisplayManager::DisplayInfo::DisplayInfo() + : has_overscan(false), + has_custom_overscan_insets(false) { +} + +void DisplayManager::RefreshDisplayInfo() { +#if defined(OS_CHROMEOS) + if (!base::chromeos::IsRunningOnChromeOS()) + return; +#endif + +#if defined(USE_X11) + std::vector<XID> outputs; + if (!ui::GetOutputDeviceHandles(&outputs)) + return; + + for (size_t output_index = 0; output_index < outputs.size(); ++output_index) { + uint16 manufacturer_id = 0; + uint16 product_code = 0; + std::string name; + ui::GetOutputDeviceData( + outputs[output_index], &manufacturer_id, &product_code, &name); + int64 id = gfx::Display::GetID(manufacturer_id, product_code, output_index); + if (IsInternalDisplayId(id)) { + display_info_[id].name = + l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME); + } else if (!name.empty()) { + display_info_[id].name = name; + } + + ui::GetOutputOverscanFlag( + outputs[output_index], &display_info_[id].has_overscan); + } +#endif +} - display_info_[new_info.id()].UpdateOverscanInfo(can_overscan); +void DisplayManager::SetDisplayIdsForTest(DisplayList* to_update) const { + DisplayList::iterator iter_to_update = to_update->begin(); + DisplayList::const_iterator iter = displays_.begin(); + for (; iter != displays_.end() && iter_to_update != to_update->end(); + ++iter, ++iter_to_update) { + (*iter_to_update).set_id((*iter).id()); + } } -gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { - DCHECK(display_info_.find(id) != display_info_.end()); - const DisplayInfo& display_info = display_info_[id]; +void DisplayManager::SetHasOverscanFlagForTest(int64 id, bool has_overscan) { + display_info_[id].has_overscan = has_overscan; +} - gfx::Display new_display(display_info.id()); - new_display.SetScaleAndBounds( - display_info.device_scale_factor(), display_info.bounds_in_pixel()); +gfx::Display CreateDisplayFromSpec(const std::string& spec) { + static int64 synthesized_display_id = 1000; - // If the display is primary, then simply set the origin to (0,0). - // The secondary display's bounds will be updated by - // |DisplayController::UpdateDisplayBoundsForLayout|, so no need - // to change there. - if (DisplayController::HasPrimaryDisplay() && - display_info.id() == DisplayController::GetPrimaryDisplay().id()) { - new_display.set_bounds(gfx::Rect(new_display.bounds().size())); +#if defined(OS_WIN) + gfx::Rect bounds(aura::RootWindowHost::GetNativeScreenSize()); +#else + gfx::Rect bounds(kDefaultHostWindowX, kDefaultHostWindowY, + kDefaultHostWindowWidth, kDefaultHostWindowHeight); +#endif + int x = 0, y = 0, width, height; + float scale = 1.0f; + if (sscanf(spec.c_str(), "%dx%d*%f", &width, &height, &scale) >= 2 || + sscanf(spec.c_str(), "%d+%d-%dx%d*%f", &x, &y, &width, &height, + &scale) >= 4) { + bounds.SetRect(x, y, width, height); } - return new_display; + + gfx::Display display(synthesized_display_id++); + display.SetScaleAndBounds(scale, bounds); + DVLOG(1) << "Display bounds=" << bounds.ToString() << ", scale=" << scale; + return display; } } // namespace internal |