Bug 1289525 - Grow the pool one at a time instead of in chunk of increment size r=jrmuizel
authorGeorge Wright <george@mozilla.com>
Thu, 28 Jul 2016 18:52:38 -0400
changeset 332449 81aab5c5f3d04bda4c8f9fda722db13fdc738ffc
parent 332448 29315d9869a2305543e7dbf5e2f269d7dda43d6e
child 332450 ded96a1a5aae33b7700f839e2ff63d364f21142f
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1289525
milestone50.0a1
Bug 1289525 - Grow the pool one at a time instead of in chunk of increment size r=jrmuizel
gfx/layers/client/TextureClientPool.cpp
gfx/layers/client/TextureClientPool.h
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/thebes/gfxPrefs.h
--- a/gfx/layers/client/TextureClientPool.cpp
+++ b/gfx/layers/client/TextureClientPool.cpp
@@ -20,24 +20,24 @@ namespace mozilla {
 namespace layers {
 
 
 TextureClientPool::TextureClientPool(LayersBackend aLayersBackend,
                                      gfx::SurfaceFormat aFormat,
                                      gfx::IntSize aSize,
                                      TextureFlags aFlags,
                                      uint32_t aInitialPoolSize,
-                                     uint32_t aPoolIncrementSize,
+                                     uint32_t aPoolUnusedSize,
                                      TextureForwarder* aAllocator)
   : mBackend(aLayersBackend)
   , mFormat(aFormat)
   , mSize(aSize)
   , mFlags(aFlags)
   , mInitialPoolSize(aInitialPoolSize)
-  , mPoolIncrementSize(aPoolIncrementSize)
+  , mPoolUnusedSize(aPoolUnusedSize)
   , 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) {
@@ -86,20 +86,19 @@ static bool TestClientPool(const char* w
 already_AddRefed<TextureClient>
 TextureClientPool::GetTextureClient()
 {
   // Try to fetch a client from the pool
   RefPtr<TextureClient> textureClient;
 
   // We initially allocate mInitialPoolSize for our pool. If we run
   // out of TextureClients, we allocate additional TextureClients to try and keep around
-  // mPoolIncrementSize
+  // mPoolUnusedSize
   if (!mTextureClients.size()) {
-    size_t size = mOutstandingClients ? mPoolIncrementSize : mInitialPoolSize;
-    AllocateTextureClients(size);
+    AllocateTextureClient();
   }
 
   if (!mTextureClients.size()) {
     // All our allocations failed, return nullptr
     return nullptr;
   }
 
   mOutstandingClients++;
@@ -114,41 +113,40 @@ TextureClientPool::GetTextureClient()
 #endif
   TCP_LOG("TexturePool %p giving %p from pool; size %u outstanding %u\n",
       this, textureClient.get(), mTextureClients.size(), mOutstandingClients);
 
   return textureClient.forget();
 }
 
 void
-TextureClientPool::AllocateTextureClients(size_t aSize)
+TextureClientPool::AllocateTextureClient()
 {
-  TCP_LOG("TexturePool %p allocating %u clients, outstanding %u\n",
-      this, aSize, mOutstandingClients);
+  TCP_LOG("TexturePool %p allocating TextureClient, outstanding %u\n",
+      this, mOutstandingClients);
 
   RefPtr<TextureClient> newClient;
-  while (mTextureClients.size() < aSize) {
-    if (gfxPrefs::ForceShmemTiles()) {
-      // gfx::BackendType::NONE means use the content backend
-      newClient =
-        TextureClient::CreateForRawBufferAccess(mSurfaceAllocator,
-                                                mFormat, mSize,
-                                                gfx::BackendType::NONE,
-                                                mFlags, ALLOC_DEFAULT);
-    } else {
-      newClient =
-        TextureClient::CreateForDrawing(mSurfaceAllocator,
-                                        mFormat, mSize,
-                                        mBackend,
-                                        BackendSelector::Content,
-                                        mFlags);
-    }
-    if (newClient) {
-      mTextureClients.push(newClient);
-    }
+  if (gfxPrefs::ForceShmemTiles()) {
+    // gfx::BackendType::NONE means use the content backend
+    newClient =
+      TextureClient::CreateForRawBufferAccess(mSurfaceAllocator,
+                                              mFormat, mSize,
+                                              gfx::BackendType::NONE,
+                                              mFlags, ALLOC_DEFAULT);
+  } else {
+    newClient =
+      TextureClient::CreateForDrawing(mSurfaceAllocator,
+                                      mFormat, mSize,
+                                      mBackend,
+                                      BackendSelector::Content,
+                                      mFlags);
+  }
+
+  if (newClient) {
+    mTextureClients.push(newClient);
   }
 }
 
 void
 TextureClientPool::ReturnTextureClient(TextureClient *aClient)
 {
   if (!aClient || mDestroyed) {
     return;
@@ -191,27 +189,27 @@ TextureClientPool::ShrinkToMaximumSize()
   // We're over our desired maximum size, immediately shrink down to the
   // maximum.
   //
   // We cull from the deferred TextureClients first, as we can't reuse those
   // until they get returned.
   uint32_t totalUnusedTextureClients = mTextureClients.size() + mTextureClientsDeferred.size();
 
   // If we have > mInitialPoolSize outstanding, then we want to keep around
-  // mPoolIncrementSize at a maximum. If we have fewer than mInitialPoolSize
+  // mPoolUnusedSize at a maximum. If we have fewer than mInitialPoolSize
   // outstanding, then keep around the entire initial pool size.
   uint32_t targetUnusedClients;
   if (mOutstandingClients > mInitialPoolSize) {
-    targetUnusedClients = mPoolIncrementSize;
+    targetUnusedClients = mPoolUnusedSize;
   } else {
     targetUnusedClients = mInitialPoolSize;
   }
 
-  TCP_LOG("TexturePool %p shrinking to maximum unused size %u; total outstanding %u\n",
-      this, targetUnusedClients, mOutstandingClients);
+  TCP_LOG("TexturePool %p shrinking to maximum unused size %u; current pool size %u; total outstanding %u\n",
+      this, targetUnusedClients, totalUnusedTextureClients, mOutstandingClients);
 
   while (totalUnusedTextureClients > targetUnusedClients) {
     if (mTextureClientsDeferred.size()) {
       mOutstandingClients--;
       TCP_LOG("TexturePool %p dropped deferred client %p; %u remaining\n",
           this, mTextureClientsDeferred.front().get(),
           mTextureClientsDeferred.size() - 1);
       mTextureClientsDeferred.pop_front();
@@ -283,13 +281,13 @@ TextureClientPool::Clear()
   }
 }
 
 void TextureClientPool::Destroy()
 {
   Clear();
   mDestroyed = true;
   mInitialPoolSize = 0;
-  mPoolIncrementSize = 0;
+  mPoolUnusedSize = 0;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/TextureClientPool.h
+++ b/gfx/layers/client/TextureClientPool.h
@@ -44,17 +44,17 @@ class TextureClientPool final : public T
   ~TextureClientPool();
 
 public:
   TextureClientPool(LayersBackend aBackend,
                     gfx::SurfaceFormat aFormat,
                     gfx::IntSize aSize,
                     TextureFlags aFlags,
                     uint32_t aInitialPoolSize,
-                    uint32_t aPoolIncrementSize,
+                    uint32_t aPoolUnusedSize,
                     TextureForwarder* aAllocator);
 
   /**
    * Gets an allocated TextureClient of size and format that are determined
    * by the initialisation parameters given to the pool. This will either be
    * a cached client that was returned to the pool, or a newly allocated
    * client if one isn't available.
    *
@@ -106,21 +106,18 @@ public:
   /**
    * Clear the pool and put it in a state where it won't recycle any new texture.
    */
   void Destroy();
 
 private:
   void ReturnUnlockedClients();
 
-  /// We maintain a number of unused texture clients for immediate return from
-  /// GetTextureClient(). This will normally be called if there are no
-  /// TextureClients available in the pool, which ideally should only ever
-  /// be at startup.
-  void AllocateTextureClients(size_t aSize);
+  /// Allocate a single TextureClient to be returned from the pool.
+  void AllocateTextureClient();
 
   /// Backend passed to the TextureClient for buffer creation.
   LayersBackend mBackend;
 
   /// Format is passed to the TextureClient for buffer creation.
   gfx::SurfaceFormat mFormat;
 
   /// The width and height of the tiles to be used.
@@ -130,17 +127,17 @@ private:
   const TextureFlags mFlags;
 
   // The initial number of unused texture clients to seed the pool with
   // on construction
   uint32_t mInitialPoolSize;
 
   // How many unused texture clients to try and keep around if we go over
   // the initial allocation
-  uint32_t mPoolIncrementSize;
+  uint32_t mPoolUnusedSize;
 
   /// This is a total number of clients in the wild and in the stack of
   /// deferred clients (see below).  So, the total number of clients in
   /// existence is always mOutstandingClients + the size of mTextureClients.
   uint32_t mOutstandingClients;
 
   // On b2g gonk, std::queue might be a better choice.
   // On ICS, fence wait happens implicitly before drawing.
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -943,17 +943,17 @@ CompositorBridgeChild::GetTexturePool(La
   }
 
   mTexturePools.AppendElement(
       new TextureClientPool(aBackend, aFormat,
                             IntSize(gfxPlatform::GetPlatform()->GetTileWidth(),
                                     gfxPlatform::GetPlatform()->GetTileHeight()),
                             aFlags,
                             gfxPrefs::LayersTileInitialPoolSize(),
-                            gfxPrefs::LayersTilePoolIncrementSize(),
+                            gfxPrefs::LayersTilePoolUnusedSize(),
                             this));
 
   return mTexturePools.LastElement();
 }
 
 void
 CompositorBridgeChild::HandleMemoryPressure()
 {
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -480,17 +480,17 @@ private:
   DECL_GFX_PREF(Once, "layers.stereo-video.enabled",           StereoVideoEnabled, bool, false);
 
   // We allow for configurable and rectangular tile size to avoid wasting memory on devices whose
   // screen size does not align nicely to the default tile size. Although layers can be any size,
   // they are often the same size as the screen, especially for width.
   DECL_GFX_PREF(Once, "layers.tile-width",                     LayersTileWidth, int32_t, 256);
   DECL_GFX_PREF(Once, "layers.tile-height",                    LayersTileHeight, int32_t, 256);
   DECL_GFX_PREF(Once, "layers.tile-initial-pool-size",         LayersTileInitialPoolSize, uint32_t, (uint32_t)50);
-  DECL_GFX_PREF(Once, "layers.tile-pool-increment-size",       LayersTilePoolIncrementSize, uint32_t, (uint32_t)10);
+  DECL_GFX_PREF(Once, "layers.tile-pool-unused-size",          LayersTilePoolUnusedSize, uint32_t, (uint32_t)10);
   DECL_GFX_PREF(Once, "layers.tiles.adjust",                   LayersTilesAdjust, bool, true);
   DECL_GFX_PREF(Once, "layers.tiles.edge-padding",             TileEdgePaddingEnabled, bool, true);
   DECL_GFX_PREF(Live, "layers.tiles.fade-in.enabled",          LayerTileFadeInEnabled, bool, false);
   DECL_GFX_PREF(Live, "layers.tiles.fade-in.duration-ms",      LayerTileFadeInDuration, uint32_t, 250);
   DECL_GFX_PREF(Live, "layers.transaction.warning-ms",         LayerTransactionWarning, uint32_t, 200);
   DECL_GFX_PREF(Once, "layers.uniformity-info",                UniformityInfo, bool, false);
   DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces",   UseImageOffscreenSurfaces, bool, true);