Backout changeset 65410094add4 (bug 539356) because of performance and correctness regressions

This commit is contained in:
Ehsan Akhgari 2012-07-03 20:19:18 -04:00
Родитель 238d1d3b87
Коммит 12c6e3a4cf
8 изменённых файлов: 35 добавлений и 174 удалений

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

@ -314,13 +314,6 @@ public:
bool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; }
/**
* Returns true if this LayerManager can properly support layers with
* SURFACE_COMPONENT_ALPHA. This can include disabling component
* alpha if required.
*/
virtual bool AreComponentAlphaLayersEnabled() { return true; }
/**
* CONSTRUCTION PHASE ONLY
* Set the root layer. The root layer is initially null. If there is

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

@ -95,8 +95,6 @@ public:
void* aCallbackData,
EndTransactionFlags aFlags = END_DEFAULT);
virtual bool AreComponentAlphaLayersEnabled() { return HasShadowManager(); }
virtual void SetRoot(Layer* aLayer);
virtual already_AddRefed<ThebesLayer> CreateThebesLayer();

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

@ -102,10 +102,6 @@ public:
CollectOldLayers();
}
enum ProcessDisplayItemsFlags {
NO_COMPONENT_ALPHA = 0x01,
};
/**
* This is the method that actually walks a display list and builds
* the child layers. We invoke it recursively to process clipped sublists.
@ -113,8 +109,7 @@ public:
* if no clipping is required
*/
void ProcessDisplayItems(const nsDisplayList& aList,
FrameLayerBuilder::Clip& aClip,
PRUint32 aFlags);
FrameLayerBuilder::Clip& aClip);
/**
* This finalizes all the open ThebesLayers by popping every element off
* mThebesLayerDataStack, then sets the children of the container layer
@ -773,11 +768,8 @@ FrameLayerBuilder::UpdateDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
LayerManagerData* managerData = static_cast<LayerManagerData*>
(builder->GetRetainingLayerManager()->GetUserData(&gLayerManagerUserData));
LayerManagerData* data = static_cast<LayerManagerData*>(props.Get(LayerManagerDataProperty()));
if (!newDisplayItems || newDisplayItems->mData.IsEmpty()) {
if (!newDisplayItems) {
// This frame was visible, but isn't anymore.
if (newDisplayItems) {
builder->mNewDisplayItemData.RawRemoveEntry(newDisplayItems);
}
if (data == managerData) {
props.Remove(LayerManagerDataProperty());
}
@ -1748,8 +1740,7 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
*/
void
ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
FrameLayerBuilder::Clip& aClip,
PRUint32 aFlags)
FrameLayerBuilder::Clip& aClip)
{
SAMPLE_LABEL("ContainerState", "ProcessDisplayItems");
for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) {
@ -1757,7 +1748,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
if (type == nsDisplayItem::TYPE_CLIP ||
type == nsDisplayItem::TYPE_CLIP_ROUNDED_RECT) {
FrameLayerBuilder::Clip childClip(aClip, item);
ProcessDisplayItems(*item->GetList(), childClip, aFlags);
ProcessDisplayItems(*item->GetList(), childClip);
continue;
}
@ -1779,22 +1770,13 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
nsIFrame* activeScrolledRoot;
bool forceInactive = false;
if (aFlags & NO_COMPONENT_ALPHA) {
activeScrolledRoot =
nsLayoutUtils::GetActiveScrolledRootFor(mContainerFrame,
mBuilder->ReferenceFrame());
forceInactive = true;
} else {
activeScrolledRoot = nsLayoutUtils::GetActiveScrolledRootFor(item, mBuilder);
}
nsIFrame* activeScrolledRoot =
nsLayoutUtils::GetActiveScrolledRootFor(item, mBuilder);
// Assign the item to a layer
if (layerState == LAYER_ACTIVE_FORCE ||
(!forceInactive &&
(layerState == LAYER_ACTIVE_EMPTY ||
layerState == LAYER_ACTIVE))) {
layerState == LAYER_ACTIVE_EMPTY ||
layerState == LAYER_ACTIVE) {
// LAYER_ACTIVE_EMPTY means the layer is created just for its metadata.
// We should never see an empty layer with any visible content!
@ -2037,12 +2019,10 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
if (entry) {
entry->mContainerLayerFrame = aContainerLayerFrame;
entry->mContainerLayerGeneration = mContainerLayerGeneration;
NS_ASSERTION(aItem->GetUnderlyingFrame(), "Must have frame");
if (tempManager) {
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
layerBuilder->Init(mDisplayListBuilder);
layerBuilder->mMaxContainerLayerGeneration = mMaxContainerLayerGeneration;
// LayerManager user data took ownership of the FrameLayerBuilder
tempManager->SetUserData(&gLayerManagerLayerBuilder, new LayerManagerLayerBuilder(layerBuilder, true));
@ -2064,12 +2044,11 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
// If BuildLayer didn't call BuildContainerLayerFor, then our new layer won't have been
// stored in layerBuilder. Manually add it now.
DisplayItemData data(layer, aItem->GetPerFrameKey(), LAYER_ACTIVE, mContainerLayerGeneration);
DisplayItemData data(layer, aItem->GetPerFrameKey(), LAYER_ACTIVE);
layerBuilder->StoreDataForFrame(aItem->GetUnderlyingFrame(), data);
tempManager->SetRoot(layer);
layerBuilder->WillEndTransaction();
mMaxContainerLayerGeneration = layerBuilder->mMaxContainerLayerGeneration;
nsIntRect invalid = props->ComputeDifferences(layer, nsnull);
if (aLayerState == LAYER_SVG_EFFECTS) {
@ -2079,8 +2058,7 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
aLayer->InvalidateRegion(invalid);
}
ClippedDisplayItem* cdi =
entry->mItems.AppendElement(ClippedDisplayItem(aItem, aClip,
mContainerLayerGeneration));
entry->mItems.AppendElement(ClippedDisplayItem(aItem, aClip));
cdi->mInactiveLayer = tempManager;
}
}
@ -2094,7 +2072,6 @@ FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame, DisplayItemData& aData)
}
entry = mNewDisplayItemData.PutEntry(aFrame);
if (entry) {
entry->mContainerLayerGeneration = mContainerLayerGeneration;
DisplayItemData *data = entry->mData.AppendElement();
*data = aData;
}
@ -2132,9 +2109,8 @@ FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
}
}
#endif
entry->mContainerLayerGeneration = mContainerLayerGeneration;
DisplayItemData* data = entry->mData.AppendElement();
DisplayItemData did(aLayer, aItem->GetPerFrameKey(), aLayerState, mContainerLayerGeneration);
DisplayItemData did(aLayer, aItem->GetPerFrameKey(), aLayerState);
*data = did;
ThebesLayer *t = aLayer->AsThebesLayer();
@ -2159,11 +2135,8 @@ nsIntPoint
FrameLayerBuilder::GetLastPaintOffset(ThebesLayer* aLayer)
{
ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
if (entry) {
entry->mContainerLayerGeneration = mContainerLayerGeneration;
if (entry->mHasExplicitLastPaintOffset)
return entry->mLastPaintOffset;
}
if (entry && entry->mHasExplicitLastPaintOffset)
return entry->mLastPaintOffset;
return GetTranslationForThebesLayer(aLayer);
}
@ -2172,7 +2145,6 @@ FrameLayerBuilder::SaveLastPaintOffset(ThebesLayer* aLayer)
{
ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
if (entry) {
entry->mContainerLayerGeneration = mContainerLayerGeneration;
entry->mLastPaintOffset = GetTranslationForThebesLayer(aLayer);
entry->mHasExplicitLastPaintOffset = true;
}
@ -2350,44 +2322,6 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
return result;
}
/* static */ PLDHashOperator
FrameLayerBuilder::RestoreDisplayItemData(DisplayItemDataEntry* aEntry, void* aUserArg)
{
PRUint32 *generation = static_cast<PRUint32*>(aUserArg);
if (aEntry->mContainerLayerGeneration >= *generation) {
return PL_DHASH_REMOVE;
}
for (PRUint32 i = 0; i < aEntry->mData.Length(); i++) {
if (aEntry->mData[i].mContainerLayerGeneration >= *generation) {
aEntry->mData.TruncateLength(i);
return PL_DHASH_NEXT;
}
}
return PL_DHASH_NEXT;
}
/* static */ PLDHashOperator
FrameLayerBuilder::RestoreThebesLayerItemEntries(ThebesLayerItemsEntry* aEntry, void* aUserArg)
{
PRUint32 *generation = static_cast<PRUint32*>(aUserArg);
if (aEntry->mContainerLayerGeneration >= *generation) {
return PL_DHASH_REMOVE;
}
for (PRUint32 i = 0; i < aEntry->mItems.Length(); i++) {
if (aEntry->mItems[i].mContainerLayerGeneration >= *generation) {
aEntry->mItems.TruncateLength(i);
return PL_DHASH_NEXT;
}
}
return PL_DHASH_NEXT;
}
already_AddRefed<ContainerLayer>
FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@ -2442,66 +2376,34 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
ContainerParameters scaleParameters =
ChooseScaleAndSetTransform(this, aContainerFrame, aTransform, aParameters,
containerLayer);
PRUint32 oldGeneration = mContainerLayerGeneration;
mContainerLayerGeneration = ++mMaxContainerLayerGeneration;
LayerManagerData* data = static_cast<LayerManagerData*>
(aManager->GetUserData(&gLayerManagerUserData));
ContainerState state(aBuilder, aManager, GetLayerBuilderForManager(aManager),
aContainerFrame, containerLayer, scaleParameters);
if (mRetainingManager) {
DisplayItemDataEntry* entry = mNewDisplayItemData.PutEntry(aContainerFrame);
if (entry) {
DisplayItemData *data = entry->mData.AppendElement();
DisplayItemData did(containerLayer, containerDisplayItemKey,
LAYER_ACTIVE, mContainerLayerGeneration);
LAYER_ACTIVE);
*data = did;
entry->mContainerLayerGeneration = mContainerLayerGeneration;
}
}
nsRect bounds;
nsIntRect pixBounds;
PRInt32 appUnitsPerDevPixel;
Clip clip;
state.ProcessDisplayItems(aChildren, clip);
LayerManagerData* data = static_cast<LayerManagerData*>
(aManager->GetUserData(&gLayerManagerUserData));
PRUint32 stateFlags =
(aContainerFrame->GetStateBits() & NS_FRAME_NO_COMPONENT_ALPHA) ?
ContainerState::NO_COMPONENT_ALPHA : 0;
// Set CONTENT_COMPONENT_ALPHA if any of our children have it.
// This is suboptimal ... a child could have text that's over transparent
// pixels in its own layer, but over opaque parts of previous siblings.
PRUint32 flags;
while (true) {
ContainerState state(aBuilder, aManager, GetLayerBuilderForManager(aManager),
aContainerFrame, containerLayer, scaleParameters);
Clip clip;
state.ProcessDisplayItems(aChildren, clip, stateFlags);
// Set CONTENT_COMPONENT_ALPHA if any of our children have it.
// This is suboptimal ... a child could have text that's over transparent
// pixels in its own layer, but over opaque parts of previous siblings.
state.Finish(&flags, data);
bounds = state.GetChildrenBounds();
pixBounds = state.ScaleToOutsidePixels(bounds, false);
appUnitsPerDevPixel = state.GetAppUnitsPerDevPixel();
if ((flags & Layer::CONTENT_COMPONENT_ALPHA) &&
mRetainingManager &&
!mRetainingManager->AreComponentAlphaLayersEnabled() &&
!stateFlags) {
// Since we don't want any component alpha layers on BasicLayers, we repeat
// the layer building process with this explicitely forced off.
// We restore the previous FrameLayerBuilder state since the first set
// of layer building will have changed it.
stateFlags = ContainerState::NO_COMPONENT_ALPHA;
mNewDisplayItemData.EnumerateEntries(RestoreDisplayItemData,
&mContainerLayerGeneration);
mThebesLayerItems.EnumerateEntries(RestoreThebesLayerItemEntries,
&mContainerLayerGeneration);
aContainerFrame->AddStateBits(NS_FRAME_NO_COMPONENT_ALPHA);
continue;
}
break;
}
state.Finish(&flags, data);
nsRect bounds = state.GetChildrenBounds();
NS_ASSERTION(bounds.IsEqualInterior(aChildren.GetBounds(aBuilder)), "Wrong bounds");
nsIntRect pixBounds = state.ScaleToOutsidePixels(bounds, false);
if (aContainerItem) {
nsIntRect itemVisibleRect =
aContainerItem->GetVisibleRect().ToOutsidePixels(AppUnitsPerDevPixel(aContainerItem));
@ -2513,7 +2415,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
// we won't paint
if (aChildren.IsOpaque() && !aChildren.NeedsTransparentSurface()) {
bounds.ScaleRoundIn(scaleParameters.mXScale, scaleParameters.mYScale);
if (bounds.Contains(pixBounds.ToAppUnits(appUnitsPerDevPixel))) {
if (bounds.Contains(pixBounds.ToAppUnits(state.GetAppUnitsPerDevPixel()))) {
// Clear CONTENT_COMPONENT_ALPHA
flags = Layer::CONTENT_OPAQUE;
}
@ -2522,7 +2424,6 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
containerLayer->SetUserData(&gNotifySubDocInvalidationData, nsnull);
mContainerLayerGeneration = oldGeneration;
return containerLayer.forget();
}

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

@ -110,9 +110,7 @@ public:
FrameLayerBuilder() :
mRetainingManager(nsnull),
mDetectedDOMModification(false),
mInvalidateAllLayers(false),
mContainerLayerGeneration(0),
mMaxContainerLayerGeneration(0)
mInvalidateAllLayers(false)
{
MOZ_COUNT_CTOR(FrameLayerBuilder);
mNewDisplayItemData.Init();
@ -454,13 +452,8 @@ protected:
*/
class DisplayItemData {
public:
DisplayItemData(Layer* aLayer, PRUint32 aKey, LayerState aLayerState, PRUint32 aGeneration)
: mLayer(aLayer)
, mDisplayItemKey(aKey)
, mContainerLayerGeneration(aGeneration)
, mLayerState(aLayerState)
, mUsed(false)
{}
DisplayItemData(Layer* aLayer, PRUint32 aKey, LayerState aLayerState)
: mLayer(aLayer), mDisplayItemKey(aKey), mLayerState(aLayerState), mUsed(false) {}
DisplayItemData()
: mUsed(false)
@ -473,7 +466,6 @@ protected:
mInactiveManager = toCopy.mInactiveManager;
mGeometry = toCopy.mGeometry;
mDisplayItemKey = toCopy.mDisplayItemKey;
mContainerLayerGeneration = toCopy.mContainerLayerGeneration;
mLayerState = toCopy.mLayerState;
mUsed = toCopy.mUsed;
}
@ -482,7 +474,6 @@ protected:
nsRefPtr<LayerManager> mInactiveManager;
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
PRUint32 mDisplayItemKey;
PRUint32 mContainerLayerGeneration;
LayerState mLayerState;
/**
@ -513,14 +504,12 @@ protected:
// This isn't actually a copy-constructor; notice that it steals toCopy's
// array. Be careful.
mData.SwapElements(toCopy.mData);
mContainerLayerGeneration = toCopy.mContainerLayerGeneration;
}
~DisplayItemDataEntry() { MOZ_COUNT_DTOR(DisplayItemDataEntry); }
bool HasNonEmptyContainerLayer();
nsAutoTArray<DisplayItemData, 1> mData;
PRUint32 mContainerLayerGeneration;
enum { ALLOW_MEMMOVE = false };
};
@ -575,8 +564,8 @@ protected:
* mItem always has an underlying frame.
*/
struct ClippedDisplayItem {
ClippedDisplayItem(nsDisplayItem* aItem, const Clip& aClip, PRUint32 aGeneration)
: mItem(aItem), mClip(aClip), mContainerLayerGeneration(aGeneration)
ClippedDisplayItem(nsDisplayItem* aItem, const Clip& aClip)
: mItem(aItem), mClip(aClip)
{
}
@ -592,7 +581,6 @@ protected:
nsRefPtr<LayerManager> mInactiveLayer;
Clip mClip;
PRUint32 mContainerLayerGeneration;
};
/**
@ -616,7 +604,6 @@ public:
// The translation set on this ThebesLayer before we started updating the
// layer tree.
nsIntPoint mLastPaintOffset;
PRUint32 mContainerLayerGeneration;
bool mHasExplicitLastPaintOffset;
/**
* The first mCommonClipCount rounded rectangle clips are identical for
@ -647,12 +634,6 @@ protected:
static PLDHashOperator StoreNewDisplayItemData(DisplayItemDataEntry* aEntry,
void* aUserArg);
static PLDHashOperator RestoreDisplayItemData(DisplayItemDataEntry* aEntry,
void *aUserArg);
static PLDHashOperator RestoreThebesLayerItemEntries(ThebesLayerItemsEntry* aEntry,
void *aUserArg);
/**
* Returns true if the DOM has been modified since we started painting,
* in which case we should bail out and not paint anymore. This should
@ -698,9 +679,6 @@ protected:
* during this paint.
*/
bool mInvalidateAllLayers;
PRUint32 mContainerLayerGeneration;
PRUint32 mMaxContainerLayerGeneration;
};
}

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

@ -2051,7 +2051,7 @@ public:
LayerManager* aManager,
const ContainerParameters& aParameters)
{
return mozilla::LAYER_ACTIVE_FORCE;
return mozilla::LAYER_ACTIVE;
}
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem)
{

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

@ -1635,10 +1635,6 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
return NS_ERROR_OUT_OF_MEMORY;
}
for (nsIFrame* f = rootFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
f->RemoveStateBits(NS_FRAME_NO_COMPONENT_ALPHA);
}
Element *root = mDocument->GetRootElement();
if (root) {

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

@ -239,11 +239,6 @@ typedef PRUint64 nsFrameState;
// This bit acts as a loop flag for recursive paint server drawing.
#define NS_FRAME_DRAWING_AS_PAINTSERVER NS_FRAME_STATE_BIT(33)
// This bit is set on frames that create ContainerLayers with component
// alpha children. With BasicLayers we avoid creating these, so we mark
// the frames for future reference.
#define NS_FRAME_NO_COMPONENT_ALPHA NS_FRAME_STATE_BIT(34)
// Frame's overflow area was clipped by the 'clip' property.
#define NS_FRAME_HAS_CLIP NS_FRAME_STATE_BIT(35)

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

@ -131,7 +131,7 @@ public:
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aParameters)
{ return mozilla::LAYER_ACTIVE_FORCE; }
{ return mozilla::LAYER_ACTIVE; }
NS_OVERRIDE
virtual already_AddRefed<Layer>