Backed out changeset 14dfa550c783 (bug 1167235)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Tue, 28 Jun 2016 20:28:23 +0200
changeset 382178 bb7effd4b6fccb7a6ba6314968de49c218a41a77
parent 382177 73deeeaaeb8644a8e1031e599aa2bcca4cdc047a
child 382179 3f5b0befdac9c69b63ea60183be171a193012f4f
push id21645
push userbmo:gasolin@mozilla.com
push dateWed, 29 Jun 2016 04:02:20 +0000
bugs1167235
milestone50.0a1
backs out14dfa550c783cc2cd10d16fed28e9281aae747d2
Backed out changeset 14dfa550c783 (bug 1167235)
dom/canvas/CanvasRenderingContext2D.cpp
dom/canvas/CanvasRenderingContext2D.h
gfx/2d/Tools.h
gfx/layers/CopyableCanvasLayer.cpp
gfx/layers/Layers.cpp
gfx/layers/PersistentBufferProvider.cpp
gfx/layers/PersistentBufferProvider.h
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CanvasClient.h
gfx/layers/client/ClientCanvasLayer.cpp
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ClientLayerManager.h
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -80,17 +80,16 @@
 #include "mozilla/dom/ImageBitmap.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/dom/PBrowserParent.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/EndianUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Helpers.h"
-#include "mozilla/gfx/Tools.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/gfx/PatternHelpers.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/ipc/PDocumentRendererParent.h"
 #include "mozilla/layers/PersistentBufferProvider.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Preferences.h"
@@ -116,17 +115,16 @@
 #include "nsFilterInstance.h"
 #include "nsSVGLength2.h"
 #include "nsDeviceContext.h"
 #include "nsFontMetrics.h"
 #include "Units.h"
 #include "CanvasUtils.h"
 #include "mozilla/StyleSetHandle.h"
 #include "mozilla/StyleSetHandleInlines.h"
-#include "mozilla/layers/CanvasClient.h"
 
 #undef free // apparently defined by some windows header, clashing with a free()
             // method in SkTypes.h
 #include "SkiaGLGlue.h"
 #ifdef USE_SKIA
 #include "SurfaceTypes.h"
 #include "GLBlitHelper.h"
 #endif
@@ -220,42 +218,20 @@ protected:
   friend class CanvasGeneralPattern;
 
   // Beginning of linear gradient.
   Point mBegin;
   // End of linear gradient.
   Point mEnd;
 };
 
-bool
-CanvasRenderingContext2D::PatternIsOpaque(CanvasRenderingContext2D::Style aStyle) const
-{
-  const ContextState& state = CurrentState();
-  if (state.globalAlpha < 1.0) {
-    return false;
-  }
-
-  if (state.patternStyles[aStyle] && state.patternStyles[aStyle]->mSurface) {
-    return IsOpaqueFormat(state.patternStyles[aStyle]->mSurface->GetFormat());
-  }
-
-  // TODO: for gradient patterns we could check that all stops are opaque
-  // colors.
-
-  if (!state.gradientStyles[aStyle]) {
-    // it's a color pattern.
-    return Color::FromABGR(state.colorStyles[aStyle]).a >= 1.0;
-  }
-
-  return false;
-}
-
 // This class is named 'GeneralCanvasPattern' instead of just
 // 'GeneralPattern' to keep Windows PGO builds from confusing the
 // GeneralPattern class in gfxContext.cpp with this one.
+
 class CanvasGeneralPattern
 {
 public:
   typedef CanvasRenderingContext2D::Style Style;
   typedef CanvasRenderingContext2D::ContextState ContextState;
 
   Pattern& ForStyle(CanvasRenderingContext2D* aCtx,
                     Style aStyle,
@@ -1295,37 +1271,33 @@ bool CanvasRenderingContext2D::SwitchRen
     }
     mCurrentVideoSize.width = 0;
     mCurrentVideoSize.height = 0;
   }
 #endif
 
   RefPtr<SourceSurface> snapshot;
   Matrix transform;
-  RefPtr<PersistentBufferProvider> oldBufferProvider = mBufferProvider;
-  AutoReturnSnapshot autoReturn(nullptr);
 
   if (mTarget) {
     snapshot = mTarget->Snapshot();
     transform = mTarget->GetTransform();
   } else {
     MOZ_ASSERT(mBufferProvider);
     // When mBufferProvider is true but we have no mTarget, our current state's
     // transform is always valid. See ReturnTarget().
     transform = CurrentState().transform;
-    snapshot = mBufferProvider->BorrowSnapshot();
-    autoReturn.mBufferProvider = mBufferProvider;
-    autoReturn.mSnapshot = &snapshot;
+    snapshot = mBufferProvider->GetSnapshot();
   }
   mTarget = nullptr;
   mBufferProvider = nullptr;
   mResetLayer = true;
 
   // Recreate target using the new rendering mode
-  RenderingMode attemptedMode = EnsureTarget(nullptr, aRenderingMode);
+  RenderingMode attemptedMode = EnsureTarget(aRenderingMode);
   if (!IsTargetValid())
     return false;
 
   // We succeeded, so update mRenderingMode to reflect reality
   mRenderingMode = attemptedMode;
 
   // Restore the content from the old DrawTarget
   gfx::Rect r(0, 0, mWidth, mHeight);
@@ -1448,44 +1420,30 @@ CanvasRenderingContext2D::CheckSizeForSk
   double scale = gDefaultScale > 0 ? gDefaultScale : 1.0;
   int32_t threshold = ceil(scale * scale * gScreenPixels);
 
   // screen size acts as max threshold
   return threshold < 0 || (aSize.width * aSize.height) <= threshold;
 }
 
 CanvasRenderingContext2D::RenderingMode
-CanvasRenderingContext2D::EnsureTarget(const gfx::Rect* aCoveredRect,
-                                       RenderingMode aRenderingMode)
+CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
 {
   // This would make no sense, so make sure we don't get ourselves in a mess
   MOZ_ASSERT(mRenderingMode != RenderingMode::DefaultBackendMode);
 
   RenderingMode mode = (aRenderingMode == RenderingMode::DefaultBackendMode) ? mRenderingMode : aRenderingMode;
 
   if (mTarget && mode == mRenderingMode) {
     return mRenderingMode;
   }
 
   if (mBufferProvider && mode == mRenderingMode) {
-    gfx::Rect rect(0, 0, mWidth, mHeight);
-    if (aCoveredRect && CurrentState().transform.TransformBounds(*aCoveredRect).Contains(rect)) {
-      mTarget = mBufferProvider->BorrowDrawTarget(IntRect());
-    } else {
-      mTarget = mBufferProvider->BorrowDrawTarget(IntRect(0, 0, mWidth, mHeight));
-    }
-
+    mTarget = mBufferProvider->GetDT(IntRect(IntPoint(), IntSize(mWidth, mHeight)));
     if (mTarget) {
-      // Restore clip and transform.
-      mTarget->SetTransform(CurrentState().transform);
-      for (uint32_t i = 0; i < mStyleStack.Length(); i++) {
-        for (uint32_t c = 0; c < mStyleStack[i].clipsPushed.Length(); c++) {
-          mTarget->PushClip(mStyleStack[i].clipsPushed[c]);
-        }
-      }
       return mRenderingMode;
     } else {
       mBufferProvider = nullptr;
     }
   }
 
   mIsSkiaGL = false;
 
@@ -1532,17 +1490,17 @@ CanvasRenderingContext2D::EnsureTarget(c
       }
 
       if (!mBufferProvider) {
         mBufferProvider = layerManager->CreatePersistentBufferProvider(size, format);
       }
     }
 
     if (mBufferProvider) {
-      mTarget = mBufferProvider->BorrowDrawTarget(IntRect(IntPoint(), IntSize(mWidth, mHeight)));
+      mTarget = mBufferProvider->GetDT(IntRect(IntPoint(), IntSize(mWidth, mHeight)));
     } else if (!mTarget) {
       mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
       mode = RenderingMode::SoftwareBackendMode;
     }
   }
 
   if (mTarget) {
     static bool registered = false;
@@ -1660,22 +1618,17 @@ CanvasRenderingContext2D::ClearTarget()
   }
 }
 
 void
 CanvasRenderingContext2D::ReturnTarget()
 {
   if (mTarget && mBufferProvider) {
     CurrentState().transform = mTarget->GetTransform();
-    for (uint32_t i = 0; i < mStyleStack.Length(); i++) {
-      for (uint32_t c = 0; c < mStyleStack[i].clipsPushed.Length(); c++) {
-        mTarget->PopClip();
-      }
-    }
-    mBufferProvider->ReturnDrawTarget(mTarget.forget());
+    mBufferProvider->ReturnAndUseDT(mTarget.forget());
   }
 }
 
 NS_IMETHODIMP
 CanvasRenderingContext2D::InitializeWithDrawTarget(nsIDocShell* aShell,
                                                    gfx::DrawTarget* aTarget)
 {
   RemovePostRefreshObserver();
@@ -2640,21 +2593,19 @@ void
 CanvasRenderingContext2D::ClearRect(double aX, double aY, double aW,
                                     double aH)
 {
   // Do not allow zeros - it's a no-op at that point per spec.
   if (!ValidateRect(aX, aY, aW, aH, false)) {
     return;
   }
 
-  gfx::Rect clearRect(aX, aY, aW, aH);
-
-  EnsureTarget(&clearRect);
-
-  mTarget->ClearRect(clearRect);
+  EnsureTarget();
+
+  mTarget->ClearRect(gfx::Rect(aX, aY, aW, aH));
 
   RedrawUser(gfxRect(aX, aY, aW, aH));
 }
 
 void
 CanvasRenderingContext2D::FillRect(double aX, double aY, double aW,
                                    double aH)
 {
@@ -2705,32 +2656,28 @@ CanvasRenderingContext2D::FillRect(doubl
         aH = patternSize.height - aY;
         if (aH < 0) {
           aH = 0;
         }
       }
     }
   }
 
-  CompositionOp op = UsedOperation();
-  bool discardContent = PatternIsOpaque(Style::FILL)
-    && (op == CompositionOp::OP_OVER || op == CompositionOp::OP_DEST_OUT);
-
-  const gfx::Rect fillRect(aX, aY, aW, aH);
-  EnsureTarget(discardContent ? &fillRect : nullptr);
-
   gfx::Rect bounds;
+
+  EnsureTarget();
   if (NeedToCalculateBounds()) {
-    bounds = mTarget->GetTransform().TransformBounds(fillRect);
+    bounds = gfx::Rect(aX, aY, aW, aH);
+    bounds = mTarget->GetTransform().TransformBounds(bounds);
   }
 
   AdjustedTarget(this, bounds.IsEmpty() ? nullptr : &bounds)->
     FillRect(gfx::Rect(aX, aY, aW, aH),
              CanvasGeneralPattern().ForStyle(this, Style::FILL, mTarget),
-             DrawOptions(state.globalAlpha, op));
+             DrawOptions(state.globalAlpha, UsedOperation()));
 
   RedrawUser(gfxRect(aX, aY, aW, aH));
 }
 
 void
 CanvasRenderingContext2D::StrokeRect(double aX, double aY, double aW,
                                      double aH)
 {
@@ -5694,24 +5641,17 @@ CanvasRenderingContext2D::GetBufferProvi
   if (mBufferProvider) {
     return mBufferProvider;
   }
 
   if (!mTarget) {
     return nullptr;
   }
 
-  if (aManager) {
-    mBufferProvider = aManager->CreatePersistentBufferProvider(gfx::IntSize(mWidth, mHeight),
-                                                               GetSurfaceFormat());
-  }
-
-  if (!mBufferProvider) {
-    mBufferProvider = new PersistentBufferProviderBasic(mTarget);
-  }
+  mBufferProvider = new PersistentBufferProviderBasic(mTarget);
 
   return mBufferProvider;
 }
 
 already_AddRefed<Layer>
 CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                          Layer *aOldLayer,
                                          LayerManager *aManager)
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -630,18 +630,17 @@ protected:
    /**
    * Create the backing surfacing, if it doesn't exist. If there is an error
    * in creating the target then it will put sErrorTarget in place. If there
    * is in turn an error in creating the sErrorTarget then they would both
    * be null so IsTargetValid() would still return null.
    *
    * Returns the actual rendering mode being used by the created target.
    */
-  RenderingMode EnsureTarget(const gfx::Rect* aCoveredRect = nullptr,
-                             RenderingMode aRenderMode = RenderingMode::DefaultBackendMode);
+  RenderingMode EnsureTarget(RenderingMode aRenderMode = RenderingMode::DefaultBackendMode);
 
   /**
    * Disposes an old target and prepares to lazily create a new target.
    */
   void ClearTarget();
 
   /*
    * Returns the target to the buffer provider. i.e. this will queue a frame for
@@ -658,22 +657,16 @@ protected:
 
   /**
     * Returns the surface format this canvas should be allocated using. Takes
     * into account mOpaque, platform requirements, etc.
     */
   mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
 
   /**
-   * Returns true if we know for sure that the pattern for a given style is opaque.
-   * Usefull to know if we can discard the content below in certain situations.
-   */
-  bool PatternIsOpaque(Style aStyle) const;
-
-  /**
    * Update CurrentState().filter with the filter description for
    * CurrentState().filterChain.
    */
   void UpdateFilter();
 
   nsLayoutUtils::SurfaceFromElementResult
     CachedSurfaceFromElement(Element* aElement);
 
--- a/gfx/2d/Tools.h
+++ b/gfx/2d/Tools.h
@@ -93,32 +93,16 @@ BytesPerPixel(SurfaceFormat aFormat)
     return 3 * sizeof(float);
   case SurfaceFormat::Depth:
     return sizeof(uint16_t);
   default:
     return 4;
   }
 }
 
-static inline bool
-IsOpaqueFormat(SurfaceFormat aFormat) {
-  switch (aFormat) {
-    case SurfaceFormat::B8G8R8X8:
-    case SurfaceFormat::R8G8B8X8:
-    case SurfaceFormat::X8R8G8B8:
-    case SurfaceFormat::YUV:
-    case SurfaceFormat::NV12:
-    case SurfaceFormat::YUV422:
-    case SurfaceFormat::R5G6B5_UINT16:
-      return true;
-    default:
-      return false;
-  }
-}
-
 template<typename T, int alignment = 16>
 struct AlignedArray
 {
   typedef T value_type;
 
   AlignedArray()
     : mPtr(nullptr)
     , mStorage(nullptr)
--- a/gfx/layers/CopyableCanvasLayer.cpp
+++ b/gfx/layers/CopyableCanvasLayer.cpp
@@ -80,42 +80,30 @@ bool
 CopyableCanvasLayer::IsDataValid(const Data& aData)
 {
   return mGLContext == aData.mGLContext;
 }
 
 void
 CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
 {
-  AutoReturnSnapshot autoReturn;
-
   if (mAsyncRenderer) {
     mSurface = mAsyncRenderer->GetSurface();
   } else if (!mGLFrontbuffer && mBufferProvider) {
-    mSurface = mBufferProvider->BorrowSnapshot();
-    if (aDestTarget) {
-      // If !aDestTarget we'll end up painting using mSurface later,
-      // so we can't return it to the provider (note that this will trigger a
-      // copy of the snapshot behind the scenes when the provider is unlocked).
-      autoReturn.mSnapshot = &mSurface;
-    }
-    // Either way we need to call ReturnSnapshot because ther may be an
-    // underlying TextureClient that has to be unlocked.
-    autoReturn.mBufferProvider = mBufferProvider;
+    mSurface = mBufferProvider->GetSnapshot();
   }
 
   if (!mGLContext && aDestTarget) {
     NS_ASSERTION(mSurface, "Must have surface to draw!");
     if (mSurface) {
       aDestTarget->CopySurface(mSurface,
                                IntRect(0, 0, mBounds.width, mBounds.height),
                                IntPoint(0, 0));
       mSurface = nullptr;
     }
-
     return;
   }
 
   if ((!mGLFrontbuffer && mBufferProvider) || mAsyncRenderer) {
     return;
   }
 
   MOZ_ASSERT(mGLContext);
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -172,22 +172,27 @@ LayerManager::CreateDrawTarget(const Int
     CreateOffscreenCanvasDrawTarget(aSize, aFormat);
 }
 
 already_AddRefed<PersistentBufferProvider>
 LayerManager::CreatePersistentBufferProvider(const mozilla::gfx::IntSize &aSize,
                                              mozilla::gfx::SurfaceFormat aFormat)
 {
   RefPtr<PersistentBufferProviderBasic> bufferProvider =
-    PersistentBufferProviderBasic::Create(aSize, aFormat,
-      gfxPlatform::GetPlatform()->GetPreferredCanvasBackend());
+    new PersistentBufferProviderBasic(aSize, aFormat,
+                                      gfxPlatform::GetPlatform()->GetPreferredCanvasBackend());
 
-  if (!bufferProvider) {
-    bufferProvider = PersistentBufferProviderBasic::Create(aSize, aFormat,
-      gfxPlatform::GetPlatform()->GetFallbackCanvasBackend());
+  if (!bufferProvider->IsValid()) {
+    bufferProvider =
+      new PersistentBufferProviderBasic(aSize, aFormat,
+                                        gfxPlatform::GetPlatform()->GetFallbackCanvasBackend());
+  }
+
+  if (!bufferProvider->IsValid()) {
+    return nullptr;
   }
 
   return bufferProvider.forget();
 }
 
 #ifdef DEBUG
 void
 LayerManager::Mutated(Layer* aLayer)
--- a/gfx/layers/PersistentBufferProvider.cpp
+++ b/gfx/layers/PersistentBufferProvider.cpp
@@ -11,221 +11,16 @@
 #include "gfxPlatform.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
-PersistentBufferProviderBasic::PersistentBufferProviderBasic(DrawTarget* aDt)
-: mDrawTarget(aDt)
-{
-  MOZ_COUNT_CTOR(PersistentBufferProviderBasic);
-}
-
-PersistentBufferProviderBasic::~PersistentBufferProviderBasic()
-{
-  MOZ_COUNT_DTOR(PersistentBufferProviderBasic);
-}
-
-already_AddRefed<gfx::DrawTarget>
-PersistentBufferProviderBasic::BorrowDrawTarget(const gfx::IntRect& aPersistedRect)
-{
-  MOZ_ASSERT(!mSnapshot);
-  RefPtr<gfx::DrawTarget> dt(mDrawTarget);
-  return dt.forget();
-}
-
-bool
-PersistentBufferProviderBasic::ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT)
-{
-  RefPtr<gfx::DrawTarget> dt(aDT);
-  MOZ_ASSERT(mDrawTarget == dt);
-  return true;
-}
-
-already_AddRefed<gfx::SourceSurface>
-PersistentBufferProviderBasic::BorrowSnapshot()
-{
-  mSnapshot = mDrawTarget->Snapshot();
-  RefPtr<SourceSurface> snapshot = mSnapshot;
-  return snapshot.forget();
-}
-
-void
-PersistentBufferProviderBasic::ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot)
-{
-  RefPtr<SourceSurface> snapshot = aSnapshot;
-  MOZ_ASSERT(!snapshot || snapshot == mSnapshot);
-  mSnapshot = nullptr;
-}
-
-//static
-already_AddRefed<PersistentBufferProviderBasic>
-PersistentBufferProviderBasic::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                      gfx::BackendType aBackend)
-{
-  RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(aBackend, aSize, aFormat);
-
-  if (!dt) {
-    return nullptr;
-  }
-
-  RefPtr<PersistentBufferProviderBasic> provider =
-    new PersistentBufferProviderBasic(dt);
-
-  return provider.forget();
-}
-
-
-//static
-already_AddRefed<PersistentBufferProviderShared>
-PersistentBufferProviderShared::Create(gfx::IntSize aSize,
-                                       gfx::SurfaceFormat aFormat,
-                                       CompositableForwarder* aFwd)
-{
-  if (!aFwd || !aFwd->IPCOpen()) {
-    return nullptr;
-  }
-
-  RefPtr<TextureClient> texture = TextureClient::CreateForDrawing(
-    aFwd, aFormat, aSize,
-    BackendSelector::Canvas,
-    TextureFlags::IMMEDIATE_UPLOAD,
-    TextureAllocationFlags::ALLOC_DEFAULT
-  );
-
-  if (!texture) {
-    return nullptr;
-  }
-
-  RefPtr<PersistentBufferProviderShared> provider =
-    new PersistentBufferProviderShared(aSize, aFormat, aFwd, texture);
-  return provider.forget();
-}
-
-PersistentBufferProviderShared::PersistentBufferProviderShared(gfx::IntSize aSize,
-                                                               gfx::SurfaceFormat aFormat,
-                                                               CompositableForwarder* aFwd,
-                                                               RefPtr<TextureClient>& aTexture)
-
-: mSize(aSize)
-, mFormat(aFormat)
-, mFwd(aFwd)
-, mBack(aTexture.forget())
-{
-  MOZ_COUNT_CTOR(PersistentBufferProviderShared);
-}
-
-PersistentBufferProviderShared::~PersistentBufferProviderShared()
+PersistentBufferProviderBasic::PersistentBufferProviderBasic(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
+                                                             gfx::BackendType aBackend)
 {
-  MOZ_COUNT_DTOR(PersistentBufferProviderShared);
-
-  mDrawTarget = nullptr;
-  if (mBack && mBack->IsLocked()) {
-    mBack->Unlock();
-  }
-  if (mFront && mFront->IsLocked()) {
-    mFront->Unlock();
-  }
-}
-
-already_AddRefed<gfx::DrawTarget>
-PersistentBufferProviderShared::BorrowDrawTarget(const gfx::IntRect& aPersistedRect)
-{
-  if (!mFwd->IPCOpen()) {
-    return nullptr;
-  }
-
-  if (!mDrawTarget) {
-    if (!mBack) {
-      mBack = TextureClient::CreateForDrawing(
-        mFwd, mFormat, mSize,
-        BackendSelector::Canvas,
-        TextureFlags::IMMEDIATE_UPLOAD,
-        TextureAllocationFlags::ALLOC_DEFAULT
-      );
-    }
-
-    if (!mBack) {
-      return nullptr;
-    }
-
-    if (!mBack->Lock(OpenMode::OPEN_READ_WRITE)) {
-      return nullptr;
-    }
-    if (!aPersistedRect.IsEmpty() && mFront
-        && mFront->Lock(OpenMode::OPEN_READ)) {
-
-      DebugOnly<bool> success = mFront->CopyToTextureClient(mBack, &aPersistedRect, nullptr);
-      MOZ_ASSERT(success);
-
-      mFront->Unlock();
-    }
-
-    mDrawTarget = mBack->BorrowDrawTarget();
-    if (!mDrawTarget) {
-      return nullptr;
-    }
-  }
-
-  RefPtr<gfx::DrawTarget> dt(mDrawTarget);
-  return dt.forget();
-}
-
-bool
-PersistentBufferProviderShared::ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT)
-{
-  RefPtr<gfx::DrawTarget> dt(aDT);
-  MOZ_ASSERT(mDrawTarget == dt);
-
-  mDrawTarget = nullptr;
-  dt = nullptr;
-
-  mBack->Unlock();
-
-  mFront = mBack;
-  mBack = nullptr;
-
-  return true;
-}
-
-already_AddRefed<gfx::SourceSurface>
-PersistentBufferProviderShared::BorrowSnapshot()
-{
-  if (!mFront || mFront->IsLocked()) {
-    MOZ_ASSERT(false);
-    return nullptr;
-  }
-
-  if (!mFront->Lock(OpenMode::OPEN_READ)) {
-    return nullptr;
-  }
-
-  mDrawTarget = mFront->BorrowDrawTarget();
-
-  if (!mDrawTarget) {
-    mFront->Unlock();
-  }
-
-  mSnapshot = mDrawTarget->Snapshot();
-
-  RefPtr<SourceSurface> snapshot = mSnapshot;
-  return snapshot.forget();
-}
-
-void
-PersistentBufferProviderShared::ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot)
-{
-  RefPtr<SourceSurface> snapshot = aSnapshot;
-  MOZ_ASSERT(!snapshot || snapshot == mSnapshot);
-
-  mSnapshot = nullptr;
-  snapshot = nullptr;
-
-  mDrawTarget = nullptr;
-
-  mFront->Unlock();
+  mDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(aBackend, aSize, aFormat);
 }
 
 } // namespace layers
 } // namespace mozilla
\ No newline at end of file
--- a/gfx/layers/PersistentBufferProvider.h
+++ b/gfx/layers/PersistentBufferProvider.h
@@ -8,22 +8,16 @@
 
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed, etc
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/gfx/Types.h"
 
 namespace mozilla {
-
-namespace gfx {
-  class SourceSurface;
-  class DrawTarget;
-}
-
 namespace layers {
 
 class CopyableCanvasLayer;
 
 /**
  * A PersistentBufferProvider is for users which require the temporary use of
  * a DrawTarget to draw into. When they're done drawing they return the
  * DrawTarget, when they later need to continue drawing they get a DrawTarget
@@ -39,120 +33,51 @@ public:
 
   virtual LayersBackend GetType() { return LayersBackend::LAYERS_NONE; }
 
   /**
    * Get a DrawTarget from the PersistentBufferProvider.
    *
    * \param aPersistedRect This indicates the area of the DrawTarget that needs
    *                       to have remained the same since the call to
-   *                       ReturnDrawTarget.
+   *                       ReturnAndUseDT.
    */
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) = 0;
-
+  virtual already_AddRefed<gfx::DrawTarget> GetDT(const gfx::IntRect& aPersistedRect) = 0;
   /**
    * Return a DrawTarget to the PersistentBufferProvider and indicate the
    * contents of this DrawTarget is to be considered current by the
    * BufferProvider. The caller should forget any references to the DrawTarget.
    */
-  virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) = 0;
-
-  virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() = 0;
+  virtual bool ReturnAndUseDT(already_AddRefed<gfx::DrawTarget> aDT) = 0;
 
