display_info.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdio.h> 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/display/display_info.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/display.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size_conversions.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size_f.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window_tree_host.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/win/dpi.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ash { 24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace { 25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool use_125_dsf_for_ui_scaling = false; 27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Check the content of |spec| and fill |bounds| and |device_scale_factor|. 296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Returns true when |bounds| is found. 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool GetDisplayBounds( 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const std::string& spec, gfx::Rect* bounds, float* device_scale_factor) { 326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int width = 0; 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int height = 0; 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int x = 0; 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int y = 0; 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (sscanf(spec.c_str(), "%dx%d*%f", 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &width, &height, device_scale_factor) >= 2 || 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) sscanf(spec.c_str(), "%d+%d-%dx%d*%f", &x, &y, &width, &height, 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) device_scale_factor) >= 4) { 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bounds->SetRect(x, y, width, height); 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return true; 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DisplayMode::DisplayMode() 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : refresh_rate(0.0f), 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) interlaced(false), 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) native(false), 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui_scale(1.0f), 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) device_scale_factor(1.0f) {} 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DisplayMode::DisplayMode(const gfx::Size& size, 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) float refresh_rate, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool interlaced, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool native) 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : size(size), 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) refresh_rate(refresh_rate), 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) interlaced(interlaced), 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) native(native), 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui_scale(1.0f), 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) device_scale_factor(1.0f) {} 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)gfx::Size DisplayMode::GetSizeInDIP() const { 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::SizeF size_dip(size); 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_dip.Scale(ui_scale); 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_dip.Scale(1.0f / device_scale_factor); 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return gfx::ToFlooredSize(size_dip); 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool DisplayMode::IsEquivalent(const DisplayMode& other) const { 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const float kEpsilon = 0.0001f; 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return size == other.size && 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::abs(ui_scale - other.ui_scale) < kEpsilon && 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::abs(device_scale_factor - other.device_scale_factor) < kEpsilon; 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// satic 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo DisplayInfo::CreateFromSpec(const std::string& spec) { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateFromSpecWithID(spec, gfx::Display::kInvalidDisplayID); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DisplayInfo::SetUse125DSFForUIScaling(bool enable) { 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci use_125_dsf_for_ui_scaling = enable; 90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// static 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo DisplayInfo::CreateFromSpecWithID(const std::string& spec, 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 id) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Default bounds for a display. 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kDefaultHostWindowX = 200; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kDefaultHostWindowY = 200; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kDefaultHostWindowWidth = 1366; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kDefaultHostWindowHeight = 768; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Use larger than max int to catch overflow early. 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static int64 synthesized_display_id = 2200000000LL; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect bounds_in_native(aura::WindowTreeHost::GetNativeScreenSize()); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect bounds_in_native(kDefaultHostWindowX, kDefaultHostWindowY, 10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) kDefaultHostWindowWidth, kDefaultHostWindowHeight); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string main_spec = spec; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float ui_scale = 1.0f; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> parts; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Tokenize(main_spec, "@", &parts) == 2) { 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double scale_in_double = 0; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::StringToDouble(parts[1], &scale_in_double)) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_scale = scale_in_double; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) main_spec = parts[0]; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t count = Tokenize(main_spec, "/", &parts); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Display::Rotation rotation(gfx::Display::ROTATE_0); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_overscan = false; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (count) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) main_spec = parts[0]; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (count >= 2) { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string options = parts[1]; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < options.size(); ++i) { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char c = options[i]; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (c) { 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 'o': 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_overscan = true; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 'r': // rotate 90 degrees to 'right'. 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation = gfx::Display::ROTATE_90; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 'u': // 180 degrees, 'u'pside-down. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation = gfx::Display::ROTATE_180; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 'l': // rotate 90 degrees to 'left'. 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation = gfx::Display::ROTATE_270; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float device_scale_factor = 1.0f; 1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!GetDisplayBounds(main_spec, &bounds_in_native, &device_scale_factor)) { 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (gfx::IsHighDPIEnabled()) { 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) device_scale_factor = gfx::GetDPIScale(); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<DisplayMode> display_modes; 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (Tokenize(main_spec, "#", &parts) == 2) { 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t native_mode = 0; 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int largest_area = -1; 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) float highest_refresh_rate = -1.0f; 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) main_spec = parts[0]; 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string resolution_list = parts[1]; 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) count = Tokenize(resolution_list, "|", &parts); 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < count; ++i) { 1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DisplayMode mode; 1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::Rect mode_bounds; 1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::vector<std::string> resolution; 1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Tokenize(parts[i], "%", &resolution); 1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (GetDisplayBounds( 1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) resolution[0], &mode_bounds, &mode.device_scale_factor)) { 1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mode.size = mode_bounds.size(); 1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (resolution.size() > 1) 1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) sscanf(resolution[1].c_str(), "%f", &mode.refresh_rate); 1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (mode.size.GetArea() >= largest_area && 1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mode.refresh_rate > highest_refresh_rate) { 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Use mode with largest area and highest refresh rate as native. 1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) largest_area = mode.size.GetArea(); 1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) highest_refresh_rate = mode.refresh_rate; 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_mode = i; 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) display_modes.push_back(mode); 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes[native_mode].native = true; 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (id == gfx::Display::kInvalidDisplayID) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id = synthesized_display_id++; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfo display_info( 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id, base::StringPrintf("Display-%d", static_cast<int>(id)), has_overscan); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info.set_device_scale_factor(device_scale_factor); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info.set_rotation(rotation); 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) display_info.set_configured_ui_scale(ui_scale); 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) display_info.SetBounds(bounds_in_native); 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_info.set_display_modes(display_modes); 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // To test the overscan, it creates the default 5% overscan. 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (has_overscan) { 20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int width = bounds_in_native.width() / device_scale_factor / 40; 20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int height = bounds_in_native.height() / device_scale_factor / 40; 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch display_info.SetOverscanInsets(gfx::Insets(height, width, height, width)); 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch display_info.UpdateDisplaySize(); 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "DisplayInfoFromSpec info=" << display_info.ToString() 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ", spec=" << spec; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return display_info; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo::DisplayInfo() 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : id_(gfx::Display::kInvalidDisplayID), 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_overscan_(false), 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_(gfx::Display::ROTATE_0), 2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) touch_device_id_(0), 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_scale_factor_(1.0f), 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_(0, 0, 0, 0), 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) configured_ui_scale_(1.0f), 220effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch native_(false), 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch is_aspect_preserving_scaling_(false), 222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch color_profile_(ui::COLOR_PROFILE_STANDARD) { 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo::DisplayInfo(int64 id, 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& name, 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_overscan) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : id_(id), 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name_(name), 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_overscan_(has_overscan), 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_(gfx::Display::ROTATE_0), 2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) touch_device_id_(0), 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_scale_factor_(1.0f), 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_(0, 0, 0, 0), 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) configured_ui_scale_(1.0f), 237effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch native_(false), 238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch color_profile_(ui::COLOR_PROFILE_STANDARD) { 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo::~DisplayInfo() { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayInfo::Copy(const DisplayInfo& native_info) { 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(id_ == native_info.id_); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name_ = native_info.name_; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_overscan_ = native_info.has_overscan_; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(!native_info.bounds_in_native_.IsEmpty()); 25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_in_native_ = native_info.bounds_in_native_; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_ = native_info.size_in_pixel_; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_scale_factor_ = native_info.device_scale_factor_; 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes_ = native_info.display_modes_; 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) touch_support_ = native_info.touch_support_; 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) touch_device_id_ = native_info.touch_device_id_; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Copy overscan_insets_in_dip_ if it's not empty. This is for test 258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // cases which use "/o" annotation which sets the overscan inset 259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // to native, and that overscan has to be propagated. This does not 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // happen on the real environment. 261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!native_info.overscan_insets_in_dip_.empty()) 262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch overscan_insets_in_dip_ = native_info.overscan_insets_in_dip_; 263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Rotation_ and ui_scale_ color_profile_ are given by preference, 265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // or unit tests. Don't copy if this native_info came from 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // DisplayChangeObserver. 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!native_info.native()) { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_ = native_info.rotation_; 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) configured_ui_scale_ = native_info.configured_ui_scale_; 270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch color_profile_ = native_info.color_profile(); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch available_color_profiles_ = native_info.available_color_profiles(); 274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't copy insets as it may be given by preference. |rotation_| 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is treated as a native so that it can be specified in 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |CreateFromSpec|. 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DisplayInfo::SetBounds(const gfx::Rect& new_bounds_in_native) { 28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_in_native_ = new_bounds_in_native; 28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_in_pixel_ = new_bounds_in_native.size(); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateDisplaySize(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 286a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfloat DisplayInfo::GetEffectiveDeviceScaleFactor() const { 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (use_125_dsf_for_ui_scaling && device_scale_factor_ == 1.25f) 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (configured_ui_scale_ == 0.8f) ? 1.25f : 1.0f; 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (device_scale_factor_ == configured_ui_scale_) 290a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return 1.0f; 291a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return device_scale_factor_; 292a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 293a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)float DisplayInfo::GetEffectiveUIScale() const { 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (use_125_dsf_for_ui_scaling && device_scale_factor_ == 1.25f) 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (configured_ui_scale_ == 0.8f) ? 1.0f : configured_ui_scale_; 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (device_scale_factor_ == configured_ui_scale_) 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 1.0f; 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return configured_ui_scale_; 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayInfo::UpdateDisplaySize() { 30368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_in_pixel_ = bounds_in_native_.size(); 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!overscan_insets_in_dip_.empty()) { 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Insets insets_in_pixel = 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_.Scale(device_scale_factor_); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_.Enlarge(-insets_in_pixel.width(), -insets_in_pixel.height()); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_.Set(0, 0, 0, 0); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rotation_ == gfx::Display::ROTATE_90 || 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_ == gfx::Display::ROTATE_270) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_.SetSize(size_in_pixel_.height(), size_in_pixel_.width()); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::SizeF size_f(size_in_pixel_); 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_f.Scale(GetEffectiveUIScale()); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_ = gfx::ToFlooredSize(size_f); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DisplayInfo::SetOverscanInsets(const gfx::Insets& insets_in_dip) { 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_ = insets_in_dip; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Insets DisplayInfo::GetOverscanInsetsInPixel() const { 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return overscan_insets_in_dip_.Scale(device_scale_factor_); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccigfx::Size DisplayInfo::GetNativeModeSize() const { 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < display_modes_.size(); ++i) { 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (display_modes_[i].native) 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return display_modes_[i].size; 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return gfx::Size(); 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DisplayInfo::ToString() const { 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rotation_degree = static_cast<int>(rotation_) * 90; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "DisplayInfo[%lld] native bounds=%s, size=%s, scale=%f, " 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "overscan=%s, rotation=%d, ui-scale=%f, touchscreen=%s, " 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "touch-device-id=%d", 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<long long int>(id_), 34468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_in_native_.ToString().c_str(), 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_.ToString().c_str(), 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_scale_factor_, 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_.ToString().c_str(), 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_degree, 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) configured_ui_scale_, 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) touch_support_ == gfx::Display::TOUCH_SUPPORT_AVAILABLE 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? "yes" 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : touch_support_ == gfx::Display::TOUCH_SUPPORT_UNAVAILABLE 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? "no" 354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : "unknown", 355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) touch_device_id_); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)std::string DisplayInfo::ToFullString() const { 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string display_modes_str; 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<DisplayMode>::const_iterator iter = display_modes_.begin(); 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (; iter != display_modes_.end(); ++iter) { 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!display_modes_str.empty()) 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes_str += ","; 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::StringAppendF(&display_modes_str, 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "(%dx%d@%f%c%s)", 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->size.width(), 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->size.height(), 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->refresh_rate, 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->interlaced ? 'I' : 'P', 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->native ? "(N)" : ""); 371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ToString() + ", display_modes==" + display_modes_str; 373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DisplayInfo::SetColorProfile(ui::ColorCalibrationProfile profile) { 376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (IsColorProfileAvailable(profile)) 377effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch color_profile_ = profile; 378effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 379effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 380effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool DisplayInfo::IsColorProfileAvailable( 381effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui::ColorCalibrationProfile profile) const { 382effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return std::find(available_color_profiles_.begin(), 383effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch available_color_profiles_.end(), 384effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch profile) != available_color_profiles_.end(); 385effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 386effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace ash 388