зеркало из https://github.com/mozilla/pjs.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:
Родитель
471522f868
Коммит
352f29c25c
|
@ -2211,7 +2211,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
// and also because our final height may depend on it. Only
|
||||
// update mY if the line is not empty, because that's what
|
||||
// PlaceLine does.
|
||||
if (!line->IsEmpty()) {
|
||||
if (!line->CachedIsEmpty()) {
|
||||
aState.mY = line->mBounds.YMost();
|
||||
// This will include any pending float clearing height, so
|
||||
// don't bother clearing previous lines' floats
|
||||
|
@ -2483,7 +2483,8 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
|
|||
// Setup the line-layout for the new line
|
||||
aState.mCurrentLine = aLine;
|
||||
aLine->ClearDirty();
|
||||
|
||||
aLine->InvalidateCachedIsEmpty();
|
||||
|
||||
// Now that we know what kind of line we have, reflow it
|
||||
if (aLine->IsBlock()) {
|
||||
nsRect oldBounds = aLine->mFirstChild->GetRect();
|
||||
|
@ -3027,7 +3028,7 @@ nsBlockFrame::ShouldApplyTopMargin(nsBlockReflowState& aState,
|
|||
|
||||
// Determine if this line is "essentially" the first 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
|
||||
// top margin applies.
|
||||
aState.SetFlag(BRS_APPLYTOPMARGIN, PR_TRUE);
|
||||
|
@ -3053,7 +3054,7 @@ nsBlockFrame::GetTopBlockChild(nsPresContext* aPresContext)
|
|||
if (firstLine->IsBlock())
|
||||
return firstLine->mFirstChild;
|
||||
|
||||
if (!firstLine->IsEmpty())
|
||||
if (!firstLine->CachedIsEmpty())
|
||||
return nsnull;
|
||||
|
||||
line_iterator secondLine = begin_lines();
|
||||
|
@ -4195,7 +4196,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
// collapsed with a block that follows.
|
||||
nscoord newY;
|
||||
|
||||
if (!aLine->IsEmpty()) {
|
||||
if (!aLine->CachedIsEmpty()) {
|
||||
// This line has some height. Therefore the application of the
|
||||
// previous-bottom-margin should stick.
|
||||
aState.mPrevBottomMargin.Zero();
|
||||
|
|
|
@ -288,6 +288,23 @@ nsLineBox::IsEmpty() const
|
|||
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
|
||||
nsLineBox::DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines)
|
||||
{
|
||||
|
|
|
@ -400,6 +400,20 @@ public:
|
|||
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
|
||||
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
|
||||
static PRInt32 GetCtorCount();
|
||||
#endif
|
||||
|
@ -418,9 +432,11 @@ public:
|
|||
PRUint32 mHasPercentageChild : 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 mEmptyCacheValid: 1;
|
||||
PRUint32 mEmptyCacheState: 1;
|
||||
PRUint32 mBreakType : 4;
|
||||
|
||||
PRUint32 mChildCount : 21;
|
||||
PRUint32 mChildCount : 19;
|
||||
};
|
||||
|
||||
struct ExtraData {
|
||||
|
|
|
@ -2211,7 +2211,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
// and also because our final height may depend on it. Only
|
||||
// update mY if the line is not empty, because that's what
|
||||
// PlaceLine does.
|
||||
if (!line->IsEmpty()) {
|
||||
if (!line->CachedIsEmpty()) {
|
||||
aState.mY = line->mBounds.YMost();
|
||||
// This will include any pending float clearing height, so
|
||||
// don't bother clearing previous lines' floats
|
||||
|
@ -2483,7 +2483,8 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
|
|||
// Setup the line-layout for the new line
|
||||
aState.mCurrentLine = aLine;
|
||||
aLine->ClearDirty();
|
||||
|
||||
aLine->InvalidateCachedIsEmpty();
|
||||
|
||||
// Now that we know what kind of line we have, reflow it
|
||||
if (aLine->IsBlock()) {
|
||||
nsRect oldBounds = aLine->mFirstChild->GetRect();
|
||||
|
@ -3027,7 +3028,7 @@ nsBlockFrame::ShouldApplyTopMargin(nsBlockReflowState& aState,
|
|||
|
||||
// Determine if this line is "essentially" the first 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
|
||||
// top margin applies.
|
||||
aState.SetFlag(BRS_APPLYTOPMARGIN, PR_TRUE);
|
||||
|
@ -3053,7 +3054,7 @@ nsBlockFrame::GetTopBlockChild(nsPresContext* aPresContext)
|
|||
if (firstLine->IsBlock())
|
||||
return firstLine->mFirstChild;
|
||||
|
||||
if (!firstLine->IsEmpty())
|
||||
if (!firstLine->CachedIsEmpty())
|
||||
return nsnull;
|
||||
|
||||
line_iterator secondLine = begin_lines();
|
||||
|
@ -4195,7 +4196,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
// collapsed with a block that follows.
|
||||
nscoord newY;
|
||||
|
||||
if (!aLine->IsEmpty()) {
|
||||
if (!aLine->CachedIsEmpty()) {
|
||||
// This line has some height. Therefore the application of the
|
||||
// previous-bottom-margin should stick.
|
||||
aState.mPrevBottomMargin.Zero();
|
||||
|
|
|
@ -288,6 +288,23 @@ nsLineBox::IsEmpty() const
|
|||
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
|
||||
nsLineBox::DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines)
|
||||
{
|
||||
|
|
|
@ -400,6 +400,20 @@ public:
|
|||
// whether the line box is "logically" empty (just like nsIFrame::IsEmpty)
|
||||
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
|
||||
static PRInt32 GetCtorCount();
|
||||
#endif
|
||||
|
@ -418,9 +432,11 @@ public:
|
|||
PRUint32 mHasPercentageChild : 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 mEmptyCacheValid: 1;
|
||||
PRUint32 mEmptyCacheState: 1;
|
||||
PRUint32 mBreakType : 4;
|
||||
|
||||
PRUint32 mChildCount : 21;
|
||||
PRUint32 mChildCount : 19;
|
||||
};
|
||||
|
||||
struct ExtraData {
|
||||
|
|
Загрузка…
Ссылка в новой задаче