Bug 1299410 - Shrink TextureClientRecycleAllocator more aggressively r=nical
authorSotaro Ikeda <sotaro.ikeda.g@gmail.com>
Fri, 02 Sep 2016 02:05:58 -0700
changeset 312391 d082b9cabd17101cb872ef5913657f8cb281036b
parent 312390 8fdff7ffdcee621fec75557a8e95eefc78624f9d
child 312392 5ad8a73c2dd13b39f46834cbc5c7ab72c091b852
push id20447
push userkwierso@gmail.com
push dateFri, 02 Sep 2016 20:36:44 +0000
treeherderfx-team@969397f22187 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1299410
milestone51.0a1
Bug 1299410 - Shrink TextureClientRecycleAllocator more aggressively r=nical
gfx/layers/client/TextureClientRecycleAllocator.cpp
--- a/gfx/layers/client/TextureClientRecycleAllocator.cpp
+++ b/gfx/layers/client/TextureClientRecycleAllocator.cpp
@@ -17,26 +17,38 @@ namespace layers {
 class TextureClientHolder
 {
   ~TextureClientHolder() {}
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureClientHolder)
 
   explicit TextureClientHolder(TextureClient* aClient)
     : mTextureClient(aClient)
+    , mWillRecycle(true)
   {}
 
   TextureClient* GetTextureClient()
   {
     return mTextureClient;
   }
 
+  bool WillRecycle()
+  {
+    return mWillRecycle;
+  }
+
+  void ClearWillRecycle()
+  {
+    mWillRecycle = false;
+  }
+
   void ClearTextureClient() { mTextureClient = nullptr; }
 protected:
   RefPtr<TextureClient> mTextureClient;
+  bool mWillRecycle;
 };
 
 class DefaultTextureClientAllocationHelper : public ITextureClientAllocationHelper
 {
 public:
   DefaultTextureClientAllocationHelper(TextureClientRecycleAllocator* aAllocator,
                                        gfx::SurfaceFormat aFormat,
                                        gfx::IntSize aSize,
@@ -216,26 +228,27 @@ TextureClientRecycleAllocator::Allocate(
 {
   return TextureClient::CreateForDrawing(mSurfaceAllocator, aFormat, aSize, aSelector,
                                          aTextureFlags, aAllocFlags);
 }
 
 void
 TextureClientRecycleAllocator::ShrinkToMinimumSize()
 {
-  RefPtr<TextureClientRecycleAllocator> kungFuDeathGrip(this);
-  std::map<TextureClient*, RefPtr<TextureClientHolder> > inUseClients;
-  {
-    MutexAutoLock lock(mLock);
-    while (!mPooledClients.empty()) {
-      mPooledClients.pop();
-    }
-    mInUseClients.swap(inUseClients);
+  MutexAutoLock lock(mLock);
+  while (!mPooledClients.empty()) {
+    mPooledClients.pop();
   }
-  inUseClients.clear();
+  // We can not clear using TextureClients safely.
+  // Just clear WillRecycle here.
+  std::map<TextureClient*, RefPtr<TextureClientHolder> >::iterator it;
+  for (it = mInUseClients.begin(); it != mInUseClients.end(); it++) {
+    RefPtr<TextureClientHolder> holder = it->second;
+    holder->ClearWillRecycle();
+  }
 }
 
 void
 TextureClientRecycleAllocator::Destroy()
 {
   MutexAutoLock lock(mLock);
   while (!mPooledClients.empty()) {
     mPooledClients.pop();
@@ -251,17 +264,18 @@ TextureClientRecycleAllocator::RecycleTe
   RefPtr<TextureClientRecycleAllocator> kungFuDeathGrip(this);
   aClient->SetRecycleAllocator(nullptr);
 
   RefPtr<TextureClientHolder> textureHolder;
   {
     MutexAutoLock lock(mLock);
     if (mInUseClients.find(aClient) != mInUseClients.end()) {
       textureHolder = mInUseClients[aClient]; // Keep reference count of TextureClientHolder within lock.
-      if (!mIsDestroyed && mPooledClients.size() < mMaxPooledSize) {
+      if (textureHolder->WillRecycle() &&
+          !mIsDestroyed && mPooledClients.size() < mMaxPooledSize) {
         mPooledClients.push(textureHolder);
       }
       mInUseClients.erase(aClient);
     }
   }
 }
 
 } // namespace layers