Bug 1578506 - Add better monitor information to about:support. r=aosmond

Differential Revision: https://phabricator.services.mozilla.com/D47110

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kris Taeleman 2019-10-03 23:43:35 +00:00
parent 7dc1b366fc
commit 3bd0cbdc09
14 changed files with 188 additions and 26 deletions

View File

@ -472,6 +472,7 @@ gfxPlatform::gfxPlatform()
mTilesInfoCollector(this, &gfxPlatform::GetTilesSupportInfo),
mFrameStatsCollector(this, &gfxPlatform::GetFrameStats),
mCMSInfoCollector(this, &gfxPlatform::GetCMSSupportInfo),
mDisplayInfoCollector(this, &gfxPlatform::GetDisplayInfo),
mCompositorBackend(layers::LayersBackend::LAYERS_NONE),
mScreenDepth(0),
mScreenPixels(0) {
@ -3456,6 +3457,22 @@ void gfxPlatform::GetCMSSupportInfo(mozilla::widget::InfoObject& aObj) {
free(profile);
}
void gfxPlatform::GetDisplayInfo(mozilla::widget::InfoObject& aObj) {
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
nsTArray<nsString> displayInfo;
auto rv = gfxInfo->GetDisplayInfo(displayInfo);
if (NS_SUCCEEDED(rv)) {
size_t displayCount = displayInfo.Length();
aObj.DefineProperty("DisplayCount", displayCount);
for (size_t i = 0; i < displayCount; i++) {
nsPrintfCString name("Display%zu", i);
aObj.DefineProperty(name.get(), displayInfo[i]);
}
}
}
class FrameStatsComparator {
public:
bool Equals(const FrameStats& aA, const FrameStats& aB) const {

View File

@ -282,6 +282,7 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
void GetTilesSupportInfo(mozilla::widget::InfoObject& aObj);
void GetFrameStats(mozilla::widget::InfoObject& aObj);
void GetCMSSupportInfo(mozilla::widget::InfoObject& aObj);
void GetDisplayInfo(mozilla::widget::InfoObject& aObj);
// Get the default content backend that will be used with the default
// compositor. If the compositor is known when calling this function,
@ -912,6 +913,7 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
mozilla::widget::GfxInfoCollector<gfxPlatform> mTilesInfoCollector;
mozilla::widget::GfxInfoCollector<gfxPlatform> mFrameStatsCollector;
mozilla::widget::GfxInfoCollector<gfxPlatform> mCMSInfoCollector;
mozilla::widget::GfxInfoCollector<gfxPlatform> mDisplayInfoCollector;
nsTArray<mozilla::layers::FrameStats> mFrameStats;

View File

@ -352,6 +352,30 @@ void glxtest() {
}
}
// Get monitor information
int screenCount = ScreenCount(dpy);
int defaultScreen = DefaultScreen(dpy);
if (screenCount != 0)
{
length += snprintf(buf + length, bufsize - length, "SCREEN_INFO\n");
if (length >= bufsize)
fatal_error("Screen Info strings length too large for buffer size");
for (int idx = 0; idx < screenCount; idx++)
{
Screen* scrn = ScreenOfDisplay(dpy, idx);
int current_height = scrn->height;
int current_width = scrn->width;
length += snprintf(buf + length, bufsize - length, "%dx%d%s%s",
current_width, current_height,
idx == defaultScreen ? " default" : "",
idx == screenCount -1 ? ";\n" : ";");
if (length >= bufsize)
fatal_error("Screen Info strings length too large for buffer size");
}
}
///// Clean up. Indeed, the parent process might fail to kill us (e.g. if it
///// doesn't need to check GL info) so we might be staying alive for longer
///// than expected, so it's important to consume as little memory as

View File

@ -131,6 +131,7 @@ void GfxInfo::GetData() {
nsCString mesaAccelerated;
// Available if using a DRI-based libGL stack.
nsCString driDriver;
nsCString screenInfo;
nsCString* stringToFill = nullptr;
char* bufptr = buf;
@ -159,6 +160,8 @@ void GfxInfo::GetData() {
stringToFill = &mAdapterRAM;
else if (!strcmp(line, "DRI_DRIVER"))
stringToFill = &driDriver;
else if (!strcmp(line, "SCREEN_INFO"))
stringToFill = &screenInfo;
}
}
@ -290,6 +293,21 @@ void GfxInfo::GetData() {
NS_WARNING("Failed to detect GL vendor!");
}
if (!screenInfo.IsEmpty()) {
PRInt32 start = 0;
PRInt32 loc = screenInfo.Find(";", PR_FALSE, start);
while (loc != kNotFound)
{
nsCString line(screenInfo.get() + start, loc - start);
nsString value;
CopyASCIItoUTF16(line, value);
mScreenInfo.AppendElement(value);
start = loc+1;
loc = screenInfo.Find(";", PR_FALSE, start);
}
}
// Fallback to GL_VENDOR and GL_RENDERER.
if (mVendorId.IsEmpty()) {
mVendorId.Assign(glVendor.get());
@ -584,6 +602,17 @@ GfxInfo::GetAdapterSubsysID2(nsAString& aAdapterSubsysID) {
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GfxInfo::GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) {
GetData();
if (!mScreenInfo.IsEmpty()){
aDisplayInfo = mScreenInfo;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) { return NS_ERROR_FAILURE; }

View File

@ -43,6 +43,7 @@ class GfxInfo final : public GfxInfoBase {
nsAString& aAdapterDriverVersion) override;
NS_IMETHOD GetAdapterDriverDate2(nsAString& aAdapterDriverDate) override;
NS_IMETHOD GetIsGPU2Active(bool* aIsGPU2Active) override;
NS_IMETHOD GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) override;
using GfxInfoBase::GetFeatureStatus;
using GfxInfoBase::GetFeatureSuggestedDriverVersion;
@ -76,6 +77,7 @@ class GfxInfo final : public GfxInfoBase {
nsCString mAdapterRAM;
nsCString mOS;
nsCString mOSRelease;
nsTArray<nsString> mScreenInfo;
bool mHasTextureFromPixmap;
unsigned int mGLMajorVersion, mGLMinorVersion;
bool mIsMesa;

View File

@ -16,6 +16,7 @@
#include <prthread.h>
#include "AndroidBridge.h"
#include "AndroidBridgeUtilities.h"
#include "AndroidRect.h"
#include "nsAlertsUtils.h"
#include "nsAppShell.h"
#include "nsOSHelperAppService.h"
@ -291,6 +292,16 @@ void AndroidBridge::GetExtensionFromMimeType(const nsACString& aMimeType,
}
}
gfx::Rect AndroidBridge::getScreenSize()
{
ALOG_BRIDGE("AndroidBridge::getScreenSize");
java::sdk::Rect::LocalRef screenrect = GeckoAppShell::GetScreenSize();
gfx::Rect screensize(screenrect->Left(), screenrect->Top(), screenrect->Width(), screenrect->Height());
return screensize;
}
int AndroidBridge::GetScreenDepth() {
ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);

View File

@ -113,6 +113,7 @@ class AndroidBridge final {
void GetExtensionFromMimeType(const nsACString& aMimeType,
nsACString& aFileExt);
gfx::Rect getScreenSize();
int GetScreenDepth();
void Vibrate(const nsTArray<uint32_t>& aPattern);

View File

@ -206,6 +206,8 @@ void GfxInfo::EnsureInitialized() {
AddCrashReportAnnotations();
mScreenInfo.mScreenDimensions = mozilla::AndroidBridge::Bridge()->getScreenSize();
mInitialized = true;
}
@ -331,6 +333,15 @@ GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) {
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
GfxInfo::GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) {
EnsureInitialized();
nsString displayInfo;
displayInfo.AppendPrintf("%dx%d", (int32_t)mScreenInfo.mScreenDimensions.width, (int32_t)mScreenInfo.mScreenDimensions.height);
aDisplayInfo.AppendElement(displayInfo);
return NS_OK;
}
void GfxInfo::AddCrashReportAnnotations() {
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
mGLStrings->Vendor());

View File

@ -52,6 +52,7 @@ class GfxInfo : public GfxInfoBase {
nsAString& aAdapterDriverVersion) override;
NS_IMETHOD GetAdapterDriverDate2(nsAString& aAdapterDriverDate) override;
NS_IMETHOD GetIsGPU2Active(bool* aIsGPU2Active) override;
NS_IMETHOD GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) override;
using GfxInfoBase::GetFeatureStatus;
using GfxInfoBase::GetFeatureSuggestedDriverVersion;
@ -76,6 +77,10 @@ class GfxInfo : public GfxInfoBase {
OperatingSystem* aOS = nullptr) override;
virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo() override;
private:
struct ScreenInfo {
gfx::Rect mScreenDimensions;
};
private:
void AddCrashReportAnnotations();
int32_t WebRtcHwEncodeSupported();
@ -94,6 +99,7 @@ class GfxInfo : public GfxInfoBase {
nsCString mOSVersion;
uint32_t mOSVersionInteger;
int32_t mSDKVersion;
ScreenInfo mScreenInfo;
};
} // namespace widget

View File

@ -45,6 +45,7 @@ class GfxInfo : public GfxInfoBase {
nsAString& aAdapterDriverVersion) override;
NS_IMETHOD GetAdapterDriverDate2(nsAString& aAdapterDriverDate) override;
NS_IMETHOD GetIsGPU2Active(bool* aIsGPU2Active) override;
NS_IMETHOD GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) override;
using GfxInfoBase::GetFeatureStatus;
using GfxInfoBase::GetFeatureSuggestedDriverVersion;

