Bug 622818. Don't clip fixed backgrounds to the viewport if we are inside a transform. r=roc a=blocking
authorTimothy Nikkel <tnikkel@gmail.com>
Tue, 08 Feb 2011 13:29:28 -0600
changeset 62160 ffe65159d361f313c2f7dbf83e498acf112b0edd
parent 62159 78778779f3706333863ffcbe44ff2b35a57fe5ab
child 62161 5ed6c4935486d1aee52f9edcd96043b0fab86fb8
push id18624
push usertnikkel@gmail.com
push dateTue, 08 Feb 2011 19:29:44 +0000
treeherdermozilla-central@ffe65159d361 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, blocking
bugs622818
milestone2.0b12pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 622818. Don't clip fixed backgrounds to the viewport if we are inside a transform. r=roc a=blocking
layout/base/nsCSSRendering.cpp
layout/reftests/backgrounds/fixed-bg-with-transform-outside-viewport-1.html
layout/reftests/backgrounds/fixed-bg-with-transform-outside-viewport-ref.html
layout/reftests/backgrounds/reftest.list
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2441,16 +2441,27 @@ ScaleDimension(const nsStyleBackground::
       NS_ABORT_IF_FALSE(PR_FALSE, "bad aDimension.mType");
       return 1.0f;
     case nsStyleBackground::Size::eAuto:
       NS_ABORT_IF_FALSE(PR_FALSE, "aDimension.mType == eAuto isn't handled");
       return 1.0f;
   }
 }
 
+static inline PRBool
+IsTransformed(nsIFrame* aForFrame, nsIFrame* aTopFrame)
+{
+  for (nsIFrame* f = aForFrame; f != aTopFrame; f = f->GetParent()) {
+    if (f->IsTransformed()) {
+      return PR_TRUE;
+    }
+  }
+  return PR_FALSE;
+}
+
 static BackgroundLayerState
 PrepareBackgroundLayer(nsPresContext* aPresContext,
                        nsIFrame* aForFrame,
                        PRUint32 aFlags,
                        const nsRect& aBorderArea,
                        const nsRect& aBGClipRect,
                        const nsStyleBackground& aBackground,
                        const nsStyleBackground::Layer& aLayer)
@@ -2611,23 +2622,25 @@ PrepareBackgroundLayer(nsPresContext* aP
       nsIScrollableFrame* scrollableFrame =
         aPresContext->PresShell()->GetRootScrollFrameAsScrollable();
       if (scrollableFrame) {
         nsMargin scrollbars = scrollableFrame->GetActualScrollbarSizes();
         bgPositioningArea.Deflate(scrollbars);
       }
     }
 
-    if (aFlags & nsCSSRendering::PAINTBG_TO_WINDOW) {
+    if (aFlags & nsCSSRendering::PAINTBG_TO_WINDOW &&
+        !IsTransformed(aForFrame, topFrame)) {
       // Clip background-attachment:fixed backgrounds to the viewport, if we're
-      // painting to the screen. This avoids triggering tiling in common cases,
-      // without affecting output since drawing is always clipped to the viewport
-      // when we draw to the screen. (But it's not a pure optimization since it
-      // can affect the values of pixels at the edge of the viewport ---
-      // whether they're sampled from a putative "next tile" or not.)
+      // painting to the screen and not transformed. This avoids triggering
+      // tiling in common cases, without affecting output since drawing is
+      // always clipped to the viewport when we draw to the screen. (But it's
+      // not a pure optimization since it can affect the values of pixels at the
+      // edge of the viewport --- whether they're sampled from a putative "next
+      // tile" or not.)
       bgClipRect.IntersectRect(bgClipRect, bgPositioningArea + aBorderArea.TopLeft());
     }
   }
 
   nsSize imageSize = state.mImageRenderer.ComputeSize(bgPositioningArea.Size());
   if (imageSize.width <= 0 || imageSize.height <= 0)
     return state;
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/backgrounds/fixed-bg-with-transform-outside-viewport-1.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<style>
+	#thediv {
+		position: absolute; left: 0; top: 100%;
+		-moz-transform: rotate(-90deg);
+		-moz-transform-origin: 0 0;
+    background: red url("blue-32x32.png") 0 0 fixed repeat; width: 200px; height: 200px;
+  }
+</style>
+</head>
+<body>
+<div id="thediv"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/backgrounds/fixed-bg-with-transform-outside-viewport-ref.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<style>
+	#thediv {
+		position: absolute; left: 0; top: 100%;
+		-moz-transform: rotate(-90deg);
+		-moz-transform-origin: 0 0;
+    background: blue 0 0 fixed repeat; width: 200px; height: 200px;
+  }
+</style>
+</head>
+<body>
+<div id="thediv"></div>
+</body>
+</html>
--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -103,10 +103,12 @@ fails == background-size-zoom-repeat.htm
 
 # background-size affects images without intrinsic dimensions specially; we may
 # not support such image formats right now, but when we do, we want
 # background-size to be changed accordingly, and hopefully these tests should
 # start failing when we do.
 fails == background-size-no-intrinsic-width-image.html background-size-no-intrinsic-width-image-ref.html
 fails == background-size-no-intrinsic-height-image.html background-size-no-intrinsic-height-image-ref.html
 
+== fixed-bg-with-transform-outside-viewport-1.html fixed-bg-with-transform-outside-viewport-ref.html
+
 HTTP == root-background-1.html root-background-ref.html
 HTTP != root-background-1.html about:blank