-  virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) = 0;
-
-  virtual TextureClient* GetTextureClient() { return nullptr; }
+  virtual already_AddRefed<gfx::SourceSurface> GetSnapshot() = 0;
+protected:
 };
 
-
 class PersistentBufferProviderBasic : public PersistentBufferProvider
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic, override)
-
-  static already_AddRefed<PersistentBufferProviderBasic>
-  Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, gfx::BackendType aBackend);
-
-  explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget);
-
-  virtual LayersBackend GetType() override { return LayersBackend::LAYERS_BASIC; }
-
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) override;
-
-  virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
-
-  virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override;
-
-  virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
-
-private:
-  ~PersistentBufferProviderBasic();
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderBasic)
 
-  RefPtr<gfx::DrawTarget> mDrawTarget;
-  RefPtr<gfx::SourceSurface> mSnapshot;
-};
-
-
-/**
- * Provides access to a buffer which can be sent to the compositor without
- * requiring a copy.
- */
-class PersistentBufferProviderShared : public PersistentBufferProvider
-{
-public:
-  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderShared, override)
-
-  static already_AddRefed<PersistentBufferProviderShared>
-  Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-         CompositableForwarder* aFwd);
-
-  virtual LayersBackend GetType() override { return LayersBackend::LAYERS_CLIENT; }
-
-  virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) override;
+  PersistentBufferProviderBasic(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
+                                gfx::BackendType aBackend);
+  explicit PersistentBufferProviderBasic(gfx::DrawTarget* aTarget) : mDrawTarget(aTarget) {}
 
