Backed out changeset a5ec817740f0. a=orange
authorJustin Lebar <justin.lebar@gmail.com>
Mon, 29 Nov 2010 09:08:24 -0800
changeset 58332 510e6e2ae3fd9c0b3e0e3d032426a311272f0d2f
parent 58315 a5ec817740f0047309cb284a9b145e240719c81d
child 58333 d5bdb25b51a03dd2af3b2ac7e54895c84463e45c
push id17248
push userjlebar@mozilla.com
push dateMon, 29 Nov 2010 17:47:34 +0000
treeherdermozilla-central@d5bdb25b51a0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersorange
milestone2.0b8pre
backs outa5ec817740f0047309cb284a9b145e240719c81d
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
Backed out changeset a5ec817740f0. a=orange
content/svg/content/src/nsSVGFilters.cpp
gfx/layers/Layers.cpp
gfx/layers/d3d10/ContainerLayerD3D10.cpp
gfx/layers/d3d9/ContainerLayerD3D9.cpp
gfx/layers/opengl/ContainerLayerOGL.cpp
gfx/thebes/Makefile.in
gfx/thebes/gfxBlur.cpp
gfx/thebes/gfxBlur.h
gfx/thebes/gfxMatrix.h
gfx/thebes/gfxThebesUtils.cpp
gfx/thebes/gfxThebesUtils.h
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
layout/base/FrameLayerBuilder.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/svg/base/src/nsSVGFilterFrame.cpp
layout/svg/base/src/nsSVGFilterInstance.cpp
layout/svg/base/src/nsSVGUtils.cpp
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -62,17 +62,16 @@
 #include "nsImageLoadingContent.h"
 #include "imgIContainer.h"
 #include "nsNetUtil.h"
 #include "nsSVGPreserveAspectRatio.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsSVGFilterElement.h"
 #include "nsSVGString.h"
 #include "nsSVGEffects.h"
-#include "gfxUtils.h"
 
 #if defined(XP_WIN) 
 // Prevent Windows redefining LoadImage
 #ifndef WINCE
 #undef LoadImage
 #endif
 #endif
 
