Bug 1043603: Expose tile pool size and pool shrink timeout as prefs. r=clord

This commit is contained in:
Milan Sreckovic 2014-07-25 15:49:47 -04:00
parent d84d3112d6
commit f5ff709aab
6 changed files with 43 additions and 22 deletions

View File

@ -6,7 +6,7 @@
#include "ClientLayerManager.h" #include "ClientLayerManager.h"
#include "CompositorChild.h" // for CompositorChild #include "CompositorChild.h" // for CompositorChild
#include "GeckoProfiler.h" // for PROFILER_LABEL #include "GeckoProfiler.h" // for PROFILER_LABEL
#include "gfxPrefs.h" // for gfxPrefs::LayersTileWidth/Height #include "gfxPrefs.h" // for gfxPrefs::LayersTile...
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Hal.h" #include "mozilla/Hal.h"
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation #include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
@ -572,6 +572,8 @@ ClientLayerManager::GetTexturePool(SurfaceFormat aFormat)
mTexturePools.AppendElement( mTexturePools.AppendElement(
new TextureClientPool(aFormat, IntSize(gfxPrefs::LayersTileWidth(), new TextureClientPool(aFormat, IntSize(gfxPrefs::LayersTileWidth(),
gfxPrefs::LayersTileHeight()), gfxPrefs::LayersTileHeight()),
gfxPrefs::LayersTileMaxPoolSize(),
gfxPrefs::LayersTileShrinkPoolTimeout(),
mForwarder)); mForwarder));
return mTexturePools.LastElement(); return mTexturePools.LastElement();
@ -586,6 +588,8 @@ ClientLayerManager::GetSimpleTileTexturePool(SurfaceFormat aFormat)
if (mSimpleTilePools[index].get() == nullptr) { if (mSimpleTilePools[index].get() == nullptr) {
mSimpleTilePools[index] = new SimpleTextureClientPool(aFormat, IntSize(gfxPrefs::LayersTileWidth(), mSimpleTilePools[index] = new SimpleTextureClientPool(aFormat, IntSize(gfxPrefs::LayersTileWidth(),
gfxPrefs::LayersTileHeight()), gfxPrefs::LayersTileHeight()),
gfxPrefs::LayersTileMaxPoolSize(),
gfxPrefs::LayersTileShrinkPoolTimeout(),
mForwarder); mForwarder);
} }

View File

