From d83203f9405cfa8517a122e263ddc56ad069cf20 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Thu, 26 Jul 2012 16:33:31 +1200 Subject: [PATCH] Bug 772296 - Forward transform the overflow rect when computing dirty rects for 3d transforms. r=roc --- layout/generic/nsFrame.cpp | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 37ff5743544..869e7700ce0 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -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;