Bug 1288474 - Don't accept TextureClient returns if the pool has been destroyed r=nical
authorGeorge Wright <george@mozilla.com>
Thu, 21 Jul 2016 13:01:49 -0400
changeset 346410 d91042a4ca776bfb2df3ddec6b0daf91c04f9311
parent 346409 6d5aca780e2d4627974e755cf0fe451ee67a83c4
child 346411 51b388f16a61188e56e89344ba708aa04dcdbe62
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1288474
milestone50.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 1288474 - Don't accept TextureClient returns if the pool has been destroyed r=nical
gfx/layers/client/TextureClientPool.cpp
gfx/layers/client/TextureClientPool.h
--- a/gfx/layers/client/TextureClientPool.cpp
+++ b/gfx/layers/client/TextureClientPool.cpp
@@ -30,16 +30,17 @@ TextureClientPool::TextureClientPool(Lay
   : mBackend(aLayersBackend)
   , mFormat(aFormat)
   , mSize(aSize)
   , mFlags(aFlags)
   , mInitialPoolSize(aInitialPoolSize)
   , mPoolIncrementSize(aPoolIncrementSize)
   , mOutstandingClients(0)
   , mSurfaceAllocator(aAllocator)
+  , mDestroyed(false)
 {
   TCP_LOG("TexturePool %p created with maximum unused texture clients %u\n",
       this, mInitialPoolSize);
   mTimer = do_CreateInstance("@mozilla.org/timer;1");
   if (aFormat == gfx::SurfaceFormat::UNKNOWN) {
     gfxWarning() << "Creating texture pool for SurfaceFormat::UNKNOWN format";
   }
 }
@@ -144,17 +145,17 @@ TextureClientPool::AllocateTextureClient
       mTextureClients.push(newClient);
     }
   }
 }
 
 void
 TextureClientPool::ReturnTextureClient(TextureClient *aClient)
 {
-  if (!aClient) {
+  if (!aClient || mDestroyed) {
     return;
   }
 #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
   DebugOnly<bool> ok = TestClientPool("return", aClient, this);
   MOZ_ASSERT(ok);
 #endif
   // Add the client to the pool:
   MOZ_ASSERT(mOutstandingClients > mTextureClientsDeferred.size());
@@ -165,17 +166,17 @@ TextureClientPool::ReturnTextureClient(T
 
   // Shrink down if we're beyond our maximum size
   ShrinkToMaximumSize();
 }
 
 void
 TextureClientPool::ReturnTextureClientDeferred(TextureClient* aClient)
 {
-  if (!aClient) {
+  if (!aClient || mDestroyed) {
     return;
   }
   MOZ_ASSERT(aClient->GetReadLock());
 #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
   DebugOnly<bool> ok = TestClientPool("defer", aClient, this);
   MOZ_ASSERT(ok);
 #endif
   mTextureClientsDeferred.push_back(aClient);
@@ -280,14 +281,15 @@ TextureClientPool::Clear()
         this, mTextureClientsDeferred.front().get());
     mTextureClientsDeferred.pop_front();
   }
 }
 
 void TextureClientPool::Destroy()
 {
   Clear();
+  mDestroyed = true;
   mInitialPoolSize = 0;
   mPoolIncrementSize = 0;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/TextureClientPool.h
+++ b/gfx/layers/client/TextureClientPool.h
@@ -146,14 +146,19 @@ private:
   // On ICS, fence wait happens implicitly before drawing.
   // Since JB, fence wait happens explicitly when fetching a client from the pool.
   std::stack<RefPtr<TextureClient> > mTextureClients;
 
   std::list<RefPtr<TextureClient>> mTextureClientsDeferred;
   RefPtr<nsITimer> mTimer;
   // This mSurfaceAllocator owns us, so no need to hold a ref to it
   TextureForwarder* mSurfaceAllocator;
+
+  // Keep track of whether this pool has been destroyed or not. If it has,
+  // we won't accept returns of TextureClients anymore, and the refcounting
+  // should take care of their destruction.
+  bool mDestroyed;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_TEXTURECLIENTPOOL_H */