mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
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:
parent
7dc1b366fc
commit
3bd0cbdc09
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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__);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user