Bug 1015718 - Keep the client-side D3D11 texture alive longer so that its destruction does not race with its deserialization. r=bas

This commit is contained in:
Nicolas Silva 2014-07-22 17:49:05 +02:00
parent 9ebf456fef
commit 549b974e67
3 changed files with 38 additions and 0 deletions

View File

@ -81,6 +81,7 @@ public:
TextureChild()
: mForwarder(nullptr)
, mTextureClient(nullptr)
, mKeep(nullptr)
, mIPCOpen(false)
{
}
@ -129,6 +130,7 @@ private:
RefPtr<CompositableForwarder> mForwarder;
RefPtr<TextureClient> mWaitForRecycle;
TextureClient* mTextureClient;
KeepAlive* mKeep;
bool mIPCOpen;
friend class TextureClient;
@ -147,6 +149,7 @@ TextureChild::ActorDestroy(ActorDestroyReason why)
mTextureClient->mActor = nullptr;
}
mWaitForRecycle = nullptr;
delete mKeep;
}
// static
@ -443,6 +446,14 @@ TextureClient::~TextureClient()
// be in Finalize() which is called just before the destructor.
}
void
TextureClient::KeepUntilFullDeallocation(KeepAlive* aKeep)
{
MOZ_ASSERT(mActor);
MOZ_ASSERT(!mActor->mKeep);
mActor->mKeep = aKeep;
}
void TextureClient::ForceRemove()
{
if (mValid && mActor) {

View File

@ -50,6 +50,7 @@ class PTextureChild;
class TextureChild;
class BufferTextureClient;
class TextureClient;
class KeepAlive;
/**
* TextureClient is the abstraction that allows us to share data between the
@ -281,6 +282,14 @@ public:
*/
bool IsValid() const { return mValid; }
/**
* kee the passed object alive until the IPDL actor is destroyed. This can
* help avoid race conditions in some cases.
* It's a temporary hack to ensure that DXGI textures don't get destroyed
* between serialization and deserialization.
*/
void KeepUntilFullDeallocation(KeepAlive* aKeep);
/**
* Create and init the TextureChild/Parent IPDL actor pair.
*
@ -613,6 +622,21 @@ struct TextureClientAutoUnlock
}
};
class KeepAlive
{
public:
virtual ~KeepAlive() {}
};
template<typename T>
class TKeepAlive : public KeepAlive
{
public:
TKeepAlive(T* aData) : mData(aData) {}
protected:
RefPtr<T> mData;
};
}
}
#endif

View File

@ -167,6 +167,9 @@ TextureClientD3D11::TextureClientD3D11(gfx::SurfaceFormat aFormat, TextureFlags
TextureClientD3D11::~TextureClientD3D11()
{
if (mTexture && mActor) {
KeepUntilFullDeallocation(new TKeepAlive<ID3D10Texture2D>(mTexture));
}
#ifdef DEBUG
// An Azure DrawTarget needs to be locked when it gets nullptr'ed as this is
// when it calls EndDraw. This EndDraw should not execute anything so it