-  virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override;
-
-  virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override;
-
-  virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
-
-  TextureClient* GetTextureClient() override {
-    return mFront;
+  bool IsValid() { return !!mDrawTarget; }
+  virtual LayersBackend GetType() { return LayersBackend::LAYERS_BASIC; }
+  already_AddRefed<gfx::DrawTarget> GetDT(const gfx::IntRect& aPersistedRect) {
+    RefPtr<gfx::DrawTarget> dt(mDrawTarget);
+    return dt.forget();
   }
-
-protected:
-  PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                 CompositableForwarder* aFwd,
-                                 RefPtr<TextureClient>& aTexture);
-
-  ~PersistentBufferProviderShared();
-
-  gfx::IntSize mSize;
-  gfx::SurfaceFormat mFormat;
-  RefPtr<CompositableForwarder> mFwd;
-  RefPtr<TextureClient> mFront;
-  RefPtr<TextureClient> mBack;
+  bool ReturnAndUseDT(already_AddRefed<gfx::DrawTarget> aDT) {
+    RefPtr<gfx::DrawTarget> dt(aDT);
+    MOZ_ASSERT(mDrawTarget == dt);
+    return true;
+  }
+  virtual already_AddRefed<gfx::SourceSurface> GetSnapshot() { return mDrawTarget->Snapshot(); }
+private:
   RefPtr<gfx::DrawTarget> mDrawTarget;
-  RefPtr<gfx::SourceSurface > mSnapshot;
-};
-
-struct AutoReturnSnapshot
-{
-  PersistentBufferProvider* mBufferProvider;
-  RefPtr<gfx::SourceSurface>* mSnapshot;
-
-  explicit AutoReturnSnapshot(PersistentBufferProvider* aProvider = nullptr)
-  : mBufferProvider(aProvider)
-  , mSnapshot(nullptr)
-  {}
-
-  ~AutoReturnSnapshot()
-  {
-    if (mBufferProvider) {
-      mBufferProvider->ReturnSnapshot(mSnapshot ? mSnapshot->forget() : nullptr);
-    }
-  }
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -62,40 +62,16 @@ CanvasClientBridge::UpdateAsync(AsyncCan
   }
 
   static_cast<ShadowLayerForwarder*>(GetForwarder())
     ->AttachAsyncCompositable(asyncID, mLayer);
   mAsyncID = asyncID;
 }
 
 void
