Bug 539356 - Make the table code use rect invalidation to avoid over invalidation. r=roc

This commit is contained in:
Matt Woodrow
2012-08-29 17:48:45 +12:00
parent 85b54a0096
commit 5e9c57eccd
16 changed files with 330 additions and 36 deletions

View File

@@ -28,6 +28,7 @@
#include "nsDisplayList.h"
#include "nsLayoutUtils.h"
#include "nsTextFrame.h"
#include "FrameLayerBuilder.h"
//TABLECELL SELECTION
#include "nsFrameSelection.h"
@@ -396,6 +397,21 @@ nsDisplayTableCellBackground::GetBounds(nsDisplayListBuilder* aBuilder,
return nsDisplayItem::GetBounds(aBuilder, aSnap);
}
void nsTableCellFrame::InvalidateFrame(uint32_t aDisplayItemKey)
{
nsIFrame::InvalidateFrame(aDisplayItemKey);
GetParent()->InvalidateFrameWithRect(GetVisualOverflowRect() + GetPosition(), aDisplayItemKey);
}
void nsTableCellFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey)
{
nsIFrame::InvalidateFrameWithRect(aRect, aDisplayItemKey);
// If we have filters applied that would affects our bounds, then
// we get an inactive layer created and this is computed
// within FrameLayerBuilder
GetParent()->InvalidateFrameWithRect(aRect + GetPosition(), aDisplayItemKey);
}
static void
PaintTableCellSelection(nsIFrame* aFrame, nsRenderingContext* aCtx,
const nsRect& aRect, nsPoint aPt)
@@ -561,6 +577,11 @@ void nsTableCellFrame::VerticallyAlignChild(nscoord aMaxAscent)
// if the content is larger than the cell height align from top
kidYTop = NS_MAX(0, kidYTop);
if (kidYTop != kidRect.y) {
// Invalidate at the old position first
firstKid->InvalidateFrameSubtree();
}
firstKid->SetPosition(nsPoint(kidRect.x, kidYTop));
nsHTMLReflowMetrics desiredSize;
desiredSize.width = mRect.width;
@@ -575,6 +596,9 @@ void nsTableCellFrame::VerticallyAlignChild(nscoord aMaxAscent)
// Make sure any child views are correctly positioned. We know the inner table
// cell won't have a view
nsContainerFrame::PositionChildViews(firstKid);
// Invalidate new overflow rect
firstKid->InvalidateFrameSubtree();
}
if (HasView()) {
nsContainerFrame::SyncFrameViewAfterReflow(PresContext(), this,
@@ -865,6 +889,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
}
nsPoint kidOrigin(leftInset, topInset);
nsRect origRect = firstKid->GetRect();
nsRect origVisualOverflow = firstKid->GetVisualOverflowRect();
bool firstReflow = (firstKid->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
kidOrigin.x, kidOrigin.y, NS_FRAME_INVALIDATE_ON_MOVE, aStatus);
@@ -875,6 +902,11 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
printf("Set table cell incomplete %p\n", static_cast<void*>(this));
}
// XXXbz is this invalidate actually needed, really?
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
InvalidateFrameSubtree();
}
#ifdef DEBUG
DebugCheckChildSize(firstKid, kidSize, availSize);
#endif
@@ -894,6 +926,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
FinishReflowChild(firstKid, aPresContext, &kidReflowState, kidSize,
kidOrigin.x, kidOrigin.y, 0);
nsTableFrame::InvalidateTableFrame(firstKid, origRect, origVisualOverflow,
firstReflow);
// first, compute the height which can be set w/o being restricted by aMaxSize.height
nscoord cellHeight = kidSize.height;
@@ -926,6 +961,13 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
}
}
// If our parent is in initial reflow, it'll handle invalidating our
// entire overflow rect.
if (!(GetParent()->GetStateBits() & NS_FRAME_FIRST_REFLOW) &&
nsSize(aDesiredSize.width, aDesiredSize.height) != mRect.Size()) {
InvalidateFrame();
}
// remember the desired size for this reflow
SetDesiredSize(aDesiredSize);