Bug 1767172 - Remove custom screen info handling from GfxInfo, use ScreenManager for that. r=jrmuizel,handyman,stransky

This removes a bunch of custom code from GfxInfo to obtain screen
information, and instead collects that screen information in
ScreenManager.

This, apart of removing duplicated code, has the extra benefit of
reporting multi-monitor information on GTK (and potentially in the
future reporting scale and refresh rate properly as well, I've kept the
telemetry as it was on that regard).

Differential Revision: https://phabricator.services.mozilla.com/D145178
This commit is contained in:
Emilio Cobos Álvarez
2022-05-05 15:07:03 +00:00
parent 89400bc676
commit 6d48fc3fcb
31 changed files with 285 additions and 836 deletions

View File

@@ -23,7 +23,6 @@
#include "mozilla/Observer.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsIScreenManager.h"
#include "nsTArray.h"
#include "nsXULAppAPI.h"
#include "nsIXULAppInfo.h"
@@ -34,6 +33,8 @@
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/widget/ScreenManager.h"
#include "mozilla/widget/Screen.h"
#include "gfxPlatform.h"
#include "gfxConfig.h"
@@ -773,14 +774,7 @@ void GfxInfoBase::GetData() {
return;
}
nsCOMPtr<nsIScreenManager> manager =
do_GetService("@mozilla.org/gfx/screenmanager;1");
if (!manager) {
MOZ_ASSERT_UNREACHABLE("failed to get nsIScreenManager");
return;
}
manager->GetTotalScreenPixels(&mScreenPixels);
ScreenManager::GetSingleton().GetTotalScreenPixels(&mScreenPixels);
}
NS_IMETHODIMP
@@ -1551,26 +1545,52 @@ void GfxInfoBase::RemoveCollector(GfxInfoCollectorBase* collector) {
}
}
nsresult GfxInfoBase::FindMonitors(JSContext* aCx, JS::HandleObject aOutArray) {
// If we have no platform specific implementation for detecting monitors, we
// can just get the screen size from gfxPlatform as the best guess.
if (!gfxPlatform::Initialized()) {
return NS_OK;
}
// If the screen size is empty, we are probably in xpcshell.
gfx::IntSize screenSize = gfxPlatform::GetPlatform()->GetScreenSize();
static void AppendMonitor(JSContext* aCx, widget::Screen& aScreen,
JS::HandleObject aOutArray, int32_t aIndex) {
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
auto screenSize = aScreen.GetRect().Size();
JS::Rooted<JS::Value> screenWidth(aCx, JS::Int32Value(screenSize.width));
JS_SetProperty(aCx, obj, "screenWidth", screenWidth);
JS::Rooted<JS::Value> screenHeight(aCx, JS::Int32Value(screenSize.height));
JS_SetProperty(aCx, obj, "screenHeight", screenHeight);
// XXX Just preserving behavior since this is exposed to telemetry, but we
// could consider including this everywhere.
#ifdef XP_MACOSX
JS::Rooted<JS::Value> scale(
aCx, JS::NumberValue(aScreen.GetContentsScaleFactor()));
JS_SetProperty(aCx, obj, "scale", scale);
#endif
#ifdef XP_WIN
JS::Rooted<JS::Value> refreshRate(aCx,
JS::Int32Value(aScreen.GetRefreshRate()));
JS_SetProperty(aCx, obj, "refreshRate", refreshRate);
JS::Rooted<JS::Value> pseudoDisplay(
aCx, JS::BooleanValue(aScreen.GetIsPseudoDisplay()));
JS_SetProperty(aCx, obj, "pseudoDisplay", pseudoDisplay);
#endif
JS::Rooted<JS::Value> element(aCx, JS::ObjectValue(*obj));
JS_SetElement(aCx, aOutArray, 0, element);
JS_SetElement(aCx, aOutArray, aIndex, element);
}
nsresult GfxInfoBase::FindMonitors(JSContext* aCx, JS::HandleObject aOutArray) {
int32_t index = 0;
auto& sm = ScreenManager::GetSingleton();
for (auto& screen : sm.CurrentScreenList()) {
AppendMonitor(aCx, *screen, aOutArray, index++);
}
if (index == 0) {
// Ensure we return at least one monitor, this is needed for xpcshell.
RefPtr<Screen> screen = sm.GetPrimaryScreen();
AppendMonitor(aCx, *screen, aOutArray, index++);
}
return NS_OK;
}
@@ -1588,9 +1608,6 @@ GfxInfoBase::GetMonitors(JSContext* aCx, JS::MutableHandleValue aResult) {
return NS_OK;
}
NS_IMETHODIMP
GfxInfoBase::RefreshMonitors() { return NS_ERROR_NOT_IMPLEMENTED; }
static inline bool SetJSPropertyString(JSContext* aCx,
JS::Handle<JSObject*> aObj,
const char* aProp, const char* aString) {
@@ -1903,6 +1920,24 @@ GfxInfoBase::GetUsingGPUProcess(bool* aOutValue) {
return NS_OK;
}
NS_IMETHODIMP_(int32_t)
GfxInfoBase::GetMaxRefreshRate(bool* aMixed) {
if (aMixed) {
*aMixed = false;
}
int32_t maxRefreshRate = 0;
for (auto& screen : ScreenManager::GetSingleton().CurrentScreenList()) {
int32_t refreshRate = screen->GetRefreshRate();
if (aMixed && maxRefreshRate > 0 && maxRefreshRate != refreshRate) {
*aMixed = true;
}
maxRefreshRate = std::max(maxRefreshRate, refreshRate);
}
return maxRefreshRate > 0 ? maxRefreshRate : -1;
}
NS_IMETHODIMP
GfxInfoBase::ControlGPUProcessForXPCShell(bool aEnable, bool* _retval) {
gfxPlatform::GetPlatform();