diff --git a/gfx/vr/ipc/PVR.ipdl b/gfx/vr/ipc/PVR.ipdl index 52ccfdb61bca..e81a2851d64c 100644 --- a/gfx/vr/ipc/PVR.ipdl +++ b/gfx/vr/ipc/PVR.ipdl @@ -9,6 +9,7 @@ using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h"; include "VRMessageUtils.h"; include GraphicsMessages; +include MemoryReportTypes; include protocol PVRGPU; include "VRMessageUtils.h"; @@ -27,7 +28,10 @@ parent: async UpdateVar(GfxVarUpdate var); async OpenVRControllerActionPathToVR(nsCString aPath); async OpenVRControllerManifestPathToVR(OpenVRControllerType aType, nsCString aPath); - + async RequestMemoryReport(uint32_t generation, + bool anonymize, + bool minimizeMemoryUsage, + FileDescriptor? DMDFile); child: // Sent when the GPU process has initialized devices. This occurs once, after // Init(). @@ -35,6 +39,8 @@ child: async OpenVRControllerActionPathToParent(nsCString aPath); async OpenVRControllerManifestPathToParent(OpenVRControllerType aType, nsCString aPath); async InitCrashReporter(Shmem shmem, NativeThreadId threadId); + async AddMemoryReport(MemoryReport aReport); + async FinishMemoryReport(uint32_t aGeneration); }; } // namespace gfx diff --git a/gfx/vr/ipc/VRChild.cpp b/gfx/vr/ipc/VRChild.cpp index 97982de34708..aaf00a6045a5 100644 --- a/gfx/vr/ipc/VRChild.cpp +++ b/gfx/vr/ipc/VRChild.cpp @@ -12,6 +12,7 @@ #include "mozilla/SystemGroup.h" #include "mozilla/Telemetry.h" #include "mozilla/VsyncDispatcher.h" +#include "mozilla/dom/MemoryReportRequest.h" #include "mozilla/ipc/CrashReporterHost.h" namespace mozilla { @@ -66,10 +67,29 @@ class OpenVRControllerManifestManager { StaticRefPtr sOpenVRControllerManifestManager; -VRChild::VRChild(VRProcessParent* aHost) : mHost(aHost) { +VRChild::VRChild(VRProcessParent* aHost) + : mHost(aHost), + mVRReady(false) { MOZ_ASSERT(XRE_IsParentProcess()); } +mozilla::ipc::IPCResult VRChild::RecvAddMemoryReport( + const MemoryReport& aReport) { + if (mMemoryReportRequest) { + mMemoryReportRequest->RecvReport(aReport); + } + return IPC_OK(); +} + +mozilla::ipc::IPCResult VRChild::RecvFinishMemoryReport( + const uint32_t& aGeneration) { + if (mMemoryReportRequest) { + mMemoryReportRequest->Finish(aGeneration); + mMemoryReportRequest = nullptr; + } + return IPC_OK(); +} + void VRChild::ActorDestroy(ActorDestroyReason aWhy) { if (aWhy == AbnormalShutdown) { if (mCrashReporter) { @@ -144,6 +164,14 @@ void VRChild::Init() { gfxVars::AddReceiver(this); } +bool VRChild::EnsureVRReady() { + if (!mVRReady) { + return false; + } + + return true; +} + mozilla::ipc::IPCResult VRChild::RecvOpenVRControllerActionPathToParent( const nsCString& aPath) { sOpenVRControllerManifestManager->SetOpenVRControllerActionPath(aPath); @@ -157,6 +185,12 @@ mozilla::ipc::IPCResult VRChild::RecvOpenVRControllerManifestPathToParent( return IPC_OK(); } +mozilla::ipc::IPCResult VRChild::RecvInitComplete() { + // We synchronously requested VR parameters before this arrived. + mVRReady = true; + return IPC_OK(); +} + mozilla::ipc::IPCResult VRChild::RecvInitCrashReporter( Shmem&& aShmem, const NativeThreadId& aThreadId) { mCrashReporter = MakeUnique(GeckoProcessType_VR, @@ -165,6 +199,16 @@ mozilla::ipc::IPCResult VRChild::RecvInitCrashReporter( return IPC_OK(); } +bool VRChild::SendRequestMemoryReport(const uint32_t& aGeneration, + const bool& aAnonymize, + const bool& aMinimizeMemoryUsage, + const Maybe& aDMDFile) { + mMemoryReportRequest = MakeUnique(aGeneration); + Unused << PVRChild::SendRequestMemoryReport(aGeneration, aAnonymize, + aMinimizeMemoryUsage, aDMDFile); + return true; +} + void VRChild::OnVarChanged(const GfxVarUpdate& aVar) { SendUpdateVar(aVar); } class DeferredDeleteVRChild : public Runnable { diff --git a/gfx/vr/ipc/VRChild.h b/gfx/vr/ipc/VRChild.h index 7e7e2a5ff8e1..2396abea2aca 100644 --- a/gfx/vr/ipc/VRChild.h +++ b/gfx/vr/ipc/VRChild.h @@ -16,12 +16,16 @@ namespace mozilla { namespace ipc { class CrashReporterHost; } // namespace ipc +namespace dom { +class MemoryReportRequestHost; +} // namespace dom namespace gfx { class VRProcessParent; class VRChild; class VRChild final : public PVRChild, public gfxVarReceiver { + typedef mozilla::dom::MemoryReportRequestHost MemoryReportRequestHost; friend class PVRChild; public: @@ -32,6 +36,10 @@ class VRChild final : public PVRChild, public gfxVarReceiver { void Init(); bool EnsureVRReady(); virtual void OnVarChanged(const GfxVarUpdate& aVar) override; + bool SendRequestMemoryReport(const uint32_t& aGeneration, + const bool& aAnonymize, + const bool& aMinimizeMemoryUsage, + const Maybe& aDMDFile); protected: virtual void ActorDestroy(ActorDestroyReason aWhy) override; @@ -43,9 +51,13 @@ class VRChild final : public PVRChild, public gfxVarReceiver { mozilla::ipc::IPCResult RecvInitCrashReporter( Shmem&& shmem, const NativeThreadId& aThreadId); + mozilla::ipc::IPCResult RecvAddMemoryReport(const MemoryReport& aReport); + mozilla::ipc::IPCResult RecvFinishMemoryReport(const uint32_t& aGeneration); + private: VRProcessParent* mHost; UniquePtr mCrashReporter; + UniquePtr mMemoryReportRequest; bool mVRReady; }; diff --git a/gfx/vr/ipc/VRParent.cpp b/gfx/vr/ipc/VRParent.cpp index 08266462ccc5..1401b94abd55 100644 --- a/gfx/vr/ipc/VRParent.cpp +++ b/gfx/vr/ipc/VRParent.cpp @@ -9,12 +9,14 @@ #include "VRManager.h" #include "gfxConfig.h" #include "nsDebugImpl.h" +#include "ProcessUtils.h" #include "mozilla/gfx/gfxVars.h" #include "mozilla/ipc/CrashReporterClient.h" #include "mozilla/ipc/ProcessChild.h" #if defined(XP_WIN) +# include # include "mozilla/gfx/DeviceManagerDx.h" #endif @@ -95,6 +97,23 @@ mozilla::ipc::IPCResult VRParent::RecvOpenVRControllerManifestPathToVR( return IPC_OK(); } +mozilla::ipc::IPCResult VRParent::RecvRequestMemoryReport( + const uint32_t& aGeneration, const bool& aAnonymize, + const bool& aMinimizeMemoryUsage, const Maybe& aDMDFile) { + MOZ_ASSERT(XRE_IsVRProcess()); + nsPrintfCString processName("VR (pid %u)", (unsigned)getpid()); + + mozilla::dom::MemoryReportRequestClient::Start( + aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName, + [&](const MemoryReport& aReport) { + Unused << SendAddMemoryReport(aReport); + }, + [&](const uint32_t& aGeneration) { + return SendFinishMemoryReport(aGeneration); + }); + return IPC_OK(); +} + void VRParent::ActorDestroy(ActorDestroyReason aWhy) { if (AbnormalShutdown == aWhy) { NS_WARNING("Shutting down VR process early due to a crash!"); diff --git a/gfx/vr/ipc/VRParent.h b/gfx/vr/ipc/VRParent.h index 999b94a244b6..fe88a6630e25 100644 --- a/gfx/vr/ipc/VRParent.h +++ b/gfx/vr/ipc/VRParent.h @@ -46,6 +46,10 @@ class VRParent final : public PVRParent { const nsCString& aPath); mozilla::ipc::IPCResult RecvOpenVRControllerManifestPathToVR( const OpenVRControllerType& aType, const nsCString& aPath); + mozilla::ipc::IPCResult RecvRequestMemoryReport( + const uint32_t& generation, const bool& anonymize, + const bool& minimizeMemoryUsage, + const Maybe& DMDFile); private: nsCString mOpenVRControllerAction; diff --git a/gfx/vr/ipc/VRProcessManager.cpp b/gfx/vr/ipc/VRProcessManager.cpp index c38e862244e9..fd3ac1d0f2ce 100644 --- a/gfx/vr/ipc/VRProcessManager.cpp +++ b/gfx/vr/ipc/VRProcessManager.cpp @@ -10,6 +10,7 @@ #include "VRChild.h" #include "VRGPUChild.h" #include "VRGPUParent.h" +#include "mozilla/MemoryReportingProcess.h" namespace mozilla { namespace gfx { @@ -195,5 +196,57 @@ void VRProcessManager::OnXPCOMShutdown() { VRChild* VRProcessManager::GetVRChild() { return mProcess->GetActor(); } +class VRMemoryReporter : public MemoryReportingProcess { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRMemoryReporter, override) + + bool IsAlive() const override { + if (VRProcessManager* vpm = VRProcessManager::Get()) { + return !!vpm->GetVRChild(); + } + return false; + } + + bool SendRequestMemoryReport(const uint32_t& aGeneration, + const bool& aAnonymize, + const bool& aMinimizeMemoryUsage, + const Maybe& aDMDFile) override { + VRChild* child = GetChild(); + if (!child) { + return false; + } + + return child->SendRequestMemoryReport(aGeneration, aAnonymize, + aMinimizeMemoryUsage, aDMDFile); + } + + int32_t Pid() const override { + if (VRChild* child = GetChild()) { + return (int32_t)child->OtherPid(); + } + return 0; + } + + private: + VRChild* GetChild() const { + if (VRProcessManager* vpm = VRProcessManager::Get()) { + if (VRChild* child = vpm->GetVRChild()) { + return child; + } + } + return nullptr; + } + + protected: + ~VRMemoryReporter() = default; +}; + +RefPtr VRProcessManager::GetProcessMemoryReporter() { + if (!EnsureVRReady()) { + return nullptr; + } + return new VRMemoryReporter(); +} + } // namespace gfx } // namespace mozilla \ No newline at end of file diff --git a/gfx/vr/ipc/VRProcessManager.h b/gfx/vr/ipc/VRProcessManager.h index 6708c3196f3c..0640ebee6fbe 100644 --- a/gfx/vr/ipc/VRProcessManager.h +++ b/gfx/vr/ipc/VRProcessManager.h @@ -9,6 +9,7 @@ #include "VRProcessParent.h" namespace mozilla { +class MemoryReportingProcess; namespace gfx { class VRManagerChild; @@ -37,6 +38,9 @@ class VRProcessManager final : public VRProcessParent::Listener { mozilla::ipc::Endpoint* aOutVRBridge); VRChild* GetVRChild(); + // If a VR process is present, create a MemoryReportingProcess object. + // Otherwise, return null. + RefPtr GetProcessMemoryReporter(); virtual void OnProcessLaunchComplete(VRProcessParent* aParent) override; virtual void OnProcessUnexpectedShutdown(VRProcessParent* aParent) override; diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 1ef57a007bac..7344f190d50b 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -27,6 +27,7 @@ #endif #include "nsNetCID.h" #include "nsThread.h" +#include "VRProcessManager.h" #include "mozilla/Attributes.h" #include "mozilla/MemoryReportingProcess.h" #include "mozilla/PodOperations.h" @@ -1814,6 +1815,12 @@ nsresult nsMemoryReporterManager::StartGettingReports() { } } + if (gfx::VRProcessManager* vr = gfx::VRProcessManager::Get()) { + if (RefPtr proc = vr->GetProcessMemoryReporter()) { + s->mChildrenPending.AppendElement(proc.forget()); + } + } + if (!mIsRegistrationBlocked && net::gIOService) { if (RefPtr proc = net::gIOService->GetSocketProcessMemoryReporter()) { diff --git a/xpcom/build/components.conf b/xpcom/build/components.conf index 9f2deda27ab5..cb25e5f5ae2b 100644 --- a/xpcom/build/components.conf +++ b/xpcom/build/components.conf @@ -67,7 +67,7 @@ Classes = [ 'type': 'nsMemoryReporterManager', 'headers': ['/xpcom/base/nsMemoryReporterManager.h'], 'init_method': 'Init', - 'processes': ProcessSelector.ALLOW_IN_GPU_AND_SOCKET_PROCESS, + 'processes': ProcessSelector.ALLOW_IN_GPU_VR_AND_SOCKET_PROCESS, }, { 'cid': '{7b4eeb20-d781-11d4-8a83-0010a4e0c9ca}',