Bug 1088417 - DecomposeIntoNoRepeatRects for D3D11. - r=nical
authorJeff Gilbert <jgilbert@mozilla.com>
Thu, 23 Oct 2014 17:08:06 -0700
changeset 212557 2aaea7a57734ed92cdf851cfbb08e973e81c2e72
parent 212556 14ec535fd1c0f29950fb1a9084f8cd3e49e7994f
child 212558 72328d61a70523e4f4154e230f2235270431366d
push id27721
push usercbook@mozilla.com
push dateTue, 28 Oct 2014 14:55:05 +0000
treeherdermozilla-central@c0ddb1b098ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1088417
milestone36.0a1
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 1088417 - DecomposeIntoNoRepeatRects for D3D11. - r=nical
gfx/layers/Compositor.cpp
gfx/layers/Compositor.h
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/opengl/CompositorOGL.cpp
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -188,10 +188,175 @@ Compositor::DrawDiagnosticsInternal(Diag
                  aTransform);
   // bottom
   this->DrawQuad(gfx::Rect(aVisibleRect.x + lWidth, aVisibleRect.y + aVisibleRect.height-lWidth,
                            aVisibleRect.width - 2 * lWidth, lWidth),
                  aClipRect, effects, opacity,
                  aTransform);
 }
 
-} // namespace
-} // namespace
+static float
+WrapTexCoord(float v)
+{
+    // fmodf gives negative results for negative numbers;
+    // that is, fmodf(0.75, 1.0) == 0.75, but
+    // fmodf(-0.75, 1.0) == -0.75.  For the negative case,
+    // the result we need is 0.25, so we add 1.0f.
+    if (v < 0.0f) {
+        return 1.0f + fmodf(v, 1.0f);
+    }
+
+    return fmodf(v, 1.0f);
+}
+
+static void
+SetRects(size_t n,
+         decomposedRectArrayT* aLayerRects,
+         decomposedRectArrayT* aTextureRects,
+         float x0, float y0, float x1, float y1,
+         float tx0, float ty0, float tx1, float ty1,
+         bool flip_y)
+{
+  if (flip_y) {
+    std::swap(ty0, ty1);
+  }
+  (*aLayerRects)[n] = gfx::Rect(x0, y0, x1 - x0, y1 - y0);
+  (*aTextureRects)[n] = gfx::Rect(tx0, ty0, tx1 - tx0, ty1 - ty0);
+}
+
+#ifdef DEBUG
+static inline bool
+FuzzyEqual(float a, float b)
+{
+  return fabs(a - b) < 0.0001f;
+}
+#endif
+
+size_t
+DecomposeIntoNoRepeatRects(const gfx::Rect& aRect,
+                           const gfx::Rect& aTexCoordRect,
+                           decomposedRectArrayT* aLayerRects,
+                           decomposedRectArrayT* aTextureRects)
+{
+  gfx::Rect texCoordRect = aTexCoordRect;
+
+  // If the texture should be flipped, it will have negative height. Detect that
+  // here and compensate for it. We will flip each rect as we emit it.
+  bool flipped = false;
+  if (texCoordRect.height < 0) {
+    flipped = true;
+    texCoordRect.y += texCoordRect.height;
+    texCoordRect.height = -texCoordRect.height;
+  }
+
+  // Wrap the texture coordinates so they are within [0,1] and cap width/height
+  // at 1. We rely on this below.
+  texCoordRect = gfx::Rect(gfx::Point(WrapTexCoord(texCoordRect.x),
+                                      WrapTexCoord(texCoordRect.y)),
+                           gfx::Size(std::min(texCoordRect.width, 1.0f),
+                                     std::min(texCoordRect.height, 1.0f)));
+
+  NS_ASSERTION(texCoordRect.x >= 0.0f && texCoordRect.x <= 1.0f &&
+               texCoordRect.y >= 0.0f && texCoordRect.y <= 1.0f &&
+               texCoordRect.width >= 0.0f && texCoordRect.width <= 1.0f &&
+               texCoordRect.height >= 0.0f && texCoordRect.height <= 1.0f &&
+               texCoordRect.XMost() >= 0.0f && texCoordRect.XMost() <= 2.0f &&
+               texCoordRect.YMost() >= 0.0f && texCoordRect.YMost() <= 2.0f,
+               "We just wrapped the texture coordinates, didn't we?");
+
+  // Get the top left and bottom right points of the rectangle. Note that
+  // tl.x/tl.y are within [0,1] but br.x/br.y are within [0,2].
+  gfx::Point tl = texCoordRect.TopLeft();
+  gfx::Point br = texCoordRect.BottomRight();
+
+  NS_ASSERTION(tl.x >= 0.0f && tl.x <= 1.0f &&
+               tl.y >= 0.0f && tl.y <= 1.0f &&
+               br.x >= tl.x && br.x <= 2.0f &&
+               br.y >= tl.y && br.y <= 2.0f &&
+               br.x - tl.x <= 1.0f &&
+               br.y - tl.y <= 1.0f,
+               "Somehow generated invalid texture coordinates");
+
+  // Then check if we wrap in either the x or y axis.
+  bool xwrap = br.x > 1.0f;
+  bool ywrap = br.y > 1.0f;
+
+  // If xwrap is false, the texture will be sampled from tl.x .. br.x.
+  // If xwrap is true, then it will be split into tl.x .. 1.0, and
+  // 0.0 .. WrapTexCoord(br.x). Same for the Y axis. The destination
+  // rectangle is also split appropriately, according to the calculated
+  // xmid/ymid values.
+  if (!xwrap && !ywrap) {
+    SetRects(0, aLayerRects, aTextureRects,
+             aRect.x, aRect.y, aRect.XMost(), aRect.YMost(),
+             tl.x, tl.y, br.x, br.y,
+             flipped);
+    return 1;
+  }
+
+  // If we are dealing with wrapping br.x and br.y are greater than 1.0 so
+  // wrap them here as well.
+  br = gfx::Point(xwrap ? WrapTexCoord(br.x) : br.x,
+                  ywrap ? WrapTexCoord(br.y) : br.y);
+
+  // If we wrap around along the x axis, we will draw first from
+  // tl.x .. 1.0 and then from 0.0 .. br.x (which we just wrapped above).
+  // The same applies for the Y axis. The midpoints we calculate here are
+  // only valid if we actually wrap around.
+  GLfloat xmid = aRect.x + (1.0f - tl.x) / texCoordRect.width * aRect.width;
+  GLfloat ymid = aRect.y + (1.0f - tl.y) / texCoordRect.height * aRect.height;
+
+  NS_ASSERTION(!xwrap ||
+               (xmid > aRect.x &&
+                xmid < aRect.XMost() &&
+                FuzzyEqual((xmid - aRect.x) + (aRect.XMost() - xmid), aRect.width)),
+               "xmid should be within [x,XMost()] and the wrapped rect should have the same width");
+  NS_ASSERTION(!ywrap ||
+               (ymid > aRect.y &&
+                ymid < aRect.YMost() &&
+                FuzzyEqual((ymid - aRect.y) + (aRect.YMost() - ymid), aRect.height)),
+               "ymid should be within [y,YMost()] and the wrapped rect should have the same height");
+
+  if (!xwrap && ywrap) {
+    SetRects(0, aLayerRects, aTextureRects,
+             aRect.x, aRect.y, aRect.XMost(), ymid,
+             tl.x, tl.y, br.x, 1.0f,
+             flipped);
+    SetRects(1, aLayerRects, aTextureRects,
+             aRect.x, ymid, aRect.XMost(), aRect.YMost(),
+             tl.x, 0.0f, br.x, br.y,
+             flipped);
+    return 2;
+  }
+
+  if (xwrap && !ywrap) {
+    SetRects(0, aLayerRects, aTextureRects,
+             aRect.x, aRect.y, xmid, aRect.YMost(),
+             tl.x, tl.y, 1.0f, br.y,
+             flipped);
+    SetRects(1, aLayerRects, aTextureRects,
+             xmid, aRect.y, aRect.XMost(), aRect.YMost(),
+             0.0f, tl.y, br.x, br.y,
+             flipped);
+    return 2;
+  }
+
+  SetRects(0, aLayerRects, aTextureRects,
+           aRect.x, aRect.y, xmid, ymid,
+           tl.x, tl.y, 1.0f, 1.0f,
+           flipped);
+  SetRects(1, aLayerRects, aTextureRects,
+           xmid, aRect.y, aRect.XMost(), ymid,
+           0.0f, tl.y, br.x, 1.0f,
+           flipped);
+  SetRects(2, aLayerRects, aTextureRects,
+           aRect.x, ymid, xmid, aRect.YMost(),
+           tl.x, 0.0f, 1.0f, br.y,
+           flipped);
+  SetRects(3, aLayerRects, aTextureRects,
+           xmid, ymid, aRect.XMost(), aRect.YMost(),
+           0.0f, 0.0f, br.x, br.y,
+           flipped);
+  return 4;
+}
+
+} // namespace layers
+} // namespace mozilla
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -535,12 +535,19 @@ protected:
   RefPtr<gfx::DrawTarget> mTarget;
   nsIntRect mTargetBounds;
 
 private:
   static LayersBackend sBackend;
 
 };
 
