diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index eeefde7cdb3..8b44605c55e 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -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); diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 897cdc7589e..610e4108913 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -171,6 +171,8 @@ ContentClientRemoteBuffer::CreateAndAllocateDeprecatedTextureClient(RefPtrEnsureAllocated(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* 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 diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index dadf2eb2cec..fdca9c3b1cc 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -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, diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 94ce0ff5d0b..2b6f47e81d2 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -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 { diff --git a/gfx/layers/composite/ContentHost.cpp b/gfx/layers/composite/ContentHost.cpp index 2df0293491f..be29e990fcc 100644 --- a/gfx/layers/composite/ContentHost.cpp +++ b/gfx/layers/composite/ContentHost.cpp @@ -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; diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index 312421df15f..1771f1a4dc6 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -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 diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index 874ad5ddbb4..3fd6fc4b5f0 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -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 surf = - reinterpret_cast(aImage.get_SurfaceDescriptorDIB().surface()); - // We added an extra ref for transport, we can release it now. - surf->Release(); + dont_AddRef(reinterpret_cast(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(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(mDescriptor.get_SurfaceDescriptorDIB().surface()), + "SurfaceDescriptor is not up to date"); + mSurface->AddRef(); + return GetDescriptor(); +} + gfxASurface* DeprecatedTextureClientDIB::LockSurface() { diff --git a/gfx/layers/d3d9/TextureD3D9.h b/gfx/layers/d3d9/TextureD3D9.h index 4f5048f41eb..70c68bd9a0a 100644 --- a/gfx/layers/d3d9/TextureD3D9.h +++ b/gfx/layers/d3d9/TextureD3D9.h @@ -169,8 +169,6 @@ protected: virtual void UpdateImpl(const SurfaceDescriptor& aSurface, nsIntRegion* aRegion, nsIntPoint *aOffset = nullptr) MOZ_OVERRIDE; - - nsRefPtr 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(aBuffer->get_SurfaceDescriptorDIB().surface())); + DeprecatedTextureHost::SetBuffer(aBuffer, aAllocator); + } + virtual SurfaceDescriptor* LockSurfaceDescriptor() const MOZ_OVERRIDE + { + NS_ASSERTION(!mBuffer || + (mBuffer->type() == SurfaceDescriptor::TSurfaceDescriptorDIB && + mSurface == reinterpret_cast(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 mTexture; + // Used to keep the surface alive if the host has responsibility for the + // lifetime of the surface. + nsRefPtr 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 {