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
Родитель cc9e275424
Коммит 3df91287ff
5 изменённых файлов: 37 добавлений и 1 удалений

Просмотреть файл

@ -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()) {

Просмотреть файл

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

Просмотреть файл

@ -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.

Просмотреть файл

@ -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();

Просмотреть файл

@ -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;