Backed out changeset cf6a31bca4e0 (bug 939276) for webgl reftest crash
authorWes Kocher <wkocher@mozilla.com>
Thu, 20 Feb 2014 15:23:52 -0800
changeset 170138 bde06c79829fa7819a7dfeec2e4dc3beff905388
parent 170137 13cc8a7ee9257a27dae141b2dab83d1f295027ae
child 170139 774001539b7ee989428bb41be52320855600c811
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
bugs939276
milestone30.0a1
backs outcf6a31bca4e0374128683c0ed35957cbb98e256d
Backed out changeset cf6a31bca4e0 (bug 939276) for webgl reftest crash
content/canvas/src/CanvasRenderingContext2D.cpp
content/canvas/src/CanvasRenderingContext2D.h
gfx/2d/2D.h
gfx/2d/DrawTargetSkia.cpp
gfx/2d/DrawTargetSkia.h
gfx/2d/Factory.cpp
gfx/2d/Types.h
gfx/gl/GLContextSkia.cpp
gfx/gl/GLContextSkia.h
gfx/gl/GLScreenBuffer.cpp
gfx/gl/GLScreenBuffer.h
gfx/gl/SharedSurfaceGL.cpp
gfx/gl/SharedSurfaceGL.h
gfx/gl/SkiaGLGlue.cpp
gfx/gl/SkiaGLGlue.h
gfx/gl/SurfaceStream.cpp
gfx/gl/SurfaceStream.h
gfx/gl/moz.build
gfx/layers/CopyableCanvasLayer.cpp
gfx/layers/CopyableCanvasLayer.h
gfx/layers/Layers.h
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/ClientCanvasLayer.cpp
gfx/layers/client/ClientCanvasLayer.h
gfx/layers/opengl/TextureClientOGL.cpp
gfx/layers/opengl/TextureClientOGL.h
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatform.h
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -89,24 +89,24 @@
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/TextMetrics.h"
 #include "mozilla/dom/UnionTypes.h"
 #include "nsGlobalWindow.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 
+#ifdef USE_SKIA_GPU
 #undef free // apparently defined by some windows header, clashing with a free()
             // method in SkTypes.h
-#include "SkiaGLGlue.h"
-#include "SurfaceStream.h"
+#include "GLContextSkia.h"
 #include "SurfaceTypes.h"
-
+#include "nsIGfxInfo.h"
+#endif
 using mozilla::gl::GLContext;
-using mozilla::gl::SkiaGLGlue;
 using mozilla::gl::GLContextProvider;
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 #include "mozilla/layers/ShadowLayers.h"
@@ -425,28 +425,38 @@ public:
   }
   ~CanvasRenderingContext2DUserData()
   {
     if (mContext) {
       mContext->mUserDatas.RemoveElement(this);
     }
   }
 
+#ifdef USE_SKIA_GPU
   static void PreTransactionCallback(void* aData)
   {
     CanvasRenderingContext2DUserData* self =
       static_cast<CanvasRenderingContext2DUserData*>(aData);
     CanvasRenderingContext2D* context = self->mContext;
-    if (!context || !context->mStream || !context->mTarget)
+    if (!context)
+      return;
+
+    GLContext* glContext = static_cast<GLContext*>(context->mTarget->GetGLContext());
+    if (!glContext)
       return;
 
-    // Since SkiaGL default to store drawing command until flush
-    // We will have to flush it before present.
-    context->mTarget->Flush();
+    if (context->mTarget) {
+      // Since SkiaGL default to store drawing command until flush
+      // We will have to flush it before present.
+      context->mTarget->Flush();
+    }
+    glContext->MakeCurrent();
+    glContext->PublishFrame();
   }
+#endif
 
   static void DidTransactionCallback(void* aData)
   {
     CanvasRenderingContext2DUserData* self =
       static_cast<CanvasRenderingContext2DUserData*>(aData);
     if (self->mContext) {
       self->mContext->MarkContextClean();
     }
@@ -527,40 +537,45 @@ NS_INTERFACE_MAP_END
 
 // Initialize our static variables.
 uint32_t CanvasRenderingContext2D::sNumLivingContexts = 0;
 DrawTarget* CanvasRenderingContext2D::sErrorTarget = nullptr;
 
 
 
 CanvasRenderingContext2D::CanvasRenderingContext2D()
-  : mForceSoftware(false), mZero(false), mOpaque(false), mResetLayer(true)
+  : mZero(false), mOpaque(false), mResetLayer(true)
   , mIPC(false)
-  , mStream(nullptr)
   , mIsEntireFrameInvalid(false)
   , mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
   , mInvalidateCount(0)
 {
   sNumLivingContexts++;
   SetIsDOMBinding();
+
+#ifdef USE_SKIA_GPU
+  mForceSoftware = false;
+#endif
 }
 
 CanvasRenderingContext2D::~CanvasRenderingContext2D()
 {
   Reset();
   // Drop references from all CanvasRenderingContext2DUserData to this context
   for (uint32_t i = 0; i < mUserDatas.Length(); ++i) {
     mUserDatas[i]->Forget();
   }
   sNumLivingContexts--;
   if (!sNumLivingContexts) {
     NS_IF_RELEASE(sErrorTarget);
   }
 
+#ifdef USE_SKIA_GPU
   RemoveDemotableContext(this);
+#endif
 }
 
 JSObject*
 CanvasRenderingContext2D::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope)
 {
   return CanvasRenderingContext2DBinding::Wrap(cx, scope, this);
 }
 
@@ -609,17 +624,16 @@ CanvasRenderingContext2D::Reset()
 
   // only do this for non-docshell created contexts,
   // since those are the ones that we created a surface for
   if (mTarget && IsTargetValid() && !mDocShell) {
     gCanvasAzureMemoryUsed -= mWidth * mHeight * 4;
   }
 
   mTarget = nullptr;
-  mStream = nullptr;
 
   // Since the target changes the backing texture will change, and this will
   // no longer be valid.
   mIsEntireFrameInvalid = false;
   mPredictManyRedrawCalls = false;
 
   return NS_OK;
 }
@@ -731,25 +745,25 @@ CanvasRenderingContext2D::RedrawUser(con
 
   mgfx::Rect newr =
     mTarget->GetTransform().TransformBounds(ToRect(r));
   Redraw(newr);
 }
 
 void CanvasRenderingContext2D::Demote()
 {
-  if (!IsTargetValid() || mForceSoftware || !mStream)
+#ifdef  USE_SKIA_GPU
+  if (!IsTargetValid() || mForceSoftware || !mTarget->GetGLContext())
     return;
 
   RemoveDemotableContext(this);
 
   RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
   RefPtr<DrawTarget> oldTarget = mTarget;
   mTarget = nullptr;
-  mStream = nullptr;
   mResetLayer = true;
   mForceSoftware = true;
 
   // Recreate target, now demoted to software only
   EnsureTarget();
   if (!IsTargetValid())
     return;
 
@@ -758,29 +772,36 @@ void CanvasRenderingContext2D::Demote()
   mTarget->DrawSurface(snapshot, r, r);
 
   // Restore the clips and transform
   for (uint32_t i = 0; i < CurrentState().clipsPushed.size(); i++) {
     mTarget->PushClip(CurrentState().clipsPushed[i]);
   }
 
   mTarget->SetTransform(oldTarget->GetTransform());
+#endif
 }
 
+#ifdef USE_SKIA_GPU
+
 std::vector<CanvasRenderingContext2D*>&
 CanvasRenderingContext2D::DemotableContexts()
 {
   static std::vector<CanvasRenderingContext2D*> contexts;
   return contexts;
 }
 
 void
 CanvasRenderingContext2D::DemoteOldestContextIfNecessary()
 {
-  const size_t kMaxContexts = 64;
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+  const size_t kMaxContexts = 2;
+#else
+  const size_t kMaxContexts = 16;
+#endif
 
   std::vector<CanvasRenderingContext2D*>& contexts = DemotableContexts();
   if (contexts.size() < kMaxContexts)
     return;
 
   CanvasRenderingContext2D* oldest = contexts.front();
   oldest->Demote();
 }
@@ -804,16 +825,18 @@ CanvasRenderingContext2D::RemoveDemotabl
 }
 
 bool
 CheckSizeForSkiaGL(IntSize size) {
   int minsize = Preferences::GetInt("gfx.canvas.min-size-for-skia-gl", 128);
   return size.width >= minsize && size.height >= minsize;
 }
 
