better table reflow debugging including support for elapsed time. sr=buster.
git-svn-id: svn://10.0.0.236/trunk@85493 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
ba0227a44d
commit
d95bd4f152
@ -213,6 +213,11 @@ struct nsHTMLReflowState {
|
||||
// is from the top of the frame tree.
|
||||
PRInt32 mReflowDepth;
|
||||
|
||||
#ifdef DEBUG
|
||||
// hook for attaching debug info (e.g. tables may attach a timer during reflow)
|
||||
void* mDebugHook;
|
||||
#endif
|
||||
|
||||
// Note: The copy constructor is written by the compiler
|
||||
// automatically. You can use that and then override specific values
|
||||
// if you want, or you can call Init as desired...
|
||||
|
||||
@ -174,6 +174,7 @@ nsHTMLReflowState::Init(nsIPresContext* aPresContext,
|
||||
mCompactMarginWidth = 0;
|
||||
mAlignCharOffset = 0;
|
||||
mUseAlignCharOffset = 0;
|
||||
mDebugHook = nsnull;
|
||||
|
||||
frame->GetStyleData(eStyleStruct_Position,
|
||||
(const nsStyleStruct*&)mStylePosition);
|
||||
|
||||
@ -213,6 +213,11 @@ struct nsHTMLReflowState {
|
||||
// is from the top of the frame tree.
|
||||
PRInt32 mReflowDepth;
|
||||
|
||||
#ifdef DEBUG
|
||||
// hook for attaching debug info (e.g. tables may attach a timer during reflow)
|
||||
void* mDebugHook;
|
||||
#endif
|
||||
|
||||
// Note: The copy constructor is written by the compiler
|
||||
// automatically. You can use that and then override specific values
|
||||
// if you want, or you can call Init as desired...
|
||||
|
||||
@ -174,6 +174,7 @@ nsHTMLReflowState::Init(nsIPresContext* aPresContext,
|
||||
mCompactMarginWidth = 0;
|
||||
mAlignCharOffset = 0;
|
||||
mUseAlignCharOffset = 0;
|
||||
mDebugHook = nsnull;
|
||||
|
||||
frame->GetStyleData(eStyleStruct_Position,
|
||||
(const nsStyleStruct*&)mStylePosition);
|
||||
|
||||
@ -24,7 +24,7 @@ DEPTH=..\..\..\..
|
||||
LIBRARY_NAME=raptorhtmltable_s
|
||||
MODULE=raptor
|
||||
|
||||
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
||||
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPPSRCS= nsCellMap.cpp \
|
||||
nsTableCellFrame.cpp \
|
||||
|
||||
@ -57,11 +57,18 @@ nsTableCellFrame::nsTableCellFrame()
|
||||
mColIndex = 0;
|
||||
mPriorAvailWidth = 0;
|
||||
mBorderEdges = nsnull;
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
mBlockTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsTableCellFrame::~nsTableCellFrame()
|
||||
{
|
||||
delete mBorderEdges;
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -688,7 +695,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableCellFrame", aReflowState.reason);
|
||||
if (nsDebugTable::gRflCell) nsTableFrame::DebugReflow("TC::Rfl", this, &aReflowState, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState);
|
||||
#endif
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
// this should probably be cached somewhere
|
||||
@ -797,13 +806,17 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
||||
firstKid->GetOrigin(kidOrigin);
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl en", firstKid, &kidReflowState, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(firstKid, (nsHTMLReflowState&)kidReflowState);
|
||||
#endif
|
||||
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
|
||||
kidOrigin.x, kidOrigin.y, 0, aStatus);
|
||||
if (isStyleChanged) {
|
||||
Invalidate(aPresContext, mRect);
|
||||
}
|
||||
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl ex", firstKid, nsnull, &kidSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(firstKid, (nsHTMLReflowState&)kidReflowState, &kidSize, aStatus);
|
||||
#endif
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
DebugCheckChildSize(firstKid, kidSize, availSize, (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth));
|
||||
@ -917,7 +930,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// remember my desired size for this reflow
|
||||
SetDesiredSize(aDesiredSize);
|
||||
|
||||
if (nsDebugTable::gRflCell) nsTableFrame::DebugReflow("TC::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -285,6 +285,10 @@ public:
|
||||
nsBorderEdges *mBorderEdges; // one list of border segments for each side of the table frame
|
||||
// used only for the collapsing border model
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsReflowTimer* mTimer;
|
||||
nsReflowTimer* mBlockTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline nsresult nsTableCellFrame::GetRowIndex(PRInt32 &aRowIndex) const
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
class nsTableColFrame;
|
||||
class nsTableFrame;
|
||||
|
||||
|
||||
enum nsTableColGroupType {
|
||||
eColGroupContent = 0, // there is real col group content associated
|
||||
eColGroupAnonymousCol = 1, // the result of a col
|
||||
@ -217,7 +218,6 @@ protected:
|
||||
unsigned int mType:4;
|
||||
unsigned int mUnused:28;
|
||||
} mBits;
|
||||
|
||||
};
|
||||
|
||||
inline nsTableColGroupFrame::nsTableColGroupFrame()
|
||||
|
||||
@ -68,22 +68,6 @@ static void GetPlaceholderFor(nsIPresContext& aPresContext, nsIFrame& aFrame, ns
|
||||
|
||||
static const PRInt32 kColumnWidthIncrement=10;
|
||||
|
||||
#if 1
|
||||
PRBool nsDebugTable::gRflTableOuter = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflTable = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflRowGrp = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflRow = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflCell = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflArea = PR_FALSE;
|
||||
#else
|
||||
PRBool nsDebugTable::gRflTableOuter = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflTable = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflRowGrp = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflRow = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflCell = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflArea = PR_TRUE;
|
||||
#endif
|
||||
static PRInt32 gRflCount = 0;
|
||||
|
||||
/* ----------- InnerTableReflowState ---------- */
|
||||
|
||||
@ -184,6 +168,9 @@ nsTableFrame::nsTableFrame()
|
||||
nsCRT::memset (mColumnWidths, 0, mColumnWidthsLength*sizeof(PRInt32));
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsTableFrame, nsHTMLContainerFrame)
|
||||
@ -259,6 +246,9 @@ nsTableFrame::~nsTableFrame()
|
||||
delete mTableLayoutStrategy;
|
||||
mTableLayoutStrategy = nsnull;
|
||||
}
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1640,8 +1630,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableFrame", aReflowState.reason);
|
||||
if (nsDebugTable::gRflTable) nsTableFrame::DebugReflow("T::Rfl en", this, &aReflowState, nsnull);
|
||||
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState);
|
||||
#endif
|
||||
|
||||
// Initialize out parameter
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = 0;
|
||||
@ -1804,7 +1796,9 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflTable) nsTableFrame::DebugReflow("T::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -4615,32 +4609,10 @@ PRInt32 nsTableFrame::GetNumCellsOriginatingInCol(PRInt32 aColIndex) const
|
||||
return cellMap->GetNumCellsOriginatingInCol(aColIndex);
|
||||
}
|
||||
|
||||
#define INDENT_PER_LEVEL 2
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
|
||||
void nsTableFrame::DebugGetIndent(const nsIFrame* aFrame,
|
||||
char* aBuf)
|
||||
{
|
||||
PRInt32 numLevels = 0;
|
||||
nsIFrame* parent = nsnull;
|
||||
aFrame->GetParent(&parent);
|
||||
while (parent) {
|
||||
nsIAtom* frameType = nsnull;
|
||||
parent->GetFrameType(&frameType);
|
||||
if ((nsDebugTable::gRflTableOuter && (nsLayoutAtoms::tableOuterFrame == frameType)) ||
|
||||
(nsDebugTable::gRflTable && (nsLayoutAtoms::tableFrame == frameType)) ||
|
||||
(nsDebugTable::gRflRowGrp && (nsLayoutAtoms::tableRowGroupFrame == frameType)) ||
|
||||
(nsDebugTable::gRflRow && (nsLayoutAtoms::tableRowFrame == frameType)) ||
|
||||
(nsDebugTable::gRflCell && (nsLayoutAtoms::tableCellFrame == frameType)) ||
|
||||
(nsDebugTable::gRflArea && (nsLayoutAtoms::areaFrame == frameType))) {
|
||||
numLevels++;
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
parent->GetParent(&parent);
|
||||
}
|
||||
PRInt32 indent = INDENT_PER_LEVEL * numLevels;
|
||||
nsCRT::memset (aBuf, ' ', indent);
|
||||
aBuf[indent] = 0;
|
||||
}
|
||||
static PRInt32 gRflCount = 0;
|
||||
#define INDENT_PER_LEVEL 1
|
||||
|
||||
void PrettyUC(nscoord aSize,
|
||||
char* aBuf)
|
||||
@ -4653,43 +4625,88 @@ void PrettyUC(nscoord aSize,
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableFrame::DebugReflow(char* aMessage,
|
||||
const nsIFrame* aFrame,
|
||||
const nsHTMLReflowState* aState,
|
||||
const nsHTMLReflowMetrics* aMetrics,
|
||||
const nsReflowStatus aStatus)
|
||||
void GetFrameTypeName(nsIAtom* aFrameType,
|
||||
char* aName)
|
||||
{
|
||||
if (nsLayoutAtoms::tableOuterFrame == aFrameType)
|
||||
strcpy(aName, "Tbl");
|
||||
else if (nsLayoutAtoms::tableFrame == aFrameType)
|
||||
strcpy(aName, "Tbl");
|
||||
else if (nsLayoutAtoms::tableRowGroupFrame == aFrameType)
|
||||
strcpy(aName, "RowG");
|
||||
else if (nsLayoutAtoms::tableRowFrame == aFrameType)
|
||||
strcpy(aName, "Row");
|
||||
else if (nsLayoutAtoms::tableCellFrame == aFrameType)
|
||||
strcpy(aName, "Cell");
|
||||
else if (nsLayoutAtoms::blockFrame == aFrameType)
|
||||
strcpy(aName, "Block");
|
||||
else
|
||||
NS_ASSERTION(PR_FALSE, "invalid call to GetFrameTypeName");
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW
|
||||
|
||||
void DebugGetIndent(const nsIFrame* aFrame,
|
||||
char* aBuf)
|
||||
{
|
||||
PRInt32 numLevels = 0;
|
||||
nsIFrame* parent = nsnull;
|
||||
aFrame->GetParent(&parent);
|
||||
while (parent) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
parent->GetFrameType(getter_AddRefs(frameType));
|
||||
if ((nsLayoutAtoms::tableOuterFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::tableFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::tableRowGroupFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::tableRowFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::tableCellFrame == frameType.get())) {
|
||||
numLevels++;
|
||||
}
|
||||
parent->GetParent(&parent);
|
||||
}
|
||||
PRInt32 indent = INDENT_PER_LEVEL * numLevels;
|
||||
nsCRT::memset (aBuf, ' ', indent);
|
||||
aBuf[indent] = 0;
|
||||
}
|
||||
|
||||
void nsTableFrame::DebugReflow(nsIFrame* aFrame,
|
||||
nsHTMLReflowState& aState,
|
||||
nsHTMLReflowMetrics* aMetrics,
|
||||
nsReflowStatus aStatus)
|
||||
{
|
||||
// get the frame type
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aFrame->GetFrameType(getter_AddRefs(fType));
|
||||
char fName[128];
|
||||
GetFrameTypeName(fType.get(), fName);
|
||||
|
||||
char indent[256];
|
||||
nsTableFrame::DebugGetIndent(aFrame, indent);
|
||||
printf("%s%s %p ", indent, aMessage, aFrame);
|
||||
char width[32];
|
||||
char height[32];
|
||||
if (aState) {
|
||||
PrettyUC(aState->availableWidth, width);
|
||||
PrettyUC(aState->availableHeight, height);
|
||||
printf("rea=%d av=(%s,%s) ", aState->reason, width, height);
|
||||
PrettyUC(aState->mComputedWidth, width);
|
||||
PrettyUC(aState->mComputedHeight, height);
|
||||
printf("comp=(%s,%s) count=%d \n ", width, height, gRflCount);
|
||||
DebugGetIndent(aFrame, indent);
|
||||
printf("%s%s %p ", indent, fName, aFrame);
|
||||
char width[16];
|
||||
char height[16];
|
||||
if (!aMetrics) { // start
|
||||
PrettyUC(aState.availableWidth, width);
|
||||
printf("r=%d a=%s ", aState.reason, width);
|
||||
PrettyUC(aState.mComputedWidth, width);
|
||||
PrettyUC(aState.mComputedHeight, height);
|
||||
printf("c=%s,%s cnt=%d \n", width, height, gRflCount);
|
||||
gRflCount++;
|
||||
//if (32 == gRflCount) {
|
||||
// NS_ASSERTION(PR_FALSE, "stop");
|
||||
//}
|
||||
}
|
||||
if (aMetrics) {
|
||||
if (aState) {
|
||||
printf("%s", indent);
|
||||
}
|
||||
if (aMetrics) { // stop
|
||||
PrettyUC(aMetrics->width, width);
|
||||
PrettyUC(aMetrics->height, height);
|
||||
printf("des=(%s,%s) ", width, height);
|
||||
printf("d=%s,%s ", width, height);
|
||||
if (aMetrics->maxElementSize) {
|
||||
PrettyUC(aMetrics->maxElementSize->width, width);
|
||||
PrettyUC(aMetrics->maxElementSize->height, height);
|
||||
printf("maxElem=(%s,%s)", width, height);
|
||||
printf("me=%s ", width);
|
||||
}
|
||||
if (aMetrics->mFlags & NS_REFLOW_CALC_MAX_WIDTH) {
|
||||
printf("max=%d ", aMetrics->mMaximumWidth);
|
||||
PrettyUC(aMetrics->mMaximumWidth, width);
|
||||
printf("m=%s ", width);
|
||||
}
|
||||
if (NS_FRAME_COMPLETE != aStatus) {
|
||||
printf("status=%d", aStatus);
|
||||
@ -4698,6 +4715,206 @@ void nsTableFrame::DebugReflow(char* aMessage,
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
nsReflowTimer* GetFrameTimer(nsIFrame* aFrame,
|
||||
nsIAtom* aFrameType)
|
||||
{
|
||||
if (nsLayoutAtoms::tableOuterFrame == aFrameType)
|
||||
return ((nsTableOuterFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::tableFrame == aFrameType)
|
||||
return ((nsTableFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::tableRowGroupFrame == aFrameType)
|
||||
return ((nsTableRowGroupFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::tableRowFrame == aFrameType)
|
||||
return ((nsTableRowFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::tableCellFrame == aFrameType)
|
||||
return ((nsTableCellFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::blockFrame == aFrameType) {
|
||||
nsIFrame* parentFrame;
|
||||
aFrame->GetParent(&parentFrame);
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
parentFrame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableCellFrame == fType) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)parentFrame;
|
||||
// fix up the block timer, which may be referring to the cell
|
||||
if (cellFrame->mBlockTimer->mFrame == parentFrame) {
|
||||
cellFrame->mBlockTimer->mFrame = aFrame;
|
||||
NS_IF_RELEASE(cellFrame->mBlockTimer->mFrameType);
|
||||
cellFrame->mBlockTimer->mFrameType = nsLayoutAtoms::blockFrame;
|
||||
NS_ADDREF(cellFrame->mBlockTimer->mFrameType);
|
||||
}
|
||||
return cellFrame->mBlockTimer;
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void DebugReflowPrint(nsReflowTimer& aTimer,
|
||||
PRUint32 aLevel,
|
||||
PRBool aSummary)
|
||||
{
|
||||
// set up the indentation
|
||||
char indentChar[128];
|
||||
PRInt32 indent = INDENT_PER_LEVEL * aLevel;
|
||||
nsCRT::memset (indentChar, ' ', indent);
|
||||
indentChar[indent] = 0;
|
||||
|
||||
// get the frame type
|
||||
char fName[128];
|
||||
GetFrameTypeName(aTimer.mFrameType, fName);
|
||||
|
||||
// print the timer
|
||||
printf("\n%s%s %dms %p", indentChar, fName, aTimer.Elapsed(), aTimer.mFrame);
|
||||
if (aSummary) {
|
||||
printf(" times=%d", aTimer.mNumStarts);
|
||||
}
|
||||
else {
|
||||
char avWidth[16];
|
||||
char compWidth[16];
|
||||
char compHeight[16];
|
||||
char desWidth[16];
|
||||
char desHeight[16];
|
||||
PrettyUC(aTimer.mAvailWidth, avWidth);
|
||||
PrettyUC(aTimer.mComputedWidth, compWidth);
|
||||
PrettyUC(aTimer.mComputedHeight, compHeight);
|
||||
PrettyUC(aTimer.mDesiredWidth, desWidth);
|
||||
PrettyUC(aTimer.mDesiredHeight, desHeight);
|
||||
printf(" r=%d a=%s c=%s,%s d=%s,%s", aTimer.mReason, avWidth, compWidth,
|
||||
compHeight, desWidth, desHeight);
|
||||
if (aTimer.mMaxElementWidth >= 0) {
|
||||
PrettyUC(aTimer.mMaxElementWidth, avWidth);
|
||||
printf(" me=%s", avWidth);
|
||||
}
|
||||
if (aTimer.mMaxWidth >= 0) {
|
||||
PrettyUC(aTimer.mMaxWidth, avWidth);
|
||||
printf(" m=%s", avWidth);
|
||||
}
|
||||
if (NS_FRAME_COMPLETE != aTimer.mStatus) {
|
||||
printf(" status=%d", aTimer.mStatus);
|
||||
}
|
||||
printf(" cnt=%d", aTimer.mCount);
|
||||
}
|
||||
// print the timer's children
|
||||
nsVoidArray& children = aTimer.mChildren;
|
||||
PRInt32 numChildren = children.Count();
|
||||
for (PRInt32 childX = 0; childX < numChildren; childX++) {
|
||||
nsReflowTimer* child = (nsReflowTimer*)children.ElementAt(childX);
|
||||
if (child) {
|
||||
DebugReflowPrint(*child, aLevel + 1, aSummary);
|
||||
}
|
||||
else NS_ASSERTION(PR_FALSE, "bad DebugTimeReflow");
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableFrame::DebugReflow(nsIFrame* aFrame,
|
||||
nsHTMLReflowState& aState,
|
||||
nsHTMLReflowMetrics* aMetrics,
|
||||
nsReflowStatus aStatus)
|
||||
{
|
||||
// get the parent timer
|
||||
const nsHTMLReflowState* parentRS = aState.parentReflowState;
|
||||
nsReflowTimer* parentTimer = nsnull;
|
||||
while (parentRS) {
|
||||
parentTimer = (nsReflowTimer *)parentRS->mDebugHook;
|
||||
if (parentTimer) break;
|
||||
parentRS = parentRS->parentReflowState;
|
||||
}
|
||||
// get the the frame summary timer
|
||||
nsCOMPtr<nsIAtom> frameType = nsnull;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
nsReflowTimer* frameTimer = GetFrameTimer(aFrame, frameType.get());
|
||||
if (!frameTimer) {
|
||||
NS_ASSERTION(PR_FALSE, "no frame timer");
|
||||
return;
|
||||
}
|
||||
if (!aMetrics) { // start
|
||||
// create the reflow timer
|
||||
nsReflowTimer* timer = new nsReflowTimer(aFrame);
|
||||
if (!timer) {
|
||||
NS_ASSERTION(PR_FALSE, "could not create timer");
|
||||
return;
|
||||
}
|
||||
timer->mReason = aState.reason;
|
||||
timer->mAvailWidth = aState.availableWidth;
|
||||
timer->mComputedWidth = aState.mComputedWidth;
|
||||
timer->mComputedHeight = aState.mComputedHeight;
|
||||
timer->mCount = gRflCount++;
|
||||
timer->Start();
|
||||
aState.mDebugHook = timer;
|
||||
if (parentTimer) {
|
||||
parentTimer->mChildren.AppendElement(timer);
|
||||
}
|
||||
// start the frame summary timer
|
||||
frameTimer->Start();
|
||||
}
|
||||
else {
|
||||
// stop the reflow timer
|
||||
nsReflowTimer* timer = (nsReflowTimer *)aState.mDebugHook;
|
||||
if (timer) {
|
||||
timer->Stop();
|
||||
timer->mDesiredWidth = aMetrics->width;
|
||||
timer->mDesiredHeight = aMetrics->height;
|
||||
timer->mMaxElementWidth = (aMetrics->maxElementSize)
|
||||
? aMetrics->maxElementSize->width : -1;
|
||||
timer->mMaxWidth = (aMetrics->mFlags & NS_REFLOW_CALC_MAX_WIDTH)
|
||||
? aMetrics->mMaximumWidth : -1;
|
||||
timer->mStatus = aStatus;
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(PR_FALSE, "bad DebugTimeReflow");
|
||||
return;
|
||||
}
|
||||
if (!parentTimer) {
|
||||
// print out all of the reflow timers
|
||||
DebugReflowPrint(*timer, 0, PR_FALSE);
|
||||
timer->Destroy();
|
||||
}
|
||||
// stop the frame summary timer
|
||||
frameTimer->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableFrame::DebugReflowDone(nsIFrame* aFrame)
|
||||
{
|
||||
// get the timer of aFrame
|
||||
nsCOMPtr<nsIAtom> frameType = nsnull;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
nsReflowTimer* thisTimer = GetFrameTimer(aFrame, frameType.get());
|
||||
|
||||
// get the nearest ancestor frame with a timer
|
||||
nsReflowTimer* ancestorTimer;
|
||||
nsIFrame* ancestorFrame;
|
||||
aFrame->GetParent(&ancestorFrame);
|
||||
while (ancestorFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType = nsnull;
|
||||
ancestorFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
ancestorTimer = GetFrameTimer(ancestorFrame, frameType.get());
|
||||
if (ancestorTimer) break;
|
||||
ancestorFrame->GetParent(&ancestorFrame);
|
||||
}
|
||||
if (ancestorTimer) { // add this timer to its parent
|
||||
ancestorTimer->mChildren.AppendElement(thisTimer);
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aFrame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableCellFrame == fType) {
|
||||
// add the cell block timer as a child of the cell timer
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aFrame;
|
||||
cellFrame->mTimer->mChildren.AppendElement(cellFrame->mBlockTimer);
|
||||
}
|
||||
}
|
||||
else { // print out all of the frame timers
|
||||
printf("\n\nSUMMARY OF REFLOW BY FRAME\n");
|
||||
DebugReflowPrint(*thisTimer, 0, PR_TRUE);
|
||||
thisTimer->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
PRBool nsTableFrame::RowHasSpanningCells(PRInt32 aRowIndex)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
@ -46,6 +46,87 @@ struct InnerTableReflowState;
|
||||
struct nsStylePosition;
|
||||
struct nsStyleSpacing;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
class nsReflowTimer
|
||||
{
|
||||
public:
|
||||
nsReflowTimer(nsIFrame* aFrame) {
|
||||
mFrame = aFrame;
|
||||
aFrame->GetFrameType(&mFrameType);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Destroy() {
|
||||
PRInt32 numChildren = mChildren.Count();
|
||||
for (PRInt32 childX = 0; childX < numChildren; childX++) {
|
||||
((nsReflowTimer*)mChildren.ElementAt(childX))->Destroy();
|
||||
}
|
||||
NS_IF_RELEASE(mFrameType);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void Print(PRUint32 aIndent,
|
||||
char* aHeader = 0) {
|
||||
if (aHeader) {
|
||||
printf("%s", aHeader);
|
||||
}
|
||||
printf(" elapsed=%d numStarts=%d \n", Elapsed(), mNumStarts);
|
||||
}
|
||||
|
||||
PRUint32 Elapsed() {
|
||||
return mTotalTime;
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
mTotalTime = mNumStarts = 0;
|
||||
mStarted = PR_FALSE;
|
||||
}
|
||||
|
||||
void Start() {
|
||||
NS_ASSERTION(!mStarted, "started timer without stopping");
|
||||
#ifdef WIN32
|
||||
mStartTime = GetTickCount();
|
||||
#else
|
||||
mStartTime = 0;
|
||||
#endif
|
||||
mStarted = PR_TRUE;
|
||||
mNumStarts++;
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
NS_ASSERTION(mStarted, "stopped timer without starting");
|
||||
mTotalTime += GetTickCount() - mStartTime;
|
||||
mStarted = PR_FALSE;
|
||||
}
|
||||
PRUint32 mTotalTime;
|
||||
PRUint32 mStartTime;
|
||||
PRUint32 mNumStarts;
|
||||
PRBool mStarted;
|
||||
const nsIFrame* mFrame;
|
||||
nsIAtom* mFrameType; // needed for frame summary timer
|
||||
nsReflowReason mReason;
|
||||
nsVoidArray mChildren;
|
||||
PRInt32 mCount;
|
||||
// reflow state/reflow metrics data
|
||||
nscoord mAvailWidth;
|
||||
nscoord mComputedWidth;
|
||||
nscoord mComputedHeight;
|
||||
nscoord mMaxElementWidth;
|
||||
nscoord mMaxWidth; // preferred width
|
||||
nscoord mDesiredWidth;
|
||||
nscoord mDesiredHeight;
|
||||
nsReflowStatus mStatus;
|
||||
|
||||
private:
|
||||
~nsReflowTimer() {}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Child list name indices
|
||||
* @see #GetAdditionalChildListName()
|
||||
@ -53,15 +134,6 @@ struct nsStyleSpacing;
|
||||
#define NS_TABLE_FRAME_COLGROUP_LIST_INDEX 0
|
||||
#define NS_TABLE_FRAME_LAST_LIST_INDEX NS_TABLE_FRAME_COLGROUP_LIST_INDEX
|
||||
|
||||
struct nsDebugTable
|
||||
{
|
||||
static PRBool gRflTableOuter;
|
||||
static PRBool gRflTable;
|
||||
static PRBool gRflRowGrp;
|
||||
static PRBool gRflRow;
|
||||
static PRBool gRflCell;
|
||||
static PRBool gRflArea;
|
||||
};
|
||||
/* ============================================================================ */
|
||||
|
||||
/** nsTableFrame maps the inner portion of a table (everything except captions.)
|
||||
@ -416,15 +488,6 @@ public:
|
||||
PRBool HasCellSpanningPctCol() const;
|
||||
void SetHasCellSpanningPctCol(PRBool aValue);
|
||||
|
||||
static void DebugReflow(char* aMessage,
|
||||
const nsIFrame* aFrame,
|
||||
const nsHTMLReflowState* aState,
|
||||
const nsHTMLReflowMetrics* aMetrics,
|
||||
const nsReflowStatus aStatus = NS_FRAME_COMPLETE);
|
||||
|
||||
static void DebugGetIndent(const nsIFrame* aFrame,
|
||||
char* aBuf);
|
||||
|
||||
protected:
|
||||
|
||||
/** protected constructor.
|
||||
@ -873,6 +936,19 @@ protected:
|
||||
// used only for the collapsing border model
|
||||
nscoord mPercentBasisForRows;
|
||||
nscoord mPreferredWidth;
|
||||
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
static void DebugReflow(nsIFrame* aFrame,
|
||||
nsHTMLReflowState& aReflowState,
|
||||
nsHTMLReflowMetrics* aMetrics = nsnull,
|
||||
nsReflowStatus aStatus = NS_FRAME_COMPLETE);
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
static void DebugReflowDone(nsIFrame* aFrame);
|
||||
|
||||
nsReflowTimer* mTimer;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -95,10 +95,16 @@ NS_IMPL_RELEASE_INHERITED(nsTableOuterFrame, nsHTMLContainerFrame)
|
||||
|
||||
nsTableOuterFrame::nsTableOuterFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsTableOuterFrame::~nsTableOuterFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult nsTableOuterFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
@ -1390,7 +1396,9 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableOuterFrame", aOuterRS.reason);
|
||||
if (nsDebugTable::gRflTableOuter) nsTableFrame::DebugReflow("TO::Rfl en", this, &aOuterRS, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aOuterRS);
|
||||
#endif
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
PRUint8 captionSide = GetCaptionSide();
|
||||
@ -1499,7 +1507,9 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflTableOuter) nsTableFrame::DebugReflow("TO::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aOuterRS, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,10 @@
|
||||
#include "nsBlockFrame.h"
|
||||
#include "nsITableLayout.h"
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
class nsReflowTimer;
|
||||
#endif
|
||||
|
||||
struct nsStyleTable;
|
||||
|
||||
class nsTableCaptionFrame : public nsBlockFrame
|
||||
@ -354,6 +358,11 @@ private:
|
||||
|
||||
nsSize mMaxElementSize;
|
||||
nscoord mInnerTableMaximumWidth;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
nsReflowTimer* mTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline nscoord nsTableOuterFrame::GetMinCaptionWidth()
|
||||
|
||||
@ -115,6 +115,16 @@ nsTableRowFrame::nsTableRowFrame()
|
||||
mBits.mMinRowSpan = 1;
|
||||
mBits.mRowIndex = 0;
|
||||
ResetTallestCell(0);
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsTableRowFrame::~nsTableRowFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1488,7 +1498,9 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableRowFrame", aReflowState.reason);
|
||||
if (nsDebugTable::gRflRow) nsTableFrame::DebugReflow("TR::Rfl en", this, &aReflowState, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState);
|
||||
#endif
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Initialize 'out' parameters (aStatus set below, undefined if rv returns an error)
|
||||
@ -1548,7 +1560,9 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
|
||||
mMaxElementSize = *aDesiredSize.maxElementSize;
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflRow) nsTableFrame::DebugReflow("TR::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,10 @@
|
||||
class nsTableFrame;
|
||||
class nsTableCellFrame;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
class nsReflowTimer;
|
||||
#endif
|
||||
|
||||
/* ----------- RowReflowState ---------- */
|
||||
|
||||
struct RowReflowState {
|
||||
@ -71,6 +75,8 @@ struct RowReflowState {
|
||||
class nsTableRowFrame : public nsHTMLContainerFrame
|
||||
{
|
||||
public:
|
||||
virtual ~nsTableRowFrame();
|
||||
|
||||
NS_IMETHOD Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
@ -321,6 +327,11 @@ private:
|
||||
// max-ascent and max-descent amongst all cells that have 'vertical-align: baseline'
|
||||
nscoord mMaxCellAscent; // does include cells with rowspan > 1
|
||||
nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
nsReflowTimer* mTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline PRInt32 nsTableRowFrame::GetRowIndex() const
|
||||
|
||||
@ -42,6 +42,20 @@
|
||||
|
||||
#include "nsCellMap.h"//table cell navigation
|
||||
|
||||
nsTableRowGroupFrame::nsTableRowGroupFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsTableRowGroupFrame::~nsTableRowGroupFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ----------- nsTableRowGroupFrame ---------- */
|
||||
nsrefcnt nsTableRowGroupFrame::AddRef(void)
|
||||
{
|
||||
@ -1055,7 +1069,9 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableRowGroupFrame", aReflowState.reason);
|
||||
if (nsDebugTable::gRflRowGrp) nsTableFrame::DebugReflow("TRG::Rfl", this, &aReflowState, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState);
|
||||
#endif
|
||||
nsresult rv=NS_OK;
|
||||
|
||||
// Initialize out parameter
|
||||
@ -1163,7 +1179,9 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
|
||||
mMaxElementSize = *aDesiredSize.maxElementSize;
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflRowGrp) nsTableFrame::DebugReflow("TRG::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
class nsTableFrame;
|
||||
class nsTableRowFrame;
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
class nsReflowTimer;
|
||||
#endif
|
||||
|
||||
/* ----------- RowGroupReflowState ---------- */
|
||||
|
||||
@ -103,6 +106,7 @@ public:
|
||||
*/
|
||||
friend nsresult
|
||||
NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
virtual ~nsTableRowGroupFrame();
|
||||
|
||||
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
@ -223,6 +227,7 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
nsTableRowGroupFrame();
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
@ -341,6 +346,10 @@ public:
|
||||
private:
|
||||
nsSize mMaxElementSize;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
nsReflowTimer* mTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline void nsTableRowGroupFrame::GetMaxElementSize(nsSize& aMaxElementSize) const
|
||||
|
||||
@ -57,11 +57,18 @@ nsTableCellFrame::nsTableCellFrame()
|
||||
mColIndex = 0;
|
||||
mPriorAvailWidth = 0;
|
||||
mBorderEdges = nsnull;
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
mBlockTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsTableCellFrame::~nsTableCellFrame()
|
||||
{
|
||||
delete mBorderEdges;
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -688,7 +695,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableCellFrame", aReflowState.reason);
|
||||
if (nsDebugTable::gRflCell) nsTableFrame::DebugReflow("TC::Rfl", this, &aReflowState, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState);
|
||||
#endif
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
// this should probably be cached somewhere
|
||||
@ -797,13 +806,17 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
||||
firstKid->GetOrigin(kidOrigin);
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl en", firstKid, &kidReflowState, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(firstKid, (nsHTMLReflowState&)kidReflowState);
|
||||
#endif
|
||||
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
|
||||
kidOrigin.x, kidOrigin.y, 0, aStatus);
|
||||
if (isStyleChanged) {
|
||||
Invalidate(aPresContext, mRect);
|
||||
}
|
||||
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl ex", firstKid, nsnull, &kidSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(firstKid, (nsHTMLReflowState&)kidReflowState, &kidSize, aStatus);
|
||||
#endif
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
DebugCheckChildSize(firstKid, kidSize, availSize, (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth));
|
||||
@ -917,7 +930,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// remember my desired size for this reflow
|
||||
SetDesiredSize(aDesiredSize);
|
||||
|
||||
if (nsDebugTable::gRflCell) nsTableFrame::DebugReflow("TC::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -285,6 +285,10 @@ public:
|
||||
nsBorderEdges *mBorderEdges; // one list of border segments for each side of the table frame
|
||||
// used only for the collapsing border model
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsReflowTimer* mTimer;
|
||||
nsReflowTimer* mBlockTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline nsresult nsTableCellFrame::GetRowIndex(PRInt32 &aRowIndex) const
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
class nsTableColFrame;
|
||||
class nsTableFrame;
|
||||
|
||||
|
||||
enum nsTableColGroupType {
|
||||
eColGroupContent = 0, // there is real col group content associated
|
||||
eColGroupAnonymousCol = 1, // the result of a col
|
||||
@ -217,7 +218,6 @@ protected:
|
||||
unsigned int mType:4;
|
||||
unsigned int mUnused:28;
|
||||
} mBits;
|
||||
|
||||
};
|
||||
|
||||
inline nsTableColGroupFrame::nsTableColGroupFrame()
|
||||
|
||||
@ -68,22 +68,6 @@ static void GetPlaceholderFor(nsIPresContext& aPresContext, nsIFrame& aFrame, ns
|
||||
|
||||
static const PRInt32 kColumnWidthIncrement=10;
|
||||
|
||||
#if 1
|
||||
PRBool nsDebugTable::gRflTableOuter = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflTable = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflRowGrp = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflRow = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflCell = PR_FALSE;
|
||||
PRBool nsDebugTable::gRflArea = PR_FALSE;
|
||||
#else
|
||||
PRBool nsDebugTable::gRflTableOuter = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflTable = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflRowGrp = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflRow = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflCell = PR_TRUE;
|
||||
PRBool nsDebugTable::gRflArea = PR_TRUE;
|
||||
#endif
|
||||
static PRInt32 gRflCount = 0;
|
||||
|
||||
/* ----------- InnerTableReflowState ---------- */
|
||||
|
||||
@ -184,6 +168,9 @@ nsTableFrame::nsTableFrame()
|
||||
nsCRT::memset (mColumnWidths, 0, mColumnWidthsLength*sizeof(PRInt32));
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsTableFrame, nsHTMLContainerFrame)
|
||||
@ -259,6 +246,9 @@ nsTableFrame::~nsTableFrame()
|
||||
delete mTableLayoutStrategy;
|
||||
mTableLayoutStrategy = nsnull;
|
||||
}
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1640,8 +1630,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableFrame", aReflowState.reason);
|
||||
if (nsDebugTable::gRflTable) nsTableFrame::DebugReflow("T::Rfl en", this, &aReflowState, nsnull);
|
||||
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState);
|
||||
#endif
|
||||
|
||||
// Initialize out parameter
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = 0;
|
||||
@ -1804,7 +1796,9 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflTable) nsTableFrame::DebugReflow("T::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -4615,32 +4609,10 @@ PRInt32 nsTableFrame::GetNumCellsOriginatingInCol(PRInt32 aColIndex) const
|
||||
return cellMap->GetNumCellsOriginatingInCol(aColIndex);
|
||||
}
|
||||
|
||||
#define INDENT_PER_LEVEL 2
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
|
||||
void nsTableFrame::DebugGetIndent(const nsIFrame* aFrame,
|
||||
char* aBuf)
|
||||
{
|
||||
PRInt32 numLevels = 0;
|
||||
nsIFrame* parent = nsnull;
|
||||
aFrame->GetParent(&parent);
|
||||
while (parent) {
|
||||
nsIAtom* frameType = nsnull;
|
||||
parent->GetFrameType(&frameType);
|
||||
if ((nsDebugTable::gRflTableOuter && (nsLayoutAtoms::tableOuterFrame == frameType)) ||
|
||||
(nsDebugTable::gRflTable && (nsLayoutAtoms::tableFrame == frameType)) ||
|
||||
(nsDebugTable::gRflRowGrp && (nsLayoutAtoms::tableRowGroupFrame == frameType)) ||
|
||||
(nsDebugTable::gRflRow && (nsLayoutAtoms::tableRowFrame == frameType)) ||
|
||||
(nsDebugTable::gRflCell && (nsLayoutAtoms::tableCellFrame == frameType)) ||
|
||||
(nsDebugTable::gRflArea && (nsLayoutAtoms::areaFrame == frameType))) {
|
||||
numLevels++;
|
||||
}
|
||||
NS_IF_RELEASE(frameType);
|
||||
parent->GetParent(&parent);
|
||||
}
|
||||
PRInt32 indent = INDENT_PER_LEVEL * numLevels;
|
||||
nsCRT::memset (aBuf, ' ', indent);
|
||||
aBuf[indent] = 0;
|
||||
}
|
||||
static PRInt32 gRflCount = 0;
|
||||
#define INDENT_PER_LEVEL 1
|
||||
|
||||
void PrettyUC(nscoord aSize,
|
||||
char* aBuf)
|
||||
@ -4653,43 +4625,88 @@ void PrettyUC(nscoord aSize,
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableFrame::DebugReflow(char* aMessage,
|
||||
const nsIFrame* aFrame,
|
||||
const nsHTMLReflowState* aState,
|
||||
const nsHTMLReflowMetrics* aMetrics,
|
||||
const nsReflowStatus aStatus)
|
||||
void GetFrameTypeName(nsIAtom* aFrameType,
|
||||
char* aName)
|
||||
{
|
||||
if (nsLayoutAtoms::tableOuterFrame == aFrameType)
|
||||
strcpy(aName, "Tbl");
|
||||
else if (nsLayoutAtoms::tableFrame == aFrameType)
|
||||
strcpy(aName, "Tbl");
|
||||
else if (nsLayoutAtoms::tableRowGroupFrame == aFrameType)
|
||||
strcpy(aName, "RowG");
|
||||
else if (nsLayoutAtoms::tableRowFrame == aFrameType)
|
||||
strcpy(aName, "Row");
|
||||
else if (nsLayoutAtoms::tableCellFrame == aFrameType)
|
||||
strcpy(aName, "Cell");
|
||||
else if (nsLayoutAtoms::blockFrame == aFrameType)
|
||||
strcpy(aName, "Block");
|
||||
else
|
||||
NS_ASSERTION(PR_FALSE, "invalid call to GetFrameTypeName");
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW
|
||||
|
||||
void DebugGetIndent(const nsIFrame* aFrame,
|
||||
char* aBuf)
|
||||
{
|
||||
PRInt32 numLevels = 0;
|
||||
nsIFrame* parent = nsnull;
|
||||
aFrame->GetParent(&parent);
|
||||
while (parent) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
parent->GetFrameType(getter_AddRefs(frameType));
|
||||
if ((nsLayoutAtoms::tableOuterFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::tableFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::tableRowGroupFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::tableRowFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::tableCellFrame == frameType.get())) {
|
||||
numLevels++;
|
||||
}
|
||||
parent->GetParent(&parent);
|
||||
}
|
||||
PRInt32 indent = INDENT_PER_LEVEL * numLevels;
|
||||
nsCRT::memset (aBuf, ' ', indent);
|
||||
aBuf[indent] = 0;
|
||||
}
|
||||
|
||||
void nsTableFrame::DebugReflow(nsIFrame* aFrame,
|
||||
nsHTMLReflowState& aState,
|
||||
nsHTMLReflowMetrics* aMetrics,
|
||||
nsReflowStatus aStatus)
|
||||
{
|
||||
// get the frame type
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aFrame->GetFrameType(getter_AddRefs(fType));
|
||||
char fName[128];
|
||||
GetFrameTypeName(fType.get(), fName);
|
||||
|
||||
char indent[256];
|
||||
nsTableFrame::DebugGetIndent(aFrame, indent);
|
||||
printf("%s%s %p ", indent, aMessage, aFrame);
|
||||
char width[32];
|
||||
char height[32];
|
||||
if (aState) {
|
||||
PrettyUC(aState->availableWidth, width);
|
||||
PrettyUC(aState->availableHeight, height);
|
||||
printf("rea=%d av=(%s,%s) ", aState->reason, width, height);
|
||||
PrettyUC(aState->mComputedWidth, width);
|
||||
PrettyUC(aState->mComputedHeight, height);
|
||||
printf("comp=(%s,%s) count=%d \n ", width, height, gRflCount);
|
||||
DebugGetIndent(aFrame, indent);
|
||||
printf("%s%s %p ", indent, fName, aFrame);
|
||||
char width[16];
|
||||
char height[16];
|
||||
if (!aMetrics) { // start
|
||||
PrettyUC(aState.availableWidth, width);
|
||||
printf("r=%d a=%s ", aState.reason, width);
|
||||
PrettyUC(aState.mComputedWidth, width);
|
||||
PrettyUC(aState.mComputedHeight, height);
|
||||
printf("c=%s,%s cnt=%d \n", width, height, gRflCount);
|
||||
gRflCount++;
|
||||
//if (32 == gRflCount) {
|
||||
// NS_ASSERTION(PR_FALSE, "stop");
|
||||
//}
|
||||
}
|
||||
if (aMetrics) {
|
||||
if (aState) {
|
||||
printf("%s", indent);
|
||||
}
|
||||
if (aMetrics) { // stop
|
||||
PrettyUC(aMetrics->width, width);
|
||||
PrettyUC(aMetrics->height, height);
|
||||
printf("des=(%s,%s) ", width, height);
|
||||
printf("d=%s,%s ", width, height);
|
||||
if (aMetrics->maxElementSize) {
|
||||
PrettyUC(aMetrics->maxElementSize->width, width);
|
||||
PrettyUC(aMetrics->maxElementSize->height, height);
|
||||
printf("maxElem=(%s,%s)", width, height);
|
||||
printf("me=%s ", width);
|
||||
}
|
||||
if (aMetrics->mFlags & NS_REFLOW_CALC_MAX_WIDTH) {
|
||||
printf("max=%d ", aMetrics->mMaximumWidth);
|
||||
PrettyUC(aMetrics->mMaximumWidth, width);
|
||||
printf("m=%s ", width);
|
||||
}
|
||||
if (NS_FRAME_COMPLETE != aStatus) {
|
||||
printf("status=%d", aStatus);
|
||||
@ -4698,6 +4715,206 @@ void nsTableFrame::DebugReflow(char* aMessage,
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
nsReflowTimer* GetFrameTimer(nsIFrame* aFrame,
|
||||
nsIAtom* aFrameType)
|
||||
{
|
||||
if (nsLayoutAtoms::tableOuterFrame == aFrameType)
|
||||
return ((nsTableOuterFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::tableFrame == aFrameType)
|
||||
return ((nsTableFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::tableRowGroupFrame == aFrameType)
|
||||
return ((nsTableRowGroupFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::tableRowFrame == aFrameType)
|
||||
return ((nsTableRowFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::tableCellFrame == aFrameType)
|
||||
return ((nsTableCellFrame*)aFrame)->mTimer;
|
||||
else if (nsLayoutAtoms::blockFrame == aFrameType) {
|
||||
nsIFrame* parentFrame;
|
||||
aFrame->GetParent(&parentFrame);
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
parentFrame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableCellFrame == fType) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)parentFrame;
|
||||
// fix up the block timer, which may be referring to the cell
|
||||
if (cellFrame->mBlockTimer->mFrame == parentFrame) {
|
||||
cellFrame->mBlockTimer->mFrame = aFrame;
|
||||
NS_IF_RELEASE(cellFrame->mBlockTimer->mFrameType);
|
||||
cellFrame->mBlockTimer->mFrameType = nsLayoutAtoms::blockFrame;
|
||||
NS_ADDREF(cellFrame->mBlockTimer->mFrameType);
|
||||
}
|
||||
return cellFrame->mBlockTimer;
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void DebugReflowPrint(nsReflowTimer& aTimer,
|
||||
PRUint32 aLevel,
|
||||
PRBool aSummary)
|
||||
{
|
||||
// set up the indentation
|
||||
char indentChar[128];
|
||||
PRInt32 indent = INDENT_PER_LEVEL * aLevel;
|
||||
nsCRT::memset (indentChar, ' ', indent);
|
||||
indentChar[indent] = 0;
|
||||
|
||||
// get the frame type
|
||||
char fName[128];
|
||||
GetFrameTypeName(aTimer.mFrameType, fName);
|
||||
|
||||
// print the timer
|
||||
printf("\n%s%s %dms %p", indentChar, fName, aTimer.Elapsed(), aTimer.mFrame);
|
||||
if (aSummary) {
|
||||
printf(" times=%d", aTimer.mNumStarts);
|
||||
}
|
||||
else {
|
||||
char avWidth[16];
|
||||
char compWidth[16];
|
||||
char compHeight[16];
|
||||
char desWidth[16];
|
||||
char desHeight[16];
|
||||
PrettyUC(aTimer.mAvailWidth, avWidth);
|
||||
PrettyUC(aTimer.mComputedWidth, compWidth);
|
||||
PrettyUC(aTimer.mComputedHeight, compHeight);
|
||||
PrettyUC(aTimer.mDesiredWidth, desWidth);
|
||||
PrettyUC(aTimer.mDesiredHeight, desHeight);
|
||||
printf(" r=%d a=%s c=%s,%s d=%s,%s", aTimer.mReason, avWidth, compWidth,
|
||||
compHeight, desWidth, desHeight);
|
||||
if (aTimer.mMaxElementWidth >= 0) {
|
||||
PrettyUC(aTimer.mMaxElementWidth, avWidth);
|
||||
printf(" me=%s", avWidth);
|
||||
}
|
||||
if (aTimer.mMaxWidth >= 0) {
|
||||
PrettyUC(aTimer.mMaxWidth, avWidth);
|
||||
printf(" m=%s", avWidth);
|
||||
}
|
||||
if (NS_FRAME_COMPLETE != aTimer.mStatus) {
|
||||
printf(" status=%d", aTimer.mStatus);
|
||||
}
|
||||
printf(" cnt=%d", aTimer.mCount);
|
||||
}
|
||||
// print the timer's children
|
||||
nsVoidArray& children = aTimer.mChildren;
|
||||
PRInt32 numChildren = children.Count();
|
||||
for (PRInt32 childX = 0; childX < numChildren; childX++) {
|
||||
nsReflowTimer* child = (nsReflowTimer*)children.ElementAt(childX);
|
||||
if (child) {
|
||||
DebugReflowPrint(*child, aLevel + 1, aSummary);
|
||||
}
|
||||
else NS_ASSERTION(PR_FALSE, "bad DebugTimeReflow");
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableFrame::DebugReflow(nsIFrame* aFrame,
|
||||
nsHTMLReflowState& aState,
|
||||
nsHTMLReflowMetrics* aMetrics,
|
||||
nsReflowStatus aStatus)
|
||||
{
|
||||
// get the parent timer
|
||||
const nsHTMLReflowState* parentRS = aState.parentReflowState;
|
||||
nsReflowTimer* parentTimer = nsnull;
|
||||
while (parentRS) {
|
||||
parentTimer = (nsReflowTimer *)parentRS->mDebugHook;
|
||||
if (parentTimer) break;
|
||||
parentRS = parentRS->parentReflowState;
|
||||
}
|
||||
// get the the frame summary timer
|
||||
nsCOMPtr<nsIAtom> frameType = nsnull;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
nsReflowTimer* frameTimer = GetFrameTimer(aFrame, frameType.get());
|
||||
if (!frameTimer) {
|
||||
NS_ASSERTION(PR_FALSE, "no frame timer");
|
||||
return;
|
||||
}
|
||||
if (!aMetrics) { // start
|
||||
// create the reflow timer
|
||||
nsReflowTimer* timer = new nsReflowTimer(aFrame);
|
||||
if (!timer) {
|
||||
NS_ASSERTION(PR_FALSE, "could not create timer");
|
||||
return;
|
||||
}
|
||||
timer->mReason = aState.reason;
|
||||
timer->mAvailWidth = aState.availableWidth;
|
||||
timer->mComputedWidth = aState.mComputedWidth;
|
||||
timer->mComputedHeight = aState.mComputedHeight;
|
||||
timer->mCount = gRflCount++;
|
||||
timer->Start();
|
||||
aState.mDebugHook = timer;
|
||||
if (parentTimer) {
|
||||
parentTimer->mChildren.AppendElement(timer);
|
||||
}
|
||||
// start the frame summary timer
|
||||
frameTimer->Start();
|
||||
}
|
||||
else {
|
||||
// stop the reflow timer
|
||||
nsReflowTimer* timer = (nsReflowTimer *)aState.mDebugHook;
|
||||
if (timer) {
|
||||
timer->Stop();
|
||||
timer->mDesiredWidth = aMetrics->width;
|
||||
timer->mDesiredHeight = aMetrics->height;
|
||||
timer->mMaxElementWidth = (aMetrics->maxElementSize)
|
||||
? aMetrics->maxElementSize->width : -1;
|
||||
timer->mMaxWidth = (aMetrics->mFlags & NS_REFLOW_CALC_MAX_WIDTH)
|
||||
? aMetrics->mMaximumWidth : -1;
|
||||
timer->mStatus = aStatus;
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(PR_FALSE, "bad DebugTimeReflow");
|
||||
return;
|
||||
}
|
||||
if (!parentTimer) {
|
||||
// print out all of the reflow timers
|
||||
DebugReflowPrint(*timer, 0, PR_FALSE);
|
||||
timer->Destroy();
|
||||
}
|
||||
// stop the frame summary timer
|
||||
frameTimer->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void nsTableFrame::DebugReflowDone(nsIFrame* aFrame)
|
||||
{
|
||||
// get the timer of aFrame
|
||||
nsCOMPtr<nsIAtom> frameType = nsnull;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
nsReflowTimer* thisTimer = GetFrameTimer(aFrame, frameType.get());
|
||||
|
||||
// get the nearest ancestor frame with a timer
|
||||
nsReflowTimer* ancestorTimer;
|
||||
nsIFrame* ancestorFrame;
|
||||
aFrame->GetParent(&ancestorFrame);
|
||||
while (ancestorFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType = nsnull;
|
||||
ancestorFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
ancestorTimer = GetFrameTimer(ancestorFrame, frameType.get());
|
||||
if (ancestorTimer) break;
|
||||
ancestorFrame->GetParent(&ancestorFrame);
|
||||
}
|
||||
if (ancestorTimer) { // add this timer to its parent
|
||||
ancestorTimer->mChildren.AppendElement(thisTimer);
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aFrame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableCellFrame == fType) {
|
||||
// add the cell block timer as a child of the cell timer
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aFrame;
|
||||
cellFrame->mTimer->mChildren.AppendElement(cellFrame->mBlockTimer);
|
||||
}
|
||||
}
|
||||
else { // print out all of the frame timers
|
||||
printf("\n\nSUMMARY OF REFLOW BY FRAME\n");
|
||||
DebugReflowPrint(*thisTimer, 0, PR_TRUE);
|
||||
thisTimer->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
PRBool nsTableFrame::RowHasSpanningCells(PRInt32 aRowIndex)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
@ -46,6 +46,87 @@ struct InnerTableReflowState;
|
||||
struct nsStylePosition;
|
||||
struct nsStyleSpacing;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
class nsReflowTimer
|
||||
{
|
||||
public:
|
||||
nsReflowTimer(nsIFrame* aFrame) {
|
||||
mFrame = aFrame;
|
||||
aFrame->GetFrameType(&mFrameType);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Destroy() {
|
||||
PRInt32 numChildren = mChildren.Count();
|
||||
for (PRInt32 childX = 0; childX < numChildren; childX++) {
|
||||
((nsReflowTimer*)mChildren.ElementAt(childX))->Destroy();
|
||||
}
|
||||
NS_IF_RELEASE(mFrameType);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void Print(PRUint32 aIndent,
|
||||
char* aHeader = 0) {
|
||||
if (aHeader) {
|
||||
printf("%s", aHeader);
|
||||
}
|
||||
printf(" elapsed=%d numStarts=%d \n", Elapsed(), mNumStarts);
|
||||
}
|
||||
|
||||
PRUint32 Elapsed() {
|
||||
return mTotalTime;
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
mTotalTime = mNumStarts = 0;
|
||||
mStarted = PR_FALSE;
|
||||
}
|
||||
|
||||
void Start() {
|
||||
NS_ASSERTION(!mStarted, "started timer without stopping");
|
||||
#ifdef WIN32
|
||||
mStartTime = GetTickCount();
|
||||
#else
|
||||
mStartTime = 0;
|
||||
#endif
|
||||
mStarted = PR_TRUE;
|
||||
mNumStarts++;
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
NS_ASSERTION(mStarted, "stopped timer without starting");
|
||||
mTotalTime += GetTickCount() - mStartTime;
|
||||
mStarted = PR_FALSE;
|
||||
}
|
||||
PRUint32 mTotalTime;
|
||||
PRUint32 mStartTime;
|
||||
PRUint32 mNumStarts;
|
||||
PRBool mStarted;
|
||||
const nsIFrame* mFrame;
|
||||
nsIAtom* mFrameType; // needed for frame summary timer
|
||||
nsReflowReason mReason;
|
||||
nsVoidArray mChildren;
|
||||
PRInt32 mCount;
|
||||
// reflow state/reflow metrics data
|
||||
nscoord mAvailWidth;
|
||||
nscoord mComputedWidth;
|
||||
nscoord mComputedHeight;
|
||||
nscoord mMaxElementWidth;
|
||||
nscoord mMaxWidth; // preferred width
|
||||
nscoord mDesiredWidth;
|
||||
nscoord mDesiredHeight;
|
||||
nsReflowStatus mStatus;
|
||||
|
||||
private:
|
||||
~nsReflowTimer() {}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Child list name indices
|
||||
* @see #GetAdditionalChildListName()
|
||||
@ -53,15 +134,6 @@ struct nsStyleSpacing;
|
||||
#define NS_TABLE_FRAME_COLGROUP_LIST_INDEX 0
|
||||
#define NS_TABLE_FRAME_LAST_LIST_INDEX NS_TABLE_FRAME_COLGROUP_LIST_INDEX
|
||||
|
||||
struct nsDebugTable
|
||||
{
|
||||
static PRBool gRflTableOuter;
|
||||
static PRBool gRflTable;
|
||||
static PRBool gRflRowGrp;
|
||||
static PRBool gRflRow;
|
||||
static PRBool gRflCell;
|
||||
static PRBool gRflArea;
|
||||
};
|
||||
/* ============================================================================ */
|
||||
|
||||
/** nsTableFrame maps the inner portion of a table (everything except captions.)
|
||||
@ -416,15 +488,6 @@ public:
|
||||
PRBool HasCellSpanningPctCol() const;
|
||||
void SetHasCellSpanningPctCol(PRBool aValue);
|
||||
|
||||
static void DebugReflow(char* aMessage,
|
||||
const nsIFrame* aFrame,
|
||||
const nsHTMLReflowState* aState,
|
||||
const nsHTMLReflowMetrics* aMetrics,
|
||||
const nsReflowStatus aStatus = NS_FRAME_COMPLETE);
|
||||
|
||||
static void DebugGetIndent(const nsIFrame* aFrame,
|
||||
char* aBuf);
|
||||
|
||||
protected:
|
||||
|
||||
/** protected constructor.
|
||||
@ -873,6 +936,19 @@ protected:
|
||||
// used only for the collapsing border model
|
||||
nscoord mPercentBasisForRows;
|
||||
nscoord mPreferredWidth;
|
||||
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
static void DebugReflow(nsIFrame* aFrame,
|
||||
nsHTMLReflowState& aReflowState,
|
||||
nsHTMLReflowMetrics* aMetrics = nsnull,
|
||||
nsReflowStatus aStatus = NS_FRAME_COMPLETE);
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
static void DebugReflowDone(nsIFrame* aFrame);
|
||||
|
||||
nsReflowTimer* mTimer;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -95,10 +95,16 @@ NS_IMPL_RELEASE_INHERITED(nsTableOuterFrame, nsHTMLContainerFrame)
|
||||
|
||||
nsTableOuterFrame::nsTableOuterFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsTableOuterFrame::~nsTableOuterFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult nsTableOuterFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
@ -1390,7 +1396,9 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableOuterFrame", aOuterRS.reason);
|
||||
if (nsDebugTable::gRflTableOuter) nsTableFrame::DebugReflow("TO::Rfl en", this, &aOuterRS, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aOuterRS);
|
||||
#endif
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
PRUint8 captionSide = GetCaptionSide();
|
||||
@ -1499,7 +1507,9 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflTableOuter) nsTableFrame::DebugReflow("TO::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aOuterRS, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,10 @@
|
||||
#include "nsBlockFrame.h"
|
||||
#include "nsITableLayout.h"
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
class nsReflowTimer;
|
||||
#endif
|
||||
|
||||
struct nsStyleTable;
|
||||
|
||||
class nsTableCaptionFrame : public nsBlockFrame
|
||||
@ -354,6 +358,11 @@ private:
|
||||
|
||||
nsSize mMaxElementSize;
|
||||
nscoord mInnerTableMaximumWidth;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
nsReflowTimer* mTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline nscoord nsTableOuterFrame::GetMinCaptionWidth()
|
||||
|
||||
@ -115,6 +115,16 @@ nsTableRowFrame::nsTableRowFrame()
|
||||
mBits.mMinRowSpan = 1;
|
||||
mBits.mRowIndex = 0;
|
||||
ResetTallestCell(0);
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsTableRowFrame::~nsTableRowFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1488,7 +1498,9 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableRowFrame", aReflowState.reason);
|
||||
if (nsDebugTable::gRflRow) nsTableFrame::DebugReflow("TR::Rfl en", this, &aReflowState, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState);
|
||||
#endif
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Initialize 'out' parameters (aStatus set below, undefined if rv returns an error)
|
||||
@ -1548,7 +1560,9 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
|
||||
mMaxElementSize = *aDesiredSize.maxElementSize;
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflRow) nsTableFrame::DebugReflow("TR::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,10 @@
|
||||
class nsTableFrame;
|
||||
class nsTableCellFrame;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
class nsReflowTimer;
|
||||
#endif
|
||||
|
||||
/* ----------- RowReflowState ---------- */
|
||||
|
||||
struct RowReflowState {
|
||||
@ -71,6 +75,8 @@ struct RowReflowState {
|
||||
class nsTableRowFrame : public nsHTMLContainerFrame
|
||||
{
|
||||
public:
|
||||
virtual ~nsTableRowFrame();
|
||||
|
||||
NS_IMETHOD Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
@ -321,6 +327,11 @@ private:
|
||||
// max-ascent and max-descent amongst all cells that have 'vertical-align: baseline'
|
||||
nscoord mMaxCellAscent; // does include cells with rowspan > 1
|
||||
nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
nsReflowTimer* mTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline PRInt32 nsTableRowFrame::GetRowIndex() const
|
||||
|
||||
@ -42,6 +42,20 @@
|
||||
|
||||
#include "nsCellMap.h"//table cell navigation
|
||||
|
||||
nsTableRowGroupFrame::nsTableRowGroupFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
mTimer = new nsReflowTimer(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsTableRowGroupFrame::~nsTableRowGroupFrame()
|
||||
{
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflowDone(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ----------- nsTableRowGroupFrame ---------- */
|
||||
nsrefcnt nsTableRowGroupFrame::AddRef(void)
|
||||
{
|
||||
@ -1055,7 +1069,9 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsTableRowGroupFrame", aReflowState.reason);
|
||||
if (nsDebugTable::gRflRowGrp) nsTableFrame::DebugReflow("TRG::Rfl", this, &aReflowState, nsnull);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState);
|
||||
#endif
|
||||
nsresult rv=NS_OK;
|
||||
|
||||
// Initialize out parameter
|
||||
@ -1163,7 +1179,9 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
|
||||
mMaxElementSize = *aDesiredSize.maxElementSize;
|
||||
}
|
||||
|
||||
if (nsDebugTable::gRflRowGrp) nsTableFrame::DebugReflow("TRG::Rfl ex", this, nsnull, &aDesiredSize, aStatus);
|
||||
#if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING
|
||||
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
class nsTableFrame;
|
||||
class nsTableRowFrame;
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
class nsReflowTimer;
|
||||
#endif
|
||||
|
||||
/* ----------- RowGroupReflowState ---------- */
|
||||
|
||||
@ -103,6 +106,7 @@ public:
|
||||
*/
|
||||
friend nsresult
|
||||
NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
virtual ~nsTableRowGroupFrame();
|
||||
|
||||
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
@ -223,6 +227,7 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
nsTableRowGroupFrame();
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
@ -341,6 +346,10 @@ public:
|
||||
private:
|
||||
nsSize mMaxElementSize;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
nsReflowTimer* mTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline void nsTableRowGroupFrame::GetMaxElementSize(nsSize& aMaxElementSize) const
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user