diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
commit | fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 (patch) | |
tree | 4c1ccaf5486d4f2009f9a338a98a83e886e29c97 /gfx/ipc | |
parent | Releasing progress-linux version 124.0.1-1~progress7.99u1. (diff) | |
download | firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.tar.xz firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.zip |
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/ipc')
-rw-r--r-- | gfx/ipc/CanvasManagerChild.cpp | 65 | ||||
-rw-r--r-- | gfx/ipc/CanvasManagerChild.h | 8 | ||||
-rw-r--r-- | gfx/ipc/CanvasShutdownManager.cpp | 179 | ||||
-rw-r--r-- | gfx/ipc/CanvasShutdownManager.h | 57 | ||||
-rw-r--r-- | gfx/ipc/GPUParent.cpp | 13 | ||||
-rw-r--r-- | gfx/ipc/GPUParent.h | 3 | ||||
-rw-r--r-- | gfx/ipc/GPUProcessManager.cpp | 60 | ||||
-rw-r--r-- | gfx/ipc/GPUProcessManager.h | 19 | ||||
-rw-r--r-- | gfx/ipc/PGPU.ipdl | 3 | ||||
-rw-r--r-- | gfx/ipc/moz.build | 2 |
10 files changed, 348 insertions, 61 deletions
diff --git a/gfx/ipc/CanvasManagerChild.cpp b/gfx/ipc/CanvasManagerChild.cpp index eca803bc4b..dee232b6b1 100644 --- a/gfx/ipc/CanvasManagerChild.cpp +++ b/gfx/ipc/CanvasManagerChild.cpp @@ -10,6 +10,7 @@ #include "mozilla/dom/WorkerPrivate.h" #include "mozilla/dom/WorkerRef.h" #include "mozilla/gfx/2D.h" +#include "mozilla/gfx/CanvasShutdownManager.h" #include "mozilla/gfx/Swizzle.h" #include "mozilla/ipc/Endpoint.h" #include "mozilla/layers/ActiveResource.h" @@ -30,7 +31,10 @@ MOZ_THREAD_LOCAL(CanvasManagerChild*) CanvasManagerChild::sLocalManager; Atomic<uint32_t> CanvasManagerChild::sNextId(1); -CanvasManagerChild::CanvasManagerChild(uint32_t aId) : mId(aId) {} +CanvasManagerChild::CanvasManagerChild(ThreadSafeWorkerRef* aWorkerRef, + uint32_t aId) + : mWorkerRef(aWorkerRef), mId(aId) {} + CanvasManagerChild::~CanvasManagerChild() = default; void CanvasManagerChild::ActorDestroy(ActorDestroyReason aReason) { @@ -42,11 +46,6 @@ void CanvasManagerChild::ActorDestroy(ActorDestroyReason aReason) { } void CanvasManagerChild::DestroyInternal() { - std::set<CanvasRenderingContext2D*> activeCanvas = std::move(mActiveCanvas); - for (const auto& i : activeCanvas) { - i->OnShutdown(); - } - if (mActiveResourceTracker) { mActiveResourceTracker->AgeAllGenerations(); mActiveResourceTracker.reset(); @@ -56,6 +55,10 @@ void CanvasManagerChild::DestroyInternal() { mCanvasChild->Destroy(); mCanvasChild = nullptr; } + + if (auto* shutdownManager = CanvasShutdownManager::Get()) { + shutdownManager->OnRemoteCanvasLost(); + } } void CanvasManagerChild::Destroy() { @@ -67,12 +70,6 @@ void CanvasManagerChild::Destroy() { } /* static */ void CanvasManagerChild::Shutdown() { - MOZ_ASSERT(NS_IsMainThread()); - - // The worker threads should destroy their own CanvasManagerChild instances - // during their shutdown sequence. We just need to take care of the main - // thread. We need to init here because we may have never created a - // CanvasManagerChild for the main thread in the first place. if (sLocalManager.init()) { RefPtr<CanvasManagerChild> manager = sLocalManager.get(); if (manager) { @@ -103,6 +100,11 @@ void CanvasManagerChild::Destroy() { return managerWeak; } + auto* shutdownManager = CanvasShutdownManager::Get(); + if (NS_WARN_IF(!shutdownManager)) { + return nullptr; + } + // We are only used on the main thread, or on worker threads. WorkerPrivate* worker = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT_IF(!worker, NS_IsMainThread()); @@ -121,29 +123,8 @@ void CanvasManagerChild::Destroy() { return nullptr; } - auto manager = MakeRefPtr<CanvasManagerChild>(sNextId++); - - if (worker) { - // The ThreadSafeWorkerRef will let us know when the worker is shutting - // down. This will let us clear our threadlocal reference and close the - // actor. We rely upon an explicit shutdown for the main thread. - RefPtr<StrongWorkerRef> workerRef = StrongWorkerRef::Create( - worker, "CanvasManager", [manager]() { manager->Destroy(); }); - if (NS_WARN_IF(!workerRef)) { - return nullptr; - } - - manager->mWorkerRef = new ThreadSafeWorkerRef(workerRef); - } else if (NS_IsMainThread()) { - if (NS_WARN_IF( - AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed))) { - return nullptr; - } - } else { - MOZ_ASSERT_UNREACHABLE("Can only be used on main or DOM worker threads!"); - return nullptr; - } - + auto manager = MakeRefPtr<CanvasManagerChild>(shutdownManager->GetWorkerRef(), + sNextId++); if (NS_WARN_IF(!childEndpoint.Bind(manager))) { return nullptr; } @@ -163,6 +144,7 @@ void CanvasManagerChild::Destroy() { } manager->SendInitialize(manager->Id()); + shutdownManager->OnRemoteCanvasRestored(); sLocalManager.set(manager); return manager; } @@ -175,16 +157,6 @@ void CanvasManagerChild::Destroy() { return sLocalManager.get(); } -void CanvasManagerChild::AddShutdownObserver( - dom::CanvasRenderingContext2D* aCanvas) { - mActiveCanvas.insert(aCanvas); -} - -void CanvasManagerChild::RemoveShutdownObserver( - dom::CanvasRenderingContext2D* aCanvas) { - mActiveCanvas.erase(aCanvas); -} - void CanvasManagerChild::EndCanvasTransaction() { if (!mCanvasChild) { return; @@ -224,8 +196,9 @@ RefPtr<layers::CanvasChild> CanvasManagerChild::GetCanvasChild() { } if (!mCanvasChild) { - mCanvasChild = MakeAndAddRef<layers::CanvasChild>(); + mCanvasChild = MakeAndAddRef<layers::CanvasChild>(mWorkerRef); if (!SendPCanvasConstructor(mCanvasChild)) { + mCanvasChild->Destroy(); mCanvasChild = nullptr; } } diff --git a/gfx/ipc/CanvasManagerChild.h b/gfx/ipc/CanvasManagerChild.h index 6369d87ada..c59ba7c502 100644 --- a/gfx/ipc/CanvasManagerChild.h +++ b/gfx/ipc/CanvasManagerChild.h @@ -10,7 +10,6 @@ #include "mozilla/gfx/PCanvasManagerChild.h" #include "mozilla/gfx/Types.h" #include "mozilla/ThreadLocal.h" -#include <set> namespace mozilla { namespace dom { @@ -35,7 +34,8 @@ class CanvasManagerChild final : public PCanvasManagerChild { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CanvasManagerChild, override); - explicit CanvasManagerChild(uint32_t aId); + explicit CanvasManagerChild(dom::ThreadSafeWorkerRef* aWorkerRef, + uint32_t aId); uint32_t Id() const { return mId; } already_AddRefed<DataSourceSurface> GetSnapshot( uint32_t aManagerId, int32_t aProtocolId, @@ -49,9 +49,6 @@ class CanvasManagerChild final : public PCanvasManagerChild { static bool CreateParent( mozilla::ipc::Endpoint<PCanvasManagerParent>&& aEndpoint); - void AddShutdownObserver(dom::CanvasRenderingContext2D* aCanvas); - void RemoveShutdownObserver(dom::CanvasRenderingContext2D* aCanvas); - bool IsCanvasActive() { return mActive; } void EndCanvasTransaction(); void ClearCachedResources(); @@ -73,7 +70,6 @@ class CanvasManagerChild final : public PCanvasManagerChild { RefPtr<layers::CanvasChild> mCanvasChild; RefPtr<webgpu::WebGPUChild> mWebGPUChild; UniquePtr<layers::ActiveResourceTracker> mActiveResourceTracker; - std::set<dom::CanvasRenderingContext2D*> mActiveCanvas; const uint32_t mId; bool mActive = true; bool mBlocked = false; diff --git a/gfx/ipc/CanvasShutdownManager.cpp b/gfx/ipc/CanvasShutdownManager.cpp new file mode 100644 index 0000000000..d7fc96d255 --- /dev/null +++ b/gfx/ipc/CanvasShutdownManager.cpp @@ -0,0 +1,179 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CanvasShutdownManager.h" +#include "mozilla/AppShutdown.h" +#include "mozilla/dom/CanvasRenderingContext2D.h" +#include "mozilla/dom/WorkerPrivate.h" +#include "mozilla/dom/WorkerRef.h" +#include "mozilla/dom/WorkerRunnable.h" +#include "mozilla/gfx/CanvasManagerChild.h" + +using namespace mozilla::dom; + +namespace mozilla::gfx { + +StaticMutex CanvasShutdownManager::sManagersMutex; +std::set<CanvasShutdownManager*> CanvasShutdownManager::sManagers; + +// The owning thread will tell us to close when it is shutdown, either via +// CanvasShutdownManager::Shutdown for the main thread, or via a shutdown +// callback from ThreadSafeWorkerRef for worker threads. +MOZ_THREAD_LOCAL(CanvasShutdownManager*) CanvasShutdownManager::sLocalManager; + +CanvasShutdownManager::CanvasShutdownManager(StrongWorkerRef* aWorkerRef) + : mWorkerRef(new ThreadSafeWorkerRef(aWorkerRef)) {} + +CanvasShutdownManager::CanvasShutdownManager() = default; +CanvasShutdownManager::~CanvasShutdownManager() = default; + +void CanvasShutdownManager::Destroy() { + std::set<CanvasRenderingContext2D*> activeCanvas = std::move(mActiveCanvas); + for (const auto& i : activeCanvas) { + i->OnShutdown(); + } + + CanvasManagerChild::Shutdown(); + mWorkerRef = nullptr; +} + +/* static */ void CanvasShutdownManager::Shutdown() { + auto* manager = MaybeGet(); + if (!manager) { + return; + } + + { + StaticMutexAutoLock lock(sManagersMutex); + sManagers.erase(manager); + } + + sLocalManager.set(nullptr); + manager->Destroy(); + delete manager; +} + +/* static */ CanvasShutdownManager* CanvasShutdownManager::MaybeGet() { + if (NS_WARN_IF(!sLocalManager.init())) { + return nullptr; + } + + return sLocalManager.get(); +} + +/* static */ CanvasShutdownManager* CanvasShutdownManager::Get() { + if (NS_WARN_IF(!sLocalManager.init())) { + return nullptr; + } + + CanvasShutdownManager* managerWeak = sLocalManager.get(); + if (managerWeak) { + return managerWeak; + } + + if (WorkerPrivate* worker = GetCurrentThreadWorkerPrivate()) { + // The ThreadSafeWorkerRef will let us know when the worker is shutting + // down. This will let us clear our threadlocal reference and close the + // actor. We rely upon an explicit shutdown for the main thread. + RefPtr<StrongWorkerRef> workerRef = StrongWorkerRef::Create( + worker, "CanvasShutdownManager", []() { Shutdown(); }); + if (NS_WARN_IF(!workerRef)) { + return nullptr; + } + + CanvasShutdownManager* manager = new CanvasShutdownManager(workerRef); + sLocalManager.set(manager); + + StaticMutexAutoLock lock(sManagersMutex); + sManagers.insert(manager); + return manager; + } + + if (NS_IsMainThread()) { + if (NS_WARN_IF( + AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed))) { + return nullptr; + } + + CanvasShutdownManager* manager = new CanvasShutdownManager(); + sLocalManager.set(manager); + + StaticMutexAutoLock lock(sManagersMutex); + sManagers.insert(manager); + return manager; + } + + MOZ_ASSERT_UNREACHABLE("Can only be used on main or DOM worker threads!"); + return nullptr; +} + +void CanvasShutdownManager::AddShutdownObserver( + dom::CanvasRenderingContext2D* aCanvas) { + mActiveCanvas.insert(aCanvas); +} + +void CanvasShutdownManager::RemoveShutdownObserver( + dom::CanvasRenderingContext2D* aCanvas) { + mActiveCanvas.erase(aCanvas); +} + +void CanvasShutdownManager::OnRemoteCanvasLost() { + // Note that the canvas cannot do anything that mutates our state. It will + // dispatch for anything that risks re-entrancy. + for (const auto& canvas : mActiveCanvas) { + canvas->OnRemoteCanvasLost(); + } +} + +void CanvasShutdownManager::OnRemoteCanvasRestored() { + // Note that the canvas cannot do anything that mutates our state. It will + // dispatch for anything that risks re-entrancy. + for (const auto& canvas : mActiveCanvas) { + canvas->OnRemoteCanvasRestored(); + } +} + +/* static */ void CanvasShutdownManager::MaybeRestoreRemoteCanvas() { + // Calling Get will recreate the CanvasManagerChild, which in turn will + // cause us to call OnRemoteCanvasRestore upon success. + if (CanvasShutdownManager* manager = MaybeGet()) { + if (!manager->mActiveCanvas.empty()) { + CanvasManagerChild::Get(); + } + } +} + +/* static */ void CanvasShutdownManager::OnCompositorManagerRestored() { + MOZ_ASSERT(NS_IsMainThread()); + + class RestoreRunnable final : public WorkerRunnable { + public: + explicit RestoreRunnable(WorkerPrivate* aWorkerPrivate) + : WorkerRunnable(aWorkerPrivate, + "CanvasShutdownManager::RestoreRunnable") {} + + bool WorkerRun(JSContext*, WorkerPrivate*) override { + MaybeRestoreRemoteCanvas(); + return true; + } + }; + + // We can restore the main thread canvases immediately. + MaybeRestoreRemoteCanvas(); + + // And dispatch to restore any DOM worker canvases. This is safe because we + // remove the manager from sManagers before clearing mWorkerRef during DOM + // worker shutdown. + StaticMutexAutoLock lock(sManagersMutex); + for (const auto& manager : sManagers) { + if (manager->mWorkerRef) { + auto task = MakeRefPtr<RestoreRunnable>(manager->mWorkerRef->Private()); + task->Dispatch(); + } + } +} + +} // namespace mozilla::gfx diff --git a/gfx/ipc/CanvasShutdownManager.h b/gfx/ipc/CanvasShutdownManager.h new file mode 100644 index 0000000000..803d6a1eb8 --- /dev/null +++ b/gfx/ipc/CanvasShutdownManager.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef _include_gfx_ipc_CanvasShutdownManager_h__ +#define _include_gfx_ipc_CanvasShutdownManager_h__ + +#include "mozilla/RefPtr.h" +#include "mozilla/StaticMutex.h" +#include "mozilla/ThreadLocal.h" +#include <set> + +namespace mozilla { +namespace dom { +class CanvasRenderingContext2D; +class StrongWorkerRef; +class ThreadSafeWorkerRef; +} // namespace dom + +namespace gfx { + +class CanvasShutdownManager final { + public: + static CanvasShutdownManager* Get(); + static CanvasShutdownManager* MaybeGet(); + static void Shutdown(); + + dom::ThreadSafeWorkerRef* GetWorkerRef() const { return mWorkerRef; } + void AddShutdownObserver(dom::CanvasRenderingContext2D* aCanvas); + void RemoveShutdownObserver(dom::CanvasRenderingContext2D* aCanvas); + + static void OnCompositorManagerRestored(); + + void OnRemoteCanvasLost(); + void OnRemoteCanvasRestored(); + + private: + explicit CanvasShutdownManager(dom::StrongWorkerRef* aWorkerRef); + CanvasShutdownManager(); + ~CanvasShutdownManager(); + void Destroy(); + + static void MaybeRestoreRemoteCanvas(); + + RefPtr<dom::ThreadSafeWorkerRef> mWorkerRef; + std::set<dom::CanvasRenderingContext2D*> mActiveCanvas; + static MOZ_THREAD_LOCAL(CanvasShutdownManager*) sLocalManager; + + static StaticMutex sManagersMutex; + static std::set<CanvasShutdownManager*> sManagers; +}; + +} // namespace gfx +} // namespace mozilla + +#endif // _include_gfx_ipc_CanvasShutdownManager_h__ diff --git a/gfx/ipc/GPUParent.cpp b/gfx/ipc/GPUParent.cpp index 283fb87ee9..f4240a5d97 100644 --- a/gfx/ipc/GPUParent.cpp +++ b/gfx/ipc/GPUParent.cpp @@ -571,6 +571,19 @@ mozilla::ipc::IPCResult GPUParent::RecvPreferenceUpdate(const Pref& aPref) { return IPC_OK(); } +mozilla::ipc::IPCResult GPUParent::RecvScreenInformationChanged() { +#if defined(XP_WIN) + DeviceManagerDx::Get()->PostUpdateMonitorInfo(); +#endif + return IPC_OK(); +} + +mozilla::ipc::IPCResult GPUParent::RecvNotifyBatteryInfo( + const BatteryInformation& aBatteryInfo) { + wr::RenderThread::Get()->SetBatteryInfo(aBatteryInfo); + return IPC_OK(); +} + static void CopyFeatureChange(Feature aFeature, Maybe<FeatureFailure>* aOut) { FeatureState& feature = gfxConfig::GetFeature(aFeature); if (feature.DisabledByDefault() || feature.IsEnabled()) { diff --git a/gfx/ipc/GPUParent.h b/gfx/ipc/GPUParent.h index 434c9eab79..4c01761e77 100644 --- a/gfx/ipc/GPUParent.h +++ b/gfx/ipc/GPUParent.h @@ -74,6 +74,9 @@ class GPUParent final : public PGPUParent { Endpoint<PProfilerChild>&& aEndpoint); mozilla::ipc::IPCResult RecvUpdateVar(const GfxVarUpdate& pref); mozilla::ipc::IPCResult RecvPreferenceUpdate(const Pref& pref); + mozilla::ipc::IPCResult RecvScreenInformationChanged(); + mozilla::ipc::IPCResult RecvNotifyBatteryInfo( + const BatteryInformation& aBatteryInfo); mozilla::ipc::IPCResult RecvNewContentCompositorManager( Endpoint<PCompositorManagerParent>&& aEndpoint, const ContentParentId& aChildId, uint32_t aNamespace); diff --git a/gfx/ipc/GPUProcessManager.cpp b/gfx/ipc/GPUProcessManager.cpp index babc523e3a..97f4d47111 100644 --- a/gfx/ipc/GPUProcessManager.cpp +++ b/gfx/ipc/GPUProcessManager.cpp @@ -136,10 +136,28 @@ GPUProcessManager::Observer::Observe(nsISupports* aSubject, const char* aTopic, } } else if (!strcmp(aTopic, "application-background")) { mManager->mAppInForeground = false; + } else if (!strcmp(aTopic, "screen-information-changed")) { + mManager->ScreenInformationChanged(); } return NS_OK; } +GPUProcessManager::BatteryObserver::BatteryObserver(GPUProcessManager* aManager) + : mManager(aManager) { + hal::RegisterBatteryObserver(this); +} + +void GPUProcessManager::BatteryObserver::Notify( + const hal::BatteryInformation& aBatteryInfo) { + mManager->NotifyBatteryInfo(aBatteryInfo); +} + +void GPUProcessManager::BatteryObserver::ShutDown() { + hal::UnregisterBatteryObserver(this); +} + +GPUProcessManager::BatteryObserver::~BatteryObserver() {} + void GPUProcessManager::OnXPCOMShutdown() { if (mObserver) { nsContentUtils::UnregisterShutdownObserver(mObserver); @@ -148,6 +166,7 @@ void GPUProcessManager::OnXPCOMShutdown() { if (obsServ) { obsServ->RemoveObserver(mObserver, "application-foreground"); obsServ->RemoveObserver(mObserver, "application-background"); + obsServ->RemoveObserver(mObserver, "screen-information-changed"); } mObserver = nullptr; } @@ -172,6 +191,21 @@ void GPUProcessManager::OnPreferenceChange(const char16_t* aData) { } } +void GPUProcessManager::ScreenInformationChanged() { +#if defined(XP_WIN) + if (!!mGPUChild) { + mGPUChild->SendScreenInformationChanged(); + } +#endif +} + +void GPUProcessManager::NotifyBatteryInfo( + const hal::BatteryInformation& aBatteryInfo) { + if (mGPUChild) { + mGPUChild->SendNotifyBatteryInfo(aBatteryInfo); + } +} + void GPUProcessManager::ResetProcessStable() { mTotalProcessAttempts++; mProcessStable = false; @@ -207,6 +241,7 @@ bool GPUProcessManager::LaunchGPUProcess() { if (obsServ) { obsServ->AddObserver(mObserver, "application-foreground", false); obsServ->AddObserver(mObserver, "application-background", false); + obsServ->AddObserver(mObserver, "screen-information-changed", false); } } @@ -566,6 +601,9 @@ void GPUProcessManager::OnProcessLaunchComplete(GPUProcessHost* aHost) { std::move(vsyncChild)); mGPUChild->SendInitVsyncBridge(std::move(vsyncParent)); + MOZ_ASSERT(!mBatteryObserver); + mBatteryObserver = new BatteryObserver(this); + // Flush any pref updates that happened during launch and weren't // included in the blobs set up in LaunchGPUProcess. for (const mozilla::dom::Pref& pref : mQueuedPrefs) { @@ -573,12 +611,11 @@ void GPUProcessManager::OnProcessLaunchComplete(GPUProcessHost* aHost) { } mQueuedPrefs.Clear(); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GPUProcessStatus, "Running"_ns); + CrashReporter::RecordAnnotationCString( + CrashReporter::Annotation::GPUProcessStatus, "Running"); - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GPUProcessLaunchCount, - static_cast<int>(mTotalProcessAttempts)); + CrashReporter::RecordAnnotationU32( + CrashReporter::Annotation::GPUProcessLaunchCount, mTotalProcessAttempts); ReinitializeRendering(); } @@ -754,8 +791,9 @@ void GPUProcessManager::NotifyWebRenderError(wr::WebRenderError aError) { Telemetry::Accumulate(Telemetry::DEVICE_RESET_REASON, uint32_t(aReason)); } - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::DeviceResetReason, int(aReason)); + CrashReporter::RecordAnnotationU32( + CrashReporter::Annotation::DeviceResetReason, + static_cast<uint32_t>(aReason)); } bool GPUProcessManager::OnDeviceReset(bool aTrackThreshold) { @@ -1062,9 +1100,13 @@ void GPUProcessManager::DestroyProcess(bool aUnexpectedShutdown) { mVsyncBridge->Close(); mVsyncBridge = nullptr; } + if (mBatteryObserver) { + mBatteryObserver->ShutDown(); + mBatteryObserver = nullptr; + } - CrashReporter::AnnotateCrashReport( - CrashReporter::Annotation::GPUProcessStatus, "Destroyed"_ns); + CrashReporter::RecordAnnotationCString( + CrashReporter::Annotation::GPUProcessStatus, "Destroyed"); } already_AddRefed<CompositorSession> GPUProcessManager::CreateTopLevelCompositor( diff --git a/gfx/ipc/GPUProcessManager.h b/gfx/ipc/GPUProcessManager.h index bf5b7e6587..8b58d15b54 100644 --- a/gfx/ipc/GPUProcessManager.h +++ b/gfx/ipc/GPUProcessManager.h @@ -14,6 +14,7 @@ #include "mozilla/gfx/GPUProcessHost.h" #include "mozilla/gfx/PGPUChild.h" #include "mozilla/gfx/Point.h" +#include "mozilla/Hal.h" #include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/ipc/TaskFactory.h" #include "mozilla/layers/LayersTypes.h" @@ -214,6 +215,7 @@ class GPUProcessManager final : public GPUProcessHost::Listener { // Called from our xpcom-shutdown observer. void OnXPCOMShutdown(); void OnPreferenceChange(const char16_t* aData); + void ScreenInformationChanged(); bool CreateContentCompositorManager( base::ProcessId aOtherProcess, dom::ContentParentId aChildId, @@ -309,6 +311,8 @@ class GPUProcessManager final : public GPUProcessHost::Listener { DISALLOW_COPY_AND_ASSIGN(GPUProcessManager); + void NotifyBatteryInfo(const hal::BatteryInformation& aBatteryInfo); + class Observer final : public nsIObserver { public: NS_DECL_ISUPPORTS @@ -322,10 +326,25 @@ class GPUProcessManager final : public GPUProcessHost::Listener { }; friend class Observer; + class BatteryObserver final : public hal::BatteryObserver { + public: + NS_INLINE_DECL_REFCOUNTING(BatteryObserver) + explicit BatteryObserver(GPUProcessManager* aManager); + + void Notify(const hal::BatteryInformation& aBatteryInfo) override; + void ShutDown(); + + protected: + virtual ~BatteryObserver(); + + GPUProcessManager* mManager; + }; + private: bool mDecodeVideoOnGpuProcess = true; RefPtr<Observer> mObserver; + RefPtr<BatteryObserver> mBatteryObserver; mozilla::ipc::TaskFactory<GPUProcessManager> mTaskFactory; RefPtr<VsyncIOThreadHolder> mVsyncIOThread; uint32_t mNextNamespace; diff --git a/gfx/ipc/PGPU.ipdl b/gfx/ipc/PGPU.ipdl index b6e84bf142..aabb81dc43 100644 --- a/gfx/ipc/PGPU.ipdl +++ b/gfx/ipc/PGPU.ipdl @@ -41,6 +41,7 @@ using mozilla::layers::OverlayInfo from "mozilla/layers/OverlayInfo.h"; using mozilla::layers::SwapChainInfo from "mozilla/layers/OverlayInfo.h"; using mozilla::media::MediaCodecsSupported from "MediaCodecsSupport.h"; using mozilla::layers::VideoBridgeSource from "mozilla/layers/VideoBridgeUtils.h"; +using mozilla::hal::BatteryInformation from "mozilla/hal_sandbox/PHal.h"; namespace mozilla { namespace gfx { @@ -79,6 +80,8 @@ parent: async UpdateVar(GfxVarUpdate var); async PreferenceUpdate(Pref pref); + async ScreenInformationChanged(); + async NotifyBatteryInfo(BatteryInformation aBatteryInfo); // Create a new content-process compositor bridge. async NewContentCompositorManager(Endpoint<PCompositorManagerParent> endpoint, ContentParentId childId, uint32_t aNamespace); diff --git a/gfx/ipc/moz.build b/gfx/ipc/moz.build index b8a52079e4..cc007a8193 100644 --- a/gfx/ipc/moz.build +++ b/gfx/ipc/moz.build @@ -13,6 +13,7 @@ EXPORTS.mozilla.gfx += [ "CanvasManagerChild.h", "CanvasManagerParent.h", "CanvasRenderThread.h", + "CanvasShutdownManager.h", "CrossProcessPaint.h", "FileHandleWrapper.h", "GPUChild.h", @@ -42,6 +43,7 @@ UNIFIED_SOURCES += [ "CanvasManagerChild.cpp", "CanvasManagerParent.cpp", "CanvasRenderThread.cpp", + "CanvasShutdownManager.cpp", "CompositorSession.cpp", "CompositorWidgetVsyncObserver.cpp", "CrossProcessPaint.cpp", |