Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_change_observer_chromeos.h" | 5 #include "ash/display/display_change_observer_chromeos.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 | 39 |
| 40 const DeviceScaleFactorDPIThreshold kThresholdTable[] = { | 40 const DeviceScaleFactorDPIThreshold kThresholdTable[] = { |
| 41 {180.0f, 2.0f}, | 41 {180.0f, 2.0f}, |
| 42 {150.0f, 1.25f}, | 42 {150.0f, 1.25f}, |
| 43 {0.0f, 1.0f}, | 43 {0.0f, 1.0f}, |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 // 1 inch in mm. | 46 // 1 inch in mm. |
| 47 const float kInchInMm = 25.4f; | 47 const float kInchInMm = 25.4f; |
| 48 | 48 |
| 49 // Display mode list is sorted by (in descending priority): | 49 // The minimum pixel width whose monitor can be called as '4K'. |
| 50 // * the area in pixels. | 50 const int kMinimumWidthFor4K = 3840; |
| 51 // * refresh rate. | 51 |
| 52 // The list of device scale factors (in addition to 1.0f) which is | |
| 53 // available in extrenal large monitors. | |
| 54 const float kAdditionalDeviceScaleFactorsFor4k[] = {1.25f, 2.0f}; | |
| 55 | |
| 56 // Display mode list is sorted by: | |
| 57 // * the area in pixels in ascending order | |
| 58 // * refresh rate in descending order | |
| 52 struct DisplayModeSorter { | 59 struct DisplayModeSorter { |
| 53 bool operator()(const DisplayMode& a, const DisplayMode& b) { | 60 bool operator()(const DisplayMode& a, const DisplayMode& b) { |
| 54 if (a.size.GetArea() == b.size.GetArea()) | 61 gfx::Size size_a_dip = a.GetSizeInDIP(); |
| 62 gfx::Size size_b_dip = b.GetSizeInDIP(); | |
| 63 if (size_a_dip.GetArea() == size_b_dip.GetArea()) | |
| 55 return (a.refresh_rate > b.refresh_rate); | 64 return (a.refresh_rate > b.refresh_rate); |
| 56 return (a.size.GetArea() > b.size.GetArea()); | 65 return (size_a_dip.GetArea() < size_b_dip.GetArea()); |
| 57 } | 66 } |
| 58 }; | 67 }; |
| 59 | 68 |
| 60 } // namespace | 69 } // namespace |
| 61 | 70 |
| 62 // static | 71 // static |
| 72 std::vector<DisplayMode> DisplayChangeObserver::GetInternalDisplayModeList( | |
| 73 const DisplayInfo& display_info, | |
| 74 const DisplayConfigurator::DisplayState& output) { | |
| 75 std::vector<DisplayMode> display_mode_list; | |
| 76 DisplayMode native_mode; | |
| 77 | |
| 78 for (std::vector<const ui::DisplayMode*>::const_iterator it = | |
| 79 output.display->modes().begin(); | |
| 80 it != output.display->modes().end(); | |
| 81 ++it) { | |
| 82 const ui::DisplayMode& mode_info = **it; | |
| 83 if (output.display->native_mode() == *it) { | |
| 84 native_mode = DisplayMode(mode_info.size(), | |
| 85 mode_info.refresh_rate(), | |
| 86 mode_info.is_interlaced(), | |
| 87 true); | |
|
oshima
2014/07/31 02:16:52
why you're iterating the most list? Can't you just
Jun Mukai
2014/07/31 04:57:52
removed the loop. good point.
| |
| 88 break; | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 if (native_mode.size.IsEmpty()) | |
| 93 return display_mode_list; | |
| 94 | |
| 95 native_mode.device_scale_factor = display_info.device_scale_factor(); | |
| 96 std::vector<float> ui_scales = | |
| 97 DisplayManager::GetScalesForDisplay(display_info); | |
| 98 for (size_t i = 0; i < ui_scales.size(); ++i) { | |
| 99 DisplayMode mode = native_mode; | |
| 100 mode.ui_scale = ui_scales[i]; | |
| 101 mode.native = (ui_scales[i] == 1.0f); | |
| 102 display_mode_list.push_back(mode); | |
| 103 } | |
| 104 | |
| 105 std::sort( | |
| 106 display_mode_list.begin(), display_mode_list.end(), DisplayModeSorter()); | |
| 107 return display_mode_list; | |
| 108 } | |
| 109 | |
| 110 // static | |
| 63 std::vector<DisplayMode> DisplayChangeObserver::GetDisplayModeList( | 111 std::vector<DisplayMode> DisplayChangeObserver::GetDisplayModeList( |
| 64 const DisplayConfigurator::DisplayState& output) { | 112 const DisplayConfigurator::DisplayState& output) { |
| 65 typedef std::map<std::pair<int, int>, DisplayMode> DisplayModeMap; | 113 typedef std::map<std::pair<int, int>, DisplayMode> DisplayModeMap; |
| 66 DisplayModeMap display_mode_map; | 114 DisplayModeMap display_mode_map; |
| 67 | 115 |
| 116 DisplayMode native_mode; | |
| 68 for (std::vector<const ui::DisplayMode*>::const_iterator it = | 117 for (std::vector<const ui::DisplayMode*>::const_iterator it = |
| 69 output.display->modes().begin(); | 118 output.display->modes().begin(); |
| 70 it != output.display->modes().end(); | 119 it != output.display->modes().end(); |
| 71 ++it) { | 120 ++it) { |
| 72 const ui::DisplayMode& mode_info = **it; | 121 const ui::DisplayMode& mode_info = **it; |
| 73 const std::pair<int, int> size(mode_info.size().width(), | 122 const std::pair<int, int> size(mode_info.size().width(), |
| 74 mode_info.size().height()); | 123 mode_info.size().height()); |
| 75 const DisplayMode display_mode(mode_info.size(), | 124 const DisplayMode display_mode(mode_info.size(), |
| 76 mode_info.refresh_rate(), | 125 mode_info.refresh_rate(), |
| 77 mode_info.is_interlaced(), | 126 mode_info.is_interlaced(), |
| 78 output.display->native_mode() == *it); | 127 output.display->native_mode() == *it); |
| 128 if (display_mode.native) | |
| 129 native_mode = display_mode; | |
| 79 | 130 |
| 80 // Add the display mode if it isn't already present and override interlaced | 131 // Add the display mode if it isn't already present and override interlaced |
| 81 // display modes with non-interlaced ones. | 132 // display modes with non-interlaced ones. |
| 82 DisplayModeMap::iterator display_mode_it = display_mode_map.find(size); | 133 DisplayModeMap::iterator display_mode_it = display_mode_map.find(size); |
| 83 if (display_mode_it == display_mode_map.end()) | 134 if (display_mode_it == display_mode_map.end()) |
| 84 display_mode_map.insert(std::make_pair(size, display_mode)); | 135 display_mode_map.insert(std::make_pair(size, display_mode)); |
| 85 else if (display_mode_it->second.interlaced && !display_mode.interlaced) | 136 else if (display_mode_it->second.interlaced && !display_mode.interlaced) |
| 86 display_mode_it->second = display_mode; | 137 display_mode_it->second = display_mode; |
| 87 } | 138 } |
| 88 | 139 |
| 89 std::vector<DisplayMode> display_mode_list; | 140 std::vector<DisplayMode> display_mode_list; |
| 90 for (DisplayModeMap::const_iterator iter = display_mode_map.begin(); | 141 for (DisplayModeMap::const_iterator iter = display_mode_map.begin(); |
| 91 iter != display_mode_map.end(); | 142 iter != display_mode_map.end(); |
| 92 ++iter) { | 143 ++iter) { |
| 93 display_mode_list.push_back(iter->second); | 144 display_mode_list.push_back(iter->second); |
| 94 } | 145 } |
| 146 | |
| 147 if (native_mode.size.width() >= kMinimumWidthFor4K) { | |
| 148 for (size_t i = 0; i < arraysize(kAdditionalDeviceScaleFactorsFor4k); | |
| 149 ++i) { | |
| 150 DisplayMode mode = native_mode; | |
| 151 mode.device_scale_factor = kAdditionalDeviceScaleFactorsFor4k[i]; | |
| 152 mode.native = false; | |
| 153 display_mode_list.push_back(mode); | |
| 154 } | |
| 155 } | |
| 156 | |
| 95 std::sort( | 157 std::sort( |
| 96 display_mode_list.begin(), display_mode_list.end(), DisplayModeSorter()); | 158 display_mode_list.begin(), display_mode_list.end(), DisplayModeSorter()); |
| 97 return display_mode_list; | 159 return display_mode_list; |
| 98 } | 160 } |
| 99 | 161 |
| 100 DisplayChangeObserver::DisplayChangeObserver() { | 162 DisplayChangeObserver::DisplayChangeObserver() { |
| 101 Shell::GetInstance()->AddShellObserver(this); | 163 Shell::GetInstance()->AddShellObserver(this); |
| 102 } | 164 } |
| 103 | 165 |
| 104 DisplayChangeObserver::~DisplayChangeObserver() { | 166 DisplayChangeObserver::~DisplayChangeObserver() { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 143 continue; | 205 continue; |
| 144 | 206 |
| 145 float device_scale_factor = 1.0f; | 207 float device_scale_factor = 1.0f; |
| 146 if (!ui::IsDisplaySizeBlackListed(state.display->physical_size())) { | 208 if (!ui::IsDisplaySizeBlackListed(state.display->physical_size())) { |
| 147 device_scale_factor = | 209 device_scale_factor = |
| 148 FindDeviceScaleFactor((kInchInMm * mode_info->size().width() / | 210 FindDeviceScaleFactor((kInchInMm * mode_info->size().width() / |
| 149 state.display->physical_size().width())); | 211 state.display->physical_size().width())); |
| 150 } | 212 } |
| 151 gfx::Rect display_bounds(state.display->origin(), mode_info->size()); | 213 gfx::Rect display_bounds(state.display->origin(), mode_info->size()); |
| 152 | 214 |
| 153 std::vector<DisplayMode> display_modes = GetDisplayModeList(state); | |
| 154 | |
| 155 std::string name = | 215 std::string name = |
| 156 state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL ? | 216 state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL ? |
| 157 l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME) : | 217 l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME) : |
| 158 state.display->display_name(); | 218 state.display->display_name(); |
| 159 if (name.empty()) | 219 if (name.empty()) |
| 160 name = l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); | 220 name = l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); |
| 161 | 221 |
| 162 bool has_overscan = state.display->has_overscan(); | 222 bool has_overscan = state.display->has_overscan(); |
| 163 int64 id = state.display->display_id(); | 223 int64 id = state.display->display_id(); |
| 164 ids.insert(id); | 224 ids.insert(id); |
| 165 | 225 |
| 166 displays.push_back(DisplayInfo(id, name, has_overscan)); | 226 displays.push_back(DisplayInfo(id, name, has_overscan)); |
| 167 DisplayInfo& new_info = displays.back(); | 227 DisplayInfo& new_info = displays.back(); |
| 168 new_info.set_device_scale_factor(device_scale_factor); | 228 new_info.set_device_scale_factor(device_scale_factor); |
| 169 new_info.SetBounds(display_bounds); | 229 new_info.SetBounds(display_bounds); |
| 170 new_info.set_native(true); | 230 new_info.set_native(true); |
| 171 new_info.set_display_modes(display_modes); | |
| 172 new_info.set_touch_support(state.touch_device_id == 0 ? | 231 new_info.set_touch_support(state.touch_device_id == 0 ? |
| 173 gfx::Display::TOUCH_SUPPORT_UNAVAILABLE : | 232 gfx::Display::TOUCH_SUPPORT_UNAVAILABLE : |
| 174 gfx::Display::TOUCH_SUPPORT_AVAILABLE); | 233 gfx::Display::TOUCH_SUPPORT_AVAILABLE); |
| 175 new_info.set_touch_device_id(state.touch_device_id); | 234 new_info.set_touch_device_id(state.touch_device_id); |
| 176 new_info.set_is_aspect_preserving_scaling( | 235 new_info.set_is_aspect_preserving_scaling( |
| 177 state.display->is_aspect_preserving_scaling()); | 236 state.display->is_aspect_preserving_scaling()); |
| 237 | |
| 238 std::vector<DisplayMode> display_modes = | |
| 239 (state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) ? | |
| 240 GetInternalDisplayModeList(new_info, state) : GetDisplayModeList(state); | |
| 241 new_info.set_display_modes(display_modes); | |
| 242 | |
| 178 new_info.set_available_color_profiles( | 243 new_info.set_available_color_profiles( |
| 179 Shell::GetInstance() | 244 Shell::GetInstance() |
| 180 ->display_configurator() | 245 ->display_configurator() |
| 181 ->GetAvailableColorCalibrationProfiles(id)); | 246 ->GetAvailableColorCalibrationProfiles(id)); |
| 182 } | 247 } |
| 183 | 248 |
| 184 // DisplayManager can be null during the boot. | 249 // DisplayManager can be null during the boot. |
| 185 Shell::GetInstance()->display_manager()->OnNativeDisplaysChanged(displays); | 250 Shell::GetInstance()->display_manager()->OnNativeDisplaysChanged(displays); |
| 186 } | 251 } |
| 187 | 252 |
| 188 void DisplayChangeObserver::OnAppTerminating() { | 253 void DisplayChangeObserver::OnAppTerminating() { |
| 189 #if defined(USE_ASH) | 254 #if defined(USE_ASH) |
| 190 // Stop handling display configuration events once the shutdown | 255 // Stop handling display configuration events once the shutdown |
| 191 // process starts. crbug.com/177014. | 256 // process starts. crbug.com/177014. |
| 192 Shell::GetInstance()->display_configurator()->PrepareForExit(); | 257 Shell::GetInstance()->display_configurator()->PrepareForExit(); |
| 193 #endif | 258 #endif |
| 194 } | 259 } |
| 195 | 260 |
| 196 // static | 261 // static |
| 197 float DisplayChangeObserver::FindDeviceScaleFactor(float dpi) { | 262 float DisplayChangeObserver::FindDeviceScaleFactor(float dpi) { |
| 198 for (size_t i = 0; i < arraysize(kThresholdTable); ++i) { | 263 for (size_t i = 0; i < arraysize(kThresholdTable); ++i) { |
| 199 if (dpi > kThresholdTable[i].dpi) | 264 if (dpi > kThresholdTable[i].dpi) |
| 200 return kThresholdTable[i].device_scale_factor; | 265 return kThresholdTable[i].device_scale_factor; |
| 201 } | 266 } |
| 202 return 1.0f; | 267 return 1.0f; |
| 203 } | 268 } |
| 204 | 269 |
| 205 } // namespace ash | 270 } // namespace ash |
| OLD | NEW |