@ -49,9 +49,13 @@ SimpleTextureClientPool::WaitForCompositorRecycleCallback(TextureClient* aClient
} }
SimpleTextureClientPool::SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize, SimpleTextureClientPool::SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
uint32_t aMaxTextureClients,
uint32_t aShrinkTimeoutMsec,
ISurfaceAllocator *aAllocator) ISurfaceAllocator *aAllocator)
: mFormat(aFormat) : mFormat(aFormat)
, mSize(aSize) , mSize(aSize)
, mMaxTextureClients(aMaxTextureClients)
, mShrinkTimeoutMsec(aShrinkTimeoutMsec)
, mSurfaceAllocator(aAllocator) , mSurfaceAllocator(aAllocator)
{ {
mTimer = do_CreateInstance("@mozilla.org/timer;1"); mTimer = do_CreateInstance("@mozilla.org/timer;1");
@ -100,7 +104,7 @@ SimpleTextureClientPool::ReturnTextureClient(TextureClient *aClient)
} }
// If we haven't hit our max cached client limit, add this one // If we haven't hit our max cached client limit, add this one
if (mAvailableTextureClients.size() < sMaxTextureClients) { if (mAvailableTextureClients.size() < mMaxTextureClients) {
mAvailableTextureClients.push(aClient); mAvailableTextureClients.push(aClient);
RECYCLE_LOG("%s recycled %p (have %d)\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), aClient, mAvailableTextureClients.size()); RECYCLE_LOG("%s recycled %p (have %d)\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), aClient, mAvailableTextureClients.size());
} else { } else {
@ -110,7 +114,7 @@ SimpleTextureClientPool::ReturnTextureClient(TextureClient *aClient)
// Kick off the pool shrinking timer if there are still more unused texture // Kick off the pool shrinking timer if there are still more unused texture
// clients than our desired minimum cache size. // clients than our desired minimum cache size.
if (mAvailableTextureClients.size() > sMinCacheSize) { if (mAvailableTextureClients.size() > sMinCacheSize) {
mTimer->InitWithFuncCallback(SimpleTextureClientPool::ShrinkCallback, this, sShrinkTimeout, mTimer->InitWithFuncCallback(SimpleTextureClientPool::ShrinkCallback, this, mShrinkTimeoutMsec,
nsITimer::TYPE_ONE_SHOT); nsITimer::TYPE_ONE_SHOT);
} }

View File

@ -32,6 +32,8 @@ public:
NS_INLINE_DECL_REFCOUNTING(SimpleTextureClientPool) NS_INLINE_DECL_REFCOUNTING(SimpleTextureClientPool)
SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize, SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
uint32_t aMaxTextureClients,
uint32_t aShrinkTimeoutMsec,
ISurfaceAllocator *aAllocator); ISurfaceAllocator *aAllocator);
/** /**
@ -49,18 +51,10 @@ public:
void Clear(); void Clear();
private: private:
// The time in milliseconds before the pool will be shrunk to the minimum
// size after returning a client.
static const uint32_t sShrinkTimeout = 3000;
// The minimum size of the pool (the number of tiles that will be kept after // The minimum size of the pool (the number of tiles that will be kept after
// shrinking). // shrinking).
static const uint32_t sMinCacheSize = 16; static const uint32_t sMinCacheSize = 16;
// This is the number of cached texture clients we don't want to exceed, even
// temporarily (pre-shrink)
static const uint32_t sMaxTextureClients = 50;
static void ShrinkCallback(nsITimer *aTimer, void *aClosure); static void ShrinkCallback(nsITimer *aTimer, void *aClosure);
static void RecycleCallback(TextureClient* aClient, void* aClosure); static void RecycleCallback(TextureClient* aClient, void* aClosure);
static void WaitForCompositorRecycleCallback(TextureClient* aClient, void* aClosure); static void WaitForCompositorRecycleCallback(TextureClient* aClient, void* aClosure);
@ -68,6 +62,14 @@ private:
gfx::SurfaceFormat mFormat; gfx::SurfaceFormat mFormat;
gfx::IntSize mSize; gfx::IntSize mSize;
// This is the number of cached texture clients we don't want to exceed, even
// temporarily (pre-shrink)
uint32_t mMaxTextureClients;
// The time in milliseconds before the pool will be shrunk to the minimum
// size after returning a client.
uint32_t mShrinkTimeoutMsec;
// We use a std::stack and make sure to use it the following way: // We use a std::stack and make sure to use it the following way:
// new (available to be used) elements are push()'d to the front // new (available to be used) elements are push()'d to the front
// requests are served from the front via pop() // requests are served from the front via pop()

View File

@ -21,9 +21,13 @@ ShrinkCallback(nsITimer *aTimer, void *aClosure)
} }
TextureClientPool::TextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize, TextureClientPool::TextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
uint32_t aMaxTextureClients,
uint32_t aShrinkTimeoutMsec,
ISurfaceAllocator *aAllocator) ISurfaceAllocator *aAllocator)
: mFormat(aFormat) : mFormat(aFormat)
, mSize(aSize) , mSize(aSize)
, mMaxTextureClients(aMaxTextureClients)
, mShrinkTimeoutMsec(aShrinkTimeoutMsec)
, mOutstandingClients(0) , mOutstandingClients(0)
, mSurfaceAllocator(aAllocator) , mSurfaceAllocator(aAllocator)
{ {
@ -82,7 +86,7 @@ TextureClientPool::ReturnTextureClient(TextureClient *aClient)
// Kick off the pool shrinking timer if there are still more unused texture // Kick off the pool shrinking timer if there are still more unused texture
// clients than our desired minimum cache size. // clients than our desired minimum cache size.
if (mTextureClients.size() > sMinCacheSize) { if (mTextureClients.size() > sMinCacheSize) {
mTimer->InitWithFuncCallback(ShrinkCallback, this, sShrinkTimeout, mTimer->InitWithFuncCallback(ShrinkCallback, this, mShrinkTimeoutMsec,
nsITimer::TYPE_ONE_SHOT); nsITimer::TYPE_ONE_SHOT);
} }
} }
@ -103,7 +107,7 @@ TextureClientPool::ShrinkToMaximumSize()
// maximum, or zero if we have too many outstanding texture clients. // maximum, or zero if we have too many outstanding texture clients.
// We cull from the deferred TextureClients first, as we can't reuse those // We cull from the deferred TextureClients first, as we can't reuse those
// until they get returned. // until they get returned.
while (totalClientsOutstanding > sMaxTextureClients) { while (totalClientsOutstanding > mMaxTextureClients) {
if (mTextureClientsDeferred.size()) { if (mTextureClientsDeferred.size()) {
mOutstandingClients--; mOutstandingClients--;
mTextureClientsDeferred.pop(); mTextureClientsDeferred.pop();
@ -111,7 +115,7 @@ TextureClientPool::ShrinkToMaximumSize()
if (!mTextureClients.size()) { if (!mTextureClients.size()) {
// Getting here means we're over our desired number of TextureClients // Getting here means we're over our desired number of TextureClients
// with none in the pool. This can happen for pathological cases, or // with none in the pool. This can happen for pathological cases, or
// it could mean that sMaxTextureClients needs adjusting for whatever // it could mean that mMaxTextureClients needs adjusting for whatever
// device we're running on. // device we're running on.
break; break;
} }

View File

@ -26,6 +26,8 @@ public:
NS_INLINE_DECL_REFCOUNTING(TextureClientPool) NS_INLINE_DECL_REFCOUNTING(TextureClientPool)
TextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize, TextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
uint32_t aMaxTextureClients,
uint32_t aShrinkTimeoutMsec,
ISurfaceAllocator *aAllocator); ISurfaceAllocator *aAllocator);
/** /**
@ -53,7 +55,7 @@ public:
/** /**
* Attempt to shrink the pool so that there are no more than * Attempt to shrink the pool so that there are no more than
* sMaxTextureClients clients outstanding. * mMaxTextureClients clients outstanding.
*/ */
void ShrinkToMaximumSize(); void ShrinkToMaximumSize();
@ -84,20 +86,23 @@ public:
gfx::SurfaceFormat GetFormat() { return mFormat; } gfx::SurfaceFormat GetFormat() { return mFormat; }
private: private:
// The time in milliseconds before the pool will be shrunk to the minimum
// size after returning a client.
static const uint32_t sShrinkTimeout = 1000;
// The minimum size of the pool (the number of tiles that will be kept after // The minimum size of the pool (the number of tiles that will be kept after
// shrinking). // shrinking).
static const uint32_t sMinCacheSize = 0; static const uint32_t sMinCacheSize = 0;
/// Format is passed to the TextureClient for buffer creation.
gfx::SurfaceFormat mFormat;
/// The width and height of the tiles to be used.
gfx::IntSize mSize;
// The maximum number of texture clients managed by this pool that we want // The maximum number of texture clients managed by this pool that we want
// to remain active. // to remain active.
static const uint32_t sMaxTextureClients = 50; uint32_t mMaxTextureClients;
gfx::SurfaceFormat mFormat; // The time in milliseconds before the pool will be shrunk to the minimum
gfx::IntSize mSize; // size after returning a client.
uint32_t mShrinkTimeoutMsec;
uint32_t mOutstandingClients; uint32_t mOutstandingClients;