+// Returns the number of rects. (Up to 4)
+typedef gfx::Rect decomposedRectArrayT[4];
+size_t DecomposeIntoNoRepeatRects(const gfx::Rect& aRect,
+                                  const gfx::Rect& aTexCoordRect,
+                                  decomposedRectArrayT* aLayerRects,
+                                  decomposedRectArrayT* aTextureRects);
+
 } // namespace layers
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_COMPOSITOR_H */
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -569,17 +569,16 @@ CompositorD3D11::DrawQuad(const gfx::Rec
                           gfx::Float aOpacity,
                           const gfx::Matrix4x4& aTransform)
 {
   MOZ_ASSERT(mCurrentRT, "No render target");
   memcpy(&mVSConstants.layerTransform, &aTransform._11, 64);
   IntPoint origin = mCurrentRT->GetOrigin();
   mVSConstants.renderTargetOffset[0] = origin.x;
   mVSConstants.renderTargetOffset[1] = origin.y;
-  mVSConstants.layerQuad = aRect;
 
   mPSConstants.layerOpacity[0] = aOpacity;
 
   bool restoreBlendMode = false;
 
   MaskType maskType = MaskType::MaskNone;
 
   if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) {
@@ -622,16 +621,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
   scissor.left = aClipRect.x;
   scissor.right = aClipRect.XMost();
   scissor.top = aClipRect.y;
   scissor.bottom = aClipRect.YMost();
   mContext->RSSetScissorRects(1, &scissor);
   mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
   mContext->VSSetShader(mAttachments->mVSQuadShader[maskType], nullptr, 0);
 
+  const Rect* pTexCoordRect = nullptr;
 
   switch (aEffectChain.mPrimaryEffect->mType) {
   case EffectTypes::SOLID_COLOR: {
       SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, SurfaceFormat::UNKNOWN);
 
       Color color =
         static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get())->mColor;
       mPSConstants.layerColor[0] = color.r * color.a * aOpacity;
@@ -641,17 +641,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
     }
     break;
   case EffectTypes::RGB:
   case EffectTypes::RENDER_TARGET:
     {
       TexturedEffect* texturedEffect =
         static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
 
-      mVSConstants.textureCoords = texturedEffect->mTextureCoords;
+      pTexCoordRect = &texturedEffect->mTextureCoords;
 
       TextureSourceD3D11* source = texturedEffect->mTexture->AsSourceD3D11();
 
       if (!source) {
         NS_WARNING("Missing texture source!");
         return;
       }
 
@@ -677,17 +677,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
     }
     break;
   case EffectTypes::YCBCR: {
       EffectYCbCr* ycbcrEffect =
         static_cast<EffectYCbCr*>(aEffectChain.mPrimaryEffect.get());
 
       SetSamplerForFilter(Filter::LINEAR);
 
-      mVSConstants.textureCoords = ycbcrEffect->mTextureCoords;
+      pTexCoordRect = &ycbcrEffect->mTextureCoords;
 
       const int Y = 0, Cb = 1, Cr = 2;
       TextureSource* source = ycbcrEffect->mTexture;
 
       if (!source) {
         NS_WARNING("No texture to composite");
         return;
       }
@@ -744,17 +744,18 @@ CompositorD3D11::DrawQuad(const gfx::Rec
         NS_WARNING("Missing texture source(s)!");
         return;
       }
 
       SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, effectComponentAlpha->mOnWhite->GetFormat());
 
       SetSamplerForFilter(effectComponentAlpha->mFilter);
 
