зеркало из https://github.com/mozilla/gecko-dev.git
Bug 269905. Remember emptiness state on line boxes, but be selective about to to minimize the invalidation burden. r+sr=dbaron
This commit is contained in:
Родитель
ae04809e92
Коммит
917ba5cead
|
@ -2211,7 +2211,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
||||||
// and also because our final height may depend on it. Only
|
// and also because our final height may depend on it. Only
|
||||||
// update mY if the line is not empty, because that's what
|
// update mY if the line is not empty, because that's what
|
||||||
// PlaceLine does.
|
// PlaceLine does.
|
||||||
if (!line->IsEmpty()) {
|
if (!line->CachedIsEmpty()) {
|
||||||
aState.mY = line->mBounds.YMost();
|
aState.mY = line->mBounds.YMost();
|
||||||
// This will include any pending float clearing height, so
|
// This will include any pending float clearing height, so
|
||||||
// don't bother clearing previous lines' floats
|
// don't bother clearing previous lines' floats
|
||||||
|
@ -2483,6 +2483,7 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
|
||||||
// Setup the line-layout for the new line
|
// Setup the line-layout for the new line
|
||||||
aState.mCurrentLine = aLine;
|
aState.mCurrentLine = aLine;
|
||||||
aLine->ClearDirty();
|
aLine->ClearDirty();
|
||||||
|
aLine->InvalidateCachedIsEmpty();
|
||||||
|
|
||||||
// Now that we know what kind of line we have, reflow it
|
// Now that we know what kind of line we have, reflow it
|
||||||
if (aLine->IsBlock()) {
|
if (aLine->IsBlock()) {
|
||||||
|
@ -3027,7 +3028,7 @@ nsBlockFrame::ShouldApplyTopMargin(nsBlockReflowState& aState,
|
||||||
|
|
||||||
// Determine if this line is "essentially" the first line
|
// Determine if this line is "essentially" the first line
|
||||||
for (line_iterator line = begin_lines(); line != aLine; ++line) {
|
for (line_iterator line = begin_lines(); line != aLine; ++line) {
|
||||||
if (!line->IsEmpty()) {
|
if (!line->CachedIsEmpty()) {
|
||||||
// A line which preceeds aLine is non-empty, so therefore the
|
// A line which preceeds aLine is non-empty, so therefore the
|
||||||
// top margin applies.
|
// top margin applies.
|
||||||
aState.SetFlag(BRS_APPLYTOPMARGIN, PR_TRUE);
|
aState.SetFlag(BRS_APPLYTOPMARGIN, PR_TRUE);
|
||||||
|
@ -3053,7 +3054,7 @@ nsBlockFrame::GetTopBlockChild(nsPresContext* aPresContext)
|
||||||
if (firstLine->IsBlock())
|
if (firstLine->IsBlock())
|
||||||
return firstLine->mFirstChild;
|
return firstLine->mFirstChild;
|
||||||
|
|
||||||
if (!firstLine->IsEmpty())
|
if (!firstLine->CachedIsEmpty())
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
line_iterator secondLine = begin_lines();
|
line_iterator secondLine = begin_lines();
|
||||||
|
@ -4195,7 +4196,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||||
// collapsed with a block that follows.
|
// collapsed with a block that follows.
|
||||||
nscoord newY;
|
nscoord newY;
|
||||||
|
|
||||||
if (!aLine->IsEmpty()) {
|
if (!aLine->CachedIsEmpty()) {
|
||||||
// This line has some height. Therefore the application of the
|
// This line has some height. Therefore the application of the
|
||||||
// previous-bottom-margin should stick.
|
// previous-bottom-margin should stick.
|
||||||
aState.mPrevBottomMargin.Zero();
|
aState.mPrevBottomMargin.Zero();
|
||||||
|
|
|
@ -288,6 +288,23 @@ nsLineBox::IsEmpty() const
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsLineBox::CachedIsEmpty()
|
||||||
|
{
|
||||||
|
if (mFlags.mDirty) {
|
||||||
|
return IsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mFlags.mEmptyCacheValid) {
|
||||||
|
return mFlags.mEmptyCacheState;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool result = IsEmpty();
|
||||||
|
mFlags.mEmptyCacheValid = PR_TRUE;
|
||||||
|
mFlags.mEmptyCacheState = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsLineBox::DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines)
|
nsLineBox::DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines)
|
||||||
{
|
{
|
||||||
|
|
|
@ -400,6 +400,20 @@ public:
|
||||||
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
|
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
|
||||||
PRBool IsEmpty() const;
|
PRBool IsEmpty() const;
|
||||||
|
|
||||||
|
// Call this only while in Reflow() for the block the line belongs
|
||||||
|
// to, only between reflowing the line (or sliding it, if we skip
|
||||||
|
// reflowing it) and the end of reflowing the the block.
|
||||||
|
PRBool CachedIsEmpty();
|
||||||
|
|
||||||
|
void InvalidateCachedIsEmpty() {
|
||||||
|
mFlags.mEmptyCacheValid = PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For debugging purposes
|
||||||
|
PRBool IsValidCachedIsEmpty() {
|
||||||
|
return mFlags.mEmptyCacheValid;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static PRInt32 GetCtorCount();
|
static PRInt32 GetCtorCount();
|
||||||
#endif
|
#endif
|
||||||
|
@ -418,9 +432,11 @@ public:
|
||||||
PRUint32 mHasPercentageChild : 1;
|
PRUint32 mHasPercentageChild : 1;
|
||||||
PRUint32 mLineWrapped: 1;
|
PRUint32 mLineWrapped: 1;
|
||||||
PRUint32 mResizeReflowOptimizationDisabled: 1; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow
|
PRUint32 mResizeReflowOptimizationDisabled: 1; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow
|
||||||
|
PRUint32 mEmptyCacheValid: 1;
|
||||||
|
PRUint32 mEmptyCacheState: 1;
|
||||||
PRUint32 mBreakType : 4;
|
PRUint32 mBreakType : 4;
|
||||||
|
|
||||||
PRUint32 mChildCount : 21;
|
PRUint32 mChildCount : 19;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExtraData {
|
struct ExtraData {
|
||||||
|
|
|
@ -2211,7 +2211,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
||||||
// and also because our final height may depend on it. Only
|
// and also because our final height may depend on it. Only
|
||||||
// update mY if the line is not empty, because that's what
|
// update mY if the line is not empty, because that's what
|
||||||
// PlaceLine does.
|
// PlaceLine does.
|
||||||
if (!line->IsEmpty()) {
|
if (!line->CachedIsEmpty()) {
|
||||||
aState.mY = line->mBounds.YMost();
|
aState.mY = line->mBounds.YMost();
|
||||||
// This will include any pending float clearing height, so
|
// This will include any pending float clearing height, so
|
||||||
// don't bother clearing previous lines' floats
|
// don't bother clearing previous lines' floats
|
||||||
|
@ -2483,6 +2483,7 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
|
||||||
// Setup the line-layout for the new line
|
// Setup the line-layout for the new line
|
||||||
aState.mCurrentLine = aLine;
|
aState.mCurrentLine = aLine;
|
||||||
aLine->ClearDirty();
|
aLine->ClearDirty();
|
||||||
|
aLine->InvalidateCachedIsEmpty();
|
||||||
|
|
||||||
// Now that we know what kind of line we have, reflow it
|
// Now that we know what kind of line we have, reflow it
|
||||||
if (aLine->IsBlock()) {
|
if (aLine->IsBlock()) {
|
||||||
|
@ -3027,7 +3028,7 @@ nsBlockFrame::ShouldApplyTopMargin(nsBlockReflowState& aState,
|
||||||
|
|
||||||
// Determine if this line is "essentially" the first line
|
// Determine if this line is "essentially" the first line
|
||||||
for (line_iterator line = begin_lines(); line != aLine; ++line) {
|
for (line_iterator line = begin_lines(); line != aLine; ++line) {
|
||||||
if (!line->IsEmpty()) {
|
if (!line->CachedIsEmpty()) {
|
||||||
// A line which preceeds aLine is non-empty, so therefore the
|
// A line which preceeds aLine is non-empty, so therefore the
|
||||||
// top margin applies.
|
// top margin applies.
|
||||||
aState.SetFlag(BRS_APPLYTOPMARGIN, PR_TRUE);
|
aState.SetFlag(BRS_APPLYTOPMARGIN, PR_TRUE);
|
||||||
|
@ -3053,7 +3054,7 @@ nsBlockFrame::GetTopBlockChild(nsPresContext* aPresContext)
|
||||||
if (firstLine->IsBlock())
|
if (firstLine->IsBlock())
|
||||||
return firstLine->mFirstChild;
|
return firstLine->mFirstChild;
|
||||||
|
|
||||||
if (!firstLine->IsEmpty())
|
if (!firstLine->CachedIsEmpty())
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
line_iterator secondLine = begin_lines();
|
line_iterator secondLine = begin_lines();
|
||||||
|
@ -4195,7 +4196,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||||
// collapsed with a block that follows.
|
// collapsed with a block that follows.
|
||||||
nscoord newY;
|
nscoord newY;
|
||||||
|
|
||||||
if (!aLine->IsEmpty()) {
|
if (!aLine->CachedIsEmpty()) {
|
||||||
// This line has some height. Therefore the application of the
|
// This line has some height. Therefore the application of the
|
||||||
// previous-bottom-margin should stick.
|
// previous-bottom-margin should stick.
|
||||||
aState.mPrevBottomMargin.Zero();
|
aState.mPrevBottomMargin.Zero();
|
||||||
|
|
|
@ -288,6 +288,23 @@ nsLineBox::IsEmpty() const
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsLineBox::CachedIsEmpty()
|
||||||
|
{
|
||||||
|
if (mFlags.mDirty) {
|
||||||
|
return IsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mFlags.mEmptyCacheValid) {
|
||||||
|
return mFlags.mEmptyCacheState;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool result = IsEmpty();
|
||||||
|
mFlags.mEmptyCacheValid = PR_TRUE;
|
||||||
|
mFlags.mEmptyCacheState = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsLineBox::DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines)
|
nsLineBox::DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines)
|
||||||
{
|
{
|
||||||
|
|
|
@ -400,6 +400,20 @@ public:
|
||||||
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
|
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
|
||||||
PRBool IsEmpty() const;
|
PRBool IsEmpty() const;
|
||||||
|
|
||||||
|
// Call this only while in Reflow() for the block the line belongs
|
||||||
|
// to, only between reflowing the line (or sliding it, if we skip
|
||||||
|
// reflowing it) and the end of reflowing the the block.
|
||||||
|
PRBool CachedIsEmpty();
|
||||||
|
|
||||||
|
void InvalidateCachedIsEmpty() {
|
||||||
|
mFlags.mEmptyCacheValid = PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For debugging purposes
|
||||||
|
PRBool IsValidCachedIsEmpty() {
|
||||||
|
return mFlags.mEmptyCacheValid;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static PRInt32 GetCtorCount();
|
static PRInt32 GetCtorCount();
|
||||||
#endif
|
#endif
|
||||||
|
@ -418,9 +432,11 @@ public:
|
||||||
PRUint32 mHasPercentageChild : 1;
|
PRUint32 mHasPercentageChild : 1;
|
||||||
PRUint32 mLineWrapped: 1;
|
PRUint32 mLineWrapped: 1;
|
||||||
PRUint32 mResizeReflowOptimizationDisabled: 1; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow
|
PRUint32 mResizeReflowOptimizationDisabled: 1; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow
|
||||||
|
PRUint32 mEmptyCacheValid: 1;
|
||||||
|
PRUint32 mEmptyCacheState: 1;
|
||||||
PRUint32 mBreakType : 4;
|
PRUint32 mBreakType : 4;
|
||||||
|
|
||||||
PRUint32 mChildCount : 21;
|
PRUint32 mChildCount : 19;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExtraData {
|
struct ExtraData {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче