Bug 1354411 - Rebuild CompositorSessions if WebRender is disabled r=kats

When WebRender creation is failed, WebRender is disabled in gecko. There is a case that WebRenderBridgeParents exist when WebRender is disabled. To handle this, gecko needs to rebuild all CompositorSessions.

There is also a problem related to gfxVars::UseWebRender on compositor thread. If e10s is enabled, but no-gpu process(default on linux and mac), gfxVars::UseWebRender change is soon notified by compositor thread tasks. If WebRender creation failure happens at 2nd WebRender creation, several WebRenderBridgeParents for 1st WebRender could exist. IPC messages from WebRenderLayerManager are normally async, then there is a chance that the WebRenderBridgeParents receive the messages after the gfxVars::UseWebRender change. Further the gfxVars::UseWebRender change in content process could be delayed than WebRenderBridgeParents, then content process does not have a way to stop sending PWebRenderBridge IPC until the change of gfxVars::UseWebRender is received. WebRenderBridgeParent related tasks handle the message, but some tasks are done based on gfxVars::UseWebRender. At this time, gfxVars::UseWebRender returned false on compositor thread, then it cause unexpected result for WebRenderBridgeParent and WebRender. To addres this inconsistent situation, WebRenderBridgeParent related tasks on compositor thread stop to use gfxVars::UseWebRender.
This commit is contained in:
sotaro 2017-08-04 14:36:41 +09:00
parent 0e18c8bb3c
commit a773ee4276
16 changed files with 50 additions and 29 deletions

View File