+#endif
+
 void
 CanvasRenderingContext2D::EnsureTarget()
 {
   if (mTarget) {
     return;
   }
 
    // Check that the dimensions are sane
@@ -829,39 +852,52 @@ CanvasRenderingContext2D::EnsureTarget()
     nsRefPtr<LayerManager> layerManager = nullptr;
 
     if (ownerDoc) {
       layerManager =
         nsContentUtils::PersistentLayerManagerForDocument(ownerDoc);
     }
 
      if (layerManager) {
-      if (gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas() &&
-          !mForceSoftware &&
-          CheckSizeForSkiaGL(size)) {
+#ifdef USE_SKIA_GPU
+      if (gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas()) {
+        SurfaceCaps caps = SurfaceCaps::ForRGBA();
+        caps.preserve = true;
+
+#ifdef MOZ_WIDGET_GONK
+        layers::ShadowLayerForwarder *forwarder = layerManager->AsShadowForwarder();
+        if (forwarder) {
+          caps.surfaceAllocator = static_cast<layers::ISurfaceAllocator*>(forwarder);
+        }
+#endif
+
         DemoteOldestContextIfNecessary();
 
-        SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
-
-        if (glue) {
-          mTarget = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(), size, format);
-          if (mTarget) {
-            mStream = gfx::SurfaceStream::CreateForType(SurfaceStreamType::TripleBuffer, glue->GetGLContext());
-            AddDemotableContext(this);
-          } else {
-            printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n");
-          }
+        nsRefPtr<GLContext> glContext;
+        nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
+        nsString vendor;
+
+        if (!mForceSoftware && CheckSizeForSkiaGL(size))
+        {
+          glContext = GLContextProvider::CreateOffscreen(gfxIntSize(size.width, size.height),
+                                                         caps);
         }
-        if (!mTarget) {
+
+        if (glContext) {
+          SkAutoTUnref<GrGLInterface> i(CreateGrGLInterfaceFromGLContext(glContext));
+          mTarget = Factory::CreateDrawTargetSkiaWithGLContextAndGrGLInterface(glContext, i, size, format);
+          AddDemotableContext(this);
+        } else {
           mTarget = layerManager->CreateDrawTarget(size, format);
         }
       } else
-        mTarget = layerManager->CreateDrawTarget(size, format);
+#endif
+       mTarget = layerManager->CreateDrawTarget(size, format);
      } else {
-        mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
+       mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
      }
   }
 
   if (mTarget) {
     static bool registered = false;
     if (!registered) {
       registered = true;
       RegisterStrongMemoryReporter(new Canvas2dPixelsReporter());
@@ -1036,20 +1072,22 @@ CanvasRenderingContext2D::SetContextOpti
 {
   if (aOptions.isNullOrUndefined()) {
     return NS_OK;
   }
 
   ContextAttributes2D attributes;
   NS_ENSURE_TRUE(attributes.Init(aCx, aOptions), NS_ERROR_UNEXPECTED);
 
+#ifdef USE_SKIA_GPU
   if (Preferences::GetBool("gfx.canvas.willReadFrequently.enable", false)) {
     // Use software when there is going to be a lot of readback
     mForceSoftware = attributes.mWillReadFrequently;
   }
+#endif
 
   return NS_OK;
 }
 
 void
 CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer,
                                          int32_t* aFormat)
 {
@@ -3203,31 +3241,33 @@ CanvasRenderingContext2D::DrawDirectlyTo
          gfxRect(gfxPoint(dx, dy), gfxIntSize(dw, dh)),
          nsIntRect(nsIntPoint(0, 0), gfxIntSize(imgSize.width, imgSize.height)),
          gfxIntSize(imgSize.width, imgSize.height), nullptr, image.mWhichFrame,
          modifiedFlags);
 
   NS_ENSURE_SUCCESS_VOID(rv);
 }
 
+#ifdef USE_SKIA_GPU
 static bool
 IsStandardCompositeOp(CompositionOp op)
 {
     return (op == CompositionOp::OP_SOURCE ||
             op == CompositionOp::OP_ATOP ||
             op == CompositionOp::OP_IN ||
             op == CompositionOp::OP_OUT ||
             op == CompositionOp::OP_OVER ||
             op == CompositionOp::OP_DEST_IN ||
             op == CompositionOp::OP_DEST_OUT ||
             op == CompositionOp::OP_DEST_OVER ||
             op == CompositionOp::OP_DEST_ATOP ||
             op == CompositionOp::OP_ADD ||
             op == CompositionOp::OP_XOR);
 }
+#endif
 
 void
 CanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op,
                                                       ErrorResult& error)
 {
   CompositionOp comp_op;
 
 #define CANVAS_OP_TO_GFX_OP(cvsop, op2d) \
@@ -3258,19 +3298,21 @@ CanvasRenderingContext2D::SetGlobalCompo
   else CANVAS_OP_TO_GFX_OP("exclusion", EXCLUSION)
   else CANVAS_OP_TO_GFX_OP("hue", HUE)
   else CANVAS_OP_TO_GFX_OP("saturation", SATURATION)
   else CANVAS_OP_TO_GFX_OP("color", COLOR)
   else CANVAS_OP_TO_GFX_OP("luminosity", LUMINOSITY)
   // XXX ERRMSG we need to report an error to developers here! (bug 329026)
   else return;
 
+#ifdef USE_SKIA_GPU
   if (!IsStandardCompositeOp(comp_op)) {
     Demote();
   }
+#endif
 
 #undef CANVAS_OP_TO_GFX_OP
   CurrentState().op = comp_op;
 }
 
 void
 CanvasRenderingContext2D::GetGlobalCompositeOperation(nsAString& op,
                                                       ErrorResult& error)
@@ -3306,19 +3348,21 @@ CanvasRenderingContext2D::GetGlobalCompo
   else CANVAS_OP_TO_GFX_OP("hue", HUE)
   else CANVAS_OP_TO_GFX_OP("saturation", SATURATION)
   else CANVAS_OP_TO_GFX_OP("color", COLOR)
   else CANVAS_OP_TO_GFX_OP("luminosity", LUMINOSITY)
   else {
     error.Throw(NS_ERROR_FAILURE);
   }
 
+#ifdef USE_SKIA_GPU
   if (!IsStandardCompositeOp(comp_op)) {
     Demote();
   }
+#endif
 
 #undef CANVAS_OP_TO_GFX_OP
 }
 
 void
 CanvasRenderingContext2D::DrawWindow(nsGlobalWindow& window, double x,
                                      double y, double w, double h,
                                      const nsAString& bgColor,
@@ -4008,27 +4052,17 @@ CanvasRenderingContext2D::GetCanvasLayer
   mTarget->Flush();
 
   if (!mResetLayer && aOldLayer) {
     CanvasRenderingContext2DUserData* userData =
       static_cast<CanvasRenderingContext2DUserData*>(
         aOldLayer->GetUserData(&g2DContextLayerUserData));
 
     CanvasLayer::Data data;
-    if (mStream) {
-      SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
-
-      if (glue) {
-        data.mGLContext = glue->GetGLContext();
-        data.mStream = mStream.get();
-      }
-    } else {
-      data.mDrawTarget = mTarget;
-    }
-
+    data.mGLContext = static_cast<GLContext*>(mTarget->GetGLContext());
     if (userData && userData->IsForContext(this) && aOldLayer->IsDataValid(data)) {
       nsRefPtr<CanvasLayer> ret = aOldLayer;
       return ret.forget();
     }
   }
 
   nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
   if (!canvasLayer) {
@@ -4051,27 +4085,25 @@ CanvasRenderingContext2D::GetCanvasLayer
   // The userData will receive DidTransactionCallbacks, which flush the
   // the invalidation state to indicate that the canvas is up to date.
   userData = new CanvasRenderingContext2DUserData(this);
   canvasLayer->SetDidTransactionCallback(
           CanvasRenderingContext2DUserData::DidTransactionCallback, userData);
   canvasLayer->SetUserData(&g2DContextLayerUserData, userData);
 
   CanvasLayer::Data data;
-  if (mStream) {
-    SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
-
-    if (glue) {
-      canvasLayer->SetPreTransactionCallback(
-              CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
-      data.mGLContext = glue->GetGLContext();
-      data.mStream = mStream.get();
-      data.mTexID = (uint32_t)((uintptr_t)mTarget->GetNativeSurface(NativeSurfaceType::OPENGL_TEXTURE));
-    }
-  } else {
+#ifdef USE_SKIA_GPU
+  GLContext* glContext = static_cast<GLContext*>(mTarget->GetGLContext());
+  if (glContext) {
+    canvasLayer->SetPreTransactionCallback(
+            CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
+    data.mGLContext = glContext;
+  } else
+#endif
+  {
     data.mDrawTarget = mTarget;
   }
 
   data.mSize = nsIntSize(mWidth, mHeight);
 
   canvasLayer->Initialize(data);
   uint32_t flags = mOpaque ? Layer::CONTENT_OPAQUE : 0;
   canvasLayer->SetContentFlags(flags);
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -26,17 +26,16 @@
 #include "nsLayoutUtils.h"
 
 class nsGlobalWindow;
 class nsXULElement;
 
 namespace mozilla {
 namespace gfx {
 class SourceSurface;
-class SurfaceStream;
 }
 
 namespace dom {
 class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
 class ImageData;
 class StringOrCanvasGradientOrCanvasPattern;
 class OwningStringOrCanvasGradientOrCanvasPattern;
 class TextMetrics;
@@ -589,24 +588,26 @@ protected:
   nsString& GetFont()
   {
     /* will initilize the value if not set, else does nothing */
     GetCurrentFontStyle();
 
     return CurrentState().font;
   }
 
+#if USE_SKIA_GPU
   static std::vector<CanvasRenderingContext2D*>& DemotableContexts();
   static void DemoteOldestContextIfNecessary();
 
   static void AddDemotableContext(CanvasRenderingContext2D* context);
   static void RemoveDemotableContext(CanvasRenderingContext2D* context);
 
   // Do not use GL
   bool mForceSoftware;
+#endif
 
   // Member vars
   int32_t mWidth, mHeight;
 
   // This is true when the canvas is valid, but of zero size, this requires
   // specific behavior on some operations.
   bool mZero;
 
@@ -623,18 +624,16 @@ protected:
   // If mCanvasElement is not provided, then a docshell is
   nsCOMPtr<nsIDocShell> mDocShell;
 
   // This is created lazily so it is necessary to call EnsureTarget before
   // accessing it. In the event of an error it will be equal to
   // sErrorTarget.
   mozilla::RefPtr<mozilla::gfx::DrawTarget> mTarget;
 
-  RefPtr<gfx::SurfaceStream> mStream;
-
   /**
     * Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
     * Redraw is called, reset to false when Render is called.
     */
   bool mIsEntireFrameInvalid;
   /**
     * When this is set, the first call to Redraw(gfxRect) should set
     * mIsEntireFrameInvalid since we expect it will be followed by
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -957,20 +957,25 @@ public:
   virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) {
     mPermitSubpixelAA = aPermitSubpixelAA;
   }
 
   bool GetPermitSubpixelAA() {
     return mPermitSubpixelAA;
   }
 
+  virtual GenericRefCountedBase* GetGLContext() const {
+    return nullptr;
+  }
+
 #ifdef USE_SKIA_GPU
-  virtual void InitWithGrContext(GrContext* aGrContext,
-                                 const IntSize &aSize,
-                                 SurfaceFormat aFormat)
+  virtual void InitWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
+                                            GrGLInterface* aGrGLInterface,
+                                            const IntSize &aSize,
+                                            SurfaceFormat aFormat)
   {
     MOZ_CRASH();
   }
 #endif
 
 protected:
   UserData mUserData;
   Matrix mTransform;
@@ -1065,19 +1070,23 @@ public:
 
   static TemporaryRef<DrawEventRecorder>
     CreateEventRecorderForFile(const char *aFilename);
 
   static void SetGlobalEventRecorder(DrawEventRecorder *aRecorder);
 
 #ifdef USE_SKIA_GPU
   static TemporaryRef<DrawTarget>
-    CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
-                                      const IntSize &aSize,
-                                      SurfaceFormat aFormat);
+    CreateDrawTargetSkiaWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
+                                                      GrGLInterface* aGrGLInterface,
+                                                      const IntSize &aSize,
+                                                      SurfaceFormat aFormat);
+
+  static void
+    SetGlobalSkiaCacheLimits(int aCount, int aSizeInBytes);
 #endif
 
   static void PurgeAllCaches();
 
 #if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
   static TemporaryRef<GlyphRenderingOptions>
     CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting);
 #endif
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -73,16 +73,90 @@ public:
   BackendType GetBackendType() const { return BackendType::SKIA; }
 
   std::vector<SkColor> mColors;
   std::vector<SkScalar> mPositions;
   int mCount;
   ExtendMode mExtendMode;
 };
 
+#ifdef USE_SKIA_GPU
+int DrawTargetSkia::sTextureCacheCount = 256;
+int DrawTargetSkia::sTextureCacheSizeInBytes = 96*1024*1024;
+
+static std::vector<DrawTargetSkia*>&
+GLDrawTargets()
+{
+  static std::vector<DrawTargetSkia*> targets;
+  return targets;
+}
+
+void
+DrawTargetSkia::RebalanceCacheLimits()
+{
+  // Divide the global cache limits equally between all currently active GL-backed
+  // Skia DrawTargets.
+  std::vector<DrawTargetSkia*>& targets = GLDrawTargets();
+  uint32_t targetCount = targets.size();
+  if (targetCount == 0)
+    return;
+
+  int individualCacheSize = sTextureCacheSizeInBytes / targetCount;
+  for (uint32_t i = 0; i < targetCount; i++) {
+    targets[i]->SetCacheLimits(sTextureCacheCount, individualCacheSize);
+  }
+}
+
+static void
+AddGLDrawTarget(DrawTargetSkia* target)
+{
+  GLDrawTargets().push_back(target);
+  DrawTargetSkia::RebalanceCacheLimits();
+}
+
+static void
+RemoveGLDrawTarget(DrawTargetSkia* target)
+{
+  std::vector<DrawTargetSkia*>& targets = GLDrawTargets();
+  std::vector<DrawTargetSkia*>::iterator it = std::find(targets.begin(), targets.end(), target);
+  if (it != targets.end()) {
+    targets.erase(it);
+    DrawTargetSkia::RebalanceCacheLimits();
+  }
+}
+
+void
+DrawTargetSkia::SetGlobalCacheLimits(int aCount, int aSizeInBytes)
+{
+  sTextureCacheCount = aCount;
+  sTextureCacheSizeInBytes = aSizeInBytes;
+
+  DrawTargetSkia::RebalanceCacheLimits();
+}
+
+void
+DrawTargetSkia::PurgeCaches()
+{
+  if (mGrContext) {
+    mGrContext->freeGpuResources();
+  }
+}
+
+/* static */ void
+DrawTargetSkia::PurgeAllCaches()
+{
+  std::vector<DrawTargetSkia*>& targets = GLDrawTargets();
+  uint32_t targetCount = targets.size();
+  for (uint32_t i = 0; i < targetCount; i++) {
+    targets[i]->PurgeCaches();
+  }
+}
+
+#endif
+
 /**
  * When constructing a temporary SkBitmap via GetBitmapForSurface, we may also
  * have to construct a temporary DataSourceSurface, which must live as long as
  * the SkBitmap. So we return a pair of the SkBitmap and the (optional)
  * temporary surface.
  */
 struct TempBitmap
 {
@@ -109,22 +183,25 @@ GetBitmapForSurface(SourceSurface* aSurf
                                  surf->GetSize().width, surf->GetSize().height,
                                  surf->Stride());
   result.mBitmap.setPixels(surf->GetData());
   result.mTmpSurface = surf.forget();
   return result;
 }
 
 DrawTargetSkia::DrawTargetSkia()
-  : mTexture(0), mSnapshot(nullptr)
+  : mSnapshot(nullptr)
 {
 }
 
 DrawTargetSkia::~DrawTargetSkia()
 {
+#ifdef USE_SKIA_GPU
+  RemoveGLDrawTarget(this);
+#endif
 }
 
 TemporaryRef<SourceSurface>
 DrawTargetSkia::Snapshot()
 {
   RefPtr<SourceSurfaceSkia> snapshot = mSnapshot;
   if (!snapshot) {
     snapshot = new SourceSurfaceSkia();
@@ -687,43 +764,55 @@ DrawTargetSkia::Init(const IntSize &aSiz
 
   mCanvas = canvas.get();
   mFormat = aFormat;
   return true;
 }
 
 #ifdef USE_SKIA_GPU
 void
-DrawTargetSkia::InitWithGrContext(GrContext* aGrContext,
-                                  const IntSize &aSize,
-                                  SurfaceFormat aFormat)
+DrawTargetSkia::InitWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
+                                                  GrGLInterface* aGrGLInterface,
+                                                  const IntSize &aSize,
+                                                  SurfaceFormat aFormat)
 {
-  mGrContext = aGrContext;
-
+  mGLContext = aGLContext;
   mSize = aSize;
   mFormat = aFormat;
 
-  GrTextureDesc targetDescriptor;
+  mGrGLInterface = aGrGLInterface;
+  mGrGLInterface->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this);
 
-  targetDescriptor.fFlags = kRenderTarget_GrTextureFlagBit;
+  GrBackendContext backendContext = reinterpret_cast<GrBackendContext>(aGrGLInterface);
+  SkAutoTUnref<GrContext> gr(GrContext::Create(kOpenGL_GrBackend, backendContext));
+  mGrContext = gr.get();
+
+  GrBackendRenderTargetDesc targetDescriptor;
+
   targetDescriptor.fWidth = mSize.width;
   targetDescriptor.fHeight = mSize.height;
   targetDescriptor.fConfig = GfxFormatToGrConfig(mFormat);
   targetDescriptor.fOrigin = kBottomLeft_GrSurfaceOrigin;
   targetDescriptor.fSampleCnt = 0;
-
-  SkAutoTUnref<GrTexture> skiaTexture(mGrContext->createUncachedTexture(targetDescriptor, NULL, 0));
+  targetDescriptor.fRenderTargetHandle = 0; // GLContext always exposes the right framebuffer as id 0
 
-  mTexture = (uint32_t)skiaTexture->getTextureHandle();
-
-  SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(mGrContext.get(), skiaTexture->asRenderTarget()));
+  SkAutoTUnref<GrRenderTarget> target(mGrContext->wrapBackendRenderTarget(targetDescriptor));
+  SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(mGrContext.get(), target.get()));
   SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
   mCanvas = canvas.get();
+
+  AddGLDrawTarget(this);
 }
 
+void
+DrawTargetSkia::SetCacheLimits(int aCount, int aSizeInBytes)
+{
+  MOZ_ASSERT(mGrContext, "No GrContext!");
+  mGrContext->setTextureCacheLimits(aCount, aSizeInBytes);
+}
 #endif
 
 void
 DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat)
 {
   SkAlphaType alphaType = kPremul_SkAlphaType;
   if (aFormat == SurfaceFormat::B8G8R8X8) {
     // We have to manually set the A channel to be 255 as Skia doesn't understand BGRX
@@ -745,27 +834,16 @@ void
 DrawTargetSkia::SetTransform(const Matrix& aTransform)
 {
   SkMatrix mat;
   GfxMatrixToSkiaMatrix(aTransform, mat);
   mCanvas->setMatrix(mat);
   mTransform = aTransform;
 }
 
-void*
-DrawTargetSkia::GetNativeSurface(NativeSurfaceType aType)
-{
-  if (aType == NativeSurfaceType::OPENGL_TEXTURE) {
-    return (void*)((uintptr_t)mTexture);
-  }
-
-  return nullptr;  
-}
-
-
 TemporaryRef<PathBuilder> 
 DrawTargetSkia::CreatePathBuilder(FillRule aFillRule) const
 {
   RefPtr<PathBuilderSkia> pb = new PathBuilderSkia(aFillRule);
   return pb;
 }
 
 void
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -94,25 +94,33 @@ public:
   virtual TemporaryRef<SourceSurface>
     CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
   virtual TemporaryRef<DrawTarget>
     CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
   virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const;
   virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode = ExtendMode::CLAMP) const;
   virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
   virtual void SetTransform(const Matrix &aTransform);
-  virtual void *GetNativeSurface(NativeSurfaceType aType);
 
   bool Init(const IntSize &aSize, SurfaceFormat aFormat);
   void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
 
 #ifdef USE_SKIA_GPU
-  void InitWithGrContext(GrContext* aGrContext,
-                         const IntSize &aSize,
-                         SurfaceFormat aFormat) MOZ_OVERRIDE;
+  virtual GenericRefCountedBase* GetGLContext() const MOZ_OVERRIDE { return mGLContext; }
+  void InitWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
+                                         GrGLInterface* aGrGLInterface,
+                                         const IntSize &aSize,
+                                         SurfaceFormat aFormat) MOZ_OVERRIDE;
+
+  void SetCacheLimits(int aCount, int aSizeInBytes);
+  void PurgeCaches();
+
+  static void SetGlobalCacheLimits(int aCount, int aSizeInBytes);
+  static void RebalanceCacheLimits();
+  static void PurgeAllCaches();
 #endif
 
   operator std::string() const {
     std::stringstream stream;
     stream << "DrawTargetSkia(" << this << ")";
     return stream.str();
   }
 
@@ -120,18 +128,28 @@ private:
   friend class SourceSurfaceSkia;
   void SnapshotDestroyed();
 
   void MarkChanged();
 
   SkRect SkRectCoveringWholeSurface() const;
 
 #ifdef USE_SKIA_GPU
+  /*
+   * These members have inter-dependencies, but do not keep each other alive, so
+   * destruction order is very important here: mGrContext uses mGrGLInterface, and
+   * through it, uses mGLContext, so it is important that they be declared in the
+   * present order.
+   */
+  RefPtr<GenericRefCountedBase> mGLContext;
+  SkRefPtr<GrGLInterface> mGrGLInterface;
   SkRefPtr<GrContext> mGrContext;
-  uint32_t mTexture;
+
+  static int sTextureCacheCount;
+  static int sTextureCacheSizeInBytes;
 #endif
 
   IntSize mSize;
   SkRefPtr<SkCanvas> mCanvas;
   SourceSurfaceSkia* mSnapshot;
 };
 
 }
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -581,31 +581,40 @@ Factory::D2DCleanup()
 {
   DrawTargetD2D::CleanupD2D();
 }
 
 #endif // XP_WIN
 
 #ifdef USE_SKIA_GPU
 TemporaryRef<DrawTarget>
-Factory::CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
-                                           const IntSize &aSize,
-                                           SurfaceFormat aFormat)
+Factory::CreateDrawTargetSkiaWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
+                                                           GrGLInterface* aGrGLInterface,
+                                                           const IntSize &aSize,
+                                                           SurfaceFormat aFormat)
 {
   DrawTargetSkia* newDrawTargetSkia = new DrawTargetSkia();
-  newDrawTargetSkia->InitWithGrContext(aGrContext, aSize, aFormat);
+  newDrawTargetSkia->InitWithGLContextAndGrGLInterface(aGLContext, aGrGLInterface, aSize, aFormat);
   RefPtr<DrawTarget> newTarget = newDrawTargetSkia;
   return newTarget;
 }
 
