зеркало из https://github.com/mozilla/pjs.git
Bug 397510 - Limit the number of lines we build textruns in BuildTextRuns (speeds up painting of huge pages) [p=roc r=smontagu a=blocking1.9+]
This commit is contained in:
Родитель
6d40f3d7ee
Коммит
b8f8919749
|
@ -572,6 +572,7 @@ public:
|
|||
|
||||
void SetAtStartOfLine() {
|
||||
mStartOfLine = PR_TRUE;
|
||||
mCanStopOnThisLine = PR_FALSE;
|
||||
}
|
||||
void SetSkipIncompleteTextRuns(PRBool aSkip) {
|
||||
mSkipIncompleteTextRuns = aSkip;
|
||||
|
@ -579,6 +580,9 @@ public:
|
|||
void SetCommonAncestorWithLastFrame(nsIFrame* aFrame) {
|
||||
mCommonAncestorWithLastFrame = aFrame;
|
||||
}
|
||||
PRBool CanStopOnThisLine() {
|
||||
return mCanStopOnThisLine;
|
||||
}
|
||||
nsIFrame* GetCommonAncestorWithLastFrame() {
|
||||
return mCommonAncestorWithLastFrame;
|
||||
}
|
||||
|
@ -686,6 +690,7 @@ private:
|
|||
PRPackedBool mTrimNextRunLeadingWhitespace;
|
||||
PRPackedBool mCurrentRunTrimLeadingWhitespace;
|
||||
PRPackedBool mSkipIncompleteTextRuns;
|
||||
PRPackedBool mCanStopOnThisLine;
|
||||
};
|
||||
|
||||
static nsIFrame*
|
||||
|
@ -798,6 +803,10 @@ BuildTextRunsScanner::FindBoundaries(nsIFrame* aFrame, FindBoundaryState* aState
|
|||
return FB_CONTINUE;
|
||||
}
|
||||
|
||||
// build text runs for the 200 lines following aForFrame, and stop after that
|
||||
// when we get a chance.
|
||||
#define NUM_LINES_TO_BUILD_TEXT_RUNS 200
|
||||
|
||||
/**
|
||||
* General routine for building text runs. This is hairy because of the need
|
||||
* to build text runs that span content nodes.
|
||||
|
@ -842,9 +851,9 @@ BuildTextRuns(gfxContext* aContext, nsTextFrame* aForFrame,
|
|||
}
|
||||
|
||||
// Find the line containing aForFrame
|
||||
nsBlockFrame::line_iterator line;
|
||||
nsBlockFrame::line_iterator startLine;
|
||||
if (aForFrameLine) {
|
||||
line = *aForFrameLine;
|
||||
startLine = *aForFrameLine;
|
||||
} else {
|
||||
NS_ASSERTION(aForFrame, "One of aForFrame or aForFrameLine must be set!");
|
||||
nsIFrame* immediateChild =
|
||||
|
@ -855,8 +864,8 @@ BuildTextRuns(gfxContext* aContext, nsTextFrame* aForFrame,
|
|||
nsLayoutUtils::FindChildContainingDescendant(block,
|
||||
presContext->FrameManager()->GetPlaceholderFrameFor(immediateChild));
|
||||
}
|
||||
line = block->FindLineFor(immediateChild);
|
||||
NS_ASSERTION(line != block->end_lines(),
|
||||
startLine = block->FindLineFor(immediateChild);
|
||||
NS_ASSERTION(startLine != block->end_lines(),
|
||||
"Frame is not in the block!!!");
|
||||
}
|
||||
|
||||
|
@ -873,12 +882,13 @@ BuildTextRuns(gfxContext* aContext, nsTextFrame* aForFrame,
|
|||
// but we discard them instead of assigning them to frames.
|
||||
// This is a little awkward because we traverse lines in the reverse direction
|
||||
// but we traverse the frames in each line in the forward direction.
|
||||
nsBlockInFlowLineIterator backIterator(block, line, PR_FALSE);
|
||||
nsBlockInFlowLineIterator backIterator(block, startLine, PR_FALSE);
|
||||
nsTextFrame* stopAtFrame = aForFrame;
|
||||
nsTextFrame* nextLineFirstTextFrame = nsnull;
|
||||
PRBool seenTextRunBoundaryOnLaterLine = PR_FALSE;
|
||||
PRBool mayBeginInTextRun = PR_TRUE;
|
||||
PRBool inOverflow = PR_FALSE;
|
||||
nsBlockFrame::line_iterator line;
|
||||
while (PR_TRUE) {
|
||||
line = backIterator.GetLine();
|
||||
block = backIterator.GetContainer();
|
||||
|
@ -927,6 +937,8 @@ BuildTextRuns(gfxContext* aContext, nsTextFrame* aForFrame,
|
|||
// text run boundary is required we flush textRunFrames ((re)building their
|
||||
// gfxTextRuns as necessary).
|
||||
nsBlockInFlowLineIterator forwardIterator(block, line, inOverflow);
|
||||
PRBool seenStartLine = PR_FALSE;
|
||||
PRUint32 linesAfterStartLine = 0;
|
||||
do {
|
||||
line = forwardIterator.GetLine();
|
||||
if (line->IsBlock())
|
||||
|
@ -940,6 +952,21 @@ BuildTextRuns(gfxContext* aContext, nsTextFrame* aForFrame,
|
|||
scanner.ScanFrame(child);
|
||||
child = child->GetNextSibling();
|
||||
}
|
||||
if (line == startLine) {
|
||||
seenStartLine = PR_TRUE;
|
||||
}
|
||||
if (seenStartLine) {
|
||||
++linesAfterStartLine;
|
||||
if (linesAfterStartLine >= NUM_LINES_TO_BUILD_TEXT_RUNS && scanner.CanStopOnThisLine()) {
|
||||
// Don't flush; we may be in the middle of a textrun that we can't
|
||||
// end here. That's OK, we just won't build it.
|
||||
// Note that we must already have finished the textrun for aForFrame,
|
||||
// because we've seen the end of a textrun in a line after the line
|
||||
// containing aForFrame.
|
||||
mLineBreaker.Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while (forwardIterator.Next());
|
||||
|
||||
// Set mStartOfLine so FlushFrames knows its textrun ends a line
|
||||
|
@ -1018,6 +1045,7 @@ void BuildTextRunsScanner::FlushFrames(PRBool aFlushLineBreaks)
|
|||
mBreakSinks.Clear();
|
||||
}
|
||||
|
||||
mCanStopOnThisLine = PR_TRUE;
|
||||
ResetRunInfo();
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче