mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 20:01:50 +00:00
Backed out changeset 0e250e45603a (bug 1886022) for causing build bustages on CanvasShutdownManager. CLOSED TREE
This commit is contained in:
parent
2bf53fd12d
commit
cb3c42a748
@ -24,7 +24,7 @@
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/dom/GeneratePlaceholderCanvasData.h"
|
||||
#include "mozilla/dom/VideoFrame.h"
|
||||
#include "mozilla/gfx/CanvasShutdownManager.h"
|
||||
#include "mozilla/gfx/CanvasManagerChild.h"
|
||||
#include "nsPresContext.h"
|
||||
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
@ -872,6 +872,41 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasGradient, mContext)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasPattern, mContext)
|
||||
|
||||
class CanvasShutdownObserver final : public nsIObserver {
|
||||
public:
|
||||
explicit CanvasShutdownObserver(CanvasRenderingContext2D* aCanvas)
|
||||
: mCanvas(aCanvas) {}
|
||||
|
||||
void OnShutdown() {
|
||||
if (!mCanvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCanvas = nullptr;
|
||||
nsContentUtils::UnregisterShutdownObserver(this);
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
private:
|
||||
~CanvasShutdownObserver() = default;
|
||||
|
||||
CanvasRenderingContext2D* mCanvas;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(CanvasShutdownObserver, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasShutdownObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
if (mCanvas && strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||
mCanvas->OnShutdown();
|
||||
OnShutdown();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(CanvasRenderingContext2D)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(CanvasRenderingContext2D)
|
||||
|
||||
@ -1208,8 +1243,14 @@ void CanvasRenderingContext2D::OnShutdown() {
|
||||
}
|
||||
|
||||
bool CanvasRenderingContext2D::AddShutdownObserver() {
|
||||
auto* const canvasManager = CanvasShutdownManager::Get();
|
||||
auto* const canvasManager = CanvasManagerChild::Get();
|
||||
if (NS_WARN_IF(!canvasManager)) {
|
||||
if (NS_IsMainThread()) {
|
||||
mShutdownObserver = new CanvasShutdownObserver(this);
|
||||
nsContentUtils::RegisterShutdownObserver(mShutdownObserver);
|
||||
return true;
|
||||
}
|
||||
|
||||
mHasShutdown = true;
|
||||
return false;
|
||||
}
|
||||
@ -1219,7 +1260,13 @@ bool CanvasRenderingContext2D::AddShutdownObserver() {
|
||||
}
|
||||
|
||||
void CanvasRenderingContext2D::RemoveShutdownObserver() {
|
||||
auto* const canvasManager = CanvasShutdownManager::MaybeGet();
|
||||
if (mShutdownObserver) {
|
||||
mShutdownObserver->OnShutdown();
|
||||
mShutdownObserver = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
auto* const canvasManager = CanvasManagerChild::MaybeGet();
|
||||
if (!canvasManager) {
|
||||
return;
|
||||
}
|
||||
|
@ -846,6 +846,7 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
|
||||
// Whether or not we have already shutdown.
|
||||
bool mHasShutdown = false;
|
||||
|
||||
RefPtr<CanvasShutdownObserver> mShutdownObserver;
|
||||
bool AddShutdownObserver();
|
||||
void RemoveShutdownObserver();
|
||||
bool AlreadyShutDown() const { return mHasShutdown; }
|
||||
|
@ -10,7 +10,6 @@
|
||||
#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"
|
||||
@ -31,10 +30,7 @@ MOZ_THREAD_LOCAL(CanvasManagerChild*) CanvasManagerChild::sLocalManager;
|
||||
|
||||
Atomic<uint32_t> CanvasManagerChild::sNextId(1);
|
||||
|
||||
CanvasManagerChild::CanvasManagerChild(ThreadSafeWorkerRef* aWorkerRef,
|
||||
uint32_t aId)
|
||||
: mWorkerRef(aWorkerRef), mId(aId) {}
|
||||
|
||||
CanvasManagerChild::CanvasManagerChild(uint32_t aId) : mId(aId) {}
|
||||
CanvasManagerChild::~CanvasManagerChild() = default;
|
||||
|
||||
void CanvasManagerChild::ActorDestroy(ActorDestroyReason aReason) {
|
||||
@ -46,6 +42,11 @@ 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();
|
||||
@ -66,6 +67,12 @@ 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) {
|
||||
@ -96,11 +103,6 @@ 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());
|
||||
@ -119,8 +121,29 @@ void CanvasManagerChild::Destroy() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto manager = MakeRefPtr<CanvasManagerChild>(shutdownManager->GetWorkerRef(),
|
||||
sNextId++);
|
||||
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;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!childEndpoint.Bind(manager))) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -152,6 +175,16 @@ 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;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/gfx/PCanvasManagerChild.h"
|
||||
#include "mozilla/gfx/Types.h"
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#include <set>
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -34,8 +35,7 @@ class CanvasManagerChild final : public PCanvasManagerChild {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CanvasManagerChild, override);
|
||||
|
||||
explicit CanvasManagerChild(dom::ThreadSafeWorkerRef* aWorkerRef,
|
||||
uint32_t aId);
|
||||
explicit CanvasManagerChild(uint32_t aId);
|
||||
uint32_t Id() const { return mId; }
|
||||
already_AddRefed<DataSourceSurface> GetSnapshot(
|
||||
uint32_t aManagerId, int32_t aProtocolId,
|
||||
@ -49,6 +49,9 @@ 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();
|
||||
@ -70,6 +73,7 @@ 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;
|
||||
|
@ -1,108 +0,0 @@
|
||||
/* -*- 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/gfx/CanvasManagerChild.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla::gfx {
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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);
|
||||
return manager;
|
||||
}
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
if (NS_WARN_IF(
|
||||
AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CanvasShutdownManager* manager = new CanvasShutdownManager();
|
||||
sLocalManager.set(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);
|
||||
}
|
||||
|
||||
} // namespace mozilla::gfx
|
@ -1,45 +0,0 @@
|
||||
/* -*- 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/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);
|
||||
|
||||
private:
|
||||
explicit CanvasShutdownManager(dom::StrongWorkerRef* aWorkerRef);
|
||||
CanvasShutdownManager();
|
||||
~CanvasShutdownManager();
|
||||
void Destroy();
|
||||
|
||||
RefPtr<dom::ThreadSafeWorkerRef> mWorkerRef;
|
||||
std::set<dom::CanvasRenderingContext2D*> mActiveCanvas;
|
||||
static MOZ_THREAD_LOCAL(CanvasShutdownManager*) sLocalManager;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // _include_gfx_ipc_CanvasShutdownManager_h__
|
@ -13,7 +13,6 @@ EXPORTS.mozilla.gfx += [
|
||||
"CanvasManagerChild.h",
|
||||
"CanvasManagerParent.h",
|
||||
"CanvasRenderThread.h",
|
||||
"CanvasShutdownManager.h",
|
||||
"CrossProcessPaint.h",
|
||||
"FileHandleWrapper.h",
|
||||
"GPUChild.h",
|
||||
@ -43,7 +42,6 @@ UNIFIED_SOURCES += [
|
||||
"CanvasManagerChild.cpp",
|
||||
"CanvasManagerParent.cpp",
|
||||
"CanvasRenderThread.cpp",
|
||||
"CanvasShutdownManager.cpp",
|
||||
"CompositorSession.cpp",
|
||||
"CompositorWidgetVsyncObserver.cpp",
|
||||
"CrossProcessPaint.cpp",
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/gfx/GraphicsMessages.h"
|
||||
#include "mozilla/gfx/CanvasManagerChild.h"
|
||||
#include "mozilla/gfx/CanvasRenderThread.h"
|
||||
#include "mozilla/gfx/CanvasShutdownManager.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/EnumTypeTraits.h"
|
||||
@ -1343,7 +1343,7 @@ void gfxPlatform::ShutdownLayersIPC() {
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
gfx::VRManagerChild::ShutDown();
|
||||
gfx::CanvasShutdownManager::Shutdown();
|
||||
gfx::CanvasManagerChild::Shutdown();
|
||||
// cf bug 1215265.
|
||||
if (StaticPrefs::layers_child_process_shutdown()) {
|
||||
layers::CompositorManagerChild::Shutdown();
|
||||
@ -1354,7 +1354,7 @@ void gfxPlatform::ShutdownLayersIPC() {
|
||||
VideoBridgeParent::Shutdown();
|
||||
RDDProcessManager::RDDProcessShutdown();
|
||||
gfx::VRManagerChild::ShutDown();
|
||||
gfx::CanvasShutdownManager::Shutdown();
|
||||
gfx::CanvasManagerChild::Shutdown();
|
||||
layers::CompositorManagerChild::Shutdown();
|
||||
layers::ImageBridgeChild::ShutDown();
|
||||
// This could be running on either the Compositor thread, the Renderer
|
||||
|
Loading…
x
Reference in New Issue
Block a user