From d2766aacef10069e7163cd403bb00985af949e00 Mon Sep 17 00:00:00 2001 From: "karnaze%netscape.com" Date: Tue, 12 Mar 2002 15:48:52 +0000 Subject: [PATCH] bug 128804 - moved optimization of text controls to nsBlockReflowState and initialized it earlier. a=dbaron, sr=attinasi, r=alexsavulov. git-svn-id: svn://10.0.0.236/trunk@116409 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsBlockFrame.cpp | 34 ++----------------- mozilla/layout/generic/nsBlockFrame.h | 5 --- mozilla/layout/generic/nsBlockReflowState.cpp | 28 +++++++++++++++ mozilla/layout/generic/nsBlockReflowState.h | 7 +++- mozilla/layout/html/base/src/nsBlockFrame.cpp | 34 ++----------------- mozilla/layout/html/base/src/nsBlockFrame.h | 5 --- .../html/base/src/nsBlockReflowState.cpp | 28 +++++++++++++++ .../layout/html/base/src/nsBlockReflowState.h | 7 +++- 8 files changed, 72 insertions(+), 76 deletions(-) diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index 68f5f14cdd8..96785c22ab4 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -781,7 +781,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, // Do nothing; the dirty lines will already have been marked. break; - case eReflowReason_Incremental: // should call GetNext() ? + case eReflowReason_Incremental: aReflowState.reflowCommand->GetTarget(target); if (this == target) { nsReflowType type; @@ -2112,33 +2112,6 @@ WrappedLinesAreDirty(nsLineList::iterator aLine, return PR_FALSE; } -PRBool nsBlockFrame::IsIncrementalDamageConstrained(const nsBlockReflowState& aState) const -{ - // see if the reflow will go through a text control. if so, we can optimize - // because we know the text control won't change size. - if (aState.mReflowState.reflowCommand) - { - nsIFrame *target; - aState.mReflowState.reflowCommand->GetTarget(target); - while (target) - { // starting with the target's parent, scan for a text control - nsIFrame *parent; - target->GetParent(&parent); - if ((nsIFrame*)this==parent || !parent) // the null check is paranoia, it should never happen - break; // we found ourself, so we know there's no text control between us and target - nsCOMPtr frameType; - parent->GetFrameType(getter_AddRefs(frameType)); - if (frameType) - { - if (nsLayoutAtoms::textInputFrame == frameType.get()) - return PR_TRUE; // damage is constrained to the text control innards - } - target = parent; // advance the loop up the frame tree - } - } - return PR_FALSE; // default case, damage is not constrained (or unknown) -} - static void PlaceFrameView(nsIPresContext* aPresContext, nsIFrame* aFrame); /** @@ -2273,10 +2246,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState) // Reflow the dirty line. If it's an incremental reflow, then force // it to invalidate the dirty area if necessary - PRBool forceInvalidate = PR_FALSE; - if (incrementalReflow) { - forceInvalidate = !IsIncrementalDamageConstrained(aState); - } + PRBool forceInvalidate = incrementalReflow && !aState.GetFlag(BRS_DAMAGECONSTRAINED); rv = ReflowLine(aState, line, &keepGoing, forceInvalidate); if (NS_FAILED(rv)) { return rv; diff --git a/mozilla/layout/generic/nsBlockFrame.h b/mozilla/layout/generic/nsBlockFrame.h index 67fa31dd636..083ec395ba7 100644 --- a/mozilla/layout/generic/nsBlockFrame.h +++ b/mozilla/layout/generic/nsBlockFrame.h @@ -230,11 +230,6 @@ protected: return 0 != (mState & NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET); } - /** return PR_TRUE if the incremental reflow described by aState is 100% contained - * within the bounds of a ancestor frame, relative to this frame. - */ - PRBool IsIncrementalDamageConstrained(const nsBlockReflowState& aState) const; - /** move the frames contained by aLine by aDY * if aLine is a block, it's child floaters are added to the state manager */ diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index 06ec84c67a0..bc54241b672 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -176,6 +176,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState, mMinLineHeight = nsHTMLReflowState::CalcLineHeight(mPresContext, aReflowState.rendContext, aReflowState.frame); + + SetFlag(BRS_DAMAGECONSTRAINED, IsIncrementalDamageConstrained(aFrame)); } nsBlockReflowState::~nsBlockReflowState() @@ -188,6 +190,32 @@ nsBlockReflowState::~nsBlockReflowState() } } +PRBool +nsBlockReflowState::IsIncrementalDamageConstrained(nsIFrame* aBlockFrame) const +{ + // see if the reflow will go through a text control. if so, we can optimize + // because we know the text control won't change size. + if ((eReflowReason_Incremental == mReflowState.reason) && (mReflowState.reflowCommand)) { + nsIFrame* target; + mReflowState.reflowCommand->GetTarget(target); + while (target) { + // starting with the target's parent, scan for a text control + nsIFrame* parent; + target->GetParent(&parent); + if ((aBlockFrame == parent) || !parent) // the null check is paranoia, it should never happen + break; // we found the block, so we know there's no text control between the block and target + nsCOMPtr frameType; + parent->GetFrameType(getter_AddRefs(frameType)); + if (frameType) { + if (nsLayoutAtoms::textInputFrame == frameType.get()) + return PR_TRUE; // damage is constrained to the text control innards + } + target = parent; // advance the loop up the frame tree + } + } + return PR_FALSE; // default case, damage is not constrained (or unknown) +} + nsLineBox* nsBlockReflowState::NewLineBox(nsIFrame* aFrame, PRInt32 aCount, diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index a6acdb2d2a0..58918bf0965 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -112,6 +112,10 @@ public: protected: void RecoverFloaters(nsLineList::iterator aLine, nscoord aDeltaY); + // return PR_TRUE if the incremental reflow is 100% contained + // within the bounds of an ancestor frame, relative to aBlockFrame + PRBool IsIncrementalDamageConstrained(nsIFrame* aBlockFrame) const; + public: void RecoverStateFrom(nsLineList::iterator aLine, nscoord aDeltaY); @@ -251,7 +255,8 @@ public: #define BRS_APPLYTOPMARGIN 0x00000100 // See ShouldApplyTopMargin #define BRS_COMPUTEMAXELEMENTSIZE 0x00000200 #define BRS_COMPUTEMAXWIDTH 0x00000400 -#define BRS_LASTFLAG BRS_COMPUTEMAXWIDTH +#define BRS_DAMAGECONSTRAINED 0x00000800 // is the target of an incremental reflow command inside a text control +#define BRS_LASTFLAG BRS_DAMAGECONSTRAINED PRInt16 mFlags; diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index 68f5f14cdd8..96785c22ab4 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -781,7 +781,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, // Do nothing; the dirty lines will already have been marked. break; - case eReflowReason_Incremental: // should call GetNext() ? + case eReflowReason_Incremental: aReflowState.reflowCommand->GetTarget(target); if (this == target) { nsReflowType type; @@ -2112,33 +2112,6 @@ WrappedLinesAreDirty(nsLineList::iterator aLine, return PR_FALSE; } -PRBool nsBlockFrame::IsIncrementalDamageConstrained(const nsBlockReflowState& aState) const -{ - // see if the reflow will go through a text control. if so, we can optimize - // because we know the text control won't change size. - if (aState.mReflowState.reflowCommand) - { - nsIFrame *target; - aState.mReflowState.reflowCommand->GetTarget(target); - while (target) - { // starting with the target's parent, scan for a text control - nsIFrame *parent; - target->GetParent(&parent); - if ((nsIFrame*)this==parent || !parent) // the null check is paranoia, it should never happen - break; // we found ourself, so we know there's no text control between us and target - nsCOMPtr frameType; - parent->GetFrameType(getter_AddRefs(frameType)); - if (frameType) - { - if (nsLayoutAtoms::textInputFrame == frameType.get()) - return PR_TRUE; // damage is constrained to the text control innards - } - target = parent; // advance the loop up the frame tree - } - } - return PR_FALSE; // default case, damage is not constrained (or unknown) -} - static void PlaceFrameView(nsIPresContext* aPresContext, nsIFrame* aFrame); /** @@ -2273,10 +2246,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState) // Reflow the dirty line. If it's an incremental reflow, then force // it to invalidate the dirty area if necessary - PRBool forceInvalidate = PR_FALSE; - if (incrementalReflow) { - forceInvalidate = !IsIncrementalDamageConstrained(aState); - } + PRBool forceInvalidate = incrementalReflow && !aState.GetFlag(BRS_DAMAGECONSTRAINED); rv = ReflowLine(aState, line, &keepGoing, forceInvalidate); if (NS_FAILED(rv)) { return rv; diff --git a/mozilla/layout/html/base/src/nsBlockFrame.h b/mozilla/layout/html/base/src/nsBlockFrame.h index 67fa31dd636..083ec395ba7 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.h +++ b/mozilla/layout/html/base/src/nsBlockFrame.h @@ -230,11 +230,6 @@ protected: return 0 != (mState & NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET); } - /** return PR_TRUE if the incremental reflow described by aState is 100% contained - * within the bounds of a ancestor frame, relative to this frame. - */ - PRBool IsIncrementalDamageConstrained(const nsBlockReflowState& aState) const; - /** move the frames contained by aLine by aDY * if aLine is a block, it's child floaters are added to the state manager */ diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index 06ec84c67a0..bc54241b672 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -176,6 +176,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState, mMinLineHeight = nsHTMLReflowState::CalcLineHeight(mPresContext, aReflowState.rendContext, aReflowState.frame); + + SetFlag(BRS_DAMAGECONSTRAINED, IsIncrementalDamageConstrained(aFrame)); } nsBlockReflowState::~nsBlockReflowState() @@ -188,6 +190,32 @@ nsBlockReflowState::~nsBlockReflowState() } } +PRBool +nsBlockReflowState::IsIncrementalDamageConstrained(nsIFrame* aBlockFrame) const +{ + // see if the reflow will go through a text control. if so, we can optimize + // because we know the text control won't change size. + if ((eReflowReason_Incremental == mReflowState.reason) && (mReflowState.reflowCommand)) { + nsIFrame* target; + mReflowState.reflowCommand->GetTarget(target); + while (target) { + // starting with the target's parent, scan for a text control + nsIFrame* parent; + target->GetParent(&parent); + if ((aBlockFrame == parent) || !parent) // the null check is paranoia, it should never happen + break; // we found the block, so we know there's no text control between the block and target + nsCOMPtr frameType; + parent->GetFrameType(getter_AddRefs(frameType)); + if (frameType) { + if (nsLayoutAtoms::textInputFrame == frameType.get()) + return PR_TRUE; // damage is constrained to the text control innards + } + target = parent; // advance the loop up the frame tree + } + } + return PR_FALSE; // default case, damage is not constrained (or unknown) +} + nsLineBox* nsBlockReflowState::NewLineBox(nsIFrame* aFrame, PRInt32 aCount, diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.h b/mozilla/layout/html/base/src/nsBlockReflowState.h index a6acdb2d2a0..58918bf0965 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.h +++ b/mozilla/layout/html/base/src/nsBlockReflowState.h @@ -112,6 +112,10 @@ public: protected: void RecoverFloaters(nsLineList::iterator aLine, nscoord aDeltaY); + // return PR_TRUE if the incremental reflow is 100% contained + // within the bounds of an ancestor frame, relative to aBlockFrame + PRBool IsIncrementalDamageConstrained(nsIFrame* aBlockFrame) const; + public: void RecoverStateFrom(nsLineList::iterator aLine, nscoord aDeltaY); @@ -251,7 +255,8 @@ public: #define BRS_APPLYTOPMARGIN 0x00000100 // See ShouldApplyTopMargin #define BRS_COMPUTEMAXELEMENTSIZE 0x00000200 #define BRS_COMPUTEMAXWIDTH 0x00000400 -#define BRS_LASTFLAG BRS_COMPUTEMAXWIDTH +#define BRS_DAMAGECONSTRAINED 0x00000800 // is the target of an incremental reflow command inside a text control +#define BRS_LASTFLAG BRS_DAMAGECONSTRAINED PRInt16 mFlags;