Commit 6f76eb65 authored by Maggie Chen's avatar Maggie Chen Committed by Commit Bot

Add display refresh rate to about://gpu on Windows

Some gpu bugs are related to the monitor refresh rate. Adding this display
information will help us on gpu debugging.

This CL is for Windows only.

Bug: 964095
Change-Id: Ic00471897f0f7c655dbe29e3b33b5b7782cab6b3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1621328Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarRobert Liao <robliao@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Commit-Queue: Maggie Chen <magchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#662910}
parent 4e3e4693
...@@ -383,6 +383,11 @@ std::unique_ptr<base::ListValue> getDisplayInfo() { ...@@ -383,6 +383,11 @@ std::unique_ptr<base::ListValue> getDisplayInfo() {
base::NumberToString(display.depth_per_component()))); base::NumberToString(display.depth_per_component())));
display_info->Append(NewDescriptionValuePair( display_info->Append(NewDescriptionValuePair(
"Bits per pixel", base::NumberToString(display.color_depth()))); "Bits per pixel", base::NumberToString(display.color_depth())));
if (display.display_frequency()) {
display_info->Append(NewDescriptionValuePair(
"Refresh Rate in Hz",
base::NumberToString(display.display_frequency())));
}
} }
return display_info; return display_info;
} }
......
...@@ -24,6 +24,7 @@ void DisplayUtil::DisplayToScreenInfo(ScreenInfo* screen_info, ...@@ -24,6 +24,7 @@ void DisplayUtil::DisplayToScreenInfo(ScreenInfo* screen_info,
screen_info->depth = display.color_depth(); screen_info->depth = display.color_depth();
screen_info->depth_per_component = display.depth_per_component(); screen_info->depth_per_component = display.depth_per_component();
screen_info->is_monochrome = display.is_monochrome(); screen_info->is_monochrome = display.is_monochrome();
screen_info->display_frequency = display.display_frequency();
screen_info->orientation_angle = display.RotationAsDegree(); screen_info->orientation_angle = display.RotationAsDegree();
#if defined(USE_AURA) #if defined(USE_AURA)
......
...@@ -356,6 +356,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::ScreenInfo) ...@@ -356,6 +356,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::ScreenInfo)
IPC_STRUCT_TRAITS_MEMBER(depth) IPC_STRUCT_TRAITS_MEMBER(depth)
IPC_STRUCT_TRAITS_MEMBER(depth_per_component) IPC_STRUCT_TRAITS_MEMBER(depth_per_component)
IPC_STRUCT_TRAITS_MEMBER(is_monochrome) IPC_STRUCT_TRAITS_MEMBER(is_monochrome)
IPC_STRUCT_TRAITS_MEMBER(display_frequency)
IPC_STRUCT_TRAITS_MEMBER(rect) IPC_STRUCT_TRAITS_MEMBER(rect)
IPC_STRUCT_TRAITS_MEMBER(available_rect) IPC_STRUCT_TRAITS_MEMBER(available_rect)
IPC_STRUCT_TRAITS_MEMBER(orientation_type) IPC_STRUCT_TRAITS_MEMBER(orientation_type)
......
...@@ -14,7 +14,8 @@ bool ScreenInfo::operator==(const ScreenInfo& other) const { ...@@ -14,7 +14,8 @@ bool ScreenInfo::operator==(const ScreenInfo& other) const {
return device_scale_factor == other.device_scale_factor && return device_scale_factor == other.device_scale_factor &&
color_space == other.color_space && depth == other.depth && color_space == other.color_space && depth == other.depth &&
depth_per_component == other.depth_per_component && depth_per_component == other.depth_per_component &&
is_monochrome == other.is_monochrome && rect == other.rect && is_monochrome == other.is_monochrome &&
display_frequency == other.display_frequency && rect == other.rect &&
available_rect == other.available_rect && available_rect == other.available_rect &&
orientation_type == other.orientation_type && orientation_type == other.orientation_type &&
orientation_angle == other.orientation_angle; orientation_angle == other.orientation_angle;
......
...@@ -38,6 +38,10 @@ struct CONTENT_EXPORT ScreenInfo { ...@@ -38,6 +38,10 @@ struct CONTENT_EXPORT ScreenInfo {
// This can be true for black and white printers // This can be true for black and white printers
bool is_monochrome = false; bool is_monochrome = false;
// The display frequency in Hz of the monitor. Set to 0 if it fails in the
// monitor frequency query.
int display_frequency = 0;
// The display monitor rectangle in virtual-screen coordinates. Note that // The display monitor rectangle in virtual-screen coordinates. Note that
// this may be negative. // this may be negative.
gfx::Rect rect; gfx::Rect rect;
......
...@@ -366,7 +366,8 @@ bool Display::operator==(const Display& rhs) const { ...@@ -366,7 +366,8 @@ bool Display::operator==(const Display& rhs) const {
maximum_cursor_size_ == rhs.maximum_cursor_size_ && maximum_cursor_size_ == rhs.maximum_cursor_size_ &&
color_space_ == rhs.color_space_ && color_depth_ == rhs.color_depth_ && color_space_ == rhs.color_space_ && color_depth_ == rhs.color_depth_ &&
depth_per_component_ == rhs.depth_per_component_ && depth_per_component_ == rhs.depth_per_component_ &&
is_monochrome_ == rhs.is_monochrome_; is_monochrome_ == rhs.is_monochrome_ &&
display_frequency_ == rhs.display_frequency_;
} }
} // namespace display } // namespace display
...@@ -255,6 +255,12 @@ class DISPLAY_EXPORT Display final { ...@@ -255,6 +255,12 @@ class DISPLAY_EXPORT Display final {
bool is_monochrome() const { return is_monochrome_; } bool is_monochrome() const { return is_monochrome_; }
void set_is_monochrome(bool is_monochrome) { is_monochrome_ = is_monochrome; } void set_is_monochrome(bool is_monochrome) { is_monochrome_ = is_monochrome; }
// The display frequency of the monitor.
int display_frequency() const { return display_frequency_; }
void set_display_frequency(int display_frequency) {
display_frequency_ = display_frequency;
}
bool operator==(const Display& rhs) const; bool operator==(const Display& rhs) const;
bool operator!=(const Display& rhs) const { return !(*this == rhs); } bool operator!=(const Display& rhs) const { return !(*this == rhs); }
...@@ -279,6 +285,7 @@ class DISPLAY_EXPORT Display final { ...@@ -279,6 +285,7 @@ class DISPLAY_EXPORT Display final {
int color_depth_; int color_depth_;
int depth_per_component_; int depth_per_component_;
bool is_monochrome_ = false; bool is_monochrome_ = false;
int display_frequency_ = 0;
}; };
} // namespace display } // namespace display
......
...@@ -90,4 +90,14 @@ TEST(DisplayTest, DisplayHDRValues) { ...@@ -90,4 +90,14 @@ TEST(DisplayTest, DisplayHDRValues) {
EXPECT_EQ(8, display.depth_per_component()); EXPECT_EQ(8, display.depth_per_component());
} }
TEST(DisplayTest, DisplayFrequency) {
Display display(0, gfx::Rect(0, 0, 100, 100));
display.set_display_frequency(60);
EXPECT_EQ(60, display.display_frequency());
display.set_display_frequency(120);
EXPECT_EQ(120, display.display_frequency());
}
} // namespace display } // namespace display
...@@ -42,4 +42,5 @@ struct Display { ...@@ -42,4 +42,5 @@ struct Display {
int32 color_depth; int32 color_depth;
int32 depth_per_component; int32 depth_per_component;
bool is_monochrome; bool is_monochrome;
int32 display_frequency;
}; };
...@@ -143,6 +143,7 @@ bool StructTraits<display::mojom::DisplayDataView, display::Display>::Read( ...@@ -143,6 +143,7 @@ bool StructTraits<display::mojom::DisplayDataView, display::Display>::Read(
out->set_color_depth(data.color_depth()); out->set_color_depth(data.color_depth());
out->set_depth_per_component(data.depth_per_component()); out->set_depth_per_component(data.depth_per_component());
out->set_is_monochrome(data.is_monochrome()); out->set_is_monochrome(data.is_monochrome());
out->set_display_frequency(data.display_frequency());
return true; return true;
} }
......
...@@ -86,6 +86,10 @@ struct StructTraits<display::mojom::DisplayDataView, display::Display> { ...@@ -86,6 +86,10 @@ struct StructTraits<display::mojom::DisplayDataView, display::Display> {
return display.is_monochrome(); return display.is_monochrome();
} }
static int32_t display_frequency(const display::Display& display) {
return display.display_frequency();
}
static bool Read(display::mojom::DisplayDataView data, display::Display* out); static bool Read(display::mojom::DisplayDataView data, display::Display* out);
}; };
......
...@@ -46,6 +46,7 @@ void CheckDisplaysEqual(const Display& input, const Display& output) { ...@@ -46,6 +46,7 @@ void CheckDisplaysEqual(const Display& input, const Display& output) {
EXPECT_EQ(input.color_depth(), output.color_depth()); EXPECT_EQ(input.color_depth(), output.color_depth());
EXPECT_EQ(input.depth_per_component(), output.depth_per_component()); EXPECT_EQ(input.depth_per_component(), output.depth_per_component());
EXPECT_EQ(input.is_monochrome(), output.is_monochrome()); EXPECT_EQ(input.is_monochrome(), output.is_monochrome());
EXPECT_EQ(input.display_frequency(), output.display_frequency());
} }
void CheckDisplayLayoutsEqual(const DisplayLayout& input, void CheckDisplayLayoutsEqual(const DisplayLayout& input,
...@@ -140,6 +141,7 @@ TEST(DisplayStructTraitsTest, SetAllDisplayValues) { ...@@ -140,6 +141,7 @@ TEST(DisplayStructTraitsTest, SetAllDisplayValues) {
input.set_color_depth(input.color_depth() + 1); input.set_color_depth(input.color_depth() + 1);
input.set_depth_per_component(input.depth_per_component() + 1); input.set_depth_per_component(input.depth_per_component() + 1);
input.set_is_monochrome(!input.is_monochrome()); input.set_is_monochrome(!input.is_monochrome());
input.set_display_frequency(input.display_frequency() + 1);
Display output; Display output;
SerializeAndDeserialize<mojom::Display>(input, &output); SerializeAndDeserialize<mojom::Display>(input, &output);
......
...@@ -8,52 +8,22 @@ ...@@ -8,52 +8,22 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
namespace display { namespace display {
namespace {
Display::Rotation GetRotationForDevice(const wchar_t* device_name) {
DEVMODE mode;
::ZeroMemory(&mode, sizeof(mode));
mode.dmSize = sizeof(mode);
mode.dmDriverExtra = 0;
if (::EnumDisplaySettings(device_name, ENUM_CURRENT_SETTINGS, &mode)) {
switch (mode.dmDisplayOrientation) {
case DMDO_DEFAULT:
return Display::ROTATE_0;
case DMDO_90:
return Display::ROTATE_90;
case DMDO_180:
return Display::ROTATE_180;
case DMDO_270:
return Display::ROTATE_270;
default:
NOTREACHED();
}
}
return Display::ROTATE_0;
}
} // namespace
namespace win { namespace win {
DisplayInfo::DisplayInfo(const MONITORINFOEX& monitor_info,
float device_scale_factor,
float sdr_white_level)
: DisplayInfo(monitor_info,
device_scale_factor,
sdr_white_level,
GetRotationForDevice(monitor_info.szDevice)) {}
DisplayInfo::DisplayInfo(const MONITORINFOEX& monitor_info, DisplayInfo::DisplayInfo(const MONITORINFOEX& monitor_info,
float device_scale_factor, float device_scale_factor,
float sdr_white_level, float sdr_white_level,
Display::Rotation rotation) Display::Rotation rotation,
int display_frequency)
: id_(DeviceIdFromDeviceName(monitor_info.szDevice)), : id_(DeviceIdFromDeviceName(monitor_info.szDevice)),
rotation_(rotation), rotation_(rotation),
screen_rect_(monitor_info.rcMonitor), screen_rect_(monitor_info.rcMonitor),
screen_work_rect_(monitor_info.rcWork), screen_work_rect_(monitor_info.rcWork),
device_scale_factor_(device_scale_factor), device_scale_factor_(device_scale_factor),
sdr_white_level_(sdr_white_level) {} sdr_white_level_(sdr_white_level),
display_frequency_(display_frequency) {}
DisplayInfo::~DisplayInfo() = default;
// static // static
int64_t DisplayInfo::DeviceIdFromDeviceName(const wchar_t* device_name) { int64_t DisplayInfo::DeviceIdFromDeviceName(const wchar_t* device_name) {
......
...@@ -17,13 +17,12 @@ namespace win { ...@@ -17,13 +17,12 @@ namespace win {
// Gathers the parameters necessary to create a win::ScreenWinDisplay. // Gathers the parameters necessary to create a win::ScreenWinDisplay.
class DISPLAY_EXPORT DisplayInfo final { class DISPLAY_EXPORT DisplayInfo final {
public: public:
DisplayInfo(const MONITORINFOEX& monitor_info,
float device_scale_factor,
float sdr_white_level);
DisplayInfo(const MONITORINFOEX& monitor_info, DisplayInfo(const MONITORINFOEX& monitor_info,
float device_scale_factor, float device_scale_factor,
float sdr_white_level, float sdr_white_level,
Display::Rotation rotation); Display::Rotation rotation,
int display_frequency);
~DisplayInfo();
static int64_t DeviceIdFromDeviceName(const wchar_t* device_name); static int64_t DeviceIdFromDeviceName(const wchar_t* device_name);
...@@ -33,6 +32,7 @@ class DISPLAY_EXPORT DisplayInfo final { ...@@ -33,6 +32,7 @@ class DISPLAY_EXPORT DisplayInfo final {
const gfx::Rect& screen_work_rect() const { return screen_work_rect_; } const gfx::Rect& screen_work_rect() const { return screen_work_rect_; }
float device_scale_factor() const { return device_scale_factor_; } float device_scale_factor() const { return device_scale_factor_; }
float sdr_white_level() const { return sdr_white_level_; } float sdr_white_level() const { return sdr_white_level_; }
int display_frequency() const { return display_frequency_; }
private: private:
int64_t id_; int64_t id_;
...@@ -41,6 +41,7 @@ class DISPLAY_EXPORT DisplayInfo final { ...@@ -41,6 +41,7 @@ class DISPLAY_EXPORT DisplayInfo final {
gfx::Rect screen_work_rect_; gfx::Rect screen_work_rect_;
float device_scale_factor_; float device_scale_factor_;
float sdr_white_level_; float sdr_white_level_;
int display_frequency_;
}; };
} // namespace win } // namespace win
......
...@@ -20,7 +20,7 @@ DisplayInfo CreateDisplayInfo(int x, int y, int width, int height, ...@@ -20,7 +20,7 @@ DisplayInfo CreateDisplayInfo(int x, int y, int width, int height,
MONITORINFOEX monitor_info = CreateMonitorInfo(gfx::Rect(x, y, width, height), MONITORINFOEX monitor_info = CreateMonitorInfo(gfx::Rect(x, y, width, height),
gfx::Rect(x, y, width, height), gfx::Rect(x, y, width, height),
kFakeDisplayName); kFakeDisplayName);
return DisplayInfo(monitor_info, scale_factor, 1.0f); return DisplayInfo(monitor_info, scale_factor, 1.0f, Display::ROTATE_0, 60);
} }
::testing::AssertionResult AssertOffsetsEqual( ::testing::AssertionResult AssertOffsetsEqual(
......
...@@ -152,6 +152,34 @@ float GetMonitorSDRWhiteLevel(HMONITOR monitor) { ...@@ -152,6 +152,34 @@ float GetMonitorSDRWhiteLevel(HMONITOR monitor) {
return ret; return ret;
} }
void GetDisplaySettingsForDevice(const wchar_t* device_name,
Display::Rotation* rotation,
int* frequency) {
*rotation = Display::ROTATE_0;
*frequency = 0;
DEVMODE mode = {};
mode.dmSize = sizeof(mode);
if (::EnumDisplaySettings(device_name, ENUM_CURRENT_SETTINGS, &mode)) {
switch (mode.dmDisplayOrientation) {
case DMDO_DEFAULT:
*rotation = Display::ROTATE_0;
break;
case DMDO_90:
*rotation = Display::ROTATE_90;
break;
case DMDO_180:
*rotation = Display::ROTATE_180;
break;
case DMDO_270:
*rotation = Display::ROTATE_270;
break;
default:
NOTREACHED();
}
*frequency = mode.dmDisplayFrequency;
}
}
std::vector<DisplayInfo> FindAndRemoveTouchingDisplayInfos( std::vector<DisplayInfo> FindAndRemoveTouchingDisplayInfos(
const DisplayInfo& ref_display_info, const DisplayInfo& ref_display_info,
std::vector<DisplayInfo>* display_infos) { std::vector<DisplayInfo>* display_infos) {
...@@ -179,6 +207,7 @@ Display CreateDisplayFromDisplayInfo(const DisplayInfo& display_info, ...@@ -179,6 +207,7 @@ Display CreateDisplayFromDisplayInfo(const DisplayInfo& display_info,
display.set_bounds(gfx::ScaleToEnclosingRect(display_info.screen_rect(), display.set_bounds(gfx::ScaleToEnclosingRect(display_info.screen_rect(),
1.0f / scale_factor)); 1.0f / scale_factor));
display.set_rotation(display_info.rotation()); display.set_rotation(display_info.rotation());
display.set_display_frequency(display_info.display_frequency());
if (!Display::HasForceDisplayColorProfile()) { if (!Display::HasForceDisplayColorProfile()) {
if (hdr_enabled) { if (hdr_enabled) {
// It doesn't matter what HDR color space we set since UI compositor will // It doesn't matter what HDR color space we set since UI compositor will
...@@ -266,8 +295,7 @@ std::vector<Display> ScreenWinDisplaysToDisplays( ...@@ -266,8 +295,7 @@ std::vector<Display> ScreenWinDisplaysToDisplays(
} }
MONITORINFOEX MonitorInfoFromHMONITOR(HMONITOR monitor) { MONITORINFOEX MonitorInfoFromHMONITOR(HMONITOR monitor) {
MONITORINFOEX monitor_info; MONITORINFOEX monitor_info = {};
::ZeroMemory(&monitor_info, sizeof(monitor_info));
monitor_info.cbSize = sizeof(monitor_info); monitor_info.cbSize = sizeof(monitor_info);
::GetMonitorInfo(monitor, &monitor_info); ::GetMonitorInfo(monitor, &monitor_info);
return monitor_info; return monitor_info;
...@@ -280,9 +308,15 @@ BOOL CALLBACK EnumMonitorForDisplayInfoCallback(HMONITOR monitor, ...@@ -280,9 +308,15 @@ BOOL CALLBACK EnumMonitorForDisplayInfoCallback(HMONITOR monitor,
std::vector<DisplayInfo>* display_infos = std::vector<DisplayInfo>* display_infos =
reinterpret_cast<std::vector<DisplayInfo>*>(data); reinterpret_cast<std::vector<DisplayInfo>*>(data);
DCHECK(display_infos); DCHECK(display_infos);
display_infos->push_back(DisplayInfo(MonitorInfoFromHMONITOR(monitor),
GetMonitorScaleFactor(monitor), Display::Rotation rotation;
GetMonitorSDRWhiteLevel(monitor))); int display_frequency;
MONITORINFOEX monitor_info = MonitorInfoFromHMONITOR(monitor);
GetDisplaySettingsForDevice(monitor_info.szDevice, &rotation,
&display_frequency);
display_infos->push_back(DisplayInfo(
monitor_info, GetMonitorScaleFactor(monitor),
GetMonitorSDRWhiteLevel(monitor), rotation, display_frequency));
return TRUE; return TRUE;
} }
......
...@@ -21,6 +21,7 @@ Display CreateDisplayFromDisplayInfo(const DisplayInfo& display_info) { ...@@ -21,6 +21,7 @@ Display CreateDisplayFromDisplayInfo(const DisplayInfo& display_info) {
display.set_bounds(gfx::ScaleToEnclosingRect(display_info.screen_rect(), display.set_bounds(gfx::ScaleToEnclosingRect(display_info.screen_rect(),
1.0f / scale_factor)); 1.0f / scale_factor));
display.set_rotation(display_info.rotation()); display.set_rotation(display_info.rotation());
display.set_display_frequency(display_info.display_frequency());
return display; return display;
} }
......
...@@ -157,7 +157,7 @@ class TestScreenWinManager final : public TestScreenWinInitializer { ...@@ -157,7 +157,7 @@ class TestScreenWinManager final : public TestScreenWinInitializer {
win::test::CreateMonitorInfo(pixel_bounds, pixel_work, device_name); win::test::CreateMonitorInfo(pixel_bounds, pixel_work, device_name);
monitor_infos_.push_back(monitor_info); monitor_infos_.push_back(monitor_info);
display_infos_.push_back(DisplayInfo(monitor_info, device_scale_factor, display_infos_.push_back(DisplayInfo(monitor_info, device_scale_factor,
Display::ROTATE_0)); 1.0f, Display::ROTATE_0, 60));
} }
HWND CreateFakeHwnd(const gfx::Rect& bounds) override { HWND CreateFakeHwnd(const gfx::Rect& bounds) override {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment