Bug 1070308. Add Acquire and Release semantics to SharedSurface. r=jgilbert
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 09 Oct 2014 16:33:22 -0400
changeset 211033 6e17d46ddda46d459e04478e8a840fe876cdd2da
parent 211032 cc77c762d6a0c1d167f05e136c9c792d37995572
child 211034 c837c78af266974cd5d2b09403553f27b6d667a3
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjgilbert
bugs1070308
milestone36.0a1
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.
gfx/gl/GLScreenBuffer.cpp
gfx/gl/SharedSurface.cpp
gfx/gl/SharedSurface.h
gfx/layers/client/TextureClient.cpp
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
--- 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;