Bug 912766. Funky refcounting to keep the gfxWindowsSurface alive during transport. r=mattwoodrow

This commit is contained in:
Nicholas Cameron 2013-09-24 13:14:12 +12:00
parent caf72f56bd
commit 446d7ab751
8 changed files with 86 additions and 25 deletions

View File

@ -107,7 +107,7 @@ CanvasClient2D::CreateBufferTextureClient(gfx::SurfaceFormat aFormat)
void
DeprecatedCanvasClient2D::Updated()
{
mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->GetDescriptor());
mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->LockSurfaceDescriptor());
}
@ -158,7 +158,7 @@ DeprecatedCanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
void
DeprecatedCanvasClientSurfaceStream::Updated()
{
mForwarder->UpdateTextureNoSwap(this, 1, mDeprecatedTextureClient->GetDescriptor());
mForwarder->UpdateTextureNoSwap(this, 1, mDeprecatedTextureClient->LockSurfaceDescriptor());
}
@ -204,7 +204,7 @@ DeprecatedCanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLaye
}
SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf);
mDeprecatedTextureClient->SetDescriptor(grallocSurf->GetDescriptor());
mDeprecatedTextureClient->SetDescriptor(grallocSurf->LockSurfaceDescriptor());
#else
printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!");
MOZ_ASSERT(false);

View File

