Bug 622328 - Always make sure the area of the root content document is considered opaque. r=roc, a=blocking.

This commit is contained in:
Timothy Nikkel 2011-01-27 16:58:50 -06:00
parent 5e444a2dba
commit 8fbd9a0bf9
8 changed files with 213 additions and 68 deletions

View File

@ -228,7 +228,8 @@ static PRUint64 RegionArea(const nsRegion& aRegion)
void
nsDisplayListBuilder::SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
const nsRegion& aRegion)
const nsRegion& aRegion,
PRBool aForceSubtract)
{
if (aRegion.IsEmpty())
return;
@ -239,7 +240,8 @@ nsDisplayListBuilder::SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
// to its bounds either, which can be very bad (see bug 516740).
// Do let aVisibleRegion get more complex if by doing so we reduce its
// area by at least half.
if (GetAccurateVisibleRegions() || tmp.GetNumRects() <= 15 ||
if (aForceSubtract || GetAccurateVisibleRegions() ||
tmp.GetNumRects() <= 15 ||
RegionArea(tmp) <= RegionArea(*aVisibleRegion)/2) {
*aVisibleRegion = tmp;
}
@ -369,7 +371,9 @@ nsDisplayList::ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRegion r;
r.And(*aVisibleRegion, GetBounds(aBuilder));
return ComputeVisibilityForSublist(aBuilder, aVisibleRegion, r.GetBounds());
PRBool notUsed;
return ComputeVisibilityForSublist(aBuilder, aVisibleRegion,
r.GetBounds(), notUsed);
}
static nsRegion
@ -390,7 +394,8 @@ TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder,
PRBool
nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aListVisibleBounds) {
const nsRect& aListVisibleBounds,
PRBool& aContainsRootContentDocBG) {
#ifdef DEBUG
nsRegion r;
r.And(*aVisibleRegion, GetBounds(aBuilder));
@ -421,12 +426,18 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
itemVisible.And(*aVisibleRegion, bounds);
item->mVisibleRect = itemVisible.GetBounds();
if (item->ComputeVisibility(aBuilder, aVisibleRegion)) {
PRBool containsRootContentDocBG = PR_FALSE;
if (item->ComputeVisibility(aBuilder, aVisibleRegion,
containsRootContentDocBG)) {
if (containsRootContentDocBG) {
aContainsRootContentDocBG = PR_TRUE;
}
anyVisible = PR_TRUE;
PRBool transparentBackground = PR_FALSE;
nsRegion opaque = TreatAsOpaque(item, aBuilder, &transparentBackground);
// Subtract opaque item from the visible region
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque);
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque,
containsRootContentDocBG);
forceTransparentSurface = forceTransparentSurface || transparentBackground;
}
AppendToBottom(item);
@ -731,7 +742,8 @@ PRBool nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder,
itemVisible.And(*aVisibleRegion, bounds);
mVisibleRect = itemVisible.GetBounds();
if (!ComputeVisibility(aBuilder, aVisibleRegion))
PRBool notUsed;
if (!ComputeVisibility(aBuilder, aVisibleRegion, notUsed))
return PR_FALSE;
PRBool forceTransparentBackground;
@ -746,6 +758,19 @@ void nsDisplaySolidColor::Paint(nsDisplayListBuilder* aBuilder,
aCtx->FillRect(mVisibleRect);
}
PRBool
nsDisplaySolidColor::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG)
{
PRBool retval = nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aContainsRootContentDocBG);
if (retval && IsRootContentDocBackground()) {
aContainsRootContentDocBG = PR_TRUE;
}
return retval;
}
static void
RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
{
@ -895,10 +920,13 @@ nsDisplayBackground::HitTest(nsDisplayListBuilder* aBuilder,
PRBool
nsDisplayBackground::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG)
{
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion))
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aContainsRootContentDocBG)) {
return PR_FALSE;
}
// Return false if the background was propagated away from this
// frame. We don't want this display item to show up and confuse
@ -1167,9 +1195,12 @@ nsDisplayOutline::Paint(nsDisplayListBuilder* aBuilder,
PRBool
nsDisplayOutline::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion))
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aContainsRootContentDocBG)) {
return PR_FALSE;
}
const nsStyleOutline* outline = mFrame->GetStyleOutline();
nsRect borderBox(ToReferenceFrame(), mFrame->GetSize());
@ -1209,9 +1240,12 @@ nsDisplayCaret::Paint(nsDisplayListBuilder* aBuilder,
PRBool
nsDisplayBorder::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion))
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aContainsRootContentDocBG)) {
return PR_FALSE;
}
nsRect paddingRect = mFrame->GetPaddingRect() - mFrame->GetPosition() +
ToReferenceFrame();
@ -1305,9 +1339,12 @@ nsDisplayBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder) {
PRBool
nsDisplayBoxShadowOuter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion))
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aContainsRootContentDocBG)) {
return PR_FALSE;
}
// Store the actual visible region
mVisibleRegion.And(*aVisibleRegion, mVisibleRect);
@ -1348,9 +1385,12 @@ nsDisplayBoxShadowInner::Paint(nsDisplayListBuilder* aBuilder,
PRBool
nsDisplayBoxShadowInner::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion))
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aContainsRootContentDocBG)) {
return PR_FALSE;
}
// Store the actual visible region
mVisibleRegion.And(*aVisibleRegion, mVisibleRect);
@ -1386,9 +1426,11 @@ nsDisplayWrapList::GetBounds(nsDisplayListBuilder* aBuilder) {
PRBool
nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG) {
return mList.ComputeVisibilityForSublist(aBuilder, aVisibleRegion,
mVisibleRect);
mVisibleRect,
aContainsRootContentDocBG);
}
nsRegion
@ -1573,7 +1615,8 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
}
PRBool nsDisplayOpacity::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG) {
// Our children are translucent so we should not allow them to subtract
// area from aVisibleRegion. We do need to find out what is visible under
// our children in the temporary compositing buffer, because if our children
@ -1582,8 +1625,12 @@ PRBool nsDisplayOpacity::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRect bounds = GetBounds(aBuilder);
nsRegion visibleUnderChildren;
visibleUnderChildren.And(*aVisibleRegion, bounds);
// do not pass up the aContainsRootContentDocBG value because anything under
// us is not opaque
PRBool notUsed;
return
nsDisplayWrapList::ComputeVisibility(aBuilder, &visibleUnderChildren);
nsDisplayWrapList::ComputeVisibility(aBuilder, &visibleUnderChildren,
notUsed);
}
PRBool nsDisplayOpacity::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
@ -1658,7 +1705,8 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
PRBool
nsDisplayScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG)
{
nsPresContext* presContext = mFrame->PresContext();
nsIPresShell* presShell = presContext->GetPresShell();
@ -1673,13 +1721,14 @@ nsDisplayScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRect boundedRect;
boundedRect.IntersectRect(childVisibleRegion.GetBounds(), mList.GetBounds(aBuilder));
PRBool visible = mList.ComputeVisibilityForSublist(
aBuilder, &childVisibleRegion, boundedRect);
aBuilder, &childVisibleRegion, boundedRect, aContainsRootContentDocBG);
mVisibleRect = boundedRect;
return visible;
} else {
return nsDisplayOwnLayer::ComputeVisibility(aBuilder, aVisibleRegion);
return nsDisplayOwnLayer::ComputeVisibility(aBuilder, aVisibleRegion,
aContainsRootContentDocBG);
}
}
@ -1728,17 +1777,20 @@ void nsDisplayClip::Paint(nsDisplayListBuilder* aBuilder,
}
PRBool nsDisplayClip::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG) {
nsRegion clipped;
clipped.And(*aVisibleRegion, mClip);
nsRegion finalClipped(clipped);
PRBool anyVisible =
nsDisplayWrapList::ComputeVisibility(aBuilder, &finalClipped);
nsDisplayWrapList::ComputeVisibility(aBuilder, &finalClipped,
aContainsRootContentDocBG);
nsRegion removed;
removed.Sub(clipped, finalClipped);
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, removed);
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, removed,
aContainsRootContentDocBG);
return anyVisible;
}
@ -1825,12 +1877,14 @@ nsDisplayClipRoundedRect::WrapWithClone(nsDisplayListBuilder* aBuilder,
PRBool nsDisplayClipRoundedRect::ComputeVisibility(
nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG)
{
nsRegion clipped;
clipped.And(*aVisibleRegion, mClip);
return nsDisplayWrapList::ComputeVisibility(aBuilder, &clipped);
PRBool notUsed;
return nsDisplayWrapList::ComputeVisibility(aBuilder, &clipped, notUsed);
// FIXME: Remove a *conservative* opaque region from aVisibleRegion
// (like in nsDisplayClip::ComputeVisibility).
}
@ -1892,7 +1946,8 @@ void nsDisplayZoom::Paint(nsDisplayListBuilder* aBuilder,
}
PRBool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
nsRegion *aVisibleRegion)
nsRegion *aVisibleRegion,
PRBool& aContainsRootContentDocBG)
{
// Convert the passed in visible region to our appunits.
nsRegion visibleRegion =
@ -1903,7 +1958,8 @@ PRBool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
mVisibleRect.ConvertAppUnitsRoundOut(mParentAPD, mAPD);
PRBool retval =
mList.ComputeVisibilityForSublist(aBuilder, &visibleRegion,
transformedVisibleRect);
transformedVisibleRect,
aContainsRootContentDocBG);
nsRegion removed;
// removed = originalVisibleRegion - visibleRegion
@ -1912,7 +1968,8 @@ PRBool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
removed = removed.ConvertAppUnitsRoundIn(mAPD, mParentAPD);
// aVisibleRegion = aVisibleRegion - removed (modulo any simplifications
// SubtractFromVisibleRegion does)
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, removed);
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, removed,
aContainsRootContentDocBG);
return retval;
}
@ -2098,7 +2155,8 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
}
PRBool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
nsRegion *aVisibleRegion)
nsRegion *aVisibleRegion,
PRBool& aContainsRootContentDocBG)
{
/* As we do this, we need to be sure to
* untransform the visible rect, since we want everything that's painting to
@ -2379,7 +2437,8 @@ void nsDisplaySVGEffects::Paint(nsDisplayListBuilder* aBuilder,
}
PRBool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG) {
nsPoint offset = aBuilder->ToReferenceFrame(mEffectsFrame);
nsRect dirtyRect =
nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(mEffectsFrame,
@ -2391,7 +2450,8 @@ PRBool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion childrenVisible(dirtyRect);
nsRect r;
r.IntersectRect(dirtyRect, mList.GetBounds(aBuilder));
mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r);
PRBool notUsed;
mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r, notUsed);
return PR_TRUE;
}

View File

@ -327,10 +327,12 @@ public:
* Subtracts aRegion from *aVisibleRegion. We avoid letting
* aVisibleRegion become overcomplex by simplifying it if necessary ---
* unless mAccurateVisibleRegions is set, in which case we let it
* get arbitrarily complex.
* get arbitrarily complex. If aForceSubtract is true then we subtract
* aRegion even if it makes the visible region more complex.
*/
void SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
const nsRegion& aRegion);
const nsRegion& aRegion,
PRBool aForceSubtract = PR_FALSE);
/**
* Mark the frames in aFrames to be displayed if they intersect aDirtyRect
@ -705,10 +707,12 @@ public:
* nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility.
*
* @return PR_TRUE if the item is visible, PR_FALSE if no part of the item
* is visible
* is visible. aContainsRootContentDocBG is set to true if this item contains
* the background for the root content document.
*/
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG)
{ return !mVisibleRect.IsEmpty(); }
/**
@ -982,11 +986,14 @@ public:
* I.e., opaque contents of this list are subtracted from aVisibleRegion.
* @param aListVisibleBounds must be equal to the bounds of the intersection
* of aVisibleRegion and GetBounds() for this list.
* @return true if any item in the list is visible
* @return true if any item in the list is visible. aContainsRootContentDocBG
* is set to true if the list contains the background for a root content
* document.
*/
PRBool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aListVisibleBounds);
const nsRect& aListVisibleBounds,
PRBool& aContainsRootContentDocBG);
/**
* As ComputeVisibilityForSublist, but computes visibility for a root
@ -1391,7 +1398,8 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
protected:
@ -1412,8 +1420,10 @@ protected:
class nsDisplaySolidColor : public nsDisplayItem {
public:
nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
const nsRect& aBounds, nscolor aColor)
: nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor) {
const nsRect& aBounds, nscolor aColor,
PRBool aIsRootContentDocBackground = PR_FALSE)
: nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor),
mIsRootContentDocBackground(aIsRootContentDocBackground) {
NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!");
MOZ_COUNT_CTOR(nsDisplaySolidColor);
}
@ -1445,12 +1455,20 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
PRBool IsRootContentDocBackground() {
return mIsRootContentDocBackground;
}
NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
private:
nsRect mBounds;
nscolor mColor;
PRBool mTransparentBackground;
PRPackedBool mIsRootContentDocBackground;
};
/**
@ -1468,7 +1486,8 @@ public:
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
PRBool* aForceTransparentSurface = nsnull);
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
@ -1506,7 +1525,8 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
private:
@ -1530,7 +1550,8 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
private:
@ -1555,7 +1576,8 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
};
@ -1616,7 +1638,8 @@ public:
nsIFrame* aFrame);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
virtual PRBool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
NS_WARNING("This list should already have been flattened!!!");
return PR_FALSE;
@ -1700,7 +1723,8 @@ public:
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
virtual PRBool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem);
NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
};
@ -1766,7 +1790,8 @@ public:
LayerManager* aManager);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
private:
nsIFrame* mViewportFrame;
@ -1796,7 +1821,8 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
virtual PRBool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem);
NS_DISPLAY_DECL_NAME("Clip", TYPE_CLIP)
virtual PRUint32 GetPerFrameKey() { return 0; }
@ -1837,7 +1863,8 @@ public:
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
virtual PRBool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem);
NS_DISPLAY_DECL_NAME("ClipRoundedRect", TYPE_CLIP_ROUNDED_RECT)
@ -1877,7 +1904,8 @@ public:
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
NS_DISPLAY_DECL_NAME("Zoom", TYPE_ZOOM)
// Get the app units per dev pixel ratio of the child document.
@ -1911,7 +1939,8 @@ public:
}
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
virtual PRBool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem);
NS_DISPLAY_DECL_NAME("SVGEffects", TYPE_SVG_EFFECTS)
@ -1974,7 +2003,8 @@ public:
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager);
virtual PRBool ComputeVisibility(nsDisplayListBuilder *aBuilder,
nsRegion *aVisibleRegion);
nsRegion *aVisibleRegion,
PRBool& aContainsRootContentDocBG);
virtual PRBool TryMerge(nsDisplayListBuilder *aBuilder, nsDisplayItem *aItem);
/**

View File

@ -140,8 +140,8 @@ typedef struct CapturingContentInfo {
{ 0x95, 0x47, 0x85, 0x06, 0x5e, 0x02, 0xec, 0xb4 } }
#define NS_IPRESSHELL_MOZILLA_2_0_BRANCH_IID \
{ 0x5e445910, 0xfbee, 0x11df, \
{ 0x8c, 0xff, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }
{ 0x4abb9970, 0xd7ce, 0x4c02, \
{ 0x8a, 0xdb, 0x42, 0xc6, 0xbd, 0xa8, 0x95, 0xb7 } }
#define NS_IPRESSHELL_MOZILLA_2_0_BRANCH2_IID \
{ 0x5ff6fd00, 0x1ba9, 0x11e0, \
@ -180,6 +180,26 @@ public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRESSHELL_MOZILLA_2_0_BRANCH_IID)
virtual PRBool GetIsViewportOverridden() = 0;
/**
* Add a solid color item to the bottom of aList with frame aFrame and bounds
* aBounds. Checks first if this needs to be done by checking if aFrame is a
* canvas frame (if the FORCE_DRAW flag is passed then this check is skipped).
* aBackstopColor is composed behind the background color of the canvas, it is
* transparent by default. The ROOT_CONTENT_DOC_BG flag indicates that this is
* the background for the root content document.
*/
enum {
FORCE_DRAW = 0x01,
ROOT_CONTENT_DOC_BG = 0x02
};
virtual nsresult AddCanvasBackgroundColorItem2(nsDisplayListBuilder& aBuilder,
nsDisplayList& aList,
nsIFrame* aFrame,
const nsRect& aBounds,
nscolor aBackstopColor = NS_RGBA(0,0,0,0),
PRUint32 aFlags = 0) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIPresShell_MOZILLA_2_0_BRANCH,