+void
+Factory::SetGlobalSkiaCacheLimits(int aCount, int aSizeInBytes)
+{
+    DrawTargetSkia::SetGlobalCacheLimits(aCount, aSizeInBytes);
+}
 #endif // USE_SKIA_GPU
 
 void
 Factory::PurgeAllCaches()
 {
+#ifdef USE_SKIA_GPU
+  DrawTargetSkia::PurgeAllCaches();
+#endif
 }
 
 #ifdef USE_SKIA_FREETYPE
 TemporaryRef<GlyphRenderingOptions>
 Factory::CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting)
 {
   RefPtr<GlyphRenderingOptionsCairo> options =
     new GlyphRenderingOptionsCairo();
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -91,18 +91,17 @@ MOZ_BEGIN_ENUM_CLASS(FontType, int8_t)
   COREGRAPHICS
 MOZ_END_ENUM_CLASS(FontType)
 
 MOZ_BEGIN_ENUM_CLASS(NativeSurfaceType, int8_t)
   D3D10_TEXTURE,
   CAIRO_SURFACE,
   CAIRO_CONTEXT,
   CGCONTEXT,
-  CGCONTEXT_ACCELERATED,
-  OPENGL_TEXTURE
+  CGCONTEXT_ACCELERATED
 MOZ_END_ENUM_CLASS(NativeSurfaceType)
 
 MOZ_BEGIN_ENUM_CLASS(NativeFontType, int8_t)
   DWRITE_FONT_FACE,
   GDI_FONT_FACE,
   MAC_FONT_FACE,
   SKIA_FONT_FACE,
   CAIRO_FONT_FACE
rename from gfx/gl/SkiaGLGlue.cpp
rename to gfx/gl/GLContextSkia.cpp
--- a/gfx/gl/SkiaGLGlue.cpp
+++ b/gfx/gl/GLContextSkia.cpp
@@ -1,42 +1,39 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "skia/GrContext.h"
 #include "skia/GrGLInterface.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/ThreadLocal.h"
 #include "mozilla/DebugOnly.h"
 
 /* SkPostConfig.h includes windows.h, which includes windef.h
  * which redefines min/max. We don't want that. */
 #ifdef _WIN32
 #undef min
 #undef max
 #endif
 
 #include "GLContext.h"
-#include "SkiaGLGlue.h"
 
 using mozilla::gl::GLContext;
 using mozilla::gl::GLFeature;
-using mozilla::gl::SkiaGLGlue;
 using mozilla::gfx::DrawTarget;
 
 static mozilla::ThreadLocal<GLContext*> sGLContext;
 
 extern "C" {
 
 void EnsureGLContext(const GrGLInterface* i)
 {
-    const SkiaGLGlue* contextSkia = reinterpret_cast<const SkiaGLGlue*>(i->fCallbackData);
-    GLContext* gl = contextSkia->GetGLContext();
+    const DrawTarget* drawTarget = reinterpret_cast<const DrawTarget*>(i->fCallbackData);
+    GLContext* gl = static_cast<GLContext*>(drawTarget->GetGLContext());
     gl->MakeCurrent();
 
     if (!sGLContext.initialized()) {
       mozilla::DebugOnly<bool> success = sGLContext.init();
       MOZ_ASSERT(success);
     }
     sGLContext.set(gl);
 }
@@ -773,17 +770,17 @@ GrGLvoid glTexGenfv_mozilla(GrGLenum coo
 
 GrGLvoid glVertexPointer_mozilla(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer)
 {
     return sGLContext.get()->fVertexPointer(size, type, stride, pointer);
 }
 
 } // extern "C"
 
-static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
+GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
 {
     GrGLInterface* i = new GrGLInterface();
     i->fCallback = EnsureGLContext;
     i->fCallbackData = 0; // must be later initialized to be a valid DrawTargetSkia* pointer
 
     // Core GL functions required by Ganesh
     i->fActiveTexture = glActiveTexture_mozilla;
     i->fAttachShader = glAttachShader_mozilla;
@@ -932,19 +929,8 @@ static GrGLInterface* CreateGrGLInterfac
     if (context->IsGLES2()) {
         i->fBindingsExported = kES2_GrGLBinding;
     } else {
         i->fBindingsExported = kDesktop_GrGLBinding;
     }
 
     return i;
 }
-
-SkiaGLGlue::SkiaGLGlue(GLContext* context)
-    : mGLContext(context)
-{
-    SkAutoTUnref<GrGLInterface> i(CreateGrGLInterfaceFromGLContext(mGLContext));
-    i->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this);
-    mGrGLInterface = i;
-    SkAutoTUnref<GrContext> gr(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)mGrGLInterface.get()));
-
-    mGrContext = gr;
-}
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLContextSkia.h
@@ -0,0 +1,8 @@
+/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "skia/GrGLInterface.h"
+
+GrGLInterface* CreateGrGLInterfaceFromGLContext(mozilla::gl::GLContext* context);
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -38,17 +38,16 @@ GLScreenBuffer::Create(GLContext* gl,
         return nullptr;
     }
 
     SurfaceFactory_GL* factory = nullptr;
 
 #ifdef MOZ_WIDGET_GONK
     /* On B2G, we want a Gralloc factory, and we want one right at the start */
     if (!factory &&
-        caps.surfaceAllocator &&
         XRE_GetProcessType() != GeckoProcessType_Default)
     {
         factory = new SurfaceFactory_Gralloc(gl, caps);
     }
 #endif
 #ifdef XP_MACOSX
     /* On OSX, we want an IOSurface factory, and we want one right at the start */
     if (!factory)
