Bug 772296 - Forward transform the overflow rect when computing dirty rects for 3d transforms. r=roc

This commit is contained in:
Matt Woodrow 2012-07-26 16:33:31 +12:00
parent 9256aef7d3
commit d83203f940

View File

@ -1778,33 +1778,24 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, this)) { nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, this)) {
dirtyRect = GetVisualOverflowRectRelativeToSelf(); dirtyRect = GetVisualOverflowRectRelativeToSelf();
} else { } else {
if (Preserves3D()) { // Trying to back-transform arbitrary rects gives us really weird results. I believe
// Preserve3D frames are difficult. Trying to back-transform arbitrary rects // this is from points that lie beyond the vanishing point. As a workaround we transform t
// gives us really weird results. I believe this is from points that lie beyond the // he overflow rect into screen space and compare in that coordinate system.
// vanishing point. As a workaround we transform the overflow rect into screen space
// and compare in that coordinate system.
// Transform the overflow rect into screen space // Transform the overflow rect into screen space
nsRect overflow = GetVisualOverflowRectRelativeToSelf(); nsRect overflow = GetVisualOverflowRectRelativeToSelf();
nsPoint offset = aBuilder->ToReferenceFrame(this); nsPoint offset = aBuilder->ToReferenceFrame(this);
overflow += offset; overflow += offset;
overflow = nsDisplayTransform::TransformRect(overflow, this, offset); overflow = nsDisplayTransform::TransformRect(overflow, this, offset);
dirtyRect += offset; dirtyRect += offset;
if (dirtyRect.Intersects(overflow)) { if (dirtyRect.Intersects(overflow)) {
dirtyRect = GetVisualOverflowRectRelativeToSelf(); // If they intersect, we take our whole overflow rect. We could instead take the intersection
} else { // and then reverse transform it but I doubt this extra work is worthwhile.
dirtyRect.SetEmpty(); dirtyRect = GetVisualOverflowRectRelativeToSelf();
}
} else { } else {
// Transform dirtyRect into our frame's local coordinate space. Note that dirtyRect.SetEmpty();
// the new value is the bounds of the old value's transformed vertices, so
// the area covered by dirtyRect may increase here.
if (!nsDisplayTransform::UntransformRect(dirtyRect, this, nsPoint(0, 0), &dirtyRect)) {
// we have a singular transform - surely we must be drawing nothing.
dirtyRect.SetEmpty();
}
} }
if (!Preserves3DChildren() && !dirtyRect.Intersects(GetVisualOverflowRectRelativeToSelf())) { if (!Preserves3DChildren() && !dirtyRect.Intersects(GetVisualOverflowRectRelativeToSelf())) {
return NS_OK; return NS_OK;