Bug 932888. Remove thebes paths from ThebesLayerBuffer (part 1). r=mattwoodrow
authorNicholas Cameron <ncameron@mozilla.com>
Wed, 27 Nov 2013 13:29:45 +1300
changeset 157690 95f3ce0b7c96b20c28bf68dadb79cd467b6deef8
parent 157689 c9ff42335f8a7859bdcce58c6b7d56a0227ed1fa
child 157691 c38b37bee01545f02c4fc7117e55d46ff13b4933
push id25719
push usercbook@mozilla.com
push dateWed, 27 Nov 2013 09:57:23 +0000
treeherdermozilla-central@2e3d89ed5dc7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs932888
milestone28.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 932888. Remove thebes paths from ThebesLayerBuffer (part 1). r=mattwoodrow
dom/plugins/ipc/PluginInstanceParent.cpp
gfx/layers/ThebesLayerBuffer.cpp
gfx/layers/ThebesLayerBuffer.h
gfx/layers/client/ContentClient.cpp
gfx/layers/client/ContentClient.h
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -21,16 +21,17 @@
 #include "gfxSharedImageSurface.h"
 #include "nsNPAPIPluginInstance.h"
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
 #endif
 #include "gfxContext.h"
 #include "gfxColor.h"
 #include "gfxUtils.h"
+#include "mozilla/gfx/2D.h"
 #include "Layers.h"
 #include "SharedTextureImage.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 
 #ifdef XP_MACOSX
 #include "MacIOSurfaceImage.h"
 #endif
@@ -809,23 +810,25 @@ PluginInstanceParent::BeginUpdateBackgro
         NS_ABORT_IF_FALSE(aRect.TopLeft() == nsIntPoint(0, 0),
                           "Expecting rect for whole frame");
         if (!CreateBackground(aRect.Size())) {
             *aCtx = nullptr;
             return NS_OK;
         }
     }
 
+    gfxIntSize sz = mBackground->GetSize();
 #ifdef DEBUG
-    gfxIntSize sz = mBackground->GetSize();
     NS_ABORT_IF_FALSE(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect),
                       "Update outside of background area");
 #endif
 
-    nsRefPtr<gfxContext> ctx = new gfxContext(mBackground);
+    RefPtr<gfx::DrawTarget> dt = gfxPlatform::GetPlatform()->
+      CreateDrawTargetForSurface(mBackground, gfx::IntSize(sz.width, sz.height));
+    nsRefPtr<gfxContext> ctx = new gfxContext(dt);
     *aCtx = ctx.forget().get();
 
     return NS_OK;
 }
 
 nsresult
 PluginInstanceParent::EndUpdateBackground(gfxContext* aCtx,
                                           const nsIntRect& aRect)
--- a/gfx/layers/ThebesLayerBuffer.cpp
+++ b/gfx/layers/ThebesLayerBuffer.cpp
@@ -77,116 +77,16 @@ RotatedBuffer::GetSourceRectangle(XSide 
  * the right side of the buffer (which is drawn on the left side of
  * mBufferRect).
  * @param aYSide TOP means we draw from the top side of the buffer (which
  * is drawn on the bottom side of mBufferRect). BOTTOM means we draw from
  * the bottom side of the buffer (which is drawn on the top side of
  * mBufferRect).
  */
 void
-RotatedBuffer::DrawBufferQuadrant(gfxContext* aTarget,
-                                  XSide aXSide, YSide aYSide,
-                                  ContextSource aSource,
-                                  float aOpacity,
-                                  gfxASurface* aMask,
-                                  const gfxMatrix* aMaskTransform) const
-{
-  // The rectangle that we're going to fill. Basically we're going to
-  // render the buffer at mBufferRect + quadrantTranslation to get the
-  // pixels in the right place, but we're only going to paint within
-  // mBufferRect
-  nsIntRect quadrantRect = GetQuadrantRectangle(aXSide, aYSide);
-  nsIntRect fillRect;
-  if (!fillRect.IntersectRect(mBufferRect, quadrantRect)) {
-    return;
-  }
-
-  nsRefPtr<gfxASurface> source;
-
-  if (aSource == BUFFER_BLACK) {
-    if (mBuffer) {
-      source = mBuffer;
-    } else if (mDTBuffer) {
-      source = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDTBuffer);
-    } else {
-      NS_WARNING("Can't draw a RotatedBuffer without any buffer!");
-      return;
-    }
-  } else {
-    MOZ_ASSERT(aSource == BUFFER_WHITE);
-    if (mBufferOnWhite) {
-      source = mBufferOnWhite;
-    } else if (mDTBufferOnWhite) {
-      source = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDTBufferOnWhite);
-    } else {
-      NS_WARNING("Can't draw a RotatedBuffer without any buffer!");
-      return;
-    }
-  }
-
-
-  aTarget->NewPath();
-  aTarget->Rectangle(gfxRect(fillRect.x, fillRect.y,
-                             fillRect.width, fillRect.height),
-                     true);
-
-  gfxPoint quadrantTranslation(quadrantRect.x, quadrantRect.y);
-  nsRefPtr<gfxPattern> pattern = new gfxPattern(source);
-
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-  GraphicsFilter filter = GraphicsFilter::FILTER_NEAREST;
-  pattern->SetFilter(filter);
-#endif
-
-  gfxContextMatrixAutoSaveRestore saveMatrix(aTarget);
-
-  // Transform from user -> buffer space.
-  gfxMatrix transform;
-  transform.Translate(-quadrantTranslation);
-
-  pattern->SetMatrix(transform);
-  aTarget->SetPattern(pattern);
-
-  if (aMask) {
-    if (aOpacity == 1.0) {
-      aTarget->SetMatrix(*aMaskTransform);
-      aTarget->Mask(aMask);
-    } else {
-      aTarget->PushGroup(GFX_CONTENT_COLOR_ALPHA);
-      aTarget->Paint(aOpacity);
-      aTarget->PopGroupToSource();
-      aTarget->SetMatrix(*aMaskTransform);
-      aTarget->Mask(aMask);
-    }
-  } else {
-    if (aOpacity == 1.0) {
-      aTarget->Fill();
-    } else {
-      aTarget->Save();
-      aTarget->Clip();
-      aTarget->Paint(aOpacity);
-      aTarget->Restore();
-    }
-  }
-
-  nsRefPtr<gfxASurface> surf = aTarget->CurrentSurface();
-  surf->Flush();
-}
-
-/**
- * @param aXSide LEFT means we draw from the left side of the buffer (which
- * is drawn on the right side of mBufferRect). RIGHT means we draw from
- * the right side of the buffer (which is drawn on the left side of
- * mBufferRect).
- * @param aYSide TOP means we draw from the top side of the buffer (which
- * is drawn on the bottom side of mBufferRect). BOTTOM means we draw from
- * the bottom side of the buffer (which is drawn on the top side of
- * mBufferRect).
- */
-void
 RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
                                   XSide aXSide, YSide aYSide,
                                   ContextSource aSource,
                                   float aOpacity,
                                   gfx::CompositionOp aOperator,
                                   gfx::SourceSurface* aMask,
                                   const gfx::Matrix* aMaskTransform) const
 {
@@ -260,31 +160,16 @@ RotatedBuffer::DrawBufferQuadrant(gfx::D
   if (aOperator == OP_SOURCE) {
     aTarget->PopClip();
   }
 
   aTarget->Flush();
 }
 
 void
-RotatedBuffer::DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource,
-                                      float aOpacity,
-                                      gfxASurface* aMask,
-                                      const gfxMatrix* aMaskTransform) const
-{
-  PROFILER_LABEL("RotatedBuffer", "DrawBufferWithRotation");
-  // Draw four quadrants. We could use REPEAT_, but it's probably better
-  // not to, to be performance-safe.
-  DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aMask, aMaskTransform);
-  DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aMask, aMaskTransform);
-  DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
-  DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
-}
-
-void
 RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aSource,
                                       float aOpacity,
                                       gfx::CompositionOp aOperator,
                                       gfx::SourceSurface* aMask,
                                       const gfx::Matrix* aMaskTransform) const
 {
   PROFILER_LABEL("RotatedBuffer", "DrawBufferWithRotation");
   // See above, in Azure Repeat should always be a safe, even faster choice
@@ -311,133 +196,77 @@ ThebesLayerBuffer::DrawTo(ThebesLayer* a
                           float aOpacity,
                           gfxASurface* aMask,
                           const gfxMatrix* aMaskTransform)
 {
   if (!EnsureBuffer()) {
     return;
   }
 
-  if (aTarget->IsCairo()) {
-    aTarget->Save();
-    // If the entire buffer is valid, we can just draw the whole thing,
-    // no need to clip. But we'll still clip if clipping is cheap ---
-    // that might let us copy a smaller region of the buffer.
-    // Also clip to the visible region if we're told to.
-    if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
-        (ToData(aLayer)->GetClipToVisibleRegion() &&
-         !aLayer->GetVisibleRegion().Contains(BufferRect())) ||
-        IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
-      // We don't want to draw invalid stuff, so we need to clip. Might as
-      // well clip to the smallest area possible --- the visible region.
-      // Bug 599189 if there is a non-integer-translation transform in aTarget,
-      // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
-      // and may cause gray lines.
-      gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion());
-    }
-
-    DrawBufferWithRotation(aTarget, BUFFER_BLACK, aOpacity, aMask, aMaskTransform);
-    aTarget->Restore();
-  } else {
-    RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
-    bool clipped = false;
+  RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
+  MOZ_ASSERT(dt, "Did you pass a non-Azure gfxContext?");
+  bool clipped = false;
 
-    // If the entire buffer is valid, we can just draw the whole thing,
-    // no need to clip. But we'll still clip if clipping is cheap ---
-    // that might let us copy a smaller region of the buffer.
-    // Also clip to the visible region if we're told to.
-    if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
-        (ToData(aLayer)->GetClipToVisibleRegion() &&
-         !aLayer->GetVisibleRegion().Contains(BufferRect())) ||
-        IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
-      // We don't want to draw invalid stuff, so we need to clip. Might as
-      // well clip to the smallest area possible --- the visible region.
-      // Bug 599189 if there is a non-integer-translation transform in aTarget,
-      // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
-      // and may cause gray lines.
-      gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion());
-      clipped = true;
-    }
-
-    RefPtr<gfx::SourceSurface> mask;
-    if (aMask) {
-      mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask);
-    }
+  // If the entire buffer is valid, we can just draw the whole thing,
+  // no need to clip. But we'll still clip if clipping is cheap ---
+  // that might let us copy a smaller region of the buffer.
+  // Also clip to the visible region if we're told to.
+  if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
+      (ToData(aLayer)->GetClipToVisibleRegion() &&
+       !aLayer->GetVisibleRegion().Contains(BufferRect())) ||
+      IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
+    // We don't want to draw invalid stuff, so we need to clip. Might as
+    // well clip to the smallest area possible --- the visible region.
+    // Bug 599189 if there is a non-integer-translation transform in aTarget,
+    // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
+    // and may cause gray lines.
+    gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion());
+    clipped = true;
+  }
 
