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