Bug 1070308. Add Acquire and Release semantics to SharedSurface. r=jgilbert
This is needed for D3D11 keyed mutex support. The added assertions
also ensure we're doing things at the right times.
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -435,17 +435,20 @@ GLScreenBuffer::Swap(const gfx::IntSize&
return false;
// Attach was successful.
mFront = mBack;
mBack = newBack;
// Fence before copying.
if (mFront) {
- mFront->Surf()->Fence();
+ mFront->Surf()->ProducerRelease();
+ }
+ if (mBack) {
+ mBack->Surf()->ProducerAcquire();
}
if (ShouldPreserveBuffer() &&
mFront &&
mBack)
{
auto src = mFront->Surf();
auto dest = mBack->Surf();
@@ -469,17 +472,23 @@ GLScreenBuffer::Resize(const gfx::IntSiz
{
RefPtr<ShSurfHandle> newBack = mFactory->NewShSurfHandle(size);
if (!newBack)
return false;
if (!Attach(newBack->Surf(), size))
return false;
+ if (mBack)
+ mBack->Surf()->ProducerRelease();
+
mBack = newBack;
+
+ mBack->Surf()->ProducerAcquire();
+
return true;
}
bool
GLScreenBuffer::CreateDraw(const gfx::IntSize& size,
UniquePtr<DrawBuffer>* out_buffer)
{
GLContext* gl = mFactory->mGL;
--- a/gfx/gl/SharedSurface.cpp
+++ b/gfx/gl/SharedSurface.cpp
@@ -205,16 +205,18 @@ SharedSurface::SharedSurface(SharedSurfa
const gfx::IntSize& size,
bool hasAlpha)
: mType(type)
, mAttachType(attachType)
, mGL(gl)
, mSize(size)
, mHasAlpha(hasAlpha)
, mIsLocked(false)
+ , mIsProducerAcquired(false)
+ , mIsConsumerAcquired(false)
#ifdef DEBUG
, mOwningThread(NS_GetCurrentThread())
#endif
{
}
void
SharedSurface::LockProd()
--- a/gfx/gl/SharedSurface.h
+++ b/gfx/gl/SharedSurface.h
@@ -48,16 +48,18 @@ public:
const SharedSurfaceType mType;
const AttachmentType mAttachType;
GLContext* const mGL;
const gfx::IntSize mSize;
const bool mHasAlpha;
protected:
bool mIsLocked;
+ bool mIsProducerAcquired;
+ bool mIsConsumerAcquired;
DebugOnly<nsIThread* const> mOwningThread;
SharedSurface(SharedSurfaceType type,
AttachmentType attachType,
GLContext* gl,
const gfx::IntSize& size,
bool hasAlpha);
@@ -75,17 +77,47 @@ public:
// Unlocking is harmless if we're already unlocked.
void UnlockProd();
protected:
virtual void LockProdImpl() = 0;
virtual void UnlockProdImpl() = 0;
+ virtual void ProducerAcquireImpl() {}
+ virtual void ProducerReleaseImpl() {
+ Fence();
+ }
+ virtual void ConsumerAcquireImpl() {
+ WaitSync();
+ }
+ virtual void ConsumerReleaseImpl() {}
+
public:
+ void ProducerAcquire() {
+ MOZ_ASSERT(!mIsProducerAcquired);
+ ProducerAcquireImpl();
+ mIsProducerAcquired = true;
+ }
+ void ProducerRelease() {
+ MOZ_ASSERT(mIsProducerAcquired);
+ ProducerReleaseImpl();
+ mIsProducerAcquired = false;
+ }
+ void ConsumerAcquire() {
+ MOZ_ASSERT(!mIsConsumerAcquired);
+ ConsumerAcquireImpl();
+ mIsConsumerAcquired = true;
+ }
+ void ConsumerRelease() {
+ MOZ_ASSERT(mIsConsumerAcquired);
+ ConsumerReleaseImpl();
+ mIsConsumerAcquired = false;
+ }
+
virtual void Fence() = 0;
virtual bool WaitSync() = 0;
virtual bool PollSync() = 0;
// Use these if you can. They can only be called from the Content
// thread, though!
void Fence_ContentThread();
bool WaitSync_ContentThread();
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -811,17 +811,16 @@ BufferTextureClient::GetLockedData() con
SharedSurfaceTextureClient::SharedSurfaceTextureClient(TextureFlags aFlags,
gl::SharedSurface* surf)
: TextureClient(aFlags)
, mIsLocked(false)
, mSurf(surf)
, mGL(mSurf->mGL)
{
- mSurf->Fence();
}
SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
{
// the data is owned externally.
}
bool
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -912,17 +912,39 @@ SharedSurfaceTextureHost::GetSize() cons
void
SharedSurfaceTextureHost::EnsureTexSource()
{
MOZ_ASSERT(mIsLocked);
if (mTexSource)
return;
- mSurf->WaitSync();
mTexSource = SharedSurfaceToTexSource(mSurf, mCompositor);
MOZ_ASSERT(mTexSource);
}
+bool
+SharedSurfaceTextureHost::Lock()
+{
+ MOZ_ASSERT(!mIsLocked);
+
+ mSurf->ConsumerAcquire();
+
+ mIsLocked = true;
+
+ EnsureTexSource();
+
+ return true;
+}
+
+void
+SharedSurfaceTextureHost::Unlock()
+{
+ MOZ_ASSERT(mIsLocked);
+ mSurf->ConsumerRelease();
+ mIsLocked = false;
+}
+
+
////////////////////////////////////////////////////////////////////////////////
} // namespace
} // namespace
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -648,17 +648,19 @@ protected:
* A TextureHost for SharedSurfaces
*/
class SharedSurfaceTextureHost : public TextureHost
{
public:
SharedSurfaceTextureHost(TextureFlags aFlags,
const SharedSurfaceDescriptor& aDesc);
- virtual ~SharedSurfaceTextureHost() {};
+ virtual ~SharedSurfaceTextureHost() {
+ MOZ_ASSERT(!mIsLocked);
+ }
virtual void DeallocateDeviceData() MOZ_OVERRIDE {};
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE {
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
}
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE {
@@ -667,27 +669,19 @@ public:
if (aCompositor == mCompositor)
return;
mTexSource = nullptr;
mCompositor = aCompositor;
}
public:
- virtual bool Lock() MOZ_OVERRIDE {
- MOZ_ASSERT(!mIsLocked);
- mIsLocked = true;
- EnsureTexSource();
- return true;
- }
- virtual void Unlock() MOZ_OVERRIDE {
- MOZ_ASSERT(mIsLocked);
- mIsLocked = false;
- }
+ virtual bool Lock() MOZ_OVERRIDE;
+ virtual void Unlock() MOZ_OVERRIDE;
virtual TextureSource* GetTextureSources() MOZ_OVERRIDE {
MOZ_ASSERT(mIsLocked);
MOZ_ASSERT(mTexSource);
return mTexSource;
}
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;