View File

@ -954,6 +954,13 @@ public:
virtual void UpdateCanvasBackground();
virtual nsresult AddCanvasBackgroundColorItem2(nsDisplayListBuilder& aBuilder,
nsDisplayList& aList,
nsIFrame* aFrame,
const nsRect& aBounds,
nscolor aBackstopColor,
PRUint32 aFlags);
virtual nsresult AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
nsDisplayList& aList,
nsIFrame* aFrame,
@ -5850,6 +5857,18 @@ nsresult PresShell::AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
const nsRect& aBounds,
nscolor aBackstopColor,
PRBool aForceDraw)
{
return AddCanvasBackgroundColorItem2(aBuilder, aList, aFrame, aBounds,
aBackstopColor,
aForceDraw ? nsIPresShell_MOZILLA_2_0_BRANCH::FORCE_DRAW : 0);
}
nsresult PresShell::AddCanvasBackgroundColorItem2(nsDisplayListBuilder& aBuilder,
nsDisplayList& aList,
nsIFrame* aFrame,
const nsRect& aBounds,
nscolor aBackstopColor,
PRUint32 aFlags)
{
// We don't want to add an item for the canvas background color if the frame
// (sub)tree we are painting doesn't include any canvas frames. There isn't
@ -5857,8 +5876,10 @@ nsresult PresShell::AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
// (sub)tree we are painting is a canvas frame that should cover us in all
// cases (it will usually be a viewport frame when we have a canvas frame in
// the (sub)tree).
if (!aForceDraw && !nsCSSRendering::IsCanvasFrame(aFrame))
if (!(aFlags & nsIPresShell_MOZILLA_2_0_BRANCH::FORCE_DRAW) &&
!nsCSSRendering::IsCanvasFrame(aFrame)) {
return NS_OK;
}
nscolor bgcolor = NS_ComposeColors(aBackstopColor, mCanvasBackgroundColor);
if (NS_GET_A(bgcolor) == 0)
@ -5881,7 +5902,8 @@ nsresult PresShell::AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
}
return aList.AppendNewToBottom(
new (&aBuilder) nsDisplaySolidColor(&aBuilder, aFrame, aBounds, bgcolor));
new (&aBuilder) nsDisplaySolidColor(&aBuilder, aFrame, aBounds, bgcolor,
!!(aFlags & nsIPresShell_MOZILLA_2_0_BRANCH::ROOT_CONTENT_DOC_BG)));
}
static PRBool IsTransparentContainerElement(nsPresContext* aPresContext)