-    Matrix maskTransform;
-    if (aMaskTransform) {
-      maskTransform = ToMatrix(*aMaskTransform);
-    }
-
-    CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator());
-    DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform);
-    if (clipped) {
-      dt->PopClip();
-    }
+  RefPtr<gfx::SourceSurface> mask;
+  if (aMask) {
+    mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask);
   }
-}
+
+  Matrix maskTransform;
+  if (aMaskTransform) {
+    maskTransform = ToMatrix(*aMaskTransform);
+  }
 
-static void
-FillSurface(gfxASurface* aSurface, const nsIntRegion& aRegion,
-            const nsIntPoint& aOffset, const gfxRGBA& aColor)
-{
-  nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
-  ctx->Translate(-gfxPoint(aOffset.x, aOffset.y));
-  gfxUtils::ClipToRegion(ctx, aRegion);
-  ctx->SetColor(aColor);
-  ctx->Paint();
+  CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator());
+  DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform);
+  if (clipped) {
+    dt->PopClip();
+  }
 }
 
 already_AddRefed<gfxContext>
 ThebesLayerBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource, nsIntPoint *aTopLeft)
 {
   if (!EnsureBuffer()) {
     return nullptr;
   }
 
   nsRefPtr<gfxContext> ctx;
   if (aSource == BUFFER_BOTH && HaveBufferOnWhite()) {
     if (!EnsureBufferOnWhite()) {
       return nullptr;
     }
-    if (mBuffer) {
-      MOZ_ASSERT(mBufferOnWhite);
-      gfxASurface* surfaces[2] = { mBuffer, mBufferOnWhite };
-      nsRefPtr<gfxTeeSurface> surf = new gfxTeeSurface(surfaces, ArrayLength(surfaces));
-
-      // XXX If the device offset is set on the individual surfaces instead of on
-      // the tee surface, we render in the wrong place. Why?
-      gfxPoint deviceOffset = mBuffer->GetDeviceOffset();
-      surfaces[0]->SetDeviceOffset(gfxPoint(0, 0));
-      surfaces[1]->SetDeviceOffset(gfxPoint(0, 0));
-      surf->SetDeviceOffset(deviceOffset);
-
-      surf->SetAllowUseAsSource(false);
-      ctx = new gfxContext(surf);
-    } else {
-      MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
-      RefPtr<DrawTarget> dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
-      ctx = new gfxContext(dualDT);
-    }
+    MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
+    RefPtr<DrawTarget> dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
+    ctx = new gfxContext(dualDT);
   } else if (aSource == BUFFER_WHITE) {
     if (!EnsureBufferOnWhite()) {
       return nullptr;
     }
-    if (mBufferOnWhite) {
-      ctx = new gfxContext(mBufferOnWhite);
-    } else {
-      ctx = new gfxContext(mDTBufferOnWhite);
-    }
+    ctx = new gfxContext(mDTBufferOnWhite);
   } else {
     // BUFFER_BLACK, or BUFFER_BOTH with a single buffer.
-    if (mBuffer) {
-      ctx = new gfxContext(mBuffer);
-    } else {
-      ctx = new gfxContext(mDTBuffer);
-    }
+    ctx = new gfxContext(mDTBuffer);
   }
 
   // Figure out which quadrant to draw in
   int32_t xBoundary = mBufferRect.XMost() - mBufferRotation.x;
   int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y;
   XSide sideX = aBounds.XMost() <= xBoundary ? RIGHT : LEFT;
   YSide sideY = aBounds.YMost() <= yBoundary ? BOTTOM : TOP;
   nsIntRect quadrantRect = GetQuadrantRectangle(sideX, sideY);
@@ -449,19 +278,16 @@ ThebesLayerBuffer::GetContextForQuadrant
   }
 
   return ctx.forget();
 }
 
 gfxContentType
 ThebesLayerBuffer::BufferContentType()
 {
-  if (mBuffer) {
-    return mBuffer->GetContentType();
-  }
   if (mBufferProvider) {
     return mBufferProvider->GetContentType();
   }
   if (mDTBuffer) {
     switch (mDTBuffer->GetFormat()) {
     case FORMAT_A8:
       return GFX_CONTENT_ALPHA;
     case FORMAT_B8G8R8A8:
@@ -478,76 +304,47 @@ bool
 ThebesLayerBuffer::BufferSizeOkFor(const nsIntSize& aSize)
 {
   return (aSize == mBufferRect.Size() ||
           (SizedToVisibleBounds != mBufferSizePolicy &&
            aSize < mBufferRect.Size()));
 }
 
 bool
-ThebesLayerBuffer::IsAzureBuffer()
-{
-  MOZ_ASSERT(!(mDTBuffer && mBuffer), "Trying to use Azure and Thebes in the same buffer?");
-  if (mDTBuffer) {
-    return true;
-  }
-  if (mBuffer) {
-    return false;
-  }
-  if (mBufferProvider) {
-    return gfxPlatform::GetPlatform()->SupportsAzureContentForType(
-      mBufferProvider->BackendType());
-  }
-  return SupportsAzureContent();
-}
-
-bool
 ThebesLayerBuffer::EnsureBuffer()
 {
-  if ((!mBuffer && !mDTBuffer) && mBufferProvider) {
-    if (IsAzureBuffer()) {
-      mDTBuffer = mBufferProvider->LockDrawTarget();
-      mBuffer = nullptr;
-    } else {
-      mBuffer = mBufferProvider->LockSurface();
-      mDTBuffer = nullptr;
-    }
+  if (!mDTBuffer && mBufferProvider) {
+    mDTBuffer = mBufferProvider->LockDrawTarget();
   }
 
-  NS_WARN_IF_FALSE(mBuffer || mDTBuffer, "no buffer");
-  return mBuffer || mDTBuffer;
+  NS_WARN_IF_FALSE(mDTBuffer, "no buffer");
+  return !!mDTBuffer;
 }
 
 bool
 ThebesLayerBuffer::EnsureBufferOnWhite()
 {
-  if ((!mBufferOnWhite && !mDTBufferOnWhite) && mBufferProviderOnWhite) {
-    if (IsAzureBuffer()) {
-      mDTBufferOnWhite = mBufferProviderOnWhite->LockDrawTarget();
-      mBufferOnWhite = nullptr;
-    } else {
-      mBufferOnWhite = mBufferProviderOnWhite->LockSurface();
-      mDTBufferOnWhite = nullptr;
-    }
+  if (!mDTBufferOnWhite && mBufferProviderOnWhite) {
+    mDTBufferOnWhite = mBufferProviderOnWhite->LockDrawTarget();
   }
 
-  NS_WARN_IF_FALSE(mBufferOnWhite || mDTBufferOnWhite, "no buffer");
-  return mBufferOnWhite || mDTBufferOnWhite;
+  NS_WARN_IF_FALSE(mDTBufferOnWhite, "no buffer");
+  return mDTBufferOnWhite;
 }
 
 bool
 ThebesLayerBuffer::HaveBuffer() const
 {
-  return mDTBuffer || mBuffer || mBufferProvider;
+  return mDTBuffer || mBufferProvider;
 }
 
 bool
 ThebesLayerBuffer::HaveBufferOnWhite() const
 {
-  return mDTBufferOnWhite || mBufferOnWhite || mBufferProviderOnWhite;
+  return mDTBufferOnWhite || mBufferProviderOnWhite;
 }
 
 static void
 WrapRotationAxis(int32_t* aRotationPoint, int32_t aSize)
 {
   if (*aRotationPoint < 0) {
     *aRotationPoint += aSize;
   } else if (*aRotationPoint >= aSize) {
@@ -675,18 +472,16 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
   NS_ASSERTION(destBufferRect.Contains(neededRegion.GetBounds()),
                "Destination rect doesn't contain what we need to paint");
 
   result.mRegionToDraw.Sub(neededRegion, validRegion);
   if (result.mRegionToDraw.IsEmpty())
     return result;
 
   nsIntRect drawBounds = result.mRegionToDraw.GetBounds();
-  nsRefPtr<gfxASurface> destBuffer;
-  nsRefPtr<gfxASurface> destBufferOnWhite;
   RefPtr<DrawTarget> destDTBuffer;
   RefPtr<DrawTarget> destDTBufferOnWhite;
   uint32_t bufferFlags = canHaveRotation ? ALLOW_REPEAT : 0;
   if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
     bufferFlags |= BUFFER_COMPONENT_ALPHA;
   }
   if (canReuseBuffer) {
     if (!EnsureBuffer()) {
@@ -709,151 +504,107 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
           (drawBounds.y < yBoundary && yBoundary < drawBounds.YMost()) ||
           (newRotation != nsIntPoint(0,0) && !canHaveRotation)) {
         // The stuff we need to redraw will wrap around an edge of the
         // buffer, so move the pixels we can keep into a position that
         // lets us redraw in just one quadrant.
         if (mBufferRotation == nsIntPoint(0,0)) {
           nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size());
           nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft();
-          if (IsAzureBuffer()) {
-            MOZ_ASSERT(mDTBuffer);
-            mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
-                                IntPoint(dest.x, dest.y));
-            if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-              if (!EnsureBufferOnWhite()) {
-                return result;
-              }
-              MOZ_ASSERT(mDTBufferOnWhite);
-              mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
-                                         IntPoint(dest.x, dest.y));
+          MOZ_ASSERT(mDTBuffer);
+          mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
+                              IntPoint(dest.x, dest.y));
+          if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
+            if (!EnsureBufferOnWhite()) {
+              return result;
             }
-          } else {
-            MOZ_ASSERT(mBuffer);
-            mBuffer->MovePixels(srcRect, dest);
-            if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-              if (!EnsureBufferOnWhite()) {
-                return result;
-              }
-              MOZ_ASSERT(mBufferOnWhite);
-              mBufferOnWhite->MovePixels(srcRect, dest);
-            }
+            MOZ_ASSERT(mDTBufferOnWhite);
+            mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
+                                       IntPoint(dest.x, dest.y));
           }
           result.mDidSelfCopy = true;
           mDidSelfCopy = true;
           // Don't set destBuffer; we special-case self-copies, and
           // just did the necessary work above.
           mBufferRect = destBufferRect;
         } else {
           // With azure and a data surface perform an buffer unrotate
           // (SelfCopy).
-          if (IsAzureBuffer()) {
-            unsigned char* data;
-            IntSize size;
-            int32_t stride;
-            SurfaceFormat format;
+          unsigned char* data;
+          IntSize size;
+          int32_t stride;
+          SurfaceFormat format;
 
-            if (mDTBuffer->LockBits(&data, &size, &stride, &format)) {
+          if (mDTBuffer->LockBits(&data, &size, &stride, &format)) {
+            uint8_t bytesPerPixel = BytesPerPixel(format);
+            BufferUnrotate(data,
+                           size.width * bytesPerPixel,
+                           size.height, stride,
+                           newRotation.x * bytesPerPixel, newRotation.y);
+            mDTBuffer->ReleaseBits(data);
+
+            if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
+              if (!EnsureBufferOnWhite()) {
+                return result;
+              }
+              MOZ_ASSERT(mDTBufferOnWhite);
+              mDTBufferOnWhite->LockBits(&data, &size, &stride, &format);
               uint8_t bytesPerPixel = BytesPerPixel(format);
               BufferUnrotate(data,
                              size.width * bytesPerPixel,
                              size.height, stride,
                              newRotation.x * bytesPerPixel, newRotation.y);
-              mDTBuffer->ReleaseBits(data);
+              mDTBufferOnWhite->ReleaseBits(data);
+            }
 
-              if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-                if (!EnsureBufferOnWhite()) {
-                  return result;
-                }
-                MOZ_ASSERT(mDTBufferOnWhite);
-                mDTBufferOnWhite->LockBits(&data, &size, &stride, &format);
-                uint8_t bytesPerPixel = BytesPerPixel(format);
-                BufferUnrotate(data,
-                               size.width * bytesPerPixel,
-                               size.height, stride,
-                               newRotation.x * bytesPerPixel, newRotation.y);
-                mDTBufferOnWhite->ReleaseBits(data);
-              }
-
-              // Buffer unrotate moves all the pixels, note that
-              // we self copied for SyncBackToFrontBuffer
-              result.mDidSelfCopy = true;
-              mDidSelfCopy = true;
-              mBufferRect = destBufferRect;
-              mBufferRotation = nsIntPoint(0, 0);
-            }
+            // Buffer unrotate moves all the pixels, note that
+            // we self copied for SyncBackToFrontBuffer
+            result.mDidSelfCopy = true;
+            mDidSelfCopy = true;
+            mBufferRect = destBufferRect;
+            mBufferRotation = nsIntPoint(0, 0);
           }
 
           if (!result.mDidSelfCopy) {
             destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
             CreateBuffer(contentType, destBufferRect, bufferFlags,
-                         getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
                          &destDTBuffer, &destDTBufferOnWhite);
-            if (!destBuffer && !destDTBuffer)
+            if (!destDTBuffer) {
               return result;
+            }
           }
         }
       } else {
         mBufferRect = destBufferRect;
         mBufferRotation = newRotation;
       }
     } else {
       // No pixels are going to be kept. The whole visible region
       // will be redrawn, so we don't need to copy anything, so we don't
       // set destBuffer.
       mBufferRect = destBufferRect;
       mBufferRotation = nsIntPoint(0,0);
     }
   } else {
     // The buffer's not big enough, so allocate a new one
     CreateBuffer(contentType, destBufferRect, bufferFlags,
-                 getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
                  &destDTBuffer, &destDTBufferOnWhite);
-    if (!destBuffer && !destDTBuffer)
+    if (!destDTBuffer) {
       return result;
+    }
   }
 
   NS_ASSERTION(!(aFlags & PAINT_WILL_RESAMPLE) || destBufferRect == neededRegion.GetBounds(),
                "If we're resampling, we need to validate the entire buffer");
 
   // If we have no buffered data already, then destBuffer will be a fresh buffer
   // and we do not need to clear it below.
   bool isClear = !HaveBuffer();
 
-  if (destBuffer) {
-    if (!isClear && (mode != Layer::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) {
-      // Copy the bits
-      nsRefPtr<gfxContext> tmpCtx = new gfxContext(destBuffer);
-      nsIntPoint offset = -destBufferRect.TopLeft();
-      tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
-      tmpCtx->Translate(gfxPoint(offset.x, offset.y));
-      if (!EnsureBuffer()) {
-        return result;
-      }
-      DrawBufferWithRotation(tmpCtx, BUFFER_BLACK);
-
-      if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-        if (!EnsureBufferOnWhite()) {
-          return result;
-        }
-        NS_ASSERTION(destBufferOnWhite, "Must have a white buffer!");
-        nsRefPtr<gfxContext> tmpCtx = new gfxContext(destBufferOnWhite);
-        tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
-        tmpCtx->Translate(gfxPoint(offset.x, offset.y));
-        DrawBufferWithRotation(tmpCtx, BUFFER_WHITE);
-      }
-    }
-
-    mBuffer = destBuffer.forget();
-    mDTBuffer = nullptr;
-    mBufferRect = destBufferRect;
-    mBufferOnWhite = destBufferOnWhite.forget();
-    mDTBufferOnWhite = nullptr;
-    mBufferRotation = nsIntPoint(0,0);
-  } else if (destDTBuffer) {
+  if (destDTBuffer) {
     if (!isClear && (mode != Layer::SURFACE_COMPONENT_ALPHA || HaveBufferOnWhite())) {
       // Copy the bits
       nsIntPoint offset = -destBufferRect.TopLeft();
       Matrix mat;
       mat.Translate(offset.x, offset.y);
       destDTBuffer->SetTransform(mat);
       if (!EnsureBuffer()) {
         return result;
@@ -870,65 +621,46 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
         }
         MOZ_ASSERT(mDTBufferOnWhite, "Have we got a Thebes buffer for some reason?");
         DrawBufferWithRotation(destDTBufferOnWhite, BUFFER_WHITE, 1.0, OP_SOURCE);
         destDTBufferOnWhite->SetTransform(Matrix());
       }
     }
 
     mDTBuffer = destDTBuffer.forget();
-    mBuffer = nullptr;
     mDTBufferOnWhite = destDTBufferOnWhite.forget();
-    mBufferOnWhite = nullptr;
     mBufferRect = destBufferRect;
     mBufferRotation = nsIntPoint(0,0);
   }
   NS_ASSERTION(canHaveRotation || mBufferRotation == nsIntPoint(0,0),
                "Rotation disabled, but we have nonzero rotation?");
 
   nsIntRegion invalidate;
   invalidate.Sub(aLayer->GetValidRegion(), destBufferRect);
   result.mRegionToInvalidate.Or(result.mRegionToInvalidate, invalidate);
 
   nsIntPoint topLeft;
   result.mContext = GetContextForQuadrantUpdate(drawBounds, BUFFER_BOTH, &topLeft);
   result.mClip = CLIP_DRAW_SNAPPED;
 
   if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