@@ -66,16 +65,17 @@ GLScreenBuffer::Create(GLContext* gl,
         gl,
         nullptr);
 
     return new GLScreenBuffer(gl, caps, factory, stream);
 }
 
 GLScreenBuffer::~GLScreenBuffer()
 {
+    delete mStream;
     delete mDraw;
     delete mRead;
 
     // bug 914823: it is crucial to destroy the Factory _after_ we destroy
     // the SharedSurfaces around here! Reason: the shared surfaces will want
     // to ask the Allocator (e.g. the ClientLayerManager) to destroy their
     // buffers, but that Allocator may be kept alive by the Factory,
     // as it currently the case in SurfaceFactory_Gralloc holding a nsRefPtr
@@ -373,16 +373,17 @@ GLScreenBuffer::Morph(SurfaceFactory_GL*
     }
 
     if (mStream->mType == streamType)
         return;
 
     SurfaceStream* newStream = SurfaceStream::CreateForType(streamType, mGL, mStream);
     MOZ_ASSERT(newStream);
 
+    delete mStream;
     mStream = newStream;
 }
 
 void
 GLScreenBuffer::Attach(SharedSurface* surface, const gfx::IntSize& size)
 {
     ScopedBindFramebuffer autoFB(mGL);
 
--- a/gfx/gl/GLScreenBuffer.h
+++ b/gfx/gl/GLScreenBuffer.h
@@ -11,17 +11,16 @@
  * actually the screen, just draw to 0. This GLScreenBuffer class takes the
  * logic handling out of GLContext.
 */
 
 #ifndef SCREEN_BUFFER_H_
 #define SCREEN_BUFFER_H_
 
 #include "SurfaceTypes.h"
-#include "SurfaceStream.h"
 #include "GLContextTypes.h"
 #include "GLDefs.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Point.h"
 
 // Forwards:
 class gfxImageSurface;
 
@@ -152,17 +151,17 @@ public:
     static GLScreenBuffer* Create(GLContext* gl,
                                   const gfx::IntSize& size,
                                   const SurfaceCaps& caps);
 
 protected:
     GLContext* const mGL;         // Owns us.
     SurfaceCaps mCaps;
     SurfaceFactory_GL* mFactory;  // Owned by us.
-    RefPtr<SurfaceStream> mStream;
+    SurfaceStream* mStream;       // Owned by us.
 
     DrawBuffer* mDraw;            // Owned by us.
     ReadBuffer* mRead;            // Owned by us.
 
     bool mNeedsBlit;
 
     // Below are the parts that help us pretend to be framebuffer 0:
     GLuint mUserDrawFB;
--- a/gfx/gl/SharedSurfaceGL.cpp
+++ b/gfx/gl/SharedSurfaceGL.cpp
@@ -114,43 +114,37 @@ SharedSurface_GL::Copy(SharedSurface_GL*
 
         return;
     }
 
     // Alright, done with cases involving Screen types.
     // Only {src,dest}x{texture,renderbuffer} left.
 
     if (src->AttachType() == AttachmentType::GLTexture) {
-        src->LockProd();
         GLuint srcTex = src->Texture();
         GLenum srcTarget = src->TextureTarget();
 
         if (dest->AttachType() == AttachmentType::GLTexture) {
-            dest->LockProd();
             GLuint destTex = dest->Texture();
             GLenum destTarget = dest->TextureTarget();
 
             gl->BlitHelper()->BlitTextureToTexture(srcTex, destTex,
                                                    src->Size(), dest->Size(),
                                                    srcTarget, destTarget);
-            src->UnlockProd();
-            dest->UnlockProd();
+
             return;
         }
 
         if (dest->AttachType() == AttachmentType::GLRenderbuffer) {
-            dest->LockProd();
-
             GLuint destRB = dest->Renderbuffer();
             ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
 
             gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, destWrapper.FB(),
                                                        src->Size(), dest->Size(), srcTarget);
-            src->UnlockProd();
-            dest->UnlockProd();
+
             return;
         }
 
         MOZ_CRASH("Unhandled dest->AttachType().");
     }
 
     if (src->AttachType() == AttachmentType::GLRenderbuffer) {
         GLuint srcRB = src->Renderbuffer();
@@ -184,33 +178,29 @@ SharedSurface_GL::Copy(SharedSurface_GL*
 
 void
 SharedSurface_GL::LockProd()
 {
     MOZ_ASSERT(!mIsLocked);
 
     LockProdImpl();
 
-    if (AttachType() == AttachmentType::Screen)
-        mGL->LockSurface(this);
-
+    mGL->LockSurface(this);
     mIsLocked = true;
 }
 
 void
 SharedSurface_GL::UnlockProd()
 {
     if (!mIsLocked)
         return;
 
     UnlockProdImpl();
 
-    if (AttachType() == AttachmentType::Screen)
-        mGL->UnlockSurface(this);
-
+    mGL->UnlockSurface(this);
     mIsLocked = false;
 }
 
 
 SurfaceFactory_GL::SurfaceFactory_GL(GLContext* gl,
                                      SharedSurfaceType type,
                                      const SurfaceCaps& caps)
     : SurfaceFactory(type, caps)
@@ -288,101 +278,72 @@ SharedSurface_Basic::SharedSurface_Basic
                                          bool hasAlpha,
                                          SurfaceFormat format,
                                          GLuint tex)
     : SharedSurface_GL(SharedSurfaceType::Basic,
                        AttachmentType::GLTexture,
                        gl,
                        size,
                        hasAlpha)
-    , mTex(tex), mFB(0)
+    , mTex(tex)
 {
-    mGL->MakeCurrent();
-    mGL->fGenFramebuffers(1, &mFB);
-    mGL->BindFB(mFB);
-    mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
-                              LOCAL_GL_COLOR_ATTACHMENT0,
-                              LOCAL_GL_TEXTURE_2D,
-                              mTex,
-                              0);
-
-    GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
-    if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
-        mGL->fDeleteFramebuffers(1, &mFB);
-        mFB = 0;
-    }
-
     mData = Factory::CreateDataSourceSurfaceWithStride(size, format,
               GetAlignedStride<4>(size.width * BytesPerPixel(format)));
 }
 
 SharedSurface_Basic::~SharedSurface_Basic()
 {
     if (!mGL->MakeCurrent())
         return;
 
-    if (mFB)
-        mGL->fDeleteFramebuffers(1, &mFB);
-
     mGL->fDeleteTextures(1, &mTex);
 }
 
 void
 SharedSurface_Basic::Fence()
 {
-    mGL->MakeCurrent();
+    MOZ_ASSERT(mData->GetSize() == mGL->OffscreenSize());
 
-    ScopedBindFramebuffer autoFB(mGL, mFB);
+    mGL->MakeCurrent();
 
     DataSourceSurface::MappedSurface map;
     mData->Map(DataSourceSurface::MapType::WRITE, &map);
     nsRefPtr<gfxImageSurface> wrappedData =
       new gfxImageSurface(map.mData,
                           ThebesIntSize(mData->GetSize()),
                           map.mStride,
                           SurfaceFormatToImageFormat(mData->GetFormat()));
-    ReadPixelsIntoImageSurface(mGL, wrappedData);
+    ReadScreenIntoImageSurface(mGL, wrappedData);
     mData->Unmap();
 }
 
 
 
 SharedSurface_GLTexture*
 SharedSurface_GLTexture::Create(GLContext* prodGL,
                                 GLContext* consGL,
                                 const GLFormats& formats,
                                 const gfx::IntSize& size,
-                                bool hasAlpha,
-                                GLuint texture)
+                                bool hasAlpha)
 {
     MOZ_ASSERT(prodGL);
     MOZ_ASSERT(!consGL || prodGL->SharesWith(consGL));
 
     prodGL->MakeCurrent();
-
-    GLuint tex = texture;
-
-    bool ownsTex = false;
+    GLuint tex = CreateTextureForOffscreen(prodGL, formats, size);
 
-    if (!tex) {
-      tex = CreateTextureForOffscreen(prodGL, formats, size);
-      ownsTex = true;
-    }
-
-    return new SharedSurface_GLTexture(prodGL, consGL, size, hasAlpha, tex, ownsTex);
+    return new SharedSurface_GLTexture(prodGL, consGL, size, hasAlpha, tex);
 }
 
 SharedSurface_GLTexture::~SharedSurface_GLTexture()
 {
     if (!mGL->MakeCurrent())
         return;
 
-    if (mOwnsTex) {
-        mGL->fDeleteTextures(1, &mTex);
-    }
+    mGL->fDeleteTextures(1, &mTex);
 
     if (mSync) {
         mGL->fDeleteSync(mSync);
     }
 }
 
 void
 SharedSurface_GLTexture::Fence()
--- a/gfx/gl/SharedSurfaceGL.h
+++ b/gfx/gl/SharedSurfaceGL.h
@@ -1,17 +1,16 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef SHARED_SURFACE_GL_H_
 #define SHARED_SURFACE_GL_H_
 
-#include "ScopedGLHelpers.h"
 #include "SharedSurface.h"
 #include "SurfaceFactory.h"
 #include "SurfaceTypes.h"
 #include "GLContextTypes.h"
 #include "nsAutoPtr.h"
 #include "gfxTypes.h"
 #include "mozilla/Mutex.h"
 
@@ -131,18 +130,16 @@ public:
     static SharedSurface_Basic* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->Type() == SharedSurfaceType::Basic);
 
         return (SharedSurface_Basic*)surf;
     }
 
 protected:
     const GLuint mTex;
-    GLuint mFB;
-
     RefPtr<gfx::DataSourceSurface> mData;
 
     SharedSurface_Basic(GLContext* gl,
                         const gfx::IntSize& size,
                         bool hasAlpha,
                         gfx::SurfaceFormat format,
                         GLuint tex);
 
@@ -190,46 +187,42 @@ public:
 class SharedSurface_GLTexture
     : public SharedSurface_GL
 {
 public:
     static SharedSurface_GLTexture* Create(GLContext* prodGL,
                                            GLContext* consGL,
                                            const GLFormats& formats,
                                            const gfx::IntSize& size,
-                                           bool hasAlpha,
-                                           GLuint texture = 0);
+                                           bool hasAlpha);
 
     static SharedSurface_GLTexture* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->Type() == SharedSurfaceType::GLTextureShare);
 
         return (SharedSurface_GLTexture*)surf;
     }
 
 protected:
     GLContext* mConsGL;
     const GLuint mTex;
-    const bool mOwnsTex;
     GLsync mSync;
     mutable Mutex mMutex;
 
     SharedSurface_GLTexture(GLContext* prodGL,
                             GLContext* consGL,
                             const gfx::IntSize& size,
                             bool hasAlpha,
-                            GLuint tex,
-                            bool ownsTex)
+                            GLuint tex)
         : SharedSurface_GL(SharedSurfaceType::GLTextureShare,
                            AttachmentType::GLTexture,
                            prodGL,
                            size,
                            hasAlpha)
         , mConsGL(consGL)
         , mTex(tex)
-        , mOwnsTex(ownsTex)
         , mSync(0)
         , mMutex("SharedSurface_GLTexture mutex")
     {
     }
 
 public:
     virtual ~SharedSurface_GLTexture();
 
deleted file mode 100755
--- a/gfx/gl/SkiaGLGlue.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this
-* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/RefPtr.h"
-
-#ifdef USE_SKIA_GPU
-
-#include "GLContext.h"
-#include "skia/GrGLInterface.h"
-#include "skia/GrContext.h"
-
-namespace mozilla {
-namespace gl {
-
-class SkiaGLGlue : public GenericAtomicRefCounted
-{
-public:
-  SkiaGLGlue(GLContext* context);
-  GLContext* GetGLContext() const { return mGLContext.get(); }
-  GrContext* GetGrContext() const { return mGrContext.get(); }
-
-protected:
-  virtual ~SkiaGLGlue() {
-    /*
-     * These members have inter-dependencies, but do not keep each other alive, so
-     * destruction order is very important here: mGrContext uses mGrGLInterface, and
-     * through it, uses mGLContext
-     */
-    mGrContext = nullptr;
-    mGrGLInterface = nullptr;
-    mGLContext = nullptr;
-  }
-
-private:
-  RefPtr<GLContext> mGLContext;
-  SkRefPtr<GrGLInterface> mGrGLInterface;
-  SkRefPtr<GrContext> mGrContext;
-};
-
-}
-}
-
-#else
-
-class GrContext;
-
-namespace mozilla {
-namespace gl {
-
-class GLContext;
-
-class SkiaGLGlue : public GenericAtomicRefCounted
-{
-public:
-  SkiaGLGlue(GLContext* context);
-  GLContext* GetGLContext() const { return nullptr; }
-  GrContext* GetGrContext() const { return nullptr; }
-};
-}
-}
-
-#endif
\ No newline at end of file
--- a/gfx/gl/SurfaceStream.cpp
+++ b/gfx/gl/SurfaceStream.cpp
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SurfaceStream.h"
 
 #include "gfxPoint.h"
 #include "SharedSurface.h"
