Bug 580494. Avoid creating an empty ThebesLayer when an inactive nsDisplayItem::BuildLayer returns null. r=tnikkel

--HG--
extra : rebase_source : a22225bb3b5c2bbc12ab2f9b50594083143dbdf0
This commit is contained in:
Robert O'Callahan 2010-08-03 15:33:24 +12:00
parent ac5a6eaab0
commit 44555f22b8
4 changed files with 43 additions and 32 deletions

View File

@ -858,6 +858,33 @@ ContainerState::FindThebesLayerFor(const nsIntRect& aVisibleRect,
return layer.forget();
}
static already_AddRefed<BasicLayerManager>
BuildTempManagerForInactiveLayer(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem)
{
// This item has an inactive layer. We will render it to a ThebesLayer
// using a temporary BasicLayerManager. Set up the layer
// manager now so that if we need to modify the retained layer
// tree during this process, those modifications will happen
// during the construction phase for the retained layer tree.
nsRefPtr<BasicLayerManager> tempManager = new BasicLayerManager();
tempManager->BeginTransaction();
nsRefPtr<Layer> layer = aItem->BuildLayer(aBuilder, tempManager);
if (!layer) {
tempManager->EndTransaction(nsnull, nsnull);
return nsnull;
}
PRInt32 appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
nsIntRect itemVisibleRect =
aItem->GetVisibleRect().ToNearestPixels(appUnitsPerDevPixel);
SetVisibleRectForLayer(layer, itemVisibleRect);
tempManager->SetRoot(layer);
// No painting should occur yet, since there is no target context.
tempManager->EndTransaction(nsnull, nsnull);
return tempManager.forget();
}
/*
* Iterate through the non-clip items in aList and its descendants.
* For each item we compute the effective clip rect. Each item is assigned
@ -946,6 +973,13 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
mNewChildLayers.AppendElement(ownLayer);
mBuilder->LayerBuilder()->AddLayerDisplayItem(ownLayer, item);
} else {
nsRefPtr<BasicLayerManager> tempLayerManager;
if (layerState == LAYER_INACTIVE) {
tempLayerManager = BuildTempManagerForInactiveLayer(mBuilder, item);
if (!tempLayerManager)
continue;
}
nsIFrame* f = item->GetUnderlyingFrame();
nsPoint offsetToActiveScrolledRoot;
nsIFrame* activeScrolledRoot =
@ -981,9 +1015,8 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
InvalidateForLayerChange(item, thebesLayer);
mBuilder->LayerBuilder()->
AddThebesDisplayItem(thebesLayer, mBuilder,
item, aClipRect, mContainerFrame,
layerState);
AddThebesDisplayItem(thebesLayer, item, aClipRect, mContainerFrame,
layerState, tempLayerManager);
}
}
}
@ -1030,36 +1063,12 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer)
void
FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem,
const nsRect* aClipRect,
nsIFrame* aContainerLayerFrame,
LayerState aLayerState)
LayerState aLayerState,
LayerManager* aTempManager)
{
nsRefPtr<BasicLayerManager> tempManager;
if (aLayerState == LAYER_INACTIVE) {
// This item has an inactive layer. We will render it to a ThebesLayer
// using a temporary BasicLayerManager. Set up the layer
// manager now so that if we need to modify the retained layer
// tree during this process, those modifications will happen
// during the construction phase for the retained layer tree.
tempManager = new BasicLayerManager();
tempManager->BeginTransaction();
nsRefPtr<Layer> layer = aItem->BuildLayer(aBuilder, tempManager);
if (!layer) {
tempManager->EndTransaction(nsnull, nsnull);
return;
}
PRInt32 appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
nsIntRect itemVisibleRect =
aItem->GetVisibleRect().ToNearestPixels(appUnitsPerDevPixel);
SetVisibleRectForLayer(layer, itemVisibleRect);
tempManager->SetRoot(layer);
// No painting should occur yet, since there is no target context.
tempManager->EndTransaction(nsnull, nsnull);
}
AddLayerDisplayItem(aLayer, aItem);
ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
@ -1068,7 +1077,7 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
NS_ASSERTION(aItem->GetUnderlyingFrame(), "Must have frame");
ClippedDisplayItem* cdi =
entry->mItems.AppendElement(ClippedDisplayItem(aItem, aClipRect));
cdi->mTempLayerManager = tempManager.forget();
cdi->mTempLayerManager = aTempManager;
}
}

View File

@ -225,11 +225,11 @@ public:
* aItem must have an underlying frame.
*/
void AddThebesDisplayItem(ThebesLayer* aLayer,
nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem,
const nsRect* aClipRect,
nsIFrame* aContainerLayerFrame,
LayerState aLayerState);
LayerState aLayerState,
LayerManager* aTempManager);
/**
* Given a frame and a display item key that uniquely identifies a

View File

@ -0,0 +1 @@
<html><body><marquee><video></video></marquee></body></html>

View File

@ -305,3 +305,4 @@ load 567292-1.xhtml
load 569018-1.html
load 572003.xul
load 572582-1.xhtml
load 580494-1.html