Skip to content

Commit

Permalink
Bug 1289525 - Shrink the TextureClientPool to maximum size after a sh…
Browse files Browse the repository at this point in the history
…ort delay, and clear the pool after a longer delay r=jrmuizel
  • Loading branch information
George Wright committed Aug 9, 2016
1 parent 6487e52 commit d0457a6
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 6 deletions.
52 changes: 47 additions & 5 deletions gfx/layers/client/TextureClientPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,39 @@
namespace mozilla {
namespace layers {

// We want to shrink to our maximum size of N unused tiles
// after a timeout to allow for short-term budget requirements
static void
ShrinkCallback(nsITimer *aTimer, void *aClosure)
{
static_cast<TextureClientPool*>(aClosure)->ShrinkToMaximumSize();
}

// After a certain amount of inactivity, let's clear the pool so that
// we don't hold onto tiles needlessly. In general, allocations are
// cheap enough that re-allocating isn't an issue unless we're allocating
// at an inopportune time (e.g. mid-animation).
static void
ClearCallback(nsITimer *aTimer, void *aClosure)
{
static_cast<TextureClientPool*>(aClosure)->Clear();
}

TextureClientPool::TextureClientPool(LayersBackend aLayersBackend,
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
TextureFlags aFlags,
uint32_t aShrinkTimeoutMsec,
uint32_t aClearTimeoutMsec,
uint32_t aInitialPoolSize,
uint32_t aPoolUnusedSize,
TextureForwarder* aAllocator)
: mBackend(aLayersBackend)
, mFormat(aFormat)
, mSize(aSize)
, mFlags(aFlags)
, mShrinkTimeoutMsec(aShrinkTimeoutMsec)
, mClearTimeoutMsec(aClearTimeoutMsec)
, mInitialPoolSize(aInitialPoolSize)
, mPoolUnusedSize(aPoolUnusedSize)
, mOutstandingClients(0)
Expand All @@ -39,15 +60,17 @@ TextureClientPool::TextureClientPool(LayersBackend aLayersBackend,
{
TCP_LOG("TexturePool %p created with maximum unused texture clients %u\n",
this, mInitialPoolSize);
mTimer = do_CreateInstance("@mozilla.org/timer;1");
mShrinkTimer = do_CreateInstance("@mozilla.org/timer;1");
mClearTimer = do_CreateInstance("@mozilla.org/timer;1");
if (aFormat == gfx::SurfaceFormat::UNKNOWN) {
gfxWarning() << "Creating texture pool for SurfaceFormat::UNKNOWN format";
}
}

TextureClientPool::~TextureClientPool()
{
mTimer->Cancel();
mShrinkTimer->Cancel();
mClearTimer->Cancel();
}

#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
Expand Down Expand Up @@ -145,6 +168,25 @@ TextureClientPool::AllocateTextureClient()
}
}

void
TextureClientPool::ResetTimers()
{
// Shrink down if we're beyond our maximum size
if (mShrinkTimeoutMsec &&
mTextureClients.size() + mTextureClientsDeferred.size() > mPoolUnusedSize) {
TCP_LOG("TexturePool %p scheduling a shrink-to-max-size\n", this);
mShrinkTimer->InitWithFuncCallback(ShrinkCallback, this, mShrinkTimeoutMsec,
nsITimer::TYPE_ONE_SHOT);
}

// Clear pool after a period of inactivity to reduce memory consumption
if (mClearTimeoutMsec) {
TCP_LOG("TexturePool %p scheduling a clear\n", this);
mClearTimer->InitWithFuncCallback(ClearCallback, this, mClearTimeoutMsec,
nsITimer::TYPE_ONE_SHOT);
}
}

void
TextureClientPool::ReturnTextureClient(TextureClient *aClient)
{
Expand All @@ -162,8 +204,7 @@ TextureClientPool::ReturnTextureClient(TextureClient *aClient)
TCP_LOG("TexturePool %p had client %p returned; size %u outstanding %u\n",
this, aClient, mTextureClients.size(), mOutstandingClients);

// Shrink down if we're beyond our maximum size
ShrinkToMaximumSize();
ResetTimers();
}

void
Expand All @@ -180,7 +221,8 @@ TextureClientPool::ReturnTextureClientDeferred(TextureClient* aClient)
mTextureClientsDeferred.push_back(aClient);
TCP_LOG("TexturePool %p had client %p defer-returned, size %u outstanding %u\n",
this, aClient, mTextureClientsDeferred.size(), mOutstandingClients);
ShrinkToMaximumSize();

ResetTimers();
}

