Bug 873378 - Add a limit on mobile of 20 layers per container layer. r=roc

This commit is contained in:
Benoit Girard 2013-07-16 16:17:18 -04:00
parent 4f9a15477d
commit 9cca89434d
5 changed files with 39 additions and 0 deletions

View File

@ -2041,6 +2041,9 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
topLeft = lastActiveScrolledRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
}
int32_t maxLayers = nsDisplayItem::MaxActiveLayers();
int layerCount = 0;
for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) {
NS_ASSERTION(mAppUnitsPerDevPixel == AppUnitsPerDevPixel(item),
"items in a container layer should all have the same app units per dev pixel");
@ -2083,6 +2086,10 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
}
}
if (maxLayers != -1 && layerCount >= maxLayers) {
forceInactive = true;
}
// Assign the item to a layer
if (layerState == LAYER_ACTIVE_FORCE ||
(layerState == LAYER_INACTIVE && !mManager->IsWidgetLayerManager()) ||
@ -2090,6 +2097,8 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
(layerState == LAYER_ACTIVE_EMPTY ||
layerState == LAYER_ACTIVE))) {
layerCount++;
// LAYER_ACTIVE_EMPTY means the layer is created just for its metadata.
// We should never see an empty layer with any visible content!
NS_ASSERTION(layerState != LAYER_ACTIVE_EMPTY ||

View File

@ -1497,6 +1497,20 @@ nsDisplayItem::ForceActiveLayers()
return sForce;
}
/* static */ int32_t
nsDisplayItem::MaxActiveLayers()
{
static int32_t sMaxLayers = false;
static bool sMaxLayersCached = false;
if (!sMaxLayersCached) {
Preferences::AddIntVarCache(&sMaxLayers, "layers.max-active", -1);
sMaxLayersCached = true;
}
return sMaxLayersCached;
}
bool
nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {

View File

@ -1003,6 +1003,12 @@ public:
*/
static bool ForceActiveLayers();
/**
* Returns the maximum number of layers that should be created
* or -1 for no limit. Requires setting the pref layers.max-acitve.
*/
static int32_t MaxActiveLayers();
/**
* @return LAYER_NONE if BuildLayer will return null. In this case
* there is no layer for the item, and Paint should be called instead

View File

@ -546,6 +546,12 @@ pref("layers.async-video.enabled", true);
pref("layers.progressive-paint", true);
pref("layers.low-precision-buffer", true);
pref("layers.low-precision-resolution", 250);
// We want to limit layers for two reasons:
// 1) We can't scroll smoothly if we have to many draw calls
// 2) Pages that have too many layers consume too much memory and crash.
// By limiting the number of layers on mobile we're making the main thread
// work harder keep scrolling smooth and memory low.
pref("layers.max-active", 20);
pref("notification.feature.enabled", true);
pref("dom.webnotifications.enabled", true);

View File

@ -4053,6 +4053,10 @@ pref("layers.acceleration.draw-fps", false);
pref("layers.draw-borders", false);
pref("layers.frame-counter", false);
// Max number of layers per container. See Overwrite in mobile prefs.
pref("layers.max-active", -1);
#ifdef XP_MACOSX
pref("layers.offmainthreadcomposition.enabled", true);
#else