Bug 1888338 - Use a single SharedContextWebgl. r=aosmond

This shares a global SharedContextWebgl among all instances of CanvasTranslator.
The goal is that regardless of how many windows are open, we only have to pay the
startup costs and shader compilation times for SharedContextWebgl once. In the
event that all CanvasTranslators are gone, the SharedContextWebgl is kept around
while its internal caches and textures are discarded to avoid significant memory
usage when no canvases are in use, while at the same time saving on startup
costs the next time a first live CanvasTranslator is created.

Differential Revision: https://phabricator.services.mozilla.com/D205977
This commit is contained in:
Lee Salzman 2024-03-28 17:33:58 +00:00
parent cc9e275424
commit 3df91287ff
5 changed files with 37 additions and 1 deletions

View File

@ -326,6 +326,11 @@ void SharedContextWebgl::UnlinkGlyphCaches() {
void SharedContextWebgl::OnMemoryPressure() { mShouldClearCaches = true; }
void SharedContextWebgl::ClearCaches() {
OnMemoryPressure();
ClearCachesIfNecessary();
}
// Clear out the entire list of texture handles from any source.
void SharedContextWebgl::ClearAllTextures() {
while (!mTextureHandles.isEmpty()) {

View File

@ -92,6 +92,8 @@ class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
void OnMemoryPressure();
void ClearCaches();
private:
SharedContextWebgl();

View File

@ -152,6 +152,9 @@ void CanvasRenderThread::Shutdown() {
// This closes all of the IPDL actors with possibly active task queues.
CanvasManagerParent::Shutdown();
// Queue any remaining global cleanup for CanvasTranslator
layers::CanvasTranslator::Shutdown();
// Any task queues that are in the process of shutting down are tracked in
// mPendingShutdownTaskQueues. We need to block on each one until all events
// are flushed so that we can safely teardown RemoteTextureMap afterwards.

View File

@ -113,6 +113,8 @@ static bool CreateAndMapShmem(RefPtr<ipc::SharedMemoryBasic>& aShmem,
return true;
}
StaticRefPtr<gfx::SharedContextWebgl> CanvasTranslator::sSharedContext;
bool CanvasTranslator::EnsureSharedContextWebgl() {
if (!mSharedContext || mSharedContext->IsContextLost()) {
if (mSharedContext) {
@ -122,7 +124,14 @@ bool CanvasTranslator::EnsureSharedContextWebgl() {
mRemoteTextureOwner->ClearRecycledTextures();
}
}
mSharedContext = gfx::SharedContextWebgl::Create();
// Check if the global shared context is still valid. If not, instantiate
// a new one before we try to use it.
if (!sSharedContext || sSharedContext->IsContextLost()) {
sSharedContext = gfx::SharedContextWebgl::Create();
}
mSharedContext = sSharedContext;
// If we can't get a new context, then the only thing left to do is block
// new canvases.
if (!mSharedContext || mSharedContext->IsContextLost()) {
mSharedContext = nullptr;
BlockCanvas();
@ -132,6 +141,13 @@ bool CanvasTranslator::EnsureSharedContextWebgl() {
return true;
}
void CanvasTranslator::Shutdown() {
if (sSharedContext) {
gfx::CanvasRenderThread::Dispatch(NS_NewRunnableFunction(
"CanvasTranslator::Shutdown", []() { sSharedContext = nullptr; }));
}
}
mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator(
TextureType aTextureType, TextureType aWebglTextureType,
gfx::BackendType aBackendType, Handle&& aReadHandle,
@ -1145,6 +1161,13 @@ void CanvasTranslator::ClearTextureInfo() {
mTextureInfo.clear();
mDrawTargets.Clear();
mSharedContext = nullptr;
// If the global shared context's ref is the last ref left, then clear out
// any internal caches and textures from the context, but still keep it
// alive. This saves on startup costs while not contributing significantly
// to memory usage.
if (sSharedContext && sSharedContext->hasOneRef()) {
sSharedContext->ClearCaches();
}
mBaseDT = nullptr;
if (mReferenceTextureData) {
mReferenceTextureData->Unlock();

View File

@ -277,6 +277,8 @@ class CanvasTranslator final : public gfx::InlineTranslator,
void GetDataSurface(uint64_t aSurfaceRef);
static void Shutdown();
private:
~CanvasTranslator();
@ -336,6 +338,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
#if defined(XP_WIN)
RefPtr<ID3D11Device> mDevice;
#endif
static StaticRefPtr<gfx::SharedContextWebgl> sSharedContext;
RefPtr<gfx::SharedContextWebgl> mSharedContext;
RefPtr<RemoteTextureOwnerClient> mRemoteTextureOwner;