Bug 735898. Part 3: In DisplayBorderBackgroundOutline, when we have created an nsDisplayBackground item and it's themed, don't bother checking to create an nsDisplayBorder item. r=mattwoodrow

It turns out that calling HasBorder() is especially expensive for themed frames since we call into the theme engine to compute the border, so avoiding it is a nice win.
This commit is contained in:
Robert O'Callahan 2012-04-11 16:49:34 +12:00
Родитель 20226ccafe
Коммит 8b347a5213
4 изменённых файлов: 23 добавлений и 8 удалений

Просмотреть файл

@ -1559,6 +1559,9 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND) NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
// Returns the value of GetUnderlyingFrame()->IsThemed(), but cached
bool IsThemed() { return mIsThemed; }
protected: protected:
nsRegion GetInsideClipRegion(nsPresContext* aPresContext, PRUint8 aClip, nsRegion GetInsideClipRegion(nsPresContext* aPresContext, PRUint8 aClip,
const nsRect& aRect, bool* aSnap); const nsRect& aRect, bool* aSnap);

Просмотреть файл

@ -1409,16 +1409,19 @@ nsIFrame::HasBorder() const
nsresult nsresult
nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder, nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists, const nsDisplayListSet& aLists,
bool aForceBackground) bool aForceBackground,
nsDisplayBackground** aBackground)
{ {
// Here we don't try to detect background propagation. Frames that might // Here we don't try to detect background propagation. Frames that might
// receive a propagated background should just set aForceBackground to // receive a propagated background should just set aForceBackground to
// true. // true.
if (aBuilder->IsForEventDelivery() || aForceBackground || if (aBuilder->IsForEventDelivery() || aForceBackground ||
!GetStyleBackground()->IsTransparent() || GetStyleDisplay()->mAppearance) { !GetStyleBackground()->IsTransparent() || GetStyleDisplay()->mAppearance) {
return aLists.BorderBackground()->AppendNewToTop(new (aBuilder) nsDisplayBackground* bg = new (aBuilder) nsDisplayBackground(aBuilder, this);
nsDisplayBackground(aBuilder, this)); *aBackground = bg;
return aLists.BorderBackground()->AppendNewToTop(bg);
} }
*aBackground = nsnull;
return NS_OK; return NS_OK;
} }
@ -1440,8 +1443,9 @@ nsFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
nsDisplayBackground* bg;
nsresult rv = nsresult rv =
DisplayBackgroundUnconditional(aBuilder, aLists, aForceBackground); DisplayBackgroundUnconditional(aBuilder, aLists, aForceBackground, &bg);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (hasBoxShadow) { if (hasBoxShadow) {
@ -1450,7 +1454,10 @@ nsFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
if (HasBorder()) { // If there's a themed background, we should not create a border item.
// It won't be rendered. Calling HasBorder() for themed frames is expensive
// too (calls into native theme code), so avoiding it is valuable.
if ((!bg || !bg->IsThemed()) && HasBorder()) {
rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder) rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
nsDisplayBorder(aBuilder, this)); nsDisplayBorder(aBuilder, this));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -130,6 +130,7 @@
//---------------------------------------------------------------------- //----------------------------------------------------------------------
struct nsBoxLayoutMetrics; struct nsBoxLayoutMetrics;
class nsDisplayBackground;
/** /**
* Implementation of a simple frame that's not splittable and has no * Implementation of a simple frame that's not splittable and has no
@ -509,10 +510,13 @@ public:
* background style appears to have no background --- this is useful * background style appears to have no background --- this is useful
* for frames that might receive a propagated background via * for frames that might receive a propagated background via
* nsCSSRendering::FindBackground * nsCSSRendering::FindBackground
* @param aBackground *aBackground is set to the new nsDisplayBackground item,
* if one is created, otherwise null.
*/ */
nsresult DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder, nsresult DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists, const nsDisplayListSet& aLists,
bool aForceBackground = false); bool aForceBackground,
nsDisplayBackground** aBackground);
/** /**
* Adds display items for standard CSS borders, background and outline for * Adds display items for standard CSS borders, background and outline for
* for this frame, as necessary. Checks IsVisibleForPainting and won't * for this frame, as necessary. Checks IsVisibleForPainting and won't

Просмотреть файл

@ -1281,7 +1281,8 @@ nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// in its own display item, so do that to take advantage of // in its own display item, so do that to take advantage of
// opacity and visibility optimizations // opacity and visibility optimizations
if (deflate == nsMargin(0, 0, 0, 0)) { if (deflate == nsMargin(0, 0, 0, 0)) {
nsresult rv = DisplayBackgroundUnconditional(aBuilder, aLists, false); nsDisplayBackground* bg;
nsresult rv = DisplayBackgroundUnconditional(aBuilder, aLists, false, &bg);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
} }