diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/ui/display | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/ui/display')
44 files changed, 776 insertions, 73 deletions
diff --git a/chromium/ui/display/BUILD.gn b/chromium/ui/display/BUILD.gn index 2ce0eb72a65..fa824fb6aae 100644 --- a/chromium/ui/display/BUILD.gn +++ b/chromium/ui/display/BUILD.gn @@ -36,6 +36,8 @@ jumbo_component("display") { "display_switches.h", "display_transform.cc", "display_transform.h", + "scoped_display_for_new_windows.cc", + "scoped_display_for_new_windows.h", "screen.cc", "screen.h", "screen_base.cc", diff --git a/chromium/ui/display/display.cc b/chromium/ui/display/display.cc index 0dc06d9d5bc..ced58c7672a 100644 --- a/chromium/ui/display/display.cc +++ b/chromium/ui/display/display.cc @@ -8,6 +8,7 @@ #include "base/command_line.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" diff --git a/chromium/ui/display/display_features.cc b/chromium/ui/display/display_features.cc index ad2894dc036..bbe1b07aa4a 100644 --- a/chromium/ui/display/display_features.cc +++ b/chromium/ui/display/display_features.cc @@ -7,11 +7,17 @@ namespace display { namespace features { +#if defined(OS_CHROMEOS) +// Enables using HDR transfer function if the monitor says it supports it. +const base::Feature kUseHDRTransferFunction{"UseHDRTransferFunction", + base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + // This features allows listing all display modes of external displays in the // display settings and setting any one of them exactly as requested, which can // be very useful for debugging and development purposes. const base::Feature kListAllDisplayModes = {"ListAllDisplayModes", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; bool IsListAllDisplayModesEnabled() { return base::FeatureList::IsEnabled(kListAllDisplayModes); diff --git a/chromium/ui/display/display_features.h b/chromium/ui/display/display_features.h index 43e5f4acccc..878fa3bb0a6 100644 --- a/chromium/ui/display/display_features.h +++ b/chromium/ui/display/display_features.h @@ -12,7 +12,7 @@ namespace display { namespace features { #if defined(OS_CHROMEOS) -DISPLAY_EXPORT extern const base::Feature kUseMonitorColorSpace; +DISPLAY_EXPORT extern const base::Feature kUseHDRTransferFunction; #endif DISPLAY_EXPORT extern const base::Feature kListAllDisplayModes; diff --git a/chromium/ui/display/display_observer.h b/chromium/ui/display/display_observer.h index c15b93ad420..1d3bc80fde9 100644 --- a/chromium/ui/display/display_observer.h +++ b/chromium/ui/display/display_observer.h @@ -25,6 +25,8 @@ class DISPLAY_EXPORT DisplayObserver : public base::CheckedObserver { DISPLAY_METRIC_PRIMARY = 1 << 4, DISPLAY_METRIC_MIRROR_STATE = 1 << 5, DISPLAY_METRIC_COLOR_SPACE = 1 << 6, + DISPLAY_METRIC_REFRESH_RATE = 1 << 7, + DISPLAY_METRIC_INTERLACED = 1 << 8, }; // This may be called before other methods to signal changes are about to diff --git a/chromium/ui/display/display_switches.cc b/chromium/ui/display/display_switches.cc index 806109ce25d..f2c0f562448 100644 --- a/chromium/ui/display/display_switches.cc +++ b/chromium/ui/display/display_switches.cc @@ -56,9 +56,6 @@ const char kUseFirstDisplayAsInternal[] = "use-first-display-as-internal"; #if defined(OS_CHROMEOS) // Enables unified desktop mode. const char kEnableUnifiedDesktop[] = "ash-enable-unified-desktop"; - -// Enables using HDR transfer function if the monitor says it supports it. -const char kEnableUseHDRTransferFunction[] = "enable-use-hdr-transfer-function"; #endif } // namespace switches diff --git a/chromium/ui/display/display_switches.h b/chromium/ui/display/display_switches.h index 78b2af3cfe6..ff76d749d0f 100644 --- a/chromium/ui/display/display_switches.h +++ b/chromium/ui/display/display_switches.h @@ -26,7 +26,6 @@ DISPLAY_EXPORT extern const char kUseFirstDisplayAsInternal[]; #if defined(OS_CHROMEOS) DISPLAY_EXPORT extern const char kEnableUnifiedDesktop[]; -DISPLAY_EXPORT extern const char kEnableUseHDRTransferFunction[]; #endif } // namespace switches diff --git a/chromium/ui/display/fake/fake_display_snapshot.cc b/chromium/ui/display/fake/fake_display_snapshot.cc index af8fad503ca..98c8b875022 100644 --- a/chromium/ui/display/fake/fake_display_snapshot.cc +++ b/chromium/ui/display/fake/fake_display_snapshot.cc @@ -10,6 +10,7 @@ #include <vector> #include "base/logging.h" +#include "base/notreached.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" @@ -164,7 +165,8 @@ std::unique_ptr<FakeDisplaySnapshot> Builder::Build() { id_, origin_, physical_size, type_, is_aspect_preserving_scaling_, has_overscan_, privacy_screen_state_, has_color_correction_matrix_, color_correction_in_linear_space_, name_, std::move(modes_), - current_mode_, native_mode_, product_code_, maximum_cursor_size_); + current_mode_, native_mode_, product_code_, maximum_cursor_size_, + color_space_, bits_per_channel_); } Builder& Builder::SetId(int64_t id) { @@ -265,6 +267,16 @@ Builder& Builder::SetPrivacyScreen(PrivacyScreenState state) { return *this; } +Builder& Builder::SetColorSpace(const gfx::ColorSpace& color_space) { + color_space_ = color_space; + return *this; +} + +Builder& Builder::SetBitsPerChannel(uint32_t bits_per_channel) { + bits_per_channel_ = bits_per_channel; + return *this; +} + const DisplayMode* Builder::AddOrFindDisplayMode(const gfx::Size& size) { for (auto& mode : modes_) { if (mode->size() == size) @@ -306,7 +318,9 @@ FakeDisplaySnapshot::FakeDisplaySnapshot( const DisplayMode* current_mode, const DisplayMode* native_mode, int64_t product_code, - const gfx::Size& maximum_cursor_size) + const gfx::Size& maximum_cursor_size, + const gfx::ColorSpace& color_space, + uint32_t bits_per_channel) : DisplaySnapshot(display_id, origin, physical_size, @@ -316,8 +330,8 @@ FakeDisplaySnapshot::FakeDisplaySnapshot( privacy_screen_state, has_color_correction_matrix, color_correction_in_linear_space, - gfx::ColorSpace(), - 8u /* bits_per_channel */, + color_space, + bits_per_channel, display_name, base::FilePath(), std::move(modes), diff --git a/chromium/ui/display/fake/fake_display_snapshot.h b/chromium/ui/display/fake/fake_display_snapshot.h index 833ac744d08..d521fb34078 100644 --- a/chromium/ui/display/fake/fake_display_snapshot.h +++ b/chromium/ui/display/fake/fake_display_snapshot.h @@ -70,6 +70,8 @@ class FAKE_DISPLAY_EXPORT FakeDisplaySnapshot : public DisplaySnapshot { // Sets physical_size for high DPI display. Builder& SetHighDPI(); Builder& SetPrivacyScreen(PrivacyScreenState state); + Builder& SetColorSpace(const gfx::ColorSpace& color_space); + Builder& SetBitsPerChannel(uint32_t bits_per_channel); private: // Returns a display mode with |size|. If there is no existing mode, insert @@ -94,6 +96,8 @@ class FAKE_DISPLAY_EXPORT FakeDisplaySnapshot : public DisplaySnapshot { DisplayModeList modes_; const DisplayMode* current_mode_ = nullptr; const DisplayMode* native_mode_ = nullptr; + gfx::ColorSpace color_space_; + uint32_t bits_per_channel_ = 8u; DISALLOW_COPY_AND_ASSIGN(Builder); }; @@ -112,7 +116,9 @@ class FAKE_DISPLAY_EXPORT FakeDisplaySnapshot : public DisplaySnapshot { const DisplayMode* current_mode, const DisplayMode* native_mode, int64_t product_code, - const gfx::Size& maximum_cursor_size); + const gfx::Size& maximum_cursor_size, + const gfx::ColorSpace& color_space, + uint32_t bits_per_channel); ~FakeDisplaySnapshot() override; // Creates a display snapshot from the provided |spec| string. Returns null if diff --git a/chromium/ui/display/manager/configure_displays_task.cc b/chromium/ui/display/manager/configure_displays_task.cc index 1b37056d62c..9bb4b1a4967 100644 --- a/chromium/ui/display/manager/configure_displays_task.cc +++ b/chromium/ui/display/manager/configure_displays_task.cc @@ -7,6 +7,7 @@ #include "base/auto_reset.h" #include "base/bind.h" #include "base/containers/queue.h" +#include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/stl_util.h" #include "ui/display/manager/display_util.h" diff --git a/chromium/ui/display/manager/display_change_observer.cc b/chromium/ui/display/manager/display_change_observer.cc index 93961fa5a03..89a9139d3fe 100644 --- a/chromium/ui/display/manager/display_change_observer.cc +++ b/chromium/ui/display/manager/display_change_observer.cc @@ -77,6 +77,51 @@ ManagedDisplayInfo::ManagedDisplayModeList GetModeListWithAllRefreshRates( return display_mode_list; } +#if defined(OS_CHROMEOS) +// Constructs the raster DisplayColorSpaces out of |snapshot_color_space|, +// including the HDR ones if present and |allow_high_bit_depth| is set. +gfx::DisplayColorSpaces FillDisplayColorSpaces( + const gfx::ColorSpace& snapshot_color_space, + bool allow_high_bit_depth) { + // ChromeOS VMs (e.g. amd64-generic or betty) have INVALID Primaries; just + // pass the color space along. + if (!snapshot_color_space.IsValid()) { + return gfx::DisplayColorSpaces(snapshot_color_space, + DisplaySnapshot::PrimaryFormat()); + } + + // TODO(b/158126931): |snapshot_color_space| Primaries/Transfer function + // cannot be used directly, as users prefer saturated colors to accurate ones. + // Instead, clamp at DCI-P3 and clamp at that level or with a small overshoot. + gfx::DisplayColorSpaces display_color_spaces( + gfx::ColorSpace::CreateSRGB(), DisplaySnapshot::PrimaryFormat()); + + if (allow_high_bit_depth) { + constexpr float kSDRJoint = 0.5; + constexpr float kHDRLevel = 3.0; + const auto primary_id = snapshot_color_space.GetPrimaryID(); + gfx::ColorSpace hdr_color_space; + if (primary_id == gfx::ColorSpace::PrimaryID::CUSTOM) { + skcms_Matrix3x3 primary_matrix{}; + snapshot_color_space.GetPrimaryMatrix(&primary_matrix); + hdr_color_space = gfx::ColorSpace::CreatePiecewiseHDR( + primary_id, kSDRJoint, kHDRLevel, &primary_matrix); + } else { + hdr_color_space = + gfx::ColorSpace::CreatePiecewiseHDR(primary_id, kSDRJoint, kHDRLevel); + } + + display_color_spaces.SetOutputColorSpaceAndBufferFormat( + gfx::ContentColorUsage::kHDR, false /* needs_alpha */, hdr_color_space, + gfx::BufferFormat::RGBA_1010102); + display_color_spaces.SetOutputColorSpaceAndBufferFormat( + gfx::ContentColorUsage::kHDR, true /* needs_alpha */, hdr_color_space, + gfx::BufferFormat::RGBA_1010102); + } + return display_color_spaces; +} +#endif + } // namespace // static @@ -337,21 +382,22 @@ ManagedDisplayInfo DisplayChangeObserver::CreateManagedDisplayInfo( if (dpi) new_info.set_device_dpi(dpi); +#if !defined(OS_CHROMEOS) // TODO(crbug.com/1012846): This should configure the HDR color spaces. gfx::DisplayColorSpaces display_color_spaces( snapshot->color_space(), DisplaySnapshot::PrimaryFormat()); new_info.set_display_color_spaces(display_color_spaces); new_info.set_bits_per_channel(snapshot->bits_per_channel()); - - // TODO(crbug.com/1012846): Remove this flag and provision when HDR is fully - // supported on ChromeOS. -#if defined(OS_CHROMEOS) +#else + // TODO(crbug.com/1012846): Remove kEnableUseHDRTransferFunction usage when + // HDR is fully supported on ChromeOS. + const bool allow_high_bit_depth = + base::FeatureList::IsEnabled(features::kUseHDRTransferFunction); + new_info.set_display_color_spaces( + FillDisplayColorSpaces(snapshot->color_space(), allow_high_bit_depth)); constexpr int32_t kNormalBitDepth = 8; - if (new_info.bits_per_channel() > kNormalBitDepth && - !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableUseHDRTransferFunction)) { - new_info.set_bits_per_channel(kNormalBitDepth); - } + new_info.set_bits_per_channel( + allow_high_bit_depth ? snapshot->bits_per_channel() : kNormalBitDepth); #endif new_info.set_refresh_rate(mode_info->refresh_rate()); diff --git a/chromium/ui/display/manager/display_change_observer.h b/chromium/ui/display/manager/display_change_observer.h index 0e896e24e5e..5c17ce60977 100644 --- a/chromium/ui/display/manager/display_change_observer.h +++ b/chromium/ui/display/manager/display_change_observer.h @@ -60,6 +60,8 @@ class DISPLAY_MANAGER_EXPORT DisplayChangeObserver DISPLAY_EXPORT static float FindDeviceScaleFactor(float dpi); private: + friend class DisplayChangeObserverTest; + void UpdateInternalDisplay( const DisplayConfigurator::DisplayStateList& display_states); diff --git a/chromium/ui/display/manager/display_change_observer_unittest.cc b/chromium/ui/display/manager/display_change_observer_unittest.cc index bb900209bac..91d90d99f55 100644 --- a/chromium/ui/display/manager/display_change_observer_unittest.cc +++ b/chromium/ui/display/manager/display_change_observer_unittest.cc @@ -14,8 +14,11 @@ #include "ui/display/display_switches.h" #include "ui/display/fake/fake_display_snapshot.h" #include "ui/display/manager/display_configurator.h" +#include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" +#include "ui/display/screen.h" #include "ui/display/types/display_mode.h" +#include "ui/events/devices/device_data_manager.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -60,6 +63,13 @@ class DisplayChangeObserverTest : public testing::Test, Test::SetUp(); } + // Pass through method to be called by individual test cases. + ManagedDisplayInfo CreateManagedDisplayInfo(DisplayChangeObserver* observer, + const DisplaySnapshot* snapshot, + const DisplayMode* mode_info) { + return observer->CreateManagedDisplayInfo(snapshot, mode_info); + } + private: base::test::ScopedFeatureList scoped_feature_list_; @@ -175,7 +185,8 @@ TEST_P(DisplayChangeObserverTest, GetEmptyExternalManagedDisplayModeList) { FakeDisplaySnapshot display_snapshot( 123, gfx::Point(), gfx::Size(), DISPLAY_CONNECTION_TYPE_UNKNOWN, false, false, PrivacyScreenState::kNotSupported, false, false, std::string(), {}, - nullptr, nullptr, 0, gfx::Size()); + nullptr, nullptr, 0, gfx::Size(), gfx::ColorSpace(), + /*bits_per_channel=*/8u); ManagedDisplayInfo::ManagedDisplayModeList display_modes = DisplayChangeObserver::GetExternalManagedDisplayModeList( @@ -294,6 +305,127 @@ TEST_P(DisplayChangeObserverTest, } } +TEST_P(DisplayChangeObserverTest, InvalidDisplayColorSpaces) { + const std::unique_ptr<DisplaySnapshot> display_snapshot = + FakeDisplaySnapshot::Builder() + .SetId(123) + .SetName("AmazingFakeDisplay") + .SetNativeMode(MakeDisplayMode(1920, 1080, true, 60)) + .SetColorSpace(gfx::ColorSpace()) + .Build(); + + ui::DeviceDataManager::CreateInstance(); + DisplayManager manager(nullptr); + const auto display_mode = MakeDisplayMode(1920, 1080, true, 60); + DisplayChangeObserver observer(&manager); + const ManagedDisplayInfo display_info = CreateManagedDisplayInfo( + &observer, display_snapshot.get(), display_mode.get()); + + EXPECT_EQ(display_info.bits_per_channel(), 8u); + const auto display_color_spaces = display_info.display_color_spaces(); + EXPECT_FALSE(display_color_spaces.SupportsHDR()); + + EXPECT_EQ( + DisplaySnapshot::PrimaryFormat(), + display_color_spaces.GetOutputBufferFormat(gfx::ContentColorUsage::kSRGB, + /*needs_alpha=*/true)); + + const auto color_space = display_color_spaces.GetRasterColorSpace(); + // DisplayColorSpaces will fix an invalid ColorSpace to return sRGB. + EXPECT_TRUE(color_space.IsValid()); + EXPECT_EQ(color_space, gfx::ColorSpace::CreateSRGB()); +} + +TEST_P(DisplayChangeObserverTest, SDRDisplayColorSpaces) { + const std::unique_ptr<DisplaySnapshot> display_snapshot = + FakeDisplaySnapshot::Builder() + .SetId(123) + .SetName("AmazingFakeDisplay") + .SetNativeMode(MakeDisplayMode(1920, 1080, true, 60)) + .SetColorSpace(gfx::ColorSpace::CreateSRGB()) + .Build(); + + ui::DeviceDataManager::CreateInstance(); + DisplayManager manager(nullptr); + const auto display_mode = MakeDisplayMode(1920, 1080, true, 60); + DisplayChangeObserver observer(&manager); + const ManagedDisplayInfo display_info = CreateManagedDisplayInfo( + &observer, display_snapshot.get(), display_mode.get()); + + EXPECT_EQ(display_info.bits_per_channel(), 8u); + + const auto display_color_spaces = display_info.display_color_spaces(); + EXPECT_FALSE(display_color_spaces.SupportsHDR()); + + EXPECT_EQ( + DisplaySnapshot::PrimaryFormat(), + display_color_spaces.GetOutputBufferFormat(gfx::ContentColorUsage::kSRGB, + /*needs_alpha=*/true)); + + const auto color_space = display_color_spaces.GetRasterColorSpace(); + EXPECT_TRUE(color_space.IsValid()); + EXPECT_EQ(color_space.GetPrimaryID(), gfx::ColorSpace::PrimaryID::BT709); + EXPECT_EQ(color_space.GetTransferID(), + gfx::ColorSpace::TransferID::IEC61966_2_1); +} + +#if defined(OS_CHROMEOS) +TEST_P(DisplayChangeObserverTest, HDRDisplayColorSpaces) { + // TODO(crbug.com/1012846): Remove this flag and provision when HDR is fully + // supported on ChromeOS. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kUseHDRTransferFunction); + + const std::unique_ptr<DisplaySnapshot> display_snapshot = + FakeDisplaySnapshot::Builder() + .SetId(123) + .SetName("AmazingFakeDisplay") + .SetNativeMode(MakeDisplayMode(1920, 1080, true, 60)) + .SetColorSpace(gfx::ColorSpace::CreateHDR10(100.0f)) + .SetBitsPerChannel(10u) + .Build(); + + ui::DeviceDataManager::CreateInstance(); + DisplayManager manager(nullptr); + const auto display_mode = MakeDisplayMode(1920, 1080, true, 60); + DisplayChangeObserver observer(&manager); + const ManagedDisplayInfo display_info = CreateManagedDisplayInfo( + &observer, display_snapshot.get(), display_mode.get()); + + EXPECT_EQ(display_info.bits_per_channel(), 10u); + + const auto display_color_spaces = display_info.display_color_spaces(); + EXPECT_TRUE(display_color_spaces.SupportsHDR()); + + // |display_color_spaces| still supports SDR rendering. + EXPECT_EQ( + DisplaySnapshot::PrimaryFormat(), + display_color_spaces.GetOutputBufferFormat(gfx::ContentColorUsage::kSRGB, + /*needs_alpha=*/true)); + + const auto sdr_color_space = + display_color_spaces.GetOutputColorSpace(gfx::ContentColorUsage::kSRGB, + /*needs_alpha=*/true); + EXPECT_TRUE(sdr_color_space.IsValid()); + EXPECT_EQ(sdr_color_space.GetPrimaryID(), gfx::ColorSpace::PrimaryID::BT709); + EXPECT_EQ(sdr_color_space.GetTransferID(), + gfx::ColorSpace::TransferID::IEC61966_2_1); + + EXPECT_EQ( + display_color_spaces.GetOutputBufferFormat(gfx::ContentColorUsage::kHDR, + /*needs_alpha=*/true), + gfx::BufferFormat::RGBA_1010102); + + const auto hdr_color_space = + display_color_spaces.GetOutputColorSpace(gfx::ContentColorUsage::kHDR, + /*needs_alpha=*/true); + EXPECT_TRUE(hdr_color_space.IsValid()); + EXPECT_EQ(hdr_color_space.GetPrimaryID(), gfx::ColorSpace::PrimaryID::BT2020); + EXPECT_EQ(hdr_color_space.GetTransferID(), + gfx::ColorSpace::TransferID::PIECEWISE_HDR); +} +#endif + INSTANTIATE_TEST_SUITE_P(All, DisplayChangeObserverTest, ::testing::Values(false, true)); diff --git a/chromium/ui/display/manager/display_configurator.cc b/chromium/ui/display/manager/display_configurator.cc index 0f078a96d7a..30774956842 100644 --- a/chromium/ui/display/manager/display_configurator.cc +++ b/chromium/ui/display/manager/display_configurator.cc @@ -785,24 +785,26 @@ bool DisplayConfigurator::SetGammaCorrection( bool DisplayConfigurator::IsPrivacyScreenSupportedOnInternalDisplay() const { return current_internal_display_ && - current_internal_display_->privacy_screen_state() != kNotSupported; + current_internal_display_->privacy_screen_state() != kNotSupported && + current_internal_display_->current_mode(); } bool DisplayConfigurator::SetPrivacyScreenOnInternalDisplay(bool enabled) { - if (!current_internal_display_) { - LOG(ERROR) << "This device does not have an internal display."; - return false; + if (IsPrivacyScreenSupportedOnInternalDisplay()) { + native_display_delegate_->SetPrivacyScreen( + current_internal_display_->display_id(), enabled); + return true; } - if (!IsPrivacyScreenSupportedOnInternalDisplay()) { + if (!current_internal_display_) { + LOG(ERROR) << "This device does not have an internal display."; + } else if (current_internal_display_->privacy_screen_state() == + kNotSupported) { LOG(ERROR) << "The internal display of this device does not support " - "privacy screeny."; - return false; + "privacy screen."; } - native_display_delegate_->SetPrivacyScreen( - current_internal_display_->display_id(), enabled); - return true; + return false; } chromeos::DisplayPowerState DisplayConfigurator::GetRequestedPowerState() diff --git a/chromium/ui/display/manager/display_manager.cc b/chromium/ui/display/manager/display_manager.cc index 11423d46aae..7d909dddb79 100644 --- a/chromium/ui/display/manager/display_manager.cc +++ b/chromium/ui/display/manager/display_manager.cc @@ -33,6 +33,7 @@ #include "ui/display/display_observer.h" #include "ui/display/display_switches.h" #include "ui/display/manager/display_layout_store.h" +#include "ui/display/manager/display_util.h" #include "ui/display/manager/managed_display_info.h" #include "ui/display/screen.h" #include "ui/display/types/display_snapshot.h" @@ -47,7 +48,6 @@ #include "chromeos/system/devicemode.h" #include "ui/display/manager/display_change_observer.h" #include "ui/display/manager/display_configurator.h" -#include "ui/display/manager/display_util.h" #include "ui/display/types/native_display_delegate.h" #include "ui/events/devices/touchscreen_device.h" #endif @@ -985,6 +985,16 @@ void DisplayManager::UpdateDisplaysWith( if (current_display.rotation() != new_display.rotation()) metrics |= DisplayObserver::DISPLAY_METRIC_ROTATION; + if (!WithinEpsilon(current_display.display_frequency(), + new_display.display_frequency())) { + metrics |= DisplayObserver::DISPLAY_METRIC_REFRESH_RATE; + } + + if (current_display_info.is_interlaced() != + new_display_info.is_interlaced()) { + metrics |= DisplayObserver::DISPLAY_METRIC_INTERLACED; + } + if (metrics != DisplayObserver::DISPLAY_METRIC_NONE) { display_changes.insert( std::pair<size_t, uint32_t>(new_displays.size(), metrics)); diff --git a/chromium/ui/display/manager/display_manager.h b/chromium/ui/display/manager/display_manager.h index d979f1f4e07..9520879323a 100644 --- a/chromium/ui/display/manager/display_manager.h +++ b/chromium/ui/display/manager/display_manager.h @@ -16,9 +16,9 @@ #include <vector> #include "base/callback.h" +#include "base/check_op.h" #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" -#include "base/logging.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" diff --git a/chromium/ui/display/manager/display_util.cc b/chromium/ui/display/manager/display_util.cc index 310e6293da6..c6b5b32b23a 100644 --- a/chromium/ui/display/manager/display_util.cc +++ b/chromium/ui/display/manager/display_util.cc @@ -62,10 +62,6 @@ constexpr std::array<ZoomListBucketDsf, 6> kZoomListBucketsForDsf{{ {1.f / kDsf_2_666, 0.5f, 0.6f, 0.8f, 0.9f, 1.f, 1.2f, 1.35f, 1.5f}}, }}; -bool WithinEpsilon(float a, float b) { - return std::abs(a - b) < std::numeric_limits<float>::epsilon(); -} - } // namespace #if defined(OS_CHROMEOS) @@ -108,6 +104,10 @@ int GetDisplayPower(const std::vector<DisplaySnapshot*>& displays, #endif // defined(OS_CHROMEOS) +bool WithinEpsilon(float a, float b) { + return std::abs(a - b) < std::numeric_limits<float>::epsilon(); +} + std::string MultipleDisplayStateToString(MultipleDisplayState state) { switch (state) { case MULTIPLE_DISPLAY_STATE_INVALID: diff --git a/chromium/ui/display/manager/display_util.h b/chromium/ui/display/manager/display_util.h index e90f055eeaa..a51c684318d 100644 --- a/chromium/ui/display/manager/display_util.h +++ b/chromium/ui/display/manager/display_util.h @@ -34,6 +34,9 @@ GetDisplayPower(const std::vector<DisplaySnapshot*>& displays, #endif // defined(OS_CHROMEOS) +// Determines whether |a| is within an epsilon of |b|. +bool WithinEpsilon(float a, float b); + // Returns a string describing |state|. std::string MultipleDisplayStateToString(MultipleDisplayState state); diff --git a/chromium/ui/display/manager/managed_display_info.cc b/chromium/ui/display/manager/managed_display_info.cc index e40b18c2cce..60720f12024 100644 --- a/chromium/ui/display/manager/managed_display_info.cc +++ b/chromium/ui/display/manager/managed_display_info.cc @@ -70,6 +70,11 @@ struct ManagedDisplayModeSorter { } }; +bool IsWithinEpsilon(float a, float b) { + constexpr float kEpsilon = 0.0001f; + return std::abs(a - b) < kEpsilon; +} + } // namespace ManagedDisplayMode::ManagedDisplayMode() {} @@ -104,6 +109,13 @@ ManagedDisplayMode::ManagedDisplayMode(const ManagedDisplayMode& other) = ManagedDisplayMode& ManagedDisplayMode::operator=( const ManagedDisplayMode& other) = default; +bool ManagedDisplayMode::operator==(const ManagedDisplayMode& other) const { + return size_ == other.size_ && is_interlaced_ == other.is_interlaced_ && + native_ == other.native_ && + IsWithinEpsilon(refresh_rate_, other.refresh_rate_) && + IsWithinEpsilon(device_scale_factor_, other.device_scale_factor_); +} + gfx::Size ManagedDisplayMode::GetSizeInDIP() const { gfx::SizeF size_dip(size_); size_dip.Scale(1.0f / device_scale_factor_); @@ -114,9 +126,8 @@ bool ManagedDisplayMode::IsEquivalent(const ManagedDisplayMode& other) const { if (display::features::IsListAllDisplayModesEnabled()) return *this == other; - const float kEpsilon = 0.0001f; return size_ == other.size_ && - std::abs(device_scale_factor_ - other.device_scale_factor_) < kEpsilon; + IsWithinEpsilon(device_scale_factor_, other.device_scale_factor_); } std::string ManagedDisplayMode::ToString() const { @@ -208,7 +219,7 @@ ManagedDisplayInfo ManagedDisplayInfo::CreateFromSpecWithID( base::SPLIT_WANT_NONEMPTY); for (size_t i = 0; i < parts.size(); ++i) { gfx::Size size; - float refresh_rate = 0.0f; + float refresh_rate = 60.0f; bool is_interlaced = false; gfx::Rect mode_bounds; diff --git a/chromium/ui/display/manager/managed_display_info.h b/chromium/ui/display/manager/managed_display_info.h index e340223f8e0..f99bf46bbcf 100644 --- a/chromium/ui/display/manager/managed_display_info.h +++ b/chromium/ui/display/manager/managed_display_info.h @@ -40,6 +40,7 @@ class DISPLAY_MANAGER_EXPORT ManagedDisplayMode { ~ManagedDisplayMode(); ManagedDisplayMode(const ManagedDisplayMode& other); ManagedDisplayMode& operator=(const ManagedDisplayMode& other); + bool operator==(const ManagedDisplayMode& other) const; // Returns the size in DIP which is visible to the user. gfx::Size GetSizeInDIP() const; @@ -66,15 +67,6 @@ class DISPLAY_MANAGER_EXPORT ManagedDisplayMode { float device_scale_factor_ = 1.0f; // The device scale factor of the mode. }; -inline bool operator==(const ManagedDisplayMode& lhs, - const ManagedDisplayMode& rhs) { - return lhs.size() == rhs.size() && - lhs.is_interlaced() == rhs.is_interlaced() && - lhs.refresh_rate() == rhs.refresh_rate() && - lhs.native() == rhs.native() && - lhs.device_scale_factor() == rhs.device_scale_factor(); -} - inline bool operator!=(const ManagedDisplayMode& lhs, const ManagedDisplayMode& rhs) { return !(lhs == rhs); diff --git a/chromium/ui/display/manager/managed_display_info_unittest.cc b/chromium/ui/display/manager/managed_display_info_unittest.cc index b73f335bed0..115214dd8be 100644 --- a/chromium/ui/display/manager/managed_display_info_unittest.cc +++ b/chromium/ui/display/manager/managed_display_info_unittest.cc @@ -68,11 +68,11 @@ TEST_F(DisplayInfoTest, CreateFromSpec) { EXPECT_EQ("200x200", info.display_modes()[3].size().ToString()); EXPECT_EQ("300x200", info.display_modes()[4].size().ToString()); - EXPECT_EQ(0.0f, info.display_modes()[0].refresh_rate()); + EXPECT_EQ(60.0f, info.display_modes()[0].refresh_rate()); EXPECT_EQ(60.0f, info.display_modes()[1].refresh_rate()); EXPECT_EQ(30.0f, info.display_modes()[2].refresh_rate()); EXPECT_EQ(59.9f, info.display_modes()[3].refresh_rate()); - EXPECT_EQ(0.0f, info.display_modes()[4].refresh_rate()); + EXPECT_EQ(60.0f, info.display_modes()[4].refresh_rate()); EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor()); EXPECT_EQ(1.0f, info.display_modes()[1].device_scale_factor()); diff --git a/chromium/ui/display/manager/touch_device_manager.cc b/chromium/ui/display/manager/touch_device_manager.cc index fc7499a38ca..4b2766bd236 100644 --- a/chromium/ui/display/manager/touch_device_manager.cc +++ b/chromium/ui/display/manager/touch_device_manager.cc @@ -11,6 +11,7 @@ #include "base/files/file_util.h" #include "base/hash/hash.h" +#include "base/logging.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" diff --git a/chromium/ui/display/manager/touch_transform_controller.cc b/chromium/ui/display/manager/touch_transform_controller.cc index 62ce69c4fc5..d2f07a537c6 100644 --- a/chromium/ui/display/manager/touch_transform_controller.cc +++ b/chromium/ui/display/manager/touch_transform_controller.cc @@ -7,6 +7,7 @@ #include <utility> #include <vector> +#include "base/logging.h" #include "third_party/skia/include/core/SkMatrix44.h" #include "ui/display/display_layout.h" #include "ui/display/manager/display_manager.h" diff --git a/chromium/ui/display/manager/update_display_configuration_task.cc b/chromium/ui/display/manager/update_display_configuration_task.cc index 0dd56cd85de..bfee8b7d58e 100644 --- a/chromium/ui/display/manager/update_display_configuration_task.cc +++ b/chromium/ui/display/manager/update_display_configuration_task.cc @@ -5,6 +5,7 @@ #include "ui/display/manager/update_display_configuration_task.h" #include "base/bind.h" +#include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "ui/display/manager/configure_displays_task.h" #include "ui/display/manager/display_layout_manager.h" diff --git a/chromium/ui/display/mojom/BUILD.gn b/chromium/ui/display/mojom/BUILD.gn index af12f462fb1..db1ab150193 100644 --- a/chromium/ui/display/mojom/BUILD.gn +++ b/chromium/ui/display/mojom/BUILD.gn @@ -9,6 +9,7 @@ mojom("mojom") { sources = [ "display.mojom", + "display_configuration_params.mojom", "display_constants.mojom", "display_layout.mojom", "display_mode.mojom", @@ -134,6 +135,18 @@ mojom("mojom") { traits_headers = [ "gamma_ramp_rgb_entry_mojom_traits.h" ] traits_public_deps = [ "//ui/display" ] }, + { + types = [ + { + mojom = "display.mojom.DisplayConfigurationParams" + cpp = "::display::DisplayConfigurationParams" + }, + ] + traits_sources = [ "display_configuration_params_mojom_traits.cc" ] + traits_headers = [ "display_configuration_params_mojom_traits.h" ] + traits_public_deps = [ "//ui/display" ] + traits_deps = [ "//ui/gfx/geometry" ] + }, ] cpp_typemaps += shared_cpp_typemaps diff --git a/chromium/ui/display/mojom/display_configuration_params.mojom b/chromium/ui/display/mojom/display_configuration_params.mojom new file mode 100644 index 00000000000..9817e7f4897 --- /dev/null +++ b/chromium/ui/display/mojom/display_configuration_params.mojom @@ -0,0 +1,15 @@ +// Copyright 2020 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. + +module display.mojom; + +import "ui/display/mojom/display_mode.mojom"; +import "ui/gfx/geometry/mojom/geometry.mojom"; + +// Corresponds to display::DisplayConfigurationParams. +struct DisplayConfigurationParams { + int64 id; + gfx.mojom.Point origin; + display.mojom.DisplayMode? mode; +}; diff --git a/chromium/ui/display/mojom/display_configuration_params_mojom_traits.cc b/chromium/ui/display/mojom/display_configuration_params_mojom_traits.cc new file mode 100644 index 00000000000..8f0cf48b631 --- /dev/null +++ b/chromium/ui/display/mojom/display_configuration_params_mojom_traits.cc @@ -0,0 +1,29 @@ +// Copyright 2020 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/mojom/display_configuration_params_mojom_traits.h" + +namespace mojo { + +// static +bool StructTraits<display::mojom::DisplayConfigurationParamsDataView, + display::DisplayConfigurationParams>:: + Read(display::mojom::DisplayConfigurationParamsDataView data, + display::DisplayConfigurationParams* out) { + gfx::Point origin; + if (!data.ReadOrigin(&origin)) + return false; + + base::Optional<std::unique_ptr<display::DisplayMode>> mode; + if (!data.ReadMode(&mode)) + return false; + + out->id = data.id(); + out->origin = origin; + out->mode = std::move(mode); + + return true; +} + +} // namespace mojo diff --git a/chromium/ui/display/mojom/display_configuration_params_mojom_traits.h b/chromium/ui/display/mojom/display_configuration_params_mojom_traits.h new file mode 100644 index 00000000000..736c9e7e002 --- /dev/null +++ b/chromium/ui/display/mojom/display_configuration_params_mojom_traits.h @@ -0,0 +1,39 @@ +// Copyright 2020 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. + +#ifndef UI_DISPLAY_MOJOM_DISPLAY_CONFIGURATION_PARAMS_MOJOM_TRAITS_H_ +#define UI_DISPLAY_MOJOM_DISPLAY_CONFIGURATION_PARAMS_MOJOM_TRAITS_H_ + +#include "ui/display/mojom/display_configuration_params.mojom.h" +#include "ui/display/types/display_configuration_params.h" +#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h" +#include "ui/gfx/ipc/color/gfx_param_traits.h" + +namespace mojo { + +template <> +struct StructTraits<display::mojom::DisplayConfigurationParamsDataView, + display::DisplayConfigurationParams> { + static int64_t id( + const display::DisplayConfigurationParams& display_configuration_params) { + return display_configuration_params.id; + } + + static gfx::Point origin( + const display::DisplayConfigurationParams& display_configuration_params) { + return display_configuration_params.origin; + } + + static const base::Optional<std::unique_ptr<display::DisplayMode>>& mode( + const display::DisplayConfigurationParams& display_configuration_params) { + return display_configuration_params.mode; + } + + static bool Read(display::mojom::DisplayConfigurationParamsDataView data, + display::DisplayConfigurationParams* out); +}; + +} // namespace mojo + +#endif // UI_DISPLAY_MOJOM_DISPLAY_CONFIGURATION_PARAMS_MOJOM_TRAITS_H_ diff --git a/chromium/ui/display/scoped_display_for_new_windows.cc b/chromium/ui/display/scoped_display_for_new_windows.cc new file mode 100644 index 00000000000..d23839b8284 --- /dev/null +++ b/chromium/ui/display/scoped_display_for_new_windows.cc @@ -0,0 +1,24 @@ +// Copyright 2020 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/scoped_display_for_new_windows.h" + +#include "ui/display/screen.h" + +namespace display { + +ScopedDisplayForNewWindows::ScopedDisplayForNewWindows(int64_t new_display) { + Screen::GetScreen()->SetScopedDisplayForNewWindows(new_display); +} + +ScopedDisplayForNewWindows::ScopedDisplayForNewWindows(gfx::NativeView view) + : ScopedDisplayForNewWindows( + Screen::GetScreen()->GetDisplayNearestView(view).id()) {} + +ScopedDisplayForNewWindows::~ScopedDisplayForNewWindows() { + Screen::GetScreen()->SetScopedDisplayForNewWindows( + display::kInvalidDisplayId); +} + +} // namespace display diff --git a/chromium/ui/display/scoped_display_for_new_windows.h b/chromium/ui/display/scoped_display_for_new_windows.h new file mode 100644 index 00000000000..073a81d660a --- /dev/null +++ b/chromium/ui/display/scoped_display_for_new_windows.h @@ -0,0 +1,27 @@ +// Copyright 2020 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. + +#ifndef UI_DISPLAY_SCOPED_DISPLAY_FOR_NEW_WINDOWS_H_ +#define UI_DISPLAY_SCOPED_DISPLAY_FOR_NEW_WINDOWS_H_ + +#include "ui/display/screen.h" +#include "ui/gfx/native_widget_types.h" + +namespace display { + +// Constructing a ScopedDisplayForNewWindows allows temporarily switching +// display for new windows during the lifetime of this object. +class DISPLAY_EXPORT ScopedDisplayForNewWindows { + public: + explicit ScopedDisplayForNewWindows(int64_t new_display); + explicit ScopedDisplayForNewWindows(gfx::NativeView view); + ~ScopedDisplayForNewWindows(); + ScopedDisplayForNewWindows(const ScopedDisplayForNewWindows&) = delete; + ScopedDisplayForNewWindows& operator=(const ScopedDisplayForNewWindows&) = + delete; +}; + +} // namespace display + +#endif // UI_DISPLAY_SCOPED_DISPLAY_FOR_NEW_WINDOWS_H_ diff --git a/chromium/ui/display/screen.cc b/chromium/ui/display/screen.cc index ef1d381d9e2..c289415a1a1 100644 --- a/chromium/ui/display/screen.cc +++ b/chromium/ui/display/screen.cc @@ -6,7 +6,8 @@ #include <utility> -#include "base/logging.h" +#include "base/check.h" +#include "base/notreached.h" #include "ui/display/display.h" #include "ui/display/types/display_constants.h" #include "ui/gfx/geometry/rect.h" @@ -44,6 +45,12 @@ Display Screen::GetDisplayNearestView(gfx::NativeView view) const { display::Display Screen::GetDisplayForNewWindows() const { display::Display display; + // Scoped value can override if it is set. + if (scoped_display_id_for_new_windows_ != kInvalidDisplayId && + GetDisplayWithDisplayId(scoped_display_id_for_new_windows_, &display)) { + return display; + } + if (GetDisplayWithDisplayId(display_id_for_new_windows_, &display)) return display; @@ -90,4 +97,15 @@ std::string Screen::GetCurrentWorkspace() { return {}; } +void Screen::SetScopedDisplayForNewWindows(int64_t display_id) { + if (display_id == scoped_display_id_for_new_windows_) + return; + // Only allow set and clear, not switch. + DCHECK(display_id == kInvalidDisplayId ^ + scoped_display_id_for_new_windows_ == kInvalidDisplayId) + << "display_id=" << display_id << ", scoped_display_id_for_new_windows_=" + << scoped_display_id_for_new_windows_; + scoped_display_id_for_new_windows_ = display_id; +} + } // namespace display diff --git a/chromium/ui/display/screen.h b/chromium/ui/display/screen.h index 2263985910f..7742ef3e192 100644 --- a/chromium/ui/display/screen.h +++ b/chromium/ui/display/screen.h @@ -128,9 +128,17 @@ class DISPLAY_EXPORT Screen { virtual std::string GetCurrentWorkspace(); private: + friend class ScopedDisplayForNewWindows; + + // Used to temporarily override the value from SetDisplayForNewWindows() by + // creating an instance of ScopedDisplayForNewWindows. Call with + // |kInvalidDisplayId| to unset. + void SetScopedDisplayForNewWindows(int64_t display_id); + static gfx::NativeWindow GetWindowForView(gfx::NativeView view); int64_t display_id_for_new_windows_; + int64_t scoped_display_id_for_new_windows_ = display::kInvalidDisplayId; DISALLOW_COPY_AND_ASSIGN(Screen); }; diff --git a/chromium/ui/display/screen_unittest.cc b/chromium/ui/display/screen_unittest.cc index 6acc48019ab..ac09e4e9f9a 100644 --- a/chromium/ui/display/screen_unittest.cc +++ b/chromium/ui/display/screen_unittest.cc @@ -6,6 +6,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display.h" +#include "ui/display/scoped_display_for_new_windows.h" #include "ui/display/test/test_screen.h" namespace display { @@ -16,6 +17,8 @@ const int DEFAULT_DISPLAY_ID = 0x1337; const int DEFAULT_DISPLAY_WIDTH = 2560; const int DEFAULT_DISPLAY_HEIGHT = 1440; +const int DISPLAY_2_ID = 0xc001; + } // namespace class ScreenTest : public testing::Test { @@ -28,6 +31,8 @@ class ScreenTest : public testing::Test { gfx::Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT)); test_screen_.display_list().RemoveDisplay(test_display.id()); test_screen_.display_list().AddDisplay(display, DisplayList::Type::PRIMARY); + test_screen_.display_list().AddDisplay(Display(DISPLAY_2_ID), + DisplayList::Type::NOT_PRIMARY); Screen::SetScreenInstance(&test_screen_); } @@ -46,7 +51,7 @@ TEST_F(ScreenTest, GetPrimaryDisplaySize) { } TEST_F(ScreenTest, GetNumDisplays) { - EXPECT_EQ(Screen::GetScreen()->GetNumDisplays(), 1); + EXPECT_EQ(Screen::GetScreen()->GetNumDisplays(), 2); } TEST_F(ScreenTest, GetDisplayWithDisplayId) { @@ -66,4 +71,20 @@ TEST_F(ScreenTest, GetDisplayForNewWindows) { screen->GetDisplayForNewWindows().id()); } +TEST_F(ScreenTest, ScopedDisplayForNewWindows) { + Screen* screen = Screen::GetScreen(); + + // Set primary as default; + screen->SetDisplayForNewWindows(DEFAULT_DISPLAY_ID); + EXPECT_EQ(DEFAULT_DISPLAY_ID, screen->GetDisplayForNewWindows().id()); + + // ScopedDisplayForNewWindows overrides while it is in scope. + { + ScopedDisplayForNewWindows scoped(DISPLAY_2_ID); + EXPECT_EQ(DISPLAY_2_ID, screen->GetDisplayForNewWindows().id()); + } + + EXPECT_EQ(DEFAULT_DISPLAY_ID, screen->GetDisplayForNewWindows().id()); +} + } // namespace display diff --git a/chromium/ui/display/types/BUILD.gn b/chromium/ui/display/types/BUILD.gn index 2b4ae22a6a8..86ea7b44df1 100644 --- a/chromium/ui/display/types/BUILD.gn +++ b/chromium/ui/display/types/BUILD.gn @@ -7,6 +7,8 @@ import("//build/config/jumbo.gni") jumbo_component("types") { output_name = "display_types" sources = [ + "display_configuration_params.cc", + "display_configuration_params.h", "display_constants.h", "display_mode.cc", "display_mode.h", diff --git a/chromium/ui/display/types/display_configuration_params.cc b/chromium/ui/display/types/display_configuration_params.cc new file mode 100644 index 00000000000..996ade949e4 --- /dev/null +++ b/chromium/ui/display/types/display_configuration_params.cc @@ -0,0 +1,21 @@ +// Copyright 2020 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/types/display_configuration_params.h" + +namespace display { + +DisplayConfigurationParams::DisplayConfigurationParams() = default; +DisplayConfigurationParams::DisplayConfigurationParams( + int64_t id, + gfx::Point origin, + const display::DisplayMode* pmode) + : id(id), origin(origin) { + if (pmode) + mode = pmode->Clone(); +} + +DisplayConfigurationParams::~DisplayConfigurationParams() = default; + +} // namespace display diff --git a/chromium/ui/display/types/display_configuration_params.h b/chromium/ui/display/types/display_configuration_params.h new file mode 100644 index 00000000000..73c009435dd --- /dev/null +++ b/chromium/ui/display/types/display_configuration_params.h @@ -0,0 +1,31 @@ +// Copyright 2020 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. + +#ifndef UI_DISPLAY_TYPES_DISPLAY_CONFIGURATION_PARAMS_H_ +#define UI_DISPLAY_TYPES_DISPLAY_CONFIGURATION_PARAMS_H_ + +#include <stdint.h> + +#include "base/optional.h" +#include "ui/display/types/display_mode.h" +#include "ui/display/types/display_types_export.h" +#include "ui/gfx/geometry/point.h" + +namespace display { + +struct DISPLAY_TYPES_EXPORT DisplayConfigurationParams { + DisplayConfigurationParams(); + DisplayConfigurationParams(int64_t id, + gfx::Point origin, + const display::DisplayMode* pmode); + ~DisplayConfigurationParams(); + + int64_t id = 0; + gfx::Point origin = gfx::Point(); + base::Optional<std::unique_ptr<display::DisplayMode>> mode = base::nullopt; +}; + +} // namespace display + +#endif // UI_DISPLAY_TYPES_DISPLAY_CONFIGURATION_PARAMS_H_ diff --git a/chromium/ui/display/util/edid_parser.cc b/chromium/ui/display/util/edid_parser.cc index 4664a3e5332..d1b248b92ed 100644 --- a/chromium/ui/display/util/edid_parser.cc +++ b/chromium/ui/display/util/edid_parser.cc @@ -328,14 +328,10 @@ void EdidParser::ParseEdid(const std::vector<uint8_t>& edid) { } // Verify if the |display_name_| consists of printable characters only. - // TODO(oshima|muka): Consider replacing unprintable chars with white space. - for (const char c : display_name_) { - if (!isascii(c) || !isprint(c)) { - display_name_.clear(); - base::UmaHistogramEnumeration(kParseEdidFailureMetric, - ParseEdidFailure::kDisplayName); - } - } + // Replace unprintable chars with white space. + std::replace_if( + display_name_.begin(), display_name_.end(), + [](char c) { return !isascii(c) || !isprint(c); }, ' '); // See http://en.wikipedia.org/wiki/Extended_display_identification_data // for the extension format of EDID. Also see EIA/CEA-861 spec for diff --git a/chromium/ui/display/util/edid_parser_unittest.cc b/chromium/ui/display/util/edid_parser_unittest.cc index 0991d79c751..73dda4af53c 100644 --- a/chromium/ui/display/util/edid_parser_unittest.cc +++ b/chromium/ui/display/util/edid_parser_unittest.cc @@ -25,6 +25,18 @@ namespace display { namespace { +// EDID with non-ascii char in display name. +constexpr unsigned char kBadDisplayName[] = + "\x00\xff\xff\xff\xff\xff\xff\x00\x22\xf0\x6c\x28\x01\x01\x01\x01" + "\x02\x16\x01\x04\xb5\x40\x28\x78\xe2\x8d\x85\xad\x4f\x35\xb1\x25" + "\x0e\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\xe2\x68\x00\xa0\xa0\x40\x2e\x60\x30\x20" + "\x36\x00\x81\x90\x21\x00\x00\x1a\xbc\x1b\x00\xa0\x50\x20\x17\x30" + "\x30\x20\x36\x00\x81\x90\x21\x00\x00\x1a\x00\x00\x00\xfc\x00\x48" + "\x50\x20\x5a\x00\x33\x30\x77\x0a\x20\x20\x20\x20\x00\x00\x00\xff" + "\x00\x43\x4e\x34\x32\x30\x32\x31\x33\x37\x51\x0a\x20\x20\x00\x71"; +constexpr size_t kBadDisplayNameLength = base::size(kBadDisplayName); + // Sample EDID data extracted from real devices. constexpr unsigned char kNormalDisplay[] = "\x00\xff\xff\xff\xff\xff\xff\x00\x22\xf0\x6c\x28\x01\x01\x01\x01" @@ -251,6 +263,24 @@ struct TestParams { } kTestCases[] = { {0x22f0u, 0x6c28u, + "HP Z 30w", // non-ascii char in display name. + gfx::Size(2560, 1600), + 2012, + false, + 2.2, + 10, + kNormalDisplayPrimaries, + 586181672, + 9834990092472576, + "HWP", + "286C", + {}, + {}, + base::nullopt, + kBadDisplayName, + kBadDisplayNameLength}, + {0x22f0u, + 0x6c28u, "HP ZR30w", gfx::Size(2560, 1600), 2012, diff --git a/chromium/ui/display/win/scaling_util.cc b/chromium/ui/display/win/scaling_util.cc index 2102a7d0475..e23e68ee6d5 100644 --- a/chromium/ui/display/win/scaling_util.cc +++ b/chromium/ui/display/win/scaling_util.cc @@ -227,8 +227,9 @@ DisplayPlacement CalculateDisplayPlacement(const DisplayInfo& parent, // corners and |rect|'s top corners when the rects don't overlap vertically. int64_t SquaredDistanceBetweenRects(const gfx::Rect& ref, const gfx::Rect& rect) { - if (ref.Intersects(rect)) - return 0; + gfx::Rect intersection_rect = gfx::IntersectRects(ref, rect); + if (!intersection_rect.IsEmpty()) + return -(intersection_rect.width() * intersection_rect.height()); CoordinateRotation degrees = ComputeCoordinateRotationRefTop(ref, rect); gfx::Rect top_rect(CoordinateRotateRect(ref, degrees)); diff --git a/chromium/ui/display/win/scaling_util.h b/chromium/ui/display/win/scaling_util.h index 18b475f3cc4..74e8d5a34ed 100644 --- a/chromium/ui/display/win/scaling_util.h +++ b/chromium/ui/display/win/scaling_util.h @@ -134,7 +134,9 @@ DISPLAY_EXPORT DisplayPlacement CalculateDisplayPlacement( // | | | | // +---+ +----+ // -// For rectangles that intersect each other, the distance is 0. +// For rectangles that intersect each other, the distance is the negative value +// of the overlapping area, so callers can distinguish different amounts of +// overlap. // // The squared distance is used to avoid taking the square root as the common // usage is to compare distances greater than 1 unit. diff --git a/chromium/ui/display/win/scaling_util_unittest.cc b/chromium/ui/display/win/scaling_util_unittest.cc index c6fd7f4c226..79c1a04bb10 100644 --- a/chromium/ui/display/win/scaling_util_unittest.cc +++ b/chromium/ui/display/win/scaling_util_unittest.cc @@ -430,15 +430,15 @@ TEST(ScalingUtilTest, CalculateDisplayPlacement2xScale) { TEST(ScalingUtilTest, SquaredDistanceBetweenRectsFullyIntersecting) { gfx::Rect rect1(0, 0, 100, 100); gfx::Rect rect2(5, 5, 10, 10); - EXPECT_EQ(0, SquaredDistanceBetweenRects(rect1, rect2)); - EXPECT_EQ(0, SquaredDistanceBetweenRects(rect2, rect1)); + EXPECT_EQ(-100, SquaredDistanceBetweenRects(rect1, rect2)); + EXPECT_EQ(-100, SquaredDistanceBetweenRects(rect2, rect1)); } TEST(ScalingUtilTest, SquaredDistanceBetweenRectsPartiallyIntersecting) { gfx::Rect rect1(0, 0, 10, 10); - gfx::Rect rect2(5, 5, 10, 10); - EXPECT_EQ(0, SquaredDistanceBetweenRects(rect1, rect2)); - EXPECT_EQ(0, SquaredDistanceBetweenRects(rect2, rect1)); + gfx::Rect rect2(5, 5, 20, 20); + EXPECT_EQ(-25, SquaredDistanceBetweenRects(rect1, rect2)); + EXPECT_EQ(-25, SquaredDistanceBetweenRects(rect2, rect1)); } TEST(ScalingUtilTest, SquaredDistanceBetweenRectsTouching) { diff --git a/chromium/ui/display/win/screen_win.cc b/chromium/ui/display/win/screen_win.cc index 0c789c42fa5..d4fc53fd60d 100644 --- a/chromium/ui/display/win/screen_win.cc +++ b/chromium/ui/display/win/screen_win.cc @@ -15,6 +15,7 @@ #include "base/numerics/ranges.h" #include "base/optional.h" #include "base/stl_util.h" +#include "base/trace_event/trace_event.h" #include "base/win/win_util.h" #include "base/win/windows_version.h" #include "ui/display/display.h" @@ -817,6 +818,8 @@ void ScreenWin::OnWndProc(HWND hwnd, (message != WM_SETTINGCHANGE || wparam != SPI_SETWORKAREA)) return; + TRACE_EVENT1("ui", "ScreenWin::OnWndProc", "message", message); + color_profile_reader_->UpdateIfNeeded(); if (request_hdr_status_callback_) request_hdr_status_callback_.Run(); @@ -836,6 +839,8 @@ void ScreenWin::OnColorProfilesChanged() { } void ScreenWin::UpdateAllDisplaysAndNotify() { + TRACE_EVENT0("ui", "ScreenWin::UpdateAllDisplaysAndNotify"); + std::vector<Display> old_displays = std::move(displays_); UpdateFromDisplayInfos(GetDisplayInfosFromSystem()); change_notifier_.NotifyDisplaysChanged(old_displays, displays_); diff --git a/chromium/ui/display/win/screen_win_unittest.cc b/chromium/ui/display/win/screen_win_unittest.cc index 059c533c4f1..fa5d8572c8f 100644 --- a/chromium/ui/display/win/screen_win_unittest.cc +++ b/chromium/ui/display/win/screen_win_unittest.cc @@ -39,7 +39,7 @@ class TestScreenWin : public ScreenWin { UpdateFromDisplayInfos(display_infos); } - ~TestScreenWin() override = default; + ~TestScreenWin() override { Screen::SetScreenInstance(old_screen_); } protected: // win::ScreenWin: @@ -122,6 +122,7 @@ class TestScreenWin : public ScreenWin { return metric; } + Screen* old_screen_ = Screen::SetScreenInstance(this); std::vector<MONITORINFOEX> monitor_infos_; std::unordered_map<HWND, gfx::Rect> hwnd_map_; @@ -148,8 +149,7 @@ class TestScreenWinInitializer { class TestScreenWinManager final : public TestScreenWinInitializer { public: TestScreenWinManager() = default; - - ~TestScreenWinManager() { Screen::SetScreenInstance(nullptr); } + ~TestScreenWinManager() = default; void AddMonitor(const gfx::Rect& pixel_bounds, const gfx::Rect& pixel_work, @@ -175,7 +175,6 @@ class TestScreenWinManager final : public TestScreenWinInitializer { ASSERT_EQ(screen_win_, nullptr); screen_win_ = std::make_unique<TestScreenWin>(display_infos_, monitor_infos_, hwnd_map_); - Screen::SetScreenInstance(screen_win_.get()); } ScreenWin* GetScreenWin() { @@ -305,6 +304,13 @@ TEST_F(ScreenWinTestSingleDisplay1x, DIPToScreenRects) { EXPECT_EQ(middle, ScreenWin::DIPToScreenRect(hwnd, middle)); } +TEST_F(ScreenWinTestSingleDisplay1x, DIPToScreenRectNullHWND) { + gfx::Rect origin(0, 0, 50, 100); + gfx::Rect middle(253, 495, 41, 52); + EXPECT_EQ(origin, ScreenWin::DIPToScreenRect(nullptr, origin)); + EXPECT_EQ(middle, ScreenWin::DIPToScreenRect(nullptr, middle)); +} + TEST_F(ScreenWinTestSingleDisplay1x, ClientToDIPRects) { HWND hwnd = GetFakeHwnd(); gfx::Rect origin(0, 0, 50, 100); @@ -467,6 +473,13 @@ TEST_F(ScreenWinTestSingleDisplay1_25x, DIPToScreenRects) { ScreenWin::DIPToScreenRect(hwnd, gfx::Rect(168, 330, 28, 36))); } +TEST_F(ScreenWinTestSingleDisplay1_25x, DIPToScreenRectNullHWND) { + EXPECT_EQ(gfx::Rect(0, 0, 43, 84), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 34, 67))); + EXPECT_EQ(gfx::Rect(210, 412, 35, 46), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(168, 330, 28, 36))); +} + TEST_F(ScreenWinTestSingleDisplay1_25x, ClientToDIPRects) { HWND hwnd = GetFakeHwnd(); EXPECT_EQ(gfx::Rect(0, 0, 40, 80), @@ -616,6 +629,13 @@ TEST_F(ScreenWinTestSingleDisplay1_5x, DIPToScreenRects) { ScreenWin::DIPToScreenRect(hwnd, gfx::Rect(168, 330, 28, 36))); } +TEST_F(ScreenWinTestSingleDisplay1_5x, DIPToScreenRectNullHWND) { + EXPECT_EQ(gfx::Rect(0, 0, 51, 101), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 34, 67))); + EXPECT_EQ(gfx::Rect(252, 495, 42, 54), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(168, 330, 28, 36))); +} + TEST_F(ScreenWinTestSingleDisplay1_5x, ClientToDIPRects) { HWND hwnd = GetFakeHwnd(); EXPECT_EQ(gfx::Rect(0, 0, 34, 67), @@ -765,6 +785,13 @@ TEST_F(ScreenWinTestSingleDisplay2x, DIPToScreenRects) { ScreenWin::DIPToScreenRect(hwnd, gfx::Rect(126, 248, 21, 26))); } +TEST_F(ScreenWinTestSingleDisplay2x, DIPToScreenRectNullHWND) { + EXPECT_EQ(gfx::Rect(0, 0, 50, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 25, 50))); + EXPECT_EQ(gfx::Rect(252, 496, 42, 52), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(126, 248, 21, 26))); +} + TEST_F(ScreenWinTestSingleDisplay2x, ClientToDIPRects) { HWND hwnd = GetFakeHwnd(); EXPECT_EQ(gfx::Rect(0, 0, 25, 50), @@ -966,6 +993,22 @@ TEST_F(ScreenWinTestTwoDisplays1x, DIPToScreenRects) { ScreenWin::DIPToScreenRect(right_hwnd, right_origin_left)); } +TEST_F(ScreenWinTestTwoDisplays1x, DIPToScreenRectNullHWND) { + gfx::Rect left_origin(0, 0, 50, 100); + gfx::Rect left_middle(253, 495, 41, 52); + EXPECT_EQ(left_origin, ScreenWin::DIPToScreenRect(nullptr, left_origin)); + EXPECT_EQ(left_middle, ScreenWin::DIPToScreenRect(nullptr, left_middle)); + + gfx::Rect right_origin(1920, 0, 200, 300); + gfx::Rect right_middle(2000, 496, 100, 200); + EXPECT_EQ(right_origin, ScreenWin::DIPToScreenRect(nullptr, right_origin)); + EXPECT_EQ(right_middle, ScreenWin::DIPToScreenRect(nullptr, right_middle)); + + gfx::Rect right_origin_left(1900, 200, 100, 100); + EXPECT_EQ(right_origin_left, + ScreenWin::DIPToScreenRect(nullptr, right_origin_left)); +} + TEST_F(ScreenWinTestTwoDisplays1x, ClientToDIPRects) { HWND left_hwnd = GetLeftFakeHwnd(); gfx::Rect origin(0, 0, 50, 100); @@ -1232,6 +1275,21 @@ TEST_F(ScreenWinTestTwoDisplays2x, DIPToScreenRects) { gfx::Rect(950, 100, 50, 50))); } +TEST_F(ScreenWinTestTwoDisplays2x, DIPToScreenRectNullHWND) { + EXPECT_EQ(gfx::Rect(0, 0, 50, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 25, 50))); + EXPECT_EQ(gfx::Rect(252, 496, 42, 52), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(126, 248, 21, 26))); + + EXPECT_EQ(gfx::Rect(1920, 0, 200, 300), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(960, 0, 100, 150))); + EXPECT_EQ(gfx::Rect(2000, 496, 100, 200), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(1000, 248, 50, 100))); + + EXPECT_EQ(gfx::Rect(1900, 200, 100, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(950, 100, 50, 50))); +} + TEST_F(ScreenWinTestTwoDisplays2x, ClientToDIPRects) { HWND left_hwnd = GetLeftFakeHwnd(); EXPECT_EQ(gfx::Rect(0, 0, 25, 50), @@ -1611,6 +1669,43 @@ TEST_F(ScreenWinTestManyDisplays1x, DIPToScreenRects) { ScreenWin::DIPToScreenRect(GetFakeHwnd(4), monitor4_middle)); } +TEST_F(ScreenWinTestManyDisplays1x, DIPToScreenRectNullHWND) { + gfx::Rect primary_origin(0, 0, 50, 100); + gfx::Rect primary_middle(250, 252, 40, 50); + EXPECT_EQ(primary_origin, + ScreenWin::DIPToScreenRect(nullptr, primary_origin)); + EXPECT_EQ(primary_middle, + ScreenWin::DIPToScreenRect(nullptr, primary_middle)); + + gfx::Rect monitor1_origin(640, 0, 25, 43); + gfx::Rect monitor1_middle(852, 357, 37, 45); + EXPECT_EQ(monitor1_origin, + ScreenWin::DIPToScreenRect(nullptr, monitor1_origin)); + EXPECT_EQ(monitor1_middle, + ScreenWin::DIPToScreenRect(nullptr, monitor1_middle)); + + gfx::Rect monitor2_origin(0, 480, 42, 40); + gfx::Rect monitor2_middle(321, 700, 103, 203); + EXPECT_EQ(monitor2_origin, + ScreenWin::DIPToScreenRect(nullptr, monitor2_origin)); + EXPECT_EQ(monitor2_middle, + ScreenWin::DIPToScreenRect(nullptr, monitor2_middle)); + + gfx::Rect monitor3_origin(1664, 768, 24, 102); + gfx::Rect monitor3_middle(1823, 1000, 35, 35); + EXPECT_EQ(monitor3_origin, + ScreenWin::DIPToScreenRect(nullptr, monitor3_origin)); + EXPECT_EQ(monitor3_middle, + ScreenWin::DIPToScreenRect(nullptr, monitor3_middle)); + + gfx::Rect monitor4_origin(1864, 1168, 15, 20); + gfx::Rect monitor4_middle(1955, 1224, 25, 30); + EXPECT_EQ(monitor4_origin, + ScreenWin::DIPToScreenRect(nullptr, monitor4_origin)); + EXPECT_EQ(monitor4_middle, + ScreenWin::DIPToScreenRect(nullptr, monitor4_middle)); +} + TEST_F(ScreenWinTestManyDisplays1x, ClientToDIPRects) { gfx::Rect origin(0, 0, 50, 100); gfx::Rect middle(253, 495, 41, 52); @@ -2027,6 +2122,38 @@ TEST_F(ScreenWinTestManyDisplays2x, DIPToScreenRects) { gfx::Rect(977, 612, 13, 15))); } +TEST_F(ScreenWinTestManyDisplays2x, DIPToScreenRectNullHWND) { + // Primary Monitor + EXPECT_EQ(gfx::Rect(0, 0, 50, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 25, 50))); + EXPECT_EQ(gfx::Rect(250, 252, 40, 50), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(125, 126, 20, 25))); + + // Monitor 1 + EXPECT_EQ(gfx::Rect(640, 0, 26, 44), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(320, 0, 13, 22))); + EXPECT_EQ(gfx::Rect(852, 356, 38, 46), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(426, 178, 19, 23))); + + // Monitor 2 + EXPECT_EQ(gfx::Rect(0, 480, 42, 40), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 240, 21, 20))); + EXPECT_EQ(gfx::Rect(320, 700, 104, 204), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(160, 350, 52, 102))); + + // Monitor 3 + EXPECT_EQ(gfx::Rect(1664, 768, 24, 102), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(832, 384, 12, 51))); + EXPECT_EQ(gfx::Rect(1822, 1000, 36, 36), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(911, 500, 18, 18))); + + // Monitor 4 + EXPECT_EQ(gfx::Rect(1864, 1168, 16, 20), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(932, 584, 8, 10))); + EXPECT_EQ(gfx::Rect(1954, 1224, 26, 30), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(977, 612, 13, 15))); +} + TEST_F(ScreenWinTestManyDisplays2x, ClientToDIPRects) { gfx::Rect client_screen_origin(0, 0, 50, 100); gfx::Rect client_dip_origin(0, 0, 25, 50); @@ -2330,6 +2457,24 @@ TEST_F(ScreenWinTestTwoDisplays1x2x, DIPToScreenRects) { gfx::Rect(1910, 100, 50, 50))); } +TEST_F(ScreenWinTestTwoDisplays1x2x, DIPToScreenRectNullHWND) { + EXPECT_EQ(gfx::Rect(0, 0, 50, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 50, 100))); + EXPECT_EQ(gfx::Rect(252, 496, 42, 52), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(252, 496, 42, 52))); + + EXPECT_EQ(gfx::Rect(1920, 0, 200, 300), + ScreenWin::DIPToScreenRect(nullptr, + gfx::Rect(1920, 0, 100, 150))); + EXPECT_EQ(gfx::Rect(2000, 496, 100, 200), + ScreenWin::DIPToScreenRect(nullptr, + gfx::Rect(1960, 248, 50, 100))); + + EXPECT_EQ(gfx::Rect(1900, 200, 100, 100), + ScreenWin::DIPToScreenRect(nullptr, + gfx::Rect(1910, 100, 50, 50))); +} + TEST_F(ScreenWinTestTwoDisplays1x2x, ClientToDIPRects) { HWND left_hwnd = GetLeftFakeHwnd(); EXPECT_EQ(gfx::Rect(0, 0, 50, 100), @@ -2605,6 +2750,21 @@ TEST_F(ScreenWinTestTwoDisplays1_5x1x, DIPToScreenRects) { gfx::Rect(514, 0, 100, 100))); } +TEST_F(ScreenWinTestTwoDisplays1_5x1x, DIPToScreenRectNullHWND) { + EXPECT_EQ(gfx::Rect(0, 0, 51, 101), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 34, 67))); + EXPECT_EQ(gfx::Rect(252, 495, 42, 54), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(168, 330, 28, 36))); + + EXPECT_EQ(gfx::Rect(800, 120, 200, 300), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(534, -80, 200, 300))); + EXPECT_EQ(gfx::Rect(1253, 496, 100, 200), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(987, 296, 100, 200))); + + EXPECT_EQ(gfx::Rect(780, 200, 100, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(514, 0, 100, 100))); +} + TEST_F(ScreenWinTestTwoDisplays1_5x1x, ClientToDIPRects) { HWND left_hwnd = GetLeftFakeHwnd(); EXPECT_EQ(gfx::Rect(0, 0, 34, 67), @@ -2876,6 +3036,22 @@ TEST_F(ScreenWinTestTwoDisplays2x1x, DIPToScreenRects) { gfx::Rect(940, 200, 100, 100))); } +TEST_F(ScreenWinTestTwoDisplays2x1x, DIPToScreenRectNullHWND) { + EXPECT_EQ(gfx::Rect(0, 0, 50, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 25, 50))); + EXPECT_EQ(gfx::Rect(252, 496, 42, 52), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(126, 248, 21, 26))); + + EXPECT_EQ(gfx::Rect(1920, 0, 200, 300), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(960, 0, 200, 300))); + EXPECT_EQ( + gfx::Rect(2000, 496, 100, 200), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(1040, 496, 100, 200))); + + EXPECT_EQ(gfx::Rect(1900, 200, 100, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(940, 200, 100, 100))); +} + TEST_F(ScreenWinTestTwoDisplays2x1x, ClientToDIPRects) { HWND left_hwnd = GetLeftFakeHwnd(); EXPECT_EQ(gfx::Rect(0, 0, 25, 50), @@ -3152,6 +3328,21 @@ TEST_F(ScreenWinTestTwoDisplays2x1xVirtualized, DIPToScreenRects) { gfx::Rect(3190, 100, 50, 50))); } +TEST_F(ScreenWinTestTwoDisplays2x1xVirtualized, DIPToScreenRectNullHWND) { + EXPECT_EQ(gfx::Rect(0, 0, 50, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 25, 50))); + EXPECT_EQ(gfx::Rect(252, 496, 42, 52), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(126, 248, 21, 26))); + + EXPECT_EQ(gfx::Rect(6400, 0, 200, 300), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(3200, 0, 100, 150))); + EXPECT_EQ(gfx::Rect(7000, 496, 100, 200), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(3500, 248, 50, 100))); + + EXPECT_EQ(gfx::Rect(6380, 200, 100, 100), + ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(3190, 100, 50, 50))); +} + TEST_F(ScreenWinTestTwoDisplays2x1xVirtualized, ClientToDIPRects) { HWND left_hwnd = GetLeftFakeHwnd(); EXPECT_EQ(gfx::Rect(0, 0, 25, 50), diff --git a/chromium/ui/display/win/uwp_text_scale_factor.cc b/chromium/ui/display/win/uwp_text_scale_factor.cc index 6d4cb4a1c8e..a5be273160b 100644 --- a/chromium/ui/display/win/uwp_text_scale_factor.cc +++ b/chromium/ui/display/win/uwp_text_scale_factor.cc @@ -11,6 +11,7 @@ #include <wrl/event.h> #include "base/lazy_instance.h" +#include "base/logging.h" #include "base/strings/string_piece.h" #include "base/threading/thread_checker.h" #include "base/win/core_winrt_util.h" |