Block compositable updates from stale layers. (bug 1256517 part 4, r=mattwoodrow,nical)

This commit is contained in:
David Anderson 2016-03-23 10:32:34 -07:00
parent 08db4be559
commit db2e8ee11d
13 changed files with 64 additions and 18 deletions

View File

@ -398,6 +398,18 @@ Compositor::ComputeBackdropCopyRect(const gfx::Rect& aRect,
return result;
}
void
Compositor::SetInvalid()
{
mParent = nullptr;
}
bool
Compositor::IsValid() const
{
return !mParent;
}
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
void
Compositor::SetDispAcquireFence(Layer* aLayer, nsIWidget* aWidget)

View File

@ -517,6 +517,11 @@ public:
return mCompositeUntilTime;
}
// A stale Compositor has no CompositorBridgeParent; it will not process
// frames and should not be used.
void SetInvalid();
bool IsValid() const;
protected:
void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
const gfx::Rect& aVisibleRect,

View File

@ -78,8 +78,9 @@ public:
bool mWrappingExistingData;
};
BasicCompositor::BasicCompositor(nsIWidget *aWidget)
: mWidget(aWidget)
BasicCompositor::BasicCompositor(CompositorBridgeParent* aParent, nsIWidget *aWidget)
: Compositor(aParent)
, mWidget(aWidget)
, mDidExternalComposition(false)
{
MOZ_COUNT_CTOR(BasicCompositor);

View File

@ -42,7 +42,7 @@ public:
class BasicCompositor : public Compositor
{
public:
explicit BasicCompositor(nsIWidget *aWidget);
explicit BasicCompositor(CompositorBridgeParent* aParent, nsIWidget *aWidget);
protected:
virtual ~BasicCompositor();

View File

@ -46,8 +46,9 @@ private:
class X11BasicCompositor : public BasicCompositor
{
public:
explicit X11BasicCompositor(nsIWidget *aWidget) : BasicCompositor(aWidget) {}
explicit X11BasicCompositor(CompositorBridgeParent* aParent, nsIWidget *aWidget)
: BasicCompositor(aParent, aWidget)
{}
virtual already_AddRefed<DataTextureSource>
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;

View File

@ -158,8 +158,9 @@ private:
bool mInitOkay;
};
CompositorD3D11::CompositorD3D11(nsIWidget* aWidget)
: mAttachments(nullptr)
CompositorD3D11::CompositorD3D11(CompositorBridgeParent* aParent, nsIWidget* aWidget)
: Compositor(aParent)
, mAttachments(nullptr)
, mWidget(aWidget)
, mHwnd(nullptr)
, mDisableSequenceForNextFrame(false)

View File

@ -42,7 +42,7 @@ struct DeviceAttachmentsD3D11;
class CompositorD3D11 : public Compositor
{
public:
CompositorD3D11(nsIWidget* aWidget);
CompositorD3D11(CompositorBridgeParent* aParent, nsIWidget* aWidget);
~CompositorD3D11();
virtual bool Initialize() override;

View File

@ -74,7 +74,12 @@ bool
CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit,
EditReplyVector& replyv)
{
// Ignore all operations on compositables created on stale compositors. We
// return true because the child is unable to handle errors.
CompositableHost* compositable = CompositableHost::FromIPDLActor(aEdit.compositableParent());
if (compositable->GetCompositor() && compositable->GetCompositor()->IsValid()) {
return true;
}
switch (aEdit.detail().type()) {
case CompositableOperationDetail::TOpPaintTextureRegion: {
@ -121,6 +126,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
}
case CompositableOperationDetail::TOpRemoveTexture: {
const OpRemoveTexture& op = aEdit.detail().get_OpRemoveTexture();
RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent());
MOZ_ASSERT(tex.get());
@ -183,7 +189,9 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
}
}
}
if (textures.Length() > 0) {
compositable->UseTextureHost(textures);
}
if (UsesImageBridge() && compositable->GetLayer()) {
ScheduleComposition(compositable);

View File

@ -1618,22 +1618,23 @@ CompositorBridgeParent::NewCompositor(const nsTArray<LayersBackend>& aBackendHin
for (size_t i = 0; i < aBackendHints.Length(); ++i) {
RefPtr<Compositor> compositor;
if (aBackendHints[i] == LayersBackend::LAYERS_OPENGL) {
compositor = new CompositorOGL(mWidget,
compositor = new CompositorOGL(this,
mWidget,
mEGLSurfaceSize.width,
mEGLSurfaceSize.height,
mUseExternalSurfaceSize);
} else if (aBackendHints[i] == LayersBackend::LAYERS_BASIC) {
#ifdef MOZ_WIDGET_GTK
if (gfxPlatformGtk::GetPlatform()->UseXRender()) {
compositor = new X11BasicCompositor(mWidget);
compositor = new X11BasicCompositor(this, mWidget);
} else
#endif
{
compositor = new BasicCompositor(mWidget);
compositor = new BasicCompositor(this, mWidget);
}
#ifdef XP_WIN
} else if (aBackendHints[i] == LayersBackend::LAYERS_D3D11) {
compositor = new CompositorD3D11(mWidget);
compositor = new CompositorD3D11(this, mWidget);
} else if (aBackendHints[i] == LayersBackend::LAYERS_D3D9) {
compositor = new CompositorD3D9(this, mWidget);
#endif
@ -2212,6 +2213,9 @@ CompositorBridgeParent::ResetCompositorImpl(const nsTArray<LayersBackend>& aBack
return Nothing();
}
if (mCompositor) {
mCompositor->SetInvalid();
}
mCompositor = compositor;
mLayerManager->ChangeCompositor(compositor);

View File

@ -587,6 +587,11 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
case Edit::TOpAttachCompositable: {
const OpAttachCompositable& op = edit.get_OpAttachCompositable();
CompositableHost* host = CompositableHost::FromIPDLActor(op.compositableParent());
if (mPendingCompositorUpdates) {
// Do not attach compositables from old layer trees. Return true since
// content cannot handle errors.
return true;
}
if (!Attach(cast(op.layerParent()), host, false)) {
return false;
}
@ -600,6 +605,11 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
NS_ERROR("CompositableParent not found in the map");
return false;
}
if (mPendingCompositorUpdates) {
// Do not attach compositables from old layer trees. Return true since
// content cannot handle errors.
return true;
}
CompositableHost* host = CompositableHost::FromIPDLActor(compositableParent);
if (!Attach(cast(op.layerParent()), host, true)) {
return false;

View File

@ -83,9 +83,11 @@ CompositorOGL::BindBackdrop(ShaderProgramOGL* aProgram, GLuint aBackdrop, GLenum
aProgram->SetBackdropTextureUnit(aTexUnit - LOCAL_GL_TEXTURE0);
}
CompositorOGL::CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth,
CompositorOGL::CompositorOGL(CompositorBridgeParent* aParent,
nsIWidget *aWidget, int aSurfaceWidth,
int aSurfaceHeight, bool aUseExternalSurfaceSize)
: mWidget(aWidget)
: Compositor(aParent)
, mWidget(aWidget)
, mWidgetSize(-1, -1)
, mSurfaceSize(aSurfaceWidth, aSurfaceHeight)
, mHasBGRA(0)

View File

@ -193,7 +193,8 @@ class CompositorOGL final : public Compositor
std::map<ShaderConfigOGL, ShaderProgramOGL*> mPrograms;
public:
explicit CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth = -1, int aSurfaceHeight = -1,
explicit CompositorOGL(CompositorBridgeParent* aParent,
nsIWidget *aWidget, int aSurfaceWidth = -1, int aSurfaceHeight = -1,
bool aUseExternalSurfaceSize = false);
protected:

View File

@ -112,13 +112,14 @@ static already_AddRefed<Compositor> CreateTestCompositor(LayersBackend backend,
RefPtr<Compositor> compositor;
if (backend == LayersBackend::LAYERS_OPENGL) {
compositor = new CompositorOGL(widget,
compositor = new CompositorOGL(nullptr,
widget,
gCompWidth,
gCompHeight,
true);
compositor->SetDestinationSurfaceSize(IntSize(gCompWidth, gCompHeight));
} else if (backend == LayersBackend::LAYERS_BASIC) {
compositor = new BasicCompositor(widget);
compositor = new BasicCompositor(nullptr, widget);
#ifdef XP_WIN
} else if (backend == LayersBackend::LAYERS_D3D11) {
//compositor = new CompositorD3D11();