-      mVSConstants.textureCoords = effectComponentAlpha->mTextureCoords;
+      pTexCoordRect = &effectComponentAlpha->mTextureCoords;
+
       RefPtr<ID3D11ShaderResourceView> views[2];
 
       HRESULT hr;
 
       hr = mDevice->CreateShaderResourceView(sourceOnBlack->GetD3D11Texture(), nullptr, byRef(views[0]));
       if (Failed(hr)) {
         return;
       }
@@ -769,22 +770,44 @@ CompositorD3D11::DrawQuad(const gfx::Rec
       mContext->OMSetBlendState(mAttachments->mComponentBlendState, sBlendFactor, 0xFFFFFFFF);
       restoreBlendMode = true;
     }
     break;
   default:
     NS_WARNING("Unknown shader type");
     return;
   }
-  if (!UpdateConstantBuffers()) {
-    NS_WARNING("Failed to update shader constant buffers");
-    return;
+
+  if (pTexCoordRect) {
+    Rect layerRects[4];
+    Rect textureRects[4];
+    size_t rects = DecomposeIntoNoRepeatRects(aRect,
+                                              *pTexCoordRect,
+                                              &layerRects,
+                                              &textureRects);
+    for (size_t i = 0; i < rects; i++) {
+      mVSConstants.layerQuad = layerRects[i];
+      mVSConstants.textureCoords = textureRects[i];
+
+      if (!UpdateConstantBuffers()) {
+        NS_WARNING("Failed to update shader constant buffers");
+        break;
+      }
+      mContext->Draw(4, 0);
+    }
+  } else {
+    mVSConstants.layerQuad = aRect;
+
+    if (!UpdateConstantBuffers()) {
+      NS_WARNING("Failed to update shader constant buffers");
+    } else {
+      mContext->Draw(4, 0);
+    }
   }
 
-  mContext->Draw(4, 0);
   if (restoreBlendMode) {
     mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF);
   }
 }
 
 void
 CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
                             const Rect* aClipRectIn,