void
Expand Down
16 changes: 15 additions & 1 deletion gfx/layers/client/TextureClientPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class TextureClientPool final : public TextureClientAllocator
gfx::SurfaceFormat aFormat,
gfx::IntSize aSize,
TextureFlags aFlags,
uint32_t aShrinkTimeoutMsec,
uint32_t aClearTimeoutMsec,
uint32_t aInitialPoolSize,
uint32_t aPoolUnusedSize,
TextureForwarder* aAllocator);
Expand Down Expand Up @@ -114,6 +116,9 @@ class TextureClientPool final : public TextureClientAllocator
/// Allocate a single TextureClient to be returned from the pool.
void AllocateTextureClient();

/// Reset and/or initialise timers for shrinking/clearing the pool.
void ResetTimers();

/// Backend passed to the TextureClient for buffer creation.
LayersBackend mBackend;

Expand All @@ -126,6 +131,14 @@ class TextureClientPool final : public TextureClientAllocator
/// Flags passed to the TextureClient for buffer creation.
const TextureFlags mFlags;

/// How long to wait after a TextureClient is returned before trying
/// to shrink the pool to its maximum size of mPoolUnusedSize.
uint32_t mShrinkTimeoutMsec;

/// How long to wait after a TextureClient is returned before trying
/// to clear the pool.
uint32_t mClearTimeoutMsec;

// The initial number of unused texture clients to seed the pool with
// on construction
uint32_t mInitialPoolSize;
Expand All @@ -145,7 +158,8 @@ class TextureClientPool final : public TextureClientAllocator
std::stack<RefPtr<TextureClient> > mTextureClients;

std::list<RefPtr<TextureClient>> mTextureClientsDeferred;
RefPtr<nsITimer> mTimer;
RefPtr<nsITimer> mShrinkTimer;
RefPtr<nsITimer> mClearTimer;
// This mSurfaceAllocator owns us, so no need to hold a ref to it
TextureForwarder* mSurfaceAllocator;

Expand Down
2 changes: 2 additions & 0 deletions gfx/layers/ipc/CompositorBridgeChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,8 @@ CompositorBridgeChild::GetTexturePool(LayersBackend aBackend,
new TextureClientPool(aBackend, aFormat,
gfx::gfxVars::TileSize(),
aFlags,
gfxPrefs::LayersTilePoolShrinkTimeout(),
gfxPrefs::LayersTilePoolClearTimeout(),
gfxPrefs::LayersTileInitialPoolSize(),
gfxPrefs::LayersTilePoolUnusedSize(),
this));
Expand Down
2 changes: 2 additions & 0 deletions gfx/thebes/gfxPrefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,8 @@ class gfxPrefs final
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-unused-size", LayersTilePoolUnusedSize, uint32_t, (uint32_t)10);
DECL_GFX_PREF(Once, "layers.tile-pool-shrink-timeout", LayersTilePoolShrinkTimeout, uint32_t, (uint32_t)50);
DECL_GFX_PREF(Once, "layers.tile-pool-clear-timeout", LayersTilePoolClearTimeout, uint32_t, (uint32_t)5000);
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);
Expand Down

0 comments on commit d0457a6

Please sign in to comment.