-    if (IsAzureBuffer()) {
-      MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
-      nsIntRegionRectIterator iter(result.mRegionToDraw);
-      const nsIntRect *iterRect;
-      while ((iterRect = iter.Next())) {
-        mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
-                            ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
-        mDTBufferOnWhite->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
-                                   ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
-      }
-    } else {
-      MOZ_ASSERT(mBuffer && mBufferOnWhite);
-      FillSurface(mBuffer, result.mRegionToDraw, topLeft, gfxRGBA(0.0, 0.0, 0.0, 1.0));
-      FillSurface(mBufferOnWhite, result.mRegionToDraw, topLeft, gfxRGBA(1.0, 1.0, 1.0, 1.0));
+    MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
+    nsIntRegionRectIterator iter(result.mRegionToDraw);
+    const nsIntRect *iterRect;
+    while ((iterRect = iter.Next())) {
+      mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
+                          ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
+      mDTBufferOnWhite->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
+                                 ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
     }
   } else if (contentType == GFX_CONTENT_COLOR_ALPHA && !isClear) {
-    if (IsAzureBuffer()) {
-      nsIntRegionRectIterator iter(result.mRegionToDraw);
-      const nsIntRect *iterRect;
-      while ((iterRect = iter.Next())) {
-        result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
-      }
-      // Clear will do something expensive with a complex clip pushed, so clip
-      // here.
-    } else {
-      MOZ_ASSERT(result.mContext->IsCairo());
-      result.mContext->Save();
-      gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
-      result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
-      result.mContext->Paint();
-      result.mContext->Restore();
+    nsIntRegionRectIterator iter(result.mRegionToDraw);
+    const nsIntRect *iterRect;
+    while ((iterRect = iter.Next())) {
+      result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
     }
   }
 
   return result;
 }
 
 }
 }