@ -171,6 +171,8 @@ ContentClientRemoteBuffer::CreateAndAllocateDeprecatedTextureClient(RefPtr<Depre
MOZ_ASSERT(aClient, "Failed to create texture client");
if (!aClient->EnsureAllocated(mSize, mContentType)) {
NS_WARNING("Could not allocate texture client");
aClient->SetFlags(0);
aClient = nullptr;
return false;
}
}
@ -207,6 +209,8 @@ ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType,
if (aFlags & BUFFER_COMPONENT_ALPHA) {
if (!CreateAndAllocateDeprecatedTextureClient(mDeprecatedTextureClientOnWhite)) {
mDeprecatedTextureClient->SetFlags(0);
mDeprecatedTextureClient = nullptr;
return;
}
mTextureInfo.mTextureFlags |= TEXTURE_COMPONENT_ALPHA;
@ -240,6 +244,9 @@ ContentClientRemoteBuffer::CreateBuffer(ContentType aType,
RefPtr<gfx::DrawTarget>* aWhiteDT)
{
BuildDeprecatedTextureClients(aType, aRect, aFlags);
if (!mDeprecatedTextureClient) {
return;
}
if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(
mDeprecatedTextureClient->BackendType())) {
@ -337,11 +344,23 @@ void
ContentClientDoubleBuffered::CreateFrontBufferAndNotify(const nsIntRect& aBufferRect)
{
if (!CreateAndAllocateDeprecatedTextureClient(mFrontClient)) {
mDeprecatedTextureClient->SetFlags(0);
mDeprecatedTextureClient = nullptr;
if (mDeprecatedTextureClientOnWhite) {
mDeprecatedTextureClientOnWhite->SetFlags(0);
mDeprecatedTextureClientOnWhite = nullptr;
}
return;
}
if (mTextureInfo.mTextureFlags & TEXTURE_COMPONENT_ALPHA) {
if (!CreateAndAllocateDeprecatedTextureClient(mFrontClientOnWhite)) {
mDeprecatedTextureClient->SetFlags(0);
mDeprecatedTextureClient = nullptr;
mDeprecatedTextureClientOnWhite->SetFlags(0);
mDeprecatedTextureClientOnWhite = nullptr;
mFrontClient->SetFlags(0);
mFrontClient = nullptr;
return;
}
}
@ -350,11 +369,11 @@ ContentClientDoubleBuffered::CreateFrontBufferAndNotify(const nsIntRect& aBuffer
mFrontBufferRotation = nsIntPoint();
mForwarder->CreatedDoubleBuffer(this,
*mFrontClient->GetDescriptor(),
*mDeprecatedTextureClient->GetDescriptor(),
*mFrontClient->LockSurfaceDescriptor(),
*mDeprecatedTextureClient->LockSurfaceDescriptor(),
mTextureInfo,
mFrontClientOnWhite ? mFrontClientOnWhite->GetDescriptor() : nullptr,
mDeprecatedTextureClientOnWhite ? mDeprecatedTextureClientOnWhite->GetDescriptor() : nullptr);
mFrontClientOnWhite ? mFrontClientOnWhite->LockSurfaceDescriptor() : nullptr,
mDeprecatedTextureClientOnWhite ? mDeprecatedTextureClientOnWhite->LockSurfaceDescriptor() : nullptr);
}
void
@ -566,9 +585,9 @@ void
ContentClientSingleBuffered::CreateFrontBufferAndNotify(const nsIntRect& aBufferRect)
{
mForwarder->CreatedSingleBuffer(this,
*mDeprecatedTextureClient->GetDescriptor(),
*mDeprecatedTextureClient->LockSurfaceDescriptor(),
mTextureInfo,
mDeprecatedTextureClientOnWhite ? mDeprecatedTextureClientOnWhite->GetDescriptor() : nullptr);
mDeprecatedTextureClientOnWhite ? mDeprecatedTextureClientOnWhite->LockSurfaceDescriptor() : nullptr);
}
void

View File

@ -449,7 +449,7 @@ DeprecatedImageClientSingle::UpdateImage(ImageContainer* aContainer,
void
DeprecatedImageClientSingle::Updated()
{
mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->GetDescriptor());
mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->LockSurfaceDescriptor());
}
ImageClientBridge::ImageClientBridge(CompositableForwarder* aFwd,

View File

@ -410,8 +410,6 @@ public:
return gfx::BACKEND_NONE;
}
virtual SurfaceDescriptor* LockSurfaceDescriptor() { return GetDescriptor(); }
virtual void ReleaseResources() {}
/**
* This unlocks the current DrawableTexture and allows the host to composite
@ -441,6 +439,11 @@ public:
mDescriptor = aDescriptor;
}
SurfaceDescriptor* GetDescriptor() { return &mDescriptor; }
/**
* Use LockSurfaceDescriptor to get the descriptor if it will be sent across IPC.
* Use GetDescriptor if you want to keep the descriptor on one thread.
*/
virtual SurfaceDescriptor* LockSurfaceDescriptor() { return GetDescriptor(); }
CompositableForwarder* GetForwarder() const
{

View File

@ -342,9 +342,9 @@ ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData,
MOZ_ASSERT((destBounds.y % size.height) + destBounds.height <= size.height,
"updated region lies across rotation boundaries!");
mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->GetBuffer(), &destRegion);
mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->LockSurfaceDescriptor(), &destRegion);
if (mDeprecatedTextureHostOnWhite) {
mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->GetBuffer(), &destRegion);
mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->LockSurfaceDescriptor(), &destRegion);
}
mInitialised = true;
@ -463,9 +463,9 @@ ContentHostDoubleBuffered::UpdateThebes(const ThebesBufferData& aData,
mDeprecatedTextureHostOnWhite = mBackHostOnWhite;
mBackHostOnWhite = oldFront;
mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->GetBuffer());
mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->LockSurfaceDescriptor());
if (mDeprecatedTextureHostOnWhite) {
mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->GetBuffer());
mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->LockSurfaceDescriptor());
}
mInitialised = true;

View File

