Chromium Code Reviews| Index: ash/display/display_change_observer_chromeos.cc |
| diff --git a/ash/display/display_change_observer_chromeos.cc b/ash/display/display_change_observer_chromeos.cc |
| index d2e90492dd1c5185e3ea4f04095ab8719bd74dec..81370f985d7b708e6aa93f7ffdb5814586dc787a 100644 |
| --- a/ash/display/display_change_observer_chromeos.cc |
| +++ b/ash/display/display_change_observer_chromeos.cc |
| @@ -46,25 +46,70 @@ const DeviceScaleFactorDPIThreshold kThresholdTable[] = { |
| // 1 inch in mm. |
| const float kInchInMm = 25.4f; |
| -// Display mode list is sorted by (in descending priority): |
| -// * the area in pixels. |
| -// * refresh rate. |
| +// The list of device scale factors (in addition to 1.0f) which is |
| +// available in extrenal large monitors. |
| +const float kAdditionalDeviceScaleFactorsFor4k[] = {1.25f, 2.0f}; |
| + |
| +// Display mode list is sorted by: |
| +// * the area in pixels in ascending order |
| +// * refresh rate in descending order |
| struct DisplayModeSorter { |
| bool operator()(const DisplayMode& a, const DisplayMode& b) { |
| - if (a.size.GetArea() == b.size.GetArea()) |
| + gfx::Size size_a_dip = a.GetSizeInDIP(); |
| + gfx::Size size_b_dip = b.GetSizeInDIP(); |
| + if (size_a_dip.GetArea() == size_b_dip.GetArea()) |
| return (a.refresh_rate > b.refresh_rate); |
| - return (a.size.GetArea() > b.size.GetArea()); |
| + return (size_a_dip.GetArea() < size_b_dip.GetArea()); |
| } |
| }; |
| } // namespace |
| // static |
| +std::vector<DisplayMode> DisplayChangeObserver::GetInternalDisplayModeList( |
| + const DisplayInfo& display_info, |
| + const DisplayConfigurator::DisplayState& output) { |
| + std::vector<DisplayMode> display_mode_list; |
| + DisplayMode native_mode; |
| + |
| + for (std::vector<const ui::DisplayMode*>::const_iterator it = |
| + output.display->modes().begin(); |
| + it != output.display->modes().end(); |
| + ++it) { |
| + const ui::DisplayMode& mode_info = **it; |
| + if (output.display->native_mode() == *it) { |
| + native_mode = DisplayMode(mode_info.size(), |
| + mode_info.refresh_rate(), |
| + mode_info.is_interlaced(), |
| + true); |
| + break; |
| + } |
| + } |
| + |
| + if (native_mode.size.IsEmpty()) |
| + return display_mode_list; |
| + |
| + std::vector<float> ui_scales = |
| + DisplayManager::GetScalesForDisplay(display_info); |
| + for (size_t i = 0; i < ui_scales.size(); ++i) { |
| + DisplayMode mode = native_mode; |
| + mode.ui_scale = ui_scales[i]; |
| + mode.native = (ui_scales[i] == 1.0f); |
| + display_mode_list.push_back(mode); |
| + } |
| + |
| + std::sort( |
| + display_mode_list.begin(), display_mode_list.end(), DisplayModeSorter()); |
| + return display_mode_list; |
| +} |
| + |
| +// static |
| std::vector<DisplayMode> DisplayChangeObserver::GetDisplayModeList( |
| const DisplayConfigurator::DisplayState& output) { |
| typedef std::map<std::pair<int, int>, DisplayMode> DisplayModeMap; |
| DisplayModeMap display_mode_map; |
| + DisplayMode native_mode; |
| for (std::vector<const ui::DisplayMode*>::const_iterator it = |
| output.display->modes().begin(); |
| it != output.display->modes().end(); |
| @@ -76,6 +121,8 @@ std::vector<DisplayMode> DisplayChangeObserver::GetDisplayModeList( |
| mode_info.refresh_rate(), |
| mode_info.is_interlaced(), |
| output.display->native_mode() == *it); |
| + if (display_mode.native) |
| + native_mode = display_mode; |
| // Add the display mode if it isn't already present and override interlaced |
| // display modes with non-interlaced ones. |
| @@ -92,6 +139,17 @@ std::vector<DisplayMode> DisplayChangeObserver::GetDisplayModeList( |
| ++iter) { |
| display_mode_list.push_back(iter->second); |
| } |
| + |
| + if (native_mode.size.width() >= 3840.0f) { |
|
stevenjb
2014/07/30 17:49:59
nit: define 3840.0f as a constant at the top of th
Jun Mukai
2014/07/30 23:50:51
Done.
|
| + for (size_t i = 0; i < arraysize(kAdditionalDeviceScaleFactorsFor4k); |
| + ++i) { |
| + DisplayMode mode = native_mode; |
| + mode.device_scale_factor = kAdditionalDeviceScaleFactorsFor4k[i]; |
| + mode.native = false; |
| + display_mode_list.push_back(mode); |
| + } |
| + } |
| + |
| std::sort( |
| display_mode_list.begin(), display_mode_list.end(), DisplayModeSorter()); |
| return display_mode_list; |
| @@ -150,8 +208,6 @@ void DisplayChangeObserver::OnDisplayModeChanged( |
| } |
| gfx::Rect display_bounds(state.display->origin(), mode_info->size()); |
| - std::vector<DisplayMode> display_modes = GetDisplayModeList(state); |
| - |
| std::string name = |
| state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL ? |
| l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME) : |
| @@ -168,13 +224,18 @@ void DisplayChangeObserver::OnDisplayModeChanged( |
| new_info.set_device_scale_factor(device_scale_factor); |
| new_info.SetBounds(display_bounds); |
| new_info.set_native(true); |
| - new_info.set_display_modes(display_modes); |
| new_info.set_touch_support(state.touch_device_id == 0 ? |
| gfx::Display::TOUCH_SUPPORT_UNAVAILABLE : |
| gfx::Display::TOUCH_SUPPORT_AVAILABLE); |
| new_info.set_touch_device_id(state.touch_device_id); |
| new_info.set_is_aspect_preserving_scaling( |
| state.display->is_aspect_preserving_scaling()); |
| + |
| + std::vector<DisplayMode> display_modes = |
| + (state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) ? |
| + GetInternalDisplayModeList(new_info, state) : GetDisplayModeList(state); |
| + new_info.set_display_modes(display_modes); |
| + |
| new_info.set_available_color_profiles( |
| Shell::GetInstance() |
| ->display_configurator() |