--- a/gfx/layers/ThebesLayerBuffer.h
+++ b/gfx/layers/ThebesLayerBuffer.h
@@ -50,25 +50,16 @@ class ThebesLayer;
  * at row 0 on the screen, and then painting rows 0 to N-1 of the buffer
  * at row H-N on the screen.
  * mBufferRotation.y would be N in this example.
  */
 class RotatedBuffer {
 public:
   typedef gfxContentType ContentType;
 
-  RotatedBuffer(gfxASurface* aBuffer, gfxASurface* aBufferOnWhite,
-                const nsIntRect& aBufferRect,
-                const nsIntPoint& aBufferRotation)
-    : mBuffer(aBuffer)
-    , mBufferOnWhite(aBufferOnWhite)
-    , mBufferRect(aBufferRect)
-    , mBufferRotation(aBufferRotation)
-    , mDidSelfCopy(false)
-  { }
   RotatedBuffer(gfx::DrawTarget* aDTBuffer, gfx::DrawTarget* aDTBufferOnWhite,
                 const nsIntRect& aBufferRect,
                 const nsIntPoint& aBufferRotation)
     : mDTBuffer(aDTBuffer)
     , mDTBufferOnWhite(aDTBufferOnWhite)
     , mBufferRect(aBufferRect)
     , mBufferRotation(aBufferRotation)
     , mDidSelfCopy(false)
@@ -80,37 +71,32 @@ public:
   /*
    * Which buffer should be drawn to/read from.
    */
   enum ContextSource {
     BUFFER_BLACK, // The normal buffer, or buffer with black background when using component alpha.
     BUFFER_WHITE, // The buffer with white background, only valid with component alpha.
     BUFFER_BOTH // The combined black/white buffers, only valid for writing operations, not reading.
   };
-  void DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource,
-                              float aOpacity = 1.0,
-                              gfxASurface* aMask = nullptr,
-                              const gfxMatrix* aMaskTransform = nullptr) const;
-
   void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource,
                               float aOpacity = 1.0,
                               gfx::CompositionOp aOperator = gfx::OP_OVER,
                               gfx::SourceSurface* aMask = nullptr,
                               const gfx::Matrix* aMaskTransform = nullptr) const;
 
   /**
    * |BufferRect()| is the rect of device pixels that this
    * ThebesLayerBuffer covers.  That is what DrawBufferWithRotation()
    * will paint when it's called.
    */
   const nsIntRect& BufferRect() const { return mBufferRect; }
   const nsIntPoint& BufferRotation() const { return mBufferRotation; }
 
-  virtual bool HaveBuffer() const { return mBuffer || mDTBuffer; }
-  virtual bool HaveBufferOnWhite() const { return mBufferOnWhite || mDTBufferOnWhite; }
+  virtual bool HaveBuffer() const { return mDTBuffer; }
+  virtual bool HaveBufferOnWhite() const { return mDTBufferOnWhite; }
 
 protected:
 
   enum XSide {
     LEFT, RIGHT
   };
   enum YSide {
     TOP, BOTTOM
@@ -119,30 +105,23 @@ protected:
 
   gfx::Rect GetSourceRectangle(XSide aXSide, YSide aYSide) const;
 
   /*
    * If aMask is non-null, then it is used as an alpha mask for rendering this
    * buffer. aMaskTransform must be non-null if aMask is non-null, and is used
    * to adjust the coordinate space of the mask.
    */
-  void DrawBufferQuadrant(gfxContext* aTarget, XSide aXSide, YSide aYSide,
-                          ContextSource aSource,
-                          float aOpacity,
-                          gfxASurface* aMask,
-                          const gfxMatrix* aMaskTransform) const;
   void DrawBufferQuadrant(gfx::DrawTarget* aTarget, XSide aXSide, YSide aYSide,
                           ContextSource aSource,
                           float aOpacity,
                           gfx::CompositionOp aOperator,
                           gfx::SourceSurface* aMask,
                           const gfx::Matrix* aMaskTransform) const;
 
-  nsRefPtr<gfxASurface> mBuffer;
-  nsRefPtr<gfxASurface> mBufferOnWhite;
   RefPtr<gfx::DrawTarget> mDTBuffer;
   RefPtr<gfx::DrawTarget> mDTBufferOnWhite;
   /** The area of the ThebesLayer that is covered by the buffer as a whole */
   nsIntRect             mBufferRect;
   /**
    * The x and y rotation of the buffer. Conceptually the buffer
    * has its origin translated to mBufferRect.TopLeft() - mBufferRotation,
    * is tiled to fill the plane, and the result is clipped to mBufferRect.
@@ -191,18 +170,16 @@ public:
   }
 
   /**
    * Wipe out all retained contents. Call this when the entire
    * buffer becomes invalid.
    */
   void Clear()
   {
-    mBuffer = nullptr;
-    mBufferOnWhite = nullptr;
     mDTBuffer = nullptr;
     mDTBufferOnWhite = nullptr;
     mBufferProvider = nullptr;
     mBufferProviderOnWhite = nullptr;
     mBufferRect.SetEmpty();
   }
 
   /**
@@ -259,80 +236,50 @@ public:
    * @param aFlags if ALLOW_REPEAT is set, then the buffer should be configured
    * to allow repeat-mode, otherwise it should be in pad (clamp) mode
    * If the created buffer supports azure content, then the result(s) will
    * be returned in aBlackDT/aWhiteDT, otherwise aBlackSurface/aWhiteSurface
    * will be used.
    */
   virtual void
   CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
-               gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface,
                RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) = 0;