View File

@ -218,6 +218,23 @@ GfxInfo::GetAdapterSubsysID(nsAString& aAdapterSubsysID) { return NS_ERROR_FAILU
NS_IMETHODIMP
GfxInfo::GetAdapterSubsysID2(nsAString& aAdapterSubsysID) { return NS_ERROR_FAILURE; }
/* readonly attribute Array<DOMString> displayInfo; */
NS_IMETHODIMP
GfxInfo::GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) {
for (NSScreen* screen in [NSScreen screens]) {
NSRect rect = [screen frame];
nsString desc;
desc.AppendPrintf(
"%dx%d scale:%f",
(int32_t)rect.size.width, (int32_t)rect.size.height,
nsCocoaUtils::GetBackingScaleFactor(screen)
);
aDisplayInfo.AppendElement(desc);
}
return NS_OK;
}
/* readonly attribute boolean isGPU2Active; */
NS_IMETHODIMP
GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) { return NS_ERROR_FAILURE; }

View File

@ -74,6 +74,11 @@ interface nsIGfxInfo : nsISupports
readonly attribute boolean isGPU2Active;
/**
* Information about display devices
*/
readonly attribute Array<AString> displayInfo;
/**
* Returns an array of objects describing each monitor. Guaranteed properties
* are "screenWidth" and "screenHeight". This is only implemented on Desktop.

View File

@ -704,6 +704,37 @@ nsresult GfxInfo::Init() {
}
}
// Get monitor information
for (int deviceIndex = 0;; deviceIndex++) {
DISPLAY_DEVICEA device;
device.cb = sizeof(device);
if (!::EnumDisplayDevicesA(nullptr, deviceIndex, &device, 0)) {
break;
}
if (!(device.StateFlags & DISPLAY_DEVICE_ACTIVE)) {
continue;
}
DEVMODEA mode;
mode.dmSize = sizeof(mode);
mode.dmDriverExtra = 0;
if (!::EnumDisplaySettingsA(device.DeviceName, ENUM_CURRENT_SETTINGS,
&mode)) {
continue;
}
DisplayInfo displayInfo;
displayInfo.mScreenWidth = mode.dmPelsWidth;
displayInfo.mScreenHeight = mode.dmPelsHeight;
displayInfo.mRefreshRate = mode.dmDisplayFrequency;
displayInfo.mIsPseudoDisplay =
!!(device.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER);
mDisplayInfo.AppendElement(displayInfo);
}
const char* spoofedDriverVersionString =
PR_GetEnv("MOZ_GFX_SPOOF_DRIVER_VERSION");
if (spoofedDriverVersionString) {
@ -870,6 +901,22 @@ GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) {
return NS_OK;
}
NS_IMETHODIMP
GfxInfo::GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) {
for (auto displayInfo : mDisplayInfo) {
nsString value;
value.AppendPrintf(
"%dx%d@%dHz %s",
displayInfo.mScreenWidth, displayInfo.mScreenHeight,
displayInfo.mRefreshRate, displayInfo.mIsPseudoDisplay ? "Pseudo Display" : ""
);
aDisplayInfo.AppendElement(value);
}
return NS_OK;
}
/* Cisco's VPN software can cause corruption of the floating point state.
* Make a note of this in our crash reports so that some weird crashes
* make more sense */
@ -1803,40 +1850,19 @@ nsresult GfxInfo::GetFeatureStatusImpl(
nsresult GfxInfo::FindMonitors(JSContext* aCx, JS::HandleObject aOutArray) {
int deviceCount = 0;
for (int deviceIndex = 0;; deviceIndex++) {
DISPLAY_DEVICEA device;
device.cb = sizeof(device);
if (!::EnumDisplayDevicesA(nullptr, deviceIndex, &device, 0)) {
break;
}
if (!(device.StateFlags & DISPLAY_DEVICE_ACTIVE)) {
continue;
}
DEVMODEA mode;
mode.dmSize = sizeof(mode);
mode.dmDriverExtra = 0;
if (!::EnumDisplaySettingsA(device.DeviceName, ENUM_CURRENT_SETTINGS,
&mode)) {
continue;
}
for (auto displayInfo : mDisplayInfo) {
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
JS::Rooted<JS::Value> screenWidth(aCx, JS::Int32Value(mode.dmPelsWidth));
JS::Rooted<JS::Value> screenWidth(aCx, JS::Int32Value(displayInfo.mScreenWidth));
JS_SetProperty(aCx, obj, "screenWidth", screenWidth);
JS::Rooted<JS::Value> screenHeight(aCx, JS::Int32Value(mode.dmPelsHeight));
JS::Rooted<JS::Value> screenHeight(aCx, JS::Int32Value(displayInfo.mScreenHeight));
JS_SetProperty(aCx, obj, "screenHeight", screenHeight);
JS::Rooted<JS::Value> refreshRate(aCx,
JS::Int32Value(mode.dmDisplayFrequency));
JS::Rooted<JS::Value> refreshRate(aCx, JS::Int32Value(displayInfo.mRefreshRate));
JS_SetProperty(aCx, obj, "refreshRate", refreshRate);
JS::Rooted<JS::Value> pseudoDisplay(
aCx, JS::BooleanValue(
!!(device.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)));
JS::Rooted<JS::Value> pseudoDisplay(aCx, JS::BooleanValue(displayInfo.mIsPseudoDisplay));
JS_SetProperty(aCx, obj, "pseudoDisplay", pseudoDisplay);
JS::Rooted<JS::Value> element(aCx, JS::ObjectValue(*obj));

View File

@ -46,6 +46,7 @@ class GfxInfo : public GfxInfoBase {
nsAString& aAdapterDriverVersion) override;
NS_IMETHOD GetAdapterDriverDate2(nsAString& aAdapterDriverDate) override;
NS_IMETHOD GetIsGPU2Active(bool* aIsGPU2Active) override;
NS_IMETHOD GetDisplayInfo(nsTArray<nsString>& aDisplayInfo) override;
using GfxInfoBase::GetFeatureStatus;
using GfxInfoBase::GetFeatureSuggestedDriverVersion;
@ -69,6 +70,14 @@ class GfxInfo : public GfxInfoBase {
void DescribeFeatures(JSContext* cx, JS::Handle<JSObject*> aOut) override;
private:
struct DisplayInfo {
uint32_t mScreenWidth;
uint32_t mScreenHeight;
uint32_t mRefreshRate;
bool mIsPseudoDisplay;
};
private:
void AddCrashReportAnnotations();
@ -83,6 +92,7 @@ class GfxInfo : public GfxInfoBase {
nsString mAdapterSubsysID[2];
uint32_t mWindowsVersion;
uint32_t mActiveGPUIndex; // This must be 0 or 1
nsTArray<DisplayInfo> mDisplayInfo;
bool mHasDualGPU;
bool mHasDriverVersionMismatch;
};