Bug 1210444 - Set DEALLOCATE_CLIENT flag for EGLImage SharedSurfaceTextureClients. r=nical, a=sylvestre
authorJamie Nicol <jnicol@mozilla.com>
Mon, 19 Oct 2015 17:26:26 +0100
changeset 289612 e7061d4d10fd
parent 289611 f23031e5a290
child 289613 2c672ff8f3fb
push id5220
push usercbook@mozilla.com
push date2015-10-22 14:31 +0000
treeherdermozilla-beta@e7061d4d10fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical, sylvestre
bugs1210444
milestone42.0
Bug 1210444 - Set DEALLOCATE_CLIENT flag for EGLImage SharedSurfaceTextureClients. r=nical, a=sylvestre SharedSurface_EGLImages are deallocated on the client side and are unable to be recycled. This led to a race condition where CanvasClient would free a TextureClient, destroying its underlying data, but ImageHost might attempt to composite the corresponding TextureHost before receiving a replacement to use instead. Give SharedSurface an interface for its backends to specify any texture flags that they require a TextureClient to set, and ensure that DEALLOCATE_CLIENT is set for SharedSurface_EGLImage SharedSurfaceTextureClients. This ensures that texture data is destroyed synchronously and, importantly, after any outstanding ipdl messages have been delivered. This guarantees that ImageHost has received a new TextureHost to composite before the previous TextureHost's data is destroyed.
gfx/gl/SharedSurface.cpp
gfx/gl/SharedSurface.h
gfx/gl/SharedSurfaceEGL.cpp
gfx/gl/SharedSurfaceEGL.h
gfx/layers/client/TextureClientSharedSurface.cpp
--- a/gfx/gl/SharedSurface.cpp
+++ b/gfx/gl/SharedSurface.cpp
@@ -215,16 +215,22 @@ SharedSurface::SharedSurface(SharedSurfa
     , mIsLocked(false)
     , mIsProducerAcquired(false)
     , mIsConsumerAcquired(false)
 #ifdef DEBUG
     , mOwningThread(NS_GetCurrentThread())
 #endif
 { }
 
+layers::TextureFlags
+SharedSurface::GetTextureFlags() const
+{
+    return layers::TextureFlags::NO_FLAGS;
+}
+
 void
 SharedSurface::LockProd()
 {
     MOZ_ASSERT(!mIsLocked);
 
     LockProdImpl();
 
     mGL->LockSurface(this);
--- a/gfx/gl/SharedSurface.h
+++ b/gfx/gl/SharedSurface.h
@@ -74,16 +74,20 @@ protected:
                   const gfx::IntSize& size,
                   bool hasAlpha,
                   bool canRecycle);
 
 public:
     virtual ~SharedSurface() {
     }
 
+    // Specifies to the TextureClient any flags which
+    // are required by the SharedSurface backend.
+    virtual layers::TextureFlags GetTextureFlags() const;
+
     bool IsLocked() const {
         return mIsLocked;
     }
 
     // This locks the SharedSurface as the production buffer for the context.
     // This is needed by backends which use PBuffers and/or EGLSurfaces.
     void LockProd();
 
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -102,16 +102,22 @@ SharedSurface_EGLImage::~SharedSurface_E
     if (mSync) {
         // We can't call this unless we have the ext, but we will always have
         // the ext if we have something to destroy.
         mEGL->fDestroySync(Display(), mSync);
         mSync = 0;
     }
 }
 
+layers::TextureFlags
+SharedSurface_EGLImage::GetTextureFlags() const
+{
+    return layers::TextureFlags::DEALLOCATE_CLIENT;
+}
+
 void
 SharedSurface_EGLImage::Fence()
 {
     MutexAutoLock lock(mMutex);
     mGL->MakeCurrent();
 
     if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
         mGL->IsExtensionSupported(GLContext::OES_EGL_sync))
--- a/gfx/gl/SharedSurfaceEGL.h
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -58,16 +58,18 @@ protected:
                            EGLImage image);
 
     EGLDisplay Display() const;
     void UpdateProdTexture(const MutexAutoLock& curAutoLock);
 
 public:
     virtual ~SharedSurface_EGLImage();
 
+    virtual layers::TextureFlags GetTextureFlags() const override;
+
     virtual void LockProdImpl() override {}
     virtual void UnlockProdImpl() override {}
 
     virtual void Fence() override;
     virtual bool WaitSync() override;
     virtual bool PollSync() override;
 
     virtual GLuint ProdTexture() override {
--- a/gfx/layers/client/TextureClientSharedSurface.cpp
+++ b/gfx/layers/client/TextureClientSharedSurface.cpp
@@ -17,17 +17,19 @@ namespace mozilla {
 namespace layers {
 
 SharedSurfaceTextureClient::SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator,
                                                        TextureFlags aFlags,
                                                        UniquePtr<gl::SharedSurface> surf,
                                                        gl::SurfaceFactory* factory)
   : TextureClient(aAllocator, aFlags | TextureFlags::RECYCLE)
   , mSurf(Move(surf))
-{ }
+{
+  AddFlags(mSurf->GetTextureFlags());
+}
 
 SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
 {
   // Free the ShSurf implicitly.
 }
 
 gfx::IntSize
 SharedSurfaceTextureClient::GetSize() const