-CanvasClient2D::UpdateFromTexture(TextureClient* aTexture)
-{
-  MOZ_ASSERT(aTexture);
-
-  if (!aTexture->IsSharedWithCompositor()) {
-    if (!AddTextureClient(aTexture)) {
-      return;
-    }
-  }
-
-  mBackBuffer = aTexture;
-
-  AutoTArray<CompositableForwarder::TimedTextureClient,1> textures;
-  CompositableForwarder::TimedTextureClient* t = textures.AppendElement();
-  t->mTextureClient = mBackBuffer;
-  t->mPictureRect = nsIntRect(nsIntPoint(0, 0), aTexture->GetSize());
-  t->mFrameID = mFrameID;
-  t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID();
-
-  GetForwarder()->UseTextures(this, textures);
-  aTexture->SyncWithObject(GetForwarder()->GetSyncObject());
-}
-
-void
 CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
 {
   AutoRemoveTexture autoRemove(this);
   if (mBackBuffer &&
       (mBackBuffer->IsImmutable() || mBackBuffer->GetSize() != aSize)) {
     autoRemove.mTexture = mBackBuffer;
     mBackBuffer = nullptr;
   }
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -8,17 +8,16 @@
 
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed
 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient
 #include "mozilla/layers/CompositorTypes.h"  // for TextureInfo, etc
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor
 #include "mozilla/layers/TextureClient.h"  // for TextureClient, etc
-#include "mozilla/layers/PersistentBufferProvider.h"
 
 // Fix X11 header brain damage that conflicts with MaybeOneOf::None
 #undef None
 #include "mozilla/MaybeOneOf.h"
 
 #include "mozilla/mozalloc.h"           // for operator delete
 
 #include "mozilla/gfx/Point.h"          // for IntSize
@@ -72,18 +71,16 @@ public:
   virtual bool AddTextureClient(TextureClient* aTexture) override
   {
     ++mFrameID;
     return CompositableClient::AddTextureClient(aTexture);
   }
 
   virtual void UpdateAsync(AsyncCanvasRenderer* aRenderer) {}
 
-  virtual void UpdateFromTexture(TextureClient* aTexture) {}
-
   virtual void Updated() { }
 
 protected:
   int32_t mFrameID;
 };
 
 // Used for 2D canvases and WebGL canvas on non-GL systems where readback is requried.
 class CanvasClient2D : public CanvasClient
@@ -102,18 +99,16 @@ public:
 
   virtual void Clear() override
   {
     mBackBuffer = mFrontBuffer = nullptr;
   }
 
   virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) override;
 
-  virtual void UpdateFromTexture(TextureClient* aBuffer) override;
-
   virtual bool AddTextureClient(TextureClient* aTexture) override
   {
     MOZ_ASSERT((mTextureFlags & aTexture->GetFlags()) == mTextureFlags);
     return CanvasClient::AddTextureClient(aTexture);
   }
 
   virtual void OnDetach() override
   {
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -125,21 +125,17 @@ ClientCanvasLayer::RenderLayer()
   }
 
   if (!IsDirty()) {
     return;
   }
   Painted();
 
   FirePreTransactionCallback();
-  if (mBufferProvider && mBufferProvider->GetTextureClient()) {
-    mCanvasClient->UpdateFromTexture(mBufferProvider->GetTextureClient());
-  } else {
-    mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);
-  }
+  mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);
 
   FireDidTransactionCallback();
 
   ClientManager()->Hold(this);
   mCanvasClient->Updated();
 }
 
 CanvasClient::CanvasClientType
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -843,25 +843,16 @@ ClientLayerManager::RemoveDidCompositeOb
 }
 
 bool
 ClientLayerManager::DependsOnStaleDevice() const
 {
   return gfxPlatform::GetPlatform()->GetDeviceCounter() != mDeviceCounter;
 }
 
-
-already_AddRefed<PersistentBufferProvider>
-ClientLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize,
-                                                   gfx::SurfaceFormat aFormat)
-{
-  return PersistentBufferProviderShared::Create(aSize, aFormat, AsShadowForwarder());
-}
-
-
 ClientLayer::~ClientLayer()
 {
   if (HasShadow()) {
     PLayerChild::Send__delete__(GetShadow());
   }
   MOZ_COUNT_DTOR(ClientLayer);
 }
 
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -241,19 +241,16 @@ public:
   class DidCompositeObserver {
   public:
     virtual void DidComposite() = 0;
   };
 
   void AddDidCompositeObserver(DidCompositeObserver* aObserver);
   void RemoveDidCompositeObserver(DidCompositeObserver* aObserver);
 
-  virtual already_AddRefed<PersistentBufferProvider>
-  CreatePersistentBufferProvider(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat) override;
-
 protected:
   enum TransactionPhase {
     PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
   };
   TransactionPhase mPhase;
 
 private:
   // Listen memory-pressure event for ClientLayerManager