@@ -855,17 +878,17 @@ CompositorD3D11::EndFrame()
   EnsureSize();
   if (oldSize == mSize) {
     mSwapChain->Present(0, mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0);
     mDisableSequenceForNextFrame = false;
     if (mTarget) {
       PaintToTarget();
     }
   }
-  
+
   mCurrentRT = nullptr;
 }
 
 void
 CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize)
 {
   D3D11_VIEWPORT viewport;
   viewport.MaxDepth = 1.0f;
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -378,199 +378,34 @@ CompositorOGL::Initialize()
       msg += NS_LITERAL_STRING("TEXTURE_RECTANGLE");
     console->LogStringMessage(msg.get());
   }
 
   reporter.SetSuccessful();
   return true;
 }
 
-static GLfloat
-WrapTexCoord(GLfloat v)
-{
-    // fmodf gives negative results for negative numbers;
-    // that is, fmodf(0.75, 1.0) == 0.75, but
-    // fmodf(-0.75, 1.0) == -0.75.  For the negative case,
-    // the result we need is 0.25, so we add 1.0f.
-    if (v < 0.0f) {
-        return 1.0f + fmodf(v, 1.0f);
-    }
-
-    return fmodf(v, 1.0f);
-}
-
-static void
-SetRects(int n,
-         Rect* aLayerRects,
-         Rect* aTextureRects,
-         GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
-         GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
-         bool flip_y /* = false */)
-{
-  if (flip_y) {
-    std::swap(ty0, ty1);
-  }
-  aLayerRects[n] = Rect(x0, y0, x1 - x0, y1 - y0);
-  aTextureRects[n] = Rect(tx0, ty0, tx1 - tx0, ty1 - ty0);
-}
-
-#ifdef DEBUG
-static inline bool
-FuzzyEqual(float a, float b)
-{
-  return fabs(a - b) < 0.0001f;
-}
-#endif
-
-static int
-DecomposeIntoNoRepeatRects(const Rect& aRect,
-                           const Rect& aTexCoordRect,
-                           Rect* aLayerRects,
-                           Rect* aTextureRects)
-{
-  Rect texCoordRect = aTexCoordRect;
-
-  // If the texture should be flipped, it will have negative height. Detect that
-  // here and compensate for it. We will flip each rect as we emit it.
-  bool flipped = false;
-  if (texCoordRect.height < 0) {
-    flipped = true;
-    texCoordRect.y += texCoordRect.height;
-    texCoordRect.height = -texCoordRect.height;
-  }
-
-  // Wrap the texture coordinates so they are within [0,1] and cap width/height
-  // at 1. We rely on this below.
-  texCoordRect = Rect(Point(WrapTexCoord(texCoordRect.x),
-                            WrapTexCoord(texCoordRect.y)),
-                      Size(std::min(texCoordRect.width, 1.0f),
-                           std::min(texCoordRect.height, 1.0f)));
-
-  NS_ASSERTION(texCoordRect.x >= 0.0f && texCoordRect.x <= 1.0f &&
-               texCoordRect.y >= 0.0f && texCoordRect.y <= 1.0f &&
-               texCoordRect.width >= 0.0f && texCoordRect.width <= 1.0f &&
-               texCoordRect.height >= 0.0f && texCoordRect.height <= 1.0f &&
-               texCoordRect.XMost() >= 0.0f && texCoordRect.XMost() <= 2.0f &&
-               texCoordRect.YMost() >= 0.0f && texCoordRect.YMost() <= 2.0f,
-               "We just wrapped the texture coordinates, didn't we?");
-
-  // Get the top left and bottom right points of the rectangle. Note that
-  // tl.x/tl.y are within [0,1] but br.x/br.y are within [0,2].
-  Point tl = texCoordRect.TopLeft();
-  Point br = texCoordRect.BottomRight();
-
-  NS_ASSERTION(tl.x >= 0.0f && tl.x <= 1.0f &&
-               tl.y >= 0.0f && tl.y <= 1.0f &&
-               br.x >= tl.x && br.x <= 2.0f &&
-               br.y >= tl.y && br.y <= 2.0f &&
-               br.x - tl.x <= 1.0f &&
-               br.y - tl.y <= 1.0f,
-               "Somehow generated invalid texture coordinates");
-
-  // Then check if we wrap in either the x or y axis.
-  bool xwrap = br.x > 1.0f;
-  bool ywrap = br.y > 1.0f;
-
-  // If xwrap is false, the texture will be sampled from tl.x .. br.x.
-  // If xwrap is true, then it will be split into tl.x .. 1.0, and
-  // 0.0 .. WrapTexCoord(br.x). Same for the Y axis. The destination
-  // rectangle is also split appropriately, according to the calculated
-  // xmid/ymid values.
-  if (!xwrap && !ywrap) {
-    SetRects(0, aLayerRects, aTextureRects,
-             aRect.x, aRect.y, aRect.XMost(), aRect.YMost(),
-             tl.x, tl.y, br.x, br.y,
-             flipped);
-    return 1;
-  }
-
-  // If we are dealing with wrapping br.x and br.y are greater than 1.0 so
-  // wrap them here as well.
-  br = Point(xwrap ? WrapTexCoord(br.x) : br.x,
-             ywrap ? WrapTexCoord(br.y) : br.y);
-
-  // If we wrap around along the x axis, we will draw first from
-  // tl.x .. 1.0 and then from 0.0 .. br.x (which we just wrapped above).
-  // The same applies for the Y axis. The midpoints we calculate here are
-  // only valid if we actually wrap around.
-  GLfloat xmid = aRect.x + (1.0f - tl.x) / texCoordRect.width * aRect.width;
-  GLfloat ymid = aRect.y + (1.0f - tl.y) / texCoordRect.height * aRect.height;
-
-  NS_ASSERTION(!xwrap ||
-               (xmid > aRect.x &&
-                xmid < aRect.XMost() &&
-                FuzzyEqual((xmid - aRect.x) + (aRect.XMost() - xmid), aRect.width)),
-               "xmid should be within [x,XMost()] and the wrapped rect should have the same width");
-  NS_ASSERTION(!ywrap ||
-               (ymid > aRect.y &&
-                ymid < aRect.YMost() &&
-                FuzzyEqual((ymid - aRect.y) + (aRect.YMost() - ymid), aRect.height)),
-               "ymid should be within [y,YMost()] and the wrapped rect should have the same height");
-
-  if (!xwrap && ywrap) {
-    SetRects(0, aLayerRects, aTextureRects,
-             aRect.x, aRect.y, aRect.XMost(), ymid,
-             tl.x, tl.y, br.x, 1.0f,
-             flipped);
-    SetRects(1, aLayerRects, aTextureRects,
-             aRect.x, ymid, aRect.XMost(), aRect.YMost(),
-             tl.x, 0.0f, br.x, br.y,
-             flipped);
-    return 2;
-  }
-
-  if (xwrap && !ywrap) {
-    SetRects(0, aLayerRects, aTextureRects,
-             aRect.x, aRect.y, xmid, aRect.YMost(),
-             tl.x, tl.y, 1.0f, br.y,
-             flipped);
-    SetRects(1, aLayerRects, aTextureRects,
-             xmid, aRect.y, aRect.XMost(), aRect.YMost(),
-             0.0f, tl.y, br.x, br.y,
-             flipped);
-    return 2;
-  }
-
-  SetRects(0, aLayerRects, aTextureRects,
-           aRect.x, aRect.y, xmid, ymid,
-           tl.x, tl.y, 1.0f, 1.0f,
-           flipped);
-  SetRects(1, aLayerRects, aTextureRects,
-           xmid, aRect.y, aRect.XMost(), ymid,
-           0.0f, tl.y, br.x, 1.0f,
-           flipped);
-  SetRects(2, aLayerRects, aTextureRects,
-           aRect.x, ymid, xmid, aRect.YMost(),
-           tl.x, 0.0f, 1.0f, br.y,
-           flipped);
-  SetRects(3, aLayerRects, aTextureRects,
-           xmid, ymid, aRect.XMost(), aRect.YMost(),
-           0.0f, 0.0f, br.x, br.y,
-           flipped);
-  return 4;
-}
-
 // |aRect| is the rectangle we want to draw to. We will draw it with
 // up to 4 draw commands if necessary to avoid wrapping.
 // |aTexCoordRect| is the rectangle from the texture that we want to
 // draw using the given program.
 // |aTexture| is the texture we are drawing. Its actual size can be
 // larger than the rectangle given by |texCoordRect|.
 void
 CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
                                               const Rect& aRect,
                                               const Rect& aTexCoordRect,
                                               TextureSource *aTexture)
 {
   Rect layerRects[4];
   Rect textureRects[4];
-  int rects = DecomposeIntoNoRepeatRects(aRect,
-                                         aTexCoordRect,
-                                         layerRects,
-                                         textureRects);
+  size_t rects = DecomposeIntoNoRepeatRects(aRect,
+                                            aTexCoordRect,
+                                            &layerRects,
+                                            &textureRects);
   BindAndDrawQuads(aProg, rects, layerRects, textureRects);
 }
 
 void
 CompositorOGL::PrepareViewport(const gfx::IntSize& aSize)
 {
   // Set the viewport correctly.
   mGLContext->fViewport(0, 0, aSize.width, aSize.height);