Bug 810470. Part 4: Make only background-attachment:fixed backgrounds that have propagated to the viewport use a dedicated layer, and refactor how we do that. r=mattwoodrow

--HG--
extra : rebase_source : 957eb0d5f45cd756fc121135ff6d8dff483c8bf4
This commit is contained in:
Robert O'Callahan 2012-11-09 18:14:14 -05:00
parent a198ed8fb6
commit 3c634e99a3
3 changed files with 21 additions and 57 deletions

View File

@ -1469,13 +1469,11 @@ nsDisplayBackground::nsDisplayBackground(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
uint32_t aLayer,
bool aIsThemed,
const nsStyleBackground* aBackgroundStyle,
bool aSkipFixedItemBoundsCheck)
const nsStyleBackground* aBackgroundStyle)
: nsDisplayItem(aBuilder, aFrame)
, mBackgroundStyle(aBackgroundStyle)
, mLayer(aLayer)
, mIsThemed(aIsThemed)
, mIsFixed(false)
, mIsBottommostLayer(true)
{
MOZ_COUNT_CTOR(nsDisplayBackground);
@ -1501,36 +1499,6 @@ nsDisplayBackground::nsDisplayBackground(nsDisplayListBuilder* aBuilder,
if (!mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty() &&
mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED) {
aBuilder->SetHasFixedItems();
// Check whether we should fix to viewport scrolling
if (mBackgroundStyle->mLayers[mLayer].mClip == NS_STYLE_BG_CLIP_BORDER &&
!nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius)) {
if (aSkipFixedItemBoundsCheck) {
mIsFixed = true;
} else {
nsPresContext* presContext = mFrame->PresContext();
nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame();
if (rootScrollFrame) {
bool snap;
nsRect bounds = GetBounds(aBuilder, &snap);
// This bounds check prevents an item fixing to the viewport unless it
// it encompasses the scroll-port. If a fixed background doesn't
// encompass the scroll-port, it usually means that scrolling will
// expose a new area of the fixed background and cause a lot of
// invalidation. This performs badly, and looks especially bad when
// async scrolling is being used.
// XXX A better check would be to see if the underlying frame is fixed to
// the viewport/is the viewport.
nsIScrollableFrame* scrollable = do_QueryFrame(rootScrollFrame);
nsRect scrollport(scrollable->GetScrollPortRect().TopLeft() +
aBuilder->ToReferenceFrame(rootScrollFrame),
scrollable->GetScrollPositionClampingScrollPortSize());
mIsFixed = bounds.Contains(scrollport);
}
}
}
}
}
}
@ -2072,12 +2040,6 @@ nsDisplayBackground::RenderingMightDependOnPositioningAreaSizeChange()
return false;
}
bool
nsDisplayBackground::ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
{
return mIsFixed;
}
static void CheckForBorderItem(nsDisplayItem *aItem, uint32_t& aFlags)
{
nsDisplayItem* nextItem = aItem->GetAbove();

View File

@ -1786,17 +1786,15 @@ private:
*/
class nsDisplayBackground : public nsDisplayItem {
public:
// aLayer signifies which background layer this item represents. Normally
// a background layer will only be marked as fixed if it covers the scroll-
// port of the root scroll-frame. This check can be skipped using
// aSkipFixedItemBoundsCheck.
// aIsThemed should be the value of aFrame->IsThemed.
// aBackgroundStyle should be the result of
// nsCSSRendering::FindBackground, or null if FindBackground returned false.
/**
* aLayer signifies which background layer this item represents.
* aIsThemed should be the value of aFrame->IsThemed.
* aBackgroundStyle should be the result of
* nsCSSRendering::FindBackground, or null if FindBackground returned false.
*/
nsDisplayBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
uint32_t aLayer, bool aIsThemed,
const nsStyleBackground* aBackgroundStyle,
bool aSkipFixedItemBoundsCheck = false);
const nsStyleBackground* aBackgroundStyle);
virtual ~nsDisplayBackground();
// This will create and append new items for all the layers of the
@ -1825,7 +1823,6 @@ public:
virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame) MOZ_OVERRIDE;
virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
/**
* GetBounds() returns the background painting area.
*/
@ -1883,9 +1880,6 @@ protected:
nsITheme::Transparency mThemeTransparency;
/* Used to cache mFrame->IsThemed() since it isn't a cheap call */
bool mIsThemed;
/* true if this item represents a background-attachment:fixed layer and
* should fix to the viewport. */
bool mIsFixed;
/* true if this item represents the bottom-most background layer */
bool mIsBottommostLayer;
};

View File

@ -127,10 +127,9 @@ public:
nsDisplayCanvasBackground(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
uint32_t aLayer, bool aIsThemed,
const nsStyleBackground* aBackgroundStyle)
: nsDisplayBackground(aBuilder, aFrame, aLayer,
aIsThemed, aBackgroundStyle, true)
: nsDisplayBackground(aBuilder, aFrame, aLayer, aIsThemed, aBackgroundStyle),
mExtraBackgroundColor(NS_RGBA(0,0,0,0))
{
mExtraBackgroundColor = NS_RGBA(0,0,0,0);
}
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
@ -172,7 +171,17 @@ public:
// We need to override so we don't consider border-radius.
aOutFrames->AppendElement(mFrame);
}
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
{
// Put background-attachment:fixed canvas background images in their own
// compositing layer. Since we know their background painting area can't
// change (unless the viewport size itself changes), async scrolling
// will work well.
return mBackgroundStyle &&
mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
!mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty();
}
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) MOZ_OVERRIDE;
@ -187,5 +196,4 @@ private:
nscolor mExtraBackgroundColor;
};
#endif /* nsCanvasFrame_h___ */