Created
January 23, 2014 17:34
-
-
Save mikeconley/8583069 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# HG changeset patch | |
# User Mike Conley <mconley@mozilla.com> | |
# Date 1380736516 14400 | |
# Node ID a50b7efcbe76a5549a217f9c4da3f152771feee1 | |
# Parent 2a580ab573f66861b054e24d0d69f4945a27ea5d | |
m-c - reflow profile for tscrollx on 030e365d7c26. try: -b o -p macosx64,linux,linux64 -u none -t svgr | |
diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp | |
--- a/layout/base/RestyleManager.cpp | |
+++ b/layout/base/RestyleManager.cpp | |
@@ -2207,16 +2207,18 @@ ElementRestyler::CaptureChange(nsStyleCo | |
* mParentContent is the content node used to resolve the parent style | |
* context. This means that, for pseudo-elements, it is the content | |
* that should be used for selector matching (rather than the fake | |
* content node attached to the frame). | |
*/ | |
void | |
ElementRestyler::Restyle(nsRestyleHint aRestyleHint) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Restyle", "Restyle"); | |
+ | |
// It would be nice if we could make stronger assertions here; they | |
// would let us simplify the ?: expressions below setting |content| | |
// and |pseudoContent| in sensible ways as well as making what | |
// |content| and |pseudoContent| mean, and their relationship to | |
// |mFrame->GetContent()|, make more sense. However, we can't, | |
// because of frame trees like the one in | |
// https://bugzilla.mozilla.org/show_bug.cgi?id=472353#c14 . Once we | |
// fix bug 242277 we should be able to make this make more sense. | |
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp | |
--- a/layout/base/nsDisplayList.cpp | |
+++ b/layout/base/nsDisplayList.cpp | |
@@ -1586,16 +1586,17 @@ nsDisplaySolidColor::GetBounds(nsDisplay | |
*aSnap = true; | |
return mBounds; | |
} | |
void | |
nsDisplaySolidColor::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "SolidColor"); | |
aCtx->SetColor(mColor); | |
aCtx->FillRect(mVisibleRect); | |
} | |
static void | |
RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) | |
{ | |
nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(aFrame); | |
@@ -2133,16 +2134,17 @@ static void CheckForBorderItem(nsDisplay | |
nextItem->GetType() == nsDisplayItem::TYPE_BORDER) { | |
aFlags |= nsCSSRendering::PAINTBG_WILL_PAINT_BORDER; | |
} | |
} | |
void | |
nsDisplayBackgroundImage::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) { | |
+ TIME_FOR_FRAME(mFrame, "Painting", "BackgroundImage"); | |
PaintInternal(aBuilder, aCtx, mVisibleRect, nullptr); | |
} | |
void | |
nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx, const nsRect& aBounds, | |
nsRect* aClipRect) { | |
nsPoint offset = ToReferenceFrame(); | |
@@ -2306,16 +2308,17 @@ nsDisplayThemedBackground::GetPositionin | |
{ | |
return nsRect(ToReferenceFrame(), mFrame->GetSize()); | |
} | |
void | |
nsDisplayThemedBackground::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "ThemedBackground"); | |
PaintInternal(aBuilder, aCtx, mVisibleRect, nullptr); | |
} | |
void | |
nsDisplayThemedBackground::PaintInternal(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx, const nsRect& aBounds, | |
nsRect* aClipRect) | |
{ | |
@@ -2383,16 +2386,17 @@ nsDisplayThemedBackground::GetBoundsInte | |
return r + ToReferenceFrame(); | |
} | |
void | |
nsDisplayBackgroundColor::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "BackgroundColor"); | |
if (mColor == NS_RGBA(0, 0, 0, 0)) { | |
return; | |
} | |
nsPoint offset = ToReferenceFrame(); | |
uint32_t flags = aBuilder->GetBackgroundPaintFlags(); | |
CheckForBorderItem(this, flags); | |
nsCSSRendering::PaintBackgroundColor(mFrame->PresContext(), *aCtx, mFrame, | |
@@ -2450,16 +2454,17 @@ nsRect | |
nsDisplayOutline::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { | |
*aSnap = false; | |
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); | |
} | |
void | |
nsDisplayOutline::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) { | |
+ TIME_FOR_FRAME(mFrame, "Painting", "Outline"); | |
// TODO join outlines together | |
nsPoint offset = ToReferenceFrame(); | |
nsCSSRendering::PaintOutline(mFrame->PresContext(), *aCtx, mFrame, | |
mVisibleRect, | |
nsRect(offset, mFrame->GetSize()), | |
mFrame->StyleContext()); | |
} | |
@@ -2532,16 +2537,17 @@ nsDisplayLayerEventRegions::AddFrame(nsD | |
if (aBuilder->GetAncestorHasTouchEventHandler()) { | |
mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, borderBox); | |
} | |
} | |
void | |
nsDisplayCaret::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) { | |
+ TIME_FOR_FRAME(mFrame, "Painting", "Caret"); | |
// Note: Because we exist, we know that the caret is visible, so we don't | |
// need to check for the caret's visibility. | |
mCaret->PaintCaret(aBuilder, aCtx, mFrame, ToReferenceFrame()); | |
} | |
bool | |
nsDisplayBorder::ComputeVisibility(nsDisplayListBuilder* aBuilder, | |
nsRegion* aVisibleRegion, | |
@@ -2589,16 +2595,17 @@ nsDisplayBorder::ComputeInvalidationRegi | |
// is apparently painting a background with this? | |
aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds); | |
} | |
} | |
void | |
nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) { | |
+ TIME_FOR_FRAME(mFrame, "Painting", "Border"); | |
nsPoint offset = ToReferenceFrame(); | |
nsCSSRendering::PaintBorder(mFrame->PresContext(), *aCtx, mFrame, | |
mVisibleRect, | |
nsRect(offset, mFrame->GetSize()), | |
mFrame->StyleContext(), | |
mFrame->GetSkipSides()); | |
} | |
@@ -2660,16 +2667,17 @@ ComputeDisjointRectangles(const nsRegion | |
accumulated = *r; | |
} | |
} | |
void | |
nsDisplayBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) { | |
+ TIME_FOR_FRAME(mFrame, "Painting", "BoxShadowOuter"); | |
nsPoint offset = ToReferenceFrame(); | |
nsRect borderRect = mFrame->VisualBorderRectRelativeToSelf() + offset; | |
nsPresContext* presContext = mFrame->PresContext(); | |
nsAutoTArray<nsRect,10> rects; | |
ComputeDisjointRectangles(mVisibleRegion, &rects); | |
PROFILER_LABEL("nsDisplayBoxShadowOuter", "Paint"); | |
for (uint32_t i = 0; i < rects.Length(); ++i) { | |
@@ -2746,16 +2754,17 @@ nsDisplayBoxShadowOuter::ComputeInvalida | |
aInvalidRegion->Or(oldShadow, newShadow); | |
} | |
} | |
void | |
nsDisplayBoxShadowInner::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) { | |
+ TIME_FOR_FRAME(mFrame, "Painting", "BoxShadowInner"); | |
nsPoint offset = ToReferenceFrame(); | |
nsRect borderRect = nsRect(offset, mFrame->GetSize()); | |
nsPresContext* presContext = mFrame->PresContext(); | |
nsAutoTArray<nsRect,10> rects; | |
ComputeDisjointRectangles(mVisibleRegion, &rects); | |
PROFILER_LABEL("nsDisplayBoxShadowInner", "Paint"); | |
for (uint32_t i = 0; i < rects.Length(); ++i) { | |
@@ -3785,16 +3794,17 @@ void nsDisplayZoom::HitTest(nsDisplayLis | |
rect = aRect.ConvertAppUnitsRoundOut(mParentAPD, mAPD); | |
} | |
mList.HitTest(aBuilder, rect, aState, aOutFrames); | |
} | |
void nsDisplayZoom::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "Zoom"); | |
mList.PaintForFrame(aBuilder, aCtx, mFrame, nsDisplayList::PAINT_DEFAULT); | |
} | |
bool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder, | |
nsRegion *aVisibleRegion, | |
const nsRect& aAllowVisibleRegionExpansion) | |
{ | |
// Convert the passed in visible region to our appunits. | |
@@ -4753,16 +4763,17 @@ nsDisplaySVGEffects::HitTest(nsDisplayLi | |
} | |
} | |
void | |
nsDisplaySVGEffects::PaintAsLayer(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx, | |
LayerManager* aManager) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "SVGEffects"); | |
nsSVGIntegrationUtils::PaintFramesWithEffects(aCtx, mFrame, | |
mVisibleRect, | |
aBuilder, aManager); | |
} | |
LayerState | |
nsDisplaySVGEffects::GetLayerState(nsDisplayListBuilder* aBuilder, | |
LayerManager* aManager, | |
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp | |
--- a/layout/base/nsLayoutUtils.cpp | |
+++ b/layout/base/nsLayoutUtils.cpp | |
@@ -2620,16 +2620,17 @@ nsLayoutUtils::GetTextShadowRectsUnion(c | |
return resultRect; | |
} | |
nsresult | |
nsLayoutUtils::GetFontMetricsForFrame(const nsIFrame* aFrame, | |
nsFontMetrics** aFontMetrics, | |
float aInflation) | |
{ | |
+ TIME_REFLOW(aFrame, "GetFontMetrics"); | |
return nsLayoutUtils::GetFontMetricsForStyleContext(aFrame->StyleContext(), | |
aFontMetrics, | |
aInflation); | |
} | |
nsresult | |
nsLayoutUtils::GetFontMetricsForStyleContext(nsStyleContext* aStyleContext, | |
nsFontMetrics** aFontMetrics, | |
@@ -3786,16 +3787,17 @@ nsLayoutUtils::DrawString(const nsIFrame | |
} | |
nscoord | |
nsLayoutUtils::GetStringWidth(const nsIFrame* aFrame, | |
nsRenderingContext* aContext, | |
const char16_t* aString, | |
int32_t aLength) | |
{ | |
+ TIME_REFLOW(aFrame, "GetStringWidth"); | |
#ifdef IBMBIDI | |
nsPresContext* presContext = aFrame->PresContext(); | |
if (presContext->BidiEnabled()) { | |
nsBidiLevel level = | |
nsBidiPresUtils::BidiLevelFromStyle(aFrame->StyleContext()); | |
return nsBidiPresUtils::MeasureTextWidth(aString, aLength, | |
level, presContext, *aContext); | |
} | |
@@ -3881,16 +3883,17 @@ nsLayoutUtils::GetFirstLineBaseline(cons | |
*aResult = position.mBaseline; | |
return true; | |
} | |
/* static */ bool | |
nsLayoutUtils::GetFirstLinePosition(const nsIFrame* aFrame, | |
LinePosition* aResult) | |
{ | |
+ TIME_REFLOW(aFrame, "GetFirstLinePosition"); | |
const nsBlockFrame* block = nsLayoutUtils::GetAsBlock(const_cast<nsIFrame*>(aFrame)); | |
if (!block) { | |
// For the first-line baseline we also have to check for a table, and if | |
// so, use the baseline of its first row. | |
nsIAtom* fType = aFrame->GetType(); | |
if (fType == nsGkAtoms::tableOuterFrame) { | |
aResult->mTop = 0; | |
aResult->mBaseline = aFrame->GetBaseline(); | |
diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp | |
--- a/layout/forms/nsButtonFrameRenderer.cpp | |
+++ b/layout/forms/nsButtonFrameRenderer.cpp | |
@@ -84,16 +84,17 @@ nsRect | |
nsDisplayButtonBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { | |
*aSnap = false; | |
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); | |
} | |
void | |
nsDisplayButtonBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) { | |
+ TIME_FOR_FRAME(mFrame, "Painting", "ButtonBoxShadowOuter"); | |
nsRect frameRect = nsRect(ToReferenceFrame(), mFrame->GetSize()); | |
nsRect buttonRect; | |
mBFR->GetButtonRect(frameRect, buttonRect); | |
nsCSSRendering::PaintBoxShadowOuter(mFrame->PresContext(), *aCtx, mFrame, | |
buttonRect, mVisibleRect); | |
} | |
@@ -161,28 +162,30 @@ nsDisplayButtonBorderBackground::Compute | |
AddInvalidRegionForSyncDecodeBackgroundImages(aBuilder, aGeometry, aInvalidRegion); | |
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); | |
} | |
void nsDisplayButtonBorderBackground::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "ButtonBorderBackground"); | |
NS_ASSERTION(mFrame, "No frame?"); | |
nsPresContext* pc = mFrame->PresContext(); | |
nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); | |
// draw the border and background inside the focus and outline borders | |
mBFR->PaintBorderAndBackground(pc, *aCtx, mVisibleRect, r, | |
aBuilder->GetBackgroundPaintFlags()); | |
} | |
void nsDisplayButtonForeground::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "ButtonForeground"); | |
nsPresContext *presContext = mFrame->PresContext(); | |
const nsStyleDisplay *disp = mFrame->StyleDisplay(); | |
if (!mFrame->IsThemed(disp) || | |
!presContext->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) { | |
// draw the focus and outline borders | |
nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); | |
mBFR->PaintOutlineAndFocusBorders(presContext, *aCtx, mVisibleRect, r); | |
} | |
diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp | |
--- a/layout/forms/nsComboboxControlFrame.cpp | |
+++ b/layout/forms/nsComboboxControlFrame.cpp | |
@@ -1445,16 +1445,17 @@ public: | |
virtual void Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx); | |
NS_DISPLAY_DECL_NAME("ComboboxFocus", TYPE_COMBOBOX_FOCUS) | |
}; | |
void nsDisplayComboboxFocus::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "ComboboxFocus"); | |
static_cast<nsComboboxControlFrame*>(mFrame) | |
->PaintFocus(*aCtx, ToReferenceFrame()); | |
} | |
void | |
nsComboboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, | |
const nsRect& aDirtyRect, | |
const nsDisplayListSet& aLists) | |
diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp | |
--- a/layout/forms/nsFieldSetFrame.cpp | |
+++ b/layout/forms/nsFieldSetFrame.cpp | |
@@ -123,16 +123,17 @@ void nsDisplayFieldSetBorderBackground:: | |
// It's not clear whether this is correct. | |
aOutFrames->AppendElement(mFrame); | |
} | |
void | |
nsDisplayFieldSetBorderBackground::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "FieldSetBorderBackground"); | |
static_cast<nsFieldSetFrame*>(mFrame)-> | |
PaintBorderBackground(*aCtx, ToReferenceFrame(), | |
mVisibleRect, aBuilder->GetBackgroundPaintFlags()); | |
} | |
void | |
nsDisplayFieldSetBorderBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, | |
const nsDisplayItemGeometry* aGeometry, | |
diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp | |
--- a/layout/forms/nsRangeFrame.cpp | |
+++ b/layout/forms/nsRangeFrame.cpp | |
@@ -170,16 +170,17 @@ public: | |
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; | |
NS_DISPLAY_DECL_NAME("RangeFocusRing", TYPE_OUTLINE) | |
}; | |
void | |
nsDisplayRangeFocusRing::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "RangeFocusRing"); | |
nsPresContext *presContext = mFrame->PresContext(); | |
nscoord appUnitsPerDevPixel = presContext->DevPixelsToAppUnits(1); | |
gfxContext* ctx = aCtx->ThebesContext(); | |
nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); | |
gfxRect pxRect(nsLayoutUtils::RectToGfxRect(r, appUnitsPerDevPixel)); | |
uint8_t borderStyles[4] = { NS_STYLE_BORDER_STYLE_DOTTED, | |
NS_STYLE_BORDER_STYLE_DOTTED, | |
NS_STYLE_BORDER_STYLE_DOTTED, | |
diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp | |
--- a/layout/generic/TextOverflow.cpp | |
+++ b/layout/generic/TextOverflow.cpp | |
@@ -198,16 +198,17 @@ PaintTextShadowCallback(nsRenderingConte | |
reinterpret_cast<nsDisplayTextOverflowMarker*>(aData)-> | |
PaintTextToContext(aCtx, aShadowOffset); | |
} | |
void | |
nsDisplayTextOverflowMarker::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "TextOverflowMarker"); | |
nscolor foregroundColor = | |
nsLayoutUtils::GetColor(mFrame, eCSSProperty_color); | |
// Paint the text-shadows for the overflow marker | |
nsLayoutUtils::PaintTextShadow(mFrame, aCtx, mRect, mVisibleRect, | |
foregroundColor, PaintTextShadowCallback, | |
(void*)this); | |
aCtx->SetColor(foregroundColor); | |
diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp | |
--- a/layout/generic/nsBulletFrame.cpp | |
+++ b/layout/generic/nsBulletFrame.cpp | |
@@ -247,16 +247,17 @@ public: | |
return nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); | |
} | |
}; | |
void nsDisplayBullet::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "Bullet"); | |
uint32_t flags = imgIContainer::FLAG_NONE; | |
if (aBuilder->ShouldSyncDecodeImages()) { | |
flags |= imgIContainer::FLAG_SYNC_DECODE; | |
} | |
static_cast<nsBulletFrame*>(mFrame)-> | |
PaintBullet(*aCtx, ToReferenceFrame(), mVisibleRect, flags); | |
} | |
diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp | |
--- a/layout/generic/nsCanvasFrame.cpp | |
+++ b/layout/generic/nsCanvasFrame.cpp | |
@@ -175,16 +175,17 @@ nsRect nsCanvasFrame::CanvasArea() const | |
} | |
return result; | |
} | |
void | |
nsDisplayCanvasBackgroundColor::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "CanvasBackgroundColor"); | |
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame); | |
nsPoint offset = ToReferenceFrame(); | |
nsRect bgClipRect = frame->CanvasArea() + offset; | |
if (NS_GET_A(mColor) > 0) { | |
aCtx->SetColor(mColor); | |
aCtx->FillRect(bgClipRect); | |
} | |
} | |
@@ -206,16 +207,17 @@ static void BlitSurface(DrawTarget* aDes | |
Rect(aRect.x, aRect.y, aRect.width, aRect.height), | |
Rect(0, 0, aRect.width, aRect.height)); | |
} | |
void | |
nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "CanvasBackgroundImage"); | |
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame); | |
nsPoint offset = ToReferenceFrame(); | |
nsRect bgClipRect = frame->CanvasArea() + offset; | |
nsRenderingContext context; | |
nsRefPtr<gfxContext> dest = aCtx->ThebesContext(); | |
nsRefPtr<gfxASurface> surf; | |
RefPtr<DrawTarget> dt; | |
@@ -273,16 +275,17 @@ nsDisplayCanvasBackgroundImage::Paint(ns | |
frame->Properties().Set(nsIFrame::CachedBackgroundImageDT(), dt.forget().drop()); | |
} | |
} | |
void | |
nsDisplayCanvasThemedBackground::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "CanvasThemedBackground"); | |
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame); | |
nsPoint offset = ToReferenceFrame(); | |
nsRect bgClipRect = frame->CanvasArea() + offset; | |
PaintInternal(aBuilder, aCtx, mVisibleRect, &bgClipRect); | |
} | |
/** | |
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp | |
--- a/layout/generic/nsFrame.cpp | |
+++ b/layout/generic/nsFrame.cpp | |
@@ -1358,16 +1358,17 @@ public: | |
NS_DISPLAY_DECL_NAME("SelectionOverlay", TYPE_SELECTION_OVERLAY) | |
private: | |
int16_t mSelectionValue; | |
}; | |
void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "SelectionOverlay"); | |
LookAndFeel::ColorID colorID; | |
if (mSelectionValue == nsISelectionController::SELECTION_ON) { | |
colorID = LookAndFeel::eColorID_TextSelectBackground; | |
} else if (mSelectionValue == nsISelectionController::SELECTION_ATTENTION) { | |
colorID = LookAndFeel::eColorID_TextSelectBackgroundAttention; | |
} else { | |
colorID = LookAndFeel::eColorID_TextSelectBackgroundDisabled; | |
} | |
diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h | |
--- a/layout/generic/nsFrame.h | |
+++ b/layout/generic/nsFrame.h | |
@@ -829,30 +829,49 @@ public: | |
dr_bdr, dr_pad) | |
#define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad) \ | |
DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad) | |
#define DISPLAY_INIT_TYPE(dr_frame, dr_result) \ | |
DR_init_type_cookie dr_cookie(dr_frame, dr_result) | |
#else | |
-#define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status) | |
+class AutoLayoutTimer | |
+{ | |
+public: | |
+ AutoLayoutTimer(const nsIFrame* aFrame, const char* aCategory, const char* aDescription); | |
+ ~AutoLayoutTimer(); | |
+ | |
+private: | |
+ nsIContent* mContent; | |
+ AutoLayoutTimer* mParent; | |
+ mozilla::TimeStamp mStartTime; | |
+ mozilla::TimeDuration mDirectChildDurationSum; | |
+ const char* mCategory; | |
+ const char* mDescription; | |
+ | |
+ static AutoLayoutTimer* sCurrentAutoLayoutTimer; | |
+}; | |
+ | |
+#define TIME_FOR_FRAME(frame, category, description) AutoLayoutTimer _timer(frame, category, description) | |
+#define TIME_REFLOW(dr_frame, dr_description) TIME_FOR_FRAME(dr_frame, "Reflow", dr_description) | |
+#define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status) TIME_REFLOW(dr_frame, "Reflow") | |
#define DISPLAY_REFLOW_CHANGE() | |
-#define DISPLAY_LAYOUT(dr_frame) PR_BEGIN_MACRO PR_END_MACRO | |
-#define DISPLAY_MIN_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO | |
-#define DISPLAY_PREF_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO | |
-#define DISPLAY_PREF_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO | |
-#define DISPLAY_MIN_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO | |
-#define DISPLAY_MAX_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO | |
+#define DISPLAY_LAYOUT(dr_frame) TIME_REFLOW(dr_frame, "Layout") | |
+#define DISPLAY_MIN_WIDTH(dr_frame, dr_result) TIME_REFLOW(dr_frame, "MinWidth") | |
+#define DISPLAY_PREF_WIDTH(dr_frame, dr_result) TIME_REFLOW(dr_frame, "PrefWidth") | |
+#define DISPLAY_PREF_SIZE(dr_frame, dr_result) TIME_REFLOW(dr_frame, "PrefSize") | |
+#define DISPLAY_MIN_SIZE(dr_frame, dr_result) TIME_REFLOW(dr_frame, "MinSize") | |
+#define DISPLAY_MAX_SIZE(dr_frame, dr_result) TIME_REFLOW(dr_frame, "MaxSize") | |
#define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, \ | |
dr_bdr, dr_pad) \ | |
- PR_BEGIN_MACRO PR_END_MACRO | |
+ TIME_REFLOW(dr_frame, "InitConstraints") | |
#define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad) \ | |
- PR_BEGIN_MACRO PR_END_MACRO | |
-#define DISPLAY_INIT_TYPE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO | |
+ TIME_REFLOW(dr_frame, "InitOffsets") | |
+#define DISPLAY_INIT_TYPE(dr_frame, dr_result) TIME_REFLOW(dr_frame, "InitType") | |
#endif | |
// End Display Reflow Debugging | |
// similar to NS_ENSURE_TRUE but with no return value | |
#define ENSURE_TRUE(x) \ | |
PR_BEGIN_MACRO \ | |
if (!(x)) { \ | |
diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp | |
--- a/layout/generic/nsFrameSetFrame.cpp | |
+++ b/layout/generic/nsFrameSetFrame.cpp | |
@@ -1476,16 +1476,17 @@ public: | |
virtual void Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx); | |
NS_DISPLAY_DECL_NAME("FramesetBorder", TYPE_FRAMESET_BORDER) | |
}; | |
void nsDisplayFramesetBorder::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "FramesetBorder"); | |
static_cast<nsHTMLFramesetBorderFrame*>(mFrame)-> | |
PaintBorder(*aCtx, ToReferenceFrame()); | |
} | |
void | |
nsHTMLFramesetBorderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, | |
const nsRect& aDirtyRect, | |
const nsDisplayListSet& aLists) | |
@@ -1675,16 +1676,17 @@ public: | |
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); | |
NS_DISPLAY_DECL_NAME("FramesetBlank", TYPE_FRAMESET_BLANK) | |
}; | |
void nsDisplayFramesetBlank::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "FrameSetBlank"); | |
nscolor white = NS_RGB(255,255,255); | |
aCtx->SetColor(white); | |
aCtx->FillRect(mVisibleRect); | |
} | |
void | |
nsHTMLFramesetBlankFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, | |
const nsRect& aDirtyRect, | |
diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp | |
--- a/layout/generic/nsImageFrame.cpp | |
+++ b/layout/generic/nsImageFrame.cpp | |
@@ -1220,16 +1220,17 @@ static void PaintDebugImageMap(nsIFrame* | |
f->GetImageMap()->Draw(aFrame, *aCtx); | |
aCtx->PopState(); | |
} | |
#endif | |
void | |
nsDisplayImage::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) { | |
+ TIME_FOR_FRAME(mFrame, "Painting", "DisplayImage"); | |
uint32_t flags = imgIContainer::FLAG_NONE; | |
if (aBuilder->ShouldSyncDecodeImages()) { | |
flags |= imgIContainer::FLAG_SYNC_DECODE; | |
} | |
if (aBuilder->IsPaintingToWindow()) { | |
flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING; | |
} | |
static_cast<nsImageFrame*>(mFrame)-> | |
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp | |
--- a/layout/generic/nsTextFrame.cpp | |
+++ b/layout/generic/nsTextFrame.cpp | |
@@ -2592,16 +2592,17 @@ NS_QUERYFRAME_TAIL_INHERITING(nsTextFram | |
gfxSkipCharsIterator | |
nsTextFrame::EnsureTextRun(TextRunType aWhichTextRun, | |
gfxContext* aReferenceContext, | |
nsIFrame* aLineContainer, | |
const nsLineList::iterator* aLine, | |
uint32_t* aFlowEndInTextRun) | |
{ | |
+ TIME_REFLOW(this, "EnsureTextRun"); | |
gfxTextRun *textRun = GetTextRun(aWhichTextRun); | |
if (textRun && (!aLine || !(*aLine)->GetInvalidateTextRuns())) { | |
if (textRun->GetExpirationState()->IsTracked()) { | |
gTextRuns->MarkUsed(textRun); | |
} | |
} else { | |
nsRefPtr<gfxContext> ctx = aReferenceContext; | |
if (!ctx) { | |
@@ -4570,16 +4571,17 @@ public: | |
virtual void DisableComponentAlpha() { mDisableSubpixelAA = true; } | |
bool mDisableSubpixelAA; | |
}; | |
void | |
nsDisplayText::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) { | |
+ TIME_FOR_FRAME(mFrame, "Painting", "Text"); | |
PROFILER_LABEL("nsDisplayText", "Paint"); | |
// Add 1 pixel of dirty area around mVisibleRect to allow us to paint | |
// antialiased pixels beyond the measured text extents. | |
// This is temporary until we do this in the actual calculation of text extents. | |
nsRect extraVisible = mVisibleRect; | |
nscoord appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); | |
extraVisible.Inflate(appUnitsPerDevPixel, appUnitsPerDevPixel); | |
nsTextFrame* f = static_cast<nsTextFrame*>(mFrame); | |
diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp | |
--- a/layout/mathml/nsMathMLChar.cpp | |
+++ b/layout/mathml/nsMathMLChar.cpp | |
@@ -2,16 +2,17 @@ | |
/* This Source Code Form is subject to the terms of the Mozilla Public | |
* License, v. 2.0. If a copy of the MPL was not distributed with this | |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
#include "nsMathMLChar.h" | |
#include "mozilla/MathAlgorithms.h" | |
#include "nsCOMPtr.h" | |
+#include "nsFrame.h" | |
#include "nsIFrame.h" | |
#include "nsPresContext.h" | |
#include "nsStyleContext.h" | |
#include "nsUnicharUtils.h" | |
#include "nsRenderingContext.h" | |
#include "mozilla/Preferences.h" | |
#include "nsIPersistentProperties2.h" | |
@@ -1617,16 +1618,17 @@ public: | |
NS_DISPLAY_DECL_NAME("MathMLSelectionRect", TYPE_MATHML_SELECTION_RECT) | |
private: | |
nsRect mRect; | |
}; | |
void nsDisplayMathMLSelectionRect::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "MathMLSelectionRect"); | |
// get color to use for selection from the look&feel object | |
nscolor bgColor = | |
LookAndFeel::GetColor(LookAndFeel::eColorID_TextSelectBackground, | |
NS_RGB(0, 0, 0)); | |
aCtx->SetColor(bgColor); | |
aCtx->FillRect(mRect + ToReferenceFrame()); | |
} | |
@@ -1664,16 +1666,17 @@ nsDisplayMathMLCharBackground::ComputeIn | |
AddInvalidRegionForSyncDecodeBackgroundImages(aBuilder, aGeometry, aInvalidRegion); | |
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); | |
} | |
void nsDisplayMathMLCharBackground::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "MathMLCharBackground"); | |
const nsStyleBorder* border = mStyleContext->StyleBorder(); | |
nsRect rect(mRect + ToReferenceFrame()); | |
nsCSSRendering::PaintBackgroundWithSC(mFrame->PresContext(), *aCtx, mFrame, | |
mVisibleRect, rect, | |
mStyleContext, *border, | |
aBuilder->GetBackgroundPaintFlags()); | |
} | |
@@ -1752,16 +1755,17 @@ public: | |
private: | |
nsRect mRect; | |
}; | |
void nsDisplayMathMLCharDebug::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "MathMLCharDebug"); | |
// for visual debug | |
int skipSides = 0; | |
nsPresContext* presContext = mFrame->PresContext(); | |
nsStyleContext* styleContext = mFrame->StyleContext(); | |
nsRect rect = mRect + ToReferenceFrame(); | |
nsCSSRendering::PaintBorder(presContext, *aCtx, mFrame, | |
mVisibleRect, rect, styleContext, skipSides); | |
nsCSSRendering::PaintOutline(presContext, *aCtx, mFrame, | |
diff --git a/layout/xul/nsBox.cpp b/layout/xul/nsBox.cpp | |
--- a/layout/xul/nsBox.cpp | |
+++ b/layout/xul/nsBox.cpp | |
@@ -15,17 +15,23 @@ | |
#include "nsFrameManager.h" | |
#include "nsIDOMNode.h" | |
#include "nsIDOMMozNamedAttrMap.h" | |
#include "nsIDOMAttr.h" | |
#include "nsITheme.h" | |
#include "nsIServiceManager.h" | |
#include "nsBoxLayout.h" | |
#include "FrameLayerBuilder.h" | |
+#include "nsAttrValue.h" | |
#include <algorithm> | |
+#include <iostream> | |
+#include <fstream> | |
+#include "prenv.h" | |
+#include "nsIURI.h" | |
+#include "nsIDocument.h" | |
using namespace mozilla; | |
#ifdef DEBUG_LAYOUT | |
int32_t gIndent = 0; | |
#endif | |
#ifdef DEBUG_LAYOUT | |
@@ -300,16 +306,17 @@ nsIFrame::GetBorderAndPadding(nsMargin& | |
aBorderAndPadding += padding; | |
return rv; | |
} | |
NS_IMETHODIMP | |
nsBox::GetBorder(nsMargin& aMargin) | |
{ | |
+ TIME_REFLOW(this, "GetBorder"); | |
aMargin.SizeTo(0,0,0,0); | |
const nsStyleDisplay* disp = StyleDisplay(); | |
if (disp->mAppearance && gTheme) { | |
// Go to the theme for the border. | |
nsPresContext *context = PresContext(); | |
if (gTheme->ThemeSupportsWidget(context, this, disp->mAppearance)) { | |
nsIntMargin margin(0, 0, 0, 0); | |
@@ -326,16 +333,17 @@ nsBox::GetBorder(nsMargin& aMargin) | |
aMargin = StyleBorder()->GetComputedBorder(); | |
return NS_OK; | |
} | |
NS_IMETHODIMP | |
nsBox::GetPadding(nsMargin& aMargin) | |
{ | |
+ TIME_REFLOW(this, "GetPadding"); | |
const nsStyleDisplay *disp = StyleDisplay(); | |
if (disp->mAppearance && gTheme) { | |
// Go to the theme for the padding. | |
nsPresContext *context = PresContext(); | |
if (gTheme->ThemeSupportsWidget(context, this, disp->mAppearance)) { | |
nsIntMargin margin(0, 0, 0, 0); | |
bool useThemePadding; | |
@@ -356,16 +364,17 @@ nsBox::GetPadding(nsMargin& aMargin) | |
StylePadding()->GetPadding(aMargin); | |
return NS_OK; | |
} | |
NS_IMETHODIMP | |
nsBox::GetMargin(nsMargin& aMargin) | |
{ | |
+ TIME_REFLOW(this, "GetMargin"); | |
aMargin.SizeTo(0,0,0,0); | |
StyleMargin()->GetMargin(aMargin); | |
return NS_OK; | |
} | |
void | |
nsBox::SizeNeedsRecalc(nsSize& aSize) | |
@@ -480,28 +489,219 @@ nsIFrame::GetOrdinal() | |
} | |
return ordinal; | |
} | |
nscoord | |
nsBox::GetBoxAscent(nsBoxLayoutState& aState) | |
{ | |
+ TIME_REFLOW(this, "GetBoxAscent"); | |
if (IsCollapsed()) | |
return 0; | |
return GetPrefSize(aState).height; | |
} | |
bool | |
nsBox::IsCollapsed() | |
{ | |
return StyleVisibility()->mVisible == NS_STYLE_VISIBILITY_COLLAPSE; | |
} | |
+static void | |
+AppendNodeDescription(std::ostream& aStr, nsIContent* aContent, nsINode* aNode) | |
+{ | |
+ aStr << "\""; | |
+ aStr << nsAtomCString(aNode->Tag()).get(); | |
+ if (aContent) { | |
+ nsIAtom* id = aContent->GetID(); | |
+ if (id) { | |
+ aStr << "#" << nsAtomCString(id).get(); | |
+ } | |
+ const nsAttrValue* elementClasses = aContent->GetClasses(); | |
+ if (elementClasses) { | |
+ int32_t atomCount = elementClasses->GetAtomCount(); | |
+ for (int32_t i = 0; i < atomCount; ++i) { | |
+ aStr << "." << nsAtomCString(elementClasses->AtomAt(i)).get(); | |
+ } | |
+ } | |
+ } else if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) { | |
+ nsIDocument* doc = static_cast<nsIDocument*>(aNode); | |
+ nsAutoCString docURL("N/A"); | |
+ nsIURI *uri = doc->GetDocumentURI(); | |
+ if (uri) | |
+ uri->GetSpec(docURL); | |
+ aStr << " (" << docURL.get() << ")"; | |
+ } | |
+ aStr << "\""; | |
+} | |
+ | |
+static void | |
+AppendParentContentPath(std::ostream& aStr, nsINode* aNode, nsIContent* aContent) | |
+{ | |
+ if (aContent) { | |
+ AppendParentContentPath(aStr, aContent->GetParentNode(), aContent->GetParent()); | |
+ } | |
+ aStr << ","; | |
+ AppendNodeDescription(aStr, aContent, aNode); | |
+} | |
+ | |
+static void | |
+AppendContentPath(std::ostream& aStr, nsIContent* aContent) | |
+{ | |
+ if (aContent) { | |
+ AppendParentContentPath(aStr, aContent, aContent); | |
+ } else { | |
+ aStr << ",\"<unknown>\""; | |
+ } | |
+} | |
+ | |
+struct LayoutTimerSelfTimeReport { | |
+ LayoutTimerSelfTimeReport() | |
+ : mContent(nullptr) | |
+ { | |
+ mCategory[0] = '\0'; | |
+ mDescription[0] = '\0'; | |
+ } | |
+ void SetDescription(const char* aDescription) | |
+ { | |
+ strncpy(mDescription, aDescription, 31); | |
+ mDescription[31] = '\0'; | |
+ } | |
+ void SetCategory(const char* aCategory) | |
+ { | |
+ strncpy(mCategory, aCategory, 31); | |
+ mCategory[31] = '\0'; | |
+ } | |
+ | |
+ TimeDuration mSelfDuration; | |
+ nsIContent* mContent; | |
+ char mCategory[32]; | |
+ char mDescription[32]; | |
+}; | |
+ | |
+/** | |
+ * profile format: | |
+ * { | |
+ * "threads":[ | |
+ * { | |
+ * "samples":[ | |
+ * { | |
+ * "weight":0.57, | |
+ * "frames":[ | |
+ * "function1ofstacktrace1", | |
+ * "function2ofstacktrace1", | |
+ * ... | |
+ * ] | |
+ * }, | |
+ * { | |
+ * "weight":0.39, | |
+ * "frames":[ | |
+ * "function1ofstacktrace2", | |
+ * "function2ofstacktrace2", | |
+ * ... | |
+ * ] | |
+ * }, | |
+ * ... | |
+ * ] | |
+ * } | |
+ * ] | |
+ * } | |
+ */ | |
+ | |
+static const size_t kMaxNumberReports = 100000; | |
+static LayoutTimerSelfTimeReport sReports[kMaxNumberReports]; | |
+static size_t sCurrentReportIndex; | |
+static std::ofstream* sProfileFile; | |
+ | |
+AutoLayoutTimer::AutoLayoutTimer(const nsIFrame* aFrame, const char* aCategory, const char* aDescription) | |
+ : mContent(aFrame->GetContent()) | |
+ , mParent(sCurrentAutoLayoutTimer) | |
+ , mStartTime(TimeStamp::Now()) | |
+ , mCategory(aCategory) | |
+ , mDescription(aDescription) | |
+{ | |
+ sCurrentAutoLayoutTimer = this; | |
+} | |
+ | |
+AutoLayoutTimer::~AutoLayoutTimer() | |
+{ | |
+ TimeDuration duration = TimeStamp::Now() - mStartTime; | |
+ if (sCurrentReportIndex < kMaxNumberReports && | |
+ duration >= TimeDuration::FromMilliseconds(0.00001)) { | |
+ LayoutTimerSelfTimeReport& report = sReports[sCurrentReportIndex++]; | |
+ report.mContent = mContent; | |
+ report.mSelfDuration = duration - mDirectChildDurationSum; | |
+ report.SetCategory(mCategory); | |
+ report.SetDescription(mDescription); | |
+ if (mParent) { | |
+ mParent->mDirectChildDurationSum += duration; | |
+ } | |
+ } | |
+ sCurrentAutoLayoutTimer = mParent; | |
+ if (!mParent && sProfileFile) { | |
+ std::ostream& str = *sProfileFile; | |
+ for (size_t i = 0; i < sCurrentReportIndex; i++) { | |
+ str << ",{\"weight\":"; | |
+ str << sReports[i].mSelfDuration.ToMilliseconds(); | |
+ str << ",\"frames\":[\"(root)\""; | |
+ AppendContentPath(str, sReports[i].mContent); | |
+ str << ",\"" << sReports[i].mDescription << " (in "; | |
+ str << sReports[i].mCategory; | |
+ str << ")\"]}"; | |
+ str.flush(); | |
+ } | |
+ sCurrentReportIndex = 0; | |
+ } | |
+} | |
+ | |
+void reflow_profiler_add_marker(const char* aMarker) | |
+{ | |
+ if (sProfileFile) { | |
+ *sProfileFile << ",{\"marker\":\"" << aMarker << "\",\"weight\":0,\"frames\":[\"(root)\"]}"; | |
+ } | |
+} | |
+ | |
+void reflow_profiler_init() | |
+{ | |
+ if (sProfileFile) { | |
+ // already inited | |
+ return; | |
+ } | |
+ if (XRE_GetProcessType() != GeckoProcessType_Default) { | |
+ // We only want to profile the parent process. | |
+ return; | |
+ } | |
+ const char* reflowProfileFile = PR_GetEnv("MOZ_REFLOW_PROFILE_FILE"); | |
+ if (reflowProfileFile) { | |
+ sProfileFile = new std::ofstream(reflowProfileFile); | |
+ if (sProfileFile->is_open()) { | |
+ *sProfileFile << "{\"threads\":[{\"samples\":[{\"weight\":0,\"frames\":[\"(root)\"]}"; | |
+ } else { | |
+ delete sProfileFile; | |
+ sProfileFile = nullptr; | |
+ } | |
+ } | |
+} | |
+ | |
+struct AutoReflowProfileFileManager { | |
+ ~AutoReflowProfileFileManager() { | |
+ if (sProfileFile) { | |
+ *sProfileFile << "]}]}"; | |
+ sProfileFile->close(); | |
+ delete sProfileFile; | |
+ } | |
+ } | |
+}; | |
+ | |
+static AutoReflowProfileFileManager sThisThingActsOnShutdown; | |
+ | |
+AutoLayoutTimer* AutoLayoutTimer::sCurrentAutoLayoutTimer; | |
+ | |
nsresult | |
nsIFrame::Layout(nsBoxLayoutState& aState) | |
{ | |
NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context"); | |
nsBox *box = static_cast<nsBox*>(this); | |
DISPLAY_LAYOUT(box); | |
diff --git a/layout/xul/nsImageBoxFrame.cpp b/layout/xul/nsImageBoxFrame.cpp | |
--- a/layout/xul/nsImageBoxFrame.cpp | |
+++ b/layout/xul/nsImageBoxFrame.cpp | |
@@ -340,16 +340,17 @@ nsImageBoxFrame::PaintImage(nsRenderingC | |
nsLayoutUtils::GetGraphicsFilterForFrame(this), | |
rect, dirty, nullptr, aFlags, hasSubRect ? &mSubRect : nullptr); | |
} | |
} | |
void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "XULImage"); | |
uint32_t flags = imgIContainer::FLAG_NONE; | |
if (aBuilder->ShouldSyncDecodeImages()) | |
flags |= imgIContainer::FLAG_SYNC_DECODE; | |
if (aBuilder->IsPaintingToWindow()) | |
flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING; | |
static_cast<nsImageBoxFrame*>(mFrame)-> | |
PaintImage(*aCtx, mVisibleRect, ToReferenceFrame(), flags); | |
diff --git a/layout/xul/nsTextBoxFrame.cpp b/layout/xul/nsTextBoxFrame.cpp | |
--- a/layout/xul/nsTextBoxFrame.cpp | |
+++ b/layout/xul/nsTextBoxFrame.cpp | |
@@ -317,16 +317,17 @@ PaintTextShadowCallback(nsRenderingConte | |
reinterpret_cast<nsDisplayXULTextBox*>(aData)-> | |
PaintTextToContext(aCtx, aShadowOffset, &aShadowColor); | |
} | |
void | |
nsDisplayXULTextBox::Paint(nsDisplayListBuilder* aBuilder, | |
nsRenderingContext* aCtx) | |
{ | |
+ TIME_FOR_FRAME(mFrame, "Painting", "XULTextBox"); | |
gfxContextAutoDisableSubpixelAntialiasing disable(aCtx->ThebesContext(), | |
mDisableSubpixelAA); | |
// Paint the text shadow before doing any foreground stuff | |
nsRect drawRect = static_cast<nsTextBoxFrame*>(mFrame)->mTextDrawRect + | |
ToReferenceFrame(); | |
nsLayoutUtils::PaintTextShadow(mFrame, aCtx, | |
drawRect, mVisibleRect, | |
diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp | |
--- a/toolkit/xre/nsEmbedFunctions.cpp | |
+++ b/toolkit/xre/nsEmbedFunctions.cpp | |
@@ -293,22 +293,22 @@ XRE_InitChildProcess(int aArgc, | |
if (_fileno(stderr) == -1 || | |
_get_osfhandle(fileno(stderr)) == -1) | |
freopen("CONOUT$", "w", stderr); | |
if (_fileno(stdin) == -1 || _get_osfhandle(fileno(stdin)) == -1) | |
freopen("CONIN$", "r", stdin); | |
} | |
#endif | |
+ sChildProcessType = aProcess; | |
+ | |
char aLocal; | |
profiler_init(&aLocal); | |
PROFILER_LABEL("Startup", "XRE_InitChildProcess"); | |
- sChildProcessType = aProcess; | |
- | |
// Complete 'task_t' exchange for Mac OS X. This structure has the same size | |
// regardless of architecture so we don't have any cross-arch issues here. | |
#ifdef XP_MACOSX | |
if (aArgc < 1) | |
return NS_ERROR_FAILURE; | |
const char* const mach_port_name = aArgv[--aArgc]; | |
const int kTimeoutMs = 1000; | |
diff --git a/tools/profiler/GeckoProfilerImpl.h b/tools/profiler/GeckoProfilerImpl.h | |
--- a/tools/profiler/GeckoProfilerImpl.h | |
+++ b/tools/profiler/GeckoProfilerImpl.h | |
@@ -382,11 +382,13 @@ inline void mozilla_sampler_call_exit(vo | |
{ | |
if (!aHandle) | |
return; | |
PseudoStack *stack = (PseudoStack*)aHandle; | |
stack->pop(); | |
} | |
+extern void reflow_profiler_add_marker(const char* aMarker); | |
+ | |
void mozilla_sampler_add_marker(const char *aMarker, ProfilerMarkerPayload *aPayload); | |
#endif /* ndef TOOLS_SPS_SAMPLER_H_ */ | |
diff --git a/tools/profiler/platform.cpp b/tools/profiler/platform.cpp | |
--- a/tools/profiler/platform.cpp | |
+++ b/tools/profiler/platform.cpp | |
@@ -432,18 +432,21 @@ bool is_main_thread_name(const char* aNa | |
return false; | |
} | |
return strcmp(aName, gGeckoThreadName) == 0; | |
} | |
//////////////////////////////////////////////////////////////////////// | |
// BEGIN externally visible functions | |
+extern void reflow_profiler_init(); | |
+ | |
void mozilla_sampler_init(void* stackTop) | |
{ | |
+ reflow_profiler_init(); | |
sInitCount++; | |
if (stack_key_initialized) | |
return; | |
LOG("BEGIN mozilla_sampler_init"); | |
if (!tlsPseudoStack.init() || !tlsTicker.init() || !tlsStackTop.init()) { | |
LOG("Failed to init."); | |
@@ -869,16 +872,18 @@ void mozilla_sampler_free_backtrace(Prof | |
void mozilla_sampler_tracing(const char* aCategory, const char* aInfo, | |
TracingMetadata aMetaData) | |
{ | |
mozilla_sampler_add_marker(aInfo, new ProfilerMarkerTracing(aCategory, aMetaData)); | |
} | |
void mozilla_sampler_add_marker(const char *aMarker, ProfilerMarkerPayload *aPayload) | |
{ | |
+ reflow_profiler_add_marker(aMarker); | |
+ | |
// Note that aPayload may be allocated by the caller, so we need to make sure | |
// that we free it at some point. | |
nsAutoPtr<ProfilerMarkerPayload> payload(aPayload); | |
if (!stack_key_initialized) | |
return; | |
// Don't insert a marker if we're not profiling to avoid |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment