Bug 836565, Part 2: Perform a horizontal resize reflow instead of a full reflow when reflowing on zoom to get better performance. [r=dbaron]

This commit is contained in:
Scott Johnson 2013-05-14 14:24:14 -05:00
parent 5acfb67e4a
commit a1007ebb6a
4 changed files with 45 additions and 7 deletions

View File

@ -1391,6 +1391,26 @@ public:
void SetMaxLineBoxWidth(nscoord aMaxLineBoxWidth);
/**
* Returns whether or not there is a reflow on zoom event pending. A reflow
* on zoom event is a change to the max line box width, followed by a reflow.
* This subsequent reflow event should treat all frames as though they resized
* horizontally (and thus reflow all their descendants), rather than marking
* all frames dirty from the root. This is the way the pres shell indicates
* that an hresize reflow should take place during reflow state construction.
*/
bool IsReflowOnZoomPending() {
return mReflowOnZoomPending;
}
/**
* Clear the flag indicating whether a reflow on zoom event is pending. This
* is performed at the very end of DoReflow().
*/
void ClearReflowOnZoomPending() {
mReflowOnZoomPending = false;
}
protected:
friend class nsRefreshDriver;
@ -1499,6 +1519,10 @@ protected:
bool mFontSizeInflationForceEnabled;
bool mFontSizeInflationDisabledInMasterProcess;
// Flag to indicate whether or not there is a reflow on zoom event pending.
// See IsReflowOnZoomPending() for more information.
bool mReflowOnZoomPending;
// The maximum width of a line box. Text on a single line that exceeds this
// width will be wrapped. A value of 0 indicates that no limit is enforced.
nscoord mMaxLineBoxWidth;

View File

@ -1877,7 +1877,7 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight)
DoReflow(rootFrame, true);
}
DidDoReflow(true);
DidDoReflow(true, false);
}
}
@ -7627,7 +7627,7 @@ PresShell::WillDoReflow()
}
void
PresShell::DidDoReflow(bool aInterruptible)
PresShell::DidDoReflow(bool aInterruptible, bool aWasInterrupted)
{
mFrameConstructor->EndUpdate();
@ -7641,6 +7641,10 @@ PresShell::DidDoReflow(bool aInterruptible)
mCaret->InvalidateOutsideCaret();
mCaret->UpdateCaretPosition();
}
if (!aWasInterrupted) {
ClearReflowOnZoomPending();
}
}
static PLDHashOperator
@ -7933,7 +7937,7 @@ PresShell::ProcessReflowCommands(bool aInterruptible)
// Exiting the scriptblocker might have killed us
if (!mIsDestroying) {
DidDoReflow(aInterruptible);
DidDoReflow(aInterruptible, interrupted);
}
// DidDoReflow might have killed us
@ -9476,6 +9480,7 @@ nsIPresShell::SetMaxLineBoxWidth(nscoord aMaxLineBoxWidth)
if (mMaxLineBoxWidth != aMaxLineBoxWidth) {
mMaxLineBoxWidth = aMaxLineBoxWidth;
FrameNeedsReflow(GetRootFrame(), eResize, NS_FRAME_IS_DIRTY);
mReflowOnZoomPending = true;
FrameNeedsReflow(GetRootFrame(), eResize, NS_FRAME_HAS_DIRTY_CHILDREN);
}
}

View File

@ -359,7 +359,15 @@ protected:
bool aTouchIsNew);
void WillDoReflow();
void DidDoReflow(bool aInterruptible);
/**
* Callback handler for whether reflow happened.
*
* @param aInterruptible Whether or not reflow interruption is allowed.
* @param aWasInterrupted Whether or not the reflow was interrupted earlier.
*
*/
void DidDoReflow(bool aInterruptible, bool aWasInterrupted);
// ProcessReflowCommands returns whether we processed all our dirty roots
// without interruptions.
bool ProcessReflowCommands(bool aInterruptible);

View File

@ -424,8 +424,9 @@ IsQuirkContainingBlockHeight(const nsHTMLReflowState* rs, nsIAtom* aFrameType)
void
nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameType)
{
bool isHResize = frame->GetSize().width !=
mComputedWidth + mComputedBorderPadding.LeftRight();
bool isHResize = (frame->GetSize().width !=
mComputedWidth + mComputedBorderPadding.LeftRight()) ||
aPresContext->PresShell()->IsReflowOnZoomPending();
if ((frame->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT) &&
nsLayoutUtils::FontSizeInflationEnabled(aPresContext)) {