display_info.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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
26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool allow_upgrade_to_high_dpi = false;
27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DisplayMode::DisplayMode()
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : refresh_rate(0.0f), interlaced(false), native(false) {}
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DisplayMode::DisplayMode(const gfx::Size& size,
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         float refresh_rate,
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         bool interlaced,
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         bool native)
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : size(size),
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      refresh_rate(refresh_rate),
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      interlaced(interlaced),
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      native(native) {}
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// satic
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo DisplayInfo::CreateFromSpec(const std::string& spec) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CreateFromSpecWithID(spec, gfx::Display::kInvalidDisplayID);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid DisplayInfo::SetAllowUpgradeToHighDPI(bool enable) {
49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  allow_upgrade_to_high_dpi = enable;
50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
51a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
52a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// static
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo DisplayInfo::CreateFromSpecWithID(const std::string& spec,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              int64 id) {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Default bounds for a display.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kDefaultHostWindowX = 200;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kDefaultHostWindowY = 200;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kDefaultHostWindowWidth = 1366;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kDefaultHostWindowHeight = 768;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Use larger than max int to catch overflow early.
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static int64 synthesized_display_id = 2200000000LL;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect bounds_in_native(aura::WindowTreeHost::GetNativeScreenSize());
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect bounds_in_native(kDefaultHostWindowX, kDefaultHostWindowY,
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                             kDefaultHostWindowWidth, kDefaultHostWindowHeight);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string main_spec = spec;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float ui_scale = 1.0f;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> parts;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (Tokenize(main_spec, "@", &parts) == 2) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    double scale_in_double = 0;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (base::StringToDouble(parts[1], &scale_in_double))
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui_scale = scale_in_double;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    main_spec = parts[0];
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t count = Tokenize(main_spec, "/", &parts);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Display::Rotation rotation(gfx::Display::ROTATE_0);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_overscan = false;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (count) {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    main_spec = parts[0];
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (count >= 2) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string options = parts[1];
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (size_t i = 0; i < options.size(); ++i) {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        char c = options[i];
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        switch (c) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case 'o':
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            has_overscan = true;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            break;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case 'r':  // rotate 90 degrees to 'right'.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            rotation = gfx::Display::ROTATE_90;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            break;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case 'u':  // 180 degrees, 'u'pside-down.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            rotation = gfx::Display::ROTATE_180;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            break;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          case 'l':  // rotate 90 degrees to 'left'.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            rotation = gfx::Display::ROTATE_270;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            break;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int x = 0, y = 0, width, height;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float device_scale_factor = 1.0f;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (sscanf(main_spec.c_str(), "%dx%d*%f",
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             &width, &height, &device_scale_factor) >= 2 ||
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sscanf(main_spec.c_str(), "%d+%d-%dx%d*%f", &x, &y, &width, &height,
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             &device_scale_factor) >= 4) {
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bounds_in_native.SetRect(x, y, width, height);
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (gfx::IsHighDPIEnabled()) {
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      device_scale_factor = gfx::GetDPIScale();
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<DisplayMode> display_modes;
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (Tokenize(main_spec, "#", &parts) == 2) {
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    size_t native_mode = 0;
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int largest_area = -1;
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    float highest_refresh_rate = -1.0f;
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    main_spec = parts[0];
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string resolution_list = parts[1];
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    count = Tokenize(resolution_list, "|", &parts);
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    for (size_t i = 0; i < count; ++i) {
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      std::string resolution = parts[i];
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      int width, height;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      float refresh_rate = 0.0f;
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (sscanf(resolution.c_str(),
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 "%dx%d%%%f",
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 &width,
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 &height,
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 &refresh_rate) >= 2) {
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (width * height >= largest_area &&
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            refresh_rate > highest_refresh_rate) {
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          // Use mode with largest area and highest refresh rate as native.
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          largest_area = width * height;
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          highest_refresh_rate = refresh_rate;
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          native_mode = i;
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        display_modes.push_back(
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            DisplayMode(gfx::Size(width, height), refresh_rate, false, false));
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    display_modes[native_mode].native = true;
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (id == gfx::Display::kInvalidDisplayID)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = synthesized_display_id++;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DisplayInfo display_info(
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id, base::StringPrintf("Display-%d", static_cast<int>(id)), has_overscan);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  display_info.set_device_scale_factor(device_scale_factor);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  display_info.set_rotation(rotation);
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  display_info.set_configured_ui_scale(ui_scale);
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  display_info.SetBounds(bounds_in_native);
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  display_info.set_display_modes(display_modes);
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // To test the overscan, it creates the default 5% overscan.
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (has_overscan) {
16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int width = bounds_in_native.width() / device_scale_factor / 40;
16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int height = bounds_in_native.height() / device_scale_factor / 40;
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    display_info.SetOverscanInsets(gfx::Insets(height, width, height, width));
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    display_info.UpdateDisplaySize();
170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "DisplayInfoFromSpec info=" << display_info.ToString()
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << ", spec=" << spec;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return display_info;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo::DisplayInfo()
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : id_(gfx::Display::kInvalidDisplayID),
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      has_overscan_(false),
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      rotation_(gfx::Display::ROTATE_0),
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN),
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      touch_device_id_(0),
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_scale_factor_(1.0f),
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overscan_insets_in_dip_(0, 0, 0, 0),
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      configured_ui_scale_(1.0f),
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      native_(false),
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      is_aspect_preserving_scaling_(false),
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      color_profile_(ui::COLOR_PROFILE_STANDARD) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo::DisplayInfo(int64 id,
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const std::string& name,
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool has_overscan)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : id_(id),
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      name_(name),
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      has_overscan_(has_overscan),
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      rotation_(gfx::Display::ROTATE_0),
1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN),
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      touch_device_id_(0),
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_scale_factor_(1.0f),
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overscan_insets_in_dip_(0, 0, 0, 0),
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      configured_ui_scale_(1.0f),
203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      native_(false),
204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      color_profile_(ui::COLOR_PROFILE_STANDARD) {
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayInfo::~DisplayInfo() {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayInfo::Copy(const DisplayInfo& native_info) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(id_ == native_info.id_);
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  name_ = native_info.name_;
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  has_overscan_ = native_info.has_overscan_;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!native_info.bounds_in_native_.IsEmpty());
21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bounds_in_native_ = native_info.bounds_in_native_;
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_in_pixel_ = native_info.size_in_pixel_;
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_scale_factor_ = native_info.device_scale_factor_;
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  display_modes_ = native_info.display_modes_;
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  touch_support_ = native_info.touch_support_;
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  touch_device_id_ = native_info.touch_device_id_;
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Copy overscan_insets_in_dip_ if it's not empty. This is for test
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // cases which use "/o" annotation which sets the overscan inset
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // to native, and that overscan has to be propagated. This does not
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // happen on the real environment.
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!native_info.overscan_insets_in_dip_.empty())
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    overscan_insets_in_dip_ = native_info.overscan_insets_in_dip_;
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
230effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Rotation_ and ui_scale_ color_profile_ are given by preference,
231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // or unit tests. Don't copy if this native_info came from
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // DisplayChangeObserver.
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!native_info.native()) {
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    rotation_ = native_info.rotation_;
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    configured_ui_scale_ = native_info.configured_ui_scale_;
236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    color_profile_ = native_info.color_profile();
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
239effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  available_color_profiles_ = native_info.available_color_profiles();
240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't copy insets as it may be given by preference.  |rotation_|
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is treated as a native so that it can be specified in
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |CreateFromSpec|.
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void DisplayInfo::SetBounds(const gfx::Rect& new_bounds_in_native) {
24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bounds_in_native_ = new_bounds_in_native;
24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  size_in_pixel_ = new_bounds_in_native.size();
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplaySize();
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfloat DisplayInfo::GetEffectiveDeviceScaleFactor() const {
253a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (allow_upgrade_to_high_dpi && configured_ui_scale_ < 1.0f &&
254a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      device_scale_factor_ == 1.0f) {
255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return 2.0f;
256a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else if (device_scale_factor_ == 2.0f && configured_ui_scale_ == 2.0f) {
257a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return 1.0f;
258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return device_scale_factor_;
260a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
261a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)float DisplayInfo::GetEffectiveUIScale() const {
263a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (allow_upgrade_to_high_dpi && configured_ui_scale_ < 1.0f &&
264a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      device_scale_factor_ == 1.0f) {
265a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return configured_ui_scale_ * 2.0f;
266a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else if (device_scale_factor_ == 2.0f && configured_ui_scale_ == 2.0f) {
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return 1.0f;
268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return configured_ui_scale_;
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayInfo::UpdateDisplaySize() {
27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  size_in_pixel_ = bounds_in_native_.size();
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!overscan_insets_in_dip_.empty()) {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Insets insets_in_pixel =
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        overscan_insets_in_dip_.Scale(device_scale_factor_);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_in_pixel_.Enlarge(-insets_in_pixel.width(), -insets_in_pixel.height());
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    overscan_insets_in_dip_.Set(0, 0, 0, 0);
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rotation_ == gfx::Display::ROTATE_90 ||
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      rotation_ == gfx::Display::ROTATE_270)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_in_pixel_.SetSize(size_in_pixel_.height(), size_in_pixel_.width());
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::SizeF size_f(size_in_pixel_);
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_f.Scale(GetEffectiveUIScale());
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_in_pixel_ = gfx::ToFlooredSize(size_f);
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DisplayInfo::SetOverscanInsets(const gfx::Insets& insets_in_dip) {
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  overscan_insets_in_dip_ = insets_in_dip;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Insets DisplayInfo::GetOverscanInsetsInPixel() const {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return overscan_insets_in_dip_.Scale(device_scale_factor_);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DisplayInfo::ToString() const {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rotation_degree = static_cast<int>(rotation_) * 90;
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::StringPrintf(
3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      "DisplayInfo[%lld] native bounds=%s, size=%s, scale=%f, "
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "overscan=%s, rotation=%d, ui-scale=%f, touchscreen=%s, "
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "touch-device-id=%d",
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<long long int>(id_),
30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      bounds_in_native_.ToString().c_str(),
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_in_pixel_.ToString().c_str(),
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_scale_factor_,
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overscan_insets_in_dip_.ToString().c_str(),
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      rotation_degree,
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      configured_ui_scale_,
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      touch_support_ == gfx::Display::TOUCH_SUPPORT_AVAILABLE
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ? "yes"
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          : touch_support_ == gfx::Display::TOUCH_SUPPORT_UNAVAILABLE
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                ? "no"
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                : "unknown",
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      touch_device_id_);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)std::string DisplayInfo::ToFullString() const {
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string display_modes_str;
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<DisplayMode>::const_iterator iter = display_modes_.begin();
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (; iter != display_modes_.end(); ++iter) {
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!display_modes_str.empty())
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      display_modes_str += ",";
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::StringAppendF(&display_modes_str,
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        "(%dx%d@%f%c%s)",
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        iter->size.width(),
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        iter->size.height(),
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        iter->refresh_rate,
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        iter->interlaced ? 'I' : 'P',
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        iter->native ? "(N)" : "");
332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ToString() + ", display_modes==" + display_modes_str;
334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
336effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid DisplayInfo::SetColorProfile(ui::ColorCalibrationProfile profile) {
337effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (IsColorProfileAvailable(profile))
338effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    color_profile_ = profile;
339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
340effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
341effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool DisplayInfo::IsColorProfileAvailable(
342effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ui::ColorCalibrationProfile profile) const {
343effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return std::find(available_color_profiles_.begin(),
344effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   available_color_profiles_.end(),
345effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   profile) != available_color_profiles_.end();
346effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
347effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ash
349