View File

@ -172,10 +172,16 @@ public:
}
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG)
{
return NS_GET_A(mExtraBackgroundColor) > 0 ||
nsDisplayBackground::ComputeVisibility(aBuilder, aVisibleRegion);
PRBool retval = NS_GET_A(mExtraBackgroundColor) > 0 ||
nsDisplayBackground::ComputeVisibility(aBuilder, aVisibleRegion,
aContainsRootContentDocBG);
if (retval && mFrame->PresContext()->IsRootContentDocument()) {
aContainsRootContentDocBG = PR_TRUE;
}
return retval;
}
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
PRBool* aForceTransparentSurface = nsnull)

View File

@ -1284,10 +1284,12 @@ nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder,
PRBool
nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG)
{
mVisibleRegion.And(*aVisibleRegion, GetBounds(aBuilder));
return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion);
return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aContainsRootContentDocBG);
}
nsRegion

View File

@ -321,7 +321,8 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsIRenderingContext* aCtx);
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion);
nsRegion* aVisibleRegion,
PRBool& aContainsRootContentDocBG);
NS_DISPLAY_DECL_NAME("Plugin", TYPE_PLUGIN)

View File

@ -411,9 +411,13 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// Add the canvas background color to the bottom of the list. This
// happens after we've built the list so that AddCanvasBackgroundColorItem
// can monkey with the contents if necessary.
PRUint32 flags = nsIPresShell_MOZILLA_2_0_BRANCH::FORCE_DRAW;
if (presContext->IsRootContentDocument()) {
flags |= nsIPresShell_MOZILLA_2_0_BRANCH::ROOT_CONTENT_DOC_BG;
}
rv = presShell->AddCanvasBackgroundColorItem(
*aBuilder, childItems, subdocRootFrame ? subdocRootFrame : this,
bounds, NS_RGBA(0,0,0,0), PR_TRUE);
bounds, NS_RGBA(0,0,0,0), flags);
}
}