@@ -170,17 +169,17 @@ nsSVGFE::SetupScalingFilter(nsSVGFilterI
   // overflow) or zero size (large kernel unit)
   if (overflow || scaledSize.width <= 0 || scaledSize.height <= 0)
     return result;
 
   gfxRect r(aDataRect.x, aDataRect.y, aDataRect.width, aDataRect.height);
   r.Scale(gfxFloat(scaledSize.width)/aTarget->mImage->Width(),
           gfxFloat(scaledSize.height)/aTarget->mImage->Height());
   r.RoundOut();
-  if (!gfxUtils::GfxRectToIntRect(r, &result.mDataRect))
+  if (NS_FAILED(nsLayoutUtils::GfxRectToIntRect(r, &result.mDataRect)))
     return result;
   
 #ifdef DEBUG_tor
   fprintf(stderr, "scaled size %d %d\n", scaledSize.width, scaledSize.height);
 #endif
   result.mSource = new gfxImageSurface(scaledSize,
                                        gfxASurface::ImageFormatARGB32);
   result.mTarget = new gfxImageSurface(scaledSize,
@@ -2959,19 +2958,19 @@ nsSVGFETileElement::Filter(nsSVGFilterIn
           rect.x, rect.y, rect.width, rect.height);
 #endif
   // XXX This code depends on the surface rect containing the filter
   // primitive subregion. ComputeTargetBBox, ComputeNeededSourceBBoxes
   // and ComputeChangeBBox are all pessimal, so that will normally be OK,
   // but nothing clips mFilterPrimitiveSubregion so this should be changed.
 
   nsIntRect tile;
-  PRBool res = gfxUtils::GfxRectToIntRect(aSources[0]->mFilterPrimitiveSubregion, &tile);
-
-  NS_ENSURE_TRUE(res, NS_ERROR_FAILURE); // asserts on failure (not 
+  nsresult res = nsLayoutUtils::GfxRectToIntRect(aSources[0]->mFilterPrimitiveSubregion, &tile);
+
+  NS_ENSURE_SUCCESS(res, res); // asserts on failure (not 
   if (tile.IsEmpty())
     return NS_OK;
 
   const nsIntRect &surfaceRect = instance->GetSurfaceRect();
   if (!tile.Intersects(surfaceRect)) {
     // nothing to draw
     return NS_OK;
   }
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -328,19 +328,17 @@ ContainerLayer::DefaultComputeEffectiveT
   mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), &residual);
 
   PRBool useIntermediateSurface;
   float opacity = GetEffectiveOpacity();
   if (opacity != 1.0f && HasMultipleChildren()) {
     useIntermediateSurface = PR_TRUE;
   } else {
     useIntermediateSurface = PR_FALSE;
-    gfxMatrix contTransform;
-    if (!mEffectiveTransform.Is2D(&contTransform) ||
-        !contTransform.PreservesAxisAlignedRectangles()) {
+    if (!mEffectiveTransform.IsIdentity()) {
       for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) {
         const nsIntRect *clipRect = child->GetEffectiveClipRect();
         /* We can't (easily) forward our transform to children with a non-empty clip
          * rect since it would need to be adjusted for the transform.
          * TODO: This is easily solvable for translation/scaling transforms.
          */
         if (clipRect && !clipRect->IsEmpty() && !child->GetVisibleRegion().IsEmpty()) {
           useIntermediateSurface = PR_TRUE;
--- a/gfx/layers/d3d10/ContainerLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ContainerLayerD3D10.cpp
@@ -32,18 +32,16 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ContainerLayerD3D10.h"
 #include "nsAlgorithm.h"
-#include "gfxUtils.h"
-#include "nsRect.h"
 
 namespace mozilla {
 namespace layers {
 
 ContainerLayerD3D10::ContainerLayerD3D10(LayerManagerD3D10 *aManager)
   : ContainerLayer(aManager, NULL)
   , LayerD3D10(aManager)
 {
@@ -140,25 +138,16 @@ LayerD3D10*
 ContainerLayerD3D10::GetFirstChildD3D10()
 {
   if (!mFirstChild) {
     return nsnull;
   }
   return static_cast<LayerD3D10*>(mFirstChild->ImplData());
 }
 
-static inline LayerD3D10*
-GetNextSiblingD3D10(LayerD3D10* aLayer)
-{
-   Layer* layer = aLayer->GetLayer()->GetNextSibling();
-   return layer ? static_cast<LayerD3D10*>(layer->
-                                           ImplData())
-                : nsnull;
-}
-
 void
 ContainerLayerD3D10::RenderLayer()
 {
   float renderTargetOffset[] = { 0, 0 };
 
   nsIntRect visibleRect = mVisibleRegion.GetBounds();
   float opacity = GetEffectiveOpacity();
   PRBool useIntermediate = UseIntermediateSurface();
@@ -166,17 +155,16 @@ ContainerLayerD3D10::RenderLayer()
   nsRefPtr<ID3D10RenderTargetView> previousRTView;
   nsRefPtr<ID3D10Texture2D> renderTexture;
   nsRefPtr<ID3D10RenderTargetView> rtView;
   float previousRenderTargetOffset[2];
   nsIntSize previousViewportSize;
 
   gfx3DMatrix oldViewMatrix;
 
-  gfxMatrix contTransform;
   if (useIntermediate) {
     device()->OMGetRenderTargets(1, getter_AddRefs(previousRTView), NULL);
  
     D3D10_TEXTURE2D_DESC desc;
     memset(&desc, 0, sizeof(D3D10_TEXTURE2D_DESC));
     desc.ArraySize = 1;
     desc.MipLevels = 1;
     desc.Width = visibleRect.width;
@@ -199,36 +187,24 @@ ContainerLayerD3D10::RenderLayer()
 
     renderTargetOffset[0] = (float)visibleRect.x;
     renderTargetOffset[1] = (float)visibleRect.y;
     effect()->GetVariableByName("vRenderTargetOffset")->
       SetRawValue(renderTargetOffset, 0, 8);
 
     previousViewportSize = mD3DManager->GetViewport();
     mD3DManager->SetViewport(nsIntSize(visibleRect.Size()));
-  } else {
-#ifdef DEBUG
-    PRBool is2d =
-#endif
-    GetEffectiveTransform().Is2D(&contTransform);
-    NS_ASSERTION(is2d, "Transform must be 2D");
   }
 
   /*
    * Render this container's contents.
    */
-  for (LayerD3D10* layerToRender = GetFirstChildD3D10();
-       layerToRender != nsnull;
-       layerToRender = GetNextSiblingD3D10(layerToRender)) {
-
-    const nsIntRect* clipRect = layerToRender->GetLayer()->GetClipRect();
-    if ((clipRect && clipRect->IsEmpty()) ||
-        layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
-      continue;
-    }
+  LayerD3D10 *layerToRender = GetFirstChildD3D10();
+  while (layerToRender) {
+    const nsIntRect *clipRect = layerToRender->GetLayer()->GetClipRect();
 
     D3D10_RECT oldScissor;
     if (clipRect || useIntermediate) {
       UINT numRects = 1;
       device()->RSGetScissorRects(&numRects, &oldScissor);
 
       RECT r;
       if (clipRect) {
@@ -241,43 +217,29 @@ ContainerLayerD3D10::RenderLayer()
         r.left = 0;
         r.top = 0;
         r.right = visibleRect.width;
         r.bottom = visibleRect.height;
       }
 
       D3D10_RECT d3drect;
       if (!useIntermediate) {
-        if (clipRect) {
-          gfxRect cliprect(r.left, r.top, r.left + r.right, r.top + r.bottom);
-          gfxRect trScissor = contTransform.TransformBounds(cliprect);
-          trScissor.Round();
-          nsIntRect trIntScissor;
-          if (gfxUtils::GfxRectToIntRect(trScissor, &trIntScissor)) {
-            r.left = trIntScissor.x;
-            r.top = trIntScissor.y;
-            r.right = trIntScissor.XMost();
-            r.bottom = trIntScissor.YMost();
-          } else {
-            r.left = 0;
-            r.top = 0;
-            r.right = visibleRect.width;
-            r.bottom = visibleRect.height;
-            clipRect = nsnull;
-          }
-        }
         // Scissor rect should be an intersection of the old and current scissor.
         r.left = NS_MAX<PRInt32>(oldScissor.left, r.left);
         r.right = NS_MIN<PRInt32>(oldScissor.right, r.right);
         r.top = NS_MAX<PRInt32>(oldScissor.top, r.top);
         r.bottom = NS_MIN<PRInt32>(oldScissor.bottom, r.bottom);
       }
 
       if (r.left >= r.right || r.top >= r.bottom) {
         // Entire layer's clipped out, don't bother drawing.
+        Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling();
+        layerToRender = nextSibling ? static_cast<LayerD3D10*>(nextSibling->
+                                                              ImplData())
+                                    : nsnull;
         continue;
       }
 
       d3drect.left = NS_MAX<PRInt32>(r.left, 0);
       d3drect.top = NS_MAX<PRInt32>(r.top, 0);
       d3drect.bottom = r.bottom;
       d3drect.right = r.right;
 
@@ -285,16 +247,21 @@ ContainerLayerD3D10::RenderLayer()
     }
 
     // SetScissorRect
     layerToRender->RenderLayer();
 
     if (clipRect || useIntermediate) {
       device()->RSSetScissorRects(1, &oldScissor);
     }
+
+    Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling();
+    layerToRender = nextSibling ? static_cast<LayerD3D10*>(nextSibling->
+                                                          ImplData())
+                                : nsnull;
   }
 
   if (useIntermediate) {
     mD3DManager->SetViewport(previousViewportSize);
     ID3D10RenderTargetView *rtView = previousRTView;
     device()->OMSetRenderTargets(1, &rtView, NULL);
     effect()->GetVariableByName("vRenderTargetOffset")->
       SetRawValue(previousRenderTargetOffset, 0, 8);
--- a/gfx/layers/d3d9/ContainerLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ContainerLayerD3D9.cpp
@@ -31,18 +31,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ContainerLayerD3D9.h"
-#include "gfxUtils.h"
-#include "nsRect.h"
 
 namespace mozilla {
 namespace layers {
 
 ContainerLayerD3D9::ContainerLayerD3D9(LayerManagerD3D9 *aManager)
   : ContainerLayer(aManager, NULL)
   , LayerD3D9(aManager)
 {
@@ -139,39 +137,29 @@ LayerD3D9*
 ContainerLayerD3D9::GetFirstChildD3D9()
 {
   if (!mFirstChild) {
     return nsnull;
   }
   return static_cast<LayerD3D9*>(mFirstChild->ImplData());
 }
 
-static inline LayerD3D9*
-GetNextSiblingD3D9(LayerD3D9* aLayer)
-{
-   Layer* layer = aLayer->GetLayer()->GetNextSibling();
-   return layer ? static_cast<LayerD3D9*>(layer->
-                                          ImplData())
-                 : nsnull;
-}
-
 void
 ContainerLayerD3D9::RenderLayer()
 {
   nsRefPtr<IDirect3DSurface9> previousRenderTarget;
   nsRefPtr<IDirect3DTexture9> renderTexture;
   float previousRenderTargetOffset[4];
   RECT oldClipRect;
   float renderTargetOffset[] = { 0, 0, 0, 0 };
   float oldViewMatrix[4][4];
 
   nsIntRect visibleRect = mVisibleRegion.GetBounds();
   PRBool useIntermediate = UseIntermediateSurface();
 
-  gfxMatrix contTransform;
   if (useIntermediate) {
     device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget));
     device()->CreateTexture(visibleRect.width, visibleRect.height, 1,
                             D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
                             D3DPOOL_DEFAULT, getter_AddRefs(renderTexture),
                             NULL);
     nsRefPtr<IDirect3DSurface9> renderSurface;
     renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface));
@@ -189,37 +177,24 @@ ContainerLayerD3D9::RenderLayer()
      */
     viewMatrix._11 = 2.0f / visibleRect.width;
     viewMatrix._22 = -2.0f / visibleRect.height;
     viewMatrix._41 = -1.0f;
     viewMatrix._42 = 1.0f;
 
     device()->GetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4);
     device()->SetVertexShaderConstantF(CBmProjection, &viewMatrix._11, 4);
-  } else {
-#ifdef DEBUG
-    PRBool is2d =
-#endif
-    GetEffectiveTransform().Is2D(&contTransform);
-    NS_ASSERTION(is2d, "Transform must be 2D");
   }
 
   /*
    * Render this container's contents.
    */
-  for (LayerD3D9* layerToRender = GetFirstChildD3D9();
-       layerToRender != nsnull;
-       layerToRender = GetNextSiblingD3D9(layerToRender)) {
-
-    const nsIntRect* clipRect = layerToRender->GetLayer()->GetClipRect();
-    if ((clipRect && clipRect->IsEmpty()) ||
-        layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
-      continue;
-    }
-
+  LayerD3D9 *layerToRender = GetFirstChildD3D9();
+  while (layerToRender) {
+    const nsIntRect *clipRect = layerToRender->GetLayer()->GetClipRect();
     if (clipRect || useIntermediate) {
       RECT r;
       device()->GetScissorRect(&oldClipRect);
       if (clipRect) {
         r.left = (LONG)(clipRect->x - renderTargetOffset[0]);
         r.top = (LONG)(clipRect->y - renderTargetOffset[1]);
         r.right = (LONG)(clipRect->x - renderTargetOffset[0] + clipRect->width);
         r.bottom = (LONG)(clipRect->y - renderTargetOffset[1] + clipRect->height);
@@ -232,35 +207,16 @@ ContainerLayerD3D9::RenderLayer()
 
       nsRefPtr<IDirect3DSurface9> renderSurface;
       device()->GetRenderTarget(0, getter_AddRefs(renderSurface));
 
       D3DSURFACE_DESC desc;
       renderSurface->GetDesc(&desc);
 
       if (!useIntermediate) {
-        // Transform clip rect
-        if (clipRect) {
-          gfxRect cliprect(r.left, r.top, r.left + r.right, r.top + r.bottom);
-          gfxRect trScissor = contTransform.TransformBounds(cliprect);
-          trScissor.Round();
-          nsIntRect trIntScissor;
-          if (gfxUtils::GfxRectToIntRect(trScissor, &trIntScissor)) {
-            r.left = trIntScissor.x;
-            r.top = trIntScissor.y;
-            r.right = trIntScissor.XMost();
-            r.bottom = trIntScissor.YMost();
-          } else {
-            r.left = 0;
-            r.top = 0;
-            r.right = visibleRect.width;
-            r.bottom = visibleRect.height;
-            clipRect = nsnull;
-          }
-        }
         // Intersect with current clip rect.
         r.left = NS_MAX<PRInt32>(oldClipRect.left, r.left);
         r.right = NS_MIN<PRInt32>(oldClipRect.right, r.right);
         r.top = NS_MAX<PRInt32>(oldClipRect.top, r.top);
         r.bottom = NS_MAX<PRInt32>(oldClipRect.bottom, r.bottom);
       } else {
         // > 0 is implied during the intersection when useIntermediate == true;
         r.left = NS_MAX<LONG>(0, r.left);
@@ -273,17 +229,20 @@ ContainerLayerD3D9::RenderLayer()
     }
 
     layerToRender->RenderLayer();
 
     if (clipRect || useIntermediate) {
       device()->SetScissorRect(&oldClipRect);
     }
 
-    continue;
+    Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling();
+    layerToRender = nextSibling ? static_cast<LayerD3D9*>(nextSibling->
+                                                          ImplData())
+                                : nsnull;
   }
 
   if (useIntermediate) {
     device()->SetRenderTarget(0, previousRenderTarget);
     device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1);
     device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4);
 
     device()->SetVertexShaderConstantF(CBvLayerQuad,
--- a/gfx/layers/opengl/ContainerLayerOGL.cpp
+++ b/gfx/layers/opengl/ContainerLayerOGL.cpp
@@ -31,17 +31,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ContainerLayerOGL.h"
-#include "gfxUtils.h"
 
 namespace mozilla {
 namespace layers {
 
 template<class Container>
 static void
 ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter)
 {
@@ -124,25 +123,16 @@ ContainerDestroy(Container* aContainer)
     while (aContainer->mFirstChild) {
       aContainer->GetFirstChildOGL()->Destroy();
       aContainer->RemoveChild(aContainer->mFirstChild);
     }
     aContainer->mDestroyed = PR_TRUE;
   }
 }
 
-static inline LayerOGL*
-GetNextSibling(LayerOGL* aLayer)
-{
-   Layer* layer = aLayer->GetLayer()->GetNextSibling();
-   return layer ? static_cast<LayerOGL*>(layer->
-                                         ImplData())
-                 : nsnull;
-}
-
 template<class Container>
 static void
 ContainerRender(Container* aContainer,
                 int aPreviousFrameBuffer,
                 const nsIntPoint& aOffset,
                 LayerManagerOGL* aManager)
 {
   /**
@@ -155,67 +145,44 @@ ContainerRender(Container* aContainer,
   nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds();
 
   nsIntRect cachedScissor = aContainer->gl()->ScissorRect();
   aContainer->gl()->PushScissorRect();
 
   float opacity = aContainer->GetEffectiveOpacity();
   const gfx3DMatrix& transform = aContainer->GetEffectiveTransform();
   bool needsFramebuffer = aContainer->UseIntermediateSurface();
-  gfxMatrix contTransform;
   if (needsFramebuffer) {
     aManager->CreateFBOWithTexture(visibleRect.width,
                                    visibleRect.height,
                                    &frameBuffer,
                                    &containerSurface);
     childOffset.x = visibleRect.x;
     childOffset.y = visibleRect.y;
 
     aContainer->gl()->PushViewportRect();
     aManager->SetupPipeline(visibleRect.width, visibleRect.height);
 
     aContainer->gl()->fScissor(0, 0, visibleRect.width, visibleRect.height);
     aContainer->gl()->fClearColor(0.0, 0.0, 0.0, 0.0);
     aContainer->gl()->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
   } else {
     frameBuffer = aPreviousFrameBuffer;
-#ifdef DEBUG
-    PRBool is2d =
-#endif
-    transform.Is2D(&contTransform);
-    NS_ASSERTION(is2d, "Transform must be 2D");
   }
 
   /**
    * Render this container's contents.
    */
-  for (LayerOGL* layerToRender = aContainer->GetFirstChildOGL();
-       layerToRender != nsnull;
-       layerToRender = GetNextSibling(layerToRender)) {
-
-    if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
-      continue;
-    }
-
+  LayerOGL *layerToRender = aContainer->GetFirstChildOGL();
+  while (layerToRender) {
     nsIntRect scissorRect(visibleRect);
 
     const nsIntRect *clipRect = layerToRender->GetLayer()->GetEffectiveClipRect();
     if (clipRect) {
-      if (clipRect->IsEmpty()) {
-        continue;
-      }
       scissorRect = *clipRect;
-      if (!needsFramebuffer) {
-        gfxRect r(scissorRect.x, scissorRect.y, scissorRect.width, scissorRect.height);
-        gfxRect trScissor = contTransform.TransformBounds(r);
-        trScissor.Round();
-        if (!gfxUtils::GfxRectToIntRect(trScissor, &scissorRect)) {
-          scissorRect = visibleRect;
-        }
-      }
     }
 
     if (needsFramebuffer) {
       scissorRect.MoveBy(- visibleRect.TopLeft());
     } else {
       if (!aPreviousFrameBuffer) {
         /**
          * glScissor coordinates are oriented with 0,0 being at the bottom left,
@@ -243,16 +210,21 @@ ContainerRender(Container* aContainer,
     } else {
       aContainer->gl()->fScissor(cachedScissor.x, 
                                  cachedScissor.y, 
                                  cachedScissor.width, 
                                  cachedScissor.height);
     }
 
     layerToRender->RenderLayer(frameBuffer, childOffset);
+
+    Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling();
+    layerToRender = nextSibling ? static_cast<LayerOGL*>(nextSibling->
+                                                         ImplData())
+                                : nsnull;
   }
 
   aContainer->gl()->PopScissorRect();
 
   if (needsFramebuffer) {
     // Unbind the current framebuffer and rebind the previous one.
     
     // Restore the viewport
--- a/gfx/thebes/Makefile.in
+++ b/gfx/thebes/Makefile.in
@@ -30,16 +30,17 @@ EXPORTS	= \
 	gfxPattern.h \
 	gfxPlatform.h \
 	gfxPoint.h \
 	gfxRect.h \
 	gfxSkipChars.h \
 	gfxTypes.h \
 	gfxTextRunCache.h \
 	gfxTextRunWordCache.h \
+	gfxThebesUtils.h \
 	gfxUtils.h \
 	gfxUserFontSet.h \
 	GLDefs.h \
 	GLContext.h \
 	GLContextSymbols.h \
 	GLContextProvider.h \
 	GLContextProviderImpl.h \
 	nsCoreAnimationSupport.h \
@@ -178,16 +179,17 @@ CPPSRCS	= \
 	gfxPath.cpp \
 	gfxPattern.cpp \
 	gfxPlatform.cpp \
 	gfxPlatformFontList.cpp \
 	gfxRect.cpp \
 	gfxSkipChars.cpp \
 	gfxTextRunCache.cpp \
 	gfxTextRunWordCache.cpp \
+	gfxThebesUtils.cpp \
 	gfxUserFontSet.cpp \
 	gfxUtils.cpp \
 	gfxUnicodeProperties.cpp \
 	gfxScriptItemizer.cpp \
 	gfxHarfBuzzShaper.cpp \
 	GLContext.cpp \
 	GLContextProviderOSMesa.cpp \
 	$(NULL)
--- a/gfx/thebes/gfxBlur.cpp
+++ b/gfx/thebes/gfxBlur.cpp
@@ -83,19 +83,18 @@ gfxAlphaBoxBlur::Init(const gfxRect& aRe
 
     if (aSkipRect) {
         // If we get passed a skip rect, we can lower the amount of
         // blurring/spreading we need to do. We convert it to nsIntRect to avoid
         // expensive int<->float conversions if we were to use gfxRect instead.
         gfxRect skipRect = *aSkipRect;
         skipRect.RoundIn();
         skipRect.Inset(aBlurRadius + aSpreadRadius);
-        gfxUtils::GfxRectToIntRect(skipRect, &mSkipRect);
-        nsIntRect shadowIntRect;
-        gfxUtils::GfxRectToIntRect(rect, &shadowIntRect);
+        mSkipRect = gfxThebesUtils::GfxRectToIntRect(skipRect);
+        nsIntRect shadowIntRect = gfxThebesUtils::GfxRectToIntRect(rect);
         mSkipRect.IntersectRect(mSkipRect, shadowIntRect);
         if (mSkipRect == shadowIntRect)
           return nsnull;
 
         mSkipRect -= shadowIntRect.TopLeft();
     } else {
         mSkipRect = nsIntRect(0, 0, 0, 0);
     }
--- a/gfx/thebes/gfxBlur.h
+++ b/gfx/thebes/gfxBlur.h
@@ -36,18 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GFX_BLUR_H
 #define GFX_BLUR_H
 
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "gfxTypes.h"
-#include "gfxUtils.h"
-#include "nsRect.h"
+#include "gfxThebesUtils.h"
 
 /**
  * Implementation of a triple box blur approximation of a Gaussian blur.
  *
  * A Gaussian blur is good for blurring because, when done independently
  * in the horizontal and vertical directions, it matches the result that
  * would be obtained using a different (rotated) set of axes.  A triple
  * box blur is a very close approximation of a Gaussian.
--- a/gfx/thebes/gfxMatrix.h
+++ b/gfx/thebes/gfxMatrix.h
@@ -260,24 +260,15 @@ public:
 
     /**
      * Snap matrix components that are close to integers
      * to integers. In particular, components that are integral when
      * converted to single precision are set to those integers.
      */
     void NudgeToIntegers(void);
 
-    /**
-     * Returns true if matrix is multiple of 90 degrees rotation with flipping,
-     * scaling and translation.
-     */
-    PRBool PreservesAxisAlignedRectangles() const {
-        return ((FuzzyEqual(xx, 0.0) && FuzzyEqual(yy, 0.0))
-            || (FuzzyEqual(xy, 0.0) && FuzzyEqual(yx, 0.0)));
-    }
-
 private:
     static PRBool FuzzyEqual(gfxFloat aV1, gfxFloat aV2) {
         return fabs(aV2 - aV1) < 1e-6;
     }
 };
 
 #endif /* GFX_MATRIX_H */
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/gfxThebesUtils.cpp
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is gfx thebes code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Michael Ventnor <m.ventnor@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "gfxThebesUtils.h"
+
+// Converts a gfxRect to an nsIntRect for speed
+nsIntRect
+gfxThebesUtils::GfxRectToIntRect(const gfxRect& aIn)
+{
+  nsIntRect result(PRInt32(aIn.X()), PRInt32(aIn.Y()),
+                   PRInt32(aIn.Width()), PRInt32(aIn.Height()));
+  NS_ASSERTION(gfxRect(result.x, result.y, result.width, result.height) == aIn,
+               "The given gfxRect isn't rounded properly!");
+  return result;
+}
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/gfxThebesUtils.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is gfx thebes code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Michael Ventnor <m.ventnor@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "gfxRect.h"
+#include "nsRect.h"
+
+#ifndef GFX_THEBES_UTILS_H
+#define GFX_THEBES_UTILS_H
+
+class THEBES_API gfxThebesUtils
+{
+public:
+    /**
+     * Converts a gfxRect into nsIntRect for speed reasons.
+     */
+    static nsIntRect GfxRectToIntRect(const gfxRect& aIn);
+};
+
+#endif /* GFX_THEBES_UTILS_H */
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -453,17 +453,8 @@ gfxUtils::ClipToRegion(gfxContext* aCont
   ClipToRegionInternal(aContext, aRegion, PR_FALSE);
 }
 
 /*static*/ void
 gfxUtils::ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion)
 {
   ClipToRegionInternal(aContext, aRegion, PR_TRUE);
 }
-
-PRBool
-gfxUtils::GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut)
-{
-  *aOut = nsIntRect(PRInt32(aIn.X()), PRInt32(aIn.Y()),
-  PRInt32(aIn.Width()), PRInt32(aIn.Height()));
-  return gfxRect(aOut->x, aOut->y, aOut->width, aOut->height) == aIn;
-}
-
--- a/gfx/thebes/gfxUtils.h
+++ b/gfx/thebes/gfxUtils.h
@@ -39,17 +39,16 @@
 #define GFX_UTILS_H
 
 #include "gfxTypes.h"
 #include "gfxPattern.h"
 #include "gfxImageSurface.h"
 
 class gfxDrawable;
 class nsIntRegion;
-class nsIntRect;
 
 class THEBES_API gfxUtils {
 public:
     /*
      * Premultiply or Unpremultiply aSourceSurface, writing the result
      * to aDestSurface or back into aSourceSurface if aDestSurface is null.
      *
      * If aDestSurface is given, it must have identical format, dimensions, and
@@ -95,18 +94,11 @@ public:
      * Clip aContext to the region aRegion, snapping the rectangles.
      */
     static void ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion);
 
     /*
      * Convert image format to depth value
      */
     static int ImageFormatToDepth(gfxASurface::gfxImageFormat aFormat);
-
-    /**
-     * If aIn can be represented exactly using an nsIntRect (i.e.
-     * integer-aligned edges and coordinates in the PRInt32 range) then we
-     * set aOut to that rectangle, otherwise return failure.
-    */
-    static PRBool GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut);
 };
 
 #endif
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -40,17 +40,16 @@
 #include "nsDisplayList.h"
 #include "nsPresContext.h"
 #include "nsLayoutUtils.h"
 #include "Layers.h"
 #include "BasicLayers.h"
 #include "nsSubDocumentFrame.h"
 #include "nsCSSRendering.h"
 #include "nsCSSFrameConstructor.h"
-#include "gfxUtils.h"
 
 #ifdef DEBUG
 #include <stdio.h>
 #endif
 
 using namespace mozilla::layers;
 
 namespace mozilla {
@@ -743,17 +742,17 @@ SetVisibleRectForLayer(Layer* aLayer, co
   if (aLayer->GetTransform().Is2D(&transform)) {
     // if 'transform' is not invertible, then nothing will be displayed
     // for the layer, so it doesn't really matter what we do here
     transform.Invert();
     gfxRect layerVisible = transform.TransformBounds(
         gfxRect(aRect.x, aRect.y, aRect.width, aRect.height));
     layerVisible.RoundOut();
     nsIntRect visibleRect;
-    if (!gfxUtils::GfxRectToIntRect(layerVisible, &visibleRect)) {
+    if (NS_FAILED(nsLayoutUtils::GfxRectToIntRect(layerVisible, &visibleRect))) {
       visibleRect = nsIntRect(0, 0, 0, 0);
       NS_WARNING("Visible rect transformed out of bounds");
     }
     aLayer->SetVisibleRegion(visibleRect);
   } else {
     NS_ERROR("Only 2D transformations currently supported");
   }
 }
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -980,16 +980,25 @@ nsLayoutUtils::InvertTransformsToRoot(ns
   /* If the ctm is singular, hand back (0, 0) as a sentinel. */
   if (ctm.IsSingular())
     return nsPoint(0, 0);
 
   /* Otherwise, invert the CTM and use it to transform the point. */
   return MatrixTransformPoint(aPoint, ctm.Invert(), aFrame->PresContext()->AppUnitsPerDevPixel());
 }
 
+nsresult
+nsLayoutUtils::GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut)
+{
+  *aOut = nsIntRect(PRInt32(aIn.X()), PRInt32(aIn.Y()),
+                    PRInt32(aIn.Width()), PRInt32(aIn.Height()));
+  return gfxRect(aOut->x, aOut->y, aOut->width, aOut->height) == aIn
+    ? NS_OK : NS_ERROR_FAILURE;
+}
+
 static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) {
   nsIntPoint offset(0, 0);
   nsIWidget* parent = aWidget->GetParent();
   while (parent) {
     nsIntRect bounds;
     aWidget->GetBounds(bounds);
     offset += bounds.TopLeft();
     aWidget = parent;
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -507,16 +507,23 @@ public:
    * app space that contains the graphics rectangle, rounding out as necessary.
    *
    * @param aRect The graphics rect to round outward.
    * @param aFactor The number of app units per graphics unit.
    * @return The smallest rectangle in app space that contains aRect.
    */
   static nsRect RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor);
 
+  /**
+   * If aIn can be represented exactly using an nsIntRect (i.e.
+   * integer-aligned edges and coordinates in the PRInt32 range) then we
+   * set aOut to that rectangle, otherwise return failure.
+   */
+  static nsresult GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut);
+
   enum {
     PAINT_IN_TRANSFORM = 0x01,
     PAINT_SYNC_DECODE_IMAGES = 0x02,
     PAINT_WIDGET_LAYERS = 0x04,
     PAINT_IGNORE_SUPPRESSION = 0x08,
     PAINT_DOCUMENT_RELATIVE = 0x10,
     PAINT_HIDE_CARET = 0x20,
     PAINT_ALL_CONTINUATIONS = 0x40,
--- a/layout/svg/base/src/nsSVGFilterFrame.cpp
+++ b/layout/svg/base/src/nsSVGFilterFrame.cpp
@@ -42,17 +42,16 @@
 #include "nsSVGFilterElement.h"
 #include "nsSVGFilters.h"
 #include "gfxASurface.h"
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "nsSVGFilterPaintCallback.h"
 #include "nsSVGRect.h"
 #include "nsSVGFilterInstance.h"
-#include "gfxUtils.h"
 
 nsIFrame*
 NS_NewSVGFilterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsSVGFilterFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGFilterFrame)
@@ -63,17 +62,17 @@ MapDeviceRectToFilterSpace(const gfxMatr
                            const nsIntRect* aDeviceRect)
 {
   nsIntRect rect(0, 0, aFilterSize.width, aFilterSize.height);
   if (aDeviceRect) {
     gfxRect r = aMatrix.TransformBounds(gfxRect(aDeviceRect->x, aDeviceRect->y,
                                                 aDeviceRect->width, aDeviceRect->height));
     r.RoundOut();
     nsIntRect intRect;
-    if (gfxUtils::GfxRectToIntRect(r, &intRect)) {
+    if (NS_SUCCEEDED(nsLayoutUtils::GfxRectToIntRect(r, &intRect))) {
       rect = intRect;
     }
   }
   return rect;
 }
 
 class NS_STACK_CLASS nsAutoFilterInstance {
 public:
@@ -232,18 +231,19 @@ nsSVGFilterFrame::FilterPaint(nsSVGRende
 static nsresult
 TransformFilterSpaceToDeviceSpace(nsSVGFilterInstance *aInstance, nsIntRect *aRect)
 {
   gfxMatrix m = aInstance->GetFilterSpaceToDeviceSpaceTransform();
   gfxRect r(aRect->x, aRect->y, aRect->width, aRect->height);
   r = m.TransformBounds(r);
   r.RoundOut();
   nsIntRect deviceRect;
-  if (!gfxUtils::GfxRectToIntRect(r, &deviceRect))
-    return NS_ERROR_FAILURE;
+  nsresult rv = nsLayoutUtils::GfxRectToIntRect(r, &deviceRect);
+  if (NS_FAILED(rv))
+    return rv;
   *aRect = deviceRect;
   return NS_OK;
 }
 
 nsIntRect
 nsSVGFilterFrame::GetInvalidationBBox(nsIFrame *aTarget, const nsIntRect& aRect)
 {
   nsAutoFilterInstance instance(aTarget, this, nsnull, nsnull, &aRect, nsnull);
--- a/layout/svg/base/src/nsSVGFilterInstance.cpp
+++ b/layout/svg/base/src/nsSVGFilterInstance.cpp
@@ -36,17 +36,16 @@
 
 #include "nsSVGFilterInstance.h"
 #include "nsSVGUtils.h"
 #include "nsIDOMSVGUnitTypes.h"
 #include "gfxPlatform.h"
 #include "nsSVGFilterPaintCallback.h"
 #include "nsSVGFilterElement.h"
 #include "nsLayoutUtils.h"
-#include "gfxUtils.h"
 
 static double Square(double aX)
 {
   return aX*aX;
 }
 
 float
 nsSVGFilterInstance::GetPrimitiveLength(nsSVGLength2 *aLength) const
@@ -161,17 +160,17 @@ nsSVGFilterInstance::BuildSources()
   gfxRect filterRegion = gfxRect(0, 0, mFilterSpaceSize.width, mFilterSpaceSize.height);
   mSourceColorAlpha.mImage.mFilterPrimitiveSubregion = filterRegion;
   mSourceAlpha.mImage.mFilterPrimitiveSubregion = filterRegion;
 
   nsIntRect sourceBoundsInt;
   gfxRect sourceBounds = UserSpaceToFilterSpace(mTargetBBox);
   sourceBounds.RoundOut();
   // Detect possible float->int overflow
-  if (!gfxUtils::GfxRectToIntRect(sourceBounds, &sourceBoundsInt))
+  if (NS_FAILED(nsLayoutUtils::GfxRectToIntRect(sourceBounds, &sourceBoundsInt)))
     return NS_ERROR_FAILURE;
 
   mSourceColorAlpha.mResultBoundingBox = sourceBoundsInt;
   mSourceAlpha.mResultBoundingBox = sourceBoundsInt;
   return NS_OK;
 }
 
 nsresult
@@ -352,18 +351,19 @@ nsSVGFilterInstance::BuildSourceImages()
     gfxMatrix userSpaceToFilterSpace = GetUserSpaceToFilterSpaceTransform();
 
     gfxRect r(neededRect.x, neededRect.y, neededRect.width, neededRect.height);
     gfxMatrix m = userSpaceToFilterSpace;
     m.Invert();
     r = m.TransformBounds(r);
     r.RoundOut();
     nsIntRect dirty;
-    if (!gfxUtils::GfxRectToIntRect(r, &dirty))
-      return NS_ERROR_FAILURE;
+    nsresult rv = nsLayoutUtils::GfxRectToIntRect(r, &dirty);
+    if (NS_FAILED(rv))
+      return rv;
 
     // SVG graphics paint to device space, so we need to set an initial device
     // space to filter space transform on the gfxContext that SourceGraphic
     // and SourceAlpha will paint to.
     //
     // (In theory it would be better to minimize error by having filtered SVG
     // graphics temporarily paint to user space when painting the sources and
     // only set a user space to filter space transform on the gfxContext
--- a/layout/svg/base/src/nsSVGUtils.cpp
+++ b/layout/svg/base/src/nsSVGUtils.cpp
@@ -87,17 +87,16 @@
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGFilterPaintCallback.h"
 #include "nsSVGGeometryFrame.h"
 #include "nsComputedDOMStyle.h"
 #include "nsSVGPathGeometryFrame.h"
 #include "prdtoa.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDOMSVGNumberList.h"
-#include "gfxUtils.h"
 
 using namespace mozilla::dom;
 
 gfxASurface *nsSVGUtils::gThebesComputationalSurface = nsnull;
 
 // c = n / 255
 // (c <= 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1 / 2.4) - 0.055) * 255 + 0.5
 static const PRUint8 glinearRGBTosRGBMap[256] = {
@@ -633,17 +632,17 @@ nsSVGUtils::FindFilterInvalidation(nsIFr
       nsSVGDisplayContainerFrame* innerSvgParent = do_QueryFrame(viewportFrame->GetParent());
       float x, y, width, height;
       static_cast<nsSVGSVGElement*>(innerSvg->GetContent())->
         GetAnimatedLengthValues(&x, &y, &width, &height, nsnull);
       gfxRect bounds = nsSVGUtils::GetCanvasTM(innerSvgParent).
                          TransformBounds(gfxRect(x, y, width, height));
       bounds.RoundOut();
       nsIntRect r;
-      if (gfxUtils::GfxRectToIntRect(bounds, &r)) {
+      if (NS_SUCCEEDED(nsLayoutUtils::GfxRectToIntRect(bounds, &r))) {
         rect = r;
       } else {
         NS_NOTREACHED("Not going to invalidate the correct area");
       }
       aFrame = viewportFrame;
     }
     aFrame = aFrame->GetParent();
   }
@@ -952,17 +951,17 @@ public:
     if (aDirtyRect) {
       gfxMatrix userToDeviceSpace = nsSVGUtils::GetCanvasTM(aTarget);
       if (userToDeviceSpace.IsSingular()) {
         return;
       }
       gfxRect dirtyBounds = userToDeviceSpace.TransformBounds(
         gfxRect(aDirtyRect->x, aDirtyRect->y, aDirtyRect->width, aDirtyRect->height));
       dirtyBounds.RoundOut();
-      if (gfxUtils::GfxRectToIntRect(dirtyBounds, &tmpDirtyRect)) {
+      if (NS_SUCCEEDED(nsLayoutUtils::GfxRectToIntRect(dirtyBounds, &tmpDirtyRect))) {
         dirtyRect = &tmpDirtyRect;
       }
     }
 
     svgChildFrame->PaintSVG(aContext, dirtyRect);
   }
 };