Bug 1671490 - Mark the GPU process as being in the foreground whenever the parent process is in the foreground to make their priorities (and priority boosts) match, r=bas.

Differential Revision: https://phabricator.services.mozilla.com/D161065
This commit is contained in:
Florian Queze 2022-11-14 16:05:34 +00:00
parent a3430fcf97
commit ea6e6f4fa1
3 changed files with 72 additions and 0 deletions

View File

@ -466,6 +466,11 @@ void GPUProcessManager::OnProcessLaunchComplete(GPUProcessHost* aHost) {
mGPUChild = mProcess->GetActor();
mProcessToken = mProcess->GetProcessToken();
#if defined(XP_WIN)
if (mAppInForeground) {
SetProcessIsForeground();
}
#endif
ipc::Endpoint<PVsyncBridgeParent> vsyncParent;
ipc::Endpoint<PVsyncBridgeChild> vsyncChild;
@ -824,7 +829,11 @@ void GPUProcessManager::HandleProcessLost() {
// Except on Android if the app is in the background, where we want to wait
// until the app is in the foreground again.
if (gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
#ifdef MOZ_WIDGET_ANDROID
if (mAppInForeground) {
#else
{
#endif
Unused << LaunchGPUProcess();
}
} else {
@ -1393,6 +1402,57 @@ RefPtr<MemoryReportingProcess> GPUProcessManager::GetProcessMemoryReporter() {
return new GPUMemoryReporter();
}
void GPUProcessManager::SetAppInForeground(bool aInForeground) {
if (mAppInForeground == aInForeground) {
return;
}
mAppInForeground = aInForeground;
#if defined(XP_WIN)
SetProcessIsForeground();
#endif
}
#if defined(XP_WIN)
void GPUProcessManager::SetProcessIsForeground() {
NTSTATUS WINAPI NtSetInformationProcess(
IN HANDLE process_handle, IN ULONG info_class,
IN PVOID process_information, IN ULONG information_length);
constexpr unsigned int NtProcessInformationForeground = 25;
static bool alreadyInitialized = false;
static decltype(NtSetInformationProcess)* setInformationProcess = nullptr;
if (!alreadyInitialized) {
alreadyInitialized = true;
nsModuleHandle module(LoadLibrary(L"ntdll.dll"));
if (module) {
setInformationProcess =
(decltype(NtSetInformationProcess)*)GetProcAddress(
module, "NtSetInformationProcess");
}
}
if (MOZ_UNLIKELY(!setInformationProcess)) {
return;
}
unsigned pid = GPUProcessPid();
if (pid <= 0) {
return;
}
// Using the handle from mProcess->GetChildProcessHandle() fails;
// the PROCESS_SET_INFORMATION permission is probably missing.
nsAutoHandle processHandle(
::OpenProcess(PROCESS_SET_INFORMATION, FALSE, pid));
if (!processHandle) {
return;
}
BOOLEAN foreground = mAppInForeground;
setInformationProcess(processHandle, NtProcessInformationForeground,
(PVOID)&foreground, sizeof(foreground));
}
#endif
RefPtr<PGPUChild::TestTriggerMetricsPromise>
GPUProcessManager::TestTriggerMetrics() {
if (!NS_WARN_IF(!mGPUChild)) {

View File

@ -199,6 +199,10 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
// Returns the process host
GPUProcessHost* Process() { return mProcess; }
// Sets the value of mAppInForeground, and (on Windows) adjusts the priority
// of the GPU process accordingly.
void SetAppInForeground(bool aInForeground);
/*
* ** Test-only Method **
*
@ -285,6 +289,10 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
void EnsureImageBridgeChild();
void EnsureVRManager();
#if defined(XP_WIN)
void SetProcessIsForeground();
#endif
#if defined(MOZ_WIDGET_ANDROID)
already_AddRefed<UiCompositorControllerChild> CreateUiCompositorController(
nsBaseWidget* aWidget, const LayersId aId);

View File

@ -6194,6 +6194,10 @@ bool nsWindow::ProcessMessageInternal(UINT msg, WPARAM& wParam, LPARAM& lParam,
}
} break;
case WM_ACTIVATEAPP: {
GPUProcessManager::Get()->SetAppInForeground(wParam);
} break;
case WM_MOUSEACTIVATE:
// A popup with a parent owner should not be activated when clicked but
// should still allow the mouse event to be fired, so the return value