Bug 1010969 - Call RemoveTextureFromCompositable at the end of updates. r=sotaro

This commit is contained in:
Nicolas Silva 2014-05-16 17:25:23 +02:00
parent e283a459e1
commit 7de3712fc0
5 changed files with 61 additions and 14 deletions

View File

@ -52,9 +52,10 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType,
void
CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
AutoRemoveTexture autoRemove(this);
if (mBuffer &&
(mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) {
GetForwarder()->RemoveTextureFromCompositable(this, mBuffer);
autoRemove.mTexture = mBuffer;
mBuffer = nullptr;
}

View File

@ -196,5 +196,11 @@ CompositableClient::OnTransaction()
{
}
void
CompositableClient::RemoveTexture(TextureClient* aTexture)
{
mForwarder->RemoveTextureFromCompositable(this, aTexture);
}
} // namespace layers
} // namespace mozilla

View File

@ -145,6 +145,15 @@ public:
*/
virtual void ClearCachedResources() {}
/**
* Should be called when deataching a TextureClient from a Compositable, because
* some platforms need to do some extra book keeping when this happens (for
* example to properly keep track of fences on Gonk).
*
* See AutoRemoveTexture to automatically invoke this at the end of a scope.
*/
virtual void RemoveTexture(TextureClient* aTexture);
static CompositableClient* FromIPDLActor(PCompositableChild* aActor);
/**
@ -175,6 +184,29 @@ protected:
friend class CompositableChild;
};
/**
* Helper to call RemoveTexture at the end of a scope.
*/
struct AutoRemoveTexture
{
AutoRemoveTexture(CompositableClient* aCompositable,
TextureClient* aTexture = nullptr)
: mTexture(aTexture)
, mCompositable(aCompositable)
{}
~AutoRemoveTexture()
{
if (mCompositable && mTexture) {
mCompositable->RemoveTexture(mTexture);
}
}
RefPtr<TextureClient> mTexture;
private:
CompositableClient* mCompositable;
};
} // namespace
} // namespace

View File

@ -111,8 +111,14 @@ ImageClient::CreateImageClient(CompositableType aCompositableHostType,
}
void
ImageClient::RemoveTextureFromCompositable(TextureClient* aTexture,
AsyncTransactionTracker* aAsyncTransactionTracker)
ImageClient::RemoveTexture(TextureClient* aTexture)
{
RemoveTextureWithTracker(aTexture, nullptr);
}
void
ImageClient::RemoveTextureWithTracker(TextureClient* aTexture,
AsyncTransactionTracker* aAsyncTransactionTracker)
{
#ifdef MOZ_WIDGET_GONK
// AsyncTransactionTracker is supported only on ImageBridge.
@ -171,7 +177,7 @@ ImageClientSingle::FlushAllImages(bool aExceptFront,
AsyncTransactionTracker* aAsyncTransactionTracker)
{
if (!aExceptFront && mFrontBuffer) {
RemoveTextureFromCompositable(mFrontBuffer, aAsyncTransactionTracker);
RemoveTextureWithTracker(mFrontBuffer, aAsyncTransactionTracker);
mFrontBuffer = nullptr;
} else if(aAsyncTransactionTracker) {
// already flushed
@ -184,11 +190,11 @@ ImageClientBuffered::FlushAllImages(bool aExceptFront,
AsyncTransactionTracker* aAsyncTransactionTracker)
{
if (!aExceptFront && mFrontBuffer) {
RemoveTextureFromCompositable(mFrontBuffer);
RemoveTexture(mFrontBuffer);
mFrontBuffer = nullptr;
}
if (mBackBuffer) {
RemoveTextureFromCompositable(mBackBuffer, aAsyncTransactionTracker);
RemoveTextureWithTracker(mBackBuffer, aAsyncTransactionTracker);
mBackBuffer = nullptr;
}
}
@ -217,13 +223,13 @@ ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer,
return true;
}
AutoRemoveTexture autoRemoveTexture(this);
if (image->AsSharedImage() && image->AsSharedImage()->GetTextureClient(this)) {
// fast path: no need to allocate and/or copy image data
RefPtr<TextureClient> texture = image->AsSharedImage()->GetTextureClient(this);
if (mFrontBuffer) {
RemoveTextureFromCompositable(mFrontBuffer);
}
autoRemoveTexture.mTexture = mFrontBuffer;
mFrontBuffer = texture;
if (!AddTextureClient(texture)) {
mFrontBuffer = nullptr;
@ -239,7 +245,7 @@ ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer,
}
if (mFrontBuffer && mFrontBuffer->IsImmutable()) {
RemoveTextureFromCompositable(mFrontBuffer);
autoRemoveTexture.mTexture = mFrontBuffer;
mFrontBuffer = nullptr;
}
@ -283,7 +289,7 @@ ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer,
gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
if (mFrontBuffer) {
RemoveTextureFromCompositable(mFrontBuffer);
autoRemoveTexture.mTexture = mFrontBuffer;
mFrontBuffer = nullptr;
}
@ -304,7 +310,7 @@ ImageClientSingle::UpdateImageInternal(ImageContainer* aContainer,
if (mFrontBuffer &&
(mFrontBuffer->IsImmutable() || mFrontBuffer->GetSize() != size)) {
RemoveTextureFromCompositable(mFrontBuffer);
autoRemoveTexture.mTexture = mFrontBuffer;
mFrontBuffer = nullptr;
}

View File

@ -75,8 +75,10 @@ public:
virtual void FlushAllImages(bool aExceptFront,
AsyncTransactionTracker* aAsyncTransactionTracker) {}
virtual void RemoveTextureFromCompositable(TextureClient* aTexture,
AsyncTransactionTracker* aAsyncTransactionTracker = nullptr);
virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE;
void RemoveTextureWithTracker(TextureClient* aTexture,
AsyncTransactionTracker* aAsyncTransactionTracker = nullptr);
protected:
ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,