Bug 1739996 - Select compositor or renderer thread for WebGL OOP depending on threadsafe GL status. r=jgilbert

If GL is threadsafe, we can run on the compositor thread. This appears
to have performance benefits, possibly because the renderer thread is
too busy. If GL is not threadsafe, we must run the WebGL OOP instances
on the renderer thread.

At the time of writing, only the nouveau drivers on Linux are considered
to be not threadsafe, so most users will see WebGL running on the
compositor thread. This patch also adds prefers to override the
blocklist to either assume GL is threadsafe
(webgl.threadsafe-gl.force-enabled) and not threadsafe
(webgl.threadsafe-gl.force-disabled).

Differential Revision: https://phabricator.services.mozilla.com/D130634
This commit is contained in:
Andrew Osmond 2021-11-09 17:33:46 +00:00
parent 4c24a1ca7d
commit 925d668db0
5 changed files with 43 additions and 10 deletions

View File

@ -84,7 +84,8 @@ class gfxVarReceiver;
_(UseEGL, bool, false) \
_(DrmRenderDevice, nsCString, nsCString()) \
_(UseDMABuf, bool, false) \
_(WebRenderRequiresHardwareDriver, bool, false)
_(WebRenderRequiresHardwareDriver, bool, false) \
_(SupportsThreadsafeGL, bool, false)
/* Add new entries above this line. */

View File

@ -6,6 +6,7 @@
#include "CanvasManagerParent.h"
#include "mozilla/dom/WebGLParent.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/webrender/RenderThread.h"
@ -19,19 +20,30 @@ CanvasManagerParent::ManagerSet CanvasManagerParent::sManagers;
Endpoint<PCanvasManagerParent>&& aEndpoint) {
MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread());
nsCOMPtr<nsIThread> owningThread = wr::RenderThread::GetRenderThread();
MOZ_ASSERT(owningThread);
auto manager = MakeRefPtr<CanvasManagerParent>();
owningThread->Dispatch(NewRunnableMethod<Endpoint<PCanvasManagerParent>&&>(
"CanvasManagerParent::Bind", manager, &CanvasManagerParent::Bind,
std::move(aEndpoint)));
if (gfxVars::SupportsThreadsafeGL()) {
manager->Bind(std::move(aEndpoint));
} else {
nsCOMPtr<nsIThread> owningThread;
owningThread = wr::RenderThread::GetRenderThread();
MOZ_ASSERT(owningThread);
owningThread->Dispatch(NewRunnableMethod<Endpoint<PCanvasManagerParent>&&>(
"CanvasManagerParent::Bind", manager, &CanvasManagerParent::Bind,
std::move(aEndpoint)));
}
}
/* static */ void CanvasManagerParent::Shutdown() {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIThread> owningThread = wr::RenderThread::GetRenderThread();
nsCOMPtr<nsISerialEventTarget> owningThread;
if (gfxVars::SupportsThreadsafeGL()) {
owningThread = layers::CompositorThread();
} else {
owningThread = wr::RenderThread::GetRenderThread();
}
if (!owningThread) {
return;
}

View File

@ -629,8 +629,10 @@ void GPUParent::ActorDestroy(ActorDestroyReason aWhy) {
mVsyncBridge = nullptr;
}
RemoteDecoderManagerParent::ShutdownVideoBridge();
CompositorThreadHolder::Shutdown();
// This could be running on either the Compositor or the Renderer
// thread.
CanvasManagerParent::Shutdown();
CompositorThreadHolder::Shutdown();
// There is a case that RenderThread exists when gfxVars::UseWebRender()
// is false. This could happen when WebRender was fallbacked to
// compositor.

View File

@ -1319,10 +1319,11 @@ void gfxPlatform::ShutdownLayersIPC() {
gfx::CanvasManagerChild::Shutdown();
layers::CompositorManagerChild::Shutdown();
layers::ImageBridgeChild::ShutDown();
// This could be running on either the Compositor or the Renderer thread.
gfx::CanvasManagerParent::Shutdown();
// This has to happen after shutting down the child protocols.
layers::CompositorThreadHolder::Shutdown();
image::ImageMemoryReporter::ShutdownForWebRender();
gfx::CanvasManagerParent::Shutdown();
// There is a case that RenderThread exists when UseWebRender() is
// false. This could happen when WebRender was fallbacked to compositor.
if (wr::RenderThread::Get()) {
@ -2727,6 +2728,11 @@ void gfxPlatform::InitWebGLConfig() {
IsFeatureOk(nsIGfxInfo::FEATURE_ALLOW_WEBGL_OUT_OF_PROCESS);
gfxVars::SetAllowWebglOop(allowWebGLOop);
bool threadsafeGL = IsFeatureOk(nsIGfxInfo::FEATURE_THREADSAFE_GL);
threadsafeGL |= StaticPrefs::webgl_threadsafe_gl_force_enabled_AtStartup();
threadsafeGL &= !StaticPrefs::webgl_threadsafe_gl_force_disabled_AtStartup();
gfxVars::SetSupportsThreadsafeGL(threadsafeGL);
if (kIsAndroid) {
// Don't enable robust buffer access on Adreno 630 devices.
// It causes the linking of some shaders to fail. See bug 1485441.

View File

@ -11864,6 +11864,18 @@
value: 100000 # 100KB
mirror: always
# Override the blocklist to assume that GL is threadsafe.
- name: webgl.threadsafe-gl.force-enabled
type: bool
value: false
mirror: once
# Override the blocklist to assume that GL is not threadsafe.
- name: webgl.threadsafe-gl.force-disabled
type: bool
value: false
mirror: once
- name: webgl.override-unmasked-renderer
type: String
value: ""