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)) {
dirtyRect = GetVisualOverflowRectRelativeToSelf();
} else {
if (Preserves3D()) {
// Preserve3D frames are difficult. Trying to back-transform arbitrary rects
// gives us really weird results. I believe this is from points that lie beyond the
// vanishing point. As a workaround we transform the overflow rect into screen space
// and compare in that coordinate system.
// Trying to back-transform arbitrary rects gives us really weird results. I believe
// this is from points that lie beyond the vanishing point. As a workaround we transform t
// he overflow rect into screen space and compare in that coordinate system.
// Transform the overflow rect into screen space
nsRect overflow = GetVisualOverflowRectRelativeToSelf();
nsPoint offset = aBuilder->ToReferenceFrame(this);
overflow += offset;
overflow = nsDisplayTransform::TransformRect(overflow, this, offset);
// Transform the overflow rect into screen space
nsRect overflow = GetVisualOverflowRectRelativeToSelf();
nsPoint offset = aBuilder->ToReferenceFrame(this);
overflow += offset;
overflow = nsDisplayTransform::TransformRect(overflow, this, offset);
dirtyRect += offset;
dirtyRect += offset;
if (dirtyRect.Intersects(overflow)) {
dirtyRect = GetVisualOverflowRectRelativeToSelf();
} else {
dirtyRect.SetEmpty();
}
if (dirtyRect.Intersects(overflow)) {
// If they intersect, we take our whole overflow rect. We could instead take the intersection
// and then reverse transform it but I doubt this extra work is worthwhile.
dirtyRect = GetVisualOverflowRectRelativeToSelf();
} else {
// Transform dirtyRect into our frame's local coordinate space. Note that
// 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();
}
dirtyRect.SetEmpty();
}
if (!Preserves3DChildren() && !dirtyRect.Intersects(GetVisualOverflowRectRelativeToSelf())) {
return NS_OK;