-#include "SharedSurfaceGL.h"
 #include "SurfaceFactory.h"
 #include "GeckoProfiler.h"
 
 namespace mozilla {
 namespace gfx {
 
 SurfaceStreamType
 SurfaceStream::ChooseGLStreamType(SurfaceStream::OMTC omtc,
@@ -49,32 +48,16 @@ SurfaceStream::CreateForType(SurfaceStre
         default:
             MOZ_CRASH("Invalid Type.");
     }
 
     result->mGLContext = glContext;
     return result;
 }
 
-bool
-SurfaceStream_TripleBuffer::CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory)
-{
-    if (!mProducer) {
-        New(factory, src->Size(), mProducer);
-        if (!mProducer) {
-            return false;
-        }
-    }
-
-    MOZ_ASSERT(src->Size() == mProducer->Size(), "Size mismatch");
-
-    SharedSurface::Copy(src, mProducer, factory);
-    return true;
-}
-
 void
 SurfaceStream::New(SurfaceFactory* factory, const gfx::IntSize& size,
                    SharedSurface*& surf)
 {
     MOZ_ASSERT(!surf);
     surf = factory->NewSharedSurface(size);
 
     if (surf)
--- a/gfx/gl/SurfaceStream.h
+++ b/gfx/gl/SurfaceStream.h
@@ -6,31 +6,30 @@
 #ifndef SURFACESTREAM_H_
 #define SURFACESTREAM_H_
 
 #include <stack>
 #include <set>
 #include "mozilla/Monitor.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/gfx/Point.h"
-#include "mozilla/GenericRefCounted.h"
 #include "SurfaceTypes.h"
 
 namespace mozilla {
 
 namespace gl {
 class GLContext;
 }
 
 namespace gfx {
 class SharedSurface;
 class SurfaceFactory;
 
 // Owned by: ScreenBuffer
-class SurfaceStream : public GenericAtomicRefCounted
+class SurfaceStream
 {
 public:
     typedef enum {
         MainThread,
         OffMainThread
     } OMTC;
 
     static SurfaceStreamType ChooseGLStreamType(OMTC omtc,
@@ -46,18 +45,16 @@ public:
 
     static SurfaceStream* FromHandle(SurfaceStreamHandle handle) {
         return (SurfaceStream*)handle;
     }
 
     const SurfaceStreamType mType;
 
     mozilla::gl::GLContext* GLContext() const { return mGLContext; }
-
-
 protected:
     // |mProd| is owned by us, but can be ripped away when
     // creating a new GLStream from this one.
     SharedSurface* mProducer;
     std::set<SharedSurface*> mSurfaces;
     std::stack<SharedSurface*> mScraps;
     mutable Monitor mMonitor;
     bool mIsAlive;
@@ -119,18 +116,16 @@ public:
      * and have everything work again.
      * One common failure is asking for a too-large |size|.
      */
     virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
                                         const gfx::IntSize& size) = 0;
 
     virtual SharedSurface* Resize(SurfaceFactory* factory, const gfx::IntSize& size);
 
-    virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory) { MOZ_ASSERT(0); return false; }
-
 protected:
     // SwapCons will return the same surface more than once,
     // if nothing new has been published.
     virtual SharedSurface* SwapConsumer_NoWait() = 0;
 
 public:
     virtual SharedSurface* SwapConsumer();
 
@@ -189,17 +184,16 @@ protected:
     SharedSurface* mConsumer;
 
     // To support subclasses initializing the mType.
     SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream);
 
 public:
     SurfaceStream_TripleBuffer(SurfaceStream* prevStream);
     virtual ~SurfaceStream_TripleBuffer();
-    virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory);
 
 private:
     // Common constructor code.
     void Init(SurfaceStream* prevStream);
 
 public:
     // Done writing to prod, swap prod and staging
     virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
--- a/gfx/gl/moz.build
+++ b/gfx/gl/moz.build
@@ -70,19 +70,19 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
         'SharedSurfaceANGLE.h',
         'WGLLibrary.h',
     ]
     UNIFIED_SOURCES += [
         'GLContextProviderEGL.cpp',
         'SharedSurfaceANGLE.cpp',
     ]
 if CONFIG['MOZ_ENABLE_SKIA_GPU']:
-    EXPORTS += ['SkiaGLGlue.h']
+    EXPORTS += ['GLContextSkia.h']
     UNIFIED_SOURCES += [
-        'SkiaGLGlue.cpp',
+        'GLContextSkia.cpp',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     UNIFIED_SOURCES += ['SharedSurfaceGralloc.cpp']
     EXPORTS += ['SharedSurfaceGralloc.h']
     LOCAL_INCLUDES += ['/widget/gonk']
 
 if gl_provider == 'CGL':
--- a/gfx/layers/CopyableCanvasLayer.cpp
+++ b/gfx/layers/CopyableCanvasLayer.cpp
@@ -27,17 +27,16 @@
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 
 namespace mozilla {
 namespace layers {
 
 CopyableCanvasLayer::CopyableCanvasLayer(LayerManager* aLayerManager, void *aImplData) :
   CanvasLayer(aLayerManager, aImplData)
-  , mStream(nullptr)
 {
   MOZ_COUNT_CTOR(CopyableCanvasLayer);
   mForceReadback = Preferences::GetBool("webgl.force-layers-readback", false);
 }
 
 CopyableCanvasLayer::~CopyableCanvasLayer()
 {
   MOZ_COUNT_DTOR(CopyableCanvasLayer);
@@ -45,17 +44,16 @@ CopyableCanvasLayer::~CopyableCanvasLaye
 
 void
 CopyableCanvasLayer::Initialize(const Data& aData)
 {
   NS_ASSERTION(mSurface == nullptr, "BasicCanvasLayer::Initialize called twice!");
 
   if (aData.mGLContext) {
     mGLContext = aData.mGLContext;
-    mStream = aData.mStream;
     mIsGLAlphaPremult = aData.mIsGLAlphaPremult;
     mNeedsYFlip = true;
     MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
 
     // [Basic Layers, non-OMTC] WebGL layer init.
     // `GLScreenBuffer::Morph`ing is only needed in BasicShadowableCanvasLayer.
   } else if (aData.mDrawTarget) {
     mDrawTarget = aData.mDrawTarget;
@@ -68,17 +66,17 @@ CopyableCanvasLayer::Initialize(const Da
   }
 
   mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
 }
 
 bool
 CopyableCanvasLayer::IsDataValid(const Data& aData)
 {
-  return mGLContext == aData.mGLContext && mStream == aData.mStream;
+  return mGLContext == aData.mGLContext;
 }
 
 void
 CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget,
                                   SourceSurface* aMaskSurface)
 {
   if (!IsDirty())
     return;
--- a/gfx/layers/CopyableCanvasLayer.h
+++ b/gfx/layers/CopyableCanvasLayer.h
@@ -17,23 +17,16 @@
 #include "mozilla/Preferences.h"        // for Preferences
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 
 namespace mozilla {
-
-namespace gfx {
-class SurfaceStream;
-class SharedSurface;
-class SurfaceFactory;
-}
-
 namespace layers {
 
 class CanvasClientWebGL;
 
 /**
  * A shared CanvasLayer implementation that supports copying
  * its contents into a gfxASurface using UpdateSurface.
  */
@@ -56,18 +49,16 @@ protected:
   void UpdateTarget(gfx::DrawTarget* aDestTarget = nullptr,
                     gfx::SourceSurface* aMaskSurface = nullptr);
 
   RefPtr<gfx::SourceSurface> mSurface;
   nsRefPtr<gfxASurface> mDeprecatedSurface;
   nsRefPtr<mozilla::gl::GLContext> mGLContext;
   mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
 
-  RefPtr<gfx::SurfaceStream> mStream;
-
   uint32_t mCanvasFramebuffer;
 
   bool mIsGLAlphaPremult;
   bool mNeedsYFlip;
   bool mForceReadback;
 
   RefPtr<gfx::DataSourceSurface> mCachedTempSurface;
   nsRefPtr<gfxImageSurface> mDeprecatedCachedTempSurface;
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -58,17 +58,16 @@ class FrameLayerBuilder;
 class WebGLContext;
 
 namespace gl {
 class GLContext;
 }
 
 namespace gfx {
 class DrawTarget;
-class SurfaceStream;
 }
 
 namespace css {
 class ComputedTimingFunction;
 }
 
 namespace layers {
 
@@ -1786,32 +1785,24 @@ protected:
  * must not be modified during a layer transaction.
  */
 class CanvasLayer : public Layer {
 public:
   struct Data {
     Data()
       : mDrawTarget(nullptr)
       , mGLContext(nullptr)
-      , mStream(nullptr)
-      , mTexID(0)
       , mSize(0,0)
       , mIsGLAlphaPremult(false)
     { }
 
     // One of these two must be specified for Canvas2D, but never both
     mozilla::gfx::DrawTarget *mDrawTarget; // a DrawTarget for the canvas contents
     mozilla::gl::GLContext* mGLContext; // or this, for GL.
 
-    // Canvas/SkiaGL uses this
-    mozilla::gfx::SurfaceStream* mStream;
-
-    // ID of the texture backing the canvas layer (defaults to 0)
-    uint32_t mTexID;
-
     // The size of the canvas content
     nsIntSize mSize;
 
     // Whether mGLContext contains data that is alpha-premultiplied.
     bool mIsGLAlphaPremult;
   };
 
   /**
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -111,28 +111,17 @@ CanvasClientSurfaceStream::CanvasClientS
   : CanvasClient(aLayerForwarder, aFlags)
 {
 }
 
 void
 CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
 {
   GLScreenBuffer* screen = aLayer->mGLContext->Screen();
-  SurfaceStream* stream = nullptr;
-
-  if (aLayer->mStream) {
-    stream = aLayer->mStream;
-
-    // Copy our current surface to the current producer surface in our stream, then
-    // call SwapProducer to make a new buffer ready.
-    stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory);
-    stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height));
-  } else {
-    stream = screen->Stream();
-  }
+  SurfaceStream* stream = screen->Stream();
 
   bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
   bool bufferCreated = false;
   if (isCrossProcess) {
 #ifdef MOZ_WIDGET_GONK
     SharedSurface* surf = stream->SwapConsumer();
     if (!surf) {
       printf_stderr("surf is null post-SwapConsumer!\n");
@@ -261,25 +250,17 @@ DeprecatedCanvasClientSurfaceStream::Upd
   }
 
   NS_ASSERTION(aLayer->mGLContext, "CanvasClientSurfaceStream should only be used with GL canvases");
 
   // the content type won't be used
   mDeprecatedTextureClient->EnsureAllocated(aSize, gfxContentType::COLOR);
 
   GLScreenBuffer* screen = aLayer->mGLContext->Screen();
-  SurfaceStream* stream = nullptr;
-
-  if (aLayer->mStream) {
-    stream = aLayer->mStream;
-    stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory);
-    stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height));
-  } else {
-    stream = screen->Stream();
-  }
+  SurfaceStream* stream = screen->Stream();
 
   bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
   if (isCrossProcess) {
     // swap staging -> consumer so we can send it to the compositor
     SharedSurface* surf = stream->SwapConsumer();
     if (!surf) {
       printf_stderr("surf is null post-SwapConsumer!\n");
       return;
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -31,81 +31,56 @@ using namespace mozilla::gl;
 
 namespace mozilla {
 namespace layers {
 
 void
 ClientCanvasLayer::Initialize(const Data& aData)
 {
   CopyableCanvasLayer::Initialize(aData);
-
+ 
   mCanvasClient = nullptr;
 
   if (mGLContext) {
     GLScreenBuffer* screen = mGLContext->Screen();
-
-    SurfaceCaps caps = screen->Caps();
-    if (mStream) {
-      // The screen caps are irrelevant if we're using a separate stream
-      caps = GetContentFlags() & CONTENT_OPAQUE ? SurfaceCaps::ForRGB() : SurfaceCaps::ForRGBA();
-    }
-
     SurfaceStreamType streamType =
         SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread,
                                           screen->PreserveBuffer());
     SurfaceFactory_GL* factory = nullptr;
     if (!mForceReadback) {
       if (ClientManager()->AsShadowForwarder()->GetCompositorBackendType() == mozilla::layers::LayersBackend::LAYERS_OPENGL) {
         if (mGLContext->GetContextType() == GLContextType::EGL) {
           bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
 
           if (!isCrossProcess) {
             // [Basic/OGL Layers, OMTC] WebGL layer init.
-            factory = SurfaceFactory_EGLImage::Create(mGLContext, caps);
+            factory = SurfaceFactory_EGLImage::Create(mGLContext, screen->Caps());
           } else {
             // [Basic/OGL Layers, OOPC] WebGL layer init. (Out Of Process Compositing)
 #ifdef MOZ_WIDGET_GONK
-            factory = new SurfaceFactory_Gralloc(mGLContext, caps, ClientManager()->AsShadowForwarder());
+            factory = new SurfaceFactory_Gralloc(mGLContext, screen->Caps(), ClientManager()->AsShadowForwarder());
 #else
             // we could do readback here maybe
             NS_NOTREACHED("isCrossProcess but not on native B2G!");
 #endif
           }
         } else {
           // [Basic Layers, OMTC] WebGL layer init.
           // Well, this *should* work...
 #ifdef XP_MACOSX
-          factory = new SurfaceFactory_IOSurface(mGLContext, caps);
+          factory = new SurfaceFactory_IOSurface(mGLContext, screen->Caps());
 #else
-          factory = new SurfaceFactory_GLTexture(mGLContext, nullptr, caps);
+          factory = new SurfaceFactory_GLTexture(mGLContext, nullptr, screen->Caps());
 #endif
         }
       }
     }
 
     if (factory) {
-      if (mStream) {
-        // We're using a stream other than the one in the default screen
-        mFactory = factory;
-
-        gfx::IntSize size = gfx::IntSize(aData.mSize.width, aData.mSize.height);
-        mTextureSurface = SharedSurface_GLTexture::Create(mGLContext, mGLContext,
-                                                          mGLContext->GetGLFormats(),
-                                                          size, caps.alpha, aData.mTexID);
-        SharedSurface* producer = mStream->SwapProducer(mFactory, size);
-        if (!producer) {
-          // Fallback to basic factory
-          delete mFactory;
-          mFactory = new SurfaceFactory_Basic(mGLContext, caps);
-          producer = mStream->SwapProducer(mFactory, size);
-          MOZ_ASSERT(producer, "Failed to create initial canvas surface with basic factory");
-        }
-      } else {
-        screen->Morph(factory, streamType);
-      }
+      screen->Morph(factory, streamType);
     }
   }
 }
 
 void
 ClientCanvasLayer::RenderLayer()
 {
   PROFILER_LABEL("ClientCanvasLayer", "Paint");
--- a/gfx/layers/client/ClientCanvasLayer.h
+++ b/gfx/layers/client/ClientCanvasLayer.h
@@ -28,18 +28,16 @@ class ShadowableLayer;
 class ClientCanvasLayer : public CopyableCanvasLayer,
                           public ClientLayer
 {
   typedef CanvasClient::CanvasClientType CanvasClientType;
 public:
   ClientCanvasLayer(ClientLayerManager* aLayerManager) :
     CopyableCanvasLayer(aLayerManager,
                         static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST()))
-    , mTextureSurface(nullptr)
-    , mFactory(nullptr)
   {
     MOZ_COUNT_CTOR(ClientCanvasLayer);
   }
   virtual ~ClientCanvasLayer()
   {
     MOZ_COUNT_DTOR(ClientCanvasLayer);
     if (mCanvasClient) {
       mCanvasClient->OnDetach();
@@ -87,19 +85,16 @@ protected:
     if (mGLContext) {
       return CanvasClient::CanvasClientGLContext;
     }
     return CanvasClient::CanvasClientSurface;
   }
 
   RefPtr<CanvasClient> mCanvasClient;
 
-  gfx::SharedSurface* mTextureSurface;
-  gfx::SurfaceFactory* mFactory;
-
   friend class DeprecatedCanvasClient2D;
   friend class CanvasClient2D;
   friend class DeprecatedCanvasClientSurfaceStream;
   friend class CanvasClientSurfaceStream;
 };
 }
 }
 
--- a/gfx/layers/opengl/TextureClientOGL.cpp
+++ b/gfx/layers/opengl/TextureClientOGL.cpp
@@ -81,16 +81,17 @@ SharedTextureClientOGL::Unlock()
 bool
 SharedTextureClientOGL::IsAllocated() const
 {
   return mHandle != 0;
 }
 
 StreamTextureClientOGL::StreamTextureClientOGL(TextureFlags aFlags)
   : TextureClient(aFlags)
+  , mStream(0)
   , mIsLocked(false)
 {
 }
 
 StreamTextureClientOGL::~StreamTextureClientOGL()
 {
   // the data is owned externally.
 }
@@ -125,17 +126,16 @@ StreamTextureClientOGL::ToSurfaceDescrip
   return true;
 }
 
 void
 StreamTextureClientOGL::InitWith(gfx::SurfaceStream* aStream)
 {
   MOZ_ASSERT(!IsAllocated());
   mStream = aStream;
-  mGL = mStream->GLContext();
 }
 
 bool
 StreamTextureClientOGL::IsAllocated() const
 {
   return mStream != 0;
 }
 
--- a/gfx/layers/opengl/TextureClientOGL.h
+++ b/gfx/layers/opengl/TextureClientOGL.h
@@ -92,17 +92,16 @@ public:
 
   virtual TextureClientData* DropTextureData() MOZ_OVERRIDE { return nullptr; }
 
   void InitWith(gfx::SurfaceStream* aStream);
 
   virtual gfx::IntSize GetSize() const { return gfx::IntSize(); }
 
 protected:
+  gfx::SurfaceStream* mStream;
   bool mIsLocked;
-  RefPtr<gfx::SurfaceStream> mStream;
-  RefPtr<gl::GLContext> mGL;
 };
 
 } // namespace
 } // namespace
 
 #endif
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -71,19 +71,16 @@
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "TexturePoolOGL.h"
 #endif
 
 #ifdef USE_SKIA
 #include "mozilla/Hal.h"
 #include "skia/SkGraphics.h"
-
-#include "SkiaGLGlue.h"
-
 #endif
 
 #include "mozilla/Preferences.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Mutex.h"
 
 #include "nsIGfxInfo.h"
@@ -229,18 +226,16 @@ NS_IMPL_ISUPPORTS1(MemoryPressureObserve
 
 NS_IMETHODIMP
 MemoryPressureObserver::Observe(nsISupports *aSubject,
                                 const char *aTopic,
                                 const char16_t *someData)
 {
     NS_ASSERTION(strcmp(aTopic, "memory-pressure") == 0, "unexpected event topic");
     Factory::PurgeAllCaches();
-
-    gfxPlatform::GetPlatform()->PurgeSkiaCache();
     return NS_OK;
 }
 
 // this needs to match the list of pref font.default.xx entries listed in all.js!
 // the order *must* match the order in eFontPrefLang
 static const char *gPrefLangNames[] = {
     "x-western",
     "x-central-euro",
@@ -298,18 +293,16 @@ gfxPlatform::gfxPlatform()
     // XXX - When 957560 is fixed, the pref can go away entirely
     mLayersUseDeprecated =
         Preferences::GetBool("layers.use-deprecated-textures", true)
         && !Preferences::GetBool("layers.prefer-opengl", false);
 #else
     mLayersUseDeprecated = false;
 #endif
 
-    mSkiaGlue = nullptr;
-
     Preferences::AddBoolVarCache(&mDrawLayerBorders,
                                  "layers.draw-borders",
                                  false);
     Preferences::AddBoolVarCache(&mDrawTileBorders,
                                  "layers.draw-tile-borders",
                                  false);
     Preferences::AddBoolVarCache(&mDrawBigImageBorders,
                                  "layers.draw-bigimage-borders",
@@ -484,16 +477,20 @@ gfxPlatform::Init()
     gPlatform->mOrientationSyncMillis = Preferences::GetUint("layers.orientation.sync.timeout", (uint32_t)0);
 
     mozilla::Preferences::AddBoolVarCache(&sDrawFrameCounter,
                                           "layers.frame-counter",
                                           false);
 
     CreateCMSOutputProfile();
 
+#ifdef USE_SKIA
+    gPlatform->InitializeSkiaCaches();
+#endif
+
     // Listen to memory pressure event so we can purge DrawTarget caches
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
         gPlatform->mMemoryPressureObserver = new MemoryPressureObserver();
         obs->AddObserver(gPlatform->mMemoryPressureObserver, "memory-pressure", false);
     }
 
     RegisterStrongMemoryReporter(new GfxMemoryImageReporter());
@@ -890,78 +887,47 @@ gfxPlatform::SupportsAzureContentForDraw
 
 bool
 gfxPlatform::UseAcceleratedSkiaCanvas()
 {
   return Preferences::GetBool("gfx.canvas.azure.accelerated", false) &&
          mPreferredCanvasBackend == BackendType::SKIA;
 }
 
-static void
-InitializeSkiaCacheLimits(GrContext* context)
+void
+gfxPlatform::InitializeSkiaCaches()
 {
-  bool usingDynamicCache = Preferences::GetBool("gfx.canvas.skiagl.dynamic-cache", false);
+#ifdef USE_SKIA_GPU
+  if (UseAcceleratedSkiaCanvas()) {
+    bool usingDynamicCache = Preferences::GetBool("gfx.canvas.skiagl.dynamic-cache", false);
 
-  int cacheItemLimit = Preferences::GetInt("gfx.canvas.skiagl.cache-items", 256);
-  int cacheSizeLimit = Preferences::GetInt("gfx.canvas.skiagl.cache-size", 96);
-
-  // Prefs are in megabytes, but we want the sizes in bytes
-  cacheSizeLimit *= 1024*1024;
+    int cacheItemLimit = Preferences::GetInt("gfx.canvas.skiagl.cache-items", 256);
+    int cacheSizeLimit = Preferences::GetInt("gfx.canvas.skiagl.cache-size", 96);
 
-  if (usingDynamicCache) {
-    uint32_t totalMemory = mozilla::hal::GetTotalSystemMemory();
+    // Prefs are in megabytes, but we want the sizes in bytes
+    cacheSizeLimit *= 1024*1024;
+
+    if (usingDynamicCache) {
+      uint32_t totalMemory = mozilla::hal::GetTotalSystemMemory();
 
-    if (totalMemory <= 256*1024*1024) {
-      // We need a very minimal cache on 256 meg devices
-      cacheSizeLimit = 2*1024*1024;
-    } else if (totalMemory > 0) {
-      cacheSizeLimit = totalMemory / 16;
+      if (totalMemory <= 256*1024*1024) {
+        // We need a very minimal cache on 256 meg devices
+        cacheSizeLimit = 2*1024*1024;
+      } else if (totalMemory > 0) {
+        cacheSizeLimit = totalMemory / 16;
+      }
     }
-  }
 
 #ifdef DEBUG
-  printf_stderr("Determined SkiaGL cache limits: Size %i, Items: %i\n", cacheSizeLimit, cacheItemLimit);
+    printf_stderr("Determined SkiaGL cache limits: Size %i, Items: %i\n", cacheSizeLimit, cacheItemLimit);
 #endif
 
-  context->setTextureCacheLimits(cacheItemLimit, cacheSizeLimit);
-}
-
-mozilla::gl::SkiaGLGlue*
-gfxPlatform::GetSkiaGLGlue()
-{
-#ifdef USE_SKIA_GPU
-  if (!mSkiaGlue) {
-    /* Dummy context. We always draw into a FBO.
-     *
-     * FIXME: This should be stored in TLS or something, since there needs to be one for each thread using it. As it
-     * stands, this only works on the main thread.
-     */
-    mozilla::gfx::SurfaceCaps caps = mozilla::gfx::SurfaceCaps::ForRGBA();
-    nsRefPtr<mozilla::gl::GLContext> glContext = mozilla::gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), caps);
-    if (!glContext) {
-      printf_stderr("Failed to create GLContext for SkiaGL!\n");
-      return nullptr;
-    }
-    mSkiaGlue = new mozilla::gl::SkiaGLGlue(glContext);
-    InitializeSkiaCacheLimits(mSkiaGlue->GetGrContext());
+    Factory::SetGlobalSkiaCacheLimits(cacheItemLimit, cacheSizeLimit);
   }
 #endif
-
-  return mSkiaGlue;
-}
-
-void
-gfxPlatform::PurgeSkiaCache()
-{
-#ifdef USE_SKIA_GPU
-  if (!mSkiaGlue)
-      return;
-
-  mSkiaGlue->GetGrContext()->freeGpuResources();
-#endif
 }
 
 already_AddRefed<gfxASurface>
 gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
 {
   if (aTarget->GetType() == BackendType::CAIRO) {
     cairo_surface_t* csurf =
       static_cast<cairo_surface_t*>(aTarget->GetNativeSurface(NativeSurfaceType::CAIRO_SURFACE));
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -35,17 +35,16 @@ class gfxTextRun;
 class nsIURI;
 class nsIAtom;
 class nsIObserver;
 struct gfxRGBA;
 
 namespace mozilla {
 namespace gl {
 class GLContext;
-class SkiaGLGlue;
 }
 namespace gfx {
 class DrawTarget;
 class SourceSurface;
 class ScaledFont;
 class DrawEventRecorder;
 
 inline uint32_t
@@ -280,16 +279,18 @@ public:
     bool SupportsAzureContentForDrawTarget(mozilla::gfx::DrawTarget* aTarget);
 
     bool SupportsAzureContentForType(mozilla::gfx::BackendType aType) {
       return BackendTypeBit(aType) & mContentBackendBitmask;
     }
 
     virtual bool UseAcceleratedSkiaCanvas();
 
+    virtual void InitializeSkiaCaches();
+
     void GetAzureBackendInfo(mozilla::widget::InfoObject &aObj) {
       aObj.DefineProperty("AzureCanvasBackend", GetBackendName(mPreferredCanvasBackend));
       aObj.DefineProperty("AzureSkiaAccelerated", UseAcceleratedSkiaCanvas());
       aObj.DefineProperty("AzureFallbackCanvasBackend", GetBackendName(mFallbackCanvasBackend));
       aObj.DefineProperty("AzureContentBackend", GetBackendName(mContentBackend));
     }
 
     mozilla::gfx::BackendType GetPreferredCanvasBackend() {
@@ -626,19 +627,16 @@ public:
      * Returns true if we should use raw memory to send data to the compositor
      * rather than using shmems.
      *
      * This method should not be called from the compositor thread.
      */
     bool PreferMemoryOverShmem() const;
     bool UseDeprecatedTextures() const { return mLayersUseDeprecated; }
 
-    mozilla::gl::SkiaGLGlue* GetSkiaGLGlue();
-    void PurgeSkiaCache();
-
 protected:
     gfxPlatform();
     virtual ~gfxPlatform();
 
     void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], uint32_t &aLen, 
                             eFontPrefLang aCharLang, eFontPrefLang aPageLang);
 
     /**
@@ -749,13 +747,11 @@ private:
     mozilla::RefPtr<mozilla::gfx::DrawEventRecorder> mRecorder;
     bool mWidgetUpdateFlashing;
     uint32_t mOrientationSyncMillis;
     bool mLayersPreferMemoryOverShmem;
     bool mLayersUseDeprecated;
     bool mDrawLayerBorders;
     bool mDrawTileBorders;
     bool mDrawBigImageBorders;
-
-    mozilla::RefPtr<mozilla::gl::SkiaGLGlue> mSkiaGlue;
 };
 
 #endif /* GFX_PLATFORM_H */