diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 13b8b8c40d8..433858a2f02 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -1559,6 +1559,9 @@ public: virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap); virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx); NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND) + // Returns the value of GetUnderlyingFrame()->IsThemed(), but cached + bool IsThemed() { return mIsThemed; } + protected: nsRegion GetInsideClipRegion(nsPresContext* aPresContext, PRUint8 aClip, const nsRect& aRect, bool* aSnap); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 0b724cd5d67..9325c067652 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1409,16 +1409,19 @@ nsIFrame::HasBorder() const nsresult nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists, - bool aForceBackground) + bool aForceBackground, + nsDisplayBackground** aBackground) { // Here we don't try to detect background propagation. Frames that might // receive a propagated background should just set aForceBackground to // true. if (aBuilder->IsForEventDelivery() || aForceBackground || !GetStyleBackground()->IsTransparent() || GetStyleDisplay()->mAppearance) { - return aLists.BorderBackground()->AppendNewToTop(new (aBuilder) - nsDisplayBackground(aBuilder, this)); + nsDisplayBackground* bg = new (aBuilder) nsDisplayBackground(aBuilder, this); + *aBackground = bg; + return aLists.BorderBackground()->AppendNewToTop(bg); } + *aBackground = nsnull; return NS_OK; } @@ -1440,8 +1443,9 @@ nsFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder, NS_ENSURE_SUCCESS(rv, rv); } + nsDisplayBackground* bg; nsresult rv = - DisplayBackgroundUnconditional(aBuilder, aLists, aForceBackground); + DisplayBackgroundUnconditional(aBuilder, aLists, aForceBackground, &bg); NS_ENSURE_SUCCESS(rv, rv); if (hasBoxShadow) { @@ -1449,8 +1453,11 @@ nsFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder, nsDisplayBoxShadowInner(aBuilder, this)); 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) nsDisplayBorder(aBuilder, this)); NS_ENSURE_SUCCESS(rv, rv); diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 922cc91eca8..510f676bf3f 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -130,6 +130,7 @@ //---------------------------------------------------------------------- struct nsBoxLayoutMetrics; +class nsDisplayBackground; /** * 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 * for frames that might receive a propagated background via * nsCSSRendering::FindBackground + * @param aBackground *aBackground is set to the new nsDisplayBackground item, + * if one is created, otherwise null. */ nsresult DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists, - bool aForceBackground = false); + bool aForceBackground, + nsDisplayBackground** aBackground); /** * Adds display items for standard CSS borders, background and outline for * for this frame, as necessary. Checks IsVisibleForPainting and won't diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index a2e0cb5b3b4..eb4d4e1e8f7 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1281,7 +1281,8 @@ nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // in its own display item, so do that to take advantage of // opacity and visibility optimizations 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); } }