Back out bug 785333 (revisions 79345542f853 and a1756976e61d) to fix crasher bug 785626

This commit is contained in:
Gavin Sharp 2012-08-27 16:41:19 -07:00
parent 6458cc3fa4
commit f99257a9f5
3 changed files with 22 additions and 82 deletions

View File

@ -882,7 +882,7 @@ FrameLayerBuilder::HasRetainedLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKe
}
Layer*
FrameLayerBuilder::GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey)
FrameLayerBuilder::GetOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
{
// If we need to build a new layer tree, then just refuse to recycle
// anything.
@ -903,31 +903,6 @@ FrameLayerBuilder::GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKe
return nullptr;
}
Layer*
FrameLayerBuilder::GetOldLayerFor(nsDisplayItem* aItem)
{
uint32_t key = aItem->GetPerFrameKey();
nsIFrame* frame = aItem->GetUnderlyingFrame();
if (frame) {
Layer* oldLayer = GetOldLayerForFrame(frame, key);
if (oldLayer) {
return oldLayer;
}
}
nsAutoTArray<nsIFrame*,4> mergedFrames;
aItem->GetMergedFrames(&mergedFrames);
for (uint32_t i = 0; i < mergedFrames.Length(); ++i) {
Layer* oldLayer = GetOldLayerForFrame(mergedFrames[i], key);
if (oldLayer) {
return oldLayer;
}
}
return nullptr;
}
/* static */ Layer*
FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
{
@ -1887,9 +1862,11 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
void
ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer)
{
NS_ASSERTION(aItem->GetUnderlyingFrame(), "Display items that render using Thebes must have a frame");
NS_ASSERTION(aItem->GetPerFrameKey(), "Display items that render using Thebes must have a key");
Layer* oldLayer = mLayerBuilder->GetOldLayerFor(aItem);
nsIFrame* f = aItem->GetUnderlyingFrame();
NS_ASSERTION(f, "Display items that render using Thebes must have a frame");
uint32_t key = aItem->GetPerFrameKey();
NS_ASSERTION(key, "Display items that render using Thebes must have a key");
Layer* oldLayer = mLayerBuilder->GetOldLayerFor(f, key);
if (!oldLayer) {
// Nothing to do here, this item didn't have a layer before
return;
@ -1961,19 +1938,6 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
}
}
void
FrameLayerBuilder::AddLayerDisplayItemForFrame(Layer* aLayer,
nsIFrame* aFrame,
PRUint32 aDisplayItemKey,
LayerState aLayerState)
{
DisplayItemDataEntry* entry = mNewDisplayItemData.PutEntry(aFrame);
if (entry) {
entry->mContainerLayerGeneration = mContainerLayerGeneration;
entry->mData.AppendElement(DisplayItemData(aLayer, aDisplayItemKey, aLayerState, mContainerLayerGeneration));
}
}
void
FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
nsDisplayItem* aItem,
@ -1983,13 +1947,10 @@ FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
return;
nsIFrame* f = aItem->GetUnderlyingFrame();
PRUint32 key = aItem->GetPerFrameKey();
AddLayerDisplayItemForFrame(aLayer, f, key, aLayerState);
nsAutoTArray<nsIFrame*,4> mergedFrames;
aItem->GetMergedFrames(&mergedFrames);
for (PRUint32 i = 0; i < mergedFrames.Length(); ++i) {
AddLayerDisplayItemForFrame(aLayer, mergedFrames[i], key, aLayerState);
DisplayItemDataEntry* entry = mNewDisplayItemData.PutEntry(f);
entry->mContainerLayerGeneration = mContainerLayerGeneration;
if (entry) {
entry->mData.AppendElement(DisplayItemData(aLayer, aItem->GetPerFrameKey(), aLayerState, mContainerLayerGeneration));
}
}
@ -2324,14 +2285,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
nsRefPtr<ContainerLayer> containerLayer;
if (aManager == mRetainingManager) {
// Using GetOldLayerFor will search merged frames, as well as the underlying
// frame. The underlying frame can change when a page scrolls, so this
// avoids layer recreation in the situation that a new underlying frame is
// picked for a layer.
Layer* oldLayer = aContainerItem ?
GetOldLayerFor(aContainerItem) :
GetOldLayerForFrame(aContainerFrame, containerDisplayItemKey);
Layer* oldLayer = GetOldLayerFor(aContainerFrame, containerDisplayItemKey);
if (oldLayer) {
NS_ASSERTION(oldLayer->Manager() == aManager, "Wrong manager");
if (oldLayer->HasUserData(&gThebesDisplayItemLayerUserData)) {
@ -2425,13 +2379,6 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
nsIFrame* mergedFrame = mergedFrames[i];
DisplayItemDataEntry* entry = mNewDisplayItemData.PutEntry(mergedFrame);
if (entry) {
// Append the container layer so we don't regenerate layers when
// the underlying frame of an item changes to one of the existing
// merged frames.
entry->mData.AppendElement(
DisplayItemData(containerLayer, containerDisplayItemKey,
LAYER_ACTIVE, mContainerLayerGeneration));
// Ensure that UpdateDisplayItemDataForFrame recognizes that we
// still have a container layer associated with this frame.
entry->mIsSharingContainerLayer = true;
@ -2505,7 +2452,7 @@ FrameLayerBuilder::GetLeafLayerFor(nsDisplayListBuilder* aBuilder,
nsIFrame* f = aItem->GetUnderlyingFrame();
NS_ASSERTION(f, "Can only call GetLeafLayerFor on items that have a frame");
Layer* layer = GetOldLayerForFrame(f, aItem->GetPerFrameKey());
Layer* layer = GetOldLayerFor(f, aItem->GetPerFrameKey());
if (!layer)
return nullptr;
if (layer->HasUserData(&gThebesDisplayItemLayerUserData)) {

View File

@ -268,7 +268,7 @@ public:
/* These are only in the public section because they need
* to be called by file-scope helper functions in FrameLayerBuilder.cpp.
*/
/**
* Record aItem as a display item that is rendered by aLayer.
*/
@ -276,14 +276,6 @@ public:
nsDisplayItem* aItem,
LayerState aLayerState);
/**
* Record aFrame as a frame that is rendered by an item on aLayer.
*/
void AddLayerDisplayItemForFrame(Layer* aLayer,
nsIFrame* aFrame,
PRUint32 aDisplayItemKey,
LayerState aLayerState);
/**
* Record aItem as a display item that is rendered by the ThebesLayer
* aLayer, with aClipRect, where aContainerLayerFrame is the frame
@ -304,14 +296,7 @@ public:
* This could be a dedicated layer for the display item, or a ThebesLayer
* that renders many display items.
*/
Layer* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey);
/**
* Calls GetOldLayerForFrame on the underlying frame of the display item,
* and each subsequent merged frame if no layer is found for the underlying
* frame.
*/
Layer* GetOldLayerFor(nsDisplayItem* aItem);
Layer* GetOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
/**

View File

@ -2692,6 +2692,14 @@ nsDisplayScrollLayer::TryMerge(nsDisplayListBuilder* aBuilder,
props.Set(nsIFrame::ScrollLayerCount(),
reinterpret_cast<void*>(GetScrollLayerCount() - 1));
// Swap frames with the other item before doing MergeFrom.
// XXX - This ensures that the frame associated with a scroll layer after
// merging is the first, rather than the last. This tends to change less,
// ensuring we're more likely to retain the associated gfx layer.
// See Bug 729534 and Bug 731641.
nsIFrame* tmp = mFrame;
mFrame = other->mFrame;
other->mFrame = tmp;
MergeFromTrackingMergedFrames(other);
return true;
}