display_info.cc revision 34680572440d7894ef8dafce81d8039ed80726a2
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); 6934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // DSF=1.25 is special. The screen is drawn with DSF=1.25 in some mode but it 7034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) // doesn't affect the screen size computation. 7134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) if (!use_125_dsf_for_ui_scaling || device_scale_factor != 1.25f) 7234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) size_dip.Scale(1.0f / device_scale_factor); 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return gfx::ToFlooredSize(size_dip); 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool DisplayMode::IsEquivalent(const DisplayMode& other) const { 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const float kEpsilon = 0.0001f; 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return size == other.size && 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::abs(ui_scale - other.ui_scale) < kEpsilon && 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::abs(device_scale_factor - other.device_scale_factor) < kEpsilon; 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// satic 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo DisplayInfo::CreateFromSpec(const std::string& spec) { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateFromSpecWithID(spec, gfx::Display::kInvalidDisplayID); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DisplayInfo::SetUse125DSFForUIScaling(bool enable) { 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci use_125_dsf_for_ui_scaling = enable; 91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// static 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo DisplayInfo::CreateFromSpecWithID(const std::string& spec, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 id) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Default bounds for a display. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kDefaultHostWindowX = 200; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kDefaultHostWindowY = 200; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kDefaultHostWindowWidth = 1366; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kDefaultHostWindowHeight = 768; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Use larger than max int to catch overflow early. 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static int64 synthesized_display_id = 2200000000LL; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Rect bounds_in_native(aura::WindowTreeHost::GetNativeScreenSize()); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect bounds_in_native(kDefaultHostWindowX, kDefaultHostWindowY, 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) kDefaultHostWindowWidth, kDefaultHostWindowHeight); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string main_spec = spec; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float ui_scale = 1.0f; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> parts; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Tokenize(main_spec, "@", &parts) == 2) { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double scale_in_double = 0; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::StringToDouble(parts[1], &scale_in_double)) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_scale = scale_in_double; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) main_spec = parts[0]; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t count = Tokenize(main_spec, "/", &parts); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Display::Rotation rotation(gfx::Display::ROTATE_0); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_overscan = false; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (count) { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) main_spec = parts[0]; 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (count >= 2) { 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string options = parts[1]; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < options.size(); ++i) { 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char c = options[i]; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (c) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 'o': 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_overscan = true; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 'r': // rotate 90 degrees to 'right'. 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation = gfx::Display::ROTATE_90; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 'u': // 180 degrees, 'u'pside-down. 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation = gfx::Display::ROTATE_180; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 'l': // rotate 90 degrees to 'left'. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation = gfx::Display::ROTATE_270; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float device_scale_factor = 1.0f; 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!GetDisplayBounds(main_spec, &bounds_in_native, &device_scale_factor)) { 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (gfx::IsHighDPIEnabled()) { 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) device_scale_factor = gfx::GetDPIScale(); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<DisplayMode> display_modes; 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (Tokenize(main_spec, "#", &parts) == 2) { 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t native_mode = 0; 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int largest_area = -1; 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) float highest_refresh_rate = -1.0f; 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) main_spec = parts[0]; 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string resolution_list = parts[1]; 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) count = Tokenize(resolution_list, "|", &parts); 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < count; ++i) { 1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DisplayMode mode; 1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::Rect mode_bounds; 1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::vector<std::string> resolution; 1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Tokenize(parts[i], "%", &resolution); 1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (GetDisplayBounds( 1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) resolution[0], &mode_bounds, &mode.device_scale_factor)) { 1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mode.size = mode_bounds.size(); 1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (resolution.size() > 1) 1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) sscanf(resolution[1].c_str(), "%f", &mode.refresh_rate); 1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (mode.size.GetArea() >= largest_area && 1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mode.refresh_rate > highest_refresh_rate) { 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Use mode with largest area and highest refresh rate as native. 1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) largest_area = mode.size.GetArea(); 1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) highest_refresh_rate = mode.refresh_rate; 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_mode = i; 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) display_modes.push_back(mode); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes[native_mode].native = true; 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (id == gfx::Display::kInvalidDisplayID) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id = synthesized_display_id++; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayInfo display_info( 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id, base::StringPrintf("Display-%d", static_cast<int>(id)), has_overscan); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info.set_device_scale_factor(device_scale_factor); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info.set_rotation(rotation); 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) display_info.set_configured_ui_scale(ui_scale); 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) display_info.SetBounds(bounds_in_native); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_info.set_display_modes(display_modes); 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // To test the overscan, it creates the default 5% overscan. 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (has_overscan) { 20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int width = bounds_in_native.width() / device_scale_factor / 40; 20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int height = bounds_in_native.height() / device_scale_factor / 40; 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch display_info.SetOverscanInsets(gfx::Insets(height, width, height, width)); 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch display_info.UpdateDisplaySize(); 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "DisplayInfoFromSpec info=" << display_info.ToString() 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ", spec=" << spec; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return display_info; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo::DisplayInfo() 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : id_(gfx::Display::kInvalidDisplayID), 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_overscan_(false), 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_(gfx::Display::ROTATE_0), 2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) touch_device_id_(0), 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_scale_factor_(1.0f), 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_(0, 0, 0, 0), 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) configured_ui_scale_(1.0f), 221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch native_(false), 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch is_aspect_preserving_scaling_(false), 223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch color_profile_(ui::COLOR_PROFILE_STANDARD) { 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo::DisplayInfo(int64 id, 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& name, 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_overscan) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : id_(id), 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name_(name), 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_overscan_(has_overscan), 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_(gfx::Display::ROTATE_0), 2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) touch_device_id_(0), 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_scale_factor_(1.0f), 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_(0, 0, 0, 0), 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) configured_ui_scale_(1.0f), 238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch native_(false), 239effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch color_profile_(ui::COLOR_PROFILE_STANDARD) { 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo::~DisplayInfo() { 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayInfo::Copy(const DisplayInfo& native_info) { 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(id_ == native_info.id_); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name_ = native_info.name_; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_overscan_ = native_info.has_overscan_; 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(!native_info.bounds_in_native_.IsEmpty()); 25168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_in_native_ = native_info.bounds_in_native_; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_ = native_info.size_in_pixel_; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_scale_factor_ = native_info.device_scale_factor_; 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes_ = native_info.display_modes_; 2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) touch_support_ = native_info.touch_support_; 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) touch_device_id_ = native_info.touch_device_id_; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Copy overscan_insets_in_dip_ if it's not empty. This is for test 259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // cases which use "/o" annotation which sets the overscan inset 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // to native, and that overscan has to be propagated. This does not 261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // happen on the real environment. 262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!native_info.overscan_insets_in_dip_.empty()) 263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch overscan_insets_in_dip_ = native_info.overscan_insets_in_dip_; 264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Rotation_ and ui_scale_ color_profile_ are given by preference, 266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // or unit tests. Don't copy if this native_info came from 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // DisplayChangeObserver. 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!native_info.native()) { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_ = native_info.rotation_; 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) configured_ui_scale_ = native_info.configured_ui_scale_; 271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch color_profile_ = native_info.color_profile(); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch available_color_profiles_ = native_info.available_color_profiles(); 275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't copy insets as it may be given by preference. |rotation_| 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is treated as a native so that it can be specified in 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |CreateFromSpec|. 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DisplayInfo::SetBounds(const gfx::Rect& new_bounds_in_native) { 28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_in_native_ = new_bounds_in_native; 28368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_in_pixel_ = new_bounds_in_native.size(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateDisplaySize(); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 287a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfloat DisplayInfo::GetEffectiveDeviceScaleFactor() const { 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (use_125_dsf_for_ui_scaling && device_scale_factor_ == 1.25f) 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (configured_ui_scale_ == 0.8f) ? 1.25f : 1.0f; 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (device_scale_factor_ == configured_ui_scale_) 291a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return 1.0f; 292a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return device_scale_factor_; 293a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 294a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)float DisplayInfo::GetEffectiveUIScale() const { 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (use_125_dsf_for_ui_scaling && device_scale_factor_ == 1.25f) 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (configured_ui_scale_ == 0.8f) ? 1.0f : configured_ui_scale_; 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (device_scale_factor_ == configured_ui_scale_) 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 1.0f; 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return configured_ui_scale_; 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayInfo::UpdateDisplaySize() { 30468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) size_in_pixel_ = bounds_in_native_.size(); 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!overscan_insets_in_dip_.empty()) { 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Insets insets_in_pixel = 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_.Scale(device_scale_factor_); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_.Enlarge(-insets_in_pixel.width(), -insets_in_pixel.height()); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_.Set(0, 0, 0, 0); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rotation_ == gfx::Display::ROTATE_90 || 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_ == gfx::Display::ROTATE_270) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_.SetSize(size_in_pixel_.height(), size_in_pixel_.width()); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::SizeF size_f(size_in_pixel_); 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_f.Scale(GetEffectiveUIScale()); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_ = gfx::ToFlooredSize(size_f); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DisplayInfo::SetOverscanInsets(const gfx::Insets& insets_in_dip) { 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_ = insets_in_dip; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Insets DisplayInfo::GetOverscanInsetsInPixel() const { 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return overscan_insets_in_dip_.Scale(device_scale_factor_); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccigfx::Size DisplayInfo::GetNativeModeSize() const { 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < display_modes_.size(); ++i) { 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (display_modes_[i].native) 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return display_modes_[i].size; 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return gfx::Size(); 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DisplayInfo::ToString() const { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int rotation_degree = static_cast<int>(rotation_) * 90; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch "DisplayInfo[%lld] native bounds=%s, size=%s, scale=%f, " 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "overscan=%s, rotation=%d, ui-scale=%f, touchscreen=%s, " 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "touch-device-id=%d", 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<long long int>(id_), 34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bounds_in_native_.ToString().c_str(), 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_in_pixel_.ToString().c_str(), 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_scale_factor_, 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) overscan_insets_in_dip_.ToString().c_str(), 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rotation_degree, 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) configured_ui_scale_, 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) touch_support_ == gfx::Display::TOUCH_SUPPORT_AVAILABLE 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? "yes" 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : touch_support_ == gfx::Display::TOUCH_SUPPORT_UNAVAILABLE 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ? "no" 355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : "unknown", 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) touch_device_id_); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)std::string DisplayInfo::ToFullString() const { 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string display_modes_str; 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<DisplayMode>::const_iterator iter = display_modes_.begin(); 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (; iter != display_modes_.end(); ++iter) { 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!display_modes_str.empty()) 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) display_modes_str += ","; 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::StringAppendF(&display_modes_str, 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "(%dx%d@%f%c%s)", 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->size.width(), 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->size.height(), 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->refresh_rate, 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->interlaced ? 'I' : 'P', 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->native ? "(N)" : ""); 372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ToString() + ", display_modes==" + display_modes_str; 374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DisplayInfo::SetColorProfile(ui::ColorCalibrationProfile profile) { 377effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (IsColorProfileAvailable(profile)) 378effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch color_profile_ = profile; 379effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 380effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 381effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool DisplayInfo::IsColorProfileAvailable( 382effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui::ColorCalibrationProfile profile) const { 383effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return std::find(available_color_profiles_.begin(), 384effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch available_color_profiles_.end(), 385effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch profile) != available_color_profiles_.end(); 386effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 387effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace ash 389