-  virtual bool SupportsAzureContent() const 
-  { return false; }
 
   /**
    * Get the underlying buffer, if any. This is useful because we can pass
    * in the buffer as the default "reference surface" if there is one.
    * Don't use it for anything else!
    */
-  gfxASurface* GetBuffer() { return mBuffer; }
-  gfxASurface* GetBufferOnWhite() { return mBufferOnWhite; }
   gfx::DrawTarget* GetDTBuffer() { return mDTBuffer; }
   gfx::DrawTarget* GetDTBufferOnWhite() { return mDTBufferOnWhite; }
 
   /**
    * Complete the drawing operation. The region to draw must have been
    * drawn before this is called. The contents of the buffer are drawn
    * to aTarget.
    */
   void DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity,
               gfxASurface* aMask, const gfxMatrix* aMaskTransform);
 
 protected:
-  // If this buffer is currently using Azure.
-  bool IsAzureBuffer();
-
-  already_AddRefed<gfxASurface>
-  SetBuffer(gfxASurface* aBuffer,
-            const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation)
-  {
-    MOZ_ASSERT(!SupportsAzureContent());
-    nsRefPtr<gfxASurface> tmp = mBuffer.forget();
-    mBuffer = aBuffer;
-    mBufferRect = aBufferRect;
-    mBufferRotation = aBufferRotation;
-    return tmp.forget();
-  }
-
-  already_AddRefed<gfxASurface>
-  SetBufferOnWhite(gfxASurface* aBuffer)
-  {
-    MOZ_ASSERT(!SupportsAzureContent());
-    nsRefPtr<gfxASurface> tmp = mBufferOnWhite.forget();
-    mBufferOnWhite = aBuffer;
-    return tmp.forget();
-  }
-
   TemporaryRef<gfx::DrawTarget>
   SetDTBuffer(gfx::DrawTarget* aBuffer,
-            const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation)
+              const nsIntRect& aBufferRect,
+              const nsIntPoint& aBufferRotation)
   {
-    MOZ_ASSERT(SupportsAzureContent());
     RefPtr<gfx::DrawTarget> tmp = mDTBuffer.forget();
     mDTBuffer = aBuffer;
     mBufferRect = aBufferRect;
     mBufferRotation = aBufferRotation;
     return tmp.forget();
   }
 
   TemporaryRef<gfx::DrawTarget>
   SetDTBufferOnWhite(gfx::DrawTarget* aBuffer)
   {
-    MOZ_ASSERT(SupportsAzureContent());
     RefPtr<gfx::DrawTarget> tmp = mDTBufferOnWhite.forget();
     mDTBufferOnWhite = aBuffer;
     return tmp.forget();
   }
 
   /**
    * Set the texture client only.  This is used with surfaces that
    * require explicit lock/unlock, which |aClient| is used to do on
@@ -343,53 +290,48 @@ protected:
    * ThebesLayerBuffer.  It's also the caller's responsibility to
    * unset the provider when inactive, by calling
    * SetBufferProvider(nullptr).
    */
   void SetBufferProvider(DeprecatedTextureClient* aClient)
   {
     // Only this buffer provider can give us a buffer.  If we
     // already have one, something has gone wrong.
-    MOZ_ASSERT(!aClient || (!mBuffer && !mDTBuffer));
+    MOZ_ASSERT(!aClient || !mDTBuffer);
 
     mBufferProvider = aClient;
     if (!mBufferProvider) {
-      mBuffer = nullptr;
       mDTBuffer = nullptr;
     } 
   }
   
   void SetBufferProviderOnWhite(DeprecatedTextureClient* aClient)
   {
     // Only this buffer provider can give us a buffer.  If we
     // already have one, something has gone wrong.
-    MOZ_ASSERT(!aClient || (!mBufferOnWhite && !mDTBufferOnWhite));
+    MOZ_ASSERT(!aClient || !mDTBufferOnWhite);
 
     mBufferProviderOnWhite = aClient;
     if (!mBufferProviderOnWhite) {
-      mBufferOnWhite = nullptr;
       mDTBufferOnWhite = nullptr;
     } 
   }
 
   /**
    * Get a context at the specified resolution for updating |aBounds|,
    * which must be contained within a single quadrant.
    *
    * Optionally returns the TopLeft coordinate of the quadrant being drawn to.
    */
   already_AddRefed<gfxContext>
   GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource, nsIntPoint* aTopLeft = nullptr);
 
   static bool IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion);
 
 protected:
-  // Buffer helpers.  Don't use mBuffer directly; instead use one of
-  // these helpers.
-
   /**
    * Return the buffer's content type.  Requires a valid buffer or
    * buffer provider.
    */
   gfxContentType BufferContentType();
   bool BufferSizeOkFor(const nsIntSize& aSize);
   /**
    * If the buffer hasn't been mapped, map it.
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -77,47 +77,27 @@ ContentClientBasic::ContentClientBasic(C
                                        BasicLayerManager* aManager)
 : ContentClient(aForwarder), ThebesLayerBuffer(ContainsVisibleBounds), mManager(aManager)
 {}
 
 void
 ContentClientBasic::CreateBuffer(ContentType aType,
                                  const nsIntRect& aRect,
                                  uint32_t aFlags,
-                                 gfxASurface** aBlackSurface,
-                                 gfxASurface** aWhiteSurface,
                                  RefPtr<gfx::DrawTarget>* aBlackDT,
                                  RefPtr<gfx::DrawTarget>* aWhiteDT)
 {
   MOZ_ASSERT(!(aFlags & BUFFER_COMPONENT_ALPHA));
-  if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
-    gfxImageFormat format =
-      gfxPlatform::GetPlatform()->OptimalFormatForContent(aType);
-
-    *aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
-      IntSize(aRect.width, aRect.height),
-      ImageFormatToSurfaceFormat(format));
-    return;
-  }
+  MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
+  gfxImageFormat format =
+    gfxPlatform::GetPlatform()->OptimalFormatForContent(aType);
 
-  nsRefPtr<gfxASurface> referenceSurface = GetBuffer();
-  if (!referenceSurface) {
-    gfxContext* defaultTarget = mManager->GetDefaultTarget();
-    if (defaultTarget) {
-      referenceSurface = defaultTarget->CurrentSurface();
-    } else {
-      nsIWidget* widget = mManager->GetRetainerWidget();
-      if (!widget || !(referenceSurface = widget->GetThebesSurface())) {
-        referenceSurface = mManager->GetTarget()->CurrentSurface();
-      }
-    }
-  }
-  nsRefPtr<gfxASurface> ret = referenceSurface->CreateSimilarSurface(
-    aType, gfxIntSize(aRect.width, aRect.height));
-  *aBlackSurface = ret.forget().get();
+  *aBlackDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+    IntSize(aRect.width, aRect.height),
+    ImageFormatToSurfaceFormat(format));
 }
 
 void
 ContentClientRemoteBuffer::DestroyBuffers()
 {
   if (!mDeprecatedTextureClient) {
     return;
   }
@@ -214,58 +194,33 @@ ContentClientRemoteBuffer::BuildDeprecat
     }
     mTextureInfo.mTextureFlags |= TEXTURE_COMPONENT_ALPHA;
   }
 
   CreateFrontBufferAndNotify(aRect);
   mIsNewBuffer = true;
 }
 
-bool
-ContentClientBasic::SupportsAzureContent() const
-{
-  return gfxPlatform::GetPlatform()->SupportsAzureContent();
-}
- 
-bool
-ContentClientRemoteBuffer::SupportsAzureContent() const
-{
-  MOZ_ASSERT(mDeprecatedTextureClient);
-
-  return gfxPlatform::GetPlatform()->SupportsAzureContentForType(
-    mDeprecatedTextureClient->BackendType());
-}
-
 void
 ContentClientRemoteBuffer::CreateBuffer(ContentType aType,
                                         const nsIntRect& aRect,
                                         uint32_t aFlags,
-                                        gfxASurface** aBlackSurface,
-                                        gfxASurface** aWhiteSurface,
                                         RefPtr<gfx::DrawTarget>* aBlackDT,
                                         RefPtr<gfx::DrawTarget>* aWhiteDT)
 {
   BuildDeprecatedTextureClients(aType, aRect, aFlags);
   if (!mDeprecatedTextureClient) {
     return;
   }
 
-  if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(
-        mDeprecatedTextureClient->BackendType())) {
-    *aBlackDT = mDeprecatedTextureClient->LockDrawTarget();
-    if (aFlags & BUFFER_COMPONENT_ALPHA) {
-      *aWhiteDT = mDeprecatedTextureClientOnWhite->LockDrawTarget();
-    }
-  } else {
-    nsRefPtr<gfxASurface> ret = mDeprecatedTextureClient->LockSurface();
-    *aBlackSurface = ret.forget().get();
-    if (aFlags & BUFFER_COMPONENT_ALPHA) {
-     nsRefPtr<gfxASurface> retWhite = mDeprecatedTextureClientOnWhite->LockSurface();
-      *aWhiteSurface = retWhite.forget().get();
-    }
+  MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContentForType(
+        mDeprecatedTextureClient->BackendType()));
+  *aBlackDT = mDeprecatedTextureClient->LockDrawTarget();
+  if (aFlags & BUFFER_COMPONENT_ALPHA) {
+    *aWhiteDT = mDeprecatedTextureClientOnWhite->LockDrawTarget();
   }
 }
 
 nsIntRegion
 ContentClientRemoteBuffer::GetUpdatedRegion(const nsIntRegion& aRegionToDraw,
                                             const nsIntRegion& aVisibleRegion,
                                             bool aDidSelfCopy)
 {
@@ -466,25 +421,16 @@ struct AutoDeprecatedTextureClient {
     : mTexture(nullptr)
   {}
   ~AutoDeprecatedTextureClient()
   {
     if (mTexture) {
       mTexture->Unlock();
     }
   }
-  gfxASurface* GetSurface(DeprecatedTextureClient* aTexture)
-  {
-    MOZ_ASSERT(!mTexture);
-    mTexture = aTexture;
-    if (mTexture) {
-      return mTexture->LockSurface();
-    }
-    return nullptr;
-  }
   DrawTarget* GetDrawTarget(DeprecatedTextureClient* aTexture)
   {
     MOZ_ASSERT(!mTexture);
     mTexture = aTexture;
     if (mTexture) {
       return mTexture->LockDrawTarget();
     }
     return nullptr;
@@ -531,35 +477,25 @@ ContentClientDoubleBuffered::SyncFrontBu
     updateRegion = mBufferRect;
   } else {
     mBufferRect = mFrontBufferRect;
     mBufferRotation = mFrontBufferRotation;
   }
  
   AutoDeprecatedTextureClient autoTextureFront;
   AutoDeprecatedTextureClient autoTextureFrontOnWhite;
-  if (SupportsAzureContent()) {
-    // We need to ensure that we lock these two buffers in the same
-    // order as the compositor to prevent deadlocks.
-    DrawTarget* dt = autoTextureFront.GetDrawTarget(mFrontClient);
-    DrawTarget* dtOnWhite = autoTextureFrontOnWhite.GetDrawTarget(mFrontClientOnWhite);
-    RotatedBuffer frontBuffer(dt,
-                              dtOnWhite,
-                              mFrontBufferRect,
-                              mFrontBufferRotation);
-    UpdateDestinationFrom(frontBuffer, updateRegion);
-  } else {
-    gfxASurface* surf = autoTextureFront.GetSurface(mFrontClient);
-    gfxASurface* surfOnWhite = autoTextureFrontOnWhite.GetSurface(mFrontClientOnWhite);
-    RotatedBuffer frontBuffer(surf,
-                              surfOnWhite,
-                              mFrontBufferRect,
-                              mFrontBufferRotation);
-    UpdateDestinationFrom(frontBuffer, updateRegion);
-  }
+  // We need to ensure that we lock these two buffers in the same
+  // order as the compositor to prevent deadlocks.
+  DrawTarget* dt = autoTextureFront.GetDrawTarget(mFrontClient);
+  DrawTarget* dtOnWhite = autoTextureFrontOnWhite.GetDrawTarget(mFrontClientOnWhite);
+  RotatedBuffer frontBuffer(dt,
+                            dtOnWhite,
+                            mFrontBufferRect,
+                            mFrontBufferRotation);
+  UpdateDestinationFrom(frontBuffer, updateRegion);
 
   mFrontAndBackBufferDiffer = false;
 }
 
 void
 ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
                                                    const nsIntRegion& aUpdateRegion)
 {
@@ -570,40 +506,30 @@ ContentClientDoubleBuffered::UpdateDesti
   }
   destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
 
   bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
   if (isClippingCheap) {
     gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
   }
 
-  if (SupportsAzureContent()) {
-    MOZ_ASSERT(!destCtx->IsCairo());
-    aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
-  } else {
-    aSource.DrawBufferWithRotation(destCtx, BUFFER_BLACK);
-  }
+  aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
 
   if (aSource.HaveBufferOnWhite()) {
     MOZ_ASSERT(HaveBufferOnWhite());
     nsRefPtr<gfxContext> destCtx =
       GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
     destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
 
     bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
     if (isClippingCheap) {
       gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
     }
 
-    if (SupportsAzureContent()) {
-      MOZ_ASSERT(!destCtx->IsCairo());
-      aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
-    } else {
-      aSource.DrawBufferWithRotation(destCtx, BUFFER_WHITE);
-    }
+    aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
   }
 }
 
 ContentClientSingleBuffered::~ContentClientSingleBuffered()
 {
   if (mDeprecatedTextureClient) {
     mDeprecatedTextureClient->SetDescriptor(SurfaceDescriptor());
   }
@@ -625,67 +551,40 @@ void
 ContentClientSingleBuffered::SyncFrontBufferToBackBuffer()
 {
   mIsNewBuffer = false;
   if (!mFrontAndBackBufferDiffer) {
     return;
   }
   mFrontAndBackBufferDiffer = false;
 
-  if (SupportsAzureContent()) {
-    DrawTarget* backBuffer = GetDTBuffer();
-    if (!backBuffer && mDeprecatedTextureClient) {
-      backBuffer = mDeprecatedTextureClient->LockDrawTarget();
-    }
-    if (!backBuffer) {
-      NS_WARNING("Could not lock texture client");
-      return;
-    }
-
-    RefPtr<DrawTarget> oldBuffer;
-    oldBuffer = SetDTBuffer(backBuffer,
-                            mBufferRect,
-                            mBufferRotation);
+  DrawTarget* backBuffer = GetDTBuffer();
+  if (!backBuffer && mDeprecatedTextureClient) {
+    backBuffer = mDeprecatedTextureClient->LockDrawTarget();
+  }
+  if (!backBuffer) {
+    NS_WARNING("Could not lock texture client");
+    return;
+  }
 
-    backBuffer = GetDTBufferOnWhite();
-    if (!backBuffer && mDeprecatedTextureClientOnWhite) {
-      backBuffer = mDeprecatedTextureClientOnWhite->LockDrawTarget();
-    }
-    if (!backBuffer) {
-      NS_WARNING("Could not lock texture client (on white)");
-      return;
-    }
-
-    oldBuffer = SetDTBufferOnWhite(backBuffer);
-  } else {
-    gfxASurface* backBuffer = GetBuffer();
-    if (!backBuffer && mDeprecatedTextureClient) {
-      backBuffer = mDeprecatedTextureClient->LockSurface();
-    }
-    if (!backBuffer) {
-      NS_WARNING("Could not lock texture client");
-      return;
-    }
-
-    nsRefPtr<gfxASurface> oldBuffer;
-    oldBuffer = SetBuffer(backBuffer,
+  RefPtr<DrawTarget> oldBuffer;
+  oldBuffer = SetDTBuffer(backBuffer,
                           mBufferRect,
                           mBufferRotation);
 
-    backBuffer = GetBufferOnWhite();
-    if (!backBuffer && mDeprecatedTextureClientOnWhite) {
-      backBuffer = mDeprecatedTextureClientOnWhite->LockSurface();
-    }
-    if (!backBuffer) {
-      NS_WARNING("Could not lock texture client (on white)");
-      return;
-    }
+  backBuffer = GetDTBufferOnWhite();
+  if (!backBuffer && mDeprecatedTextureClientOnWhite) {
+    backBuffer = mDeprecatedTextureClientOnWhite->LockDrawTarget();
+  }
+  if (!backBuffer) {
+    NS_WARNING("Could not lock texture client (on white)");
+    return;
+  }
 
-    oldBuffer = SetBufferOnWhite(backBuffer);
-  }
+  oldBuffer = SetDTBufferOnWhite(backBuffer);
 }
 
 static void
 WrapRotationAxis(int32_t* aRotationPoint, int32_t aSize)
 {
   if (*aRotationPoint < 0) {
     *aRotationPoint += aSize;
   } else if (*aRotationPoint >= aSize) {
@@ -895,49 +794,29 @@ ContentClientIncremental::BeginPaintBuff
     nsIntRegion drawRegionCopy = result.mRegionToDraw;
     nsRefPtr<gfxASurface> onBlack = GetUpdateSurface(BUFFER_BLACK, drawRegionCopy);
     nsRefPtr<gfxASurface> onWhite = GetUpdateSurface(BUFFER_WHITE, result.mRegionToDraw);
     if (onBlack && onWhite) {
       NS_ASSERTION(result.mRegionToDraw == drawRegionCopy,
                    "BeginUpdate should always modify the draw region in the same way!");
       FillSurface(onBlack, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0));
       FillSurface(onWhite, result.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0));
-      if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
-        RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize());
-        RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize());
-        RefPtr<DrawTarget> dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
-        result.mContext = new gfxContext(dt);
-      } else {
-        gfxASurface* surfaces[2] = { onBlack.get(), onWhite.get() };
-        nsRefPtr<gfxTeeSurface> surf = new gfxTeeSurface(surfaces, ArrayLength(surfaces));
-
-        // XXX If the device offset is set on the individual surfaces instead of on
-        // the tee surface, we render in the wrong place. Why?
-        gfxPoint deviceOffset = onBlack->GetDeviceOffset();
-        onBlack->SetDeviceOffset(gfxPoint(0, 0));
-        onWhite->SetDeviceOffset(gfxPoint(0, 0));
-        surf->SetDeviceOffset(deviceOffset);
-
-        // Using this surface as a source will likely go horribly wrong, since
-        // only the onBlack surface will really be used, so alpha information will
-        // be incorrect.
-        surf->SetAllowUseAsSource(false);
-        result.mContext = new gfxContext(surf);
-      }
+      MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
+      RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize());
+      RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize());
+      RefPtr<DrawTarget> dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
+      result.mContext = new gfxContext(dt);
     } else {
       result.mContext = nullptr;
     }
   } else {
     nsRefPtr<gfxASurface> surf = GetUpdateSurface(BUFFER_BLACK, result.mRegionToDraw);
-    if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
-      RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize());
-      result.mContext = new gfxContext(dt);
-    } else {
-      result.mContext = new gfxContext(surf);
-    }
+    MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
+    RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize());
+    result.mContext = new gfxContext(dt);
   }
   if (!result.mContext) {
     NS_WARNING("unable to get context for update");
     return result;
   }
   result.mContext->Translate(-gfxPoint(drawBounds.x, drawBounds.y));
 
   // If we do partial updates, we have to clip drawing to the regionToDraw.
--- a/gfx/layers/client/ContentClient.h
+++ b/gfx/layers/client/ContentClient.h
@@ -149,19 +149,17 @@ public:
 
   void DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity,
               gfxASurface* aMask, const gfxMatrix* aMaskTransform)
   {
     ThebesLayerBuffer::DrawTo(aLayer, aTarget, aOpacity, aMask, aMaskTransform);
   }
 
   virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
-                            gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
-  virtual bool SupportsAzureContent() const;
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     MOZ_CRASH("Should not be called on non-remote ContentClient");
   }
 
   virtual void OnActorDestroy() MOZ_OVERRIDE {}
 
@@ -232,21 +230,18 @@ public:
     return ThebesLayerBuffer::BufferRect();
   }
   virtual const nsIntPoint& BufferRotation() const
   {
     return ThebesLayerBuffer::BufferRotation();
   }
 
   virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
-                            gfxASurface** aBlackSurface, gfxASurface** aWhiteSurface,
                             RefPtr<gfx::DrawTarget>* aBlackDT, RefPtr<gfx::DrawTarget>* aWhiteDT) MOZ_OVERRIDE;
 
-  virtual bool SupportsAzureContent() const MOZ_OVERRIDE;
-
   void DestroyBuffers();
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     return mTextureInfo;
   }
 
   virtual void OnActorDestroy() MOZ_OVERRIDE;