Backed out changeset 7be71c699b85 (bug 984226) for crashtest asserts.

This commit is contained in:
Ryan VanderMeulen
2014-04-08 15:31:45 -04:00
parent 4f2ab11f5d
commit 3312b5d3a8
9 changed files with 70 additions and 126 deletions

View File

@@ -687,8 +687,7 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
// FinishAndStoreOverflow on it: // FinishAndStoreOverflow on it:
hint = NS_SubtractHint(hint, hint = NS_SubtractHint(hint,
NS_CombineHint(nsChangeHint_UpdateOverflow, NS_CombineHint(nsChangeHint_UpdateOverflow,
NS_CombineHint(nsChangeHint_ChildrenOnlyTransform, nsChangeHint_ChildrenOnlyTransform));
nsChangeHint_UpdatePostTransformOverflow)));
} }
if (hint & nsChangeHint_UpdateEffects) { if (hint & nsChangeHint_UpdateEffects) {
@@ -716,10 +715,7 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
NS_ASSERTION(!(hint & nsChangeHint_ChildrenOnlyTransform) || NS_ASSERTION(!(hint & nsChangeHint_ChildrenOnlyTransform) ||
(hint & nsChangeHint_UpdateOverflow), (hint & nsChangeHint_UpdateOverflow),
"nsChangeHint_UpdateOverflow should be passed too"); "nsChangeHint_UpdateOverflow should be passed too");
if (!didReflowThisFrame && if ((hint & nsChangeHint_UpdateOverflow) && !didReflowThisFrame) {
(hint & (nsChangeHint_UpdateOverflow |
nsChangeHint_UpdatePostTransformOverflow))) {
OverflowChangedTracker::ChangeKind changeKind;
if (hint & nsChangeHint_ChildrenOnlyTransform) { if (hint & nsChangeHint_ChildrenOnlyTransform) {
// The overflow areas of the child frames need to be updated: // The overflow areas of the child frames need to be updated:
nsIFrame* hintFrame = GetFrameForChildrenOnlyTransformHint(frame); nsIFrame* hintFrame = GetFrameForChildrenOnlyTransformHint(frame);
@@ -737,7 +733,7 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
// updating overflows since that will happen when it's reflowed. // updating overflows since that will happen when it's reflowed.
if (!(childFrame->GetStateBits() & if (!(childFrame->GetStateBits() &
(NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN))) { (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN))) {
mOverflowChangedTracker.AddFrame(childFrame, OverflowChangedTracker::CHILDREN_CHANGED); mOverflowChangedTracker.AddFrame(childFrame);
} }
NS_ASSERTION(!nsLayoutUtils::GetNextContinuationOrIBSplitSibling(childFrame), NS_ASSERTION(!nsLayoutUtils::GetNextContinuationOrIBSplitSibling(childFrame),
"SVG frames should not have continuations " "SVG frames should not have continuations "
@@ -750,17 +746,9 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
// overflows since that will happen when it's reflowed. // overflows since that will happen when it's reflowed.
if (!(frame->GetStateBits() & if (!(frame->GetStateBits() &
(NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN))) { (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN))) {
// If we have both nsChangeHint_UpdateOverflow and
// nsChangeHint_UpdatePostTransformOverflow, CHILDREN_CHANGED
// is selected as it is stronger.
if (hint & nsChangeHint_UpdateOverflow) {
changeKind = OverflowChangedTracker::CHILDREN_CHANGED;
} else {
changeKind = OverflowChangedTracker::TRANSFORM_CHANGED;
}
for (nsIFrame *cont = frame; cont; cont = for (nsIFrame *cont = frame; cont; cont =
nsLayoutUtils::GetNextContinuationOrIBSplitSibling(cont)) { nsLayoutUtils::GetNextContinuationOrIBSplitSibling(cont)) {
mOverflowChangedTracker.AddFrame(cont, changeKind); mOverflowChangedTracker.AddFrame(cont);
} }
} }
} }

View File

@@ -28,19 +28,6 @@ class RestyleManager;
class OverflowChangedTracker class OverflowChangedTracker
{ {
public: public:
enum ChangeKind {
/**
* The overflow areas of children have changed
* and we need to call UpdateOverflow on the frame.
*/
CHILDREN_CHANGED,
/**
* The frame was explicitly added as a result of
* nsChangeHint_UpdatePostTransformOverflow and hence may have had a style
* change that changes its geometry relative to parent, without reflowing.
*/
TRANSFORM_CHANGED
};
OverflowChangedTracker() : OverflowChangedTracker() :
mSubtreeRoot(nullptr) mSubtreeRoot(nullptr)
@@ -62,19 +49,14 @@ public:
* If the overflow area changes, then UpdateOverflow will also * If the overflow area changes, then UpdateOverflow will also
* be called on the parent. * be called on the parent.
*/ */
void AddFrame(nsIFrame* aFrame, ChangeKind aChangeKind) { void AddFrame(nsIFrame* aFrame) {
uint32_t depth = aFrame->GetDepthInFrameTree(); uint32_t depth = aFrame->GetDepthInFrameTree();
Entry *entry = nullptr; if (mEntryList.empty() ||
if (!mEntryList.empty()) { !mEntryList.find(Entry(aFrame, depth))) {
entry = mEntryList.find(Entry(aFrame, depth)); // All frames in mEntryList at this stage have STYLE_CHANGED so we don't
} // need to worry about setting the STYLE_CHANGED flag if 'find'
if (entry == nullptr) { // returns true.
// Add new entry mEntryList.insert(new Entry(aFrame, depth, STYLE_CHANGED));
mEntryList.insert(new Entry(aFrame, depth, aChangeKind));
} else if (aChangeKind == CHILDREN_CHANGED) {
// Update existing entry. CHILDREN_CHANGED is stronger than
// TRANSFORM_CHANGED and will replace CHILDREN_CHANGED value.
entry->mChangeKind = CHILDREN_CHANGED;
} }
} }
@@ -112,49 +94,38 @@ public:
Entry *entry = mEntryList.removeMin(); Entry *entry = mEntryList.removeMin();
nsIFrame *frame = entry->mFrame; nsIFrame *frame = entry->mFrame;
bool overflowChanged = false; bool overflowChanged;
if (entry->mChangeKind == CHILDREN_CHANGED) { if (entry->mFlags & CHILDREN_CHANGED) {
// Need to union the overflow areas of the children. // Need to union the overflow areas of the children.
overflowChanged = frame->UpdateOverflow(); overflowChanged = frame->UpdateOverflow();
} else { } else {
// Take a faster path that doesn't require unioning the overflow areas nsOverflowAreas* pre = static_cast<nsOverflowAreas*>
// of our children. (frame->Properties().Get(frame->PreTransformOverflowAreasProperty()));
if (pre) {
#ifdef DEBUG // Since we have the pre-transform-overflow-areas, we can take a
bool hasInitialOverflowPropertyApplied = false; // faster path that doesn't require unioning the overflow areas
frame->Properties().Get(nsIFrame::DebugInitialOverflowPropertyApplied(), // of our children.
&hasInitialOverflowPropertyApplied);
NS_ASSERTION(hasInitialOverflowPropertyApplied,
"InitialOverflowProperty must be set first.");
#endif
nsOverflowAreas* overflow =
static_cast<nsOverflowAreas*>(frame->Properties().Get(nsIFrame::InitialOverflowProperty()));
if (overflow) {
// FinishAndStoreOverflow will change the overflow areas passed in, // FinishAndStoreOverflow will change the overflow areas passed in,
// so make a copy. // so make a copy.
nsOverflowAreas overflowCopy = *overflow; nsOverflowAreas overflowAreas = *pre;
frame->FinishAndStoreOverflow(overflowCopy, frame->GetSize()); frame->FinishAndStoreOverflow(overflowAreas, frame->GetSize());
// We can't tell if the overflow changed, so be conservative
overflowChanged = true;
} else { } else {
nsRect bounds(nsPoint(0, 0), frame->GetSize()); // We can't take the faster path here. Do it the hard way.
nsOverflowAreas boundsOverflow; overflowChanged = frame->UpdateOverflow();
boundsOverflow.SetAllTo(bounds);
frame->FinishAndStoreOverflow(boundsOverflow, bounds.Size());
} }
// We can't tell if the overflow changed, so be conservative
overflowChanged = true;
} }
// If the frame style changed (e.g. positioning offsets) // If the frame style changed (e.g. positioning offsets)
// then we need to update the parent with the overflow areas of its // then we need to update the parent with the overflow areas of its
// children. // children.
if (overflowChanged) { if (overflowChanged || (entry->mFlags & STYLE_CHANGED)) {
nsIFrame *parent = frame->GetParent(); nsIFrame *parent = frame->GetParent();
if (parent && parent != mSubtreeRoot) { if (parent && parent != mSubtreeRoot) {
Entry* parentEntry = mEntryList.find(Entry(parent, entry->mDepth - 1)); Entry* parentEntry = mEntryList.find(Entry(parent, entry->mDepth - 1));
if (parentEntry) { if (parentEntry) {
parentEntry->mChangeKind = CHILDREN_CHANGED; parentEntry->mFlags |= CHILDREN_CHANGED;
} else { } else {
mEntryList.insert(new Entry(parent, entry->mDepth - 1, CHILDREN_CHANGED)); mEntryList.insert(new Entry(parent, entry->mDepth - 1, CHILDREN_CHANGED));
} }
@@ -165,12 +136,26 @@ public:
} }
private: private:
enum {
/**
* Set if the overflow areas of children have changed so we need to call
* UpdateOverflow on the frame.
*/
CHILDREN_CHANGED = 0x01,
/**
* True if the frame was explicitly added and hence may have had a style
* change that changes its geometry relative to parent, without reflowing.
* In this case we must update overflow on the frame's parent even if
* this frame's overflow did not change.
*/
STYLE_CHANGED = 0x02
};
struct Entry : SplayTreeNode<Entry> struct Entry : SplayTreeNode<Entry>
{ {
Entry(nsIFrame* aFrame, uint32_t aDepth, ChangeKind aChangeKind = CHILDREN_CHANGED) Entry(nsIFrame* aFrame, uint32_t aDepth, uint8_t aFlags = 0)
: mFrame(aFrame) : mFrame(aFrame)
, mDepth(aDepth) , mDepth(aDepth)
, mChangeKind(aChangeKind) , mFlags(aFlags)
{} {}
bool operator==(const Entry& aOther) const bool operator==(const Entry& aOther) const
@@ -204,7 +189,7 @@ private:
nsIFrame* mFrame; nsIFrame* mFrame;
/* Depth in the frame tree */ /* Depth in the frame tree */
uint32_t mDepth; uint32_t mDepth;
ChangeKind mChangeKind; uint8_t mFlags;
}; };
/* A list of frames to process, sorted by their depth in the frame tree */ /* A list of frames to process, sorted by their depth in the frame tree */

View File

@@ -72,23 +72,17 @@ enum nsChangeHint {
nsChangeHint_ReconstructFrame = 0x400, nsChangeHint_ReconstructFrame = 0x400,
/** /**
* The frame's overflow area has changed, either through a change in its * The frame's effect on its ancestors' overflow areas has changed,
* transform or a change in its position. Does not update any descendant * either through a change in its transform or a change in its position.
* frames.
*/
nsChangeHint_UpdateOverflow = 0x800,
/**
* The frame's overflow area has changed, through a change in its transform.
* Does not update any descendant frames. * Does not update any descendant frames.
*/ */
nsChangeHint_UpdatePostTransformOverflow = 0x1000, nsChangeHint_UpdateOverflow = 0x800,
/** /**
* The children-only transform of an SVG frame changed, requiring the * The children-only transform of an SVG frame changed, requiring the
* overflow rects of the frame's immediate children to be updated. * overflow rects of the frame's immediate children to be updated.
*/ */
nsChangeHint_ChildrenOnlyTransform = 0x2000, nsChangeHint_ChildrenOnlyTransform = 0x1000,
/** /**
* The frame's offsets have changed, while its dimensions might have * The frame's offsets have changed, while its dimensions might have
@@ -100,7 +94,7 @@ enum nsChangeHint {
* nsChangeHint_UpdateOverflow in order to get the overflow areas of * nsChangeHint_UpdateOverflow in order to get the overflow areas of
* the ancestors updated as well. * the ancestors updated as well.
*/ */
nsChangeHint_RecomputePosition = 0x4000, nsChangeHint_RecomputePosition = 0x2000,
/** /**
* Behaves like ReconstructFrame, but only if the frame has descendants * Behaves like ReconstructFrame, but only if the frame has descendants
@@ -108,7 +102,7 @@ enum nsChangeHint {
* has changed whether the frame is a container for fixed-pos or abs-pos * has changed whether the frame is a container for fixed-pos or abs-pos
* elements, but reframing is otherwise not needed. * elements, but reframing is otherwise not needed.
*/ */
nsChangeHint_AddOrRemoveTransform = 0x8000, nsChangeHint_AddOrRemoveTransform = 0x4000,
/** /**
* This change hint has *no* change handling behavior. However, it * This change hint has *no* change handling behavior. However, it
@@ -116,13 +110,13 @@ enum nsChangeHint {
* changes, and it's inherited by a child, that might require a reflow * changes, and it's inherited by a child, that might require a reflow
* due to the border-width change on the child. * due to the border-width change on the child.
*/ */
nsChangeHint_BorderStyleNoneChange = 0x10000, nsChangeHint_BorderStyleNoneChange = 0x8000,
/** /**
* SVG textPath needs to be recomputed because the path has changed. * SVG textPath needs to be recomputed because the path has changed.
* This means that the glyph positions of the text need to be recomputed. * This means that the glyph positions of the text need to be recomputed.
*/ */
nsChangeHint_UpdateTextPath = 0x20000 nsChangeHint_UpdateTextPath = 0x10000
// IMPORTANT NOTE: When adding new hints, consider whether you need to // IMPORTANT NOTE: When adding new hints, consider whether you need to
// add them to NS_HintsNotHandledForDescendantsIn() below. // add them to NS_HintsNotHandledForDescendantsIn() below.
@@ -178,7 +172,6 @@ inline bool NS_IsHintSubset(nsChangeHint aSubset, nsChangeHint aSuperSet) {
nsChangeHint_UpdateEffects | \ nsChangeHint_UpdateEffects | \
nsChangeHint_UpdateOpacityLayer | \ nsChangeHint_UpdateOpacityLayer | \
nsChangeHint_UpdateOverflow | \ nsChangeHint_UpdateOverflow | \
nsChangeHint_UpdatePostTransformOverflow | \
nsChangeHint_ChildrenOnlyTransform | \ nsChangeHint_ChildrenOnlyTransform | \
nsChangeHint_RecomputePosition | \ nsChangeHint_RecomputePosition | \
nsChangeHint_AddOrRemoveTransform | \ nsChangeHint_AddOrRemoveTransform | \
@@ -192,7 +185,6 @@ inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint)
nsChangeHint_UpdateEffects | nsChangeHint_UpdateEffects |
nsChangeHint_UpdateOpacityLayer | nsChangeHint_UpdateOpacityLayer |
nsChangeHint_UpdateOverflow | nsChangeHint_UpdateOverflow |
nsChangeHint_UpdatePostTransformOverflow |
nsChangeHint_ChildrenOnlyTransform | nsChangeHint_ChildrenOnlyTransform |
nsChangeHint_RecomputePosition | nsChangeHint_RecomputePosition |
nsChangeHint_AddOrRemoveTransform | nsChangeHint_AddOrRemoveTransform |

View File

@@ -371,12 +371,9 @@ StickyScrollContainer::UpdatePositions(nsPoint aScrollPosition,
// nsIFrame::Init. // nsIFrame::Init.
PositionContinuations(f); PositionContinuations(f);
f = f->GetParent(); for (nsIFrame* cont = f; cont;
if (f != aSubtreeRoot) { cont = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(cont)) {
for (nsIFrame* cont = f; cont; oct.AddFrame(cont);
cont = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(cont)) {
oct.AddFrame(cont, OverflowChangedTracker::CHILDREN_CHANGED);
}
} }
} }
oct.Flush(); oct.Flush();

View File

@@ -7182,28 +7182,18 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
"Don't call - overflow rects not maintained on these SVG frames"); "Don't call - overflow rects not maintained on these SVG frames");
nsRect bounds(nsPoint(0, 0), aNewSize); nsRect bounds(nsPoint(0, 0), aNewSize);
// Store the passed in overflow area if we are a preserve-3d frame or we have // Store the passed in overflow area if we are a preserve-3d frame,
// a transform, and it's not just the frame bounds. // and it's not just the frame bounds.
if (Preserves3D() || HasPerspective() || IsTransformed()) { if ((Preserves3D() || HasPerspective()) && (!aOverflowAreas.VisualOverflow().IsEqualEdges(bounds) ||
if (!aOverflowAreas.VisualOverflow().IsEqualEdges(bounds) || !aOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds))) {
!aOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds)) { nsOverflowAreas* initial =
static_cast<nsOverflowAreas*>(Properties().Get(nsIFrame::InitialOverflowProperty()));
nsOverflowAreas* initial = if (!initial) {
static_cast<nsOverflowAreas*>(Properties().Get(nsIFrame::InitialOverflowProperty())); Properties().Set(nsIFrame::InitialOverflowProperty(),
if (!initial) { new nsOverflowAreas(aOverflowAreas));
Properties().Set(nsIFrame::InitialOverflowProperty(), } else if (initial != &aOverflowAreas) {
new nsOverflowAreas(aOverflowAreas)); *initial = aOverflowAreas;
} else if (initial != &aOverflowAreas) {
*initial = aOverflowAreas;
}
} }
#ifdef DEBUG
Properties().Set(nsIFrame::DebugInitialOverflowPropertyApplied(), nullptr);
#endif
} else {
#ifdef DEBUG
Properties().Delete(nsIFrame::DebugInitialOverflowPropertyApplied());
#endif
} }
// This is now called FinishAndStoreOverflow() instead of // This is now called FinishAndStoreOverflow() instead of

View File

@@ -877,17 +877,10 @@ public:
DestroyOverflowAreas) DestroyOverflowAreas)
// The initial overflow area passed to FinishAndStoreOverflow. This is only set // The initial overflow area passed to FinishAndStoreOverflow. This is only set
// on frames that Preserve3D() or HasPerspective() or IsTransformed(), and // on frames that Preserve3D(), and when at least one of the overflow areas
// when at least one of the overflow areas differs from the frame bound rect. // differs from the frame bound rect.
NS_DECLARE_FRAME_PROPERTY(InitialOverflowProperty, DestroyOverflowAreas) NS_DECLARE_FRAME_PROPERTY(InitialOverflowProperty, DestroyOverflowAreas)
#ifdef DEBUG
// InitialOverflowPropertyDebug is added to the frame to indicate that either
// the InitialOverflowProperty has been stored or the InitialOverflowProperty
// has been suppressed due to being set to the default value (frame bounds)
NS_DECLARE_FRAME_PROPERTY(DebugInitialOverflowPropertyApplied, nullptr)
#endif
NS_DECLARE_FRAME_PROPERTY(UsedMarginProperty, DestroyMargin) NS_DECLARE_FRAME_PROPERTY(UsedMarginProperty, DestroyMargin)
NS_DECLARE_FRAME_PROPERTY(UsedPaddingProperty, DestroyMargin) NS_DECLARE_FRAME_PROPERTY(UsedPaddingProperty, DestroyMargin)
NS_DECLARE_FRAME_PROPERTY(UsedBorderProperty, DestroyMargin) NS_DECLARE_FRAME_PROPERTY(UsedBorderProperty, DestroyMargin)

View File

@@ -2524,7 +2524,7 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
if (!mSpecifiedTransform != !aOther.mSpecifiedTransform || if (!mSpecifiedTransform != !aOther.mSpecifiedTransform ||
(mSpecifiedTransform && (mSpecifiedTransform &&
*mSpecifiedTransform != *aOther.mSpecifiedTransform)) { *mSpecifiedTransform != *aOther.mSpecifiedTransform)) {
NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_UpdatePostTransformOverflow, NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_UpdateOverflow,
nsChangeHint_UpdateTransformLayer)); nsChangeHint_UpdateTransformLayer));
} }

