123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ui/display/display.h"
- #include <algorithm>
- #include "base/command_line.h"
- #include "base/containers/contains.h"
- #include "base/logging.h"
- #include "base/notreached.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/strings/stringprintf.h"
- #include "build/build_config.h"
- #include "ui/display/display_switches.h"
- #include "ui/display/util/display_util.h"
- #include "ui/gfx/geometry/insets.h"
- #include "ui/gfx/geometry/rect_conversions.h"
- #include "ui/gfx/geometry/rect_f.h"
- #include "ui/gfx/geometry/transform.h"
- #include "ui/gfx/icc_profile.h"
- namespace display {
- namespace {
- // This variable tracks whether the forced device scale factor switch needs to
- // be read from the command line, i.e. if it is set to -1 then the command line
- // is checked.
- int g_has_forced_device_scale_factor = -1;
- // This variable caches the forced device scale factor value which is read off
- // the command line. If the cache is invalidated by setting this variable to
- // -1.0, we read the forced device scale factor again.
- float g_forced_device_scale_factor = -1.0;
- // An allowance error epsilon caused by fractional scale factor to produce
- // expected DP display size.
- constexpr float kDisplaySizeAllowanceEpsilon = 0.01f;
- bool HasForceDeviceScaleFactorImpl() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kForceDeviceScaleFactor);
- }
- float GetForcedDeviceScaleFactorImpl() {
- double scale_in_double = 1.0;
- if (HasForceDeviceScaleFactorImpl()) {
- std::string value =
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kForceDeviceScaleFactor);
- if (!base::StringToDouble(value, &scale_in_double)) {
- LOG(ERROR) << "Failed to parse the default device scale factor:" << value;
- scale_in_double = 1.0;
- }
- }
- return static_cast<float>(scale_in_double);
- }
- const char* ToRotationString(display::Display::Rotation rotation) {
- switch (rotation) {
- case display::Display::ROTATE_0:
- return "0";
- case display::Display::ROTATE_90:
- return "90";
- case display::Display::ROTATE_180:
- return "180";
- case display::Display::ROTATE_270:
- return "270";
- }
- NOTREACHED();
- return "unkonwn";
- }
- } // namespace
- // static
- float Display::GetForcedDeviceScaleFactor() {
- if (g_forced_device_scale_factor < 0)
- g_forced_device_scale_factor = GetForcedDeviceScaleFactorImpl();
- return g_forced_device_scale_factor;
- }
- // static
- bool Display::HasForceDeviceScaleFactor() {
- if (g_has_forced_device_scale_factor == -1)
- g_has_forced_device_scale_factor = HasForceDeviceScaleFactorImpl();
- return !!g_has_forced_device_scale_factor;
- }
- // static
- void Display::ResetForceDeviceScaleFactorForTesting() {
- g_has_forced_device_scale_factor = -1;
- g_forced_device_scale_factor = -1.0;
- }
- // static
- void Display::SetForceDeviceScaleFactor(double dsf) {
- // Reset any previously set values and unset the flag.
- g_has_forced_device_scale_factor = -1;
- g_forced_device_scale_factor = -1.0;
- base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
- switches::kForceDeviceScaleFactor, base::StringPrintf("%.2f", dsf));
- }
- // static
- gfx::ColorSpace Display::GetForcedRasterColorProfile() {
- DCHECK(HasForceRasterColorProfile());
- std::string value =
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kForceRasterColorProfile);
- return ForcedColorProfileStringToColorSpace(value);
- }
- // static
- bool Display::HasForceRasterColorProfile() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kForceRasterColorProfile);
- }
- // static
- bool Display::HasEnsureForcedColorProfile() {
- static bool has_ensure_forced_color_profile =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnsureForcedColorProfile);
- return has_ensure_forced_color_profile;
- }
- // static
- display::Display::Rotation Display::DegreesToRotation(int degrees) {
- if (degrees == 0)
- return display::Display::ROTATE_0;
- if (degrees == 90)
- return display::Display::ROTATE_90;
- if (degrees == 180)
- return display::Display::ROTATE_180;
- if (degrees == 270)
- return display::Display::ROTATE_270;
- NOTREACHED();
- return display::Display::ROTATE_0;
- }
- // static
- int Display::RotationToDegrees(display::Display::Rotation rotation) {
- switch (rotation) {
- case display::Display::ROTATE_0:
- return 0;
- case display::Display::ROTATE_90:
- return 90;
- case display::Display::ROTATE_180:
- return 180;
- case display::Display::ROTATE_270:
- return 270;
- }
- NOTREACHED();
- return 0;
- }
- // static
- bool Display::IsValidRotation(int degrees) {
- return degrees == 0 || degrees == 90 || degrees == 180 || degrees == 270;
- }
- Display::Display() : Display(kInvalidDisplayId) {}
- Display::Display(int64_t id) : Display(id, gfx::Rect()) {}
- Display::Display(int64_t id, const gfx::Rect& bounds)
- : id_(id),
- bounds_(bounds),
- work_area_(bounds),
- device_scale_factor_(GetForcedDeviceScaleFactor()) {
- // On Android we need to ensure the platform supports a color profile before
- // using it. Using a not supported profile can result in fatal errors in the
- // GPU process.
- auto color_space = gfx::ColorSpace::CreateSRGB();
- #if !BUILDFLAG(IS_ANDROID)
- if (HasForceDisplayColorProfile())
- color_space = GetForcedDisplayColorProfile();
- #endif
- color_spaces_ = gfx::DisplayColorSpaces(color_space);
- if (color_spaces_.SupportsHDR()) {
- color_depth_ = kHDR10BitsPerPixel;
- depth_per_component_ = kHDR10BitsPerComponent;
- } else {
- color_depth_ = kDefaultBitsPerPixel;
- depth_per_component_ = kDefaultBitsPerComponent;
- }
- #if defined(USE_AURA)
- if (!bounds.IsEmpty())
- SetScaleAndBounds(device_scale_factor_, bounds);
- #endif
- }
- Display::Display(const Display& other) = default;
- Display::~Display() {}
- // static
- Display Display::GetDefaultDisplay() {
- return Display(kDefaultDisplayId, gfx::Rect(0, 0, 1920, 1080));
- }
- int Display::RotationAsDegree() const {
- switch (rotation_) {
- case ROTATE_0:
- return 0;
- case ROTATE_90:
- return 90;
- case ROTATE_180:
- return 180;
- case ROTATE_270:
- return 270;
- }
- NOTREACHED();
- return 0;
- }
- void Display::set_color_spaces(const gfx::DisplayColorSpaces& color_spaces) {
- color_spaces_ = color_spaces;
- if (color_spaces.SupportsHDR()) {
- color_depth_ = kHDR10BitsPerPixel;
- depth_per_component_ = kHDR10BitsPerComponent;
- } else {
- color_depth_ = kDefaultBitsPerPixel;
- depth_per_component_ = kDefaultBitsPerComponent;
- }
- }
- void Display::SetRotationAsDegree(int rotation) {
- switch (rotation) {
- case 0:
- rotation_ = ROTATE_0;
- break;
- case 90:
- rotation_ = ROTATE_90;
- break;
- case 180:
- rotation_ = ROTATE_180;
- break;
- case 270:
- rotation_ = ROTATE_270;
- break;
- default:
- // We should not reach that but we will just ignore the call if we do.
- NOTREACHED();
- }
- }
- int Display::PanelRotationAsDegree() const {
- return RotationToDegrees(panel_rotation());
- }
- gfx::Insets Display::GetWorkAreaInsets() const {
- return gfx::Insets::TLBR(work_area_.y() - bounds_.y(),
- work_area_.x() - bounds_.x(),
- bounds_.bottom() - work_area_.bottom(),
- bounds_.right() - work_area_.right());
- }
- void Display::SetScaleAndBounds(float device_scale_factor,
- const gfx::Rect& bounds_in_pixel) {
- gfx::Insets insets = bounds_.InsetsFrom(work_area_);
- SetScale(device_scale_factor);
- gfx::RectF f(bounds_in_pixel);
- f.Scale(1.f / device_scale_factor_);
- bounds_ = gfx::ToEnclosedRectIgnoringError(f, kDisplaySizeAllowanceEpsilon);
- size_in_pixels_ = bounds_in_pixel.size();
- UpdateWorkAreaFromInsets(insets);
- }
- void Display::SetScale(float device_scale_factor) {
- if (!HasForceDeviceScaleFactor()) {
- #if BUILDFLAG(IS_APPLE)
- // Unless an explicit scale factor was provided for testing, ensure the
- // scale is integral.
- device_scale_factor = static_cast<int>(device_scale_factor);
- #endif
- device_scale_factor_ = device_scale_factor;
- }
- device_scale_factor_ = std::max(0.5f, device_scale_factor_);
- }
- void Display::SetSize(const gfx::Size& size_in_pixel) {
- gfx::Point origin = bounds_.origin();
- #if defined(USE_AURA)
- origin = gfx::ScaleToFlooredPoint(origin, device_scale_factor_);
- #endif
- SetScaleAndBounds(device_scale_factor_, gfx::Rect(origin, size_in_pixel));
- }
- void Display::UpdateWorkAreaFromInsets(const gfx::Insets& insets) {
- work_area_ = bounds_;
- work_area_.Inset(insets);
- }
- gfx::Size Display::GetSizeInPixel() const {
- if (!size_in_pixels_.IsEmpty())
- return size_in_pixels_;
- return gfx::ScaleToFlooredSize(size(), device_scale_factor_);
- }
- std::string Display::ToString() const {
- return base::StringPrintf(
- "Display[%lld] bounds=[%s], workarea=[%s], scale=%g, rotation=%s, "
- "panel_rotation=%s %s.",
- static_cast<long long int>(id_), bounds_.ToString().c_str(),
- work_area_.ToString().c_str(), device_scale_factor_,
- ToRotationString(rotation_), ToRotationString(panel_rotation()),
- IsInternal() ? "internal" : "external");
- }
- bool Display::IsInternal() const {
- return is_valid() && display::IsInternalDisplayId(id_);
- }
- // static
- int64_t Display::InternalDisplayId() {
- auto& ids = GetInternalDisplayIds();
- DCHECK_EQ(1u, ids.size());
- return ids.size() ? *ids.begin() : kInvalidDisplayId;
- }
- bool Display::operator==(const Display& rhs) const {
- return id_ == rhs.id_ && bounds_ == rhs.bounds_ &&
- size_in_pixels_ == rhs.size_in_pixels_ &&
- work_area_ == rhs.work_area_ &&
- device_scale_factor_ == rhs.device_scale_factor_ &&
- rotation_ == rhs.rotation_ && touch_support_ == rhs.touch_support_ &&
- accelerometer_support_ == rhs.accelerometer_support_ &&
- maximum_cursor_size_ == rhs.maximum_cursor_size_ &&
- color_spaces_ == rhs.color_spaces_ &&
- color_depth_ == rhs.color_depth_ &&
- depth_per_component_ == rhs.depth_per_component_ &&
- is_monochrome_ == rhs.is_monochrome_ &&
- display_frequency_ == rhs.display_frequency_ && label_ == rhs.label_;
- }
- } // namespace display
|