Bug 1210444 - Set DEALLOCATE_CLIENT flag for EGLImage SharedSurfaceTextureClients. r=nical
authorJamie Nicol <jnicol@mozilla.com>
Mon, 19 Oct 2015 17:26:26 +0100
changeset 303945 302c448ac9388093afc0a235cf4b3c4fbced102b
parent 303944 dd0747ee0782de1427d4d30db3ff695857a5dd5f
child 303946 e532df30d2a14409ce4a25e2a127468bf3eee55b
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1210444
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1210444 - Set DEALLOCATE_CLIENT flag for EGLImage SharedSurfaceTextureClients. r=nical 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
@@ -76,16 +76,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
@@ -101,16 +101,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
@@ -21,17 +21,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