View File

@@ -1901,7 +1901,6 @@ struct nsStyleDisplay {
nsChangeHint_UpdateOpacityLayer | nsChangeHint_UpdateOpacityLayer |
nsChangeHint_UpdateTransformLayer | nsChangeHint_UpdateTransformLayer |
nsChangeHint_UpdateOverflow | nsChangeHint_UpdateOverflow |
nsChangeHint_UpdatePostTransformOverflow |
nsChangeHint_AddOrRemoveTransform); nsChangeHint_AddOrRemoveTransform);
} }
static nsChangeHint MaxDifferenceNeverInherited() { static nsChangeHint MaxDifferenceNeverInherited() {

View File

@@ -1955,7 +1955,7 @@ nsTableFrame::FixupPositionedTableParts(nsPresContext* aPresContext,
// FIXME: Unconditionally using NS_UNCONSTRAINEDSIZE for the height and // FIXME: Unconditionally using NS_UNCONSTRAINEDSIZE for the height and
// ignoring any change to the reflow status aren't correct. We'll never // ignoring any change to the reflow status aren't correct. We'll never
// paginate absolutely positioned frames. // paginate absolutely positioned frames.
overflowTracker.AddFrame(positionedPart, OverflowChangedTracker::CHILDREN_CHANGED); overflowTracker.AddFrame(positionedPart);
nsFrame* positionedFrame = static_cast<nsFrame*>(positionedPart); nsFrame* positionedFrame = static_cast<nsFrame*>(positionedPart);
positionedFrame->FinishReflowWithAbsoluteFrames(PresContext(), positionedFrame->FinishReflowWithAbsoluteFrames(PresContext(),
desiredSize, desiredSize,