View File

@ -230,6 +230,8 @@ private:
// they are often the same size as the screen, especially for width. // 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-width", LayersTileWidth, int32_t, 256);
DECL_GFX_PREF(Once, "layers.tile-height", LayersTileHeight, int32_t, 256); DECL_GFX_PREF(Once, "layers.tile-height", LayersTileHeight, int32_t, 256);
DECL_GFX_PREF(Once, "layers.tile-max-pool-size", LayersTileMaxPoolSize, uint32_t, (uint32_t)50);
DECL_GFX_PREF(Once, "layers.tile-shrink-pool-timeout", LayersTileShrinkPoolTimeout, uint32_t, (uint32_t)1000);
DECL_GFX_PREF(Once, "layers.overzealous-gralloc-unlocking", OverzealousGrallocUnlocking, bool, false); DECL_GFX_PREF(Once, "layers.overzealous-gralloc-unlocking", OverzealousGrallocUnlocking, bool, false);
DECL_GFX_PREF(Once, "layers.force-shmem-tiles", ForceShmemTiles, bool, false); DECL_GFX_PREF(Once, "layers.force-shmem-tiles", ForceShmemTiles, bool, false);
DECL_GFX_PREF(Live, "layers.frame-counter", DrawFrameCounter, bool, false); DECL_GFX_PREF(Live, "layers.frame-counter", DrawFrameCounter, bool, false);