| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/common/display/display_info.h" | 5 #include "ash/common/display/display_info.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 } | 53 } |
| 54 return false; | 54 return false; |
| 55 } | 55 } |
| 56 | 56 |
| 57 // Display mode list is sorted by: | 57 // Display mode list is sorted by: |
| 58 // * the area in pixels in ascending order | 58 // * the area in pixels in ascending order |
| 59 // * refresh rate in descending order | 59 // * refresh rate in descending order |
| 60 struct DisplayModeSorter { | 60 struct DisplayModeSorter { |
| 61 explicit DisplayModeSorter(bool is_internal) : is_internal(is_internal) {} | 61 explicit DisplayModeSorter(bool is_internal) : is_internal(is_internal) {} |
| 62 | 62 |
| 63 bool operator()(const DisplayMode& a, const DisplayMode& b) { | 63 bool operator()(const scoped_refptr<DisplayMode>& a, |
| 64 gfx::Size size_a_dip = a.GetSizeInDIP(is_internal); | 64 const scoped_refptr<DisplayMode>& b) { |
| 65 gfx::Size size_b_dip = b.GetSizeInDIP(is_internal); | 65 gfx::Size size_a_dip = a->GetSizeInDIP(is_internal); |
| 66 gfx::Size size_b_dip = b->GetSizeInDIP(is_internal); |
| 66 if (size_a_dip.GetArea() == size_b_dip.GetArea()) | 67 if (size_a_dip.GetArea() == size_b_dip.GetArea()) |
| 67 return (a.refresh_rate > b.refresh_rate); | 68 return (a->refresh_rate() > b->refresh_rate()); |
| 68 return (size_a_dip.GetArea() < size_b_dip.GetArea()); | 69 return (size_a_dip.GetArea() < size_b_dip.GetArea()); |
| 69 } | 70 } |
| 70 | 71 |
| 71 bool is_internal; | 72 bool is_internal; |
| 72 }; | 73 }; |
| 73 | 74 |
| 74 } // namespace | 75 } // namespace |
| 75 | 76 |
| 76 DisplayMode::DisplayMode() | 77 DisplayMode::DisplayMode() |
| 77 : refresh_rate(0.0f), | 78 : refresh_rate_(0.0f), |
| 78 interlaced(false), | 79 is_interlaced_(false), |
| 79 native(false), | 80 native_(false), |
| 80 ui_scale(1.0f), | 81 ui_scale_(1.0f), |
| 81 device_scale_factor(1.0f) {} | 82 device_scale_factor_(1.0f) {} |
| 83 |
| 84 DisplayMode::DisplayMode(const gfx::Size& size) |
| 85 : size_(size), |
| 86 refresh_rate_(0.0f), |
| 87 is_interlaced_(false), |
| 88 native_(false), |
| 89 ui_scale_(1.0f), |
| 90 device_scale_factor_(1.0f) {} |
| 82 | 91 |
| 83 DisplayMode::DisplayMode(const gfx::Size& size, | 92 DisplayMode::DisplayMode(const gfx::Size& size, |
| 84 float refresh_rate, | 93 float refresh_rate, |
| 85 bool interlaced, | 94 bool is_interlaced, |
| 86 bool native) | 95 bool native) |
| 87 : size(size), | 96 : size_(size), |
| 88 refresh_rate(refresh_rate), | 97 refresh_rate_(refresh_rate), |
| 89 interlaced(interlaced), | 98 is_interlaced_(is_interlaced), |
| 90 native(native), | 99 native_(native), |
| 91 ui_scale(1.0f), | 100 ui_scale_(1.0f), |
| 92 device_scale_factor(1.0f) {} | 101 device_scale_factor_(1.0f) {} |
| 102 |
| 103 DisplayMode::~DisplayMode(){}; |
| 104 |
| 105 DisplayMode::DisplayMode(const gfx::Size& size, |
| 106 float refresh_rate, |
| 107 bool is_interlaced, |
| 108 bool native, |
| 109 float ui_scale, |
| 110 float device_scale_factor) |
| 111 : size_(size), |
| 112 refresh_rate_(refresh_rate), |
| 113 is_interlaced_(is_interlaced), |
| 114 native_(native), |
| 115 ui_scale_(ui_scale), |
| 116 device_scale_factor_(device_scale_factor) {} |
| 93 | 117 |
| 94 gfx::Size DisplayMode::GetSizeInDIP(bool is_internal) const { | 118 gfx::Size DisplayMode::GetSizeInDIP(bool is_internal) const { |
| 95 gfx::SizeF size_dip(size); | 119 gfx::SizeF size_dip(size_); |
| 96 size_dip.Scale(ui_scale); | 120 size_dip.Scale(ui_scale_); |
| 97 // DSF=1.25 is special on internal display. The screen is drawn with DSF=1.25 | 121 // DSF=1.25 is special on internal display. The screen is drawn with DSF=1.25 |
| 98 // but it doesn't affect the screen size computation. | 122 // but it doesn't affect the screen size computation. |
| 99 if (use_125_dsf_for_ui_scaling && is_internal && device_scale_factor == 1.25f) | 123 if (use_125_dsf_for_ui_scaling && is_internal && |
| 124 device_scale_factor_ == 1.25f) |
| 100 return gfx::ToFlooredSize(size_dip); | 125 return gfx::ToFlooredSize(size_dip); |
| 101 size_dip.Scale(1.0f / device_scale_factor); | 126 size_dip.Scale(1.0f / device_scale_factor_); |
| 102 return gfx::ToFlooredSize(size_dip); | 127 return gfx::ToFlooredSize(size_dip); |
| 103 } | 128 } |
| 104 | 129 |
| 105 bool DisplayMode::IsEquivalent(const DisplayMode& other) const { | 130 bool DisplayMode::IsEquivalent(const scoped_refptr<DisplayMode>& other) const { |
| 106 const float kEpsilon = 0.0001f; | 131 const float kEpsilon = 0.0001f; |
| 107 return size == other.size && std::abs(ui_scale - other.ui_scale) < kEpsilon && | 132 return size_ == other->size_ && |
| 108 std::abs(device_scale_factor - other.device_scale_factor) < kEpsilon; | 133 std::abs(ui_scale_ - other->ui_scale_) < kEpsilon && |
| 134 std::abs(device_scale_factor_ - other->device_scale_factor_) < |
| 135 kEpsilon; |
| 109 } | 136 } |
| 110 | 137 |
| 111 // satic | 138 // static |
| 112 DisplayInfo DisplayInfo::CreateFromSpec(const std::string& spec) { | 139 DisplayInfo DisplayInfo::CreateFromSpec(const std::string& spec) { |
| 113 return CreateFromSpecWithID(spec, display::Display::kInvalidDisplayID); | 140 return CreateFromSpecWithID(spec, display::Display::kInvalidDisplayID); |
| 114 } | 141 } |
| 115 | 142 |
| 116 // static | 143 // static |
| 117 DisplayInfo DisplayInfo::CreateFromSpecWithID(const std::string& spec, | 144 DisplayInfo DisplayInfo::CreateFromSpecWithID(const std::string& spec, |
| 118 int64_t id) { | 145 int64_t id) { |
| 119 #if defined(OS_WIN) | 146 #if defined(OS_WIN) |
| 120 gfx::Rect bounds_in_native( | 147 gfx::Rect bounds_in_native( |
| 121 gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN))); | 148 gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN))); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 } | 195 } |
| 169 } | 196 } |
| 170 | 197 |
| 171 float device_scale_factor = 1.0f; | 198 float device_scale_factor = 1.0f; |
| 172 if (!GetDisplayBounds(main_spec, &bounds_in_native, &device_scale_factor)) { | 199 if (!GetDisplayBounds(main_spec, &bounds_in_native, &device_scale_factor)) { |
| 173 #if defined(OS_WIN) | 200 #if defined(OS_WIN) |
| 174 device_scale_factor = display::win::GetDPIScale(); | 201 device_scale_factor = display::win::GetDPIScale(); |
| 175 #endif | 202 #endif |
| 176 } | 203 } |
| 177 | 204 |
| 178 std::vector<DisplayMode> display_modes; | 205 DisplayModeList display_modes; |
| 179 parts = base::SplitString(main_spec, "#", base::KEEP_WHITESPACE, | 206 parts = base::SplitString(main_spec, "#", base::KEEP_WHITESPACE, |
| 180 base::SPLIT_WANT_NONEMPTY); | 207 base::SPLIT_WANT_NONEMPTY); |
| 181 if (parts.size() == 2) { | 208 if (parts.size() == 2) { |
| 182 size_t native_mode = 0; | 209 size_t native_mode = 0; |
| 183 int largest_area = -1; | 210 int largest_area = -1; |
| 184 float highest_refresh_rate = -1.0f; | 211 float highest_refresh_rate = -1.0f; |
| 185 main_spec = parts[0]; | 212 main_spec = parts[0]; |
| 186 std::string resolution_list = parts[1]; | 213 std::string resolution_list = parts[1]; |
| 187 parts = base::SplitString(resolution_list, "|", base::KEEP_WHITESPACE, | 214 parts = base::SplitString(resolution_list, "|", base::KEEP_WHITESPACE, |
| 188 base::SPLIT_WANT_NONEMPTY); | 215 base::SPLIT_WANT_NONEMPTY); |
| 189 for (size_t i = 0; i < parts.size(); ++i) { | 216 for (size_t i = 0; i < parts.size(); ++i) { |
| 190 DisplayMode mode; | 217 gfx::Size size; |
| 218 float refresh_rate = 0.0f; |
| 219 bool is_interlaced = false; |
| 220 |
| 191 gfx::Rect mode_bounds; | 221 gfx::Rect mode_bounds; |
| 192 std::vector<std::string> resolution = base::SplitString( | 222 std::vector<std::string> resolution = base::SplitString( |
| 193 parts[i], "%", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | 223 parts[i], "%", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| 194 if (GetDisplayBounds(resolution[0], &mode_bounds, | 224 if (GetDisplayBounds(resolution[0], &mode_bounds, &device_scale_factor)) { |
| 195 &mode.device_scale_factor)) { | 225 size = mode_bounds.size(); |
| 196 mode.size = mode_bounds.size(); | |
| 197 if (resolution.size() > 1) | 226 if (resolution.size() > 1) |
| 198 sscanf(resolution[1].c_str(), "%f", &mode.refresh_rate); | 227 sscanf(resolution[1].c_str(), "%f", &refresh_rate); |
| 199 if (mode.size.GetArea() >= largest_area && | 228 if (size.GetArea() >= largest_area && |
| 200 mode.refresh_rate > highest_refresh_rate) { | 229 refresh_rate > highest_refresh_rate) { |
| 201 // Use mode with largest area and highest refresh rate as native. | 230 // Use mode with largest area and highest refresh rate as native. |
| 202 largest_area = mode.size.GetArea(); | 231 largest_area = size.GetArea(); |
| 203 highest_refresh_rate = mode.refresh_rate; | 232 highest_refresh_rate = refresh_rate; |
| 204 native_mode = i; | 233 native_mode = i; |
| 205 } | 234 } |
| 206 display_modes.push_back(mode); | 235 display_modes.push_back(make_scoped_refptr( |
| 236 new DisplayMode(size, refresh_rate, is_interlaced, false, 1.0, |
| 237 device_scale_factor))); |
| 207 } | 238 } |
| 208 } | 239 } |
| 209 display_modes[native_mode].native = true; | 240 scoped_refptr<DisplayMode> dm = display_modes[native_mode]; |
| 241 display_modes[native_mode] = |
| 242 new DisplayMode(dm->size(), dm->refresh_rate(), dm->is_interlaced(), |
| 243 true, dm->ui_scale(), dm->device_scale_factor()); |
| 210 } | 244 } |
| 211 | 245 |
| 212 if (id == display::Display::kInvalidDisplayID) | 246 if (id == display::Display::kInvalidDisplayID) |
| 213 id = synthesized_display_id++; | 247 id = synthesized_display_id++; |
| 214 DisplayInfo display_info( | 248 DisplayInfo display_info( |
| 215 id, base::StringPrintf("Display-%d", static_cast<int>(id)), has_overscan); | 249 id, base::StringPrintf("Display-%d", static_cast<int>(id)), has_overscan); |
| 216 display_info.set_device_scale_factor(device_scale_factor); | 250 display_info.set_device_scale_factor(device_scale_factor); |
| 217 display_info.SetRotation(rotation, display::Display::ROTATION_SOURCE_ACTIVE); | 251 display_info.SetRotation(rotation, display::Display::ROTATION_SOURCE_ACTIVE); |
| 218 display_info.set_configured_ui_scale(ui_scale); | 252 display_info.set_configured_ui_scale(ui_scale); |
| 219 display_info.SetBounds(bounds_in_native); | 253 display_info.SetBounds(bounds_in_native); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 } | 399 } |
| 366 | 400 |
| 367 void DisplayInfo::SetOverscanInsets(const gfx::Insets& insets_in_dip) { | 401 void DisplayInfo::SetOverscanInsets(const gfx::Insets& insets_in_dip) { |
| 368 overscan_insets_in_dip_ = insets_in_dip; | 402 overscan_insets_in_dip_ = insets_in_dip; |
| 369 } | 403 } |
| 370 | 404 |
| 371 gfx::Insets DisplayInfo::GetOverscanInsetsInPixel() const { | 405 gfx::Insets DisplayInfo::GetOverscanInsetsInPixel() const { |
| 372 return overscan_insets_in_dip_.Scale(device_scale_factor_); | 406 return overscan_insets_in_dip_.Scale(device_scale_factor_); |
| 373 } | 407 } |
| 374 | 408 |
| 375 void DisplayInfo::SetDisplayModes( | 409 void DisplayInfo::SetDisplayModes(const DisplayModeList& display_modes) { |
| 376 const std::vector<DisplayMode>& display_modes) { | |
| 377 display_modes_ = display_modes; | 410 display_modes_ = display_modes; |
| 378 std::sort(display_modes_.begin(), display_modes_.end(), | 411 std::sort(display_modes_.begin(), display_modes_.end(), |
| 379 DisplayModeSorter(display::Display::IsInternalDisplayId(id_))); | 412 DisplayModeSorter(display::Display::IsInternalDisplayId(id_))); |
| 380 } | 413 } |
| 381 | 414 |
| 382 gfx::Size DisplayInfo::GetNativeModeSize() const { | 415 gfx::Size DisplayInfo::GetNativeModeSize() const { |
| 383 for (size_t i = 0; i < display_modes_.size(); ++i) { | 416 for (size_t i = 0; i < display_modes_.size(); ++i) { |
| 384 if (display_modes_[i].native) | 417 if (display_modes_[i]->native()) |
| 385 return display_modes_[i].size; | 418 return display_modes_[i]->size(); |
| 386 } | 419 } |
| 387 | |
| 388 return gfx::Size(); | 420 return gfx::Size(); |
| 389 } | 421 } |
| 390 | 422 |
| 391 std::string DisplayInfo::ToString() const { | 423 std::string DisplayInfo::ToString() const { |
| 392 int rotation_degree = static_cast<int>(GetActiveRotation()) * 90; | 424 int rotation_degree = static_cast<int>(GetActiveRotation()) * 90; |
| 393 std::string devices_str; | 425 std::string devices_str; |
| 394 | 426 |
| 395 for (size_t i = 0; i < input_devices_.size(); ++i) { | 427 for (size_t i = 0; i < input_devices_.size(); ++i) { |
| 396 devices_str += base::IntToString(input_devices_[i]); | 428 devices_str += base::IntToString(input_devices_[i]); |
| 397 if (i != input_devices_.size() - 1) | 429 if (i != input_devices_.size() - 1) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 411 : touch_support_ == display::Display::TOUCH_SUPPORT_UNAVAILABLE | 443 : touch_support_ == display::Display::TOUCH_SUPPORT_UNAVAILABLE |
| 412 ? "no" | 444 ? "no" |
| 413 : "unknown", | 445 : "unknown", |
| 414 devices_str.c_str()); | 446 devices_str.c_str()); |
| 415 | 447 |
| 416 return result; | 448 return result; |
| 417 } | 449 } |
| 418 | 450 |
| 419 std::string DisplayInfo::ToFullString() const { | 451 std::string DisplayInfo::ToFullString() const { |
| 420 std::string display_modes_str; | 452 std::string display_modes_str; |
| 421 std::vector<DisplayMode>::const_iterator iter = display_modes_.begin(); | 453 DisplayModeList::const_iterator iter = display_modes_.begin(); |
| 422 for (; iter != display_modes_.end(); ++iter) { | 454 for (; iter != display_modes_.end(); ++iter) { |
| 455 scoped_refptr<DisplayMode> m(*iter); |
| 423 if (!display_modes_str.empty()) | 456 if (!display_modes_str.empty()) |
| 424 display_modes_str += ","; | 457 display_modes_str += ","; |
| 425 base::StringAppendF(&display_modes_str, "(%dx%d@%f%c%s)", | 458 base::StringAppendF(&display_modes_str, "(%dx%d@%f%c%s)", m->size().width(), |
| 426 iter->size.width(), iter->size.height(), | 459 m->size().height(), m->refresh_rate(), |
| 427 iter->refresh_rate, iter->interlaced ? 'I' : 'P', | 460 m->is_interlaced() ? 'I' : 'P', |
| 428 iter->native ? "(N)" : ""); | 461 m->native() ? "(N)" : ""); |
| 429 } | 462 } |
| 430 return ToString() + ", display_modes==" + display_modes_str; | 463 return ToString() + ", display_modes==" + display_modes_str; |
| 431 } | 464 } |
| 432 | 465 |
| 433 void DisplayInfo::SetColorProfile(ui::ColorCalibrationProfile profile) { | 466 void DisplayInfo::SetColorProfile(ui::ColorCalibrationProfile profile) { |
| 434 if (IsColorProfileAvailable(profile)) | 467 if (IsColorProfileAvailable(profile)) |
| 435 color_profile_ = profile; | 468 color_profile_ = profile; |
| 436 } | 469 } |
| 437 | 470 |
| 438 bool DisplayInfo::IsColorProfileAvailable( | 471 bool DisplayInfo::IsColorProfileAvailable( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 453 | 486 |
| 454 void DisplayInfo::ClearInputDevices() { | 487 void DisplayInfo::ClearInputDevices() { |
| 455 input_devices_.clear(); | 488 input_devices_.clear(); |
| 456 } | 489 } |
| 457 | 490 |
| 458 void ResetDisplayIdForTest() { | 491 void ResetDisplayIdForTest() { |
| 459 synthesized_display_id = kSynthesizedDisplayIdStart; | 492 synthesized_display_id = kSynthesizedDisplayIdStart; |
| 460 } | 493 } |
| 461 | 494 |
| 462 } // namespace ash | 495 } // namespace ash |
| OLD | NEW |