Bug 647560. Clean up MarkLeafLayersHidden and make it set the hidden state on container layers. r=tnikkel

Instead of doing tricks with the cliprect to prevent layer content from adding to aOpaqueRegion, pass an explicit flag to control that.
Mark a ContainerLayer hidden if all its children are hidden. This will need to be changed if/when we add layer properties
that result in a ContainerLayer drawing content even if it has no children.
This commit is contained in:
Robert O'Callahan 2011-05-18 23:24:52 +12:00
parent 211b76b78d
commit f243295b25

View File

@ -1267,22 +1267,22 @@ TransformIntRect(nsIntRect& aRect, const gfxMatrix& aMatrix,
* @param aOpaqueRegion the opaque region covering aLayer, in the
* root coordinate system.
*/
enum {
ALLOW_OPAQUE = 0x01,
};
static void
MarkLeafLayersHidden(Layer* aLayer, const nsIntRect& aClipRect,
const nsIntRect& aDirtyRect,
nsIntRegion& aOpaqueRegion)
MarkLayersHidden(Layer* aLayer, const nsIntRect& aClipRect,
const nsIntRect& aDirtyRect,
nsIntRegion& aOpaqueRegion,
PRUint32 aFlags)
{
Layer* child = aLayer->GetLastChild();
BasicImplData* data = ToData(aLayer);
data->SetHidden(PR_FALSE);
nsIntRect newClipRect(aClipRect);
PRUint32 newFlags = aFlags;
// Allow aLayer or aLayer's descendants to cover underlying layers
// only if it's opaque. GetEffectiveOpacity() could be used instead,
// but it does extra passes from descendant to ancestor.
// only if it's opaque.
if (aLayer->GetOpacity() != 1.0f) {
newClipRect.SetRect(0, 0, 0, 0);
newFlags &= ~ALLOW_OPAQUE;
}
{
@ -1305,9 +1305,12 @@ MarkLeafLayersHidden(Layer* aLayer, const nsIntRect& aClipRect,
}
}
BasicImplData* data = ToData(aLayer);
Layer* child = aLayer->GetLastChild();
if (!child) {
gfxMatrix transform;
if (!aLayer->GetEffectiveTransform().Is2D(&transform)) {
data->SetHidden(PR_FALSE);
return;
}
@ -1319,24 +1322,26 @@ MarkLeafLayersHidden(Layer* aLayer, const nsIntRect& aClipRect,
// Allow aLayer to cover underlying layers only if aLayer's
// content is opaque
if (!(aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE)) {
return;
}
if ((aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
(newFlags & ALLOW_OPAQUE)) {
nsIntRegionRectIterator it(region);
while (const nsIntRect* sr = it.Next()) {
r = *sr;
TransformIntRect(r, transform, ToInsideIntRect);
nsIntRegionRectIterator it(region);
while (const nsIntRect* sr = it.Next()) {
r = *sr;
TransformIntRect(r, transform, ToInsideIntRect);
r.IntersectRect(r, newClipRect);
if (!r.IsEmpty()) {
r.IntersectRect(r, newClipRect);
aOpaqueRegion.Or(aOpaqueRegion, r);
}
}
} else {
PRBool allHidden = PR_TRUE;
for (; child; child = child->GetPrevSibling()) {
MarkLeafLayersHidden(child, newClipRect, aDirtyRect, aOpaqueRegion);
MarkLayersHidden(child, newClipRect, aDirtyRect, aOpaqueRegion, newFlags);
if (!ToData(child)->IsHidden()) {
allHidden = PR_FALSE;
}
}
data->SetHidden(allHidden);
}
}
@ -1378,7 +1383,7 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
clipRect = ToOutsideIntRect(mTarget->GetClipExtents());
}
// Need to do this before we call MarkLeafLayersHidden,
// Need to do this before we call MarkLayersHidden,
// which depends on correct effective transforms
mSnapEffectiveTransforms =
!(mTarget->GetFlags() & gfxContext::FLAG_DISABLE_SNAPPING);
@ -1388,7 +1393,7 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
// which uses information about which layers are going to be drawn.
if (IsRetained()) {
nsIntRegion region;
MarkLeafLayersHidden(mRoot, clipRect, clipRect, region);
MarkLayersHidden(mRoot, clipRect, clipRect, region, ALLOW_OPAQUE);
}
nsRefPtr<gfxContext> finalTarget = mTarget;