@ -13,6 +13,7 @@
#include "mozilla/Sprintf.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/layers/APZCTreeManagerChild.h"
#include "mozilla/layers/CompositorBridgeParent.h"
@ -419,6 +420,27 @@ GPUProcessManager::SimulateDeviceReset()
}
}
void
GPUProcessManager::DisableWebRender()
{
MOZ_ASSERT(gfx::gfxVars::UseWebRender());
if (!gfx::gfxVars::UseWebRender()) {
return;
}
// Disable WebRender
gfx::gfxConfig::GetFeature(gfx::Feature::WEBRENDER).ForceDisable(
gfx::FeatureStatus::Unavailable,
"WebRender initialization failed",
NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBRENDER_INITIALIZE"));
gfx::gfxVars::SetUseWebRender(false);
if (mProcess) {
OnRemoteProcessDeviceReset(mProcess);
} else {
OnInProcessDeviceReset();
}
}
void
GPUProcessManager::OnInProcessDeviceReset()
{

View File

@ -146,6 +146,7 @@ public:
void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;
void SimulateDeviceReset();
void DisableWebRender();
void OnInProcessDeviceReset();
void OnRemoteProcessDeviceReset(GPUProcessHost* aHost) override;
void NotifyListenersOnCompositeDeviceReset();

View File

@ -118,7 +118,7 @@ CompositableHost::RemoveMaskEffect()
}
/* static */ already_AddRefed<CompositableHost>
CompositableHost::Create(const TextureInfo& aTextureInfo)
CompositableHost::Create(const TextureInfo& aTextureInfo, bool aUseWebRender)
{
RefPtr<CompositableHost> result;
switch (aTextureInfo.mCompositableType) {
@ -129,21 +129,21 @@ CompositableHost::Create(const TextureInfo& aTextureInfo)
result = new TiledContentHost(aTextureInfo);
break;
case CompositableType::IMAGE:
if (gfxVars::UseWebRender()) {
if (aUseWebRender) {
result = new WebRenderImageHost(aTextureInfo);
} else {
result = new ImageHost(aTextureInfo);
}
break;
case CompositableType::CONTENT_SINGLE:
if (gfxVars::UseWebRender()) {
if (aUseWebRender) {
result = new WebRenderImageHost(aTextureInfo);
} else {
result = new ContentHostSingleBuffered(aTextureInfo);
}
break;
case CompositableType::CONTENT_DOUBLE:
MOZ_ASSERT(!gfxVars::UseWebRender());
MOZ_ASSERT(!aUseWebRender);
result = new ContentHostDoubleBuffered(aTextureInfo);
break;
default:

View File

@ -89,7 +89,7 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableHost)
explicit CompositableHost(const TextureInfo& aTextureInfo);
static already_AddRefed<CompositableHost> Create(const TextureInfo& aTextureInfo);
static already_AddRefed<CompositableHost> Create(const TextureInfo& aTextureInfo, bool aUseWebRender);
virtual CompositableType GetType() = 0;

View File

@ -98,8 +98,7 @@ WrapWithWebRenderTextureHost(ISurfaceAllocator* aDeallocator,
LayersBackend aBackend,
TextureFlags aFlags)
{
if (!gfx::gfxVars::UseWebRender() ||
(aFlags & TextureFlags::SNAPSHOT) ||
if ((aFlags & TextureFlags::SNAPSHOT) ||
(aBackend != LayersBackend::LAYERS_WR) ||
(!aDeallocator->UsesImageBridge() && !aDeallocator->AsCompositorBridgeParentBase())) {
return false;

View File

@ -241,7 +241,8 @@ CompositableParentManager::DestroyActor(const OpDestroy& aOp)
RefPtr<CompositableHost>
CompositableParentManager::AddCompositable(const CompositableHandle& aHandle,
const TextureInfo& aInfo)
const TextureInfo& aInfo,
bool aUseWebRender)
{
if (mCompositables.find(aHandle.Value()) != mCompositables.end()) {
NS_ERROR("Client should not allocate duplicate handles");
@ -252,7 +253,7 @@ CompositableParentManager::AddCompositable(const CompositableHandle& aHandle,
return nullptr;
}
RefPtr<CompositableHost> host = CompositableHost::Create(aInfo);
RefPtr<CompositableHost> host = CompositableHost::Create(aInfo, aUseWebRender);
if (!host) {
return nullptr;
}

View File

@ -41,7 +41,8 @@ public:
RefPtr<CompositableHost> AddCompositable(
const CompositableHandle& aHandle,
const TextureInfo& aInfo);
const TextureInfo& aInfo,
bool aUseWebRender);
RefPtr<CompositableHost> FindCompositable(const CompositableHandle& aHandle);
bool AddReadLocks(ReadLockArray&& aReadLocks);

View File

@ -537,7 +537,7 @@ CompositorBridgeParent::RecvWaitOnTransactionProcessed()
mozilla::ipc::IPCResult
CompositorBridgeParent::RecvFlushRendering()
{
if (gfxVars::UseWebRender()) {
if (mOptions.UseWebRender()) {
mWrBridge->FlushRendering(/* aIsSync */ true);
return IPC_OK();
}
@ -552,7 +552,7 @@ CompositorBridgeParent::RecvFlushRendering()
mozilla::ipc::IPCResult
CompositorBridgeParent::RecvFlushRenderingAsync()
{
if (gfxVars::UseWebRender()) {
if (mOptions.UseWebRender()) {
mWrBridge->FlushRendering(/* aIsSync */ false);
return IPC_OK();
}
@ -706,7 +706,7 @@ CompositorBridgeParent::PauseComposition()
if (!mPaused) {
mPaused = true;
if (!gfxVars::UseWebRender()) {
if (!mOptions.UseWebRender()) {
mCompositor->Pause();
} else {
mWrBridge->Pause();
@ -727,7 +727,7 @@ CompositorBridgeParent::ResumeComposition()
MonitorAutoLock lock(mResumeCompositionMonitor);
bool resumed = gfxVars::UseWebRender() ? mWrBridge->Resume() : mCompositor->Resume();
bool resumed = mOptions.UseWebRender() ? mWrBridge->Resume() : mCompositor->Resume();
if (!resumed) {
#ifdef MOZ_WIDGET_ANDROID
// We can't get a surface. This could be because the activity changed between

View File

@ -328,7 +328,7 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable,
CompositableHandle handle(id);
aCompositable->InitIPDL(handle);
SendNewCompositable(handle, aCompositable->GetTextureInfo());
SendNewCompositable(handle, aCompositable->GetTextureInfo(), GetCompositorBackendType());
}
void

View File

@ -248,9 +248,12 @@ mozilla::ipc::IPCResult ImageBridgeParent::RecvWillClose()
}
mozilla::ipc::IPCResult
ImageBridgeParent::RecvNewCompositable(const CompositableHandle& aHandle, const TextureInfo& aInfo)
ImageBridgeParent::RecvNewCompositable(const CompositableHandle& aHandle,
const TextureInfo& aInfo,
const LayersBackend& aLayersBackend)
{
RefPtr<CompositableHost> host = AddCompositable(aHandle, aInfo);
bool useWebRender = aLayersBackend == LayersBackend::LAYERS_WR;
RefPtr<CompositableHost> host = AddCompositable(aHandle, aInfo, useWebRender);
if (!host) {
return IPC_FAIL_NO_REASON(this);
}

View File

@ -87,7 +87,8 @@ public:
virtual bool DeallocPTextureParent(PTextureParent* actor) override;
virtual mozilla::ipc::IPCResult RecvNewCompositable(const CompositableHandle& aHandle,
const TextureInfo& aInfo) override;
const TextureInfo& aInfo,
const LayersBackend& aLayersBackend) override;
virtual mozilla::ipc::IPCResult RecvReleaseCompositable(const CompositableHandle& aHandle) override;
PMediaSystemResourceManagerParent* AllocPMediaSystemResourceManagerParent() override;

View File

@ -1003,7 +1003,7 @@ LayerTransactionParent::AsLayer(const LayerHandle& aHandle)
mozilla::ipc::IPCResult
LayerTransactionParent::RecvNewCompositable(const CompositableHandle& aHandle, const TextureInfo& aInfo)
{
if (!AddCompositable(aHandle, aInfo)) {
if (!AddCompositable(aHandle, aInfo, /* aUseWebRender */ false)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();

View File

@ -60,7 +60,7 @@ parent:
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend, TextureFlags aTextureFlags, uint64_t aSerial, MaybeExternalImageId aExternalImageId);
async PMediaSystemResourceManager();
sync NewCompositable(CompositableHandle aHandle, TextureInfo aInfo);
sync NewCompositable(CompositableHandle aHandle, TextureInfo aInfo, LayersBackend aBackend);
async ReleaseCompositable(CompositableHandle aHandle);
};

View File

@ -809,7 +809,6 @@ WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const ExternalImage
MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
RefPtr<CompositableHost> host = FindCompositable(aHandle);
MOZ_ASSERT(host->AsWebRenderImageHost());
WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
if (!wrHost) {
return IPC_OK();
@ -1392,7 +1391,7 @@ WebRenderBridgeParent::RecvNewCompositable(const CompositableHandle& aHandle,
if (mDestroyed) {
return IPC_OK();
}
if (!AddCompositable(aHandle, aInfo)) {
if (!AddCompositable(aHandle, aInfo, /* aUseWebRender */ true)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();

View File

@ -207,7 +207,6 @@ void WebRenderImageHost::Attach(Layer* aLayer,
TextureSourceProvider* aProvider,
AttachFlags aFlags)
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
}
void

View File

@ -1294,12 +1294,7 @@ nsBaseWidget::CreateCompositorSession(int aWidth,
if (textureFactoryIdentifier.mParentBackend != LayersBackend::LAYERS_WR) {
retry = true;
DestroyCompositor();
// Disable WebRender
gfx::gfxConfig::GetFeature(gfx::Feature::WEBRENDER).ForceDisable(
gfx::FeatureStatus::Unavailable,
"WebRender initialization failed",
NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBRENDER_INITIALIZE"));
gfx::gfxVars::SetUseWebRender(false);
gfx::GPUProcessManager::Get()->DisableWebRender();
}
}