Fix performance problem on home.netscape.com: Don't do full reflow of all absolutely positioned elements whose containing block is on the path to the target of an incremental reflow. b=146831 sr=waterson r=kin
This commit is contained in:
@@ -194,8 +194,11 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
|
|||||||
// Initialize OUT parameter
|
// Initialize OUT parameter
|
||||||
aChildBounds.SetRect(0, 0, 0, 0);
|
aChildBounds.SetRect(0, 0, 0, 0);
|
||||||
|
|
||||||
// Make a copy of the reflow state. If the reason is eReflowReason_Incremental,
|
// Make a copy of the reflow state. If the reason is
|
||||||
// then change it to eReflowReason_Resize
|
// eReflowReason_Incremental (which should mean either that the target
|
||||||
|
// is the frame for which this is the absolute container or that the
|
||||||
|
// container changed size due to incremental reflow of its children),
|
||||||
|
// then change it to eReflowReason_Resize.
|
||||||
nsHTMLReflowState reflowState(aReflowState);
|
nsHTMLReflowState reflowState(aReflowState);
|
||||||
if (eReflowReason_Incremental == reflowState.reason) {
|
if (eReflowReason_Incremental == reflowState.reason) {
|
||||||
reflowState.reason = eReflowReason_Resize;
|
reflowState.reason = eReflowReason_Resize;
|
||||||
|
|||||||
@@ -729,6 +729,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nsRect oldRect(mRect);
|
||||||
|
|
||||||
// Should we create a space manager?
|
// Should we create a space manager?
|
||||||
nsAutoSpaceManager autoSpaceManager(NS_CONST_CAST(nsHTMLReflowState &, aReflowState));
|
nsAutoSpaceManager autoSpaceManager(NS_CONST_CAST(nsHTMLReflowState &, aReflowState));
|
||||||
|
|
||||||
@@ -739,8 +741,10 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
if (NS_BLOCK_SPACE_MGR & mState)
|
if (NS_BLOCK_SPACE_MGR & mState)
|
||||||
autoSpaceManager.CreateSpaceManagerFor(aPresContext, this);
|
autoSpaceManager.CreateSpaceManagerFor(aPresContext, this);
|
||||||
|
|
||||||
// See if it's an incremental reflow command
|
// See if it's an incremental reflow command and we're not the target
|
||||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
if (mAbsoluteContainer.HasAbsoluteFrames() &&
|
||||||
|
eReflowReason_Incremental == aReflowState.reason &&
|
||||||
|
!aReflowState.path->mReflowCommand) {
|
||||||
// Give the absolute positioning code a chance to handle it
|
// Give the absolute positioning code a chance to handle it
|
||||||
nscoord containingBlockWidth;
|
nscoord containingBlockWidth;
|
||||||
nscoord containingBlockHeight;
|
nscoord containingBlockHeight;
|
||||||
@@ -1021,7 +1025,18 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
// Let the absolutely positioned container reflow any absolutely positioned
|
// Let the absolutely positioned container reflow any absolutely positioned
|
||||||
// child frames that need to be reflowed, e.g., elements with a percentage
|
// child frames that need to be reflowed, e.g., elements with a percentage
|
||||||
// based width/height
|
// based width/height
|
||||||
if (NS_SUCCEEDED(rv) && mAbsoluteContainer.HasAbsoluteFrames()) {
|
// We want to do this under either of two conditions:
|
||||||
|
// 1. If we didn't do the incremental reflow above.
|
||||||
|
// 2. If our size changed.
|
||||||
|
// Even though it's the padding edge that's the containing block, we
|
||||||
|
// can use our rect (the border edge) since if the border style
|
||||||
|
// changed, the reflow would have been targeted at us so we'd satisfy
|
||||||
|
// condition 1.
|
||||||
|
if (NS_SUCCEEDED(rv) &&
|
||||||
|
mAbsoluteContainer.HasAbsoluteFrames() &&
|
||||||
|
(eReflowReason_Incremental != aReflowState.reason ||
|
||||||
|
aReflowState.path->mReflowCommand ||
|
||||||
|
mRect != oldRect)) {
|
||||||
nscoord containingBlockWidth;
|
nscoord containingBlockWidth;
|
||||||
nscoord containingBlockHeight;
|
nscoord containingBlockHeight;
|
||||||
nsRect childBounds;
|
nsRect childBounds;
|
||||||
@@ -2168,7 +2183,8 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
|
|
||||||
// If we're supposed to update our maximum width, then we'll also need to
|
// If we're supposed to update our maximum width, then we'll also need to
|
||||||
// reflow this line if it's line wrapped and any of the continuing lines
|
// reflow this line if it's line wrapped and any of the continuing lines
|
||||||
// are dirty. If we are printing (constrained height), always reflow the line
|
// are dirty. If we are printing (constrained height), always reflow
|
||||||
|
// the line.
|
||||||
if ((NS_UNCONSTRAINEDSIZE != aState.mReflowState.availableHeight) ||
|
if ((NS_UNCONSTRAINEDSIZE != aState.mReflowState.availableHeight) ||
|
||||||
(!line->IsDirty() &&
|
(!line->IsDirty() &&
|
||||||
aState.GetFlag(BRS_COMPUTEMAXWIDTH) &&
|
aState.GetFlag(BRS_COMPUTEMAXWIDTH) &&
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "nsIFontMetrics.h"
|
#include "nsIFontMetrics.h"
|
||||||
#include "nsAbsoluteContainingBlock.h"
|
#include "nsAbsoluteContainingBlock.h"
|
||||||
#include "nsLayoutAtoms.h"
|
#include "nsLayoutAtoms.h"
|
||||||
|
#include "nsReflowPath.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#undef NOISY_PUSHING
|
#undef NOISY_PUSHING
|
||||||
@@ -1204,8 +1205,12 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
// See if it's an incremental reflow command
|
nsRect oldRect(mRect);
|
||||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
|
||||||
|
// See if it's an incremental reflow command and we're not the target
|
||||||
|
if (mAbsoluteContainer.HasAbsoluteFrames() &&
|
||||||
|
eReflowReason_Incremental == aReflowState.reason &&
|
||||||
|
!aReflowState.path->mReflowCommand) {
|
||||||
// Give the absolute positioning code a chance to handle it
|
// Give the absolute positioning code a chance to handle it
|
||||||
PRBool handled;
|
PRBool handled;
|
||||||
nsRect childBounds;
|
nsRect childBounds;
|
||||||
@@ -1252,7 +1257,18 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
// Let the absolutely positioned container reflow any absolutely positioned
|
// Let the absolutely positioned container reflow any absolutely positioned
|
||||||
// child frames that need to be reflowed
|
// child frames that need to be reflowed
|
||||||
if (NS_SUCCEEDED(rv)) {
|
// We want to do this under either of two conditions:
|
||||||
|
// 1. If we didn't do the incremental reflow above.
|
||||||
|
// 2. If our size changed.
|
||||||
|
// Even though it's the padding edge that's the containing block, we
|
||||||
|
// can use our rect (the border edge) since if the border style
|
||||||
|
// changed, the reflow would have been targeted at us so we'd satisfy
|
||||||
|
// condition 1.
|
||||||
|
if (NS_SUCCEEDED(rv) &&
|
||||||
|
mAbsoluteContainer.HasAbsoluteFrames() &&
|
||||||
|
(eReflowReason_Incremental != aReflowState.reason ||
|
||||||
|
aReflowState.path->mReflowCommand ||
|
||||||
|
mRect != oldRect)) {
|
||||||
nscoord containingBlockWidth = -1;
|
nscoord containingBlockWidth = -1;
|
||||||
nscoord containingBlockHeight = -1;
|
nscoord containingBlockHeight = -1;
|
||||||
nsRect childBounds;
|
nsRect childBounds;
|
||||||
|
|||||||
@@ -194,8 +194,11 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
|
|||||||
// Initialize OUT parameter
|
// Initialize OUT parameter
|
||||||
aChildBounds.SetRect(0, 0, 0, 0);
|
aChildBounds.SetRect(0, 0, 0, 0);
|
||||||
|
|
||||||
// Make a copy of the reflow state. If the reason is eReflowReason_Incremental,
|
// Make a copy of the reflow state. If the reason is
|
||||||
// then change it to eReflowReason_Resize
|
// eReflowReason_Incremental (which should mean either that the target
|
||||||
|
// is the frame for which this is the absolute container or that the
|
||||||
|
// container changed size due to incremental reflow of its children),
|
||||||
|
// then change it to eReflowReason_Resize.
|
||||||
nsHTMLReflowState reflowState(aReflowState);
|
nsHTMLReflowState reflowState(aReflowState);
|
||||||
if (eReflowReason_Incremental == reflowState.reason) {
|
if (eReflowReason_Incremental == reflowState.reason) {
|
||||||
reflowState.reason = eReflowReason_Resize;
|
reflowState.reason = eReflowReason_Resize;
|
||||||
|
|||||||
@@ -729,6 +729,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nsRect oldRect(mRect);
|
||||||
|
|
||||||
// Should we create a space manager?
|
// Should we create a space manager?
|
||||||
nsAutoSpaceManager autoSpaceManager(NS_CONST_CAST(nsHTMLReflowState &, aReflowState));
|
nsAutoSpaceManager autoSpaceManager(NS_CONST_CAST(nsHTMLReflowState &, aReflowState));
|
||||||
|
|
||||||
@@ -739,8 +741,10 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
if (NS_BLOCK_SPACE_MGR & mState)
|
if (NS_BLOCK_SPACE_MGR & mState)
|
||||||
autoSpaceManager.CreateSpaceManagerFor(aPresContext, this);
|
autoSpaceManager.CreateSpaceManagerFor(aPresContext, this);
|
||||||
|
|
||||||
// See if it's an incremental reflow command
|
// See if it's an incremental reflow command and we're not the target
|
||||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
if (mAbsoluteContainer.HasAbsoluteFrames() &&
|
||||||
|
eReflowReason_Incremental == aReflowState.reason &&
|
||||||
|
!aReflowState.path->mReflowCommand) {
|
||||||
// Give the absolute positioning code a chance to handle it
|
// Give the absolute positioning code a chance to handle it
|
||||||
nscoord containingBlockWidth;
|
nscoord containingBlockWidth;
|
||||||
nscoord containingBlockHeight;
|
nscoord containingBlockHeight;
|
||||||
@@ -1021,7 +1025,18 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
// Let the absolutely positioned container reflow any absolutely positioned
|
// Let the absolutely positioned container reflow any absolutely positioned
|
||||||
// child frames that need to be reflowed, e.g., elements with a percentage
|
// child frames that need to be reflowed, e.g., elements with a percentage
|
||||||
// based width/height
|
// based width/height
|
||||||
if (NS_SUCCEEDED(rv) && mAbsoluteContainer.HasAbsoluteFrames()) {
|
// We want to do this under either of two conditions:
|
||||||
|
// 1. If we didn't do the incremental reflow above.
|
||||||
|
// 2. If our size changed.
|
||||||
|
// Even though it's the padding edge that's the containing block, we
|
||||||
|
// can use our rect (the border edge) since if the border style
|
||||||
|
// changed, the reflow would have been targeted at us so we'd satisfy
|
||||||
|
// condition 1.
|
||||||
|
if (NS_SUCCEEDED(rv) &&
|
||||||
|
mAbsoluteContainer.HasAbsoluteFrames() &&
|
||||||
|
(eReflowReason_Incremental != aReflowState.reason ||
|
||||||
|
aReflowState.path->mReflowCommand ||
|
||||||
|
mRect != oldRect)) {
|
||||||
nscoord containingBlockWidth;
|
nscoord containingBlockWidth;
|
||||||
nscoord containingBlockHeight;
|
nscoord containingBlockHeight;
|
||||||
nsRect childBounds;
|
nsRect childBounds;
|
||||||
@@ -2168,7 +2183,8 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
|
|
||||||
// If we're supposed to update our maximum width, then we'll also need to
|
// If we're supposed to update our maximum width, then we'll also need to
|
||||||
// reflow this line if it's line wrapped and any of the continuing lines
|
// reflow this line if it's line wrapped and any of the continuing lines
|
||||||
// are dirty. If we are printing (constrained height), always reflow the line
|
// are dirty. If we are printing (constrained height), always reflow
|
||||||
|
// the line.
|
||||||
if ((NS_UNCONSTRAINEDSIZE != aState.mReflowState.availableHeight) ||
|
if ((NS_UNCONSTRAINEDSIZE != aState.mReflowState.availableHeight) ||
|
||||||
(!line->IsDirty() &&
|
(!line->IsDirty() &&
|
||||||
aState.GetFlag(BRS_COMPUTEMAXWIDTH) &&
|
aState.GetFlag(BRS_COMPUTEMAXWIDTH) &&
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "nsIFontMetrics.h"
|
#include "nsIFontMetrics.h"
|
||||||
#include "nsAbsoluteContainingBlock.h"
|
#include "nsAbsoluteContainingBlock.h"
|
||||||
#include "nsLayoutAtoms.h"
|
#include "nsLayoutAtoms.h"
|
||||||
|
#include "nsReflowPath.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#undef NOISY_PUSHING
|
#undef NOISY_PUSHING
|
||||||
@@ -1204,8 +1205,12 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
// See if it's an incremental reflow command
|
nsRect oldRect(mRect);
|
||||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
|
||||||
|
// See if it's an incremental reflow command and we're not the target
|
||||||
|
if (mAbsoluteContainer.HasAbsoluteFrames() &&
|
||||||
|
eReflowReason_Incremental == aReflowState.reason &&
|
||||||
|
!aReflowState.path->mReflowCommand) {
|
||||||
// Give the absolute positioning code a chance to handle it
|
// Give the absolute positioning code a chance to handle it
|
||||||
PRBool handled;
|
PRBool handled;
|
||||||
nsRect childBounds;
|
nsRect childBounds;
|
||||||
@@ -1252,7 +1257,18 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
// Let the absolutely positioned container reflow any absolutely positioned
|
// Let the absolutely positioned container reflow any absolutely positioned
|
||||||
// child frames that need to be reflowed
|
// child frames that need to be reflowed
|
||||||
if (NS_SUCCEEDED(rv)) {
|
// We want to do this under either of two conditions:
|
||||||
|
// 1. If we didn't do the incremental reflow above.
|
||||||
|
// 2. If our size changed.
|
||||||
|
// Even though it's the padding edge that's the containing block, we
|
||||||
|
// can use our rect (the border edge) since if the border style
|
||||||
|
// changed, the reflow would have been targeted at us so we'd satisfy
|
||||||
|
// condition 1.
|
||||||
|
if (NS_SUCCEEDED(rv) &&
|
||||||
|
mAbsoluteContainer.HasAbsoluteFrames() &&
|
||||||
|
(eReflowReason_Incremental != aReflowState.reason ||
|
||||||
|
aReflowState.path->mReflowCommand ||
|
||||||
|
mRect != oldRect)) {
|
||||||
nscoord containingBlockWidth = -1;
|
nscoord containingBlockWidth = -1;
|
||||||
nscoord containingBlockHeight = -1;
|
nscoord containingBlockHeight = -1;
|
||||||
nsRect childBounds;
|
nsRect childBounds;
|
||||||
|
|||||||
Reference in New Issue
Block a user