Bug 678859. Don't create layers for content less than 16x16 pixels. r=tn

This commit is contained in:
Robert O'Callahan 2011-10-26 14:14:49 +13:00
Родитель dc516e92fb
Коммит f2d3346139
1 изменённых файлов: 17 добавлений и 10 удалений

Просмотреть файл

@ -88,6 +88,11 @@ public:
namespace {
/**
* Active layers smaller than this in each dimension are treated as inactive.
*/
static const int MIN_ACTIVE_LAYER_SIZE = 16;
static void DestroyRegion(void* aPropertyValue)
{
delete static_cast<nsRegion*>(aPropertyValue);
@ -1328,7 +1333,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
NS_ASSERTION(appUnitsPerDevPixel == AppUnitsPerDevPixel(item),
"items in a container layer should all have the same app units per dev pixel");
nsIntRect itemVisibleRect =
nsIntRect itemVisibleRectPixels =
item->GetVisibleRect().ScaleToOutsidePixels(
mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel);
nsRect itemContent = item->GetBounds(mBuilder);
@ -1346,22 +1351,24 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
// Assign the item to a layer
if (layerState == LAYER_ACTIVE_FORCE ||
layerState == LAYER_ACTIVE_EMPTY ||
layerState == LAYER_ACTIVE && (aClip.mRoundedClipRects.IsEmpty() ||
// We can use the visible rect here only because the item has its own
// layer, like the comment below.
!aClip.IsRectClippedByRoundedCorner(item->GetVisibleRect()))) {
(layerState == LAYER_ACTIVE &&
(aClip.mRoundedClipRects.IsEmpty() ||
// We can use the visible rect here only because the item has its own
// layer, like the comment below.
!aClip.IsRectClippedByRoundedCorner(item->GetVisibleRect())) &&
!(itemVisibleRectPixels.Size() < nsIntSize(MIN_ACTIVE_LAYER_SIZE, MIN_ACTIVE_LAYER_SIZE)))) {
// 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 ||
itemVisibleRect.IsEmpty(),
itemVisibleRectPixels.IsEmpty(),
"State is LAYER_ACTIVE_EMPTY but visible rect is not.");
// If the item would have its own layer but is invisible, just hide it.
// Note that items without their own layers can't be skipped this
// way, since their ThebesLayer may decide it wants to draw them
// into its buffer even if they're currently covered.
if (itemVisibleRect.IsEmpty() && layerState != LAYER_ACTIVE_EMPTY) {
if (itemVisibleRectPixels.IsEmpty() && layerState != LAYER_ACTIVE_EMPTY) {
InvalidateForLayerChange(item, nsnull);
continue;
}
@ -1399,14 +1406,14 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
}
ThebesLayerData* data = GetTopThebesLayerData();
if (data) {
data->mVisibleAboveRegion.Or(data->mVisibleAboveRegion, itemVisibleRect);
data->mVisibleAboveRegion.Or(data->mVisibleAboveRegion, itemVisibleRectPixels);
// Add the entire bounds rect to the mDrawAboveRegion.
// The visible region may be excluding opaque content above the
// item, and we need to ensure that that content is not placed
// in a ThebesLayer below the item!
data->mDrawAboveRegion.Or(data->mDrawAboveRegion, itemDrawRect);
}
RestrictVisibleRegionForLayer(ownLayer, itemVisibleRect);
RestrictVisibleRegionForLayer(ownLayer, itemVisibleRectPixels);
ContainerLayer* oldContainer = ownLayer->GetParent();
if (oldContainer && oldContainer != mContainerLayer) {
oldContainer->RemoveChild(ownLayer);
@ -1420,7 +1427,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
mBuilder->LayerBuilder()->AddLayerDisplayItem(ownLayer, item, layerState);
} else {
nsRefPtr<ThebesLayer> thebesLayer =
FindThebesLayerFor(item, itemVisibleRect, itemDrawRect, aClip,
FindThebesLayerFor(item, itemVisibleRectPixels, itemDrawRect, aClip,
activeScrolledRoot);
thebesLayer->SetIsFixedPosition(!nsLayoutUtils::ScrolledByViewportScrolling(