@ -697,6 +697,7 @@ public:
SurfaceDescriptor* GetBuffer() const { return mBuffer; }
virtual SurfaceDescriptor* LockSurfaceDescriptor() const { return GetBuffer(); }
/**
* Set a SurfaceDescriptor for this texture host. By setting a buffer and

View File

@ -513,10 +513,13 @@ DeprecatedTextureHostDIB::UpdateImpl(const SurfaceDescriptor& aImage,
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorDIB);
MOZ_ASSERT(mCompositor, "Must have compositor to update.");
if (!mCompositor->device()) {
return;
}
// We added an extra ref for transport, so we shouldn't AddRef now.
nsRefPtr<gfxWindowsSurface> surf =
reinterpret_cast<gfxWindowsSurface*>(aImage.get_SurfaceDescriptorDIB().surface());
// We added an extra ref for transport, we can release it now.
surf->Release();
dont_AddRef(reinterpret_cast<gfxWindowsSurface*>(aImage.get_SurfaceDescriptorDIB().surface()));
gfxIntSize size = surf->GetSize();
mSize = IntSize(size.width, size.height);
@ -728,6 +731,8 @@ DeprecatedTextureClientDIB::~DeprecatedTextureClientDIB()
{
MOZ_COUNT_DTOR(DeprecatedTextureClientDIB);
Unlock();
// It is OK not to dealloc the surface descriptor because it is only a pointer
// to mSurface and we will release our strong reference to that automatically.
mDescriptor = SurfaceDescriptor();
mDrawTarget = nullptr;
}
@ -753,19 +758,28 @@ DeprecatedTextureClientDIB::EnsureAllocated(gfx::IntSize aSize,
{
NS_WARNING("Could not create surface");
mSurface = nullptr;
mDescriptor = SurfaceDescriptor();
return false;
}
mSize = aSize;
mContentType = aType;
mDescriptor = SurfaceDescriptorDIB(reinterpret_cast<uintptr_t>(mSurface.get()));
// The host will release this ref when it receives the surface descriptor.
// We AddRef in case we die before the host receives the pointer.
mSurface->AddRef();
return true;
}
SurfaceDescriptor*
DeprecatedTextureClientDIB::LockSurfaceDescriptor()
{
// The host will release this ref when it receives the surface descriptor.
// We AddRef in case we die before the host receives the pointer.
NS_ASSERTION(mSurface == reinterpret_cast<gfxWindowsSurface*>(mDescriptor.get_SurfaceDescriptorDIB().surface()),
"SurfaceDescriptor is not up to date");
mSurface->AddRef();
return GetDescriptor();
}
gfxASurface*
DeprecatedTextureClientDIB::LockSurface()
{

View File

@ -169,8 +169,6 @@ protected:
virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
nsIntRegion* aRegion,
nsIntPoint *aOffset = nullptr) MOZ_OVERRIDE;
nsRefPtr<IDirect3DTexture9> mTexture;
};
class DeprecatedTextureHostYCbCrD3D9 : public DeprecatedTextureHost
@ -218,13 +216,38 @@ public:
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() { return "DeprecatedTextureHostDIB"; }
#endif
virtual void SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator) MOZ_OVERRIDE
{
MOZ_ASSERT(aBuffer->type() == SurfaceDescriptor::TSurfaceDescriptorDIB);
// We are responsible for keeping the surface alive. But the client will have AddRefed it
// for transport to the host. So we don't need to AddRef here.
mSurface = dont_AddRef(reinterpret_cast<gfxWindowsSurface*>(aBuffer->get_SurfaceDescriptorDIB().surface()));
DeprecatedTextureHost::SetBuffer(aBuffer, aAllocator);
}
virtual SurfaceDescriptor* LockSurfaceDescriptor() const MOZ_OVERRIDE
{
NS_ASSERTION(!mBuffer ||
(mBuffer->type() == SurfaceDescriptor::TSurfaceDescriptorDIB &&
mSurface == reinterpret_cast<gfxWindowsSurface*>(mBuffer->get_SurfaceDescriptorDIB().surface())),
"SurfaceDescriptor is not up to date");
// We are either going to pass the surface descriptor to the content thread
// or we are going to give the our surface descriptor to a compositable host,
// pretending that it is from the client thread. In either case it is going to
// get released, so we need to AddRef here.
if (mBuffer) {
mSurface->AddRef();
}
return DeprecatedTextureHost::LockSurfaceDescriptor();
}
protected:
virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
nsIntRegion* aRegion,
nsIntPoint *aOffset = nullptr) MOZ_OVERRIDE;
nsRefPtr<IDirect3DTexture9> mTexture;
// Used to keep the surface alive if the host has responsibility for the
// lifetime of the surface.
nsRefPtr<gfxWindowsSurface> mSurface;
};
// If we want to use d3d9 textures for transport, use this class.
@ -295,6 +318,7 @@ public:
}
virtual void Unlock() MOZ_OVERRIDE;
virtual SurfaceDescriptor* LockSurfaceDescriptor() MOZ_OVERRIDE;
virtual void SetDescriptor(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
virtual gfxASurface::gfxContentType GetContentType() MOZ_OVERRIDE
{